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