OSDN Git Service

rtl8723au: Convert pu1Byte to "u8 *"
[android-x86/external-modules-rtl8723au.git] / core / rtw_ioctl_set.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 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_IOCTL_SET_C_
21
22 #include <drv_conf.h>
23 #include <osdep_service.h>
24 #include <drv_types.h>
25 #include <rtw_ioctl_set.h>
26 #include <hal_intf.h>
27
28 #include <usb_osintf.h>
29 #include <usb_ops.h>
30 #include <linux/ieee80211.h>
31
32 extern void indicate_wx_scan_complete_event(_adapter *padapter);
33
34 u8 rtw_validate_ssid(NDIS_802_11_SSID *ssid)
35 {
36         u8       i;
37         u8      ret=_TRUE;
38
39 _func_enter_;
40
41         if (ssid->SsidLength > 32) {
42                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid length >32\n"));
43                 ret= _FALSE;
44                 goto exit;
45         }
46
47         for(i = 0; i < ssid->SsidLength; i++)
48         {
49                 /* wifi, printable ascii code must be supported */
50                 if(!( (ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e) )){
51                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid has nonprintabl ascii\n"));
52                         ret= _FALSE;
53                         break;
54                 }
55         }
56
57 exit:
58
59 _func_exit_;
60
61         return ret;
62 }
63
64 u8 rtw_do_join(_adapter * padapter);
65 u8 rtw_do_join(_adapter * padapter)
66 {
67         struct list_head        *plist, *phead;
68         u8* pibss = NULL;
69         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
70         _queue  *queue  = &(pmlmepriv->scanned_queue);
71         u8 ret=_SUCCESS;
72
73 _func_enter_;
74
75         spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
76         phead = get_list_head(queue);
77         plist = phead->next;
78
79         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("\n rtw_do_join: phead = %p; plist = %p \n\n\n", phead, plist));
80
81         pmlmepriv->cur_network.join_res = -2;
82
83         set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
84
85         pmlmepriv->pscanned = plist;
86
87         pmlmepriv->to_join = _TRUE;
88
89         if(_rtw_queue_empty(queue)== _TRUE)
90         {
91                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
92                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
93
94                 /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */
95                 /* we try to issue sitesurvey firstly */
96
97                 if (pmlmepriv->LinkDetectInfo.bBusyTraffic ==_FALSE
98                         || rtw_to_roaming(padapter) > 0
99                 )
100                 {
101                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_do_join(): site survey if scanned_queue is empty\n."));
102                         /*  submit site_survey_cmd */
103                         if(_SUCCESS!=(ret=rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)) ) {
104                                 pmlmepriv->to_join = _FALSE;
105                                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_do_join(): site survey return error\n."));
106                         }
107                 }
108                 else
109                 {
110                         pmlmepriv->to_join = _FALSE;
111                         ret = _FAIL;
112                 }
113
114                 goto exit;
115         }
116         else
117         {
118                 int select_ret;
119                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
120                 if((select_ret=rtw_select_and_join_from_scanned_queue(pmlmepriv))==_SUCCESS)
121                 {
122                         pmlmepriv->to_join = _FALSE;
123                         _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
124                 }
125                 else
126                 {
127                         if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE)
128                         {
129                                 /*  submit createbss_cmd to change to a ADHOC_MASTER */
130
131                                 /* pmlmepriv->lock has been acquired by caller... */
132                                 WLAN_BSSID_EX    *pdev_network = &(padapter->registrypriv.dev_network);
133
134                                 pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
135
136                                 pibss = padapter->registrypriv.dev_network.MacAddress;
137
138                                 memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
139
140                                 rtw_update_registrypriv_dev_network(padapter);
141
142                                 rtw_generate_random_ibss(pibss);
143
144                                 if(rtw_createbss_cmd(padapter)!=_SUCCESS)
145                                 {
146                                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("***Error=>do_goin: rtw_createbss_cmd status FAIL*** \n "));
147                                         ret =  _FALSE;
148                                         goto exit;
149                                 }
150
151                                 pmlmepriv->to_join = _FALSE;
152
153                                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("***Error=> rtw_select_and_join_from_scanned_queue FAIL under STA_Mode*** \n "));
154
155                         }
156                         else
157                         {
158                                 /*  can't associate ; reset under-linking */
159                                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
160
161                                 /* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */
162                                 /* we try to issue sitesurvey firstly */
163                                 if(pmlmepriv->LinkDetectInfo.bBusyTraffic==_FALSE
164                                         || rtw_to_roaming(padapter) > 0
165                                 )
166                                 {
167                                         /* DBG_8723A("rtw_do_join() when   no desired bss in scanning queue \n"); */
168                                         if( _SUCCESS!=(ret=rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)) ){
169                                                 pmlmepriv->to_join = _FALSE;
170                                                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("do_join(): site survey return error\n."));
171                                         }
172                                 }
173                                 else
174                                 {
175                                         ret = _FAIL;
176                                         pmlmepriv->to_join = _FALSE;
177                                 }
178                         }
179
180                 }
181
182         }
183
184 exit:
185
186 _func_exit_;
187
188         return ret;
189 }
190
191 u8 rtw_set_802_11_bssid(_adapter* padapter, u8 *bssid)
192 {
193         u8 status=_SUCCESS;
194         u32 cur_time = 0;
195
196         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
197
198 _func_enter_;
199
200         DBG_8723A_LEVEL(_drv_always_, "set bssid:%pM\n", bssid);
201
202         if (is_zero_ether_addr(bssid) ||
203             is_broadcast_ether_addr(bssid)) {
204                 status = _FAIL;
205                 goto exit;
206         }
207
208         spin_lock_bh(&pmlmepriv->lock);
209
210         DBG_8723A("Set BSSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
211         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
212                 goto handle_tkip_countermeasure;
213         } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
214                 goto release_mlme_lock;
215         }
216
217         if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE)
218         {
219                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
220
221                 if (!memcmp(&pmlmepriv->cur_network.network.MacAddress,
222                             bssid, ETH_ALEN))
223                 {
224                         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)
225                                 goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
226                 } else {
227                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set BSSID not the same bssid\n"));
228                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_bssid="MAC_FMT"\n", MAC_ARG(bssid) ));
229                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("cur_bssid="MAC_FMT"\n", MAC_ARG(pmlmepriv->cur_network.network.MacAddress) ));
230
231                         rtw_disassoc_cmd(padapter, 0, _TRUE);
232
233                         if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
234                                 rtw_indicate_disconnect(padapter);
235
236                         rtw_free_assoc_resources(padapter, 1);
237
238                         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
239                                 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
240                                 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
241                         }
242                 }
243         }
244
245 handle_tkip_countermeasure:
246         /* should we add something here...? */
247
248         if (padapter->securitypriv.btkip_countermeasure == _TRUE) {
249                 cur_time = rtw_get_current_time();
250
251                 if( (cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ )
252                 {
253                         padapter->securitypriv.btkip_countermeasure = _FALSE;
254                         padapter->securitypriv.btkip_countermeasure_time = 0;
255                 }
256                 else
257                 {
258                         status = _FAIL;
259                         goto release_mlme_lock;
260                 }
261         }
262
263         memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
264         pmlmepriv->assoc_by_bssid=_TRUE;
265
266         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
267                 pmlmepriv->to_join = _TRUE;
268         }
269         else {
270                 status = rtw_do_join(padapter);
271         }
272
273 release_mlme_lock:
274         spin_unlock_bh(&pmlmepriv->lock);
275
276 exit:
277         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
278                 ("rtw_set_802_11_bssid: status=%d\n", status));
279
280 _func_exit_;
281
282         return status;
283 }
284
285 u8 rtw_set_802_11_ssid(_adapter* padapter, NDIS_802_11_SSID *ssid)
286 {
287         u8 status = _SUCCESS;
288         u32 cur_time = 0;
289
290         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
291         struct wlan_network *pnetwork = &pmlmepriv->cur_network;
292
293 _func_enter_;
294
295         DBG_8723A_LEVEL(_drv_always_, "set ssid [%s] fw_state=0x%08x\n",
296                         ssid->Ssid, get_fwstate(pmlmepriv));
297
298         if(padapter->hw_init_completed==_FALSE){
299                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
300                          ("set_ssid: hw_init_completed==_FALSE=>exit!!!\n"));
301                 status = _FAIL;
302                 goto exit;
303         }
304
305         spin_lock_bh(&pmlmepriv->lock);
306
307         DBG_8723A("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
308         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
309                 goto handle_tkip_countermeasure;
310         } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
311                 goto release_mlme_lock;
312         }
313
314         if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE)
315         {
316                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
317                          ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
318
319                 if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
320                     !memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength))
321                 {
322                         if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE))
323                         {
324                                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
325                                          ("Set SSID is the same ssid, fw_state=0x%08x\n",
326                                           get_fwstate(pmlmepriv)));
327
328                                 if(rtw_is_same_ibss(padapter, pnetwork) == _FALSE)
329                                 {
330                                         /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */
331                                         rtw_disassoc_cmd(padapter, 0, _TRUE);
332
333                                         if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
334                                                 rtw_indicate_disconnect(padapter);
335
336                                         rtw_free_assoc_resources(padapter, 1);
337
338                                         if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
339                                                 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
340                                                 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
341                                         }
342                                 }
343                                 else
344                                 {
345                                         goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
346                                 }
347                         }
348 #ifdef CONFIG_LPS
349                         else {
350                                 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1);
351                         }
352 #endif
353                 }
354                 else
355                 {
356                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set SSID not the same ssid\n"));
357                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_ssid=[%s] len=0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength));
358                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("assoc_ssid=[%s] len=0x%x\n", pmlmepriv->assoc_ssid.Ssid, (unsigned int)pmlmepriv->assoc_ssid.SsidLength));
359
360                         rtw_disassoc_cmd(padapter, 0, _TRUE);
361
362                         if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
363                                 rtw_indicate_disconnect(padapter);
364
365                         rtw_free_assoc_resources(padapter, 1);
366
367                         if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
368                                 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
369                                 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
370                         }
371                 }
372         }
373
374 handle_tkip_countermeasure:
375
376         if (padapter->securitypriv.btkip_countermeasure == _TRUE) {
377                 cur_time = rtw_get_current_time();
378
379                 if( (cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ )
380                 {
381                         padapter->securitypriv.btkip_countermeasure = _FALSE;
382                         padapter->securitypriv.btkip_countermeasure_time = 0;
383                 }
384                 else
385                 {
386                         status = _FAIL;
387                         goto release_mlme_lock;
388                 }
389         }
390
391         #ifdef CONFIG_VALIDATE_SSID
392         if (rtw_validate_ssid(ssid) == _FALSE) {
393                 status = _FAIL;
394                 goto release_mlme_lock;
395         }
396         #endif
397
398         memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
399         pmlmepriv->assoc_by_bssid=_FALSE;
400
401         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
402                 pmlmepriv->to_join = _TRUE;
403         }
404         else {
405                 status = rtw_do_join(padapter);
406         }
407
408 release_mlme_lock:
409         spin_unlock_bh(&pmlmepriv->lock);
410
411 exit:
412         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
413                 ("-rtw_set_802_11_ssid: status=%d\n", status));
414
415 _func_exit_;
416
417         return status;
418 }
419
420 u8 rtw_set_802_11_infrastructure_mode(_adapter* padapter,
421         NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
422 {
423         struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
424         struct  wlan_network    *cur_network = &pmlmepriv->cur_network;
425         NDIS_802_11_NETWORK_INFRASTRUCTURE* pold_state = &(cur_network->network.InfrastructureMode);
426
427 _func_enter_;
428
429         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_notice_,
430                  ("+rtw_set_802_11_infrastructure_mode: old=%d new=%d fw_state=0x%08x\n",
431                   *pold_state, networktype, get_fwstate(pmlmepriv)));
432
433         if(*pold_state != networktype)
434         {
435                 spin_lock_bh(&pmlmepriv->lock);
436
437                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,(" change mode!"));
438                 /* DBG_8723A("change mode, old_mode=%d, new_mode=%d, fw_state=0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); */
439
440                 if(*pold_state==Ndis802_11APMode)
441                 {
442                         /* change to other mode from Ndis802_11APMode */
443                         cur_network->join_res = -1;
444
445 #ifdef CONFIG_NATIVEAP_MLME
446                         stop_ap_mode(padapter);
447 #endif
448                 }
449
450                 if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) ||(*pold_state==Ndis802_11IBSS))
451                         rtw_disassoc_cmd(padapter, 0, _TRUE);
452
453                 if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) ||
454                         (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)== _TRUE) )
455                         rtw_free_assoc_resources(padapter, 1);
456
457                 if((*pold_state == Ndis802_11Infrastructure) ||(*pold_state == Ndis802_11IBSS))
458                {
459                         if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
460                         {
461                                 rtw_indicate_disconnect(padapter); /* will clr Linked_state; before this function, we must have chked whether  issue dis-assoc_cmd or not */
462                         }
463                }
464
465                 *pold_state = networktype;
466
467                 _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
468
469                 switch(networktype)
470                 {
471                         case Ndis802_11IBSS:
472                                 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
473                                 break;
474
475                         case Ndis802_11Infrastructure:
476                                 set_fwstate(pmlmepriv, WIFI_STATION_STATE);
477                                 break;
478
479                         case Ndis802_11APMode:
480                                 set_fwstate(pmlmepriv, WIFI_AP_STATE);
481 #ifdef CONFIG_NATIVEAP_MLME
482                                 start_ap_mode(padapter);
483                                 /* rtw_indicate_connect(padapter); */
484 #endif
485
486                                 break;
487
488                         case Ndis802_11AutoUnknown:
489                         case Ndis802_11InfrastructureMax:
490                                 break;
491                 }
492
493                 /* SecClearAllKeys(adapter); */
494
495                 /* RT_TRACE(COMP_OID_SET, DBG_LOUD, ("set_infrastructure: fw_state:%x after changing mode\n", */
496                 /*                                                                      get_fwstate(pmlmepriv) )); */
497
498                 spin_unlock_bh(&pmlmepriv->lock);
499         }
500
501 _func_exit_;
502
503         return _TRUE;
504 }
505
506 u8 rtw_set_802_11_disassociate(_adapter *padapter)
507 {
508         struct mlme_priv * pmlmepriv = &padapter->mlmepriv;
509
510 _func_enter_;
511
512         spin_lock_bh(&pmlmepriv->lock);
513
514         if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
515         {
516                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_disassociate: rtw_indicate_disconnect\n"));
517
518                 rtw_disassoc_cmd(padapter, 0, _TRUE);
519                 rtw_indicate_disconnect(padapter);
520                 rtw_free_assoc_resources(padapter, 1);
521                 rtw_pwr_wakeup(padapter);
522         }
523
524         spin_unlock_bh(&pmlmepriv->lock);
525
526 _func_exit_;
527
528         return _TRUE;
529 }
530
531 u8 rtw_set_802_11_bssid_list_scan(_adapter* padapter, NDIS_802_11_SSID *pssid, int ssid_max_num)
532 {
533         struct  mlme_priv               *pmlmepriv= &padapter->mlmepriv;
534         u8      res=_TRUE;
535
536 _func_enter_;
537
538         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("+rtw_set_802_11_bssid_list_scan(), fw_state=%x\n", get_fwstate(pmlmepriv)));
539
540         if (padapter == NULL) {
541                 res=_FALSE;
542                 goto exit;
543         }
544         if (padapter->hw_init_completed==_FALSE){
545                 res = _FALSE;
546                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n===rtw_set_802_11_bssid_list_scan:hw_init_completed==_FALSE===\n"));
547                 goto exit;
548         }
549
550         if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) ||
551                 (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE))
552         {
553                 /*  Scan or linking is in progress, do nothing. */
554                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_bssid_list_scan fail since fw_state = %x\n", get_fwstate(pmlmepriv)));
555                 res = _TRUE;
556
557                 if(check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))== _TRUE){
558                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n###_FW_UNDER_SURVEY|_FW_UNDER_LINKING\n\n"));
559                 } else {
560                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n###pmlmepriv->sitesurveyctrl.traffic_busy==_TRUE\n\n"));
561                 }
562         } else {
563                 if (rtw_is_scan_deny(padapter)) {
564                         DBG_8723A(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter));
565                         indicate_wx_scan_complete_event(padapter);
566                         return _SUCCESS;
567                 }
568
569                 spin_lock_bh(&pmlmepriv->lock);
570
571                 res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0);
572
573                 spin_unlock_bh(&pmlmepriv->lock);
574         }
575 exit:
576
577 _func_exit_;
578
579         return res;
580 }
581
582 u8 rtw_set_802_11_authentication_mode(_adapter* padapter, NDIS_802_11_AUTHENTICATION_MODE authmode)
583 {
584         struct security_priv *psecuritypriv = &padapter->securitypriv;
585         int res;
586         u8 ret;
587
588 _func_enter_;
589
590         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_802_11_auth.mode(): mode=%x\n", authmode));
591
592         psecuritypriv->ndisauthtype=authmode;
593
594         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_authentication_mode:psecuritypriv->ndisauthtype=%d", psecuritypriv->ndisauthtype));
595
596         if(psecuritypriv->ndisauthtype>3)
597                 psecuritypriv->dot11AuthAlgrthm=dot11AuthAlgrthm_8021X;
598
599         res=rtw_set_auth(padapter,psecuritypriv);
600
601         if(res==_SUCCESS)
602                 ret=_TRUE;
603         else
604                 ret=_FALSE;
605
606 _func_exit_;
607
608         return ret;
609 }
610
611 u8 rtw_set_802_11_add_wep(_adapter* padapter, NDIS_802_11_WEP *wep){
612
613         u8              bdefaultkey;
614         u8              btransmitkey;
615         int             keyid,res;
616         struct security_priv* psecuritypriv=&(padapter->securitypriv);
617         u8              ret=_SUCCESS;
618
619 _func_enter_;
620
621         bdefaultkey=(wep->KeyIndex & 0x40000000) > 0 ? _FALSE : _TRUE;   /* for ??? */
622         btransmitkey= (wep->KeyIndex & 0x80000000) > 0 ? _TRUE  : _FALSE;       /* for ??? */
623         keyid=wep->KeyIndex & 0x3fffffff;
624
625         if(keyid >= 4) {
626                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("MgntActrtw_set_802_11_add_wep:keyid>4=>fail\n"));
627                 ret=_FALSE;
628                 goto exit;
629         }
630
631         switch(wep->KeyLength)
632         {
633                 case 5:
634                         psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
635                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength=5\n"));
636                         break;
637                 case 13:
638                         psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
639                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength=13\n"));
640                         break;
641                 default:
642                         psecuritypriv->dot11PrivacyAlgrthm=_NO_PRIVACY_;
643                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength!=5 or 13\n"));
644                         break;
645         }
646
647         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_wep:befor memcpy, wep->KeyLength=0x%x wep->KeyIndex=0x%x  keyid =%x\n",wep->KeyLength,wep->KeyIndex,keyid));
648
649         memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]),&(wep->KeyMaterial),wep->KeyLength);
650
651         psecuritypriv->dot11DefKeylen[keyid]=wep->KeyLength;
652
653         psecuritypriv->dot11PrivacyKeyIndex=keyid;
654
655         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_wep:security key material : %x %x %x %x %x %x %x %x %x %x %x %x %x \n",
656                 psecuritypriv->dot11DefKey[keyid].skey[0],psecuritypriv->dot11DefKey[keyid].skey[1],psecuritypriv->dot11DefKey[keyid].skey[2],
657                 psecuritypriv->dot11DefKey[keyid].skey[3],psecuritypriv->dot11DefKey[keyid].skey[4],psecuritypriv->dot11DefKey[keyid].skey[5],
658                 psecuritypriv->dot11DefKey[keyid].skey[6],psecuritypriv->dot11DefKey[keyid].skey[7],psecuritypriv->dot11DefKey[keyid].skey[8],
659                 psecuritypriv->dot11DefKey[keyid].skey[9],psecuritypriv->dot11DefKey[keyid].skey[10],psecuritypriv->dot11DefKey[keyid].skey[11],
660                 psecuritypriv->dot11DefKey[keyid].skey[12]));
661
662         res=rtw_set_key(padapter,psecuritypriv, keyid, 1);
663
664         if(res==_FAIL)
665                 ret= _FALSE;
666 exit:
667
668 _func_exit_;
669
670         return ret;
671 }
672
673 u8 rtw_set_802_11_remove_wep(_adapter* padapter, u32 keyindex){
674
675         u8 ret=_SUCCESS;
676
677 _func_enter_;
678
679         if (keyindex >= 0x80000000 || padapter == NULL){
680
681                 ret=_FALSE;
682                 goto exit;
683
684         }
685         else
686         {
687                 int res;
688                 struct security_priv* psecuritypriv=&(padapter->securitypriv);
689                 if( keyindex < 4 ){
690
691                         memset(&psecuritypriv->dot11DefKey[keyindex], 0, 16);
692
693                         res=rtw_set_key(padapter,psecuritypriv,keyindex, 0);
694
695                         psecuritypriv->dot11DefKeylen[keyindex]=0;
696
697                         if(res==_FAIL)
698                                 ret=_FAIL;
699
700                 }
701                 else
702                 {
703                         ret=_FAIL;
704                 }
705
706         }
707
708 exit:
709
710 _func_exit_;
711
712         return ret;
713 }
714
715 u8 rtw_set_802_11_add_key(_adapter* padapter, NDIS_802_11_KEY *key){
716
717         uint    encryptionalgo;
718         u8 * pbssid;
719         struct sta_info *stainfo;
720         u8      bgroup = _FALSE;
721         u8      bgrouptkey = _FALSE;/* can be remove later */
722         u8      ret=_SUCCESS;
723
724 _func_enter_;
725
726         if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)){
727
728                 /*  It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination, */
729                 /*  it must fail the request and return NDIS_STATUS_INVALID_DATA. */
730                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key: ((key->KeyIndex & 0x80000000) == 0)[=%d] ",(int)(key->KeyIndex & 0x80000000) == 0));
731                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key:((key->KeyIndex & 0x40000000) > 0)[=%d]" , (int)(key->KeyIndex & 0x40000000) > 0));
732                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key: key->KeyIndex=%d \n" ,(int)key->KeyIndex));
733                 ret= _FAIL;
734                 goto exit;
735         }
736
737         if(key->KeyIndex & 0x40000000)
738         {
739                 /*  Pairwise key */
740
741                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Pairwise key +++++\n"));
742
743                 pbssid=get_bssid(&padapter->mlmepriv);
744                 stainfo=rtw_get_stainfo(&padapter->stapriv, pbssid);
745
746                 if((stainfo!=NULL)&&(padapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)){
747                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:( stainfo!=NULL)&&(Adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)\n"));
748                         encryptionalgo=stainfo->dot118021XPrivacy;
749                 }
750                 else{
751                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: stainfo==NULL)||(Adapter->securitypriv.dot11AuthAlgrthm!=dot11AuthAlgrthm_8021X)\n"));
752                         encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm;
753                 }
754
755                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (encryptionalgo ==%d)!\n",encryptionalgo ));
756                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11PrivacyAlgrthm ==%d)!\n",padapter->securitypriv.dot11PrivacyAlgrthm));
757                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11AuthAlgrthm ==%d)!\n",padapter->securitypriv.dot11AuthAlgrthm));
758
759                 if((stainfo!=NULL)){
760                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (stainfo->dot118021XPrivacy ==%d)!\n", stainfo->dot118021XPrivacy));
761                 }
762
763                 if(key->KeyIndex & 0x000000FF){
764                         /*  The key index is specified in the lower 8 bits by values of zero to 255. */
765                         /*  The key index should be set to zero for a Pairwise key, and the driver should fail with */
766                         /*  NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero */
767                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" key->KeyIndex & 0x000000FF.\n"));
768                         ret= _FAIL;
769                         goto exit;
770                 }
771
772                 /*  check BSSID */
773                 if (is_broadcast_ether_addr(key->BSSID)) {
774
775                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("is_broadcast_ether_addr(key->BSSID)\n"));
776                         ret= _FALSE;
777                         goto exit;
778                 }
779
780                 /*  Check key length for TKIP. */
781                 /* if(encryptionAlgorithm == RT_ENC_TKIP_ENCRYPTION && key->KeyLength != 32) */
782                 if((encryptionalgo== _TKIP_)&& (key->KeyLength != 32)){
783                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("TKIP KeyLength:0x%x != 32\n", key->KeyLength));
784                         ret=_FAIL;
785                         goto exit;
786
787                 }
788
789                 /*  Check key length for AES. */
790                 if((encryptionalgo== _AES_)&& (key->KeyLength != 16)) {
791                         /*  For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case. */
792                         if(key->KeyLength == 32) {
793                                 key->KeyLength = 16;
794                         } else {
795                                 ret= _FAIL;
796                                 goto exit;
797                         }
798                 }
799
800                 /*  Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko. */
801                 if(     (encryptionalgo== _WEP40_|| encryptionalgo== _WEP104_) && (key->KeyLength != 5 && key->KeyLength != 13)) {
802                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("WEP KeyLength:0x%x != 5 or 13\n", key->KeyLength));
803                         ret=_FAIL;
804                         goto exit;
805                 }
806
807                 bgroup = _FALSE;
808
809                 /*  Check the pairwise key. Added by Annie, 2005-07-06. */
810                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n"));
811                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Pairwise Key set]\n"));
812                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n"));
813                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3)));
814                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength));
815                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n"));
816
817         }
818         else
819         {
820                 /*  Group key - KeyIndex(BIT30==0) */
821                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Group key +++++\n"));
822
823                 /*  when add wep key through add key and didn't assigned encryption type before */
824                 if((padapter->securitypriv.ndisauthtype<=3)&&(padapter->securitypriv.dot118021XGrpPrivacy==0))
825                 {
826                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("keylen=%d( Adapter->securitypriv.dot11PrivacyAlgrthm=%x  )padapter->securitypriv.dot118021XGrpPrivacy(%x)\n", key->KeyLength,padapter->securitypriv.dot11PrivacyAlgrthm,padapter->securitypriv.dot118021XGrpPrivacy));
827
828                         switch(key->KeyLength)
829                         {
830                                 case 5:
831                                         padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
832                                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength));
833                                         break;
834                                 case 13:
835                                         padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
836                                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength));
837                                         break;
838                                 default:
839                                         padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
840                                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u \n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength));
841                                         break;
842                         }
843
844                         encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm;
845
846                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" Adapter->securitypriv.dot11PrivacyAlgrthm=%x\n", padapter->securitypriv.dot11PrivacyAlgrthm));
847
848                 }
849                 else
850                 {
851                         encryptionalgo=padapter->securitypriv.dot118021XGrpPrivacy;
852                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("( Adapter->securitypriv.dot11PrivacyAlgrthm=%x  )encryptionalgo(%x)=padapter->securitypriv.dot118021XGrpPrivacy(%x)keylen=%d\n", padapter->securitypriv.dot11PrivacyAlgrthm,encryptionalgo,padapter->securitypriv.dot118021XGrpPrivacy,key->KeyLength));
853
854                 }
855
856                 if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE) && (!is_broadcast_ether_addr(key->BSSID))) {
857                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" IBSS but BSSID is not Broadcast Address.\n"));
858                         ret= _FAIL;
859                         goto exit;
860                 }
861
862                 /*  Check key length for TKIP */
863                 if((encryptionalgo== _TKIP_) && (key->KeyLength != 32)) {
864
865                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" TKIP GTK KeyLength:%u != 32\n", key->KeyLength));
866                         ret= _FAIL;
867                         goto exit;
868
869                 } else if(encryptionalgo== _AES_ && (key->KeyLength != 16 && key->KeyLength != 32) ) {
870
871                         /*  Check key length for AES */
872                         /*  For NDTEST, we allow keylen=32 in this case. 2005.01.27, by rcnjko. */
873                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("<=== SetInfo, OID_802_11_ADD_KEY: AES GTK KeyLength:%u != 16 or 32\n", key->KeyLength));
874                         ret= _FAIL;
875                         goto exit;
876                 }
877
878                 /*  Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03. */
879                 if((encryptionalgo==  _AES_) && (key->KeyLength == 32) ) {
880                         key->KeyLength = 16;
881                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("AES key length changed: %u\n", key->KeyLength) );
882                 }
883
884                 if(key->KeyIndex & 0x8000000) {/* error ??? 0x8000_0000 */
885                         bgrouptkey = _TRUE;
886                 }
887
888                 if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE)&&(check_fwstate(&padapter->mlmepriv, _FW_LINKED)==_TRUE))
889                 {
890                         bgrouptkey = _TRUE;
891                 }
892
893                 bgroup = _TRUE;
894
895                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n") );
896                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Group Key set]\n") );
897                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")) ;
898                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3)));
899                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength)) ;
900                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n"));
901
902         }
903
904         /*  If WEP encryption algorithm, just call rtw_set_802_11_add_wep(). */
905         if((padapter->securitypriv.dot11AuthAlgrthm !=dot11AuthAlgrthm_8021X)&&(encryptionalgo== _WEP40_  || encryptionalgo== _WEP104_))
906         {
907                 u8 ret;
908                 u32 keyindex;
909                 u32 len = FIELD_OFFSET(NDIS_802_11_KEY, KeyMaterial) + key->KeyLength;
910                 NDIS_802_11_WEP *wep = &padapter->securitypriv.ndiswep;
911
912                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ WEP key +++++\n"));
913
914                 wep->Length = len;
915                 keyindex = key->KeyIndex&0x7fffffff;
916                 wep->KeyIndex = keyindex ;
917                 wep->KeyLength = key->KeyLength;
918
919                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:Before memcpy \n"));
920
921                 memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength);
922                 memcpy(&(padapter->securitypriv.dot11DefKey[keyindex].skey[0]), key->KeyMaterial, key->KeyLength);
923
924                 padapter->securitypriv.dot11DefKeylen[keyindex]=key->KeyLength;
925                 padapter->securitypriv.dot11PrivacyKeyIndex=keyindex;
926
927                 ret = rtw_set_802_11_add_wep(padapter, wep);
928
929                 goto exit;
930
931         }
932
933         if(key->KeyIndex & 0x20000000){
934                 /*  SetRSC */
935                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ SetRSC+++++\n"));
936                 if(bgroup == _TRUE)
937                 {
938                         NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL;
939                         memcpy(&padapter->securitypriv.dot11Grprxpn, &keysrc, 8);
940                 }
941                 else
942                 {
943                         NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL;
944                         memcpy(&padapter->securitypriv.dot11Grptxpn, &keysrc, 8);
945                 }
946
947         }
948
949         /*  Indicate this key idx is used for TX */
950         /*  Save the key in KeyMaterial */
951         if(bgroup == _TRUE) /*  Group transmit key */
952         {
953                 int res;
954
955                 if(bgrouptkey == _TRUE)
956                 {
957                         padapter->securitypriv.dot118021XGrpKeyid=(u8)key->KeyIndex;
958                 }
959
960                 if((key->KeyIndex&0x3) == 0){
961                         ret = _FAIL;
962                         goto exit;
963                 }
964
965                 memset(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
966                 memset(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
967                 memset(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
968
969                 if((key->KeyIndex & 0x10000000))
970                 {
971                         memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8);
972                         memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8);
973
974                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
975                                 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1],
976                                 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3],
977                                 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5],
978                                 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7]));
979                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n"));
980
981                 }
982                 else
983                 {
984                         memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8);
985                         memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8);
986
987                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
988                                 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1],
989                                 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3],
990                                 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5],
991                                 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7]));
992                         RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n"));
993
994                 }
995
996                 /* set group key by index */
997                 memcpy(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial, key->KeyLength);
998
999                 key->KeyIndex=key->KeyIndex & 0x03;
1000
1001                 padapter->securitypriv.binstallGrpkey=_TRUE;
1002
1003                 padapter->securitypriv.bcheck_grpkey=_FALSE;
1004
1005                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("reset group key"));
1006
1007                 res=rtw_set_key(padapter,&padapter->securitypriv, key->KeyIndex, 1);
1008
1009                 if(res==_FAIL)
1010                         ret= _FAIL;
1011
1012                 goto exit;
1013
1014         }
1015         else /*  Pairwise Key */
1016         {
1017                 u8 res;
1018
1019                 pbssid=get_bssid(&padapter->mlmepriv);
1020                 stainfo=rtw_get_stainfo(&padapter->stapriv , pbssid );
1021
1022                 if(stainfo!=NULL)
1023                 {
1024                         memcpy(&stainfo->dot118021x_UncstKey, key->KeyMaterial, 16);
1025
1026                         if(encryptionalgo== _TKIP_)
1027                         {
1028                                 padapter->securitypriv.busetkipkey=_FALSE;
1029
1030                                 /* _set_timer(&padapter->securitypriv.tkip_timer, 50); */
1031
1032                                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n ==========_set_timer\n"));
1033
1034                                 /*  if TKIP, save the Receive/Transmit MIC key in KeyMaterial[128-255] */
1035                                 if((key->KeyIndex & 0x10000000)){
1036                                         memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 16, 8);
1037                                         memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 24, 8);
1038
1039                                 } else {
1040                                         memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 24, 8);
1041                                         memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 16, 8);
1042
1043                                 }
1044
1045                         }
1046                         else if(encryptionalgo == _AES_)
1047                         {
1048
1049                         }
1050
1051                         /* Set key to CAM through H2C command */
1052                         if(bgrouptkey)/* never go to here */
1053                         {
1054                                 res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _FALSE);
1055                                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(group)\n"));
1056                         }
1057                         else{
1058                                 res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _TRUE);
1059                                 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(unicast)\n"));
1060                         }
1061
1062                         if(res ==_FALSE)
1063                                 ret= _FAIL;
1064
1065                 }
1066
1067         }
1068
1069 exit:
1070
1071 _func_exit_;
1072
1073         return ret;
1074 }
1075
1076 u8 rtw_set_802_11_remove_key(_adapter*  padapter, NDIS_802_11_REMOVE_KEY *key){
1077
1078         uint                            encryptionalgo;
1079         u8 * pbssid;
1080         struct sta_info *stainfo;
1081         u8      bgroup = (key->KeyIndex & 0x4000000) > 0 ? _FALSE: _TRUE;
1082         u8      keyIndex = (u8)key->KeyIndex & 0x03;
1083         u8      ret=_SUCCESS;
1084
1085 _func_enter_;
1086
1087         if ((key->KeyIndex & 0xbffffffc) > 0) {
1088                 ret=_FAIL;
1089                 goto exit;
1090         }
1091
1092         if (bgroup == _TRUE) {
1093                 encryptionalgo= padapter->securitypriv.dot118021XGrpPrivacy;
1094                 /*  clear group key by index */
1095                 /* NdisZeroMemory(Adapter->MgntInfo.SecurityInfo.KeyBuf[keyIndex], MAX_WEP_KEY_LEN); */
1096                 /* Adapter->MgntInfo.SecurityInfo.KeyLen[keyIndex] = 0; */
1097
1098                 memset(&padapter->securitypriv.dot118021XGrpKey[keyIndex], 0, 16);
1099
1100                 /*  \todo Send a H2C Command to Firmware for removing this Key in CAM Entry. */
1101
1102         } else {
1103
1104                 pbssid=get_bssid(&padapter->mlmepriv);
1105                 stainfo=rtw_get_stainfo(&padapter->stapriv , pbssid );
1106                 if(stainfo !=NULL){
1107                         encryptionalgo=stainfo->dot118021XPrivacy;
1108
1109                 /*  clear key by BSSID */
1110                 memset(&stainfo->dot118021x_UncstKey, 0, 16);
1111
1112                 /*  \todo Send a H2C Command to Firmware for disable this Key in CAM Entry. */
1113
1114                 }
1115                 else{
1116                         ret= _FAIL;
1117                         goto exit;
1118                 }
1119         }
1120
1121 exit:
1122
1123 _func_exit_;
1124
1125         return _TRUE;
1126 }
1127
1128 /*
1129 * rtw_get_cur_max_rate -
1130 * @adapter: pointer to _adapter structure
1131 *
1132 * Return 0 or 100Kbps
1133 */
1134 u16 rtw_get_cur_max_rate(_adapter *adapter)
1135 {
1136         int     i = 0;
1137         u8      *p;
1138         u16     rate = 0, max_rate = 0;
1139         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
1140         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1141         struct registry_priv *pregistrypriv = &adapter->registrypriv;
1142         struct mlme_priv        *pmlmepriv = &adapter->mlmepriv;
1143         WLAN_BSSID_EX  *pcur_bss = &pmlmepriv->cur_network.network;
1144 #ifdef CONFIG_80211N_HT
1145         struct ieee80211_ht_cap *pht_capie;
1146         u8      rf_type = 0;
1147         u8      bw_40MHz=0, short_GI_20=0, short_GI_40=0;
1148         u16     mcs_rate=0;
1149         u32     ht_ielen = 0;
1150 #endif
1151
1152         if((check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE)
1153                 && (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE))
1154                 return 0;
1155
1156 #ifdef CONFIG_80211N_HT
1157         if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N|WIRELESS_11_5N)) {
1158                 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12);
1159                 if(p && ht_ielen>0)
1160                 {
1161                         pht_capie = (struct ieee80211_ht_cap *)(p+2);
1162
1163                         memcpy(&mcs_rate , &pht_capie->mcs, 2);
1164
1165                         /* bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1:0; */
1166                         /* cur_bwmod is updated by beacon, pmlmeinfo is updated by association response */
1167                         bw_40MHz = (pmlmeext->cur_bwmode && (HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH & pmlmeinfo->HT_info.infos[0])) ? 1:0;
1168
1169                         /* short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1:0; */
1170                         short_GI_20 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info&IEEE80211_HT_CAP_SGI_20) ? 1:0;
1171                         short_GI_40 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info&IEEE80211_HT_CAP_SGI_40) ? 1:0;
1172
1173                         rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
1174                         max_rate = rtw_mcs_rate(
1175                                 rf_type,
1176                                 bw_40MHz & (pregistrypriv->cbw40_enable),
1177                                 short_GI_20,
1178                                 short_GI_40,
1179                                 pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate
1180                         );
1181                 }
1182         }
1183         else
1184 #endif /* CONFIG_80211N_HT */
1185         {
1186                 while( (pcur_bss->SupportedRates[i]!=0) && (pcur_bss->SupportedRates[i]!=0xFF))
1187                 {
1188                         rate = pcur_bss->SupportedRates[i]&0x7F;
1189                         if(rate>max_rate)
1190                                 max_rate = rate;
1191                         i++;
1192                 }
1193
1194                 max_rate = max_rate*10/2;
1195         }
1196
1197         return max_rate;
1198 }
1199
1200 /*
1201 * rtw_set_scan_mode -
1202 * @adapter: pointer to _adapter structure
1203 * @scan_mode:
1204 *
1205 * Return _SUCCESS or _FAIL
1206 */
1207 int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode)
1208 {
1209         if(scan_mode != SCAN_ACTIVE && scan_mode != SCAN_PASSIVE)
1210                 return _FAIL;
1211
1212         adapter->mlmepriv.scan_mode = scan_mode;
1213
1214         return _SUCCESS;
1215 }
1216
1217 /*
1218 * rtw_set_channel_plan -
1219 * @adapter: pointer to _adapter structure
1220 * @channel_plan:
1221 *
1222 * Return _SUCCESS or _FAIL
1223 */
1224 int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan)
1225 {
1226         struct registry_priv *pregistrypriv = &adapter->registrypriv;
1227         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1228
1229         /* handle by cmd_thread to sync with scan operation */
1230         return rtw_set_chplan_cmd(adapter, channel_plan, 1);
1231 }
1232
1233 /*
1234 * rtw_set_country -
1235 * @adapter: pointer to _adapter structure
1236 * @country_code: string of country code
1237 *
1238 * Return _SUCCESS or _FAIL
1239 */
1240 int rtw_set_country(_adapter *adapter, const char *country_code)
1241 {
1242         int channel_plan = RT_CHANNEL_DOMAIN_WORLD_WIDE_5G;
1243
1244         DBG_8723A("%s country_code:%s\n", __func__, country_code);
1245
1246         /* TODO: should have a table to match country code and RT_CHANNEL_DOMAIN */
1247         /* TODO: should consider 2-character and 3-character country code */
1248         if(0 == strcmp(country_code, "US"))
1249                 channel_plan = RT_CHANNEL_DOMAIN_FCC;
1250         else if(0 == strcmp(country_code, "EU"))
1251                 channel_plan = RT_CHANNEL_DOMAIN_ETSI;
1252         else if(0 == strcmp(country_code, "JP"))
1253                 channel_plan = RT_CHANNEL_DOMAIN_MKK;
1254         else if(0 == strcmp(country_code, "CN"))
1255                 channel_plan = RT_CHANNEL_DOMAIN_CHINA;
1256         else
1257                 DBG_8723A("%s unknown country_code:%s\n", __FUNCTION__, country_code);
1258
1259         return rtw_set_channel_plan(adapter, channel_plan);
1260 }