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