1
2
3
4#define _RTW_IOCTL_SET_C_
5
6#include "../include/osdep_service.h"
7#include "../include/drv_types.h"
8#include "../include/rtw_ioctl_set.h"
9#include "../include/hal_intf.h"
10
11#include "../include/usb_osintf.h"
12#include "../include/usb_ops.h"
13
14extern void indicate_wx_scan_complete_event(struct adapter *padapter);
15
16u8 rtw_do_join(struct adapter *padapter)
17{
18 struct list_head *plist, *phead;
19 u8 *pibss = NULL;
20 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
21 struct __queue *queue = &pmlmepriv->scanned_queue;
22 u8 ret = _SUCCESS;
23
24 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
25 phead = get_list_head(queue);
26 plist = phead->next;
27
28 pmlmepriv->cur_network.join_res = -2;
29
30 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
31
32 pmlmepriv->pscanned = plist;
33
34 pmlmepriv->to_join = true;
35
36 if (list_empty(&queue->queue)) {
37 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
38 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
39
40
41
42
43 if (!pmlmepriv->LinkDetectInfo.bBusyTraffic ||
44 pmlmepriv->to_roaming > 0) {
45
46 ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
47 if (_SUCCESS != ret)
48 pmlmepriv->to_join = false;
49 } else {
50 pmlmepriv->to_join = false;
51 ret = _FAIL;
52 }
53
54 return ret;
55 } else {
56 int select_ret;
57
58 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
59 select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
60 if (select_ret == _SUCCESS) {
61 pmlmepriv->to_join = false;
62 _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
63 } else {
64 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
65
66
67
68 struct wlan_bssid_ex *pdev_network = &padapter->registrypriv.dev_network;
69
70 pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
71
72 pibss = padapter->registrypriv.dev_network.MacAddress;
73
74 memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
75 memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
76
77 rtw_update_registrypriv_dev_network(padapter);
78
79 rtw_generate_random_ibss(pibss);
80
81 if (rtw_createbss_cmd(padapter) != _SUCCESS)
82 return false;
83
84 pmlmepriv->to_join = false;
85 } else {
86
87 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
88
89
90
91 if (!pmlmepriv->LinkDetectInfo.bBusyTraffic ||
92 pmlmepriv->to_roaming > 0) {
93 ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
94 if (_SUCCESS != ret)
95 pmlmepriv->to_join = false;
96 } else {
97 ret = _FAIL;
98 pmlmepriv->to_join = false;
99 }
100 }
101 }
102 }
103
104 return ret;
105}
106
107u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid)
108{
109 u8 status = _SUCCESS;
110 u32 cur_time = 0;
111 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
112
113 DBG_88E_LEVEL(_drv_info_, "set bssid:%pM\n", bssid);
114
115 if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 &&
116 bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) ||
117 (bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF &&
118 bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) {
119 status = _FAIL;
120 goto exit;
121 }
122
123 spin_lock_bh(&pmlmepriv->lock);
124
125 DBG_88E("Set BSSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
126 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
127 goto handle_tkip_countermeasure;
128 else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
129 goto release_mlme_lock;
130
131 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
132 if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN)) {
133 if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE))
134 goto release_mlme_lock;
135 } else {
136 rtw_disassoc_cmd(padapter, 0, true);
137
138 if (check_fwstate(pmlmepriv, _FW_LINKED))
139 rtw_indicate_disconnect(padapter);
140
141 rtw_free_assoc_resources(padapter, 1);
142
143 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
144 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
145 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
146 }
147 }
148 }
149
150handle_tkip_countermeasure:
151
152
153 if (padapter->securitypriv.btkip_countermeasure) {
154 cur_time = jiffies;
155
156 if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) {
157 padapter->securitypriv.btkip_countermeasure = false;
158 padapter->securitypriv.btkip_countermeasure_time = 0;
159 } else {
160 status = _FAIL;
161 goto release_mlme_lock;
162 }
163 }
164
165 memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
166 pmlmepriv->assoc_by_bssid = true;
167
168 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
169 pmlmepriv->to_join = true;
170 else
171 status = rtw_do_join(padapter);
172
173release_mlme_lock:
174 spin_unlock_bh(&pmlmepriv->lock);
175
176exit:
177 return status;
178}
179
180u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid)
181{
182 u8 status = _SUCCESS;
183 u32 cur_time = 0;
184
185 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
186 struct wlan_network *pnetwork = &pmlmepriv->cur_network;
187
188 DBG_88E_LEVEL(_drv_info_, "set ssid [%s] fw_state=0x%08x\n",
189 ssid->Ssid, get_fwstate(pmlmepriv));
190
191 if (!padapter->hw_init_completed) {
192 status = _FAIL;
193 goto exit;
194 }
195
196 spin_lock_bh(&pmlmepriv->lock);
197
198 DBG_88E("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
199 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
200 goto handle_tkip_countermeasure;
201 } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
202 goto release_mlme_lock;
203 }
204
205 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
206 if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
207 (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength))) {
208 if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
209 if (!rtw_is_same_ibss(padapter, pnetwork)) {
210
211 rtw_disassoc_cmd(padapter, 0, true);
212
213 if (check_fwstate(pmlmepriv, _FW_LINKED))
214 rtw_indicate_disconnect(padapter);
215
216 rtw_free_assoc_resources(padapter, 1);
217
218 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
219 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
220 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
221 }
222 } else {
223 goto release_mlme_lock;
224 }
225 } else {
226 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1);
227 }
228 } else {
229 rtw_disassoc_cmd(padapter, 0, true);
230
231 if (check_fwstate(pmlmepriv, _FW_LINKED))
232 rtw_indicate_disconnect(padapter);
233
234 rtw_free_assoc_resources(padapter, 1);
235
236 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
237 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
238 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
239 }
240 }
241 }
242
243handle_tkip_countermeasure:
244
245 if (padapter->securitypriv.btkip_countermeasure) {
246 cur_time = jiffies;
247
248 if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) {
249 padapter->securitypriv.btkip_countermeasure = false;
250 padapter->securitypriv.btkip_countermeasure_time = 0;
251 } else {
252 status = _FAIL;
253 goto release_mlme_lock;
254 }
255 }
256
257 memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid));
258 pmlmepriv->assoc_by_bssid = false;
259
260 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
261 pmlmepriv->to_join = true;
262 } else {
263 status = rtw_do_join(padapter);
264 }
265
266release_mlme_lock:
267 spin_unlock_bh(&pmlmepriv->lock);
268
269exit:
270 return status;
271}
272
273u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter,
274 enum ndis_802_11_network_infra networktype)
275{
276 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
277 struct wlan_network *cur_network = &pmlmepriv->cur_network;
278 enum ndis_802_11_network_infra *pold_state = &cur_network->network.InfrastructureMode;
279
280 if (*pold_state != networktype) {
281 spin_lock_bh(&pmlmepriv->lock);
282
283
284
285 if (*pold_state == Ndis802_11APMode) {
286
287 cur_network->join_res = -1;
288
289 stop_ap_mode(padapter);
290 }
291
292 if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
293 (*pold_state == Ndis802_11IBSS))
294 rtw_disassoc_cmd(padapter, 0, true);
295
296 if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
297 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
298 rtw_free_assoc_resources(padapter, 1);
299
300 if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) {
301 if (check_fwstate(pmlmepriv, _FW_LINKED))
302 rtw_indicate_disconnect(padapter);
303 }
304
305 *pold_state = networktype;
306
307 _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
308
309 switch (networktype) {
310 case Ndis802_11IBSS:
311 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
312 break;
313 case Ndis802_11Infrastructure:
314 set_fwstate(pmlmepriv, WIFI_STATION_STATE);
315 break;
316 case Ndis802_11APMode:
317 set_fwstate(pmlmepriv, WIFI_AP_STATE);
318 break;
319 case Ndis802_11AutoUnknown:
320 case Ndis802_11InfrastructureMax:
321 break;
322 }
323 spin_unlock_bh(&pmlmepriv->lock);
324 }
325
326 return true;
327}
328
329u8 rtw_set_802_11_disassociate(struct adapter *padapter)
330{
331 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
332
333 spin_lock_bh(&pmlmepriv->lock);
334
335 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
336 rtw_disassoc_cmd(padapter, 0, true);
337 rtw_indicate_disconnect(padapter);
338 rtw_free_assoc_resources(padapter, 1);
339 rtw_pwr_wakeup(padapter);
340 }
341
342 spin_unlock_bh(&pmlmepriv->lock);
343
344 return true;
345}
346
347u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_ssid *pssid, int ssid_max_num)
348{
349 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
350 u8 res = true;
351
352 if (!padapter) {
353 res = false;
354 goto exit;
355 }
356 if (!padapter->hw_init_completed) {
357 res = false;
358 goto exit;
359 }
360
361 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) ||
362 (pmlmepriv->LinkDetectInfo.bBusyTraffic)) {
363
364 res = true;
365 } else {
366 if (rtw_is_scan_deny(padapter)) {
367 DBG_88E(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter));
368 indicate_wx_scan_complete_event(padapter);
369 return _SUCCESS;
370 }
371
372 spin_lock_bh(&pmlmepriv->lock);
373
374 res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0);
375
376 spin_unlock_bh(&pmlmepriv->lock);
377 }
378exit:
379
380 return res;
381}
382
383u8 rtw_set_802_11_authentication_mode(struct adapter *padapter, enum ndis_802_11_auth_mode authmode)
384{
385 struct security_priv *psecuritypriv = &padapter->securitypriv;
386 int res;
387 u8 ret;
388
389 psecuritypriv->ndisauthtype = authmode;
390
391 if (psecuritypriv->ndisauthtype > 3)
392 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
393
394 res = rtw_set_auth(padapter, psecuritypriv);
395
396 if (res == _SUCCESS)
397 ret = true;
398 else
399 ret = false;
400
401 return ret;
402}
403
404u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep)
405{
406 int keyid, res;
407 struct security_priv *psecuritypriv = &padapter->securitypriv;
408 u8 ret = _SUCCESS;
409
410 keyid = wep->KeyIndex & 0x3fffffff;
411
412 if (keyid >= 4) {
413 ret = false;
414 goto exit;
415 }
416
417 switch (wep->KeyLength) {
418 case 5:
419 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
420 break;
421 case 13:
422 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
423 break;
424 default:
425 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
426 break;
427 }
428
429 memcpy(&psecuritypriv->dot11DefKey[keyid].skey[0], &wep->KeyMaterial, wep->KeyLength);
430
431 psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength;
432
433 psecuritypriv->dot11PrivacyKeyIndex = keyid;
434
435 res = rtw_set_key(padapter, psecuritypriv, keyid, 1);
436
437 if (res == _FAIL)
438 ret = false;
439exit:
440
441 return ret;
442}
443
444
445
446
447
448
449
450u16 rtw_get_cur_max_rate(struct adapter *adapter)
451{
452 int i = 0;
453 u8 *p;
454 u16 rate = 0, max_rate = 0;
455 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
456 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
457 struct registry_priv *pregistrypriv = &adapter->registrypriv;
458 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
459 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
460 struct ieee80211_ht_cap *pht_capie;
461 u8 rf_type = 0;
462 u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0;
463 u16 mcs_rate = 0;
464 u32 ht_ielen = 0;
465
466 if ((!check_fwstate(pmlmepriv, _FW_LINKED)) &&
467 (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
468 return 0;
469
470 if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N)) {
471 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12);
472 if (p && ht_ielen > 0) {
473 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
474
475 memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2);
476
477
478 bw_40MHz = (pmlmeext->cur_bwmode && (HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH & pmlmeinfo->HT_info.infos[0])) ? 1 : 0;
479
480 short_GI_20 = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & IEEE80211_HT_CAP_SGI_20) ? 1 : 0;
481 short_GI_40 = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & IEEE80211_HT_CAP_SGI_40) ? 1 : 0;
482
483 GetHwReg8188EU(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
484 max_rate = rtw_mcs_rate(
485 rf_type,
486 bw_40MHz & (pregistrypriv->cbw40_enable),
487 short_GI_20,
488 short_GI_40,
489 pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate
490 );
491 }
492 } else {
493 while ((pcur_bss->SupportedRates[i] != 0) && (pcur_bss->SupportedRates[i] != 0xFF)) {
494 rate = pcur_bss->SupportedRates[i] & 0x7F;
495 if (rate > max_rate)
496 max_rate = rate;
497 i++;
498 }
499
500 max_rate *= 5;
501 }
502
503 return max_rate;
504}
505