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