OSDN Git Service

staging: rtl8723bs: update to the latest driver
[android-x86/kernel.git] / drivers / staging / rtl8723bs / 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  ******************************************************************************/
15 #define _RTW_IOCTL_SET_C_
16
17 #include <drv_types.h>
18 #include <rtw_debug.h>
19
20 #define IS_MAC_ADDRESS_BROADCAST(addr) \
21 (\
22         ((addr[0] == 0xff) && (addr[1] == 0xff) && \
23                 (addr[2] == 0xff) && (addr[3] == 0xff) && \
24                 (addr[4] == 0xff) && (addr[5] == 0xff))  ? true : false \
25 )
26
27 u8 rtw_validate_bssid(u8 *bssid)
28 {
29         u8 ret = true;
30
31         if (is_zero_mac_addr(bssid)
32                 || is_broadcast_mac_addr(bssid)
33                 || is_multicast_mac_addr(bssid)
34         ) {
35                 ret = false;
36         }
37
38         return ret;
39 }
40
41 u8 rtw_validate_ssid(struct ndis_802_11_ssid *ssid)
42 {
43         u8 ret =true;
44
45         if (ssid->SsidLength > 32) {
46                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid length >32\n"));
47                 ret = false;
48                 goto exit;
49         }
50
51 #ifdef CONFIG_VALIDATE_SSID
52         for (i = 0; i < ssid->SsidLength; i++)
53         {
54                 /* wifi, printable ascii code must be supported */
55                 if (!((ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e))) {
56                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid has nonprintabl ascii\n"));
57                         ret = false;
58                         break;
59                 }
60         }
61 #endif /* CONFIG_VALIDATE_SSID */
62
63 exit:
64         return ret;
65 }
66
67 u8 rtw_do_join(struct adapter *padapter);
68 u8 rtw_do_join(struct adapter *padapter)
69 {
70         struct list_head        *plist, *phead;
71         u8 *pibss = NULL;
72         struct  mlme_priv *pmlmepriv = &(padapter->mlmepriv);
73         struct __queue  *queue  = &(pmlmepriv->scanned_queue);
74         u8 ret = _SUCCESS;
75
76         spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
77         phead = get_list_head(queue);
78         plist = get_next(phead);
79
80         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("\n rtw_do_join: phead = %p; plist = %p\n\n\n", phead, plist));
81
82         pmlmepriv->cur_network.join_res = -2;
83
84         set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
85
86         pmlmepriv->pscanned = plist;
87
88         pmlmepriv->to_join = true;
89
90         if (list_empty(&queue->queue))
91         {
92                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
93                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
94
95                 /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */
96                 /* we try to issue sitesurvey firstly */
97
98                 if (pmlmepriv->LinkDetectInfo.bBusyTraffic ==false
99                         || rtw_to_roam(padapter) > 0
100                 )
101                 {
102                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("rtw_do_join(): site survey if scanned_queue is empty\n."));
103                         /*  submit site_survey_cmd */
104                         if (_SUCCESS!=(ret =rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0))) {
105                                 pmlmepriv->to_join = false;
106                                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_do_join(): site survey return error\n."));
107                         }
108                 }
109                 else
110                 {
111                         pmlmepriv->to_join = false;
112                         ret = _FAIL;
113                 }
114
115                 goto exit;
116         }
117         else
118         {
119                 int select_ret;
120                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
121                 if ((select_ret =rtw_select_and_join_from_scanned_queue(pmlmepriv)) == _SUCCESS)
122                 {
123                         pmlmepriv->to_join = false;
124                         _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
125                 }
126                 else
127                 {
128                         if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ==true)
129                         {
130                                 /*  submit createbss_cmd to change to a ADHOC_MASTER */
131
132                                 /* pmlmepriv->lock has been acquired by caller... */
133                                 struct wlan_bssid_ex    *pdev_network = &(padapter->registrypriv.dev_network);
134
135                                 pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
136
137                                 pibss = padapter->registrypriv.dev_network.MacAddress;
138
139                                 memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
140                                 memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
141
142                                 rtw_update_registrypriv_dev_network(padapter);
143
144                                 rtw_generate_random_ibss(pibss);
145
146                                 if (rtw_createbss_cmd(padapter)!= _SUCCESS)
147                                 {
148                                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("***Error =>do_goin: rtw_createbss_cmd status FAIL***\n "));
149                                         ret =  false;
150                                         goto exit;
151                                 }
152
153                                 pmlmepriv->to_join = false;
154
155                                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("***Error => rtw_select_and_join_from_scanned_queue FAIL under STA_Mode***\n "));
156
157                         }
158                         else
159                         {
160                                 /*  can't associate ; reset under-linking */
161                                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
162
163                                 /* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */
164                                 /* we try to issue sitesurvey firstly */
165                                 if (pmlmepriv->LinkDetectInfo.bBusyTraffic ==false
166                                         || rtw_to_roam(padapter) > 0
167                                 )
168                                 {
169                                         /* DBG_871X("rtw_do_join() when   no desired bss in scanning queue\n"); */
170                                         if (_SUCCESS!=(ret =rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0))) {
171                                                 pmlmepriv->to_join = false;
172                                                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("do_join(): site survey return error\n."));
173                                         }
174                                 }
175                                 else
176                                 {
177                                         ret = _FAIL;
178                                         pmlmepriv->to_join = false;
179                                 }
180                         }
181
182                 }
183
184         }
185
186 exit:
187         return ret;
188 }
189
190 u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid)
191 {
192         u8 status = _SUCCESS;
193
194         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
195
196         DBG_871X_LEVEL(_drv_always_, "set bssid:%pM\n", bssid);
197
198         if ((bssid[0]== 0x00 && bssid[1]== 0x00 && bssid[2]== 0x00 && bssid[3]== 0x00 && bssid[4]== 0x00 &&bssid[5]== 0x00) ||
199             (bssid[0]== 0xFF && bssid[1]== 0xFF && bssid[2]== 0xFF && bssid[3]== 0xFF && bssid[4]== 0xFF &&bssid[5]== 0xFF))
200         {
201                 status = _FAIL;
202                 goto exit;
203         }
204
205         spin_lock_bh(&pmlmepriv->lock);
206
207
208         DBG_871X("Set BSSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
209         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
210                 goto handle_tkip_countermeasure;
211         } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
212                 goto release_mlme_lock;
213         }
214
215         if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true)
216         {
217                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
218
219                 if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN))
220                 {
221                         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)
222                                 goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
223                 } else {
224                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("Set BSSID not the same bssid\n"));
225                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid ="MAC_FMT"\n", MAC_ARG(bssid)));
226                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("cur_bssid ="MAC_FMT"\n", MAC_ARG(pmlmepriv->cur_network.network.MacAddress)));
227
228                         rtw_disassoc_cmd(padapter, 0, true);
229
230                         if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
231                                 rtw_indicate_disconnect(padapter);
232
233                         rtw_free_assoc_resources(padapter, 1);
234
235                         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
236                                 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
237                                 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
238                         }
239                 }
240         }
241
242 handle_tkip_countermeasure:
243         if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
244                 status = _FAIL;
245                 goto release_mlme_lock;
246         }
247
248         memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
249         memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
250         pmlmepriv->assoc_by_bssid =true;
251
252         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
253                 pmlmepriv->to_join = true;
254         }
255         else {
256                 status = rtw_do_join(padapter);
257         }
258
259 release_mlme_lock:
260         spin_unlock_bh(&pmlmepriv->lock);
261
262 exit:
263         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
264                 ("rtw_set_802_11_bssid: status =%d\n", status));
265
266         return status;
267 }
268
269 u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid)
270 {
271         u8 status = _SUCCESS;
272
273         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
274         struct wlan_network *pnetwork = &pmlmepriv->cur_network;
275
276         DBG_871X_LEVEL(_drv_always_, "set ssid [%s] fw_state = 0x%08x\n",
277                         ssid->Ssid, get_fwstate(pmlmepriv));
278
279         if (padapter->hw_init_completed ==false) {
280                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
281                          ("set_ssid: hw_init_completed ==false =>exit!!!\n"));
282                 status = _FAIL;
283                 goto exit;
284         }
285
286         spin_lock_bh(&pmlmepriv->lock);
287
288         DBG_871X("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
289         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
290                 goto handle_tkip_countermeasure;
291         } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
292                 goto release_mlme_lock;
293         }
294
295         if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true)
296         {
297                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
298                          ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
299
300                 if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
301                     (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength)))
302                 {
303                         if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false))
304                         {
305                                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
306                                          ("Set SSID is the same ssid, fw_state = 0x%08x\n",
307                                           get_fwstate(pmlmepriv)));
308
309                                 if (rtw_is_same_ibss(padapter, pnetwork) == false)
310                                 {
311                                         /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */
312                                         rtw_disassoc_cmd(padapter, 0, true);
313
314                                         if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
315                                                 rtw_indicate_disconnect(padapter);
316
317                                         rtw_free_assoc_resources(padapter, 1);
318
319                                         if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
320                                                 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
321                                                 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
322                                         }
323                                 }
324                                 else
325                                 {
326                                         goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
327                                 }
328                         }
329                         else {
330                                 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1);
331                         }
332                 }
333                 else
334                 {
335                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("Set SSID not the same ssid\n"));
336                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid =[%s] len = 0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength));
337                         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));
338
339                         rtw_disassoc_cmd(padapter, 0, true);
340
341                         if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
342                                 rtw_indicate_disconnect(padapter);
343
344                         rtw_free_assoc_resources(padapter, 1);
345
346                         if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
347                                 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
348                                 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
349                         }
350                 }
351         }
352
353 handle_tkip_countermeasure:
354         if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
355                 status = _FAIL;
356                 goto release_mlme_lock;
357         }
358
359         if (rtw_validate_ssid(ssid) == false) {
360                 status = _FAIL;
361                 goto release_mlme_lock;
362         }
363
364         memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid));
365         pmlmepriv->assoc_by_bssid =false;
366
367         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
368                 pmlmepriv->to_join = true;
369         }
370         else {
371                 status = rtw_do_join(padapter);
372         }
373
374 release_mlme_lock:
375         spin_unlock_bh(&pmlmepriv->lock);
376
377 exit:
378         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
379                 ("-rtw_set_802_11_ssid: status =%d\n", status));
380
381         return status;
382 }
383
384 u8 rtw_set_802_11_connect(struct adapter *padapter, u8 *bssid, struct ndis_802_11_ssid *ssid)
385 {
386         u8 status = _SUCCESS;
387         bool bssid_valid = true;
388         bool ssid_valid = true;
389         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
390
391         if (!ssid || rtw_validate_ssid(ssid) == false)
392                 ssid_valid = false;
393
394         if (!bssid || rtw_validate_bssid(bssid) == false)
395                 bssid_valid = false;
396
397         if (ssid_valid == false && bssid_valid == false) {
398                 DBG_871X(FUNC_ADPT_FMT" ssid:%p, ssid_valid:%d, bssid:%p, bssid_valid:%d\n",
399                         FUNC_ADPT_ARG(padapter), ssid, ssid_valid, bssid, bssid_valid);
400                 status = _FAIL;
401                 goto exit;
402         }
403
404         if (padapter->hw_init_completed ==false) {
405                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
406                          ("set_ssid: hw_init_completed ==false =>exit!!!\n"));
407                 status = _FAIL;
408                 goto exit;
409         }
410
411         spin_lock_bh(&pmlmepriv->lock);
412
413         DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT"  fw_state = 0x%08x\n",
414                 FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv));
415
416         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
417                 goto handle_tkip_countermeasure;
418         } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
419                 goto release_mlme_lock;
420         }
421
422 handle_tkip_countermeasure:
423         if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
424                 status = _FAIL;
425                 goto release_mlme_lock;
426         }
427
428         if (ssid && ssid_valid)
429                 memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid));
430         else
431                 memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
432
433         if (bssid && bssid_valid) {
434                 memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
435                 pmlmepriv->assoc_by_bssid = true;
436         } else {
437                 pmlmepriv->assoc_by_bssid = false;
438         }
439
440         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
441                 pmlmepriv->to_join = true;
442         }
443         else {
444                 status = rtw_do_join(padapter);
445         }
446
447 release_mlme_lock:
448         spin_unlock_bh(&pmlmepriv->lock);
449
450 exit:
451         return status;
452 }
453
454 u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter,
455         enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
456 {
457         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
458         struct  wlan_network    *cur_network = &pmlmepriv->cur_network;
459         enum NDIS_802_11_NETWORK_INFRASTRUCTURE *pold_state = &(cur_network->network.InfrastructureMode);
460
461         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_,
462                  ("+rtw_set_802_11_infrastructure_mode: old =%d new =%d fw_state = 0x%08x\n",
463                   *pold_state, networktype, get_fwstate(pmlmepriv)));
464
465         if (*pold_state != networktype)
466         {
467                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, (" change mode!"));
468                 /* DBG_871X("change mode, old_mode =%d, new_mode =%d, fw_state = 0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); */
469
470                 if (*pold_state ==Ndis802_11APMode)
471                 {
472                         /* change to other mode from Ndis802_11APMode */
473                         cur_network->join_res = -1;
474
475                         stop_ap_mode(padapter);
476                 }
477
478                 spin_lock_bh(&pmlmepriv->lock);
479
480                 if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||(*pold_state ==Ndis802_11IBSS))
481                         rtw_disassoc_cmd(padapter, 0, true);
482
483                 if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||
484                         (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true))
485                         rtw_free_assoc_resources(padapter, 1);
486
487                 if ((*pold_state == Ndis802_11Infrastructure) ||(*pold_state == Ndis802_11IBSS))
488                {
489                         if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
490                         {
491                                 rtw_indicate_disconnect(padapter); /* will clr Linked_state; before this function, we must have chked whether  issue dis-assoc_cmd or not */
492                         }
493                }
494
495                 *pold_state = networktype;
496
497                 _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
498
499                 switch (networktype)
500                 {
501                         case Ndis802_11IBSS:
502                                 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
503                                 break;
504
505                         case Ndis802_11Infrastructure:
506                                 set_fwstate(pmlmepriv, WIFI_STATION_STATE);
507                                 break;
508
509                         case Ndis802_11APMode:
510                                 set_fwstate(pmlmepriv, WIFI_AP_STATE);
511                                 start_ap_mode(padapter);
512                                 /* rtw_indicate_connect(padapter); */
513
514                                 break;
515
516                         case Ndis802_11AutoUnknown:
517                         case Ndis802_11InfrastructureMax:
518                                 break;
519                 }
520
521                 /* SecClearAllKeys(adapter); */
522
523                 /* RT_TRACE(COMP_OID_SET, DBG_LOUD, ("set_infrastructure: fw_state:%x after changing mode\n", */
524                 /*                                                                      get_fwstate(pmlmepriv))); */
525
526                 spin_unlock_bh(&pmlmepriv->lock);
527         }
528         return true;
529 }
530
531
532 u8 rtw_set_802_11_disassociate(struct adapter *padapter)
533 {
534         struct mlme_priv * pmlmepriv = &padapter->mlmepriv;
535
536         spin_lock_bh(&pmlmepriv->lock);
537
538         if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
539         {
540                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_disassociate: rtw_indicate_disconnect\n"));
541
542                 rtw_disassoc_cmd(padapter, 0, true);
543                 rtw_indicate_disconnect(padapter);
544                 /* modify for CONFIG_IEEE80211W, none 11w can use it */
545                 rtw_free_assoc_resources_cmd(padapter);
546                 if (_FAIL == rtw_pwr_wakeup(padapter))
547                         DBG_871X("%s(): rtw_pwr_wakeup fail !!!\n", __func__);
548         }
549
550         spin_unlock_bh(&pmlmepriv->lock);
551
552         return true;
553 }
554
555 u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_ssid *pssid, int ssid_max_num)
556 {
557         struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
558         u8 res =true;
559
560         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("+rtw_set_802_11_bssid_list_scan(), fw_state =%x\n", get_fwstate(pmlmepriv)));
561
562         if (padapter == NULL) {
563                 res =false;
564                 goto exit;
565         }
566         if (padapter->hw_init_completed ==false) {
567                 res = false;
568                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n ===rtw_set_802_11_bssid_list_scan:hw_init_completed ==false ===\n"));
569                 goto exit;
570         }
571
572         if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true) ||
573                 (pmlmepriv->LinkDetectInfo.bBusyTraffic == true))
574         {
575                 /*  Scan or linking is in progress, do nothing. */
576                 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)));
577                 res = true;
578
579                 if (check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)) == true) {
580                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n###_FW_UNDER_SURVEY|_FW_UNDER_LINKING\n\n"));
581                 } else {
582                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n###pmlmepriv->sitesurveyctrl.traffic_busy ==true\n\n"));
583                 }
584         } else {
585                 if (rtw_is_scan_deny(padapter)) {
586                         DBG_871X(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter));
587                         indicate_wx_scan_complete_event(padapter);
588                         return _SUCCESS;
589                 }
590
591                 spin_lock_bh(&pmlmepriv->lock);
592
593                 res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0);
594
595                 spin_unlock_bh(&pmlmepriv->lock);
596         }
597 exit:
598
599         return res;
600 }
601
602 u8 rtw_set_802_11_authentication_mode(struct adapter *padapter, enum NDIS_802_11_AUTHENTICATION_MODE authmode)
603 {
604         struct security_priv *psecuritypriv = &padapter->securitypriv;
605         int res;
606         u8 ret;
607
608         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_802_11_auth.mode(): mode =%x\n", authmode));
609
610         psecuritypriv->ndisauthtype =authmode;
611
612         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("rtw_set_802_11_authentication_mode:psecuritypriv->ndisauthtype =%d", psecuritypriv->ndisauthtype));
613
614         if (psecuritypriv->ndisauthtype>3)
615                 psecuritypriv->dot11AuthAlgrthm =dot11AuthAlgrthm_8021X;
616
617         res =rtw_set_auth(padapter, psecuritypriv);
618
619         if (res == _SUCCESS)
620                 ret =true;
621         else
622                 ret =false;
623
624         return ret;
625 }
626
627 u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep) {
628
629         u8 bdefaultkey;
630         u8 btransmitkey;
631         sint            keyid, res;
632         struct security_priv* psecuritypriv =&(padapter->securitypriv);
633         u8 ret = _SUCCESS;
634
635         bdefaultkey =(wep->KeyIndex & 0x40000000) > 0 ? false : true;   /* for ??? */
636         btransmitkey = (wep->KeyIndex & 0x80000000) > 0 ? true  : false;        /* for ??? */
637         keyid =wep->KeyIndex & 0x3fffffff;
638
639         if (keyid>=4)
640         {
641                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("MgntActrtw_set_802_11_add_wep:keyid>4 =>fail\n"));
642                 ret =false;
643                 goto exit;
644         }
645
646         switch (wep->KeyLength)
647         {
648                 case 5:
649                         psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
650                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength =5\n"));
651                         break;
652                 case 13:
653                         psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
654                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength = 13\n"));
655                         break;
656                 default:
657                         psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
658                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength!=5 or 13\n"));
659                         break;
660         }
661
662         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));
663
664         memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]),&(wep->KeyMaterial), wep->KeyLength);
665
666         psecuritypriv->dot11DefKeylen[keyid]=wep->KeyLength;
667
668         psecuritypriv->dot11PrivacyKeyIndex =keyid;
669
670         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",
671                 psecuritypriv->dot11DefKey[keyid].skey[0], psecuritypriv->dot11DefKey[keyid].skey[1], psecuritypriv->dot11DefKey[keyid].skey[2],
672                 psecuritypriv->dot11DefKey[keyid].skey[3], psecuritypriv->dot11DefKey[keyid].skey[4], psecuritypriv->dot11DefKey[keyid].skey[5],
673                 psecuritypriv->dot11DefKey[keyid].skey[6], psecuritypriv->dot11DefKey[keyid].skey[7], psecuritypriv->dot11DefKey[keyid].skey[8],
674                 psecuritypriv->dot11DefKey[keyid].skey[9], psecuritypriv->dot11DefKey[keyid].skey[10], psecuritypriv->dot11DefKey[keyid].skey[11],
675                 psecuritypriv->dot11DefKey[keyid].skey[12]));
676
677         res =rtw_set_key(padapter, psecuritypriv, keyid, 1, true);
678
679         if (res == _FAIL)
680                 ret = false;
681 exit:
682
683         return ret;
684 }
685
686 /*
687 * rtw_get_cur_max_rate -
688 * @adapter: pointer to struct adapter structure
689 *
690 * Return 0 or 100Kbps
691 */
692 u16 rtw_get_cur_max_rate(struct adapter *adapter)
693 {
694         int     i = 0;
695         u16 rate = 0, max_rate = 0;
696         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
697         struct wlan_bssid_ex    *pcur_bss = &pmlmepriv->cur_network.network;
698         struct sta_info *psta = NULL;
699         u8 short_GI = 0;
700         u8 rf_type = 0;
701
702         if ((check_fwstate(pmlmepriv, _FW_LINKED) != true)
703                 && (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != true))
704                 return 0;
705
706         psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
707         if (psta == NULL)
708                 return 0;
709
710         short_GI = query_ra_short_GI(psta);
711
712         if (IsSupportedHT(psta->wireless_mode)) {
713                 rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
714
715                 max_rate = rtw_mcs_rate(
716                         rf_type,
717                         ((psta->bw_mode == CHANNEL_WIDTH_40)?1:0),
718                         short_GI,
719                         psta->htpriv.ht_cap.supp_mcs_set
720                 );
721         }
722         else
723         {
724                 while ((pcur_bss->SupportedRates[i]!= 0) && (pcur_bss->SupportedRates[i]!= 0xFF))
725                 {
726                         rate = pcur_bss->SupportedRates[i]&0x7F;
727                         if (rate>max_rate)
728                                 max_rate = rate;
729                         i++;
730                 }
731
732                 max_rate = max_rate*10/2;
733         }
734
735         return max_rate;
736 }