]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/net/wireless/realtek/rtl8192cu/core/rtw_ioctl_set.c
net: Fix rtl8192cu build errors on other platforms
[mirror_ubuntu-artful-kernel.git] / drivers / net / wireless / realtek / rtl8192cu / core / rtw_ioctl_set.c
CommitLineData
abb3b3dc 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
37extern 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
1130c632 46u8 rtw_validate_bssid(const u8 *bssid)
abb3b3dc 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
60u8 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
85exit:
86
87_func_exit_;
88
89 return ret;
90}
91
92u8 rtw_do_join(_adapter * padapter);
93u8 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
225exit:
226
227_func_exit_;
228
229 return ret;
230}
231
232#ifdef PLATFORM_WINDOWS
233u8 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
250u8 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
268u8 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
291u8 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
319u8 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
328u8 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
385handle_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
401release_mlme_lock:
402 _exit_critical_bh(&pmlmepriv->lock, &irqL);
403
404exit:
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
413u8 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
504handle_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
525release_mlme_lock:
526 _exit_critical_bh(&pmlmepriv->lock, &irqL);
527
528exit:
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
1130c632
PE
538u8 rtw_set_802_11_connect(_adapter *padapter, const u8 *bssid
539 , NDIS_802_11_SSID *ssid)
abb3b3dc 540{
541 _irqL irqL;
542 u8 status = _SUCCESS;
543 u32 cur_time = 0;
544 bool bssid_valid = _TRUE;
545 bool ssid_valid = _TRUE;
546 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
547
548_func_enter_;
549
550 if (!ssid || rtw_validate_ssid(ssid) == _FALSE)
551 ssid_valid = _FALSE;
552
553 if (!bssid || rtw_validate_bssid(bssid) == _FALSE)
554 bssid_valid = _FALSE;
555
556 if (ssid_valid == _FALSE && bssid_valid == _FALSE) {
557 DBG_871X(FUNC_ADPT_FMT" ssid:%p, ssid_valid:%d, bssid:%p, bssid_valid:%d\n",
558 FUNC_ADPT_ARG(padapter), ssid, ssid_valid, bssid, bssid_valid);
559 status = _FAIL;
560 goto exit;
561 }
562
563 if(padapter->hw_init_completed==_FALSE){
564 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
565 ("set_ssid: hw_init_completed==_FALSE=>exit!!!\n"));
566 status = _FAIL;
567 goto exit;
568 }
569
570 _enter_critical_bh(&pmlmepriv->lock, &irqL);
571
572 LOG_LEVEL(_drv_info_, FUNC_ADPT_FMT" fw_state=0x%08x\n",
573 FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv));
574
575 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
576 goto handle_tkip_countermeasure;
577 } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
578 goto release_mlme_lock;
579 }
580
581handle_tkip_countermeasure:
582 if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
583 status = _FAIL;
584 goto release_mlme_lock;
585 }
586
587 if (ssid && ssid_valid)
588 _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
589
590 if (bssid && bssid_valid) {
591 _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
592 pmlmepriv->assoc_by_bssid = _TRUE;
593 }
594
595 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
596 pmlmepriv->to_join = _TRUE;
597 }
598 else {
599 status = rtw_do_join(padapter);
600 }
601
602release_mlme_lock:
603 _exit_critical_bh(&pmlmepriv->lock, &irqL);
604
605exit:
606
607_func_exit_;
608
609 return status;
610}
611
612/*
613rtw_set_802_11_infrastructure_mode(~)
614 ### NOTE:#### (!!!!)
615 MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock and scanned_queue->lock in sequence
616*/
617u8 rtw_set_802_11_infrastructure_mode(_adapter* padapter,
618 NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
619{
620 _irqL irqL;
621 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
622 struct wlan_network *cur_network = &pmlmepriv->cur_network;
623 NDIS_802_11_NETWORK_INFRASTRUCTURE* pold_state = &(cur_network->network.InfrastructureMode);
624
625_func_enter_;
626
627 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_notice_,
628 ("+rtw_set_802_11_infrastructure_mode: old=%d new=%d fw_state=0x%08x\n",
629 *pold_state, networktype, get_fwstate(pmlmepriv)));
630
631 if(*pold_state != networktype)
632 {
633
634 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,(" change mode!"));
635 //DBG_871X("change mode, old_mode=%d, new_mode=%d, fw_state=0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv));
636
637 if(*pold_state==Ndis802_11APMode)
638 {
639 //change to other mode from Ndis802_11APMode
640 cur_network->join_res = -1;
641
642#ifdef CONFIG_NATIVEAP_MLME
643 stop_ap_mode(padapter);
644#endif
645 }
646
647 if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) ||(*pold_state==Ndis802_11IBSS))
648 rtw_disassoc_cmd(padapter, 0, _TRUE);
649
650 if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) ||
651 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)== _TRUE) )
652 rtw_free_assoc_resources(padapter, 0);
653
654 if((*pold_state == Ndis802_11Infrastructure) ||(*pold_state == Ndis802_11IBSS))
655 {
656 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
657 {
658 rtw_indicate_disconnect(padapter); //will clr Linked_state; before this function, we must have chked whether issue dis-assoc_cmd or not
659 }
660 }
661
662 *pold_state = networktype;
663
664 _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
665
666 switch(networktype)
667 {
668 case Ndis802_11IBSS:
669 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
670 break;
671
672 case Ndis802_11Infrastructure:
673 set_fwstate(pmlmepriv, WIFI_STATION_STATE);
674 break;
675
676 case Ndis802_11APMode:
677 set_fwstate(pmlmepriv, WIFI_AP_STATE);
678#ifdef CONFIG_NATIVEAP_MLME
679 start_ap_mode(padapter);
680 //rtw_indicate_connect(padapter);
681#endif
682
683 break;
684
685 case Ndis802_11AutoUnknown:
686 case Ndis802_11InfrastructureMax:
687 break;
688 }
689
690 //SecClearAllKeys(adapter);
691
692 //RT_TRACE(COMP_OID_SET, DBG_LOUD, ("set_infrastructure: fw_state:%x after changing mode\n",
693 // get_fwstate(pmlmepriv) ));
694
695 }
696
697_func_exit_;
698
699 return _TRUE;
700}
701
702
703u8 rtw_set_802_11_disassociate(_adapter *padapter)
704{
705 _irqL irqL;
706 struct mlme_priv * pmlmepriv = &padapter->mlmepriv;
707
708_func_enter_;
709
710 _enter_critical_bh(&pmlmepriv->lock, &irqL);
711
712 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
713 {
714 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_disassociate: rtw_indicate_disconnect\n"));
715
716 rtw_disassoc_cmd(padapter, 0, _TRUE);
717 rtw_indicate_disconnect(padapter);
718 //modify for CONFIG_IEEE80211W, none 11w can use it
719 rtw_free_assoc_resources_cmd(padapter);
720 }
721
722 _exit_critical_bh(&pmlmepriv->lock, &irqL);
723
724_func_exit_;
725
726 return _TRUE;
727}
728
729u8 rtw_set_802_11_bssid_list_scan(_adapter* padapter, NDIS_802_11_SSID *pssid, int ssid_max_num)
730{
731 _irqL irqL;
732 struct mlme_priv *pmlmepriv= &padapter->mlmepriv;
733 u8 res=_TRUE;
734
735_func_enter_;
736
737 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("+rtw_set_802_11_bssid_list_scan(), fw_state=%x\n", get_fwstate(pmlmepriv)));
738
739 if (padapter == NULL) {
740 res=_FALSE;
741 goto exit;
742 }
743 if (padapter->hw_init_completed==_FALSE){
744 res = _FALSE;
745 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n===rtw_set_802_11_bssid_list_scan:hw_init_completed==_FALSE===\n"));
746 goto exit;
747 }
748
749 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) ||
750 (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE))
751 {
752 // Scan or linking is in progress, do nothing.
753 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)));
754 res = _TRUE;
755
756 if(check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))== _TRUE){
757 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n###_FW_UNDER_SURVEY|_FW_UNDER_LINKING\n\n"));
758 } else {
759 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n###pmlmepriv->sitesurveyctrl.traffic_busy==_TRUE\n\n"));
760 }
761 } else {
762 if (rtw_is_scan_deny(padapter)) {
763 DBG_871X(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter));
764 indicate_wx_scan_complete_event(padapter);
765 return _SUCCESS;
766 }
767
768 _enter_critical_bh(&pmlmepriv->lock, &irqL);
769
770 res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0);
771
772 _exit_critical_bh(&pmlmepriv->lock, &irqL);
773 }
774exit:
775
776_func_exit_;
777
778 return res;
779}
780
781u8 rtw_set_802_11_authentication_mode(_adapter* padapter, NDIS_802_11_AUTHENTICATION_MODE authmode)
782{
783 struct security_priv *psecuritypriv = &padapter->securitypriv;
784 int res;
785 u8 ret;
786
787_func_enter_;
788
789 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_802_11_auth.mode(): mode=%x\n", authmode));
790
791 psecuritypriv->ndisauthtype=authmode;
792
793 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_authentication_mode:psecuritypriv->ndisauthtype=%d", psecuritypriv->ndisauthtype));
794
795 if(psecuritypriv->ndisauthtype>3)
796 psecuritypriv->dot11AuthAlgrthm=dot11AuthAlgrthm_8021X;
797
798 res=rtw_set_auth(padapter,psecuritypriv);
799
800 if(res==_SUCCESS)
801 ret=_TRUE;
802 else
803 ret=_FALSE;
804
805_func_exit_;
806
807 return ret;
808}
809
810u8 rtw_set_802_11_add_wep(_adapter* padapter, NDIS_802_11_WEP *wep){
811
812 u8 bdefaultkey;
813 u8 btransmitkey;
814 sint keyid,res;
815 struct security_priv* psecuritypriv=&(padapter->securitypriv);
816 u8 ret=_SUCCESS;
817
818_func_enter_;
819
820 bdefaultkey=(wep->KeyIndex & 0x40000000) > 0 ? _FALSE : _TRUE; //for ???
821 btransmitkey= (wep->KeyIndex & 0x80000000) > 0 ? _TRUE : _FALSE; //for ???
822 keyid=wep->KeyIndex & 0x3fffffff;
823
824 if(keyid>4)
825 {
826 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("MgntActrtw_set_802_11_add_wep:keyid>4=>fail\n"));
827 ret=_FALSE;
828 goto exit;
829 }
830
831 switch(wep->KeyLength)
832 {
833 case 5:
834 psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
835 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength=5\n"));
836 break;
837 case 13:
838 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
839 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength=13\n"));
840 break;
841 default:
842 psecuritypriv->dot11PrivacyAlgrthm=_NO_PRIVACY_;
843 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength!=5 or 13\n"));
844 break;
845 }
846
847 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));
848
849 _rtw_memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]),&(wep->KeyMaterial),wep->KeyLength);
850
851 psecuritypriv->dot11DefKeylen[keyid]=wep->KeyLength;
852
853 psecuritypriv->dot11PrivacyKeyIndex=keyid;
854
855 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",
856 psecuritypriv->dot11DefKey[keyid].skey[0],psecuritypriv->dot11DefKey[keyid].skey[1],psecuritypriv->dot11DefKey[keyid].skey[2],
857 psecuritypriv->dot11DefKey[keyid].skey[3],psecuritypriv->dot11DefKey[keyid].skey[4],psecuritypriv->dot11DefKey[keyid].skey[5],
858 psecuritypriv->dot11DefKey[keyid].skey[6],psecuritypriv->dot11DefKey[keyid].skey[7],psecuritypriv->dot11DefKey[keyid].skey[8],
859 psecuritypriv->dot11DefKey[keyid].skey[9],psecuritypriv->dot11DefKey[keyid].skey[10],psecuritypriv->dot11DefKey[keyid].skey[11],
860 psecuritypriv->dot11DefKey[keyid].skey[12]));
861
862 res=rtw_set_key(padapter,psecuritypriv, keyid, 1);
863
864 if(res==_FAIL)
865 ret= _FALSE;
866exit:
867
868_func_exit_;
869
870 return ret;
871
872}
873
874u8 rtw_set_802_11_remove_wep(_adapter* padapter, u32 keyindex){
875
876 u8 ret=_SUCCESS;
877
878_func_enter_;
879
880 if (keyindex >= 0x80000000 || padapter == NULL){
881
882 ret=_FALSE;
883 goto exit;
884
885 }
886 else
887 {
888 int res;
889 struct security_priv* psecuritypriv=&(padapter->securitypriv);
890 if( keyindex < 4 ){
891
892 _rtw_memset(&psecuritypriv->dot11DefKey[keyindex], 0, 16);
893
894 res=rtw_set_key(padapter,psecuritypriv,keyindex, 0);
895
896 psecuritypriv->dot11DefKeylen[keyindex]=0;
897
898 if(res==_FAIL)
899 ret=_FAIL;
900
901 }
902 else
903 {
904 ret=_FAIL;
905 }
906
907 }
908
909exit:
910
911_func_exit_;
912
913 return ret;
914
915}
916
917u8 rtw_set_802_11_add_key(_adapter* padapter, NDIS_802_11_KEY *key){
918
919 uint encryptionalgo;
920 u8 * pbssid;
921 struct sta_info *stainfo;
922 u8 bgroup = _FALSE;
923 u8 bgrouptkey = _FALSE;//can be remove later
924 u8 ret=_SUCCESS;
925
926_func_enter_;
927
928 if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)){
929
930 // It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination,
931 // it must fail the request and return NDIS_STATUS_INVALID_DATA.
932 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));
933 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));
934 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key: key->KeyIndex=%d \n" ,(int)key->KeyIndex));
935 ret= _FAIL;
936 goto exit;
937 }
938
939 if(key->KeyIndex & 0x40000000)
940 {
941 // Pairwise key
942
943 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Pairwise key +++++\n"));
944
945 pbssid=get_bssid(&padapter->mlmepriv);
946 stainfo=rtw_get_stainfo(&padapter->stapriv, pbssid);
947
948 if((stainfo!=NULL)&&(padapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)){
949 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:( stainfo!=NULL)&&(Adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)\n"));
950 encryptionalgo=stainfo->dot118021XPrivacy;
951 }
952 else{
953 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: stainfo==NULL)||(Adapter->securitypriv.dot11AuthAlgrthm!=dot11AuthAlgrthm_8021X)\n"));
954 encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm;
955 }
956
957 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (encryptionalgo ==%d)!\n",encryptionalgo ));
958 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11PrivacyAlgrthm ==%d)!\n",padapter->securitypriv.dot11PrivacyAlgrthm));
959 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11AuthAlgrthm ==%d)!\n",padapter->securitypriv.dot11AuthAlgrthm));
960
961 if((stainfo!=NULL)){
962 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (stainfo->dot118021XPrivacy ==%d)!\n", stainfo->dot118021XPrivacy));
963 }
964
965 if(key->KeyIndex & 0x000000FF){
966 // The key index is specified in the lower 8 bits by values of zero to 255.
967 // The key index should be set to zero for a Pairwise key, and the driver should fail with
968 // NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero
969 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" key->KeyIndex & 0x000000FF.\n"));
970 ret= _FAIL;
971 goto exit;
972 }
973
974 // check BSSID
975 if (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _TRUE){
976
977 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("MacAddr_isBcst(key->BSSID)\n"));
978 ret= _FALSE;
979 goto exit;
980 }
981
982 // Check key length for TKIP.
983 //if(encryptionAlgorithm == RT_ENC_TKIP_ENCRYPTION && key->KeyLength != 32)
984 if((encryptionalgo== _TKIP_)&& (key->KeyLength != 32)){
985 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("TKIP KeyLength:0x%x != 32\n", key->KeyLength));
986 ret=_FAIL;
987 goto exit;
988
989 }
990
991 // Check key length for AES.
992 if((encryptionalgo== _AES_)&& (key->KeyLength != 16)) {
993 // For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case.
994 if(key->KeyLength == 32) {
995 key->KeyLength = 16;
996 } else {
997 ret= _FAIL;
998 goto exit;
999 }
1000 }
1001
1002 // Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko.
1003 if( (encryptionalgo== _WEP40_|| encryptionalgo== _WEP104_) && (key->KeyLength != 5 || key->KeyLength != 13)) {
1004 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("WEP KeyLength:0x%x != 5 or 13\n", key->KeyLength));
1005 ret=_FAIL;
1006 goto exit;
1007 }
1008
1009 bgroup = _FALSE;
1010
1011 // Check the pairwise key. Added by Annie, 2005-07-06.
1012 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n"));
1013 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Pairwise Key set]\n"));
1014 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n"));
1015 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3)));
1016 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength));
1017 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n"));
1018
1019 }
1020 else
1021 {
1022 // Group key - KeyIndex(BIT30==0)
1023 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Group key +++++\n"));
1024
1025
1026 // when add wep key through add key and didn't assigned encryption type before
1027 if((padapter->securitypriv.ndisauthtype<=3)&&(padapter->securitypriv.dot118021XGrpPrivacy==0))
1028 {
1029 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));
1030
1031 switch(key->KeyLength)
1032 {
1033 case 5:
1034 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
1035 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength));
1036 break;
1037 case 13:
1038 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
1039 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength));
1040 break;
1041 default:
1042 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
1043 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u \n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength));
1044 break;
1045 }
1046
1047 encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm;
1048
1049 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" Adapter->securitypriv.dot11PrivacyAlgrthm=%x\n", padapter->securitypriv.dot11PrivacyAlgrthm));
1050
1051 }
1052 else
1053 {
1054 encryptionalgo=padapter->securitypriv.dot118021XGrpPrivacy;
1055 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));
1056
1057 }
1058
1059 if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE) && (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _FALSE)) {
1060 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" IBSS but BSSID is not Broadcast Address.\n"));
1061 ret= _FAIL;
1062 goto exit;
1063 }
1064
1065 // Check key length for TKIP
1066 if((encryptionalgo== _TKIP_) && (key->KeyLength != 32)) {
1067
1068 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" TKIP GTK KeyLength:%u != 32\n", key->KeyLength));
1069 ret= _FAIL;
1070 goto exit;
1071
1072 } else if(encryptionalgo== _AES_ && (key->KeyLength != 16 && key->KeyLength != 32) ) {
1073
1074 // Check key length for AES
1075 // For NDTEST, we allow keylen=32 in this case. 2005.01.27, by rcnjko.
1076 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));
1077 ret= _FAIL;
1078 goto exit;
1079 }
1080
1081 // Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03.
1082 if((encryptionalgo== _AES_) && (key->KeyLength == 32) ) {
1083 key->KeyLength = 16;
1084 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("AES key length changed: %u\n", key->KeyLength) );
1085 }
1086
1087 if(key->KeyIndex & 0x8000000) {//error ??? 0x8000_0000
1088 bgrouptkey = _TRUE;
1089 }
1090
1091 if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE)&&(check_fwstate(&padapter->mlmepriv, _FW_LINKED)==_TRUE))
1092 {
1093 bgrouptkey = _TRUE;
1094 }
1095
1096 bgroup = _TRUE;
1097
1098 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n") );
1099 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Group Key set]\n") );
1100 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")) ;
1101 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3)));
1102 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength)) ;
1103 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n"));
1104
1105 }
1106
1107 // If WEP encryption algorithm, just call rtw_set_802_11_add_wep().
1108 if((padapter->securitypriv.dot11AuthAlgrthm !=dot11AuthAlgrthm_8021X)&&(encryptionalgo== _WEP40_ || encryptionalgo== _WEP104_))
1109 {
1110 u8 ret;
1111 u32 keyindex;
1112 u32 len = FIELD_OFFSET(NDIS_802_11_KEY, KeyMaterial) + key->KeyLength;
1113 NDIS_802_11_WEP *wep = &padapter->securitypriv.ndiswep;
1114
1115 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ WEP key +++++\n"));
1116
1117 wep->Length = len;
1118 keyindex = key->KeyIndex&0x7fffffff;
1119 wep->KeyIndex = keyindex ;
1120 wep->KeyLength = key->KeyLength;
1121
1122 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:Before memcpy \n"));
1123
1124 _rtw_memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength);
1125 _rtw_memcpy(&(padapter->securitypriv.dot11DefKey[keyindex].skey[0]), key->KeyMaterial, key->KeyLength);
1126
1127 padapter->securitypriv.dot11DefKeylen[keyindex]=key->KeyLength;
1128 padapter->securitypriv.dot11PrivacyKeyIndex=keyindex;
1129
1130 ret = rtw_set_802_11_add_wep(padapter, wep);
1131
1132 goto exit;
1133
1134 }
1135
1136 if(key->KeyIndex & 0x20000000){
1137 // SetRSC
1138 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ SetRSC+++++\n"));
1139 if(bgroup == _TRUE)
1140 {
1141 NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL;
1142 _rtw_memcpy(&padapter->securitypriv.dot11Grprxpn, &keysrc, 8);
1143 }
1144 else
1145 {
1146 NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL;
1147 _rtw_memcpy(&padapter->securitypriv.dot11Grptxpn, &keysrc, 8);
1148 }
1149
1150 }
1151
1152 // Indicate this key idx is used for TX
1153 // Save the key in KeyMaterial
1154 if(bgroup == _TRUE) // Group transmit key
1155 {
1156 int res;
1157
1158 if(bgrouptkey == _TRUE)
1159 {
1160 padapter->securitypriv.dot118021XGrpKeyid=(u8)key->KeyIndex;
1161 }
1162
1163 if((key->KeyIndex&0x3) == 0){
1164 ret = _FAIL;
1165 goto exit;
1166 }
1167
1168 _rtw_memset(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
1169 _rtw_memset(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
1170 _rtw_memset(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
1171
1172 if((key->KeyIndex & 0x10000000))
1173 {
1174 _rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8);
1175 _rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8);
1176
1177 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",
1178 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1],
1179 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3],
1180 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5],
1181 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7]));
1182 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n"));
1183
1184 }
1185 else
1186 {
1187 _rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8);
1188 _rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8);
1189
1190 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",
1191 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1],
1192 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3],
1193 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5],
1194 padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7]));
1195 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n"));
1196
1197 }
1198
1199 //set group key by index
1200 _rtw_memcpy(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial, key->KeyLength);
1201
1202 key->KeyIndex=key->KeyIndex & 0x03;
1203
1204 padapter->securitypriv.binstallGrpkey=_TRUE;
1205
1206 padapter->securitypriv.bcheck_grpkey=_FALSE;
1207
1208 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("reset group key"));
1209
1210 res=rtw_set_key(padapter,&padapter->securitypriv, key->KeyIndex, 1);
1211
1212 if(res==_FAIL)
1213 ret= _FAIL;
1214
1215 goto exit;
1216
1217 }
1218 else // Pairwise Key
1219 {
1220 u8 res;
1221
1222 pbssid=get_bssid(&padapter->mlmepriv);
1223 stainfo=rtw_get_stainfo(&padapter->stapriv , pbssid );
1224
1225 if(stainfo!=NULL)
1226 {
1227 _rtw_memset( &stainfo->dot118021x_UncstKey, 0, 16);// clear keybuffer
1228
1229 _rtw_memcpy(&stainfo->dot118021x_UncstKey, key->KeyMaterial, 16);
1230
1231 if(encryptionalgo== _TKIP_)
1232 {
1233 padapter->securitypriv.busetkipkey=_FALSE;
1234
1235 //_set_timer(&padapter->securitypriv.tkip_timer, 50);
1236
1237 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n ==========_set_timer\n"));
1238
1239 // if TKIP, save the Receive/Transmit MIC key in KeyMaterial[128-255]
1240 if((key->KeyIndex & 0x10000000)){
1241 _rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 16, 8);
1242 _rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 24, 8);
1243
1244 } else {
1245 _rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 24, 8);
1246 _rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 16, 8);
1247
1248 }
1249
1250 }
1251 else if(encryptionalgo == _AES_)
1252 {
1253
1254 }
1255
1256
1257 //Set key to CAM through H2C command
1258 if(bgrouptkey)//never go to here
1259 {
1260 res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _FALSE);
1261 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(group)\n"));
1262 }
1263 else{
1264 res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _TRUE);
1265 RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(unicast)\n"));
1266 }
1267
1268 if(res ==_FALSE)
1269 ret= _FAIL;
1270
1271 }
1272
1273 }
1274
1275exit:
1276
1277_func_exit_;
1278
1279 return ret;
1280}
1281
1282u8 rtw_set_802_11_remove_key(_adapter* padapter, NDIS_802_11_REMOVE_KEY *key){
1283
1284 uint encryptionalgo;
1285 u8 * pbssid;
1286 struct sta_info *stainfo;
1287 u8 bgroup = (key->KeyIndex & 0x4000000) > 0 ? _FALSE: _TRUE;
1288 u8 keyIndex = (u8)key->KeyIndex & 0x03;
1289 u8 ret=_SUCCESS;
1290
1291_func_enter_;
1292
1293 if ((key->KeyIndex & 0xbffffffc) > 0) {
1294 ret=_FAIL;
1295 goto exit;
1296 }
1297
1298 if (bgroup == _TRUE) {
1299 encryptionalgo= padapter->securitypriv.dot118021XGrpPrivacy;
1300 // clear group key by index
1301 //NdisZeroMemory(Adapter->MgntInfo.SecurityInfo.KeyBuf[keyIndex], MAX_WEP_KEY_LEN);
1302 //Adapter->MgntInfo.SecurityInfo.KeyLen[keyIndex] = 0;
1303
1304 _rtw_memset(&padapter->securitypriv.dot118021XGrpKey[keyIndex], 0, 16);
1305
1306 //! \todo Send a H2C Command to Firmware for removing this Key in CAM Entry.
1307
1308 } else {
1309
1310 pbssid=get_bssid(&padapter->mlmepriv);
1311 stainfo=rtw_get_stainfo(&padapter->stapriv , pbssid );
1312 if(stainfo !=NULL){
1313 encryptionalgo=stainfo->dot118021XPrivacy;
1314
1315 // clear key by BSSID
1316 _rtw_memset(&stainfo->dot118021x_UncstKey, 0, 16);
1317
1318 //! \todo Send a H2C Command to Firmware for disable this Key in CAM Entry.
1319
1320 }
1321 else{
1322 ret= _FAIL;
1323 goto exit;
1324 }
1325 }
1326
1327exit:
1328
1329_func_exit_;
1330
1331 return _TRUE;
1332
1333}
1334
1335/*
1336* rtw_get_cur_max_rate -
1337* @adapter: pointer to _adapter structure
1338*
1339* Return 0 or 100Kbps
1340*/
1341u16 rtw_get_cur_max_rate(_adapter *adapter)
1342{
1343 int i = 0;
1344 u8 *p;
1345 u16 rate = 0, max_rate = 0;
1346 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
1347 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1348 struct registry_priv *pregistrypriv = &adapter->registrypriv;
1349 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1350 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1351#ifdef CONFIG_80211N_HT
1352 struct rtw_ieee80211_ht_cap *pht_capie;
1353 u8 rf_type = 0;
1354 u8 bw_40MHz=0, short_GI_20=0, short_GI_40=0;
1355 u16 mcs_rate=0;
1356 u32 ht_ielen = 0;
1357#endif
1358
1359#ifdef CONFIG_MP_INCLUDED
1360 if (adapter->registrypriv.mp_mode == 1)
1361 {
1362 if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
1363 return 0;
1364 }
1365#endif
1366
1367 if((check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE)
1368 && (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE))
1369 return 0;
1370
1371#ifdef CONFIG_80211N_HT
1372 if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N|WIRELESS_11_5N)) {
1373 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12);
1374 if(p && ht_ielen>0)
1375 {
1376 pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
1377
1378 _rtw_memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
1379
1380 //bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH) ? 1:0;
1381 //cur_bwmod is updated by beacon, pmlmeinfo is updated by association response
1382 bw_40MHz = (pmlmeext->cur_bwmode && (HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH & pmlmeinfo->HT_info.infos[0])) ? 1:0;
1383
1384 //short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1:0;
1385 short_GI_20 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info&IEEE80211_HT_CAP_SGI_20) ? 1:0;
1386 short_GI_40 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info&IEEE80211_HT_CAP_SGI_40) ? 1:0;
1387
1388 rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
1389 max_rate = rtw_mcs_rate(
1390 rf_type,
1391 bw_40MHz & (pregistrypriv->cbw40_enable),
1392 short_GI_20,
1393 short_GI_40,
1394 pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate
1395 );
1396 }
1397 }
1398 else
1399#endif //CONFIG_80211N_HT
1400 {
1401 while( (pcur_bss->SupportedRates[i]!=0) && (pcur_bss->SupportedRates[i]!=0xFF))
1402 {
1403 rate = pcur_bss->SupportedRates[i]&0x7F;
1404 if(rate>max_rate)
1405 max_rate = rate;
1406 i++;
1407 }
1408
1409 max_rate = max_rate*10/2;
1410 }
1411
1412 return max_rate;
1413}
1414
1415/*
1416* rtw_set_scan_mode -
1417* @adapter: pointer to _adapter structure
1418* @scan_mode:
1419*
1420* Return _SUCCESS or _FAIL
1421*/
1422int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode)
1423{
1424 if(scan_mode != SCAN_ACTIVE && scan_mode != SCAN_PASSIVE)
1425 return _FAIL;
1426
1427 adapter->mlmepriv.scan_mode = scan_mode;
1428
1429 return _SUCCESS;
1430}
1431
1432/*
1433* rtw_set_channel_plan -
1434* @adapter: pointer to _adapter structure
1435* @channel_plan:
1436*
1437* Return _SUCCESS or _FAIL
1438*/
1439int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan)
1440{
1441 struct registry_priv *pregistrypriv = &adapter->registrypriv;
1442 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1443
1444 //handle by cmd_thread to sync with scan operation
1445 return rtw_set_chplan_cmd(adapter, channel_plan, 1);
1446}
1447
1448/*
1449* rtw_set_country -
1450* @adapter: pointer to _adapter structure
1451* @country_code: string of country code
1452*
1453* Return _SUCCESS or _FAIL
1454*/
1455int rtw_set_country(_adapter *adapter, const char *country_code)
1456{
1457 int channel_plan = RT_CHANNEL_DOMAIN_WORLD_WIDE_5G;
1458
1459 DBG_871X("%s country_code:%s\n", __func__, country_code);
1460
1461 //TODO: should have a table to match country code and RT_CHANNEL_DOMAIN
1462 //TODO: should consider 2-character and 3-character country code
1463 if(0 == strcmp(country_code, "US"))
1464 channel_plan = RT_CHANNEL_DOMAIN_FCC;
1465 else if(0 == strcmp(country_code, "EU"))
1466 channel_plan = RT_CHANNEL_DOMAIN_ETSI;
1467 else if(0 == strcmp(country_code, "JP"))
1468 channel_plan = RT_CHANNEL_DOMAIN_MKK;
1469 else if(0 == strcmp(country_code, "CN"))
1470 channel_plan = RT_CHANNEL_DOMAIN_CHINA;
1471 else
1472 DBG_871X("%s unknown country_code:%s\n", __FUNCTION__, country_code);
1473
1474 return rtw_set_channel_plan(adapter, channel_plan);
1475}
1476
1477/*
1478* rtw_set_band -
1479* @adapter: pointer to _adapter structure
1480* @band: band to set
1481*
1482* Return _SUCCESS or _FAIL
1483*/
1484int rtw_set_band(_adapter *adapter, enum _BAND band)
1485{
1486 if (rtw_band_valid(band)) {
1487 DBG_871X(FUNC_ADPT_FMT" band:%d\n", FUNC_ADPT_ARG(adapter), band);
1488 adapter->setband = band;
1489 return _SUCCESS;
1490 }
1491
1492 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" band:%d fail\n", FUNC_ADPT_ARG(adapter), band);
1493 return _FAIL;
1494}