1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3 *
4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 *
6 ******************************************************************************/
7 #define _RTW_IOCTL_SET_C_
8
9 #include <drv_types.h>
10 #include <rtw_debug.h>
11
12 #define IS_MAC_ADDRESS_BROADCAST(addr) \
13 (\
14 ((addr[0] == 0xff) && (addr[1] == 0xff) && \
15 (addr[2] == 0xff) && (addr[3] == 0xff) && \
16 (addr[4] == 0xff) && (addr[5] == 0xff)) ? true : false \
17 )
18
rtw_validate_bssid(u8 * bssid)19 u8 rtw_validate_bssid(u8 *bssid)
20 {
21 u8 ret = true;
22
23 if (is_zero_mac_addr(bssid)
24 || is_broadcast_mac_addr(bssid)
25 || is_multicast_mac_addr(bssid)
26 ) {
27 ret = false;
28 }
29
30 return ret;
31 }
32
rtw_validate_ssid(struct ndis_802_11_ssid * ssid)33 u8 rtw_validate_ssid(struct ndis_802_11_ssid *ssid)
34 {
35 u8 ret = true;
36
37 if (ssid->SsidLength > 32) {
38 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid length >32\n"));
39 ret = false;
40 goto exit;
41 }
42
43 #ifdef CONFIG_VALIDATE_SSID
44 for (i = 0; i < ssid->SsidLength; i++) {
45 /* wifi, printable ascii code must be supported */
46 if (!((ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e))) {
47 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid has nonprintabl ascii\n"));
48 ret = false;
49 break;
50 }
51 }
52 #endif /* CONFIG_VALIDATE_SSID */
53
54 exit:
55 return ret;
56 }
57
58 u8 rtw_do_join(struct adapter *padapter);
rtw_do_join(struct adapter * padapter)59 u8 rtw_do_join(struct adapter *padapter)
60 {
61 struct list_head *plist, *phead;
62 u8 *pibss = NULL;
63 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
64 struct __queue *queue = &(pmlmepriv->scanned_queue);
65 u8 ret = _SUCCESS;
66
67 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
68 phead = get_list_head(queue);
69 plist = get_next(phead);
70
71 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("\n rtw_do_join: phead = %p; plist = %p\n\n\n", phead, plist));
72
73 pmlmepriv->cur_network.join_res = -2;
74
75 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
76
77 pmlmepriv->pscanned = plist;
78
79 pmlmepriv->to_join = true;
80
81 if (list_empty(&queue->queue)) {
82 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
83 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
84
85 /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */
86 /* we try to issue sitesurvey firstly */
87
88 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == false
89 || rtw_to_roam(padapter) > 0
90 ) {
91 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("rtw_do_join(): site survey if scanned_queue is empty\n."));
92 /* submit site_survey_cmd */
93 ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
94 if (_SUCCESS != ret) {
95 pmlmepriv->to_join = false;
96 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_do_join(): site survey return error\n."));
97 }
98 } else{
99 pmlmepriv->to_join = false;
100 ret = _FAIL;
101 }
102
103 goto exit;
104 } else{
105 int select_ret;
106 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
107 select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
108 if (select_ret == _SUCCESS) {
109 pmlmepriv->to_join = false;
110 _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
111 } else{
112 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) {
113 /* submit createbss_cmd to change to a ADHOC_MASTER */
114
115 /* pmlmepriv->lock has been acquired by caller... */
116 struct wlan_bssid_ex *pdev_network = &(padapter->registrypriv.dev_network);
117
118 pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
119
120 pibss = padapter->registrypriv.dev_network.MacAddress;
121
122 memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
123
124 rtw_update_registrypriv_dev_network(padapter);
125
126 rtw_generate_random_ibss(pibss);
127
128 if (rtw_createbss_cmd(padapter) != _SUCCESS) {
129 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("***Error =>do_goin: rtw_createbss_cmd status FAIL***\n "));
130 ret = false;
131 goto exit;
132 }
133
134 pmlmepriv->to_join = false;
135
136 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("***Error => rtw_select_and_join_from_scanned_queue FAIL under STA_Mode***\n "));
137
138 } else{
139 /* can't associate ; reset under-linking */
140 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
141
142 /* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */
143 /* we try to issue sitesurvey firstly */
144 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == false
145 || rtw_to_roam(padapter) > 0
146 ) {
147 /* DBG_871X("rtw_do_join() when no desired bss in scanning queue\n"); */
148 ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
149 if (_SUCCESS != ret) {
150 pmlmepriv->to_join = false;
151 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("do_join(): site survey return error\n."));
152 }
153 } else{
154 ret = _FAIL;
155 pmlmepriv->to_join = false;
156 }
157 }
158
159 }
160
161 }
162
163 exit:
164 return ret;
165 }
166
rtw_set_802_11_bssid(struct adapter * padapter,u8 * bssid)167 u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid)
168 {
169 u8 status = _SUCCESS;
170
171 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
172
173 DBG_871X_LEVEL(_drv_always_, "set bssid:%pM\n", bssid);
174
175 if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 && bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) ||
176 (bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF && bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) {
177 status = _FAIL;
178 goto exit;
179 }
180
181 spin_lock_bh(&pmlmepriv->lock);
182
183
184 DBG_871X("Set BSSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
185 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
186 goto handle_tkip_countermeasure;
187 } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
188 goto release_mlme_lock;
189 }
190
191 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) {
192 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
193
194 if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN)) {
195 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)
196 goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
197 } else {
198 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("Set BSSID not the same bssid\n"));
199 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid ="MAC_FMT"\n", MAC_ARG(bssid)));
200 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("cur_bssid ="MAC_FMT"\n", MAC_ARG(pmlmepriv->cur_network.network.MacAddress)));
201
202 rtw_disassoc_cmd(padapter, 0, true);
203
204 if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
205 rtw_indicate_disconnect(padapter);
206
207 rtw_free_assoc_resources(padapter, 1);
208
209 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
210 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
211 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
212 }
213 }
214 }
215
216 handle_tkip_countermeasure:
217 if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
218 status = _FAIL;
219 goto release_mlme_lock;
220 }
221
222 memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
223 memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
224 pmlmepriv->assoc_by_bssid = true;
225
226 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
227 pmlmepriv->to_join = true;
228 } else {
229 status = rtw_do_join(padapter);
230 }
231
232 release_mlme_lock:
233 spin_unlock_bh(&pmlmepriv->lock);
234
235 exit:
236 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
237 ("rtw_set_802_11_bssid: status =%d\n", status));
238
239 return status;
240 }
241
rtw_set_802_11_ssid(struct adapter * padapter,struct ndis_802_11_ssid * ssid)242 u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid)
243 {
244 u8 status = _SUCCESS;
245
246 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
247 struct wlan_network *pnetwork = &pmlmepriv->cur_network;
248
249 DBG_871X_LEVEL(_drv_always_, "set ssid [%s] fw_state = 0x%08x\n",
250 ssid->Ssid, get_fwstate(pmlmepriv));
251
252 if (padapter->hw_init_completed == false) {
253 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
254 ("set_ssid: hw_init_completed ==false =>exit!!!\n"));
255 status = _FAIL;
256 goto exit;
257 }
258
259 spin_lock_bh(&pmlmepriv->lock);
260
261 DBG_871X("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
262 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
263 goto handle_tkip_countermeasure;
264 } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
265 goto release_mlme_lock;
266 }
267
268 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) {
269 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
270 ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
271
272 if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
273 (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength))) {
274 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)) {
275 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
276 ("Set SSID is the same ssid, fw_state = 0x%08x\n",
277 get_fwstate(pmlmepriv)));
278
279 if (rtw_is_same_ibss(padapter, pnetwork) == false) {
280 /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */
281 rtw_disassoc_cmd(padapter, 0, true);
282
283 if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
284 rtw_indicate_disconnect(padapter);
285
286 rtw_free_assoc_resources(padapter, 1);
287
288 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
289 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
290 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
291 }
292 } else{
293 goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
294 }
295 } else {
296 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1);
297 }
298 } else{
299 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("Set SSID not the same ssid\n"));
300 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid =[%s] len = 0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength));
301 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));
302
303 rtw_disassoc_cmd(padapter, 0, true);
304
305 if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
306 rtw_indicate_disconnect(padapter);
307
308 rtw_free_assoc_resources(padapter, 1);
309
310 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
311 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
312 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
313 }
314 }
315 }
316
317 handle_tkip_countermeasure:
318 if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
319 status = _FAIL;
320 goto release_mlme_lock;
321 }
322
323 if (rtw_validate_ssid(ssid) == false) {
324 status = _FAIL;
325 goto release_mlme_lock;
326 }
327
328 memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid));
329 pmlmepriv->assoc_by_bssid = false;
330
331 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
332 pmlmepriv->to_join = true;
333 } else {
334 status = rtw_do_join(padapter);
335 }
336
337 release_mlme_lock:
338 spin_unlock_bh(&pmlmepriv->lock);
339
340 exit:
341 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
342 ("-rtw_set_802_11_ssid: status =%d\n", status));
343
344 return status;
345 }
346
rtw_set_802_11_connect(struct adapter * padapter,u8 * bssid,struct ndis_802_11_ssid * ssid)347 u8 rtw_set_802_11_connect(struct adapter *padapter, u8 *bssid, struct ndis_802_11_ssid *ssid)
348 {
349 u8 status = _SUCCESS;
350 bool bssid_valid = true;
351 bool ssid_valid = true;
352 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
353
354 if (!ssid || rtw_validate_ssid(ssid) == false)
355 ssid_valid = false;
356
357 if (!bssid || rtw_validate_bssid(bssid) == false)
358 bssid_valid = false;
359
360 if (ssid_valid == false && bssid_valid == false) {
361 DBG_871X(FUNC_ADPT_FMT" ssid:%p, ssid_valid:%d, bssid:%p, bssid_valid:%d\n",
362 FUNC_ADPT_ARG(padapter), ssid, ssid_valid, bssid, bssid_valid);
363 status = _FAIL;
364 goto exit;
365 }
366
367 if (padapter->hw_init_completed == false) {
368 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
369 ("set_ssid: hw_init_completed ==false =>exit!!!\n"));
370 status = _FAIL;
371 goto exit;
372 }
373
374 spin_lock_bh(&pmlmepriv->lock);
375
376 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" fw_state = 0x%08x\n",
377 FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv));
378
379 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
380 goto handle_tkip_countermeasure;
381 } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
382 goto release_mlme_lock;
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 if (ssid && ssid_valid)
392 memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid));
393 else
394 memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
395
396 if (bssid && bssid_valid) {
397 memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
398 pmlmepriv->assoc_by_bssid = true;
399 } else {
400 pmlmepriv->assoc_by_bssid = false;
401 }
402
403 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
404 pmlmepriv->to_join = true;
405 } else {
406 status = rtw_do_join(padapter);
407 }
408
409 release_mlme_lock:
410 spin_unlock_bh(&pmlmepriv->lock);
411
412 exit:
413 return status;
414 }
415
rtw_set_802_11_infrastructure_mode(struct adapter * padapter,enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)416 u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter,
417 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
418 {
419 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
420 struct wlan_network *cur_network = &pmlmepriv->cur_network;
421 enum NDIS_802_11_NETWORK_INFRASTRUCTURE *pold_state = &(cur_network->network.InfrastructureMode);
422
423 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_,
424 ("+rtw_set_802_11_infrastructure_mode: old =%d new =%d fw_state = 0x%08x\n",
425 *pold_state, networktype, get_fwstate(pmlmepriv)));
426
427 if (*pold_state != networktype) {
428 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, (" change mode!"));
429 /* DBG_871X("change mode, old_mode =%d, new_mode =%d, fw_state = 0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); */
430
431 if (*pold_state == Ndis802_11APMode) {
432 /* change to other mode from Ndis802_11APMode */
433 cur_network->join_res = -1;
434
435 stop_ap_mode(padapter);
436 }
437
438 spin_lock_bh(&pmlmepriv->lock);
439
440 if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) || (*pold_state == Ndis802_11IBSS))
441 rtw_disassoc_cmd(padapter, 0, true);
442
443 if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||
444 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true))
445 rtw_free_assoc_resources(padapter, 1);
446
447 if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) {
448 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
449 rtw_indicate_disconnect(padapter); /* will clr Linked_state; before this function, we must have chked whether issue dis-assoc_cmd or not */
450 }
451 }
452
453 *pold_state = networktype;
454
455 _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
456
457 switch (networktype) {
458 case Ndis802_11IBSS:
459 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
460 break;
461
462 case Ndis802_11Infrastructure:
463 set_fwstate(pmlmepriv, WIFI_STATION_STATE);
464 break;
465
466 case Ndis802_11APMode:
467 set_fwstate(pmlmepriv, WIFI_AP_STATE);
468 start_ap_mode(padapter);
469 /* rtw_indicate_connect(padapter); */
470
471 break;
472
473 case Ndis802_11AutoUnknown:
474 case Ndis802_11InfrastructureMax:
475 break;
476 }
477
478 /* SecClearAllKeys(adapter); */
479
480 /* RT_TRACE(COMP_OID_SET, DBG_LOUD, ("set_infrastructure: fw_state:%x after changing mode\n", */
481 /* get_fwstate(pmlmepriv))); */
482
483 spin_unlock_bh(&pmlmepriv->lock);
484 }
485 return true;
486 }
487
488
rtw_set_802_11_disassociate(struct adapter * padapter)489 u8 rtw_set_802_11_disassociate(struct adapter *padapter)
490 {
491 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
492
493 spin_lock_bh(&pmlmepriv->lock);
494
495 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
496 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_disassociate: rtw_indicate_disconnect\n"));
497
498 rtw_disassoc_cmd(padapter, 0, true);
499 rtw_indicate_disconnect(padapter);
500 /* modify for CONFIG_IEEE80211W, none 11w can use it */
501 rtw_free_assoc_resources_cmd(padapter);
502 if (_FAIL == rtw_pwr_wakeup(padapter))
503 DBG_871X("%s(): rtw_pwr_wakeup fail !!!\n", __func__);
504 }
505
506 spin_unlock_bh(&pmlmepriv->lock);
507
508 return true;
509 }
510
rtw_set_802_11_bssid_list_scan(struct adapter * padapter,struct ndis_802_11_ssid * pssid,int ssid_max_num)511 u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_ssid *pssid, int ssid_max_num)
512 {
513 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
514 u8 res = true;
515
516 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("+rtw_set_802_11_bssid_list_scan(), fw_state =%x\n", get_fwstate(pmlmepriv)));
517
518 if (padapter == NULL) {
519 res = false;
520 goto exit;
521 }
522 if (padapter->hw_init_completed == false) {
523 res = false;
524 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n ===rtw_set_802_11_bssid_list_scan:hw_init_completed ==false ===\n"));
525 goto exit;
526 }
527
528 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true) ||
529 (pmlmepriv->LinkDetectInfo.bBusyTraffic == true)) {
530 /* Scan or linking is in progress, do nothing. */
531 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)));
532 res = true;
533
534 if (check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)) == true) {
535 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n###_FW_UNDER_SURVEY|_FW_UNDER_LINKING\n\n"));
536 } else {
537 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n###pmlmepriv->sitesurveyctrl.traffic_busy ==true\n\n"));
538 }
539 } else {
540 if (rtw_is_scan_deny(padapter)) {
541 DBG_871X(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter));
542 indicate_wx_scan_complete_event(padapter);
543 return _SUCCESS;
544 }
545
546 spin_lock_bh(&pmlmepriv->lock);
547
548 res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0);
549
550 spin_unlock_bh(&pmlmepriv->lock);
551 }
552 exit:
553
554 return res;
555 }
556
rtw_set_802_11_authentication_mode(struct adapter * padapter,enum NDIS_802_11_AUTHENTICATION_MODE authmode)557 u8 rtw_set_802_11_authentication_mode(struct adapter *padapter, enum NDIS_802_11_AUTHENTICATION_MODE authmode)
558 {
559 struct security_priv *psecuritypriv = &padapter->securitypriv;
560 int res;
561 u8 ret;
562
563 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_802_11_auth.mode(): mode =%x\n", authmode));
564
565 psecuritypriv->ndisauthtype = authmode;
566
567 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("rtw_set_802_11_authentication_mode:psecuritypriv->ndisauthtype =%d", psecuritypriv->ndisauthtype));
568
569 if (psecuritypriv->ndisauthtype > 3)
570 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
571
572 res = rtw_set_auth(padapter, psecuritypriv);
573
574 if (res == _SUCCESS)
575 ret = true;
576 else
577 ret = false;
578
579 return ret;
580 }
581
rtw_set_802_11_add_wep(struct adapter * padapter,struct ndis_802_11_wep * wep)582 u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep)
583 {
584
585 sint keyid, res;
586 struct security_priv *psecuritypriv = &(padapter->securitypriv);
587 u8 ret = _SUCCESS;
588
589 keyid = wep->KeyIndex & 0x3fffffff;
590
591 if (keyid >= 4) {
592 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("MgntActrtw_set_802_11_add_wep:keyid>4 =>fail\n"));
593 ret = false;
594 goto exit;
595 }
596
597 switch (wep->KeyLength) {
598 case 5:
599 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
600 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength =5\n"));
601 break;
602 case 13:
603 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
604 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength = 13\n"));
605 break;
606 default:
607 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
608 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength!=5 or 13\n"));
609 break;
610 }
611
612 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
613 ("rtw_set_802_11_add_wep:before memcpy, wep->KeyLength = 0x%x wep->KeyIndex = 0x%x keyid =%x\n",
614 wep->KeyLength, wep->KeyIndex, keyid));
615
616 memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]), &(wep->KeyMaterial), wep->KeyLength);
617
618 psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength;
619
620 psecuritypriv->dot11PrivacyKeyIndex = keyid;
621
622 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",
623 psecuritypriv->dot11DefKey[keyid].skey[0], psecuritypriv->dot11DefKey[keyid].skey[1], psecuritypriv->dot11DefKey[keyid].skey[2],
624 psecuritypriv->dot11DefKey[keyid].skey[3], psecuritypriv->dot11DefKey[keyid].skey[4], psecuritypriv->dot11DefKey[keyid].skey[5],
625 psecuritypriv->dot11DefKey[keyid].skey[6], psecuritypriv->dot11DefKey[keyid].skey[7], psecuritypriv->dot11DefKey[keyid].skey[8],
626 psecuritypriv->dot11DefKey[keyid].skey[9], psecuritypriv->dot11DefKey[keyid].skey[10], psecuritypriv->dot11DefKey[keyid].skey[11],
627 psecuritypriv->dot11DefKey[keyid].skey[12]));
628
629 res = rtw_set_key(padapter, psecuritypriv, keyid, 1, true);
630
631 if (res == _FAIL)
632 ret = false;
633 exit:
634
635 return ret;
636 }
637
638 /*
639 * rtw_get_cur_max_rate -
640 * @adapter: pointer to struct adapter structure
641 *
642 * Return 0 or 100Kbps
643 */
rtw_get_cur_max_rate(struct adapter * adapter)644 u16 rtw_get_cur_max_rate(struct adapter *adapter)
645 {
646 int i = 0;
647 u16 rate = 0, max_rate = 0;
648 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
649 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
650 struct sta_info *psta = NULL;
651 u8 short_GI = 0;
652 u8 rf_type = 0;
653
654 if ((check_fwstate(pmlmepriv, _FW_LINKED) != true)
655 && (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != true))
656 return 0;
657
658 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
659 if (psta == NULL)
660 return 0;
661
662 short_GI = query_ra_short_GI(psta);
663
664 if (IsSupportedHT(psta->wireless_mode)) {
665 rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
666
667 max_rate = rtw_mcs_rate(
668 rf_type,
669 ((psta->bw_mode == CHANNEL_WIDTH_40)?1:0),
670 short_GI,
671 psta->htpriv.ht_cap.supp_mcs_set
672 );
673 } else{
674 while ((pcur_bss->SupportedRates[i] != 0) && (pcur_bss->SupportedRates[i] != 0xFF)) {
675 rate = pcur_bss->SupportedRates[i]&0x7F;
676 if (rate > max_rate)
677 max_rate = rate;
678 i++;
679 }
680
681 max_rate = max_rate*10/2;
682 }
683
684 return max_rate;
685 }
686