net: wireless: rockchip_wlan: add rtl8188eu support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8188eu / 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 <hal_data.h>
23
24 extern void indicate_wx_scan_complete_event(_adapter *padapter);
25 extern u8 rtw_do_join(_adapter * padapter);
26
27
28 sint    _rtw_init_mlme_priv (_adapter* padapter)
29 {
30         sint    i;
31         u8      *pbuf;
32         struct wlan_network     *pnetwork;
33         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
34         sint    res = _SUCCESS;
35
36 _func_enter_;
37
38         // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc().
39         //_rtw_memset((u8 *)pmlmepriv, 0, sizeof(struct mlme_priv));
40
41         pmlmepriv->nic_hdl = (u8 *)padapter;
42
43         pmlmepriv->pscanned = NULL;
44         pmlmepriv->fw_state = WIFI_STATION_STATE; // Must sync with rtw_wdev_alloc() 
45                                                   // wdev->iftype = NL80211_IFTYPE_STATION
46         pmlmepriv->cur_network.network.InfrastructureMode = Ndis802_11AutoUnknown;
47         pmlmepriv->scan_mode=SCAN_ACTIVE;// 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff)
48
49         _rtw_spinlock_init(&(pmlmepriv->lock)); 
50         _rtw_init_queue(&(pmlmepriv->free_bss_pool));
51         _rtw_init_queue(&(pmlmepriv->scanned_queue));
52
53         set_scanned_network_val(pmlmepriv, 0);
54         
55         _rtw_memset(&pmlmepriv->assoc_ssid,0,sizeof(NDIS_802_11_SSID));
56
57         pbuf = rtw_zvmalloc(MAX_BSS_CNT * (sizeof(struct wlan_network)));
58         
59         if (pbuf == NULL){
60                 res=_FAIL;
61                 goto exit;
62         }
63         pmlmepriv->free_bss_buf = pbuf;
64                 
65         pnetwork = (struct wlan_network *)pbuf;
66         
67         for(i = 0; i < MAX_BSS_CNT; i++)
68         {               
69                 _rtw_init_listhead(&(pnetwork->list));
70
71                 rtw_list_insert_tail(&(pnetwork->list), &(pmlmepriv->free_bss_pool.queue));
72
73                 pnetwork++;
74         }
75
76         //allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf
77
78         rtw_clear_scan_deny(padapter);
79 #ifdef CONFIG_ARP_KEEP_ALIVE
80         pmlmepriv->bGetGateway = 0;
81 #endif
82
83 #ifdef CONFIG_LAYER2_ROAMING
84         #define RTW_ROAM_SCAN_RESULT_EXP_MS 5*1000
85         #define RTW_ROAM_RSSI_DIFF_TH 10
86         #define RTW_ROAM_SCAN_INTERVAL_MS 10*1000
87
88         pmlmepriv->roam_flags = 0
89                 | RTW_ROAM_ON_EXPIRED
90                 #ifdef CONFIG_LAYER2_ROAMING_RESUME
91                 | RTW_ROAM_ON_RESUME
92                 #endif
93                 #ifdef CONFIG_LAYER2_ROAMING_ACTIVE
94                 | RTW_ROAM_ACTIVE
95                 #endif
96                 ;
97
98         pmlmepriv->roam_scanr_exp_ms = RTW_ROAM_SCAN_RESULT_EXP_MS;
99         pmlmepriv->roam_rssi_diff_th = RTW_ROAM_RSSI_DIFF_TH;
100         pmlmepriv->roam_scan_int_ms = RTW_ROAM_SCAN_INTERVAL_MS;
101 #endif /* CONFIG_LAYER2_ROAMING */
102
103         rtw_init_mlme_timer(padapter);
104
105 exit:
106
107 _func_exit_;
108
109         return res;
110 }       
111
112 void rtw_mfree_mlme_priv_lock (struct mlme_priv *pmlmepriv);
113 void rtw_mfree_mlme_priv_lock (struct mlme_priv *pmlmepriv)
114 {
115         _rtw_spinlock_free(&pmlmepriv->lock);
116         _rtw_spinlock_free(&(pmlmepriv->free_bss_pool.lock));
117         _rtw_spinlock_free(&(pmlmepriv->scanned_queue.lock));
118 }
119
120 static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
121 {
122         if(*ppie)
123         {               
124                 rtw_mfree(*ppie, *plen);
125                 *plen = 0;
126                 *ppie=NULL;
127         }       
128 }
129
130 void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
131 {
132 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
133         rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
134         rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
135         rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len);
136         rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len);
137         rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len);
138         rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len);
139         
140         rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len);
141         rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len);
142         rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len);
143         rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len);
144         rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len);
145         rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_resp_ie, &pmlmepriv->p2p_assoc_resp_ie_len);
146 #endif
147
148 #if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211)       
149         rtw_free_mlme_ie_data(&pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);
150         rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);
151         rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);
152         rtw_free_mlme_ie_data(&pmlmepriv->wfd_go_probe_resp_ie, &pmlmepriv->wfd_go_probe_resp_ie_len);
153         rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
154         rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_resp_ie, &pmlmepriv->wfd_assoc_resp_ie_len);
155 #endif
156
157 }
158
159 #if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211)
160 int rtw_mlme_update_wfd_ie_data(struct mlme_priv *mlme, u8 type, u8 *ie, u32 ie_len)
161 {
162         _adapter *adapter = mlme_to_adapter(mlme);
163         struct wifi_display_info *wfd_info = &adapter->wfd_info;
164         u8 clear = 0;
165         u8 **t_ie = NULL;
166         u32 *t_ie_len = NULL;
167         int ret = _FAIL;
168
169         if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
170                 goto success;
171
172         if (wfd_info->wfd_enable == _TRUE)
173                 goto success; /* WFD IE is build by self */
174
175         if (!ie && !ie_len) {
176                 clear = 1;
177         } else if (!ie || !ie_len) {
178                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" type:%u, ie:%p, ie_len:%u"
179                         , FUNC_ADPT_ARG(adapter), type, ie, ie_len);
180                 rtw_warn_on(1);
181                 goto exit;
182         }
183
184         switch (type) {
185         case MLME_BEACON_IE:
186                 t_ie = &mlme->wfd_beacon_ie;
187                 t_ie_len = &mlme->wfd_beacon_ie_len;
188                 break;
189         case MLME_PROBE_REQ_IE:
190                 t_ie = &mlme->wfd_probe_req_ie;
191                 t_ie_len = &mlme->wfd_probe_req_ie_len;
192                 break;
193         case MLME_PROBE_RESP_IE:
194                 t_ie = &mlme->wfd_probe_resp_ie;
195                 t_ie_len = &mlme->wfd_probe_resp_ie_len;
196                 break;
197         case MLME_GO_PROBE_RESP_IE:
198                 t_ie = &mlme->wfd_go_probe_resp_ie;
199                 t_ie_len = &mlme->wfd_go_probe_resp_ie_len;
200                 break;
201         case MLME_ASSOC_REQ_IE:
202                 t_ie = &mlme->wfd_assoc_req_ie;
203                 t_ie_len = &mlme->wfd_assoc_req_ie_len;
204                 break;
205         case MLME_ASSOC_RESP_IE:
206                 t_ie = &mlme->wfd_assoc_resp_ie;
207                 t_ie_len = &mlme->wfd_assoc_resp_ie_len;
208                 break;
209         default:
210                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" unsupported type:%u"
211                         , FUNC_ADPT_ARG(adapter), type);
212                 rtw_warn_on(1);
213                 goto exit;
214         }
215
216         if (*t_ie) {
217                 u32 free_len = *t_ie_len;
218                 *t_ie_len = 0;
219                 rtw_mfree(*t_ie, free_len);
220                 *t_ie = NULL;
221         }
222
223         if (!clear) {
224                 *t_ie = rtw_malloc(ie_len);
225                 if (*t_ie == NULL) {
226                         DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" type:%u, rtw_malloc() fail\n"
227                                 , FUNC_ADPT_ARG(adapter), type);
228                         goto exit;
229                 }
230                 _rtw_memcpy(*t_ie, ie, ie_len);
231                 *t_ie_len = ie_len;
232         }
233
234         if (*t_ie && *t_ie_len) {
235                 u8 *attr_content;
236                 u32 attr_contentlen = 0;
237
238                 attr_content = rtw_get_wfd_attr_content(*t_ie, *t_ie_len, WFD_ATTR_DEVICE_INFO, NULL, &attr_contentlen);
239                 if (attr_content && attr_contentlen) {
240                         if (RTW_GET_BE16(attr_content + 2) != wfd_info->rtsp_ctrlport) {
241                                 wfd_info->rtsp_ctrlport = RTW_GET_BE16(attr_content + 2);
242                                 DBG_871X(FUNC_ADPT_FMT" type:%u, RTSP CTRL port = %u\n"
243                                         , FUNC_ADPT_ARG(adapter), type, wfd_info->rtsp_ctrlport);
244                         }
245                 }
246         }
247
248 success:
249         ret = _SUCCESS;
250
251 exit:
252         return ret;
253 }
254 #endif /* defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211) */
255
256 void _rtw_free_mlme_priv (struct mlme_priv *pmlmepriv)
257 {
258 _func_enter_;
259         if (NULL == pmlmepriv){
260                 rtw_warn_on(1);
261                 goto exit;
262         }
263         rtw_free_mlme_priv_ie_data(pmlmepriv);
264
265         if(pmlmepriv){
266                 rtw_mfree_mlme_priv_lock (pmlmepriv);
267
268                 if (pmlmepriv->free_bss_buf) {
269                         rtw_vmfree(pmlmepriv->free_bss_buf, MAX_BSS_CNT * sizeof(struct wlan_network));
270                 }
271         }
272 exit:
273 _func_exit_;    
274 }
275
276 sint    _rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork)
277 {
278         _irqL irqL;
279
280 _func_enter_;   
281
282         if (pnetwork == NULL)
283                 goto exit;
284         
285         _enter_critical_bh(&queue->lock, &irqL);
286
287         rtw_list_insert_tail(&pnetwork->list, &queue->queue);
288
289         _exit_critical_bh(&queue->lock, &irqL);
290
291 exit:   
292
293 _func_exit_;            
294
295         return _SUCCESS;
296 }
297
298 /*
299 struct  wlan_network *_rtw_dequeue_network(_queue *queue)
300 {
301         _irqL irqL;
302
303         struct wlan_network *pnetwork;
304
305 _func_enter_;   
306
307         _enter_critical_bh(&queue->lock, &irqL);
308
309         if (_rtw_queue_empty(queue) == _TRUE)
310
311                 pnetwork = NULL;
312         
313         else
314         {
315                 pnetwork = LIST_CONTAINOR(get_next(&queue->queue), struct wlan_network, list);
316                 
317                 rtw_list_delete(&(pnetwork->list));
318         }
319         
320         _exit_critical_bh(&queue->lock, &irqL);
321
322 _func_exit_;            
323
324         return pnetwork;
325 }
326 */
327
328 struct  wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv )//(_queue *free_queue)
329 {
330         _irqL   irqL;
331         struct  wlan_network    *pnetwork;      
332         _queue *free_queue = &pmlmepriv->free_bss_pool;
333         _list* plist = NULL;
334         
335 _func_enter_;   
336
337         _enter_critical_bh(&free_queue->lock, &irqL);
338         
339         if (_rtw_queue_empty(free_queue) == _TRUE) {
340                 pnetwork=NULL;
341                 goto exit;
342         }
343         plist = get_next(&(free_queue->queue));
344         
345         pnetwork = LIST_CONTAINOR(plist , struct wlan_network, list);
346         
347         rtw_list_delete(&pnetwork->list);
348         
349         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("_rtw_alloc_network: ptr=%p\n", plist));
350         pnetwork->network_type = 0;
351         pnetwork->fixed = _FALSE;
352         pnetwork->last_scanned = rtw_get_current_time();
353         pnetwork->aid=0;        
354         pnetwork->join_res=0;
355
356         pmlmepriv->num_of_scanned ++;
357         
358 exit:
359         _exit_critical_bh(&free_queue->lock, &irqL);
360
361 _func_exit_;            
362
363         return pnetwork;        
364 }
365
366 void _rtw_free_network(struct   mlme_priv *pmlmepriv ,struct wlan_network *pnetwork, u8 isfreeall)
367 {
368         u32 delta_time;
369         u32 lifetime = SCANQUEUE_LIFETIME;
370         _irqL irqL;     
371         _queue *free_queue = &(pmlmepriv->free_bss_pool);
372         
373 _func_enter_;           
374
375         if (pnetwork == NULL)
376                 goto exit;
377
378         if (pnetwork->fixed == _TRUE)
379                 goto exit;
380
381         if ( (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE ) || 
382                 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE ) )
383                 lifetime = 1;
384
385         if(!isfreeall)
386         {
387                 delta_time = (u32) rtw_get_passing_time_ms(pnetwork->last_scanned);
388                 if(delta_time < lifetime)// unit:msec
389                         goto exit;
390         }
391
392         _enter_critical_bh(&free_queue->lock, &irqL);
393         
394         rtw_list_delete(&(pnetwork->list));
395
396         rtw_list_insert_tail(&(pnetwork->list),&(free_queue->queue));
397                 
398         pmlmepriv->num_of_scanned --;
399         
400
401         //DBG_871X("_rtw_free_network:SSID=%s\n", pnetwork->network.Ssid.Ssid);
402         
403         _exit_critical_bh(&free_queue->lock, &irqL);
404         
405 exit:           
406         
407 _func_exit_;                    
408
409 }
410
411 void _rtw_free_network_nolock(struct    mlme_priv *pmlmepriv, struct wlan_network *pnetwork)
412 {
413
414         _queue *free_queue = &(pmlmepriv->free_bss_pool);
415
416 _func_enter_;           
417
418         if (pnetwork == NULL)
419                 goto exit;
420
421         if (pnetwork->fixed == _TRUE)
422                 goto exit;
423
424         //_enter_critical(&free_queue->lock, &irqL);
425         
426         rtw_list_delete(&(pnetwork->list));
427
428         rtw_list_insert_tail(&(pnetwork->list), get_list_head(free_queue));
429                 
430         pmlmepriv->num_of_scanned --;
431         
432         //_exit_critical(&free_queue->lock, &irqL);
433         
434 exit:           
435
436 _func_exit_;                    
437
438 }
439
440
441 /*
442         return the wlan_network with the matching addr
443
444         Shall be calle under atomic context... to avoid possible racing condition...
445 */
446 struct wlan_network *_rtw_find_network(_queue *scanned_queue, u8 *addr)
447 {
448
449         //_irqL irqL;
450         _list   *phead, *plist;
451         struct  wlan_network *pnetwork = NULL;
452         u8 zero_addr[ETH_ALEN] = {0,0,0,0,0,0};
453         
454 _func_enter_;   
455
456         if(_rtw_memcmp(zero_addr, addr, ETH_ALEN)){
457                 pnetwork=NULL;
458                 goto exit;
459         }
460         
461         //_enter_critical_bh(&scanned_queue->lock, &irqL);
462         
463         phead = get_list_head(scanned_queue);
464         plist = get_next(phead);
465          
466         while (plist != phead)
467        {
468                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network ,list);
469
470                 if (_rtw_memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE)
471                         break;
472                 
473                 plist = get_next(plist);
474         }
475
476         if(plist == phead)
477                 pnetwork = NULL;
478
479         //_exit_critical_bh(&scanned_queue->lock, &irqL);
480         
481 exit:           
482         
483 _func_exit_;            
484
485         return pnetwork;
486         
487 }
488
489
490 void _rtw_free_network_queue(_adapter *padapter, u8 isfreeall)
491 {
492         _irqL irqL;
493         _list *phead, *plist;
494         struct wlan_network *pnetwork;
495         struct mlme_priv* pmlmepriv = &padapter->mlmepriv;
496         _queue *scanned_queue = &pmlmepriv->scanned_queue;
497
498 _func_enter_;   
499         
500
501         _enter_critical_bh(&scanned_queue->lock, &irqL);
502
503         phead = get_list_head(scanned_queue);
504         plist = get_next(phead);
505
506         while (rtw_end_of_queue_search(phead, plist) == _FALSE)
507         {
508
509                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
510
511                 plist = get_next(plist);
512
513                 _rtw_free_network(pmlmepriv,pnetwork, isfreeall);
514                 
515         }
516
517         _exit_critical_bh(&scanned_queue->lock, &irqL);
518         
519 _func_exit_;            
520
521 }
522
523
524
525
526 sint rtw_if_up(_adapter *padapter)      {
527
528         sint res;
529 _func_enter_;           
530
531         if (RTW_CANNOT_RUN(padapter) ||
532                 (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _FALSE)) {
533                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_if_up:bDriverStopped(%s) OR bSurpriseRemoved(%s)"
534                         , rtw_is_drv_stopped(padapter)?"True":"False"
535                         , rtw_is_surprise_removed(padapter)?"True":"False"));
536                 res=_FALSE;
537         }
538         else
539                 res=  _TRUE;
540         
541 _func_exit_;
542         return res;
543 }
544
545
546 void rtw_generate_random_ibss(u8* pibss)
547 {
548         *((u32 *)(&pibss[2])) = rtw_random32();
549         pibss[0] = 0x02; /* in ad-hoc mode local bit must set to 1 */
550         pibss[1] = 0x11;
551         pibss[2] = 0x87;
552 }
553
554 u8 *rtw_get_capability_from_ie(u8 *ie)
555 {
556         return (ie + 8 + 2);
557 }
558
559
560 u16 rtw_get_capability(WLAN_BSSID_EX *bss)
561 {
562         u16     val;
563 _func_enter_;   
564
565         _rtw_memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->IEs), 2); 
566
567 _func_exit_;            
568         return le16_to_cpu(val);
569 }
570
571 u8 *rtw_get_timestampe_from_ie(u8 *ie)
572 {
573         return (ie + 0);        
574 }
575
576 u8 *rtw_get_beacon_interval_from_ie(u8 *ie)
577 {
578         return (ie + 8);        
579 }
580
581
582 int     rtw_init_mlme_priv (_adapter *padapter)//(struct        mlme_priv *pmlmepriv)
583 {
584         int     res;
585 _func_enter_;   
586         res = _rtw_init_mlme_priv(padapter);// (pmlmepriv);
587 _func_exit_;    
588         return res;
589 }
590
591 void rtw_free_mlme_priv (struct mlme_priv *pmlmepriv)
592 {
593 _func_enter_;
594         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_mlme_priv\n"));
595         _rtw_free_mlme_priv (pmlmepriv);
596 _func_exit_;    
597 }
598
599 int     rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork);
600 int     rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork)
601 {
602         int     res;
603 _func_enter_;           
604         res = _rtw_enqueue_network(queue, pnetwork);
605 _func_exit_;            
606         return res;
607 }
608
609 /*
610 static struct   wlan_network *rtw_dequeue_network(_queue *queue)
611 {
612         struct wlan_network *pnetwork;
613 _func_enter_;           
614         pnetwork = _rtw_dequeue_network(queue);
615 _func_exit_;            
616         return pnetwork;
617 }
618 */
619
620 struct  wlan_network *rtw_alloc_network(struct  mlme_priv *pmlmepriv );
621 struct  wlan_network *rtw_alloc_network(struct  mlme_priv *pmlmepriv )//(_queue *free_queue)
622 {
623         struct  wlan_network    *pnetwork;
624 _func_enter_;                   
625         pnetwork = _rtw_alloc_network(pmlmepriv);
626 _func_exit_;                    
627         return pnetwork;
628 }
629
630 void rtw_free_network(struct mlme_priv *pmlmepriv, struct       wlan_network *pnetwork, u8 is_freeall);
631 void rtw_free_network(struct mlme_priv *pmlmepriv, struct       wlan_network *pnetwork, u8 is_freeall)//(struct wlan_network *pnetwork, _queue  *free_queue)
632 {
633 _func_enter_;           
634         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_network==> ssid = %s \n\n" , pnetwork->network.Ssid.Ssid));
635         _rtw_free_network(pmlmepriv, pnetwork, is_freeall);
636 _func_exit_;
637 }
638
639 void rtw_free_network_nolock(_adapter * padapter, struct wlan_network *pnetwork );
640 void rtw_free_network_nolock(_adapter * padapter, struct wlan_network *pnetwork )
641 {
642 _func_enter_;           
643         //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_network==> ssid = %s \n\n" , pnetwork->network.Ssid.Ssid));
644         _rtw_free_network_nolock(&(padapter->mlmepriv), pnetwork);
645 #ifdef CONFIG_IOCTL_CFG80211
646         rtw_cfg80211_unlink_bss(padapter, pnetwork);
647 #endif //CONFIG_IOCTL_CFG80211
648 _func_exit_;            
649 }
650
651
652 void rtw_free_network_queue(_adapter* dev, u8 isfreeall)
653 {
654 _func_enter_;           
655         _rtw_free_network_queue(dev, isfreeall);
656 _func_exit_;                    
657 }
658
659 /*
660         return the wlan_network with the matching addr
661
662         Shall be calle under atomic context... to avoid possible racing condition...
663 */
664 struct  wlan_network *rtw_find_network(_queue *scanned_queue, u8 *addr)
665 {
666         struct  wlan_network *pnetwork = _rtw_find_network(scanned_queue, addr);
667
668         return pnetwork;
669 }
670
671 int rtw_is_same_ibss(_adapter *adapter, struct wlan_network *pnetwork)
672 {
673         int ret=_TRUE;
674         struct security_priv *psecuritypriv = &adapter->securitypriv;
675
676         if ( (psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_ ) &&
677                     ( pnetwork->network.Privacy == 0 ) )
678         {
679                 ret=_FALSE;
680         }
681         else if((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_ ) &&
682                  ( pnetwork->network.Privacy == 1 ) )
683         {
684                 ret=_FALSE;
685         }
686         else
687         {
688                 ret=_TRUE;
689         }
690         
691         return ret;
692         
693 }
694
695 inline int is_same_ess(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b)
696 {
697         //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("(%s,%d)(%s,%d)\n",
698         //              a->Ssid.Ssid,a->Ssid.SsidLength,b->Ssid.Ssid,b->Ssid.SsidLength));
699         return (a->Ssid.SsidLength == b->Ssid.SsidLength) 
700                 &&  _rtw_memcmp(a->Ssid.Ssid, b->Ssid.Ssid, a->Ssid.SsidLength)==_TRUE;
701 }
702
703 int is_same_network(WLAN_BSSID_EX *src, WLAN_BSSID_EX *dst, u8 feature)
704 {
705          u16 s_cap, d_cap;
706          
707 _func_enter_;   
708
709         if(rtw_bug_check(dst, src, &s_cap, &d_cap)==_FALSE)
710                         return _FALSE;
711
712         _rtw_memcpy((u8 *)&s_cap, rtw_get_capability_from_ie(src->IEs), 2);
713         _rtw_memcpy((u8 *)&d_cap, rtw_get_capability_from_ie(dst->IEs), 2);
714
715         
716         s_cap = le16_to_cpu(s_cap);
717         d_cap = le16_to_cpu(d_cap);
718         
719 _func_exit_;                    
720
721 #ifdef CONFIG_P2P
722         if ((feature == 1) && // 1: P2P supported
723                 (_rtw_memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN) == _TRUE)
724                 ) {
725                 return _TRUE;
726         }
727 #endif
728
729         return ((src->Ssid.SsidLength == dst->Ssid.SsidLength) &&
730                 //      (src->Configuration.DSConfig == dst->Configuration.DSConfig) &&
731                         ( (_rtw_memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN)) == _TRUE) &&
732                         ( (_rtw_memcmp(src->Ssid.Ssid, dst->Ssid.Ssid, src->Ssid.SsidLength)) == _TRUE) &&
733                         ((s_cap & WLAN_CAPABILITY_IBSS) == 
734                         (d_cap & WLAN_CAPABILITY_IBSS)) &&
735                         ((s_cap & WLAN_CAPABILITY_BSS) == 
736                         (d_cap & WLAN_CAPABILITY_BSS)));
737         
738 }
739
740 struct wlan_network *_rtw_find_same_network(_queue *scanned_queue, struct wlan_network *network)
741 {
742         _list *phead, *plist;
743         struct wlan_network *found = NULL;
744
745         phead = get_list_head(scanned_queue);
746         plist = get_next(phead);
747
748         while (plist != phead) {
749                 found = LIST_CONTAINOR(plist, struct wlan_network ,list);
750
751                 if (is_same_network(&network->network, &found->network,0))
752                         break;
753
754                 plist = get_next(plist);
755         }
756
757         if(plist == phead)
758                 found = NULL;
759 exit:           
760         return found;
761 }
762
763 struct wlan_network *rtw_find_same_network(_queue *scanned_queue, struct wlan_network *network)
764 {
765         _irqL irqL;
766         struct wlan_network *found = NULL;
767
768         if (scanned_queue == NULL || network == NULL)
769                 goto exit;      
770
771         _enter_critical_bh(&scanned_queue->lock, &irqL);
772         found = _rtw_find_same_network(scanned_queue, network);
773         _exit_critical_bh(&scanned_queue->lock, &irqL);
774
775 exit:
776         return found;
777 }
778
779 struct  wlan_network    * rtw_get_oldest_wlan_network(_queue *scanned_queue)
780 {
781         _list   *plist, *phead;
782
783         
784         struct  wlan_network    *pwlan = NULL;
785         struct  wlan_network    *oldest = NULL;
786 _func_enter_;           
787         phead = get_list_head(scanned_queue);
788         
789         plist = get_next(phead);
790
791         while(1)
792         {
793                 
794                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
795                         break;
796                 
797                 pwlan= LIST_CONTAINOR(plist, struct wlan_network, list);
798
799                 if(pwlan->fixed!=_TRUE)
800                 {               
801                         if (oldest == NULL ||time_after(oldest->last_scanned, pwlan->last_scanned))
802                                 oldest = pwlan;
803                 }
804                 
805                 plist = get_next(plist);
806         }
807 _func_exit_;            
808         return oldest;
809         
810 }
811
812 void update_network(WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src,
813         _adapter * padapter, bool update_ie)
814 {
815         u8 ss_ori = dst->PhyInfo.SignalStrength;
816         u8 sq_ori = dst->PhyInfo.SignalQuality;
817         long rssi_ori = dst->Rssi;
818
819         u8 ss_smp = src->PhyInfo.SignalStrength;
820         u8 sq_smp = src->PhyInfo.SignalQuality;
821         long rssi_smp = src->Rssi;
822
823         u8 ss_final;
824         u8 sq_final;
825         long rssi_final;
826
827 _func_enter_;           
828
829 #ifdef CONFIG_ANTENNA_DIVERSITY
830         rtw_hal_antdiv_rssi_compared(padapter, dst, src); //this will update src.Rssi, need consider again
831 #endif
832
833         #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1
834         if(strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
835                 DBG_871X(FUNC_ADPT_FMT" %s("MAC_FMT", ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n"
836                         , FUNC_ADPT_ARG(padapter)
837                         , src->Ssid.Ssid, MAC_ARG(src->MacAddress), src->Configuration.DSConfig
838                         ,ss_ori, sq_ori, rssi_ori
839                         ,ss_smp, sq_smp, rssi_smp
840                 );
841         }
842         #endif
843
844         /* The rule below is 1/5 for sample value, 4/5 for history value */
845         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src, 0)) {
846                 /* Take the recvpriv's value for the connected AP*/
847                 ss_final = padapter->recvpriv.signal_strength;
848                 sq_final = padapter->recvpriv.signal_qual;
849                 /* the rssi value here is undecorated, and will be used for antenna diversity */
850                 if(sq_smp != 101) /* from the right channel */
851                         rssi_final = (src->Rssi+dst->Rssi*4)/5;
852                 else
853                         rssi_final = rssi_ori;
854         }
855         else {
856                 if(sq_smp != 101) { /* from the right channel */
857                         ss_final = ((u32)(src->PhyInfo.SignalStrength)+(u32)(dst->PhyInfo.SignalStrength)*4)/5;
858                         sq_final = ((u32)(src->PhyInfo.SignalQuality)+(u32)(dst->PhyInfo.SignalQuality)*4)/5;
859                         rssi_final = (src->Rssi+dst->Rssi*4)/5;
860                 } else {
861                         /* bss info not receving from the right channel, use the original RX signal infos */
862                         ss_final = dst->PhyInfo.SignalStrength;
863                         sq_final = dst->PhyInfo.SignalQuality;
864                         rssi_final = dst->Rssi;
865                 }
866                 
867         }
868
869         if (update_ie) {
870                 dst->Reserved[0] = src->Reserved[0];
871                 dst->Reserved[1] = src->Reserved[1];
872                 _rtw_memcpy((u8 *)dst, (u8 *)src, get_WLAN_BSSID_EX_sz(src));
873         }
874
875         dst->PhyInfo.SignalStrength = ss_final;
876         dst->PhyInfo.SignalQuality = sq_final;
877         dst->Rssi = rssi_final;
878
879         #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1
880         if(strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
881                 DBG_871X(FUNC_ADPT_FMT" %s("MAC_FMT"), SignalStrength:%u, SignalQuality:%u, RawRSSI:%ld\n"
882                         , FUNC_ADPT_ARG(padapter)
883                         , dst->Ssid.Ssid, MAC_ARG(dst->MacAddress), dst->PhyInfo.SignalStrength, dst->PhyInfo.SignalQuality, dst->Rssi);
884         }
885         #endif
886
887 #if 0 // old codes, may be useful one day...
888 //      DBG_871X("update_network: rssi=0x%lx dst->Rssi=%d ,dst->Rssi=0x%lx , src->Rssi=0x%lx",(dst->Rssi+src->Rssi)/2,dst->Rssi,dst->Rssi,src->Rssi);
889         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src))
890         {
891         
892                 //DBG_871X("b:ssid=%s update_network: src->rssi=0x%d padapter->recvpriv.ui_rssi=%d\n",src->Ssid.Ssid,src->Rssi,padapter->recvpriv.signal);
893                 if(padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX)
894                 {
895                       padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX;
896                       last_evm = padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index];
897                       padapter->recvpriv.signal_qual_data.total_val -= last_evm;
898                 }
899                 padapter->recvpriv.signal_qual_data.total_val += query_rx_pwr_percentage(src->Rssi);
900
901                 padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index++] = query_rx_pwr_percentage(src->Rssi);
902                 if(padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX)
903                        padapter->recvpriv.signal_qual_data.index = 0;
904
905                 //DBG_871X("Total SQ=%d  pattrib->signal_qual= %d\n", padapter->recvpriv.signal_qual_data.total_val, src->Rssi);
906
907                 // <1> Showed on UI for user,in percentage.
908                 tmpVal = padapter->recvpriv.signal_qual_data.total_val/padapter->recvpriv.signal_qual_data.total_num;
909                 padapter->recvpriv.signal=(u8)tmpVal;//Link quality
910
911                 src->Rssi= translate_percentage_to_dbm(padapter->recvpriv.signal) ;
912         }
913         else{
914 //      DBG_871X("ELSE:ssid=%s update_network: src->rssi=0x%d dst->rssi=%d\n",src->Ssid.Ssid,src->Rssi,dst->Rssi);
915                 src->Rssi=(src->Rssi +dst->Rssi)/2;//dBM
916         }       
917
918 //      DBG_871X("a:update_network: src->rssi=0x%d padapter->recvpriv.ui_rssi=%d\n",src->Rssi,padapter->recvpriv.signal);
919
920 #endif
921
922 _func_exit_;            
923 }
924
925 static void update_current_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork)
926 {
927         struct  mlme_priv       *pmlmepriv = &(adapter->mlmepriv);
928         
929 _func_enter_;           
930
931         rtw_bug_check(&(pmlmepriv->cur_network.network), 
932                 &(pmlmepriv->cur_network.network), 
933                 &(pmlmepriv->cur_network.network), 
934                 &(pmlmepriv->cur_network.network));
935
936         if ( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork, 0)))
937         {
938                 //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"Same Network\n");
939
940                 //if(pmlmepriv->cur_network.network.IELength<= pnetwork->IELength)
941                 {
942                         update_network(&(pmlmepriv->cur_network.network), pnetwork,adapter, _TRUE);
943                         rtw_update_protection(adapter, (pmlmepriv->cur_network.network.IEs) + sizeof (NDIS_802_11_FIXED_IEs), 
944                                                                         pmlmepriv->cur_network.network.IELength);
945                 }
946         }
947
948 _func_exit_;                    
949
950 }
951
952
953 /*
954
955 Caller must hold pmlmepriv->lock first.
956
957
958 */
959 void rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target)
960 {
961         _irqL irqL;
962         _list   *plist, *phead;
963         ULONG   bssid_ex_sz;
964         struct mlme_priv        *pmlmepriv = &(adapter->mlmepriv);
965         struct mlme_ext_priv    *pmlmeext = &(adapter->mlmeextpriv);
966 #ifdef CONFIG_P2P
967         struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
968 #endif // CONFIG_P2P
969         _queue  *queue  = &(pmlmepriv->scanned_queue);
970         struct wlan_network     *pnetwork = NULL;
971         struct wlan_network     *oldest = NULL;
972         int target_find = 0;
973         u8 feature = 0;    
974
975 _func_enter_;
976
977         _enter_critical_bh(&queue->lock, &irqL);
978         phead = get_list_head(queue);
979         plist = get_next(phead);
980
981 #ifdef CONFIG_P2P
982         if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
983                 feature = 1; // p2p enable
984 #endif
985
986         while(1)
987         {
988                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
989                         break;
990
991                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
992
993                 rtw_bug_check(pnetwork, pnetwork, pnetwork, pnetwork);
994
995 #ifdef CONFIG_P2P
996                 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
997                         (_rtw_memcmp(pnetwork->network.MacAddress, target->MacAddress, ETH_ALEN) == _TRUE))
998                 {
999                         target_find = 1;
1000                         break;
1001                 }
1002 #endif
1003
1004                 if (is_same_network(&(pnetwork->network), target, feature))
1005                 {
1006                         target_find = 1;
1007                         break;
1008                 }
1009
1010                 if (rtw_roam_flags(adapter)) {
1011                         /* TODO: don't  select netowrk in the same ess as oldest if it's new enough*/
1012                 }
1013
1014                 if (oldest == NULL || time_after(oldest->last_scanned, pnetwork->last_scanned))
1015                         oldest = pnetwork;
1016
1017                 plist = get_next(plist);
1018
1019         }
1020         
1021         
1022         /* If we didn't find a match, then get a new network slot to initialize
1023          * with this beacon's information */
1024         //if (rtw_end_of_queue_search(phead,plist)== _TRUE) {
1025         if (!target_find) {             
1026                 if (_rtw_queue_empty(&(pmlmepriv->free_bss_pool)) == _TRUE) {
1027                         /* If there are no more slots, expire the oldest */
1028                         //list_del_init(&oldest->list);
1029                         pnetwork = oldest;
1030                         if(pnetwork==NULL){ 
1031                                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n\n\nsomething wrong here\n\n\n"));
1032                                 goto exit;
1033                         }
1034 #ifdef CONFIG_ANTENNA_DIVERSITY
1035                         rtw_hal_get_odm_var(adapter, HAL_ODM_ANTDIV_SELECT, &(target->PhyInfo.Optimum_antenna), NULL);
1036 #endif
1037                         _rtw_memcpy(&(pnetwork->network), target,  get_WLAN_BSSID_EX_sz(target));
1038                         //pnetwork->last_scanned = rtw_get_current_time();
1039                         // variable initialize
1040                         pnetwork->fixed = _FALSE;
1041                         pnetwork->last_scanned = rtw_get_current_time();
1042
1043                         pnetwork->network_type = 0;     
1044                         pnetwork->aid=0;                
1045                         pnetwork->join_res=0;
1046
1047                         /* bss info not receving from the right channel */
1048                         if (pnetwork->network.PhyInfo.SignalQuality == 101)
1049                                 pnetwork->network.PhyInfo.SignalQuality = 0;
1050                 }
1051                 else {
1052                         /* Otherwise just pull from the free list */
1053
1054                         pnetwork = rtw_alloc_network(pmlmepriv); // will update scan_time
1055
1056                         if(pnetwork==NULL){ 
1057                                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n\n\nsomething wrong here\n\n\n"));
1058                                 goto exit;
1059                         }
1060
1061                         bssid_ex_sz = get_WLAN_BSSID_EX_sz(target);
1062                         target->Length = bssid_ex_sz;
1063 #ifdef CONFIG_ANTENNA_DIVERSITY
1064                         rtw_hal_get_odm_var(adapter, HAL_ODM_ANTDIV_SELECT, &(target->PhyInfo.Optimum_antenna), NULL);
1065 #endif
1066                         _rtw_memcpy(&(pnetwork->network), target, bssid_ex_sz );
1067
1068                         pnetwork->last_scanned = rtw_get_current_time();
1069
1070                         /* bss info not receving from the right channel */
1071                         if (pnetwork->network.PhyInfo.SignalQuality == 101)
1072                                 pnetwork->network.PhyInfo.SignalQuality = 0;
1073
1074                         rtw_list_insert_tail(&(pnetwork->list),&(queue->queue)); 
1075
1076                 }
1077         }
1078         else {
1079                 /* we have an entry and we are going to update it. But this entry may
1080                  * be already expired. In this case we do the same as we found a new 
1081                  * net and call the new_net handler
1082                  */
1083                 bool update_ie = _TRUE;
1084
1085                 pnetwork->last_scanned = rtw_get_current_time();
1086
1087                 //target.Reserved[0]==1, means that scaned network is a bcn frame.
1088                 if((pnetwork->network.IELength>target->IELength) && (target->Reserved[0]==1))
1089                         update_ie = _FALSE;
1090
1091                 // probe resp(3) > beacon(1) > probe req(2)
1092                 if ((target->Reserved[0] != 2) &&
1093                         (target->Reserved[0] >= pnetwork->network.Reserved[0])
1094                         ) {
1095                         update_ie = _TRUE;
1096                 }
1097                 else {
1098                         update_ie = _FALSE;
1099                 }
1100
1101                 update_network(&(pnetwork->network), target,adapter, update_ie);
1102         }
1103
1104 exit:
1105         _exit_critical_bh(&queue->lock, &irqL);
1106
1107 _func_exit_;
1108 }
1109
1110 void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork);
1111 void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork)
1112 {
1113         _irqL irqL;
1114         struct  mlme_priv       *pmlmepriv = &(((_adapter *)adapter)->mlmepriv);
1115         //_queue        *queue  = &(pmlmepriv->scanned_queue);
1116
1117 _func_enter_;           
1118
1119         //_enter_critical_bh(&queue->lock, &irqL);
1120
1121         #if defined(CONFIG_P2P) && defined(CONFIG_P2P_REMOVE_GROUP_INFO)
1122         if (adapter->registrypriv.wifi_spec == 0)
1123                 rtw_bss_ex_del_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO);
1124         #endif
1125         
1126         if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
1127                 rtw_bss_ex_del_wfd_ie(pnetwork);
1128
1129         update_current_network(adapter, pnetwork);
1130         
1131         rtw_update_scanned_network(adapter, pnetwork);
1132
1133         //_exit_critical_bh(&queue->lock, &irqL);
1134         
1135 _func_exit_;            
1136 }
1137
1138 //select the desired network based on the capability of the (i)bss.
1139 // check items: (1) security
1140 //                         (2) network_type
1141 //                         (3) WMM
1142 //                         (4) HT
1143 //                     (5) others
1144 int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork);
1145 int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork)
1146 {
1147         struct security_priv *psecuritypriv = &adapter->securitypriv;
1148         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1149         u32 desired_encmode;
1150         u32 privacy;
1151
1152         //u8 wps_ie[512];
1153         uint wps_ielen;
1154
1155         int bselected = _TRUE;
1156         
1157         desired_encmode = psecuritypriv->ndisencryptstatus;
1158         privacy = pnetwork->network.Privacy;
1159
1160         if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
1161         {
1162                 if(rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen)!=NULL)
1163                 {
1164                         return _TRUE;
1165                 }
1166                 else
1167                 {       
1168                         return _FALSE;
1169                 }       
1170         }
1171         if (adapter->registrypriv.wifi_spec == 1) //for  correct flow of 8021X  to do....
1172         {
1173                 u8 *p=NULL;
1174                 uint ie_len=0;
1175
1176                 if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0))
1177                     bselected = _FALSE;
1178
1179                 if ( psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
1180                         p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_));
1181                         if (p && ie_len>0) {
1182                                 bselected = _TRUE;
1183                         } else {
1184                                 bselected = _FALSE;
1185                         }
1186                 }
1187         }
1188         
1189
1190         if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0)) {
1191                 DBG_871X("desired_encmode: %d, privacy: %d\n", desired_encmode, privacy);
1192                 bselected = _FALSE;
1193         }
1194
1195         if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
1196         {
1197                 if(pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
1198                         bselected = _FALSE;
1199         }       
1200                 
1201
1202         return bselected;
1203 }
1204
1205 /* TODO: Perry : For Power Management */
1206 void rtw_atimdone_event_callback(_adapter       *adapter , u8 *pbuf)
1207 {
1208
1209 _func_enter_;           
1210         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("receive atimdone_evet\n"));        
1211 _func_exit_;                    
1212         return; 
1213 }
1214
1215
1216 void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf)
1217 {
1218         _irqL  irqL;
1219         u32 len;
1220         WLAN_BSSID_EX *pnetwork;
1221         struct  mlme_priv       *pmlmepriv = &(adapter->mlmepriv);
1222
1223 _func_enter_;           
1224
1225         pnetwork = (WLAN_BSSID_EX *)pbuf;
1226
1227         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_survey_event_callback, ssid=%s\n",  pnetwork->Ssid.Ssid));
1228
1229 #ifdef CONFIG_RTL8712
1230         //endian_convert
1231         pnetwork->Length = le32_to_cpu(pnetwork->Length);
1232         pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength);     
1233         pnetwork->Privacy =le32_to_cpu( pnetwork->Privacy);
1234         pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi);
1235         pnetwork->NetworkTypeInUse =le32_to_cpu(pnetwork->NetworkTypeInUse);    
1236         pnetwork->Configuration.ATIMWindow = le32_to_cpu(pnetwork->Configuration.ATIMWindow);
1237         pnetwork->Configuration.BeaconPeriod = le32_to_cpu(pnetwork->Configuration.BeaconPeriod);
1238         pnetwork->Configuration.DSConfig =le32_to_cpu(pnetwork->Configuration.DSConfig);
1239         pnetwork->Configuration.FHConfig.DwellTime=le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime);
1240         pnetwork->Configuration.FHConfig.HopPattern=le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern);
1241         pnetwork->Configuration.FHConfig.HopSet=le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet);
1242         pnetwork->Configuration.FHConfig.Length=le32_to_cpu(pnetwork->Configuration.FHConfig.Length);   
1243         pnetwork->Configuration.Length = le32_to_cpu(pnetwork->Configuration.Length);
1244         pnetwork->InfrastructureMode = le32_to_cpu(pnetwork->InfrastructureMode);
1245         pnetwork->IELength = le32_to_cpu(pnetwork->IELength);
1246 #endif  
1247
1248         len = get_WLAN_BSSID_EX_sz(pnetwork);
1249         if(len > (sizeof(WLAN_BSSID_EX)))
1250         {
1251                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n ****rtw_survey_event_callback: return a wrong bss ***\n"));
1252                 return;
1253         }
1254
1255
1256         _enter_critical_bh(&pmlmepriv->lock, &irqL);
1257
1258         // update IBSS_network 's timestamp
1259         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE)
1260         {
1261                 //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"rtw_survey_event_callback : WIFI_ADHOC_MASTER_STATE \n\n");
1262                 if(_rtw_memcmp(&(pmlmepriv->cur_network.network.MacAddress), pnetwork->MacAddress, ETH_ALEN))
1263                 {
1264                         struct wlan_network* ibss_wlan = NULL;
1265                         _irqL   irqL;
1266                         
1267                         _rtw_memcpy(pmlmepriv->cur_network.network.IEs, pnetwork->IEs, 8);
1268                         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1269                         ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue,  pnetwork->MacAddress);
1270                         if(ibss_wlan)
1271                         {
1272                                 _rtw_memcpy(ibss_wlan->network.IEs , pnetwork->IEs, 8);                 
1273                                 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);             
1274                                 goto exit;
1275                         }
1276                         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1277                 }
1278         }
1279
1280         // lock pmlmepriv->lock when you accessing network_q
1281         if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == _FALSE)
1282         {               
1283                 if( pnetwork->Ssid.Ssid[0] == 0 )
1284                 {
1285                         pnetwork->Ssid.SsidLength = 0;
1286                 }       
1287                 rtw_add_network(adapter, pnetwork);
1288         }       
1289
1290 exit:   
1291                 
1292         _exit_critical_bh(&pmlmepriv->lock, &irqL);
1293
1294 _func_exit_;            
1295
1296         return; 
1297 }
1298
1299 void rtw_surveydone_event_callback(_adapter     *adapter, u8 *pbuf)
1300 {
1301         _irqL  irqL;
1302         u8 timer_cancelled;
1303         struct  mlme_priv       *pmlmepriv = &(adapter->mlmepriv);
1304
1305 #ifdef CONFIG_MLME_EXT
1306         mlmeext_surveydone_event_callback(adapter);
1307 #endif
1308
1309 _func_enter_;
1310
1311         _enter_critical_bh(&pmlmepriv->lock, &irqL);
1312         if (pmlmepriv->wps_probe_req_ie) {
1313                 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
1314                 pmlmepriv->wps_probe_req_ie_len = 0;
1315                 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
1316                 pmlmepriv->wps_probe_req_ie = NULL;
1317         }
1318
1319         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_surveydone_event_callback: fw_state:%x\n\n", get_fwstate(pmlmepriv)));
1320
1321         if (check_fwstate(pmlmepriv,_FW_UNDER_SURVEY) == _FALSE) {
1322                 DBG_871X(FUNC_ADPT_FMT" fw_state:0x%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
1323                 //rtw_warn_on(1);
1324         }
1325
1326         _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1327         _exit_critical_bh(&pmlmepriv->lock, &irqL);
1328
1329         _cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled);
1330
1331         _enter_critical_bh(&pmlmepriv->lock, &irqL);
1332
1333         #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
1334         rtw_set_signal_stat_timer(&adapter->recvpriv);
1335         #endif
1336
1337         if(pmlmepriv->to_join == _TRUE)
1338         {
1339                 if((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE) )
1340                 {
1341                         if(check_fwstate(pmlmepriv, _FW_LINKED)==_FALSE)
1342                         {
1343                                 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);      
1344                                 
1345                                 if(rtw_select_and_join_from_scanned_queue(pmlmepriv)==_SUCCESS)
1346                                 {
1347                                         _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
1348                                 }
1349                                 else
1350                                 {
1351                                         WLAN_BSSID_EX    *pdev_network = &(adapter->registrypriv.dev_network);                  
1352                                         u8 *pibss = adapter->registrypriv.dev_network.MacAddress;
1353
1354                                         //pmlmepriv->fw_state ^= _FW_UNDER_SURVEY;//because don't set assoc_timer
1355                                         _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1356
1357                                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("switching to adhoc master\n"));
1358                                 
1359                                         _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
1360                                         _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
1361         
1362                                         rtw_update_registrypriv_dev_network(adapter);
1363                                         rtw_generate_random_ibss(pibss);
1364
1365         
1366                                         pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
1367                         
1368                                         if (rtw_create_ibss_cmd(adapter, 0) != _SUCCESS)
1369                                                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("Error=>rtw_create_ibss_cmd status FAIL\n"));
1370
1371                                         pmlmepriv->to_join = _FALSE;
1372                                 }
1373                         }
1374                 }
1375                 else
1376                 {
1377                         int s_ret;
1378                         set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
1379                         pmlmepriv->to_join = _FALSE;
1380                         if(_SUCCESS == (s_ret=rtw_select_and_join_from_scanned_queue(pmlmepriv)))
1381                         {
1382                              _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);      
1383                         }
1384                         else if(s_ret == 2)//there is no need to wait for join
1385                         {
1386                                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1387                                 rtw_indicate_connect(adapter);
1388                         }
1389                         else
1390                         {
1391                                 DBG_871X("try_to_join, but select scanning queue fail, to_roam:%d\n", rtw_to_roam(adapter));
1392
1393                                 if (rtw_to_roam(adapter) != 0) {
1394                                         if(rtw_dec_to_roam(adapter) == 0
1395                                                 || _SUCCESS != rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)
1396                                         ) {
1397                                                 rtw_set_to_roam(adapter, 0);
1398 #ifdef CONFIG_INTEL_WIDI
1399                                                 if(adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING)
1400                                                 {
1401                                                         _rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN);
1402                                                         intel_widi_wk_cmd(adapter, INTEL_WIDI_LISTEN_WK, NULL, 0);
1403                                                         DBG_871X("change to widi listen\n");
1404                                                 }
1405 #endif // CONFIG_INTEL_WIDI
1406                                                 rtw_free_assoc_resources(adapter, 1);
1407                                                 rtw_indicate_disconnect(adapter);
1408                                         } else {
1409                                                 pmlmepriv->to_join = _TRUE;
1410                                         }
1411                                 }
1412                                 else
1413                                 {
1414                                         rtw_indicate_disconnect(adapter);
1415                                 }
1416                                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1417                         }
1418                 }
1419         } else {
1420                 if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) {
1421                         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
1422                                 && check_fwstate(pmlmepriv, _FW_LINKED))
1423                         {
1424                                 if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) {
1425                                         receive_disconnect(adapter, pmlmepriv->cur_network.network.MacAddress
1426                                                 , WLAN_REASON_ACTIVE_ROAM);
1427                                 }
1428                         }
1429                 }
1430         }
1431         
1432         //DBG_871X("scan complete in %dms\n",rtw_get_passing_time_ms(pmlmepriv->scan_start_time));
1433
1434         _exit_critical_bh(&pmlmepriv->lock, &irqL);
1435
1436 #ifdef CONFIG_P2P_PS
1437         if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
1438                 p2p_ps_wk_cmd(adapter, P2P_PS_SCAN_DONE, 0);
1439         }
1440 #endif // CONFIG_P2P_PS
1441
1442         rtw_os_xmit_schedule(adapter);
1443 #ifdef CONFIG_CONCURRENT_MODE   
1444         rtw_os_xmit_schedule(adapter->pbuddy_adapter);
1445 #endif
1446
1447 #ifdef CONFIG_DRVEXT_MODULE_WSC
1448         drvext_surveydone_callback(&adapter->drvextpriv);
1449 #endif
1450
1451 #ifdef DBG_CONFIG_ERROR_DETECT
1452         {
1453                 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;         
1454                 if(pmlmeext->sitesurvey_res.bss_cnt == 0){
1455                         //rtw_hal_sreset_reset(adapter);
1456                 }
1457         }
1458 #endif
1459
1460 #ifdef CONFIG_IOCTL_CFG80211
1461         rtw_cfg80211_surveydone_event_callback(adapter);
1462 #endif //CONFIG_IOCTL_CFG80211
1463
1464         rtw_indicate_scan_done(adapter, _FALSE);
1465
1466 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_IOCTL_CFG80211)
1467         if (adapter->pbuddy_adapter) {
1468                 _adapter *buddy_adapter = adapter->pbuddy_adapter;
1469                 struct mlme_priv *buddy_mlme = &(buddy_adapter->mlmepriv);
1470                 struct rtw_wdev_priv *buddy_wdev_priv = adapter_wdev_data(buddy_adapter);
1471                 bool indicate_buddy_scan = _FALSE;
1472
1473                 _enter_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
1474                 if (buddy_wdev_priv->scan_request && buddy_mlme->scanning_via_buddy_intf == _TRUE) {
1475                         buddy_mlme->scanning_via_buddy_intf = _FALSE;
1476                         clr_fwstate(buddy_mlme, _FW_UNDER_SURVEY);
1477                         indicate_buddy_scan = _TRUE;
1478                 }
1479                 _exit_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
1480
1481                 if (indicate_buddy_scan == _TRUE) {
1482                         #ifdef CONFIG_IOCTL_CFG80211
1483                         rtw_cfg80211_surveydone_event_callback(buddy_adapter);
1484                         #endif
1485                         rtw_indicate_scan_done(buddy_adapter, _FALSE);
1486                 }
1487         }
1488 #endif /* CONFIG_CONCURRENT_MODE */
1489
1490 _func_exit_;    
1491
1492 }
1493
1494 void rtw_dummy_event_callback(_adapter *adapter , u8 *pbuf)
1495 {
1496
1497 }
1498
1499 void rtw_fwdbg_event_callback(_adapter *adapter , u8 *pbuf)
1500 {
1501
1502 }
1503
1504 static void free_scanqueue(struct       mlme_priv *pmlmepriv)
1505 {
1506         _irqL irqL, irqL0;
1507         _queue *free_queue = &pmlmepriv->free_bss_pool;
1508         _queue *scan_queue = &pmlmepriv->scanned_queue;
1509         _list   *plist, *phead, *ptemp;
1510         
1511 _func_enter_;           
1512         
1513         RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+free_scanqueue\n"));
1514         _enter_critical_bh(&scan_queue->lock, &irqL0);
1515         _enter_critical_bh(&free_queue->lock, &irqL);
1516
1517         phead = get_list_head(scan_queue);
1518         plist = get_next(phead);
1519
1520         while (plist != phead)
1521        {
1522                 ptemp = get_next(plist);
1523                 rtw_list_delete(plist);
1524                 rtw_list_insert_tail(plist, &free_queue->queue);
1525                 plist =ptemp;
1526                 pmlmepriv->num_of_scanned --;
1527         }
1528         
1529         _exit_critical_bh(&free_queue->lock, &irqL);
1530         _exit_critical_bh(&scan_queue->lock, &irqL0);
1531         
1532 _func_exit_;
1533 }
1534
1535 void rtw_reset_rx_info(struct debug_priv *pdbgpriv){
1536         pdbgpriv->dbg_rx_ampdu_drop_count = 0;
1537         pdbgpriv->dbg_rx_ampdu_forced_indicate_count = 0;
1538         pdbgpriv->dbg_rx_ampdu_loss_count = 0;
1539         pdbgpriv->dbg_rx_dup_mgt_frame_drop_count = 0;
1540         pdbgpriv->dbg_rx_ampdu_window_shift_cnt = 0;
1541 }
1542         
1543 /*
1544 *rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock
1545 */
1546 void rtw_free_assoc_resources(_adapter *adapter, int lock_scanned_queue)
1547 {
1548         _irqL irqL;
1549         struct wlan_network* pwlan = NULL;
1550         struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
1551         struct  sta_priv *pstapriv = &adapter->stapriv;
1552         struct wlan_network *tgt_network = &pmlmepriv->cur_network;
1553         struct dvobj_priv *psdpriv = adapter->dvobj;
1554         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;        
1555
1556         
1557 #ifdef CONFIG_TDLS
1558         struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
1559 #endif //CONFIG_TDLS
1560 _func_enter_;                   
1561
1562         RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_free_assoc_resources\n"));
1563         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("tgt_network->network.MacAddress="MAC_FMT" ssid=%s\n",
1564                 MAC_ARG(tgt_network->network.MacAddress), tgt_network->network.Ssid.Ssid));
1565
1566         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1567                 struct sta_info* psta;
1568                 
1569                 psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress);
1570
1571 #ifdef CONFIG_TDLS
1572                 if (ptdlsinfo->link_established == _TRUE) {
1573                         rtw_tdls_cmd(adapter, NULL, TDLS_RS_RCR);
1574                         rtw_reset_tdls_info(adapter);
1575                         rtw_free_all_stainfo(adapter);
1576                         //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
1577                 }
1578                 else
1579 #endif //CONFIG_TDLS
1580                 {
1581                         //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
1582                         rtw_free_stainfo(adapter,  psta);
1583                 }
1584
1585                 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
1586                 
1587         }
1588
1589         if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) {
1590                 struct sta_info* psta;
1591         
1592                 rtw_free_all_stainfo(adapter);
1593
1594                 psta = rtw_get_bcmc_stainfo(adapter);
1595                 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);                
1596                 rtw_free_stainfo(adapter, psta);
1597                 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);         
1598
1599                 rtw_init_bcmc_stainfo(adapter); 
1600         }
1601
1602         if(lock_scanned_queue)
1603                 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1604         
1605         pwlan = _rtw_find_same_network(&pmlmepriv->scanned_queue, tgt_network);
1606         if(pwlan)               
1607         {
1608                 pwlan->fixed = _FALSE;
1609
1610                 DBG_871X("free disconnecting network\n");
1611                 rtw_free_network_nolock(adapter, pwlan);
1612 #ifdef CONFIG_P2P
1613                 if(!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE))
1614                 {
1615                         rtw_set_scan_deny(adapter, 2000);
1616                         //rtw_clear_scan_deny(adapter);                 
1617                 }
1618 #endif //CONFIG_P2P
1619         }       
1620         else
1621         {
1622                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_assoc_resources : pwlan== NULL \n\n"));
1623         }
1624
1625
1626         if((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) && (adapter->stapriv.asoc_sta_count== 1))
1627                 /*||check_fwstate(pmlmepriv, WIFI_STATION_STATE)*/)
1628         {
1629                 if (pwlan)
1630                         rtw_free_network_nolock(adapter, pwlan);
1631         }
1632
1633         if(lock_scanned_queue)
1634                 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1635         
1636         adapter->securitypriv.key_mask = 0;
1637
1638         rtw_reset_rx_info(pdbgpriv);
1639
1640 _func_exit_;    
1641         
1642 }
1643
1644 /*
1645 *rtw_indicate_connect: the caller has to lock pmlmepriv->lock
1646 */
1647 void rtw_indicate_connect(_adapter *padapter)
1648 {
1649         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
1650         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
1651         
1652 _func_enter_;
1653
1654         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("+rtw_indicate_connect\n"));
1655  
1656         pmlmepriv->to_join = _FALSE;
1657
1658         if(!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) 
1659         {
1660
1661                 set_fwstate(pmlmepriv, _FW_LINKED);
1662
1663                 rtw_led_control(padapter, LED_CTL_LINK);
1664
1665         
1666 #ifdef CONFIG_DRVEXT_MODULE
1667                 if(padapter->drvextpriv.enable_wpa)
1668                 {
1669                         indicate_l2_connect(padapter);
1670                 }
1671                 else
1672 #endif
1673                 {
1674                         rtw_os_indicate_connect(padapter);
1675                 }
1676
1677         }
1678
1679         rtw_set_to_roam(padapter, 0);
1680 #ifdef CONFIG_INTEL_WIDI
1681         if(padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING)
1682         {
1683                 _rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN);
1684                 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_WK, NULL, 0);
1685                 DBG_871X("change to widi listen\n");
1686         }
1687 #endif // CONFIG_INTEL_WIDI
1688
1689         rtw_set_scan_deny(padapter, 3000);
1690
1691         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("-rtw_indicate_connect: fw_state=0x%08x\n", get_fwstate(pmlmepriv)));
1692  
1693 _func_exit_;
1694
1695 }
1696
1697
1698 /*
1699 *rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock
1700 */
1701 void rtw_indicate_disconnect( _adapter *padapter )
1702 {
1703         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;     
1704         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1705         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1706         WLAN_BSSID_EX   *cur_network = &(pmlmeinfo->network);
1707         struct sta_info *psta;
1708         struct sta_priv *pstapriv = &padapter->stapriv;
1709         u8 *wps_ie=NULL;
1710         uint wpsie_len=0;
1711
1712 _func_enter_;   
1713         
1714         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("+rtw_indicate_disconnect\n"));
1715
1716         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS);
1717
1718         // force to clear cur_network_scanned's SELECTED REGISTRAR
1719         if (pmlmepriv->cur_network_scanned) {
1720                 WLAN_BSSID_EX   *current_joined_bss = &(pmlmepriv->cur_network_scanned->network);
1721                 if (current_joined_bss) {
1722                         wps_ie=rtw_get_wps_ie(current_joined_bss->IEs +_FIXED_IE_LENGTH_,
1723                                 current_joined_bss->IELength-_FIXED_IE_LENGTH_, NULL, &wpsie_len);
1724                         if (wps_ie && wpsie_len>0) {
1725                                 u8 *attr = NULL;
1726                                 u32 attr_len;
1727                                 attr=rtw_get_wps_attr(wps_ie, wpsie_len, WPS_ATTR_SELECTED_REGISTRAR,
1728                                                        NULL, &attr_len);
1729                                 if (attr)
1730                                         *(attr + 4) = 0;
1731                         }
1732                 }
1733         }
1734         //DBG_871X("clear wps when %s\n", __func__);
1735
1736         if(rtw_to_roam(padapter) > 0)
1737                 _clr_fwstate_(pmlmepriv, _FW_LINKED);
1738
1739 #ifdef CONFIG_WAPI_SUPPORT
1740         psta = rtw_get_stainfo(pstapriv,cur_network->MacAddress);
1741         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1742         {
1743                 rtw_wapi_return_one_sta_info(padapter, psta->hwaddr);
1744         }
1745         else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
1746                 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
1747         {
1748                 rtw_wapi_return_all_sta_info(padapter);
1749         }
1750 #endif
1751
1752         if(check_fwstate(&padapter->mlmepriv, _FW_LINKED) 
1753                 || (rtw_to_roam(padapter) <= 0)
1754         )
1755         {
1756                 rtw_os_indicate_disconnect(padapter);
1757
1758                 //set ips_deny_time to avoid enter IPS before LPS leave
1759                 rtw_set_ips_deny(padapter, 3000);
1760
1761               _clr_fwstate_(pmlmepriv, _FW_LINKED);
1762
1763                 rtw_led_control(padapter, LED_CTL_NO_LINK);
1764
1765                 rtw_clear_scan_deny(padapter);
1766         }
1767
1768 #ifdef CONFIG_P2P_PS
1769         p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
1770 #endif // CONFIG_P2P_PS
1771
1772 #ifdef CONFIG_LPS
1773         rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1);
1774 #endif
1775
1776 #ifdef CONFIG_BEAMFORMING
1777         beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_LEAVE, cur_network->MacAddress, ETH_ALEN, 1);
1778 #endif /*CONFIG_BEAMFORMING*/
1779
1780 _func_exit_;    
1781 }
1782
1783 inline void rtw_indicate_scan_done( _adapter *padapter, bool aborted)
1784 {
1785         DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
1786
1787         rtw_os_indicate_scan_done(padapter, aborted);
1788
1789 #ifdef CONFIG_IPS
1790         if (is_primary_adapter(padapter)
1791                 && (_FALSE == adapter_to_pwrctl(padapter)->bInSuspend)
1792                 && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE|WIFI_UNDER_LINKING) == _FALSE))
1793         {
1794                 struct pwrctrl_priv *pwrpriv;
1795
1796                 pwrpriv = adapter_to_pwrctl(padapter);
1797                 rtw_set_ips_deny(padapter, 0);
1798 #ifdef CONFIG_IPS_CHECK_IN_WD
1799                 _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 1);
1800 #else // !CONFIG_IPS_CHECK_IN_WD
1801                 _rtw_set_pwr_state_check_timer(pwrpriv, 1);
1802 #endif // !CONFIG_IPS_CHECK_IN_WD
1803         }
1804 #endif // CONFIG_IPS
1805 }
1806
1807 static u32 _rtw_wait_scan_done(_adapter *adapter, u8 abort, u32 timeout_ms)
1808 {
1809         u32 start;
1810         u32 pass_ms;
1811         struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
1812         struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
1813
1814         start = rtw_get_current_time();
1815         
1816         pmlmeext->scan_abort = abort;
1817         
1818         while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)
1819                 && rtw_get_passing_time_ms(start) <= timeout_ms) {
1820
1821                 if (RTW_CANNOT_RUN(adapter))
1822                         break;
1823
1824                 DBG_871X(FUNC_NDEV_FMT"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev));
1825                 rtw_msleep_os(20);
1826         }
1827
1828         if (_TRUE == abort) {
1829                 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
1830                         if (!RTW_CANNOT_RUN(adapter))
1831                                 DBG_871X(FUNC_NDEV_FMT"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter->pnetdev));
1832                         #ifdef CONFIG_PLATFORM_MSTAR
1833                         /*_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);*/
1834                         set_survey_timer(pmlmeext, 0);
1835                         mlme_set_scan_to_timer(pmlmepriv, 50);
1836                         #endif
1837                         rtw_indicate_scan_done(adapter, _TRUE);
1838                 }
1839         }
1840         
1841         pmlmeext->scan_abort = _FALSE;
1842         pass_ms = rtw_get_passing_time_ms(start);
1843
1844         return pass_ms;
1845
1846 }
1847
1848 void rtw_scan_wait_completed(_adapter *adapter)
1849 {
1850         u32 scan_to = SCANNING_TIMEOUT;
1851
1852 #ifdef CONFIG_SCAN_BACKOP
1853         if (IsSupported5G(adapter->registrypriv.wireless_mode) 
1854                 && IsSupported24G(adapter->registrypriv.wireless_mode)) /*dual band*/
1855                 scan_to = CONC_SCANNING_TIMEOUT_DUAL_BAND;
1856         else /*single band*/
1857                 scan_to = CONC_SCANNING_TIMEOUT_SINGLE_BAND;
1858 #endif /* CONFIG_SCAN_BACKOP */
1859
1860         _rtw_wait_scan_done(adapter, _FALSE, scan_to);
1861 }
1862
1863 u32 rtw_scan_abort_timeout(_adapter *adapter, u32 timeout_ms)
1864 {
1865         return _rtw_wait_scan_done(adapter, _TRUE, timeout_ms);
1866 }
1867
1868 void rtw_scan_abort_no_wait(_adapter *adapter)
1869 {
1870         struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
1871         struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
1872
1873         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1874                 pmlmeext->scan_abort = _TRUE;
1875 }
1876
1877 void rtw_scan_abort(_adapter *adapter)
1878 {
1879         rtw_scan_abort_timeout(adapter, 200);
1880 }
1881
1882 static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wlan_network *pnetwork)
1883 {
1884         int i;
1885         struct sta_info *bmc_sta, *psta=NULL;
1886         struct recv_reorder_ctrl *preorder_ctrl;
1887         struct sta_priv *pstapriv = &padapter->stapriv;
1888         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1889
1890         psta = rtw_get_stainfo(pstapriv, pnetwork->network.MacAddress);
1891         if(psta==NULL) {
1892                 psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.MacAddress);
1893         }
1894
1895         if(psta) //update ptarget_sta
1896         {
1897                 DBG_871X("%s\n", __FUNCTION__);
1898         
1899                 psta->aid  = pnetwork->join_res;
1900
1901 #if 0 //alloc macid when call rtw_alloc_stainfo(), and release macid when call rtw_free_stainfo()
1902 #ifdef CONFIG_CONCURRENT_MODE   
1903
1904                 if(PRIMARY_ADAPTER == padapter->adapter_type)
1905                         psta->mac_id=0;
1906                 else
1907                         psta->mac_id=2;
1908 #else
1909                 psta->mac_id=0;
1910 #endif
1911 #endif //removed
1912
1913                 update_sta_info(padapter, psta);
1914
1915                 //update station supportRate
1916                 psta->bssratelen = rtw_get_rateset_len(pnetwork->network.SupportedRates);
1917                 _rtw_memcpy(psta->bssrateset, pnetwork->network.SupportedRates, psta->bssratelen);
1918                 rtw_hal_update_sta_rate_mask(padapter, psta);
1919
1920                 psta->wireless_mode = pmlmeext->cur_wireless_mode;
1921                 psta->raid = rtw_hal_networktype_to_raid(padapter,psta);
1922
1923
1924                 //sta mode
1925                 rtw_hal_set_odm_var(padapter,HAL_ODM_STA_INFO,psta,_TRUE);
1926
1927                 //security related
1928                 if(padapter->securitypriv.dot11AuthAlgrthm== dot11AuthAlgrthm_8021X)
1929                 {                                               
1930                         padapter->securitypriv.binstallGrpkey=_FALSE;
1931                         padapter->securitypriv.busetkipkey=_FALSE;                                              
1932                         padapter->securitypriv.bgrpkey_handshake=_FALSE;
1933
1934                         psta->ieee8021x_blocked=_TRUE;
1935                         psta->dot118021XPrivacy=padapter->securitypriv.dot11PrivacyAlgrthm;
1936                                                 
1937                         _rtw_memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof (union Keytype));
1938                                                 
1939                         _rtw_memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof (union Keytype));
1940                         _rtw_memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof (union Keytype));
1941                                                 
1942                         _rtw_memset((u8 *)&psta->dot11txpn, 0, sizeof (union pn48));
1943                         psta->dot11txpn.val = psta->dot11txpn.val + 1;
1944 #ifdef CONFIG_IEEE80211W
1945                         _rtw_memset((u8 *)&psta->dot11wtxpn, 0, sizeof (union pn48));
1946 #endif //CONFIG_IEEE80211W
1947                         _rtw_memset((u8 *)&psta->dot11rxpn, 0, sizeof (union pn48));    
1948                 }
1949
1950                 //      Commented by Albert 2012/07/21
1951                 //      When doing the WPS, the wps_ie_len won't equal to 0
1952                 //      And the Wi-Fi driver shouldn't allow the data packet to be tramsmitted.
1953                 if ( padapter->securitypriv.wps_ie_len != 0 )
1954                 {
1955                         psta->ieee8021x_blocked=_TRUE;
1956                         padapter->securitypriv.wps_ie_len = 0;
1957                 }
1958
1959
1960                 //for A-MPDU Rx reordering buffer control for bmc_sta & sta_info
1961                 //if A-MPDU Rx is enabled, reseting  rx_ordering_ctrl wstart_b(indicate_seq) to default value=0xffff
1962                 //todo: check if AP can send A-MPDU packets
1963                 for(i=0; i < 16 ; i++)
1964                 {
1965                         //preorder_ctrl = &precvpriv->recvreorder_ctrl[i];
1966                         preorder_ctrl = &psta->recvreorder_ctrl[i];
1967                         preorder_ctrl->enable = _FALSE;
1968                         preorder_ctrl->indicate_seq = 0xffff;
1969                         #ifdef DBG_RX_SEQ
1970                         DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
1971                                 preorder_ctrl->indicate_seq);
1972                         #endif
1973                         preorder_ctrl->wend_b= 0xffff;
1974                         preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32
1975                         preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
1976                 }
1977
1978                 
1979                 bmc_sta = rtw_get_bcmc_stainfo(padapter);
1980                 if(bmc_sta)
1981                 {
1982                         for(i=0; i < 16 ; i++)
1983                         {
1984                                 //preorder_ctrl = &precvpriv->recvreorder_ctrl[i];
1985                                 preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
1986                                 preorder_ctrl->enable = _FALSE;
1987                                 preorder_ctrl->indicate_seq = 0xffff;
1988                                 #ifdef DBG_RX_SEQ
1989                                 DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
1990                                         preorder_ctrl->indicate_seq);
1991                                 #endif
1992                                 preorder_ctrl->wend_b= 0xffff;
1993                                 preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32
1994                                 preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
1995                         }
1996                 }
1997         }
1998                                         
1999         return psta;
2000         
2001 }
2002
2003 //pnetwork : returns from rtw_joinbss_event_callback
2004 //ptarget_wlan: found from scanned_queue
2005 static void rtw_joinbss_update_network(_adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network  *pnetwork)
2006 {
2007         struct mlme_priv        *pmlmepriv = &(padapter->mlmepriv);     
2008         struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
2009
2010         DBG_871X("%s\n", __FUNCTION__);
2011         
2012         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\nfw_state:%x, BSSID:"MAC_FMT"\n"
2013                 ,get_fwstate(pmlmepriv), MAC_ARG(pnetwork->network.MacAddress)));
2014
2015                                 
2016         // why not use ptarget_wlan??
2017         _rtw_memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.Length);
2018         // some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs
2019         cur_network->network.IELength = ptarget_wlan->network.IELength;
2020         _rtw_memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0], MAX_IE_SZ);
2021
2022         cur_network->aid = pnetwork->join_res;
2023
2024                                 
2025 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
2026         rtw_set_signal_stat_timer(&padapter->recvpriv);
2027 #endif
2028         padapter->recvpriv.signal_strength = ptarget_wlan->network.PhyInfo.SignalStrength;
2029         padapter->recvpriv.signal_qual = ptarget_wlan->network.PhyInfo.SignalQuality;
2030         //the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled)
2031         padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength);
2032         #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
2033                 DBG_871X(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u"
2034                         "\n"
2035                         , FUNC_ADPT_ARG(padapter)
2036                         , padapter->recvpriv.signal_strength
2037                         , padapter->recvpriv.rssi
2038                         , padapter->recvpriv.signal_qual
2039         );
2040         #endif
2041 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
2042         rtw_set_signal_stat_timer(&padapter->recvpriv);
2043 #endif
2044                                 
2045         //update fw_state //will clr _FW_UNDER_LINKING here indirectly
2046         switch(pnetwork->network.InfrastructureMode)
2047         {       
2048                 case Ndis802_11Infrastructure:                                          
2049                         
2050                                 if(pmlmepriv->fw_state&WIFI_UNDER_WPS)
2051                                         pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS;
2052                                 else
2053                                         pmlmepriv->fw_state = WIFI_STATION_STATE;
2054                                 
2055                                 break;
2056                 case Ndis802_11IBSS:            
2057                                 pmlmepriv->fw_state = WIFI_ADHOC_STATE;
2058                                 break;
2059                 default:
2060                                 pmlmepriv->fw_state = WIFI_NULL_STATE;
2061                                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Invalid network_mode\n"));
2062                                 break;
2063         }
2064
2065         rtw_update_protection(padapter, (cur_network->network.IEs) + sizeof (NDIS_802_11_FIXED_IEs), 
2066                                                                         (cur_network->network.IELength));
2067
2068 #ifdef CONFIG_80211N_HT                 
2069         rtw_update_ht_cap(padapter, cur_network->network.IEs, cur_network->network.IELength, (u8) cur_network->network.Configuration.DSConfig);
2070 #endif
2071 }
2072
2073 //Notes: the fucntion could be > passive_level (the same context as Rx tasklet)
2074 //pnetwork : returns from rtw_joinbss_event_callback
2075 //ptarget_wlan: found from scanned_queue
2076 //if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if  "ptarget_sta" & "ptarget_wlan" exist.       
2077 //if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist.
2078 //if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan !=NULL).
2079 //
2080 //#define REJOIN
2081 void rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf)
2082 {
2083         _irqL irqL,irqL2;
2084         static u8 retry=0;
2085         u8 timer_cancelled;
2086         struct sta_info *ptarget_sta= NULL, *pcur_sta = NULL;
2087         struct  sta_priv *pstapriv = &adapter->stapriv;
2088         struct  mlme_priv       *pmlmepriv = &(adapter->mlmepriv);
2089         struct wlan_network     *pnetwork       = (struct wlan_network *)pbuf;
2090         struct wlan_network     *cur_network = &(pmlmepriv->cur_network);
2091         struct wlan_network     *pcur_wlan = NULL, *ptarget_wlan = NULL;
2092         unsigned int            the_same_macaddr = _FALSE;      
2093
2094 _func_enter_;   
2095
2096 #ifdef CONFIG_RTL8712
2097        //endian_convert
2098         pnetwork->join_res = le32_to_cpu(pnetwork->join_res);
2099         pnetwork->network_type = le32_to_cpu(pnetwork->network_type);
2100         pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length);
2101         pnetwork->network.Ssid.SsidLength = le32_to_cpu(pnetwork->network.Ssid.SsidLength);
2102         pnetwork->network.Privacy =le32_to_cpu( pnetwork->network.Privacy);
2103         pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi);
2104         pnetwork->network.NetworkTypeInUse =le32_to_cpu(pnetwork->network.NetworkTypeInUse) ;   
2105         pnetwork->network.Configuration.ATIMWindow = le32_to_cpu(pnetwork->network.Configuration.ATIMWindow);
2106         pnetwork->network.Configuration.BeaconPeriod = le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod);
2107         pnetwork->network.Configuration.DSConfig = le32_to_cpu(pnetwork->network.Configuration.DSConfig);
2108         pnetwork->network.Configuration.FHConfig.DwellTime=le32_to_cpu(pnetwork->network.Configuration.FHConfig.DwellTime);
2109         pnetwork->network.Configuration.FHConfig.HopPattern=le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopPattern);
2110         pnetwork->network.Configuration.FHConfig.HopSet=le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet);
2111         pnetwork->network.Configuration.FHConfig.Length=le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length);   
2112         pnetwork->network.Configuration.Length = le32_to_cpu(pnetwork->network.Configuration.Length);
2113         pnetwork->network.InfrastructureMode = le32_to_cpu(pnetwork->network.InfrastructureMode);
2114         pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength );
2115 #endif
2116
2117         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("joinbss event call back received with res=%d\n", pnetwork->join_res));
2118
2119         rtw_get_encrypt_decrypt_from_registrypriv(adapter);
2120         
2121
2122         if (pmlmepriv->assoc_ssid.SsidLength == 0)
2123         {
2124                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("@@@@@   joinbss event call back  for Any SSid\n"));                
2125         }
2126         else
2127         {
2128                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("@@@@@   rtw_joinbss_event_callback for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid));
2129         }
2130         
2131         the_same_macaddr = _rtw_memcmp(pnetwork->network.MacAddress, cur_network->network.MacAddress, ETH_ALEN);
2132
2133         pnetwork->network.Length = get_WLAN_BSSID_EX_sz(&pnetwork->network);
2134         if(pnetwork->network.Length > sizeof(WLAN_BSSID_EX))
2135         {
2136                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n\n ***joinbss_evt_callback return a wrong bss ***\n\n"));
2137                 goto ignore_joinbss_callback;
2138         }
2139                 
2140         _enter_critical_bh(&pmlmepriv->lock, &irqL);
2141         
2142         pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
2143         pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
2144         
2145         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\n rtw_joinbss_event_callback !! _enter_critical \n"));
2146
2147         if(pnetwork->join_res > 0)
2148         {
2149                 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2150                 retry = 0;
2151                 if (check_fwstate(pmlmepriv,_FW_UNDER_LINKING) )
2152                 {
2153                         //s1. find ptarget_wlan
2154                         if(check_fwstate(pmlmepriv, _FW_LINKED) )
2155                         {
2156                                 if(the_same_macaddr == _TRUE)
2157                                 {
2158                                         ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);                                    
2159                                 }
2160                                 else
2161                                 {
2162                                         pcur_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
2163                                         if(pcur_wlan)   pcur_wlan->fixed = _FALSE;
2164
2165                                         pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
2166                                         if(pcur_sta){
2167                                                 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2);
2168                                                 rtw_free_stainfo(adapter,  pcur_sta);
2169                                                 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2);
2170                                         }
2171
2172                                         ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
2173                                         if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE){
2174                                                 if(ptarget_wlan)        ptarget_wlan->fixed = _TRUE;                    
2175                                         }
2176                                 }
2177
2178                         }
2179                         else
2180                         {
2181                                 ptarget_wlan = _rtw_find_same_network(&pmlmepriv->scanned_queue, pnetwork);
2182                                 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE){
2183                                         if(ptarget_wlan)        ptarget_wlan->fixed = _TRUE;                    
2184                                 }
2185                         }
2186                 
2187                         //s2. update cur_network 
2188                         if(ptarget_wlan)
2189                         {                       
2190                                 rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork);
2191                         }
2192                         else
2193                         {                       
2194                                 DBG_871X_LEVEL(_drv_always_, "Can't find ptarget_wlan when joinbss_event callback\n");
2195                                 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2196                                 goto ignore_joinbss_callback;
2197                         }
2198                                         
2199                         
2200                         //s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode 
2201                         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
2202                                 ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork);
2203                                 if (ptarget_sta == NULL) {
2204                                         DBG_871X_LEVEL(_drv_err_, "Can't update stainfo when joinbss_event callback\n");
2205                                         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2206                                         goto ignore_joinbss_callback;
2207                                 }
2208                         }
2209
2210                         //s4. indicate connect                  
2211                         if (MLME_IS_STA(adapter) || MLME_IS_ADHOC(adapter)) {
2212                                 pmlmepriv->cur_network_scanned = ptarget_wlan;
2213                                 rtw_indicate_connect(adapter);
2214                         }
2215                                 
2216                         //s5. Cancle assoc_timer                                        
2217                         _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled);
2218                 
2219                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("Cancle assoc_timer \n"));         
2220                 
2221                 }
2222                 else
2223                 {
2224                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_joinbss_event_callback err: fw_state:%x", get_fwstate(pmlmepriv)));    
2225                         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2226                         goto ignore_joinbss_callback;
2227                 }
2228                 
2229                 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);     
2230                                 
2231         }
2232         else if(pnetwork->join_res == -4) 
2233         {
2234                 rtw_reset_securitypriv(adapter);
2235                 _set_timer(&pmlmepriv->assoc_timer, 1);                                 
2236
2237                 //rtw_free_assoc_resources(adapter, 1);
2238
2239                 if((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == _TRUE)
2240                 {               
2241                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n", get_fwstate(pmlmepriv)));
2242                         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
2243                 }       
2244                 
2245         }
2246         else //if join_res < 0 (join fails), then try again
2247         {
2248         
2249                 #ifdef REJOIN
2250                 res = _FAIL;
2251                 if(retry < 2) {
2252                         res = rtw_select_and_join_from_scanned_queue(pmlmepriv);
2253                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_select_and_join_from_scanned_queue again! res:%d\n",res));
2254                 }
2255
2256                  if(res == _SUCCESS)
2257                 {
2258                         //extend time of assoc_timer
2259                         _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
2260                         retry++;
2261                 }
2262                 else if(res == 2)//there is no need to wait for join
2263                 {
2264                         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
2265                         rtw_indicate_connect(adapter);
2266                 }       
2267                 else
2268                 {
2269                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Set Assoc_Timer = 1; can't find match ssid in scanned_q \n"));
2270                 #endif
2271                         
2272                         _set_timer(&pmlmepriv->assoc_timer, 1);
2273                         //rtw_free_assoc_resources(adapter, 1);
2274                         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
2275                         
2276                 #ifdef REJOIN
2277                         retry = 0;      
2278                 }
2279                 #endif
2280         }
2281
2282 ignore_joinbss_callback:
2283
2284         _exit_critical_bh(&pmlmepriv->lock, &irqL);
2285         _func_exit_;    
2286 }
2287
2288 void rtw_joinbss_event_callback(_adapter *adapter, u8 *pbuf)
2289 {
2290         struct wlan_network     *pnetwork       = (struct wlan_network *)pbuf;
2291
2292 _func_enter_;
2293
2294         mlmeext_joinbss_event_callback(adapter, pnetwork->join_res);
2295
2296         rtw_os_xmit_schedule(adapter);
2297
2298 #ifdef CONFIG_CONCURRENT_MODE   
2299         rtw_os_xmit_schedule(adapter->pbuddy_adapter);
2300 #endif  
2301
2302 _func_exit_;
2303 }
2304
2305 void rtw_sta_media_status_rpt(_adapter *adapter, struct sta_info *sta, bool connected)
2306 {
2307         struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
2308         bool miracast_enabled = 0;
2309         bool miracast_sink = 0;
2310         u8 role = H2C_MSR_ROLE_RSVD;
2311
2312         if (sta == NULL) {
2313                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" sta is NULL\n"
2314                         , FUNC_ADPT_ARG(adapter));
2315                 rtw_warn_on(1);
2316                 return;
2317         }
2318
2319         if (sta->mac_id >= macid_ctl->num) {
2320                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" invalid macid:%u\n"
2321                         , FUNC_ADPT_ARG(adapter), sta->mac_id);
2322                 rtw_warn_on(1);
2323                 return;
2324         }
2325
2326         if (!rtw_macid_is_used(macid_ctl, sta->mac_id)) {
2327                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" macid:%u not is used, set connected to 0\n"
2328                         , FUNC_ADPT_ARG(adapter), sta->mac_id);
2329                 connected = 0;
2330                 rtw_warn_on(1);
2331         }
2332
2333         if (connected && !rtw_macid_is_bmc(macid_ctl, sta->mac_id)) {
2334                 miracast_enabled = STA_OP_WFD_MODE(sta) != 0 && is_miracast_enabled(adapter);
2335                 miracast_sink = miracast_enabled && (STA_OP_WFD_MODE(sta) & MIRACAST_SINK);
2336
2337                 #ifdef CONFIG_TDLS
2338                 if (sta->tdls_sta_state & TDLS_LINKED_STATE)
2339                         role = H2C_MSR_ROLE_TDLS;
2340                 else
2341                 #endif
2342                 if (MLME_IS_STA(adapter)) {
2343                         if (MLME_IS_GC(adapter))
2344                                 role = H2C_MSR_ROLE_GO;
2345                         else
2346                                 role = H2C_MSR_ROLE_AP;
2347                 } else if (MLME_IS_AP(adapter)) {
2348                         if (MLME_IS_GO(adapter))
2349                                 role = H2C_MSR_ROLE_GC;
2350                         else
2351                                 role = H2C_MSR_ROLE_STA;
2352                 } else if (MLME_IS_ADHOC(adapter) || MLME_IS_ADHOC_MASTER(adapter))
2353                         role = H2C_MSR_ROLE_ADHOC;
2354
2355                 #ifdef CONFIG_WFD
2356                 if (role == H2C_MSR_ROLE_GC
2357                         || role == H2C_MSR_ROLE_GO
2358                         || role == H2C_MSR_ROLE_TDLS
2359                 ) {
2360                         if (adapter->wfd_info.rtsp_ctrlport
2361                                 || adapter->wfd_info.tdls_rtsp_ctrlport
2362                                 || adapter->wfd_info.peer_rtsp_ctrlport)
2363                                 rtw_wfd_st_switch(sta, 1);
2364                 }
2365                 #endif
2366         }
2367
2368         rtw_hal_set_FwMediaStatusRpt_single_cmd(adapter
2369                 , connected
2370                 , miracast_enabled
2371                 , miracast_sink
2372                 , role
2373                 , sta->mac_id
2374         );
2375 }
2376
2377 u8 rtw_sta_media_status_rpt_cmd(_adapter *adapter, struct sta_info *sta, bool connected)
2378 {
2379         struct cmd_priv *cmdpriv = &adapter->cmdpriv;
2380         struct cmd_obj *cmdobj;
2381         struct drvextra_cmd_parm *cmd_parm;
2382         struct sta_media_status_rpt_cmd_parm *rpt_parm;
2383         u8      res = _SUCCESS;
2384
2385         cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
2386         if (cmdobj == NULL) {
2387                 res = _FAIL;
2388                 goto exit;
2389         }
2390
2391         cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
2392         if (cmd_parm == NULL) {
2393                 rtw_mfree((u8 *)cmdobj, sizeof(struct cmd_obj));
2394                 res = _FAIL;
2395                 goto exit;
2396         }
2397
2398         rpt_parm = (struct sta_media_status_rpt_cmd_parm *)rtw_zmalloc(sizeof(struct sta_media_status_rpt_cmd_parm));
2399         if (rpt_parm == NULL) {
2400                 rtw_mfree((u8 *)cmdobj, sizeof(struct cmd_obj));
2401                 rtw_mfree((u8 *)cmd_parm, sizeof(struct drvextra_cmd_parm));
2402                 res = _FAIL;
2403                 goto exit;
2404         }
2405
2406         rpt_parm->sta = sta;
2407         rpt_parm->connected = connected;
2408
2409         cmd_parm->ec_id = STA_MSTATUS_RPT_WK_CID;
2410         cmd_parm->type = 0;
2411         cmd_parm->size = sizeof(struct sta_media_status_rpt_cmd_parm);
2412         cmd_parm->pbuf = (u8 *)rpt_parm;
2413         init_h2fwcmd_w_parm_no_rsp(cmdobj, cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2414
2415         res = rtw_enqueue_cmd(cmdpriv, cmdobj);
2416
2417 exit:
2418         return res;
2419 }
2420
2421 inline void rtw_sta_media_status_rpt_cmd_hdl(_adapter *adapter, struct sta_media_status_rpt_cmd_parm *parm)
2422 {
2423         rtw_sta_media_status_rpt(adapter, parm->sta, parm->connected);
2424 }
2425
2426 void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf)
2427 {
2428         _irqL irqL;     
2429         struct sta_info *psta;
2430         struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
2431         struct stassoc_event    *pstassoc       = (struct stassoc_event*)pbuf;
2432         struct wlan_network     *cur_network = &(pmlmepriv->cur_network);
2433         struct wlan_network     *ptarget_wlan = NULL;
2434         
2435 _func_enter_;   
2436         
2437         if(rtw_access_ctrl(adapter, pstassoc->macaddr) == _FALSE)
2438                 return;
2439
2440 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
2441         if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
2442         {
2443                 psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);   
2444                 if(psta)
2445                 {               
2446                         u8 *passoc_req = NULL;
2447                         u32 assoc_req_len = 0;
2448                 
2449                         rtw_sta_media_status_rpt(adapter, psta, 1);
2450                 
2451 #ifndef CONFIG_AUTO_AP_MODE
2452
2453                         ap_sta_info_defer_update(adapter, psta);
2454
2455                         //report to upper layer 
2456                         DBG_871X("indicate_sta_assoc_event to upper layer - hostapd\n");
2457 #ifdef CONFIG_IOCTL_CFG80211
2458                         _enter_critical_bh(&psta->lock, &irqL);
2459                         if(psta->passoc_req && psta->assoc_req_len>0)
2460                         {                               
2461                                 passoc_req = rtw_zmalloc(psta->assoc_req_len);
2462                                 if(passoc_req)
2463                                 {
2464                                         assoc_req_len = psta->assoc_req_len;
2465                                         _rtw_memcpy(passoc_req, psta->passoc_req, assoc_req_len);
2466                                         
2467                                         rtw_mfree(psta->passoc_req , psta->assoc_req_len);
2468                                         psta->passoc_req = NULL;
2469                                         psta->assoc_req_len = 0;
2470                                 }
2471                         }                       
2472                         _exit_critical_bh(&psta->lock, &irqL);
2473
2474                         if(passoc_req && assoc_req_len>0)
2475                         {
2476                                 rtw_cfg80211_indicate_sta_assoc(adapter, passoc_req, assoc_req_len);
2477
2478                                 rtw_mfree(passoc_req, assoc_req_len);
2479                         }                       
2480 #else //!CONFIG_IOCTL_CFG80211  
2481                         rtw_indicate_sta_assoc_event(adapter, psta);
2482 #endif //!CONFIG_IOCTL_CFG80211
2483 #endif //!CONFIG_AUTO_AP_MODE
2484
2485 #ifdef CONFIG_BEAMFORMING
2486                         beamforming_wk_cmd(adapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
2487 #endif/*CONFIG_BEAMFORMING*/
2488                 }               
2489                 goto exit;
2490         }       
2491 #endif //defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
2492
2493         /* for AD-HOC mode */
2494         psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
2495         if (psta == NULL) {
2496                 DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" get no sta_info with "MAC_FMT"\n"
2497                         , FUNC_ADPT_ARG(adapter), MAC_ARG(pstassoc->macaddr));
2498                 rtw_warn_on(1);
2499                 goto exit;
2500         }
2501
2502         rtw_hal_set_odm_var(adapter,HAL_ODM_STA_INFO,psta,_TRUE);
2503
2504         rtw_sta_media_status_rpt(adapter, psta, 1);
2505         
2506         if(adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)
2507                 psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm;
2508         
2509
2510         psta->ieee8021x_blocked = _FALSE;               
2511         
2512         _enter_critical_bh(&pmlmepriv->lock, &irqL);
2513
2514         if ( (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE ) || 
2515                 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE ) )
2516         {
2517                 if(adapter->stapriv.asoc_sta_count== 2)
2518                 {
2519                         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2520                         ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
2521                         pmlmepriv->cur_network_scanned = ptarget_wlan;
2522                         if(ptarget_wlan)        ptarget_wlan->fixed = _TRUE;
2523                         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2524                         // a sta + bc/mc_stainfo (not Ibss_stainfo)
2525                         rtw_indicate_connect(adapter);
2526                 }
2527         }
2528
2529         _exit_critical_bh(&pmlmepriv->lock, &irqL);
2530
2531
2532         mlmeext_sta_add_event_callback(adapter, psta);
2533         
2534 #ifdef CONFIG_RTL8711
2535         //submit SetStaKey_cmd to tell fw, fw will allocate an CAM entry for this sta   
2536         rtw_setstakey_cmd(adapter, psta, GROUP_KEY, _TRUE);
2537 #endif
2538                 
2539 exit:
2540         
2541 _func_exit_;    
2542
2543 }
2544
2545 #ifdef CONFIG_IEEE80211W
2546 void rtw_sta_timeout_event_callback(_adapter *adapter, u8 *pbuf)
2547 {
2548         _irqL irqL;
2549         struct sta_info *psta;
2550         struct stadel_event *pstadel = (struct stadel_event *)pbuf;
2551         struct sta_priv *pstapriv = &adapter->stapriv;
2552         
2553 _func_enter_;
2554         
2555         psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr);
2556
2557         if (psta) {
2558                 u8 updated = _FALSE;
2559                 
2560                 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2561                 if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
2562                         rtw_list_delete(&psta->asoc_list);
2563                         pstapriv->asoc_list_cnt--;
2564                         updated = ap_free_sta(adapter, psta, _TRUE, WLAN_REASON_PREV_AUTH_NOT_VALID, _TRUE);
2565                 }
2566                 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2567
2568                 associated_clients_update(adapter, updated, STA_INFO_UPDATE_ALL);
2569         }
2570
2571         
2572 _func_exit_;    
2573
2574 }
2575 #endif /* CONFIG_IEEE80211W */
2576
2577 void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf)
2578 {
2579         _irqL irqL,irqL2;
2580         int mac_id = (-1);
2581         struct sta_info *psta;
2582         struct wlan_network* pwlan = NULL;
2583         WLAN_BSSID_EX    *pdev_network=NULL;
2584         u8* pibss = NULL;
2585         struct  mlme_priv       *pmlmepriv = &(adapter->mlmepriv);
2586         struct  stadel_event *pstadel   = (struct stadel_event*)pbuf;
2587         struct  sta_priv *pstapriv = &adapter->stapriv;
2588         struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
2589         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
2590         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2591         struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
2592
2593 _func_enter_;   
2594         
2595         psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr);
2596         if(psta)
2597                 mac_id = psta->mac_id;
2598         else
2599                 mac_id = pstadel->mac_id;
2600
2601         DBG_871X("%s(mac_id=%d)=" MAC_FMT "\n", __func__, mac_id, MAC_ARG(pstadel->macaddr));
2602
2603         if (mac_id >= 0 && mac_id < macid_ctl->num) {
2604                 rtw_hal_set_FwMediaStatusRpt_single_cmd(adapter, 0, 0, 0, 0, mac_id);
2605                 /*
2606                  * For safety, prevent from keeping macid sleep.
2607                  * If we can sure all power mode enter/leave are paired,
2608                  * this check can be removed.
2609                  * Lucas@20131113
2610                  */
2611                 /* wakeup macid after disconnect. */
2612                 if (MLME_IS_STA(adapter))
2613                         rtw_hal_macid_wakeup(adapter, mac_id);
2614
2615                 if (psta)
2616                         rtw_wfd_st_switch(psta, 0);
2617         } else {
2618                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" invalid macid:%u\n"
2619                         , FUNC_ADPT_ARG(adapter), mac_id);
2620                 rtw_warn_on(1);
2621         }
2622
2623         //if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
2624         if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
2625         {
2626 #ifdef CONFIG_IOCTL_CFG80211
2627                 #ifdef COMPAT_KERNEL_RELEASE
2628
2629                 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
2630                 rtw_cfg80211_indicate_sta_disassoc(adapter, pstadel->macaddr, *(u16*)pstadel->rsvd);
2631                 #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
2632 #endif //CONFIG_IOCTL_CFG80211
2633
2634                 return;
2635         }
2636
2637
2638         mlmeext_sta_del_event_callback(adapter);
2639
2640         _enter_critical_bh(&pmlmepriv->lock, &irqL2);
2641
2642         if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) )
2643         {
2644                 u16 reason = *((unsigned short *)(pstadel->rsvd));
2645                 bool roam = _FALSE;
2646                 struct wlan_network *roam_target = NULL;
2647
2648                 #ifdef CONFIG_LAYER2_ROAMING
2649                 if(adapter->registrypriv.wifi_spec==1) {
2650                         roam = _FALSE;
2651                 } else if (reason == WLAN_REASON_EXPIRATION_CHK && rtw_chk_roam_flags(adapter, RTW_ROAM_ON_EXPIRED)) {
2652                         roam = _TRUE;
2653                 } else if (reason == WLAN_REASON_ACTIVE_ROAM && rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) {
2654                         roam = _TRUE;
2655                         roam_target = pmlmepriv->roam_network;
2656                 }
2657 #ifdef CONFIG_INTEL_WIDI
2658                 else if (adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_CONNECTED) {
2659                         roam = _TRUE;
2660                 }
2661 #endif // CONFIG_INTEL_WIDI
2662
2663                 if (roam == _TRUE) {
2664                         if (rtw_to_roam(adapter) > 0)
2665                                 rtw_dec_to_roam(adapter); /* this stadel_event is caused by roaming, decrease to_roam */
2666                         else if (rtw_to_roam(adapter) == 0)
2667                                 rtw_set_to_roam(adapter, adapter->registrypriv.max_roaming_times);
2668                 } else {
2669                         rtw_set_to_roam(adapter, 0);
2670                 }
2671                 #endif /* CONFIG_LAYER2_ROAMING */
2672
2673                 rtw_free_uc_swdec_pending_queue(adapter);
2674
2675                 rtw_free_assoc_resources(adapter, 1);
2676                 rtw_indicate_disconnect(adapter);
2677                 rtw_free_mlme_priv_ie_data(pmlmepriv);
2678
2679                 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2680                 // remove the network entry in scanned_queue
2681                 pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);   
2682                 if (pwlan) {                    
2683                         pwlan->fixed = _FALSE;
2684                         rtw_free_network_nolock(adapter, pwlan);
2685                 }
2686                 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2687
2688 #ifdef CONFIG_INTEL_WIDI
2689                 if (!rtw_to_roam(adapter))
2690                         process_intel_widi_disconnect(adapter, 1);
2691 #endif // CONFIG_INTEL_WIDI
2692
2693                 _rtw_roaming(adapter, roam_target);
2694         }
2695
2696         if ( check_fwstate(pmlmepriv,WIFI_ADHOC_MASTER_STATE) || 
2697               check_fwstate(pmlmepriv,WIFI_ADHOC_STATE))
2698         {
2699                 
2700                 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
2701                 rtw_free_stainfo(adapter,  psta);
2702                 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
2703                 
2704                 if(adapter->stapriv.asoc_sta_count== 1) //a sta + bc/mc_stainfo (not Ibss_stainfo)
2705                 { 
2706                         //rtw_indicate_disconnect(adapter);//removed@20091105
2707                         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2708                         //free old ibss network
2709                         //pwlan = rtw_find_network(&pmlmepriv->scanned_queue, pstadel->macaddr);
2710                         pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
2711                         if(pwlan)       
2712                         {
2713                                 pwlan->fixed = _FALSE;
2714                                 rtw_free_network_nolock(adapter, pwlan); 
2715                         }
2716                         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2717                         //re-create ibss
2718                         pdev_network = &(adapter->registrypriv.dev_network);                    
2719                         pibss = adapter->registrypriv.dev_network.MacAddress;
2720
2721                         _rtw_memcpy(pdev_network, &tgt_network->network, get_WLAN_BSSID_EX_sz(&tgt_network->network));
2722                         
2723                         _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
2724                         _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
2725         
2726                         rtw_update_registrypriv_dev_network(adapter);                   
2727
2728                         rtw_generate_random_ibss(pibss);
2729                         
2730                         if(check_fwstate(pmlmepriv,WIFI_ADHOC_STATE))
2731                         {
2732                                 set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
2733                                 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
2734                         }
2735
2736                         if (rtw_create_ibss_cmd(adapter, 0) != _SUCCESS)
2737                                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("***Error=>stadel_event_callback: rtw_create_ibss_cmd status FAIL***\n"));
2738
2739                 }
2740                 
2741         }
2742         
2743         _exit_critical_bh(&pmlmepriv->lock, &irqL2);
2744         
2745 _func_exit_;    
2746
2747 }
2748
2749
2750 void rtw_cpwm_event_callback(PADAPTER padapter, u8 *pbuf)
2751 {
2752 #ifdef CONFIG_LPS_LCLK
2753         struct reportpwrstate_parm *preportpwrstate;
2754 #endif
2755
2756 _func_enter_;
2757
2758         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("+rtw_cpwm_event_callback !!!\n"));
2759 #ifdef CONFIG_LPS_LCLK
2760         preportpwrstate = (struct reportpwrstate_parm*)pbuf;
2761         preportpwrstate->state |= (u8)(adapter_to_pwrctl(padapter)->cpwm_tog + 0x80);
2762         cpwm_int_hdl(padapter, preportpwrstate);
2763 #endif
2764
2765 _func_exit_;
2766
2767 }
2768
2769
2770 void rtw_wmm_event_callback(PADAPTER padapter, u8 *pbuf)
2771 {
2772 _func_enter_;
2773
2774         WMMOnAssocRsp(padapter);
2775
2776 _func_exit_;
2777
2778 }
2779
2780 /*
2781 * _rtw_join_timeout_handler - Timeout/faliure handler for CMD JoinBss
2782 * @adapter: pointer to _adapter structure
2783 */
2784 void _rtw_join_timeout_handler (_adapter *adapter)
2785 {
2786         _irqL irqL;
2787         struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
2788
2789 #if 0
2790         if (rtw_is_drv_stopped(adapter)) {
2791                 _rtw_up_sema(&pmlmepriv->assoc_terminate);
2792                 return;
2793         }
2794 #endif  
2795
2796 _func_enter_;           
2797
2798
2799         DBG_871X("%s, fw_state=%x\n", __FUNCTION__, get_fwstate(pmlmepriv));
2800         
2801         if (RTW_CANNOT_RUN(adapter))
2802                 return;
2803
2804         
2805         _enter_critical_bh(&pmlmepriv->lock, &irqL);
2806
2807         #ifdef CONFIG_LAYER2_ROAMING
2808         if (rtw_to_roam(adapter) > 0) { /* join timeout caused by roaming */
2809                 while(1) {
2810                         rtw_dec_to_roam(adapter);
2811                         if (rtw_to_roam(adapter) != 0) { /* try another */
2812                                 int do_join_r;
2813                                 DBG_871X("%s try another roaming\n", __FUNCTION__);
2814                                 if( _SUCCESS!=(do_join_r=rtw_do_join(adapter)) ) {
2815                                         DBG_871X("%s roaming do_join return %d\n", __FUNCTION__ ,do_join_r);
2816                                         continue;
2817                                 }
2818                                 break;
2819                         } else {
2820 #ifdef CONFIG_INTEL_WIDI
2821                                 if(adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING)
2822                                 {
2823                                         _rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN);
2824                                         intel_widi_wk_cmd(adapter, INTEL_WIDI_LISTEN_WK, NULL, 0);
2825                                         DBG_871X("change to widi listen\n");
2826                                 }
2827 #endif // CONFIG_INTEL_WIDI
2828                                 DBG_871X("%s We've try roaming but fail\n", __FUNCTION__);
2829                                 rtw_indicate_disconnect(adapter);
2830                                 break;
2831                         }
2832                 }
2833                 
2834         } else 
2835         #endif
2836         {
2837                 rtw_indicate_disconnect(adapter);
2838                 free_scanqueue(pmlmepriv);//???
2839
2840 #ifdef CONFIG_IOCTL_CFG80211
2841                 //indicate disconnect for the case that join_timeout and check_fwstate != FW_LINKED
2842                 rtw_cfg80211_indicate_disconnect(adapter);
2843 #endif //CONFIG_IOCTL_CFG80211
2844
2845         }
2846
2847         _exit_critical_bh(&pmlmepriv->lock, &irqL);
2848         
2849
2850 #ifdef CONFIG_DRVEXT_MODULE_WSC 
2851         drvext_assoc_fail_indicate(&adapter->drvextpriv);       
2852 #endif  
2853
2854         
2855 _func_exit_;
2856
2857 }
2858
2859 /*
2860 * rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey
2861 * @adapter: pointer to _adapter structure
2862 */
2863 void rtw_scan_timeout_handler (_adapter *adapter)
2864 {       
2865         _irqL irqL;
2866         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2867         DBG_871X(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
2868
2869         _enter_critical_bh(&pmlmepriv->lock, &irqL);
2870         
2871         _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
2872         
2873         _exit_critical_bh(&pmlmepriv->lock, &irqL);
2874         
2875 #ifdef CONFIG_IOCTL_CFG80211
2876         rtw_cfg80211_surveydone_event_callback(adapter);
2877 #endif //CONFIG_IOCTL_CFG80211
2878         
2879         rtw_indicate_scan_done(adapter, _TRUE);
2880
2881 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_IOCTL_CFG80211)
2882         if (adapter->pbuddy_adapter) {
2883                 _adapter *buddy_adapter = adapter->pbuddy_adapter;
2884                 struct mlme_priv *buddy_mlme = &(buddy_adapter->mlmepriv);
2885                 struct rtw_wdev_priv *buddy_wdev_priv = adapter_wdev_data(buddy_adapter);
2886                 bool indicate_buddy_scan = _FALSE;
2887
2888                 _enter_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
2889                 if (buddy_wdev_priv->scan_request && buddy_mlme->scanning_via_buddy_intf == _TRUE) {
2890                         buddy_mlme->scanning_via_buddy_intf = _FALSE;
2891                         clr_fwstate(buddy_mlme, _FW_UNDER_SURVEY);
2892                         indicate_buddy_scan = _TRUE;
2893                 }
2894                 _exit_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
2895
2896                 if (indicate_buddy_scan == _TRUE) {
2897                         rtw_indicate_scan_done(buddy_adapter, _TRUE);
2898                 }
2899         }
2900 #endif /* CONFIG_CONCURRENT_MODE */
2901 }
2902
2903 void rtw_mlme_reset_auto_scan_int(_adapter *adapter)
2904 {
2905         struct mlme_priv *mlme = &adapter->mlmepriv;
2906         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
2907         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2908
2909 #ifdef CONFIG_P2P
2910         if(!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) {
2911                 mlme->auto_scan_int_ms = 0; /* disabled */
2912                 goto exit;
2913         }
2914 #endif  
2915
2916 #ifdef CONFIG_TDLS
2917         if (adapter->tdlsinfo.link_established == _TRUE) {
2918                 mlme->auto_scan_int_ms = 0;
2919                 goto exit;
2920         }
2921 #endif
2922
2923         if(pmlmeinfo->VHT_enable) //disable auto scan when connect to 11AC AP
2924         {
2925                 mlme->auto_scan_int_ms = 0;
2926         }
2927         else if(adapter->registrypriv.wifi_spec && is_client_associated_to_ap(adapter) == _TRUE) {
2928                 mlme->auto_scan_int_ms = 60*1000;
2929 #ifdef CONFIG_LAYER2_ROAMING
2930         } else if(rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) {
2931                 if (check_fwstate(mlme, WIFI_STATION_STATE) && check_fwstate(mlme, _FW_LINKED))
2932                         mlme->auto_scan_int_ms = mlme->roam_scan_int_ms;
2933 #endif
2934         } else {
2935                 mlme->auto_scan_int_ms = 0; /* disabled */
2936         }
2937 exit:
2938         return;
2939 }
2940
2941 void rtw_drv_scan_by_self(_adapter *padapter)
2942 {
2943         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2944
2945         if (!padapter->registrypriv.wifi_spec) {
2946                 if (check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING)) == _TRUE) {
2947                         DBG_871X(FUNC_ADPT_FMT" _FW_UNDER_SURVEY|_FW_UNDER_LINKING\n", FUNC_ADPT_ARG(padapter));
2948                         goto exit;
2949                 }
2950                         
2951                 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE) {
2952                         DBG_871X(FUNC_ADPT_FMT" exit BusyTraffic\n", FUNC_ADPT_ARG(padapter));
2953                         goto exit;
2954                 }
2955         }
2956
2957 #ifdef CONFIG_CONCURRENT_MODE
2958         if (rtw_buddy_adapter_up(padapter)) {
2959                 if ((check_buddy_fwstate(padapter, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING)) == _TRUE) ||
2960                         (padapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)) {            
2961                                 DBG_871X(FUNC_ADPT_FMT", but buddy_intf is under scanning or linking or BusyTraffic\n", FUNC_ADPT_ARG(padapter));
2962                                 goto exit;
2963                 }
2964         }
2965 #endif
2966
2967         DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
2968
2969         rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
2970
2971 exit:
2972         return; 
2973 }
2974
2975 static void rtw_auto_scan_handler(_adapter *padapter)
2976 {
2977         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2978
2979         rtw_mlme_reset_auto_scan_int(padapter);
2980
2981         if (pmlmepriv->auto_scan_int_ms != 0
2982                 && rtw_get_passing_time_ms(pmlmepriv->scan_start_time) > pmlmepriv->auto_scan_int_ms) 
2983                 rtw_drv_scan_by_self(padapter);
2984         
2985 }
2986
2987 void rtw_dynamic_check_timer_handlder(_adapter *adapter)
2988 {
2989 #ifdef CONFIG_AP_MODE
2990         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2991 #endif //CONFIG_AP_MODE
2992         struct registry_priv *pregistrypriv = &adapter->registrypriv;
2993 #ifdef CONFIG_CONCURRENT_MODE   
2994         PADAPTER pbuddy_adapter = adapter->pbuddy_adapter;
2995 #endif
2996
2997         if(!adapter)
2998                 return; 
2999
3000         if (!rtw_is_hw_init_completed(adapter))
3001                 return;
3002
3003         if (RTW_CANNOT_RUN(adapter))
3004                 return;
3005
3006         
3007 #ifdef CONFIG_CONCURRENT_MODE
3008         if(pbuddy_adapter)
3009         {
3010                 if(adapter->net_closed == _TRUE && pbuddy_adapter->net_closed == _TRUE)
3011                 {
3012                         return;
3013                 }               
3014         }
3015         else
3016 #endif //CONFIG_CONCURRENT_MODE
3017         if(adapter->net_closed == _TRUE)
3018         {
3019                 return;
3020         }       
3021
3022 #ifdef CONFIG_BT_COEXIST
3023         if (is_primary_adapter(adapter)) {
3024                 if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
3025                         DBG_871X("IsBtDisabled=%d, IsBtControlLps=%d\n" , rtw_btcoex_IsBtDisabled(adapter) , rtw_btcoex_IsBtControlLps(adapter));
3026         }
3027 #endif
3028
3029 #ifdef CONFIG_LPS_LCLK_WD_TIMER /* to avoid leaving lps 32k frequently*/
3030         if ((adapter_to_pwrctl(adapter)->bFwCurrentInPSMode ==_TRUE )
3031 #ifdef CONFIG_BT_COEXIST
3032                 && (rtw_btcoex_IsBtControlLps(adapter) == _FALSE)
3033 #endif          
3034                 ) 
3035         {
3036                 u8 bEnterPS;    
3037                 
3038                 linked_status_chk(adapter, 1);  
3039                         
3040                 bEnterPS = traffic_status_watchdog(adapter, 1);
3041                 if(bEnterPS)
3042                 {
3043                         //rtw_lps_ctrl_wk_cmd(adapter, LPS_CTRL_ENTER, 1);
3044                         rtw_hal_dm_watchdog_in_lps(adapter);
3045                 }
3046                 else
3047                 {
3048                         //call rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1) in traffic_status_watchdog()
3049                 }
3050                         
3051         }
3052         else
3053 #endif //CONFIG_LPS_LCLK_WD_TIMER       
3054         {
3055                 if(is_primary_adapter(adapter))
3056                 {       
3057                         rtw_dynamic_chk_wk_cmd(adapter);                
3058                 }       
3059         }       
3060
3061         /* auto site survey */
3062         rtw_auto_scan_handler(adapter);
3063
3064 #ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
3065 #ifdef CONFIG_AP_MODE
3066         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3067         {
3068                 expire_timeout_chk(adapter);
3069         }       
3070 #endif
3071 #endif //!CONFIG_ACTIVE_KEEP_ALIVE_CHECK
3072
3073 #ifdef CONFIG_BR_EXT
3074
3075 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
3076         rcu_read_lock();
3077 #endif  // (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
3078
3079 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) 
3080         if( adapter->pnetdev->br_port 
3081 #else   // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
3082         if( rcu_dereference(adapter->pnetdev->rx_handler_data)
3083 #endif  // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
3084                 && (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) )
3085         {
3086                 // expire NAT2.5 entry
3087                 void nat25_db_expire(_adapter *priv);
3088                 nat25_db_expire(adapter);
3089
3090                 if (adapter->pppoe_connection_in_progress > 0) {
3091                         adapter->pppoe_connection_in_progress--;
3092                 }
3093                 
3094                 // due to rtw_dynamic_check_timer_handlder() is called every 2 seconds
3095                 if (adapter->pppoe_connection_in_progress > 0) {
3096                         adapter->pppoe_connection_in_progress--;
3097                 }
3098         }
3099
3100 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
3101         rcu_read_unlock();
3102 #endif  // (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
3103
3104 #endif  // CONFIG_BR_EXT
3105         
3106 }
3107
3108
3109 #ifdef CONFIG_SET_SCAN_DENY_TIMER
3110 inline bool rtw_is_scan_deny(_adapter *adapter)
3111 {
3112         struct mlme_priv *mlmepriv = &adapter->mlmepriv;
3113         return (ATOMIC_READ(&mlmepriv->set_scan_deny) != 0) ? _TRUE : _FALSE;
3114 }
3115
3116 inline void rtw_clear_scan_deny(_adapter *adapter)
3117 {
3118         struct mlme_priv *mlmepriv = &adapter->mlmepriv;
3119         ATOMIC_SET(&mlmepriv->set_scan_deny, 0);
3120         if (0)
3121                 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
3122 }
3123
3124 void rtw_set_scan_deny_timer_hdl(_adapter *adapter)
3125 {
3126         rtw_clear_scan_deny(adapter);
3127 }
3128
3129 void rtw_set_scan_deny(_adapter *adapter, u32 ms)
3130 {
3131         struct mlme_priv *mlmepriv = &adapter->mlmepriv;
3132 #ifdef CONFIG_CONCURRENT_MODE
3133         struct mlme_priv *b_mlmepriv;
3134 #endif
3135
3136         if (0)
3137                 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
3138         ATOMIC_SET(&mlmepriv->set_scan_deny, 1);
3139         _set_timer(&mlmepriv->set_scan_deny_timer, ms);
3140         
3141 #ifdef CONFIG_CONCURRENT_MODE
3142         if (!adapter->pbuddy_adapter)
3143                 return;
3144
3145         if (0)
3146                 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter->pbuddy_adapter));
3147         b_mlmepriv = &adapter->pbuddy_adapter->mlmepriv;
3148         ATOMIC_SET(&b_mlmepriv->set_scan_deny, 1);
3149         _set_timer(&b_mlmepriv->set_scan_deny_timer, ms);       
3150 #endif
3151         
3152 }
3153 #endif
3154
3155 #ifdef CONFIG_LAYER2_ROAMING
3156 /*
3157 * Select a new roaming candidate from the original @param candidate and @param competitor
3158 * @return _TRUE: candidate is updated
3159 * @return _FALSE: candidate is not updated
3160 */
3161 static int rtw_check_roaming_candidate(struct mlme_priv *mlme
3162         , struct wlan_network **candidate, struct wlan_network *competitor)
3163 {
3164         int updated = _FALSE;
3165         _adapter *adapter = container_of(mlme, _adapter, mlmepriv);
3166
3167         if(is_same_ess(&competitor->network, &mlme->cur_network.network) == _FALSE)
3168                 goto exit;
3169
3170         if(rtw_is_desired_network(adapter, competitor) == _FALSE)
3171                 goto exit;
3172
3173         DBG_871X("roam candidate:%s %s("MAC_FMT", ch%3u) rssi:%d, age:%5d\n",
3174                 (competitor == mlme->cur_network_scanned)?"*":" " ,
3175                 competitor->network.Ssid.Ssid,
3176                 MAC_ARG(competitor->network.MacAddress),
3177                 competitor->network.Configuration.DSConfig,
3178                 (int)competitor->network.Rssi,
3179                 rtw_get_passing_time_ms(competitor->last_scanned)
3180         );
3181
3182         /* got specific addr to roam */
3183         if (!is_zero_mac_addr(mlme->roam_tgt_addr)) {
3184                 if(_rtw_memcmp(mlme->roam_tgt_addr, competitor->network.MacAddress, ETH_ALEN) == _TRUE)
3185                         goto update;
3186                 else
3187                         goto exit;
3188         }
3189         #if 1
3190         if(rtw_get_passing_time_ms((u32)competitor->last_scanned) >= mlme->roam_scanr_exp_ms)
3191                 goto exit;
3192
3193         if (competitor->network.Rssi - mlme->cur_network_scanned->network.Rssi < mlme->roam_rssi_diff_th)
3194                 goto exit;
3195
3196         if(*candidate != NULL && (*candidate)->network.Rssi>=competitor->network.Rssi)
3197                 goto exit;
3198         #else
3199         goto exit;
3200         #endif
3201
3202 update:
3203         *candidate = competitor;
3204         updated = _TRUE;
3205
3206 exit:
3207         return updated;
3208 }
3209
3210 int rtw_select_roaming_candidate(struct mlme_priv *mlme)
3211 {
3212         _irqL   irqL;
3213         int ret = _FAIL;
3214         _list   *phead;
3215         _adapter *adapter;      
3216         _queue  *queue  = &(mlme->scanned_queue);
3217         struct  wlan_network    *pnetwork = NULL;
3218         struct  wlan_network    *candidate = NULL;
3219         u8              bSupportAntDiv = _FALSE;
3220
3221 _func_enter_;
3222
3223         if (mlme->cur_network_scanned == NULL) {
3224                 rtw_warn_on(1);
3225                 goto exit;
3226         }
3227
3228         _enter_critical_bh(&(mlme->scanned_queue.lock), &irqL);
3229         phead = get_list_head(queue);           
3230         adapter = (_adapter *)mlme->nic_hdl;
3231
3232         mlme->pscanned = get_next(phead);
3233
3234         while (!rtw_end_of_queue_search(phead, mlme->pscanned)) {
3235
3236                 pnetwork = LIST_CONTAINOR(mlme->pscanned, struct wlan_network, list);
3237                 if(pnetwork==NULL){
3238                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s return _FAIL:(pnetwork==NULL)\n", __FUNCTION__));
3239                         ret = _FAIL;
3240                         goto exit;
3241                 }
3242                 
3243                 mlme->pscanned = get_next(mlme->pscanned);
3244
3245                 if (0)
3246                         DBG_871X("%s("MAC_FMT", ch%u) rssi:%d\n"
3247                                 , pnetwork->network.Ssid.Ssid
3248                                 , MAC_ARG(pnetwork->network.MacAddress)
3249                                 , pnetwork->network.Configuration.DSConfig
3250                                 , (int)pnetwork->network.Rssi);
3251
3252                 rtw_check_roaming_candidate(mlme, &candidate, pnetwork);
3253  
3254         }
3255
3256         if(candidate == NULL) {
3257                 DBG_871X("%s: return _FAIL(candidate == NULL)\n", __FUNCTION__);
3258                 ret = _FAIL;
3259                 goto exit;
3260         } else {
3261                 DBG_871X("%s: candidate: %s("MAC_FMT", ch:%u)\n", __FUNCTION__,
3262                         candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress),
3263                         candidate->network.Configuration.DSConfig);
3264
3265                 mlme->roam_network = candidate;
3266
3267                 if (_rtw_memcmp(candidate->network.MacAddress, mlme->roam_tgt_addr, ETH_ALEN) == _TRUE)
3268                         _rtw_memset(mlme->roam_tgt_addr,0, ETH_ALEN);
3269         }
3270
3271         ret = _SUCCESS;
3272 exit:
3273         _exit_critical_bh(&(mlme->scanned_queue.lock), &irqL);
3274
3275         return ret;
3276 }
3277 #endif /* CONFIG_LAYER2_ROAMING */
3278
3279 /*
3280 * Select a new join candidate from the original @param candidate and @param competitor
3281 * @return _TRUE: candidate is updated
3282 * @return _FALSE: candidate is not updated
3283 */
3284 static int rtw_check_join_candidate(struct mlme_priv *mlme
3285         , struct wlan_network **candidate, struct wlan_network *competitor)
3286 {
3287         int updated = _FALSE;
3288         _adapter *adapter = container_of(mlme, _adapter, mlmepriv);
3289
3290
3291         //check bssid, if needed
3292         if(mlme->assoc_by_bssid==_TRUE) {
3293                 if(_rtw_memcmp(competitor->network.MacAddress, mlme->assoc_bssid, ETH_ALEN) ==_FALSE)
3294                         goto exit;
3295         }
3296
3297         //check ssid, if needed
3298         if(mlme->assoc_ssid.Ssid[0] && mlme->assoc_ssid.SsidLength) {
3299                 if(     competitor->network.Ssid.SsidLength != mlme->assoc_ssid.SsidLength
3300                         || _rtw_memcmp(competitor->network.Ssid.Ssid, mlme->assoc_ssid.Ssid, mlme->assoc_ssid.SsidLength) == _FALSE
3301                 )
3302                         goto exit;
3303         }
3304
3305         if(rtw_is_desired_network(adapter, competitor)  == _FALSE)
3306                 goto exit;
3307
3308 #ifdef  CONFIG_LAYER2_ROAMING
3309         if(rtw_to_roam(adapter) > 0) {
3310                 if(     rtw_get_passing_time_ms((u32)competitor->last_scanned) >= mlme->roam_scanr_exp_ms
3311                         || is_same_ess(&competitor->network, &mlme->cur_network.network) == _FALSE
3312                 )
3313                         goto exit;
3314         }
3315 #endif
3316         
3317         if(*candidate == NULL ||(*candidate)->network.Rssi<competitor->network.Rssi )
3318         {
3319                 *candidate = competitor;
3320                 updated = _TRUE;
3321         }
3322
3323         if(updated){
3324                 DBG_871X("[by_bssid:%u][assoc_ssid:%s][to_roam:%u] "
3325                         "new candidate: %s("MAC_FMT", ch%u) rssi:%d\n",
3326                         mlme->assoc_by_bssid,
3327                         mlme->assoc_ssid.Ssid,
3328                         rtw_to_roam(adapter),
3329                         (*candidate)->network.Ssid.Ssid,
3330                         MAC_ARG((*candidate)->network.MacAddress),
3331                         (*candidate)->network.Configuration.DSConfig,
3332                         (int)(*candidate)->network.Rssi
3333                 );
3334         }
3335
3336 exit:
3337         return updated;
3338 }
3339
3340 /*
3341 Calling context:
3342 The caller of the sub-routine will be in critical section...
3343
3344 The caller must hold the following spinlock
3345
3346 pmlmepriv->lock
3347
3348
3349 */
3350
3351 int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv )
3352 {
3353         _irqL   irqL;
3354         int ret;
3355         _list   *phead;
3356         _adapter *adapter;      
3357         _queue  *queue  = &(pmlmepriv->scanned_queue);
3358         struct  wlan_network    *pnetwork = NULL;
3359         struct  wlan_network    *candidate = NULL;
3360         u8              bSupportAntDiv = _FALSE;
3361
3362 _func_enter_;
3363
3364         adapter = (_adapter *)pmlmepriv->nic_hdl;
3365
3366         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3367
3368         #ifdef CONFIG_LAYER2_ROAMING
3369         if (pmlmepriv->roam_network) {
3370                 candidate = pmlmepriv->roam_network;
3371                 pmlmepriv->roam_network = NULL;
3372                 goto candidate_exist;
3373         }
3374         #endif
3375
3376         phead = get_list_head(queue);
3377         pmlmepriv->pscanned = get_next(phead);
3378
3379         while (!rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) {
3380
3381                 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
3382                 if(pnetwork==NULL){
3383                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s return _FAIL:(pnetwork==NULL)\n", __FUNCTION__));
3384                         ret = _FAIL;
3385                         goto exit;
3386                 }
3387                 
3388                 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
3389
3390                 if (0)
3391                         DBG_871X("%s("MAC_FMT", ch%u) rssi:%d\n"
3392                                 , pnetwork->network.Ssid.Ssid
3393                                 , MAC_ARG(pnetwork->network.MacAddress)
3394                                 , pnetwork->network.Configuration.DSConfig
3395                                 , (int)pnetwork->network.Rssi);
3396
3397                 rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
3398  
3399         }
3400
3401         if(candidate == NULL) {
3402                 DBG_871X("%s: return _FAIL(candidate == NULL)\n", __FUNCTION__);
3403 #ifdef CONFIG_WOWLAN
3404                 _clr_fwstate_(pmlmepriv, _FW_LINKED|_FW_UNDER_LINKING);
3405 #endif
3406                 ret = _FAIL;
3407                 goto exit;
3408         } else {
3409                 DBG_871X("%s: candidate: %s("MAC_FMT", ch:%u)\n", __FUNCTION__,
3410                         candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress),
3411                         candidate->network.Configuration.DSConfig);
3412                 goto candidate_exist;
3413         }
3414         
3415 candidate_exist:
3416
3417         // check for situation of  _FW_LINKED 
3418         if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
3419         {
3420                 DBG_871X("%s: _FW_LINKED while ask_for_joinbss!!!\n", __FUNCTION__);
3421
3422                 #if 0 // for WPA/WPA2 authentication, wpa_supplicant will expect authentication from AP, it is needed to reconnect AP...
3423                 if(is_same_network(&pmlmepriv->cur_network.network, &candidate->network))
3424                 {
3425                         DBG_871X("%s: _FW_LINKED and is same network, it needn't join again\n", __FUNCTION__);
3426
3427                         rtw_indicate_connect(adapter);//rtw_indicate_connect again
3428                                 
3429                         ret = 2;
3430                         goto exit;
3431                 }
3432                 else
3433                 #endif
3434                 {
3435                         rtw_disassoc_cmd(adapter, 0, _TRUE);
3436                         rtw_indicate_disconnect(adapter);
3437                         rtw_free_assoc_resources(adapter, 0);
3438                 }
3439         }
3440         
3441         #ifdef CONFIG_ANTENNA_DIVERSITY
3442         rtw_hal_get_def_var(adapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(bSupportAntDiv));
3443         if(_TRUE == bSupportAntDiv)     
3444         {
3445                 u8 CurrentAntenna;
3446                 rtw_hal_get_odm_var(adapter, HAL_ODM_ANTDIV_SELECT, &(CurrentAntenna), NULL);
3447                 DBG_871X("#### Opt_Ant_(%s) , cur_Ant(%s)\n",
3448                         (MAIN_ANT == candidate->network.PhyInfo.Optimum_antenna) ? "MAIN_ANT":"AUX_ANT",
3449                         (MAIN_ANT == CurrentAntenna) ? "MAIN_ANT":"AUX_ANT"
3450                 );
3451         }
3452         #endif
3453         set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
3454         ret = rtw_joinbss_cmd(adapter, candidate);
3455         
3456 exit:
3457         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3458
3459 _func_exit_;
3460
3461         return ret;
3462 }
3463
3464 sint rtw_set_auth(_adapter * adapter,struct security_priv *psecuritypriv)
3465 {
3466         struct  cmd_obj* pcmd;
3467         struct  setauth_parm *psetauthparm;
3468         struct  cmd_priv        *pcmdpriv=&(adapter->cmdpriv);
3469         sint            res=_SUCCESS;
3470         
3471 _func_enter_;   
3472
3473         pcmd = (struct  cmd_obj*)rtw_zmalloc(sizeof(struct      cmd_obj));
3474         if(pcmd==NULL){
3475                 res= _FAIL;  //try again
3476                 goto exit;
3477         }
3478         
3479         psetauthparm=(struct setauth_parm*)rtw_zmalloc(sizeof(struct setauth_parm));
3480         if(psetauthparm==NULL){
3481                 rtw_mfree((unsigned char *)pcmd, sizeof(struct  cmd_obj));
3482                 res= _FAIL;
3483                 goto exit;
3484         }
3485
3486         _rtw_memset(psetauthparm, 0, sizeof(struct setauth_parm));
3487         psetauthparm->mode=(unsigned char)psecuritypriv->dot11AuthAlgrthm;
3488         
3489         pcmd->cmdcode = _SetAuth_CMD_;
3490         pcmd->parmbuf = (unsigned char *)psetauthparm;   
3491         pcmd->cmdsz =  (sizeof(struct setauth_parm));  
3492         pcmd->rsp = NULL;
3493         pcmd->rspsz = 0;
3494
3495
3496         _rtw_init_listhead(&pcmd->list);
3497
3498         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("after enqueue set_auth_cmd, auth_mode=%x\n", psecuritypriv->dot11AuthAlgrthm));
3499
3500         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
3501
3502 exit:
3503
3504 _func_exit_;
3505
3506         return res;
3507
3508 }
3509
3510
3511 sint rtw_set_key(_adapter * adapter,struct security_priv *psecuritypriv,sint keyid, u8 set_tx, bool enqueue)
3512 {
3513         u8      keylen;
3514         struct cmd_obj          *pcmd;
3515         struct setkey_parm      *psetkeyparm;
3516         struct cmd_priv         *pcmdpriv = &(adapter->cmdpriv);
3517         struct mlme_priv                *pmlmepriv = &(adapter->mlmepriv);
3518         sint    res=_SUCCESS;
3519         
3520 _func_enter_;
3521
3522         psetkeyparm=(struct setkey_parm*)rtw_zmalloc(sizeof(struct setkey_parm));
3523         if(psetkeyparm==NULL){          
3524                 res= _FAIL;
3525                 goto exit;
3526         }
3527         _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm));
3528
3529         if(psecuritypriv->dot11AuthAlgrthm ==dot11AuthAlgrthm_8021X){           
3530                 psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy;      
3531                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy=%d \n", psetkeyparm->algorithm));
3532         }       
3533         else{
3534                 psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm;
3535                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm=%d \n", psetkeyparm->algorithm));
3536
3537         }
3538         psetkeyparm->keyid = (u8)keyid;//0~3
3539         psetkeyparm->set_tx = set_tx;
3540         if (is_wep_enc(psetkeyparm->algorithm))
3541                 adapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid);
3542
3543         DBG_871X("==> rtw_set_key algorithm(%x),keyid(%x),key_mask(%x)\n",psetkeyparm->algorithm,psetkeyparm->keyid, adapter->securitypriv.key_mask);
3544         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=%d psetkeyparm->keyid=(u8)keyid=%d \n",psetkeyparm->algorithm, keyid));
3545
3546         switch(psetkeyparm->algorithm){
3547                         
3548                 case _WEP40_:
3549                         keylen=5;
3550                         _rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
3551                         break;
3552                 case _WEP104_:
3553                         keylen=13;
3554                         _rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
3555                         break;
3556                 case _TKIP_:
3557                         keylen=16;                      
3558                         _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
3559                         psetkeyparm->grpkey=1;
3560                         break;
3561                 case _AES_:
3562                         keylen=16;                      
3563                         _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
3564                         psetkeyparm->grpkey=1;
3565                         break;
3566                 default:
3567                         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));
3568                         res= _FAIL;
3569                         rtw_mfree((unsigned char *)psetkeyparm, sizeof(struct setkey_parm));
3570                         goto exit;
3571         }
3572                 
3573                 
3574         if(enqueue){
3575                 pcmd = (struct  cmd_obj*)rtw_zmalloc(sizeof(struct      cmd_obj));
3576                 if(pcmd==NULL){
3577                         rtw_mfree((unsigned char *)psetkeyparm, sizeof(struct setkey_parm));
3578                         res= _FAIL;  //try again
3579                         goto exit;
3580                 }
3581                 
3582                 pcmd->cmdcode = _SetKey_CMD_;
3583                 pcmd->parmbuf = (u8 *)psetkeyparm;   
3584                 pcmd->cmdsz =  (sizeof(struct setkey_parm));  
3585                 pcmd->rsp = NULL;
3586                 pcmd->rspsz = 0;
3587
3588                 _rtw_init_listhead(&pcmd->list);
3589
3590                 //_rtw_init_sema(&(pcmd->cmd_sem), 0);
3591
3592                 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
3593         }
3594         else{
3595                 setkey_hdl(adapter, (u8 *)psetkeyparm);
3596                 rtw_mfree((u8 *) psetkeyparm, sizeof(struct setkey_parm));
3597         }
3598 exit:
3599 _func_exit_;
3600         return res;
3601
3602 }
3603
3604
3605 //adjust IEs for rtw_joinbss_cmd in WMM
3606 int rtw_restruct_wmm_ie(_adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len)
3607 {
3608         unsigned        int ielength=0;
3609         unsigned int i, j;
3610
3611         i = 12; //after the fixed IE
3612         while(i<in_len)
3613         {
3614                 ielength = initial_out_len;             
3615                 
3616                 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
3617                 {
3618
3619                         //Append WMM IE to the last index of out_ie
3620                         /*
3621                         for(j=i; j< i+(in_ie[i+1]+2); j++)
3622                         {
3623                                 out_ie[ielength] = in_ie[j];                            
3624                                 ielength++;
3625                         }
3626                         out_ie[initial_out_len+8] = 0x00; //force the QoS Info Field to be zero
3627                         */
3628                        
3629                         for ( j = i; j < i + 9; j++ )
3630                         {
3631                             out_ie[ ielength] = in_ie[ j ];
3632                             ielength++;
3633                         } 
3634                         out_ie[ initial_out_len + 1 ] = 0x07;
3635                         out_ie[ initial_out_len + 6 ] = 0x00;
3636                         out_ie[ initial_out_len + 8 ] = 0x00;
3637         
3638                         break;
3639                 }
3640
3641                 i+=(in_ie[i+1]+2); // to the next IE element
3642         }
3643         
3644         return ielength;
3645         
3646 }
3647
3648
3649 //
3650 // Ported from 8185: IsInPreAuthKeyList(). (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.)
3651 // Added by Annie, 2006-05-07.
3652 //
3653 // Search by BSSID,
3654 // Return Value:
3655 //              -1              :if there is no pre-auth key in the  table
3656 //              >=0             :if there is pre-auth key, and   return the entry id
3657 //
3658 //
3659
3660 static int SecIsInPMKIDList(_adapter *Adapter, u8 *bssid)
3661 {
3662         struct security_priv *psecuritypriv=&Adapter->securitypriv;
3663         int i=0;
3664
3665         do
3666         {
3667                 if( ( psecuritypriv->PMKIDList[i].bUsed ) && 
3668                     (  _rtw_memcmp( psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN ) == _TRUE ) )
3669                 {
3670                         break;
3671                 }
3672                 else
3673                 {       
3674                         i++;
3675                         //continue;
3676                 }
3677                 
3678         }while(i<NUM_PMKID_CACHE);
3679
3680         if( i == NUM_PMKID_CACHE )
3681         { 
3682                 i = -1;// Could not find.
3683         }
3684         else
3685         { 
3686                 // There is one Pre-Authentication Key for the specific BSSID.
3687         }
3688
3689         return (i);
3690         
3691 }
3692
3693 //
3694 // Check the RSN IE length
3695 // If the RSN IE length <= 20, the RSN IE didn't include the PMKID information
3696 // 0-11th element in the array are the fixed IE
3697 // 12th element in the array is the IE
3698 // 13th element in the array is the IE length  
3699 //
3700
3701 static int rtw_append_pmkid(_adapter *adapter,int iEntry, u8 *ie, uint ie_len)
3702 {
3703         struct security_priv *sec=&adapter->securitypriv;
3704
3705         if (ie[13] > 20) {
3706                 int i;
3707                 u16 pmkid_cnt = RTW_GET_LE16(ie+14+20);
3708                 if (pmkid_cnt == 1 && _rtw_memcmp(ie+14+20+2, &sec->PMKIDList[iEntry].PMKID, 16)) {
3709                         DBG_871X(FUNC_ADPT_FMT" has carried the same PMKID:"KEY_FMT"\n"
3710                                 , FUNC_ADPT_ARG(adapter), KEY_ARG(&sec->PMKIDList[iEntry].PMKID));
3711                         goto exit;
3712                 }
3713
3714                 DBG_871X(FUNC_ADPT_FMT" remove original PMKID, count:%u\n"
3715                         , FUNC_ADPT_ARG(adapter), pmkid_cnt);
3716
3717                 for (i=0;i<pmkid_cnt;i++)
3718                         DBG_871X("    "KEY_FMT"\n", KEY_ARG(ie+14+20+2+i*16));
3719
3720                 ie_len -= 2+pmkid_cnt*16;
3721                 ie[13] = 20;
3722         }
3723
3724         if (ie[13] <= 20) {     
3725                 /* The RSN IE didn't include the PMK ID, append the PMK information */
3726
3727                 DBG_871X(FUNC_ADPT_FMT" append PMKID:"KEY_FMT"\n"
3728                                 , FUNC_ADPT_ARG(adapter), KEY_ARG(&sec->PMKIDList[iEntry].PMKID));
3729
3730                 RTW_PUT_LE16(&ie[ie_len], 1);
3731                 ie_len += 2;
3732
3733                 _rtw_memcpy(&ie[ie_len], &sec->PMKIDList[iEntry].PMKID, 16);
3734                 ie_len += 16;
3735
3736                 ie[13] += 18;//PMKID length = 2+16
3737         }
3738
3739 exit:
3740         return (ie_len);
3741 }
3742
3743 static int rtw_remove_pmkid(_adapter *adapter, u8 *ie, uint ie_len)
3744 {
3745         struct security_priv *sec=&adapter->securitypriv;
3746         int i;
3747         u16 pmkid_cnt = RTW_GET_LE16(ie+14+20);
3748
3749         if (ie[13] <= 20)
3750                 goto exit;
3751
3752         DBG_871X(FUNC_ADPT_FMT" remove original PMKID, count:%u\n"
3753                 , FUNC_ADPT_ARG(adapter), pmkid_cnt);
3754
3755         for (i=0;i<pmkid_cnt;i++)
3756                 DBG_871X("    "KEY_FMT"\n", KEY_ARG(ie+14+20+2+i*16));
3757
3758         ie_len -= 2+pmkid_cnt*16;
3759         ie[13] = 20;
3760
3761 exit:
3762         return (ie_len);
3763 }
3764
3765 sint rtw_restruct_sec_ie(_adapter *adapter,u8 *in_ie, u8 *out_ie, uint in_len)
3766 {
3767         u8 authmode=0x0, securitytype, match;
3768         u8 sec_ie[255], uncst_oui[4], bkup_ie[255];
3769         u8 wpa_oui[4]={0x0, 0x50, 0xf2, 0x01};
3770         uint    ielength, cnt, remove_cnt;
3771         int iEntry;
3772
3773         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3774         struct security_priv *psecuritypriv=&adapter->securitypriv;
3775         uint    ndisauthmode=psecuritypriv->ndisauthtype;
3776         uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
3777         
3778 _func_enter_;
3779
3780         RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
3781                  ("+rtw_restruct_sec_ie: ndisauthmode=%d ndissecuritytype=%d\n",
3782                   ndisauthmode, ndissecuritytype));
3783         
3784         //copy fixed ie only
3785         _rtw_memcpy(out_ie, in_ie,12);
3786         ielength=12;
3787         if((ndisauthmode==Ndis802_11AuthModeWPA)||(ndisauthmode==Ndis802_11AuthModeWPAPSK))
3788                         authmode=_WPA_IE_ID_;
3789         if((ndisauthmode==Ndis802_11AuthModeWPA2)||(ndisauthmode==Ndis802_11AuthModeWPA2PSK))
3790                         authmode=_WPA2_IE_ID_;
3791
3792         if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
3793         {
3794                 _rtw_memcpy(out_ie+ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len);
3795                 
3796                 ielength += psecuritypriv->wps_ie_len;
3797         }
3798         else if((authmode==_WPA_IE_ID_)||(authmode==_WPA2_IE_ID_))
3799         {               
3800                 //copy RSN or SSN               
3801                 _rtw_memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1]+2);
3802                 /* debug for CONFIG_IEEE80211W
3803                 {
3804                         int jj;
3805                         printk("supplicant_ie_length=%d &&&&&&&&&&&&&&&&&&&\n", psecuritypriv->supplicant_ie[1]+2);
3806                         for(jj=0; jj < psecuritypriv->supplicant_ie[1]+2; jj++)
3807                                 printk(" %02x ", psecuritypriv->supplicant_ie[jj]);
3808                         printk("\n");
3809                 }*/
3810                 ielength+=psecuritypriv->supplicant_ie[1]+2;
3811                 rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie);
3812         
3813 #ifdef CONFIG_DRVEXT_MODULE
3814                 drvext_report_sec_ie(&adapter->drvextpriv, authmode, sec_ie);   
3815 #endif
3816         }
3817
3818         iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
3819         if(iEntry<0)
3820         {
3821                 if(authmode == _WPA2_IE_ID_)
3822                         ielength = rtw_remove_pmkid(adapter, out_ie, ielength);
3823         }
3824         else
3825         {
3826                 if(authmode == _WPA2_IE_ID_)
3827                         ielength=rtw_append_pmkid(adapter, iEntry, out_ie, ielength);
3828         }
3829
3830 _func_exit_;
3831         
3832         return ielength;        
3833 }
3834
3835 void rtw_init_registrypriv_dev_network( _adapter* adapter)
3836 {
3837         struct registry_priv* pregistrypriv = &adapter->registrypriv;
3838         WLAN_BSSID_EX    *pdev_network = &pregistrypriv->dev_network;
3839         u8 *myhwaddr = adapter_mac_addr(adapter);
3840         
3841 _func_enter_;
3842
3843         _rtw_memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN);
3844
3845         _rtw_memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, sizeof(NDIS_802_11_SSID));
3846         
3847         pdev_network->Configuration.Length=sizeof(NDIS_802_11_CONFIGURATION);
3848         pdev_network->Configuration.BeaconPeriod = 100; 
3849         pdev_network->Configuration.FHConfig.Length = 0;
3850         pdev_network->Configuration.FHConfig.HopPattern = 0;
3851         pdev_network->Configuration.FHConfig.HopSet = 0;
3852         pdev_network->Configuration.FHConfig.DwellTime = 0;
3853         
3854         
3855 _func_exit_;    
3856         
3857 }
3858
3859 void rtw_update_registrypriv_dev_network(_adapter* adapter) 
3860 {
3861         int sz=0;
3862         struct registry_priv* pregistrypriv = &adapter->registrypriv;   
3863         WLAN_BSSID_EX    *pdev_network = &pregistrypriv->dev_network;
3864         struct  security_priv*  psecuritypriv = &adapter->securitypriv;
3865         struct  wlan_network    *cur_network = &adapter->mlmepriv.cur_network;
3866         //struct        xmit_priv       *pxmitpriv = &adapter->xmitpriv;
3867         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
3868
3869 _func_enter_;
3870
3871 #if 0
3872         pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense;
3873         pxmitpriv->vcs = pregistrypriv->vcs_type;
3874         pxmitpriv->vcs_type = pregistrypriv->vcs_type;
3875         //pxmitpriv->rts_thresh = pregistrypriv->rts_thresh;
3876         pxmitpriv->frag_len = pregistrypriv->frag_thresh;
3877         
3878         adapter->qospriv.qos_option = pregistrypriv->wmm_enable;
3879 #endif  
3880
3881         pdev_network->Privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0) ; // adhoc no 802.1x
3882
3883         pdev_network->Rssi = 0;
3884
3885         switch(pregistrypriv->wireless_mode)
3886         {
3887                 case WIRELESS_11B:
3888                         pdev_network->NetworkTypeInUse = (Ndis802_11DS);
3889                         break;  
3890                 case WIRELESS_11G:
3891                 case WIRELESS_11BG:
3892                 case WIRELESS_11_24N:
3893                 case WIRELESS_11G_24N:
3894                 case WIRELESS_11BG_24N:
3895                         pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24);
3896                         break;
3897                 case WIRELESS_11A:
3898                 case WIRELESS_11A_5N:
3899                         pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5);
3900                         break;
3901                 case WIRELESS_11ABGN:
3902                         if(pregistrypriv->channel > 14)
3903                                 pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5);
3904                         else
3905                                 pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24);
3906                         break;
3907                 default :
3908                         // TODO
3909                         break;
3910         }
3911         
3912         pdev_network->Configuration.DSConfig = (pregistrypriv->channel);
3913         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("pregistrypriv->channel=%d, pdev_network->Configuration.DSConfig=0x%x\n", pregistrypriv->channel, pdev_network->Configuration.DSConfig));  
3914
3915         if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) {
3916                 pdev_network->Configuration.ATIMWindow = (0);
3917
3918                 if (pmlmeext->cur_channel != 0)
3919                         pdev_network->Configuration.DSConfig = pmlmeext->cur_channel;
3920                 else 
3921                         pdev_network->Configuration.DSConfig = 1;
3922         }
3923
3924         pdev_network->InfrastructureMode = (cur_network->network.InfrastructureMode);
3925
3926         // 1. Supported rates
3927         // 2. IE
3928
3929         //rtw_set_supported_rate(pdev_network->SupportedRates, pregistrypriv->wireless_mode) ; // will be called in rtw_generate_ie
3930         sz = rtw_generate_ie(pregistrypriv);
3931
3932         pdev_network->IELength = sz;
3933
3934         pdev_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX  *)pdev_network);
3935
3936         //notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd();
3937         //pdev_network->IELength = cpu_to_le32(sz);
3938                 
3939 _func_exit_;    
3940
3941 }
3942
3943 void rtw_get_encrypt_decrypt_from_registrypriv(_adapter* adapter)
3944 {
3945 _func_enter_;
3946
3947
3948 _func_exit_;    
3949         
3950 }
3951
3952 //the fucntion is at passive_level 
3953 void rtw_joinbss_reset(_adapter *padapter)
3954 {
3955         u8      threshold;
3956         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
3957         //todo: if you want to do something io/reg/hw setting before join_bss, please add code here
3958         
3959 #ifdef CONFIG_80211N_HT 
3960         struct ht_priv          *phtpriv = &pmlmepriv->htpriv;  
3961
3962         pmlmepriv->num_FortyMHzIntolerant = 0;
3963
3964         pmlmepriv->num_sta_no_ht = 0;
3965
3966         phtpriv->ampdu_enable = _FALSE;//reset to disabled
3967
3968 #if defined( CONFIG_USB_HCI) || defined (CONFIG_SDIO_HCI)
3969         // TH=1 => means that invalidate usb rx aggregation
3970         // TH=0 => means that validate usb rx aggregation, use init value.
3971         if(phtpriv->ht_option)
3972         {
3973                 if(padapter->registrypriv.wifi_spec==1)         
3974                         threshold = 1;
3975                 else
3976                         threshold = 0;          
3977                 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
3978         }
3979         else
3980         {
3981                 threshold = 1;
3982                 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
3983         }
3984 #endif//#if defined( CONFIG_USB_HCI) || defined (CONFIG_SDIO_HCI)
3985
3986 #endif//#ifdef CONFIG_80211N_HT
3987
3988 }
3989
3990
3991 #ifdef CONFIG_80211N_HT
3992 void    rtw_ht_use_default_setting(_adapter *padapter)
3993 {
3994         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
3995         struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
3996         struct registry_priv    *pregistrypriv = &padapter->registrypriv;
3997         BOOLEAN         bHwLDPCSupport = _FALSE, bHwSTBCSupport = _FALSE;
3998         BOOLEAN         bHwSupportBeamformer = _FALSE, bHwSupportBeamformee = _FALSE;
3999
4000         if (pregistrypriv->wifi_spec)
4001                 phtpriv->bss_coexist = 1;
4002         else
4003                 phtpriv->bss_coexist = 0;
4004
4005         phtpriv->sgi_40m = TEST_FLAG(pregistrypriv->short_gi, BIT1) ? _TRUE : _FALSE;
4006         phtpriv->sgi_20m = TEST_FLAG(pregistrypriv->short_gi, BIT0) ? _TRUE : _FALSE;
4007
4008         // LDPC support
4009         rtw_hal_get_def_var(padapter, HAL_DEF_RX_LDPC, (u8 *)&bHwLDPCSupport);
4010         CLEAR_FLAGS(phtpriv->ldpc_cap);
4011         if(bHwLDPCSupport)
4012         {
4013                 if(TEST_FLAG(pregistrypriv->ldpc_cap, BIT4))
4014                         SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX);
4015         }
4016         rtw_hal_get_def_var(padapter, HAL_DEF_TX_LDPC, (u8 *)&bHwLDPCSupport);
4017         if(bHwLDPCSupport)
4018         {
4019                 if(TEST_FLAG(pregistrypriv->ldpc_cap, BIT5))
4020                         SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX);
4021         }
4022         if (phtpriv->ldpc_cap)
4023                 DBG_871X("[HT] HAL Support LDPC = 0x%02X\n", phtpriv->ldpc_cap);
4024
4025         // STBC
4026         rtw_hal_get_def_var(padapter, HAL_DEF_TX_STBC, (u8 *)&bHwSTBCSupport);
4027         CLEAR_FLAGS(phtpriv->stbc_cap);
4028         if(bHwSTBCSupport)
4029         {
4030                 if(TEST_FLAG(pregistrypriv->stbc_cap, BIT5))
4031                         SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX);
4032         }
4033         rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)&bHwSTBCSupport);
4034         if(bHwSTBCSupport)
4035         {
4036                 if(TEST_FLAG(pregistrypriv->stbc_cap, BIT4))
4037                         SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX);
4038         }
4039         if (phtpriv->stbc_cap)
4040                 DBG_871X("[HT] HAL Support STBC = 0x%02X\n", phtpriv->stbc_cap);
4041
4042         // Beamforming setting
4043         rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&bHwSupportBeamformer);
4044         rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&bHwSupportBeamformee);
4045         CLEAR_FLAGS(phtpriv->beamform_cap);
4046         if(TEST_FLAG(pregistrypriv->beamform_cap, BIT4) && bHwSupportBeamformer)
4047         {
4048                 SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
4049                 DBG_871X("[HT] HAL Support Beamformer\n");
4050         }
4051         if(TEST_FLAG(pregistrypriv->beamform_cap, BIT5) && bHwSupportBeamformee)
4052         {
4053                 SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
4054                 DBG_871X("[HT] HAL Support Beamformee\n");
4055         }
4056 }
4057 void rtw_build_wmm_ie_ht(_adapter *padapter, u8 *out_ie, uint *pout_len)
4058 {
4059         unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
4060         int out_len;
4061         u8 *pframe;
4062
4063         if(padapter->mlmepriv.qospriv.qos_option == 0)
4064         {
4065                 out_len = *pout_len;
4066                 pframe = rtw_set_ie(out_ie+out_len, _VENDOR_SPECIFIC_IE_, 
4067                                                         _WMM_IE_Length_, WMM_IE, pout_len);
4068
4069                 padapter->mlmepriv.qospriv.qos_option = 1;
4070         }
4071 }
4072
4073 /* the fucntion is >= passive_level */
4074 unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len, u8 channel)
4075 {
4076         u32 ielen, out_len;
4077         HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
4078         HT_CAP_AMPDU_DENSITY best_ampdu_density;
4079         unsigned char *p, *pframe;
4080         struct rtw_ieee80211_ht_cap ht_capie;
4081         u8      cbw40_enable = 0, rf_type = 0, operation_bw = 0, rf_num = 0, rx_stbc_nss = 0;
4082         struct registry_priv *pregistrypriv = &padapter->registrypriv;
4083         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
4084         struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
4085         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
4086
4087         phtpriv->ht_option = _FALSE;
4088
4089         out_len = *pout_len;
4090
4091         _rtw_memset(&ht_capie, 0, sizeof(struct rtw_ieee80211_ht_cap));
4092
4093         ht_capie.cap_info = IEEE80211_HT_CAP_DSSSCCK40;
4094
4095         if (phtpriv->sgi_20m)
4096                 ht_capie.cap_info |= IEEE80211_HT_CAP_SGI_20;
4097
4098         /* Get HT BW */
4099         if (in_ie == NULL) {
4100                 /* TDLS: TODO 20/40 issue */
4101                 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
4102                         operation_bw = padapter->mlmeextpriv.cur_bwmode;
4103                         if (operation_bw > CHANNEL_WIDTH_40)
4104                                 operation_bw = CHANNEL_WIDTH_40;
4105                 } else
4106                         /* TDLS: TODO 40? */
4107                         operation_bw = CHANNEL_WIDTH_40;
4108         } else {
4109                 p = rtw_get_ie(in_ie, _HT_ADD_INFO_IE_, &ielen, in_len);
4110                 if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) {
4111                         struct HT_info_element *pht_info = (struct HT_info_element *)(p+2);
4112                         if (pht_info->infos[0] & BIT(2)) {
4113                                 switch (pht_info->infos[0] & 0x3) {
4114                                 case 1:
4115                                 case 3:
4116                                         operation_bw = CHANNEL_WIDTH_40;
4117                                         break;
4118                                 default:
4119                                         operation_bw = CHANNEL_WIDTH_20;
4120                                         break;
4121                                 }
4122                         } else {
4123                                 operation_bw = CHANNEL_WIDTH_20;
4124                         }
4125                 }
4126         }
4127
4128         /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
4129         if (hal_chk_bw_cap(padapter, BW_CAP_40M)) {
4130                 if (channel > 14) {
4131                         if (REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
4132                                 cbw40_enable = 1;
4133                 } else {
4134                         if (REGSTY_IS_BW_2G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
4135                                 cbw40_enable = 1;
4136                 }
4137         }
4138
4139         if ((cbw40_enable == 1) && (operation_bw == CHANNEL_WIDTH_40)) {
4140                 ht_capie.cap_info |= IEEE80211_HT_CAP_SUP_WIDTH;
4141                 if (phtpriv->sgi_40m)
4142                         ht_capie.cap_info |= IEEE80211_HT_CAP_SGI_40;
4143         }
4144
4145         /* todo: disable SM power save mode */
4146         ht_capie.cap_info |= IEEE80211_HT_CAP_SM_PS;
4147
4148         /* RX LDPC */
4149         if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX)) {
4150                 ht_capie.cap_info |= IEEE80211_HT_CAP_LDPC_CODING;
4151                 DBG_871X("[HT] Declare supporting RX LDPC\n");
4152         }
4153
4154         /* TX STBC */
4155         if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX)) {
4156                 ht_capie.cap_info |= IEEE80211_HT_CAP_TX_STBC;
4157                 DBG_871X("[HT] Declare supporting TX STBC\n");
4158         }
4159
4160         /* RX STBC */
4161         if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX)) {
4162                 if((pregistrypriv->rx_stbc == 0x3) ||                                                   /* enable for 2.4/5 GHz */
4163                         ((channel <= 14) && (pregistrypriv->rx_stbc == 0x1)) ||         /* enable for 2.4GHz */
4164                         ((channel > 14) && (pregistrypriv->rx_stbc == 0x2)) ||          /* enable for 5GHz */
4165                         (pregistrypriv->wifi_spec == 1)) {
4166                         /* HAL_DEF_RX_STBC means STBC RX spatial stream, todo: VHT 4 streams */
4167                         rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)(&rx_stbc_nss));
4168                         SET_HT_CAP_ELE_RX_STBC(&ht_capie, rx_stbc_nss);
4169                         DBG_871X("[HT] Declare supporting RX STBC = %d\n", rx_stbc_nss);
4170                 }
4171         }
4172
4173         //fill default supported_mcs_set
4174         _rtw_memcpy(ht_capie.supp_mcs_set, pmlmeext->default_supported_mcs_set, 16);
4175
4176         //update default supported_mcs_set
4177         rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
4178
4179         switch(rf_type)
4180         {
4181         case RF_1T1R:
4182                 set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_1R);
4183                         break;
4184
4185         case RF_2T2R:
4186         case RF_1T2R:
4187                 #ifdef CONFIG_DISABLE_MCS13TO15
4188                 if(((cbw40_enable == 1) && (operation_bw == CHANNEL_WIDTH_40)) && (pregistrypriv->wifi_spec!=1))
4189                                 set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R_13TO15_OFF);    
4190                 else
4191                                 set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R);       
4192                 #else //CONFIG_DISABLE_MCS13TO15
4193                         set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R);
4194                 #endif //CONFIG_DISABLE_MCS13TO15
4195                 break;
4196         case RF_3T3R:
4197                 set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_3R);
4198                 break;
4199         default:
4200                 DBG_871X("[warning] rf_type %d is not expected\n", rf_type);
4201         }
4202
4203         {
4204                 u32 rx_packet_offset, max_recvbuf_sz;
4205                 rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset);
4206                 rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz);
4207                 //if(max_recvbuf_sz-rx_packet_offset>(8191-256)) {
4208                 //      DBG_871X("%s IEEE80211_HT_CAP_MAX_AMSDU is set\n", __FUNCTION__);
4209                 //      ht_capie.cap_info = ht_capie.cap_info |IEEE80211_HT_CAP_MAX_AMSDU;
4210                 //}
4211         }
4212         /*      
4213         AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
4214         AMPDU_para [4:2]:Min MPDU Start Spacing 
4215         */
4216
4217         /*
4218         #if defined(CONFIG_RTL8188E )&& defined (CONFIG_SDIO_HCI)
4219         ht_capie.ampdu_params_info = 2;
4220         #else
4221         ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR&0x03);
4222         #endif
4223         */
4224
4225         if(padapter->driver_rx_ampdu_factor != 0xFF)
4226                 max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)padapter->driver_rx_ampdu_factor;
4227         else
4228                 rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
4229                                 
4230         //rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
4231         ht_capie.ampdu_params_info = (max_rx_ampdu_factor&0x03);
4232
4233         if(padapter->driver_rx_ampdu_spacing != 0xFF) 
4234         {
4235                 ht_capie.ampdu_params_info |= (( padapter->driver_rx_ampdu_spacing&0x07) <<2);  
4236         }
4237         else
4238         {
4239                 if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) {
4240                         /*
4241                         *       Todo : Each chip must to ask DD , this chip best ampdu_density setting
4242                         *       By yiwei.sun
4243                         */
4244                         rtw_hal_get_def_var(padapter, HW_VAR_BEST_AMPDU_DENSITY, &best_ampdu_density);
4245
4246                         ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & (best_ampdu_density << 2));
4247
4248                  } else
4249                         ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
4250         }
4251 #ifdef CONFIG_BEAMFORMING
4252         ht_capie.tx_BF_cap_info = 0;
4253
4254         /* HT Beamformer*/
4255         if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE)) {
4256                 /* Transmit NDP Capable */
4257                 SET_HT_CAP_TXBF_TRANSMIT_NDP_CAP(&ht_capie, 1);
4258                 /* Explicit Compressed Steering Capable */
4259                 SET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(&ht_capie, 1);
4260                 /* Compressed Steering Number Antennas */
4261                 SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(&ht_capie, 1);
4262                 rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMER_CAP, (u8 *)&rf_num);
4263                 SET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(&ht_capie, rf_num);
4264         }
4265
4266         /* HT Beamformee */
4267         if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) {
4268                 /* Receive NDP Capable */
4269                 SET_HT_CAP_TXBF_RECEIVE_NDP_CAP(&ht_capie, 1);
4270                 /* Explicit Compressed Beamforming Feedback Capable */
4271                 SET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(&ht_capie, 2);
4272                 rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMEE_CAP, (u8 *)&rf_num);
4273                 SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(&ht_capie, rf_num);
4274         }
4275 #endif/*CONFIG_BEAMFORMING*/
4276
4277         pframe = rtw_set_ie(out_ie+out_len, _HT_CAPABILITY_IE_, 
4278                                                 sizeof(struct rtw_ieee80211_ht_cap), (unsigned char*)&ht_capie, pout_len);
4279
4280         phtpriv->ht_option = _TRUE;
4281
4282         if(in_ie!=NULL)
4283         {
4284                 p = rtw_get_ie(in_ie, _HT_ADD_INFO_IE_, &ielen, in_len);
4285                 if(p && (ielen==sizeof(struct ieee80211_ht_addt_info)))
4286                 {
4287                         out_len = *pout_len;            
4288                         pframe = rtw_set_ie(out_ie+out_len, _HT_ADD_INFO_IE_, ielen, p+2 , pout_len);
4289                 }
4290         }
4291
4292         return (phtpriv->ht_option);
4293         
4294 }
4295
4296 //the fucntion is > passive_level (in critical_section)
4297 void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel)
4298 {       
4299         u8 *p, max_ampdu_sz;
4300         int len;                
4301         //struct sta_info *bmc_sta, *psta;
4302         struct rtw_ieee80211_ht_cap *pht_capie;
4303         struct ieee80211_ht_addt_info *pht_addtinfo;
4304         //struct recv_reorder_ctrl *preorder_ctrl;
4305         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
4306         struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
4307         //struct recv_priv *precvpriv = &padapter->recvpriv;
4308         struct registry_priv *pregistrypriv = &padapter->registrypriv;
4309         //struct wlan_network *pcur_network = &(pmlmepriv->cur_network);;
4310         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
4311         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4312         u8 cbw40_enable=0;
4313         
4314
4315         if(!phtpriv->ht_option)
4316                 return;
4317
4318         if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
4319                 return;
4320
4321         DBG_871X("+rtw_update_ht_cap()\n");
4322
4323         //maybe needs check if ap supports rx ampdu.
4324         if((phtpriv->ampdu_enable==_FALSE) &&(pregistrypriv->ampdu_enable==1))
4325         {
4326                 if(pregistrypriv->wifi_spec==1)
4327                 {
4328                         //remove this part because testbed AP should disable RX AMPDU
4329                         //phtpriv->ampdu_enable = _FALSE;
4330                         phtpriv->ampdu_enable = _TRUE;
4331                 }
4332                 else
4333                 {
4334                         phtpriv->ampdu_enable = _TRUE;
4335                 }
4336         }
4337         else if(pregistrypriv->ampdu_enable==2)
4338         {
4339                 //remove this part because testbed AP should disable RX AMPDU
4340                 //phtpriv->ampdu_enable = _TRUE;
4341         }
4342
4343         
4344         //check Max Rx A-MPDU Size 
4345         len = 0;
4346         p = rtw_get_ie(pie+sizeof (NDIS_802_11_FIXED_IEs), _HT_CAPABILITY_IE_, &len, ie_len-sizeof (NDIS_802_11_FIXED_IEs));
4347         if(p && len>0)  
4348         {
4349                 pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
4350                 max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_CAP_AMPDU_FACTOR);
4351                 max_ampdu_sz = 1 << (max_ampdu_sz+3); // max_ampdu_sz (kbytes);
4352                 
4353                 //DBG_871X("rtw_update_ht_cap(): max_ampdu_sz=%d\n", max_ampdu_sz);
4354                 phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
4355                 
4356         }
4357
4358
4359         len=0;
4360         p = rtw_get_ie(pie+sizeof (NDIS_802_11_FIXED_IEs), _HT_ADD_INFO_IE_, &len, ie_len-sizeof (NDIS_802_11_FIXED_IEs));
4361         if(p && len>0)  
4362         {
4363                 pht_addtinfo = (struct ieee80211_ht_addt_info *)(p+2);
4364                 //todo:
4365         }
4366
4367         if (hal_chk_bw_cap(padapter, BW_CAP_40M)) {
4368                 if (channel > 14) {
4369                         if (REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
4370                                 cbw40_enable = 1;
4371                 } else {
4372                         if (REGSTY_IS_BW_2G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
4373                                 cbw40_enable = 1;
4374                 }
4375         }
4376
4377         //update cur_bwmode & cur_ch_offset
4378         if ((cbw40_enable) &&
4379                 (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) && 
4380                 (pmlmeinfo->HT_info.infos[0] & BIT(2)))
4381         {
4382                 int i;
4383                 u8      rf_type = RF_1T1R;
4384
4385                 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
4386
4387                 //update the MCS set
4388                 for (i = 0; i < 16; i++)
4389                         pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i];
4390
4391                 //update the MCS rates
4392                 switch(rf_type)
4393                 {
4394                         case RF_1T1R:
4395                         case RF_1T2R:
4396                                 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R);                                                        
4397                                 break;
4398                         case RF_2T2R:
4399                                 #ifdef CONFIG_DISABLE_MCS13TO15
4400                                 if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 && pregistrypriv->wifi_spec != 1 )                          
4401                                         set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R_13TO15_OFF);                             
4402                                 else
4403                                         set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R);
4404 #else //CONFIG_DISABLE_MCS13TO15
4405                                 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R);
4406 #endif //CONFIG_DISABLE_MCS13TO15
4407                                 break;
4408                         case RF_3T3R:
4409                                 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_3R);
4410                                 break;
4411                         default:
4412                                 DBG_871X("[warning] rf_type %d is not expected\n", rf_type);
4413                 }
4414
4415                 //switch to the 40M Hz mode accoring to the AP
4416                 //pmlmeext->cur_bwmode = CHANNEL_WIDTH_40;
4417                 switch ((pmlmeinfo->HT_info.infos[0] & 0x3))
4418                 {
4419                         case EXTCHNL_OFFSET_UPPER:
4420                                 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
4421                                 break;
4422                         
4423                         case EXTCHNL_OFFSET_LOWER:
4424                                 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
4425                                 break;
4426                                 
4427                         default:
4428                                 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4429                                 break;
4430                 }               
4431         }
4432
4433         //
4434         // Config SM Power Save setting
4435         //
4436         pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
4437         if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
4438         {
4439                 /*u8 i;
4440                 //update the MCS rates
4441                 for (i = 0; i < 16; i++)
4442                 {
4443                         pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
4444                 }*/
4445                 DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__);
4446         }
4447
4448         //
4449         // Config current HT Protection mode.
4450         //
4451         pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
4452
4453         
4454         
4455 #if 0 //move to rtw_update_sta_info_client()
4456         //for A-MPDU Rx reordering buffer control for bmc_sta & sta_info
4457         //if A-MPDU Rx is enabled, reseting  rx_ordering_ctrl wstart_b(indicate_seq) to default value=0xffff
4458         //todo: check if AP can send A-MPDU packets
4459         bmc_sta = rtw_get_bcmc_stainfo(padapter);
4460         if(bmc_sta)
4461         {
4462                 for(i=0; i < 16 ; i++)
4463                 {
4464                         //preorder_ctrl = &precvpriv->recvreorder_ctrl[i];
4465                         preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
4466                         preorder_ctrl->enable = _FALSE;
4467                         preorder_ctrl->indicate_seq = 0xffff;
4468                         #ifdef DBG_RX_SEQ
4469                         DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
4470                                 preorder_ctrl->indicate_seq);
4471                         #endif
4472                         preorder_ctrl->wend_b= 0xffff;
4473                         preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32
4474                 }
4475         }
4476
4477         psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress);
4478         if(psta)
4479         {
4480                 for(i=0; i < 16 ; i++)
4481                 {
4482                         //preorder_ctrl = &precvpriv->recvreorder_ctrl[i];
4483                         preorder_ctrl = &psta->recvreorder_ctrl[i];
4484                         preorder_ctrl->enable = _FALSE;
4485                         preorder_ctrl->indicate_seq = 0xffff;
4486                         #ifdef DBG_RX_SEQ
4487                         DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
4488                                 preorder_ctrl->indicate_seq);
4489                         #endif
4490                         preorder_ctrl->wend_b= 0xffff;
4491                         preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32
4492                 }
4493         }
4494 #endif  
4495
4496 }
4497
4498 #ifdef CONFIG_TDLS
4499 void rtw_issue_addbareq_cmd_tdls(_adapter *padapter, struct xmit_frame *pxmitframe)
4500 {
4501         struct pkt_attrib *pattrib =&pxmitframe->attrib;
4502         struct sta_info *ptdls_sta = NULL;
4503         u8 issued;
4504         int priority;
4505         struct ht_priv  *phtpriv;
4506
4507         priority = pattrib->priority;
4508
4509         if (pattrib->direct_link == _TRUE) {
4510                 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
4511                 if ((ptdls_sta != NULL) && (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)) {
4512                         phtpriv = &ptdls_sta->htpriv;
4513
4514                         if ((phtpriv->ht_option == _TRUE) && (phtpriv->ampdu_enable == _TRUE)) {
4515                                 issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
4516                                 issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
4517
4518                                 if (0 == issued) {
4519                                         DBG_871X("[%s], p=%d\n", __FUNCTION__, priority);
4520                                         ptdls_sta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
4521                                         rtw_addbareq_cmd(padapter,(u8)priority, pattrib->dst);
4522                                 }
4523                         }
4524                 }
4525         }
4526 }
4527 #endif //CONFIG_TDLS
4528
4529 void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe)
4530 {
4531         u8 issued;
4532         int priority;
4533         struct sta_info *psta=NULL;
4534         struct ht_priv  *phtpriv;
4535         struct pkt_attrib *pattrib =&pxmitframe->attrib;
4536         s32 bmcst = IS_MCAST(pattrib->ra);
4537
4538         //if(bmcst || (padapter->mlmepriv.LinkDetectInfo.bTxBusyTraffic == _FALSE))
4539         if(bmcst || (padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod<100))    
4540                 return;
4541         
4542         priority = pattrib->priority;
4543
4544 #ifdef CONFIG_TDLS
4545         rtw_issue_addbareq_cmd_tdls(padapter, pxmitframe);
4546 #endif //CONFIG_TDLS
4547
4548         psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
4549         if(pattrib->psta != psta)
4550         {
4551                 DBG_871X("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
4552                 return;
4553         }
4554         
4555         if(psta==NULL)
4556         {
4557                 DBG_871X("%s, psta==NUL\n", __func__);
4558                 return;
4559         }
4560
4561         if(!(psta->state &_FW_LINKED))
4562         {
4563                 DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
4564                 return;
4565         }       
4566
4567
4568         phtpriv = &psta->htpriv;
4569
4570         if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE)) 
4571         {
4572                 issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
4573                 issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
4574
4575                 if(0==issued)
4576                 {
4577                         DBG_871X("rtw_issue_addbareq_cmd, p=%d\n", priority);
4578                         psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
4579                         rtw_addbareq_cmd(padapter,(u8) priority, pattrib->ra);
4580                 }
4581         }
4582
4583 }
4584
4585 void rtw_append_exented_cap(_adapter *padapter, u8 *out_ie, uint *pout_len)
4586 {
4587         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
4588         struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
4589 #ifdef CONFIG_80211AC_VHT
4590         struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
4591 #endif //CONFIG_80211AC_VHT
4592         u8      cap_content[8] = { 0 };
4593         u8      *pframe;
4594         u8   null_content[8] = {0};
4595
4596         if (phtpriv->bss_coexist) {
4597                 SET_EXT_CAPABILITY_ELE_BSS_COEXIST(cap_content, 1);
4598         }
4599
4600 #ifdef CONFIG_80211AC_VHT
4601         if (pvhtpriv->vht_option) {
4602                 SET_EXT_CAPABILITY_ELE_OP_MODE_NOTIF(cap_content, 1);
4603         }
4604 #endif //CONFIG_80211AC_VHT
4605         /*
4606                 From 802.11 specification,if a STA does not support any of capabilities defined
4607                 in the Extended Capabilities element, then the STA is not required to 
4608                 transmit the Extended Capabilities element. 
4609         */
4610         if (_FALSE == _rtw_memcmp(cap_content, null_content, 8))
4611                 pframe = rtw_set_ie(out_ie + *pout_len, EID_EXTCapability, 8, cap_content , pout_len);
4612 }
4613 #endif
4614
4615 #ifdef CONFIG_LAYER2_ROAMING
4616 inline void rtw_set_to_roam(_adapter *adapter, u8 to_roam)
4617 {
4618         if (to_roam == 0)
4619                 adapter->mlmepriv.to_join = _FALSE;
4620         adapter->mlmepriv.to_roam = to_roam;
4621 }
4622
4623 inline u8 rtw_dec_to_roam(_adapter *adapter)
4624 {
4625         adapter->mlmepriv.to_roam--;
4626         return adapter->mlmepriv.to_roam;
4627 }
4628
4629 inline u8 rtw_to_roam(_adapter *adapter)
4630 {
4631         return adapter->mlmepriv.to_roam;
4632 }
4633
4634 void rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network)
4635 {
4636         _irqL irqL;
4637         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
4638
4639         _enter_critical_bh(&pmlmepriv->lock, &irqL);
4640         _rtw_roaming(padapter, tgt_network);
4641         _exit_critical_bh(&pmlmepriv->lock, &irqL);
4642 }
4643 void _rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network)
4644 {
4645         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
4646         struct wlan_network *cur_network = &pmlmepriv->cur_network;
4647         int do_join_r;
4648         
4649         if(0 < rtw_to_roam(padapter)) {
4650                 DBG_871X("roaming from %s("MAC_FMT"), length:%d\n",
4651                                 cur_network->network.Ssid.Ssid, MAC_ARG(cur_network->network.MacAddress),
4652                                 cur_network->network.Ssid.SsidLength);
4653                 _rtw_memcpy(&pmlmepriv->assoc_ssid, &cur_network->network.Ssid, sizeof(NDIS_802_11_SSID));
4654
4655                 pmlmepriv->assoc_by_bssid = _FALSE;
4656
4657 #ifdef CONFIG_WAPI_SUPPORT
4658                 rtw_wapi_return_all_sta_info(padapter);
4659 #endif
4660
4661                 while(1) {
4662                         if( _SUCCESS==(do_join_r=rtw_do_join(padapter)) ) {
4663                                 break;
4664                         } else {
4665                                 DBG_871X("roaming do_join return %d\n", do_join_r);
4666                                 rtw_dec_to_roam(padapter);
4667                                 
4668                                 if(rtw_to_roam(padapter) > 0) {
4669                                         continue;
4670                                 } else {
4671                                         DBG_871X("%s(%d) -to roaming fail, indicate_disconnect\n", __FUNCTION__,__LINE__);
4672                                         rtw_indicate_disconnect(padapter);
4673                                         break;
4674                                 }
4675                         }
4676                 }
4677         }
4678         
4679 }
4680 #endif /* CONFIG_LAYER2_ROAMING */
4681
4682 bool rtw_adjust_chbw(_adapter *adapter, u8 req_ch, u8 *req_bw, u8 *req_offset)
4683 {
4684         struct registry_priv *regsty = adapter_to_regsty(adapter);
4685         u8 allowed_bw;
4686
4687         if (req_ch <= 14)
4688                 allowed_bw = REGSTY_BW_2G(regsty);
4689         else
4690                 allowed_bw = REGSTY_BW_5G(regsty);
4691
4692         allowed_bw = hal_largest_bw(adapter, allowed_bw);
4693
4694         if (allowed_bw == CHANNEL_WIDTH_80 && *req_bw > CHANNEL_WIDTH_80)
4695                 *req_bw = CHANNEL_WIDTH_80;
4696         else if (allowed_bw == CHANNEL_WIDTH_40 && *req_bw > CHANNEL_WIDTH_40)
4697                 *req_bw = CHANNEL_WIDTH_40;
4698         else if (allowed_bw == CHANNEL_WIDTH_20 && *req_bw > CHANNEL_WIDTH_20) {
4699                 *req_bw = CHANNEL_WIDTH_20;
4700                 *req_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4701         } else
4702                 return _FALSE;
4703
4704         return _TRUE;
4705 }
4706
4707 sint rtw_linked_check(_adapter *padapter)
4708 {
4709         if(     (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) ||
4710                         (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE))
4711         {
4712                 if(padapter->stapriv.asoc_sta_count > 2)
4713                         return _TRUE;
4714         }
4715         else
4716         {       //Station mode
4717                 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)== _TRUE)
4718                         return _TRUE;
4719         }
4720         return _FALSE;
4721 }
4722
4723 #ifdef CONFIG_CONCURRENT_MODE
4724 sint rtw_buddy_adapter_up(_adapter *padapter)
4725 {       
4726         sint res = _FALSE;
4727         
4728         if(padapter == NULL)
4729                 return res;
4730
4731
4732         if(padapter->pbuddy_adapter == NULL)
4733                 res = _FALSE;
4734         else if (RTW_CANNOT_RUN(padapter) ||
4735                 (padapter->pbuddy_adapter->bup == _FALSE) || (!rtw_is_hw_init_completed(padapter)))
4736                 res = _FALSE;
4737         else
4738                 res = _TRUE;
4739
4740         return res;     
4741
4742 }
4743
4744 sint check_buddy_fwstate(_adapter *padapter, sint state)
4745 {
4746         if(padapter == NULL)
4747                 return _FALSE;  
4748         
4749         if(padapter->pbuddy_adapter == NULL)
4750                 return _FALSE;  
4751                 
4752         if ((state == WIFI_FW_NULL_STATE) && 
4753                 (padapter->pbuddy_adapter->mlmepriv.fw_state == WIFI_FW_NULL_STATE))
4754                 return _TRUE;           
4755         
4756         if (padapter->pbuddy_adapter->mlmepriv.fw_state & state)
4757                 return _TRUE;
4758
4759         return _FALSE;
4760 }
4761
4762 u8 rtw_get_buddy_bBusyTraffic(_adapter *padapter)
4763 {
4764         if(padapter == NULL)
4765                 return _FALSE;  
4766         
4767         if(padapter->pbuddy_adapter == NULL)
4768                 return _FALSE;  
4769         
4770         return padapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic;
4771 }
4772
4773 #endif //CONFIG_CONCURRENT_MODE
4774
4775 bool is_miracast_enabled(_adapter *adapter)
4776 {
4777         bool enabled = 0;
4778 #ifdef CONFIG_WFD
4779         struct wifi_display_info *wfdinfo = &adapter->wfd_info;
4780
4781         enabled = (wfdinfo->stack_wfd_mode & (MIRACAST_SOURCE | MIRACAST_SINK))
4782                 || (wfdinfo->op_wfd_mode & (MIRACAST_SOURCE | MIRACAST_SINK));
4783 #endif
4784
4785         return enabled;
4786 }
4787
4788 bool rtw_chk_miracast_mode(_adapter *adapter, u8 mode)
4789 {
4790         bool ret = 0;
4791 #ifdef CONFIG_WFD
4792         struct wifi_display_info *wfdinfo = &adapter->wfd_info;
4793
4794         ret = (wfdinfo->stack_wfd_mode & mode) || (wfdinfo->op_wfd_mode & mode);
4795 #endif
4796
4797         return ret;
4798 }
4799
4800 const char *get_miracast_mode_str(int mode)
4801 {
4802         if (mode == MIRACAST_SOURCE)
4803                 return "SOURCE";
4804         else if (mode == MIRACAST_SINK)
4805                 return "SINK";
4806         else if (mode == (MIRACAST_SOURCE | MIRACAST_SINK))
4807                 return "SOURCE&SINK";
4808         else if (mode == MIRACAST_DISABLED)
4809                 return "DISABLED";
4810         else
4811                 return "INVALID";
4812 }
4813
4814 #ifdef CONFIG_WFD
4815 static bool wfd_st_match_rule(_adapter *adapter, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port)
4816 {
4817         struct wifi_display_info *wfdinfo = &adapter->wfd_info;
4818
4819         if (ntohs(*((u16 *)local_port)) == wfdinfo->rtsp_ctrlport
4820                 || ntohs(*((u16 *)local_port)) == wfdinfo->tdls_rtsp_ctrlport
4821                 || ntohs(*((u16 *)remote_port)) == wfdinfo->peer_rtsp_ctrlport)
4822                 return _TRUE;
4823         return _FALSE;
4824 }
4825
4826 static struct st_register wfd_st_reg = {
4827         .s_proto = 0x06,
4828         .rule = wfd_st_match_rule,
4829 };
4830 #endif /* CONFIG_WFD */
4831
4832 inline void rtw_wfd_st_switch(struct sta_info *sta, bool on)
4833 {
4834 #ifdef CONFIG_WFD
4835         if (on)
4836                 rtw_st_ctl_register(&sta->st_ctl, SESSION_TRACKER_REG_ID_WFD, &wfd_st_reg);
4837         else
4838                 rtw_st_ctl_unregister(&sta->st_ctl, SESSION_TRACKER_REG_ID_WFD);
4839 #endif
4840 }
4841