]>
Commit | Line | Data |
---|---|---|
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 | ||
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 | ||
1130c632 | 46 | u8 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 | ||
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 | ||
1130c632 PE |
538 | u8 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 | ||
581 | handle_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 | ||
602 | release_mlme_lock: | |
603 | _exit_critical_bh(&pmlmepriv->lock, &irqL); | |
604 | ||
605 | exit: | |
606 | ||
607 | _func_exit_; | |
608 | ||
609 | return status; | |
610 | } | |
611 | ||
612 | /* | |
613 | rtw_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 | */ | |
617 | u8 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 | ||
703 | u8 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 | ||
729 | u8 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 | } | |
774 | exit: | |
775 | ||
776 | _func_exit_; | |
777 | ||
778 | return res; | |
779 | } | |
780 | ||
781 | u8 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 | ||
810 | u8 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; | |
866 | exit: | |
867 | ||
868 | _func_exit_; | |
869 | ||
870 | return ret; | |
871 | ||
872 | } | |
873 | ||
874 | u8 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 | ||
909 | exit: | |
910 | ||
911 | _func_exit_; | |
912 | ||
913 | return ret; | |
914 | ||
915 | } | |
916 | ||
917 | u8 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 | ||
1275 | exit: | |
1276 | ||
1277 | _func_exit_; | |
1278 | ||
1279 | return ret; | |
1280 | } | |
1281 | ||
1282 | u8 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 | ||
1327 | exit: | |
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 | */ | |
1341 | u16 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 | */ | |
1422 | int 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 | */ | |
1439 | int 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 | */ | |
1455 | int 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 | */ | |
1484 | int 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 | } |