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