GNU Linux-libre 4.9.309-gnu1
[releases.git] / drivers / staging / rtl8188eu / 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 <osdep_service.h>
18 #include <drv_types.h>
19 #include <rtw_ioctl_set.h>
20 #include <hal_intf.h>
21
22 extern void indicate_wx_scan_complete_event(struct adapter *padapter);
23
24 u8 rtw_do_join(struct adapter *padapter)
25 {
26         struct list_head *plist, *phead;
27         u8 *pibss = NULL;
28         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
29         struct __queue *queue   = &(pmlmepriv->scanned_queue);
30         u8 ret = _SUCCESS;
31
32
33         spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
34         phead = get_list_head(queue);
35         plist = phead->next;
36
37         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("\n rtw_do_join: phead = %p; plist = %p\n\n\n", phead, plist));
38
39         pmlmepriv->cur_network.join_res = -2;
40
41         set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
42
43         pmlmepriv->pscanned = plist;
44
45         pmlmepriv->to_join = true;
46
47         if (list_empty(&queue->queue)) {
48                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
49                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
50
51                 /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */
52                 /* we try to issue sitesurvey firstly */
53
54                 if (!pmlmepriv->LinkDetectInfo.bBusyTraffic ||
55                     pmlmepriv->to_roaming > 0) {
56                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("rtw_do_join(): site survey if scanned_queue is empty\n."));
57                         /*  submit site_survey_cmd */
58                         ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
59                         if (_SUCCESS != ret) {
60                                 pmlmepriv->to_join = false;
61                                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_do_join(): site survey return error\n."));
62                         }
63                 } else {
64                         pmlmepriv->to_join = false;
65                         ret = _FAIL;
66                 }
67
68                 goto exit;
69         } else {
70                 int select_ret;
71
72                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
73                 select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
74                 if (select_ret == _SUCCESS) {
75                         pmlmepriv->to_join = false;
76                         mod_timer(&pmlmepriv->assoc_timer,
77                                   jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
78                 } else {
79                         if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) {
80                                 /*  submit createbss_cmd to change to a ADHOC_MASTER */
81
82                                 /* pmlmepriv->lock has been acquired by caller... */
83                                 struct wlan_bssid_ex    *pdev_network = &(padapter->registrypriv.dev_network);
84
85                                 pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
86
87                                 pibss = padapter->registrypriv.dev_network.MacAddress;
88
89                                 memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
90
91                                 rtw_update_registrypriv_dev_network(padapter);
92
93                                 rtw_generate_random_ibss(pibss);
94
95                                 if (rtw_createbss_cmd(padapter) != _SUCCESS) {
96                                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("***Error =>do_goin: rtw_createbss_cmd status FAIL***\n "));
97                                         ret =  false;
98                                         goto exit;
99                                 }
100                                 pmlmepriv->to_join = false;
101
102                                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
103                                          ("***Error => rtw_select_and_join_from_scanned_queue FAIL under STA_Mode***\n "));
104                         } else {
105                                 /*  can't associate ; reset under-linking */
106                                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
107
108                                 /* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */
109                                 /* we try to issue sitesurvey firstly */
110                                 if (!pmlmepriv->LinkDetectInfo.bBusyTraffic ||
111                                     pmlmepriv->to_roaming > 0) {
112                                         ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
113                                         if (_SUCCESS != ret) {
114                                                 pmlmepriv->to_join = false;
115                                                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("do_join(): site survey return error\n."));
116                                         }
117                                 } else {
118                                         ret = _FAIL;
119                                         pmlmepriv->to_join = false;
120                                 }
121                         }
122                 }
123         }
124
125 exit:
126
127
128         return ret;
129 }
130
131 u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid)
132 {
133         u8 status = _SUCCESS;
134         u32 cur_time = 0;
135         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
136
137
138         DBG_88E_LEVEL(_drv_info_, "set bssid:%pM\n", bssid);
139
140         if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 &&
141              bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) ||
142             (bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF &&
143              bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) {
144                 status = _FAIL;
145                 goto exit;
146         }
147
148         spin_lock_bh(&pmlmepriv->lock);
149
150
151         DBG_88E("Set BSSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
152         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
153                 goto handle_tkip_countermeasure;
154         else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
155                 goto release_mlme_lock;
156
157         if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
158                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
159
160                 if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN)) {
161                         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)
162                                 goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
163                 } else {
164                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("Set BSSID not the same bssid\n"));
165                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid =%pM\n", (bssid)));
166                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("cur_bssid =%pM\n", (pmlmepriv->cur_network.network.MacAddress)));
167
168                         rtw_disassoc_cmd(padapter, 0, true);
169
170                         if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
171                                 rtw_indicate_disconnect(padapter);
172
173                         rtw_free_assoc_resources(padapter);
174
175                         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
176                                 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
177                                 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
178                         }
179                 }
180         }
181
182 handle_tkip_countermeasure:
183         /* should we add something here...? */
184
185         if (padapter->securitypriv.btkip_countermeasure) {
186                 cur_time = jiffies;
187
188                 if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) {
189                         padapter->securitypriv.btkip_countermeasure = false;
190                         padapter->securitypriv.btkip_countermeasure_time = 0;
191                 } else {
192                         status = _FAIL;
193                         goto release_mlme_lock;
194                 }
195         }
196
197         memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
198         pmlmepriv->assoc_by_bssid = true;
199
200         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
201                 pmlmepriv->to_join = true;
202         else
203                 status = rtw_do_join(padapter);
204
205 release_mlme_lock:
206         spin_unlock_bh(&pmlmepriv->lock);
207
208 exit:
209         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
210                  ("rtw_set_802_11_bssid: status=%d\n", status));
211
212
213         return status;
214 }
215
216 u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid)
217 {
218         u8 status = _SUCCESS;
219         u32 cur_time = 0;
220
221         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
222         struct wlan_network *pnetwork = &pmlmepriv->cur_network;
223
224
225         DBG_88E_LEVEL(_drv_info_, "set ssid [%s] fw_state=0x%08x\n",
226                       ssid->Ssid, get_fwstate(pmlmepriv));
227
228         if (!padapter->hw_init_completed) {
229                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
230                          ("set_ssid: hw_init_completed == false =>exit!!!\n"));
231                 status = _FAIL;
232                 goto exit;
233         }
234
235         spin_lock_bh(&pmlmepriv->lock);
236
237         DBG_88E("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
238         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
239                 goto handle_tkip_countermeasure;
240         else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
241                 goto release_mlme_lock;
242
243         if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
244                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
245                          ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
246
247                 if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
248                     (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength))) {
249                         if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)) {
250                                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
251                                          ("Set SSID is the same ssid, fw_state = 0x%08x\n",
252                                           get_fwstate(pmlmepriv)));
253
254                                 if (!rtw_is_same_ibss(padapter, pnetwork)) {
255                                         /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */
256                                         rtw_disassoc_cmd(padapter, 0, true);
257
258                                         if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
259                                                 rtw_indicate_disconnect(padapter);
260
261                                         rtw_free_assoc_resources(padapter);
262
263                                         if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
264                                                 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
265                                                 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
266                                         }
267                                 } else {
268                                         goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
269                                 }
270                         } else {
271                                 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1);
272                         }
273                 } else {
274                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("Set SSID not the same ssid\n"));
275                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid =[%s] len = 0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength));
276                         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));
277
278                         rtw_disassoc_cmd(padapter, 0, true);
279
280                         if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
281                                 rtw_indicate_disconnect(padapter);
282
283                         rtw_free_assoc_resources(padapter);
284
285                         if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
286                                 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
287                                 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
288                         }
289                 }
290         }
291
292 handle_tkip_countermeasure:
293
294         if (padapter->securitypriv.btkip_countermeasure) {
295                 cur_time = jiffies;
296
297                 if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) {
298                         padapter->securitypriv.btkip_countermeasure = false;
299                         padapter->securitypriv.btkip_countermeasure_time = 0;
300                 } else {
301                         status = _FAIL;
302                         goto release_mlme_lock;
303                 }
304         }
305
306         memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid));
307         pmlmepriv->assoc_by_bssid = false;
308
309         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
310                 pmlmepriv->to_join = true;
311         else
312                 status = rtw_do_join(padapter);
313
314 release_mlme_lock:
315         spin_unlock_bh(&pmlmepriv->lock);
316
317 exit:
318         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
319                  ("-rtw_set_802_11_ssid: status =%d\n", status));
320         return status;
321 }
322
323 u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter,
324         enum ndis_802_11_network_infra networktype)
325 {
326         struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
327         struct  wlan_network    *cur_network = &pmlmepriv->cur_network;
328         enum ndis_802_11_network_infra *pold_state = &(cur_network->network.InfrastructureMode);
329
330
331         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_,
332                  ("+rtw_set_802_11_infrastructure_mode: old =%d new =%d fw_state = 0x%08x\n",
333                   *pold_state, networktype, get_fwstate(pmlmepriv)));
334
335         if (*pold_state != networktype) {
336                 spin_lock_bh(&pmlmepriv->lock);
337
338                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, (" change mode!"));
339                 /* DBG_88E("change mode, old_mode =%d, new_mode =%d, fw_state = 0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); */
340
341                 if (*pold_state == Ndis802_11APMode) {
342                         /* change to other mode from Ndis802_11APMode */
343                         cur_network->join_res = -1;
344
345 #ifdef CONFIG_88EU_AP_MODE
346                         stop_ap_mode(padapter);
347 #endif
348                 }
349
350                 if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
351                     (*pold_state == Ndis802_11IBSS))
352                         rtw_disassoc_cmd(padapter, 0, true);
353
354                 if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
355                     (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
356                         rtw_free_assoc_resources(padapter);
357
358                 if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) {
359                         if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
360                                 rtw_indicate_disconnect(padapter); /* will clr Linked_state; before this function, we must have checked whether  issue dis-assoc_cmd or not */
361                }
362
363                 *pold_state = networktype;
364
365                 _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
366
367                 switch (networktype) {
368                 case Ndis802_11IBSS:
369                         set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
370                         break;
371                 case Ndis802_11Infrastructure:
372                         set_fwstate(pmlmepriv, WIFI_STATION_STATE);
373                         break;
374                 case Ndis802_11APMode:
375                         set_fwstate(pmlmepriv, WIFI_AP_STATE);
376 #ifdef CONFIG_88EU_AP_MODE
377                         start_ap_mode(padapter);
378 #endif
379                         break;
380                 case Ndis802_11AutoUnknown:
381                 case Ndis802_11InfrastructureMax:
382                         break;
383                 }
384                 spin_unlock_bh(&pmlmepriv->lock);
385         }
386
387
388         return true;
389 }
390
391
392 u8 rtw_set_802_11_disassociate(struct adapter *padapter)
393 {
394         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
395
396
397         spin_lock_bh(&pmlmepriv->lock);
398
399         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
400                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
401                          ("MgntActrtw_set_802_11_disassociate: rtw_indicate_disconnect\n"));
402
403                 rtw_disassoc_cmd(padapter, 0, true);
404                 rtw_indicate_disconnect(padapter);
405                 rtw_free_assoc_resources(padapter);
406                 rtw_pwr_wakeup(padapter);
407         }
408
409         spin_unlock_bh(&pmlmepriv->lock);
410
411
412         return true;
413 }
414
415 u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_ssid *pssid, int ssid_max_num)
416 {
417         struct  mlme_priv               *pmlmepriv = &padapter->mlmepriv;
418         u8      res = true;
419
420
421         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("+rtw_set_802_11_bssid_list_scan(), fw_state =%x\n", get_fwstate(pmlmepriv)));
422
423         if (padapter == NULL) {
424                 res = false;
425                 goto exit;
426         }
427         if (!padapter->hw_init_completed) {
428                 res = false;
429                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n === rtw_set_802_11_bssid_list_scan:hw_init_completed == false ===\n"));
430                 goto exit;
431         }
432
433         if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) ||
434             (pmlmepriv->LinkDetectInfo.bBusyTraffic)) {
435                 /*  Scan or linking is in progress, do nothing. */
436                 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)));
437                 res = true;
438
439                 if (check_fwstate(pmlmepriv,
440                                 (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)) == true)
441                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n###_FW_UNDER_SURVEY|_FW_UNDER_LINKING\n\n"));
442                 else
443                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n###pmlmepriv->sitesurveyctrl.traffic_busy == true\n\n"));
444
445         } else {
446                 if (rtw_is_scan_deny(padapter)) {
447                         DBG_88E(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter));
448                         indicate_wx_scan_complete_event(padapter);
449                         return _SUCCESS;
450                 }
451
452                 spin_lock_bh(&pmlmepriv->lock);
453
454                 res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0);
455
456                 spin_unlock_bh(&pmlmepriv->lock);
457         }
458 exit:
459
460
461         return res;
462 }
463
464 u8 rtw_set_802_11_authentication_mode(struct adapter *padapter, enum ndis_802_11_auth_mode authmode)
465 {
466         struct security_priv *psecuritypriv = &padapter->securitypriv;
467         int res;
468         u8 ret;
469
470
471         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_802_11_auth.mode(): mode =%x\n", authmode));
472
473         psecuritypriv->ndisauthtype = authmode;
474
475         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
476                  ("rtw_set_802_11_authentication_mode:psecuritypriv->ndisauthtype=%d",
477                  psecuritypriv->ndisauthtype));
478
479         if (psecuritypriv->ndisauthtype > 3)
480                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
481
482         res = rtw_set_auth(padapter, psecuritypriv);
483
484         if (res == _SUCCESS)
485                 ret = true;
486         else
487                 ret = false;
488
489
490         return ret;
491 }
492
493 u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep)
494 {
495         int             keyid, res;
496         struct security_priv *psecuritypriv = &(padapter->securitypriv);
497         u8              ret = _SUCCESS;
498
499
500         keyid = wep->KeyIndex & 0x3fffffff;
501
502         if (keyid >= 4) {
503                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("MgntActrtw_set_802_11_add_wep:keyid>4 =>fail\n"));
504                 ret = false;
505                 goto exit;
506         }
507
508         switch (wep->KeyLength) {
509         case 5:
510                 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
511                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength = 5\n"));
512                 break;
513         case 13:
514                 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
515                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength = 13\n"));
516                 break;
517         default:
518                 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
519                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength!= 5 or 13\n"));
520                 break;
521         }
522         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
523                  ("rtw_set_802_11_add_wep:before memcpy, wep->KeyLength = 0x%x wep->KeyIndex = 0x%x  keyid =%x\n",
524                  wep->KeyLength, wep->KeyIndex, keyid));
525
526         memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]), &(wep->KeyMaterial), wep->KeyLength);
527
528         psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength;
529
530         psecuritypriv->dot11PrivacyKeyIndex = keyid;
531
532         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
533                  ("rtw_set_802_11_add_wep:security key material : %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
534                  psecuritypriv->dot11DefKey[keyid].skey[0],
535                  psecuritypriv->dot11DefKey[keyid].skey[1],
536                  psecuritypriv->dot11DefKey[keyid].skey[2],
537                  psecuritypriv->dot11DefKey[keyid].skey[3],
538                  psecuritypriv->dot11DefKey[keyid].skey[4],
539                  psecuritypriv->dot11DefKey[keyid].skey[5],
540                  psecuritypriv->dot11DefKey[keyid].skey[6],
541                  psecuritypriv->dot11DefKey[keyid].skey[7],
542                  psecuritypriv->dot11DefKey[keyid].skey[8],
543                  psecuritypriv->dot11DefKey[keyid].skey[9],
544                  psecuritypriv->dot11DefKey[keyid].skey[10],
545                  psecuritypriv->dot11DefKey[keyid].skey[11],
546                  psecuritypriv->dot11DefKey[keyid].skey[12]));
547
548         res = rtw_set_key(padapter, psecuritypriv, keyid, 1);
549
550         if (res == _FAIL)
551                 ret = false;
552 exit:
553         return ret;
554 }
555
556 /*
557 * rtw_get_cur_max_rate -
558 * @adapter: pointer to struct adapter structure
559 *
560 * Return 0 or 100Kbps
561 */
562 u16 rtw_get_cur_max_rate(struct adapter *adapter)
563 {
564         int     i = 0;
565         u8      *p;
566         u16     rate = 0, max_rate = 0;
567         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
568         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
569         struct registry_priv *pregistrypriv = &adapter->registrypriv;
570         struct mlme_priv        *pmlmepriv = &adapter->mlmepriv;
571         struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
572         u8      rf_type = 0;
573         u8      bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0;
574         u32     ht_ielen = 0;
575
576         if (adapter->registrypriv.mp_mode == 1) {
577                 if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
578                         return 0;
579         }
580
581         if ((!check_fwstate(pmlmepriv, _FW_LINKED)) &&
582             (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
583                 return 0;
584
585         if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N|WIRELESS_11_5N)) {
586                 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12);
587                 if (p && ht_ielen > 0) {
588                         /* cur_bwmod is updated by beacon, pmlmeinfo is updated by association response */
589                         bw_40MHz = (pmlmeext->cur_bwmode && (HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH & pmlmeinfo->HT_info.infos[0])) ? 1 : 0;
590
591                         short_GI_20 = (le16_to_cpu(pmlmeinfo->HT_caps.cap_info) & IEEE80211_HT_CAP_SGI_20) ? 1 : 0;
592                         short_GI_40 = (le16_to_cpu(pmlmeinfo->HT_caps.cap_info) & IEEE80211_HT_CAP_SGI_40) ? 1 : 0;
593
594                         rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
595                         max_rate = rtw_mcs_rate(
596                                 rf_type,
597                                 bw_40MHz & (pregistrypriv->cbw40_enable),
598                                 short_GI_20,
599                                 short_GI_40,
600                                 pmlmeinfo->HT_caps.mcs.rx_mask
601                         );
602                 }
603         } else {
604                 while ((pcur_bss->SupportedRates[i] != 0) && (pcur_bss->SupportedRates[i] != 0xFF)) {
605                         rate = pcur_bss->SupportedRates[i]&0x7F;
606                         if (rate > max_rate)
607                                 max_rate = rate;
608                         i++;
609                 }
610
611                 max_rate = max_rate*10/2;
612         }
613
614         return max_rate;
615 }
616
617 /*
618 * rtw_set_country -
619 * @adapter: pointer to struct adapter structure
620 * @country_code: string of country code
621 *
622 * Return _SUCCESS or _FAIL
623 */
624 int rtw_set_country(struct adapter *adapter, const char *country_code)
625 {
626         int i;
627         int channel_plan = RT_CHANNEL_DOMAIN_WORLD_WIDE_5G;
628
629         DBG_88E("%s country_code:%s\n", __func__, country_code);
630         for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
631                 if (0 == strcmp(channel_table[i].name, country_code)) {
632                         channel_plan = channel_table[i].channel_plan;
633                         break;
634                 }
635         }
636
637         if (i == ARRAY_SIZE(channel_table))
638                 DBG_88E("%s unknown country_code:%s\n", __func__, country_code);
639
640         return rtw_set_chplan_cmd(adapter, channel_plan, 1);
641 }