1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2019 Realtek Corporation.
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 *****************************************************************************/
15 #define _RTW_IOCTL_SET_C_
16
17 #include <drv_types.h>
18 #include <hal_data.h>
19
20
21 extern void indicate_wx_scan_complete_event(_adapter *padapter);
22
23 #define IS_MAC_ADDRESS_BROADCAST(addr) \
24 (\
25 ((addr[0] == 0xff) && (addr[1] == 0xff) && \
26 (addr[2] == 0xff) && (addr[3] == 0xff) && \
27 (addr[4] == 0xff) && (addr[5] == 0xff)) ? _TRUE : _FALSE \
28 )
29
rtw_validate_bssid(u8 * bssid)30 u8 rtw_validate_bssid(u8 *bssid)
31 {
32 u8 ret = _TRUE;
33
34 if (is_zero_mac_addr(bssid)
35 || is_broadcast_mac_addr(bssid)
36 || is_multicast_mac_addr(bssid)
37 )
38 ret = _FALSE;
39
40 return ret;
41 }
42
rtw_validate_ssid(NDIS_802_11_SSID * ssid)43 u8 rtw_validate_ssid(NDIS_802_11_SSID *ssid)
44 {
45 #ifdef CONFIG_VALIDATE_SSID
46 u8 i;
47 #endif
48 u8 ret = _TRUE;
49
50
51 if (ssid->SsidLength > 32) {
52 ret = _FALSE;
53 goto exit;
54 }
55
56 #ifdef CONFIG_VALIDATE_SSID
57 for (i = 0; i < ssid->SsidLength; i++) {
58 /* wifi, printable ascii code must be supported */
59 if (!((ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e))) {
60 ret = _FALSE;
61 break;
62 }
63 }
64 #endif /* CONFIG_VALIDATE_SSID */
65
66 exit:
67
68
69 return ret;
70 }
71
72 u8 rtw_do_join(_adapter *padapter);
rtw_do_join(_adapter * padapter)73 u8 rtw_do_join(_adapter *padapter)
74 {
75 _irqL irqL;
76 _list *plist, *phead;
77 u8 *pibss = NULL;
78 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
79 struct sitesurvey_parm parm;
80 _queue *queue = &(pmlmepriv->scanned_queue);
81 u8 ret = _SUCCESS;
82
83
84 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
85 phead = get_list_head(queue);
86 plist = get_next(phead);
87
88
89 pmlmepriv->cur_network.join_res = -2;
90
91 set_fwstate(pmlmepriv, WIFI_UNDER_LINKING);
92
93 pmlmepriv->pscanned = plist;
94
95 pmlmepriv->to_join = _TRUE;
96
97 rtw_init_sitesurvey_parm(padapter, &parm);
98 _rtw_memcpy(&parm.ssid[0], &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
99 parm.ssid_num = 1;
100
101 if (pmlmepriv->assoc_ch) {
102 parm.ch_num = 1;
103 parm.ch[0].hw_value = pmlmepriv->assoc_ch;
104 parm.ch[0].flags = 0;
105 }
106
107 if (_rtw_queue_empty(queue) == _TRUE) {
108 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
109 _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING);
110
111 /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */
112 /* we try to issue sitesurvey firstly */
113
114 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _FALSE
115 || rtw_to_roam(padapter) > 0
116 ) {
117 u8 ssc_chk = rtw_sitesurvey_condition_check(padapter, _FALSE);
118
119 if ((ssc_chk == SS_ALLOW) || (ssc_chk == SS_DENY_BUSY_TRAFFIC) ){
120 /* submit site_survey_cmd */
121 ret = rtw_sitesurvey_cmd(padapter, &parm);
122 if (_SUCCESS != ret)
123 pmlmepriv->to_join = _FALSE;
124 } else {
125 /*if (ssc_chk == SS_DENY_BUDDY_UNDER_SURVEY)*/
126 pmlmepriv->to_join = _FALSE;
127 ret = _FAIL;
128 }
129 } else {
130 pmlmepriv->to_join = _FALSE;
131 ret = _FAIL;
132 }
133
134 goto exit;
135 } else {
136 int select_ret;
137 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
138 select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
139 if (select_ret == _SUCCESS) {
140 u32 join_timeout = MAX_JOIN_TIMEOUT;
141
142 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
143 struct rf_ctl_t *rfctl;
144 rfctl = adapter_to_rfctl(padapter);
145 if (rfctl->ap_csa_en == CSA_STA_JOINBSS)
146 join_timeout += (rfctl->ap_csa_switch_cnt * 100);
147 #endif
148
149 pmlmepriv->to_join = _FALSE;
150 _set_timer(&pmlmepriv->assoc_timer, join_timeout);
151 } else {
152 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
153 #ifdef CONFIG_AP_MODE
154 /* submit createbss_cmd to change to a ADHOC_MASTER */
155
156 /* pmlmepriv->lock has been acquired by caller... */
157 WLAN_BSSID_EX *pdev_network = &(padapter->registrypriv.dev_network);
158
159 /*pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;*/
160 init_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
161
162 pibss = padapter->registrypriv.dev_network.MacAddress;
163
164 _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
165 _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
166
167 rtw_update_registrypriv_dev_network(padapter);
168
169 rtw_generate_random_ibss(pibss);
170
171 if (rtw_create_ibss_cmd(padapter, 0) != _SUCCESS) {
172 ret = _FALSE;
173 goto exit;
174 }
175
176 pmlmepriv->to_join = _FALSE;
177 #endif /* CONFIG_AP_MODE */
178 } else {
179 /* can't associate ; reset under-linking */
180 _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING);
181
182 /* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */
183 /* we try to issue sitesurvey firstly */
184 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _FALSE
185 || rtw_to_roam(padapter) > 0
186 ) {
187 u8 ssc_chk = rtw_sitesurvey_condition_check(padapter, _FALSE);
188
189 if ((ssc_chk == SS_ALLOW) || (ssc_chk == SS_DENY_BUSY_TRAFFIC)){
190 /* RTW_INFO(("rtw_do_join() when no desired bss in scanning queue\n"); */
191 ret = rtw_sitesurvey_cmd(padapter, &parm);
192 if (_SUCCESS != ret)
193 pmlmepriv->to_join = _FALSE;
194 } else {
195 /*if (ssc_chk == SS_DENY_BUDDY_UNDER_SURVEY) {
196 } else {*/
197 ret = _FAIL;
198 pmlmepriv->to_join = _FALSE;
199 }
200 } else {
201 ret = _FAIL;
202 pmlmepriv->to_join = _FALSE;
203 }
204 }
205
206 }
207
208 }
209
210 exit:
211
212 return ret;
213 }
214
rtw_set_802_11_bssid(_adapter * padapter,u8 * bssid)215 u8 rtw_set_802_11_bssid(_adapter *padapter, u8 *bssid)
216 {
217 _irqL irqL;
218 u8 status = _SUCCESS;
219
220 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
221
222
223 RTW_PRINT("set bssid:%pM\n", bssid);
224
225 if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 && bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) ||
226 (bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF && bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) {
227 status = _FAIL;
228 goto exit;
229 }
230
231 _enter_critical_bh(&pmlmepriv->lock, &irqL);
232
233
234 RTW_INFO("Set BSSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
235 if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE)
236 goto handle_tkip_countermeasure;
237 else if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE)
238 goto release_mlme_lock;
239
240 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE) {
241
242 if (_rtw_memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN) == _TRUE) {
243 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)
244 goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
245 } else {
246
247 rtw_disassoc_cmd(padapter, 0, 0);
248
249 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
250 rtw_indicate_disconnect(padapter, 0, _FALSE);
251
252 rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);
253
254 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
255 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
256 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
257 }
258 }
259 }
260
261 handle_tkip_countermeasure:
262 if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
263 status = _FAIL;
264 goto release_mlme_lock;
265 }
266
267 _rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID));
268 _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
269 pmlmepriv->assoc_ch = 0;
270 pmlmepriv->assoc_by_bssid = _TRUE;
271
272 if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE)
273 pmlmepriv->to_join = _TRUE;
274 else
275 status = rtw_do_join(padapter);
276
277 release_mlme_lock:
278 _exit_critical_bh(&pmlmepriv->lock, &irqL);
279
280 exit:
281
282
283 return status;
284 }
285
rtw_set_802_11_ssid(_adapter * padapter,NDIS_802_11_SSID * ssid)286 u8 rtw_set_802_11_ssid(_adapter *padapter, NDIS_802_11_SSID *ssid)
287 {
288 _irqL irqL;
289 u8 status = _SUCCESS;
290
291 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
292 struct wlan_network *pnetwork = &pmlmepriv->cur_network;
293
294
295 RTW_PRINT("set ssid [%s] fw_state=0x%08x\n",
296 ssid->Ssid, get_fwstate(pmlmepriv));
297
298 if (!rtw_is_hw_init_completed(padapter)) {
299 status = _FAIL;
300 goto exit;
301 }
302
303 _enter_critical_bh(&pmlmepriv->lock, &irqL);
304
305 RTW_INFO("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
306 if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE)
307 goto handle_tkip_countermeasure;
308 else if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE)
309 goto release_mlme_lock;
310
311 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE) {
312
313 if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
314 (_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE)) {
315 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)) {
316
317 if (rtw_is_same_ibss(padapter, pnetwork) == _FALSE) {
318 /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */
319 rtw_disassoc_cmd(padapter, 0, 0);
320
321 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
322 rtw_indicate_disconnect(padapter, 0, _FALSE);
323
324 rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);
325
326 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
327 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
328 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
329 }
330 } else {
331 goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
332 }
333 }
334 #ifdef CONFIG_LPS
335 else
336 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 0);
337 #endif
338 } else {
339
340 rtw_disassoc_cmd(padapter, 0, 0);
341
342 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
343 rtw_indicate_disconnect(padapter, 0, _FALSE);
344
345 rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);
346
347 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
348 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
349 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
350 }
351 }
352 }
353
354 handle_tkip_countermeasure:
355 if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
356 status = _FAIL;
357 goto release_mlme_lock;
358 }
359
360 if (rtw_validate_ssid(ssid) == _FALSE) {
361 status = _FAIL;
362 goto release_mlme_lock;
363 }
364
365 _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
366 pmlmepriv->assoc_ch = 0;
367 pmlmepriv->assoc_by_bssid = _FALSE;
368
369 if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE)
370 pmlmepriv->to_join = _TRUE;
371 else
372 status = rtw_do_join(padapter);
373
374 release_mlme_lock:
375 _exit_critical_bh(&pmlmepriv->lock, &irqL);
376
377 exit:
378
379
380 return status;
381
382 }
383
rtw_set_802_11_connect(_adapter * padapter,u8 * bssid,NDIS_802_11_SSID * ssid,u16 ch)384 u8 rtw_set_802_11_connect(_adapter *padapter,
385 u8 *bssid, NDIS_802_11_SSID *ssid, u16 ch)
386 {
387 _irqL irqL;
388 u8 status = _SUCCESS;
389 bool bssid_valid = _TRUE;
390 bool ssid_valid = _TRUE;
391 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
392
393
394 if (!ssid || rtw_validate_ssid(ssid) == _FALSE)
395 ssid_valid = _FALSE;
396
397 if (!bssid || rtw_validate_bssid(bssid) == _FALSE)
398 bssid_valid = _FALSE;
399
400 if (ssid_valid == _FALSE && bssid_valid == _FALSE) {
401 RTW_INFO(FUNC_ADPT_FMT" ssid:%p, ssid_valid:%d, bssid:%p, bssid_valid:%d\n",
402 FUNC_ADPT_ARG(padapter), ssid, ssid_valid, bssid, bssid_valid);
403 status = _FAIL;
404 goto exit;
405 }
406
407 if (!rtw_is_hw_init_completed(padapter)) {
408 status = _FAIL;
409 goto exit;
410 }
411
412 _enter_critical_bh(&pmlmepriv->lock, &irqL);
413
414 RTW_PRINT(FUNC_ADPT_FMT" fw_state=0x%08x\n",
415 FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv));
416
417 if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE)
418 goto handle_tkip_countermeasure;
419 else if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE)
420 goto release_mlme_lock;
421
422 handle_tkip_countermeasure:
423 if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
424 status = _FAIL;
425 goto release_mlme_lock;
426 }
427
428 if (ssid && ssid_valid)
429 _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
430 else
431 _rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID));
432
433 if (bssid && bssid_valid) {
434 _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
435 pmlmepriv->assoc_by_bssid = _TRUE;
436 } else
437 pmlmepriv->assoc_by_bssid = _FALSE;
438
439 pmlmepriv->assoc_ch = ch;
440
441 if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE)
442 pmlmepriv->to_join = _TRUE;
443 else
444 status = rtw_do_join(padapter);
445
446 release_mlme_lock:
447 _exit_critical_bh(&pmlmepriv->lock, &irqL);
448
449 exit:
450 return status;
451 }
452
rtw_set_802_11_infrastructure_mode(_adapter * padapter,NDIS_802_11_NETWORK_INFRASTRUCTURE networktype,u8 flags)453 u8 rtw_set_802_11_infrastructure_mode(_adapter *padapter,
454 NDIS_802_11_NETWORK_INFRASTRUCTURE networktype, u8 flags)
455 {
456 _irqL irqL;
457 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
458 struct wlan_network *cur_network = &pmlmepriv->cur_network;
459 NDIS_802_11_NETWORK_INFRASTRUCTURE *pold_state = &(cur_network->network.InfrastructureMode);
460 u8 ap2sta_mode = _FALSE;
461 u8 ret = _TRUE;
462 u8 is_linked = _FALSE, is_adhoc_master = _FALSE;
463
464 if (*pold_state != networktype) {
465 /* RTW_INFO("change mode, old_mode=%d, new_mode=%d, fw_state=0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); */
466
467 if (*pold_state == Ndis802_11APMode
468 || *pold_state == Ndis802_11_mesh
469 ) {
470 /* change to other mode from Ndis802_11APMode/Ndis802_11_mesh */
471 cur_network->join_res = -1;
472 ap2sta_mode = _TRUE;
473 #ifdef CONFIG_NATIVEAP_MLME
474 stop_ap_mode(padapter);
475 #endif
476 }
477
478 _enter_critical_bh(&pmlmepriv->lock, &irqL);
479 is_linked = check_fwstate(pmlmepriv, WIFI_ASOC_STATE);
480 is_adhoc_master = check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
481
482 /* flags = 0, means enqueue cmd and no wait */
483 if (flags != 0)
484 _exit_critical_bh(&pmlmepriv->lock, &irqL);
485
486 if ((is_linked == _TRUE) || (*pold_state == Ndis802_11IBSS))
487 rtw_disassoc_cmd(padapter, 0, flags);
488
489 if ((is_linked == _TRUE) ||
490 (is_adhoc_master == _TRUE))
491 rtw_free_assoc_resources_cmd(padapter, _TRUE, flags);
492
493 if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) {
494 if (is_linked == _TRUE) {
495 rtw_indicate_disconnect(padapter, 0, _FALSE); /*will clr Linked_state; before this function, we must have checked whether issue dis-assoc_cmd or not*/
496 }
497 }
498
499 /* flags = 0, means enqueue cmd and no wait */
500 if (flags != 0)
501 _enter_critical_bh(&pmlmepriv->lock, &irqL);
502
503 *pold_state = networktype;
504
505 _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
506
507 switch (networktype) {
508 case Ndis802_11IBSS:
509 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
510 break;
511
512 case Ndis802_11Infrastructure:
513 set_fwstate(pmlmepriv, WIFI_STATION_STATE);
514
515 if (ap2sta_mode)
516 rtw_init_bcmc_stainfo(padapter);
517 break;
518
519 case Ndis802_11APMode:
520 set_fwstate(pmlmepriv, WIFI_AP_STATE);
521 #ifdef CONFIG_NATIVEAP_MLME
522 start_ap_mode(padapter);
523 /* rtw_indicate_connect(padapter); */
524 #endif
525
526 break;
527
528 #ifdef CONFIG_RTW_MESH
529 case Ndis802_11_mesh:
530 set_fwstate(pmlmepriv, WIFI_MESH_STATE);
531 start_ap_mode(padapter);
532 break;
533 #endif
534
535 case Ndis802_11AutoUnknown:
536 case Ndis802_11InfrastructureMax:
537 break;
538 #ifdef CONFIG_WIFI_MONITOR
539 case Ndis802_11Monitor:
540 set_fwstate(pmlmepriv, WIFI_MONITOR_STATE);
541 break;
542 #endif /* CONFIG_WIFI_MONITOR */
543 default:
544 ret = _FALSE;
545 rtw_warn_on(1);
546 }
547
548 /* SecClearAllKeys(adapter); */
549
550
551 _exit_critical_bh(&pmlmepriv->lock, &irqL);
552 }
553
554 return ret;
555 }
556
557
rtw_set_802_11_disassociate(_adapter * padapter)558 u8 rtw_set_802_11_disassociate(_adapter *padapter)
559 {
560 _irqL irqL;
561 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
562
563
564 _enter_critical_bh(&pmlmepriv->lock, &irqL);
565
566 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
567
568 rtw_disassoc_cmd(padapter, 0, 0);
569 rtw_indicate_disconnect(padapter, 0, _FALSE);
570 /* modify for CONFIG_IEEE80211W, none 11w can use it */
571 rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);
572 if (_FAIL == rtw_pwr_wakeup(padapter))
573 RTW_INFO("%s(): rtw_pwr_wakeup fail !!!\n", __FUNCTION__);
574 }
575
576 _exit_critical_bh(&pmlmepriv->lock, &irqL);
577
578
579 return _TRUE;
580 }
581
582 #if 1
rtw_set_802_11_bssid_list_scan(_adapter * padapter,struct sitesurvey_parm * pparm)583 u8 rtw_set_802_11_bssid_list_scan(_adapter *padapter, struct sitesurvey_parm *pparm)
584 {
585 _irqL irqL;
586 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
587 u8 res = _TRUE;
588
589 _enter_critical_bh(&pmlmepriv->lock, &irqL);
590 res = rtw_sitesurvey_cmd(padapter, pparm);
591 _exit_critical_bh(&pmlmepriv->lock, &irqL);
592
593 return res;
594 }
595
596 #else
rtw_set_802_11_bssid_list_scan(_adapter * padapter,struct sitesurvey_parm * pparm)597 u8 rtw_set_802_11_bssid_list_scan(_adapter *padapter, struct sitesurvey_parm *pparm)
598 {
599 _irqL irqL;
600 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
601 u8 res = _TRUE;
602
603
604
605 if (padapter == NULL) {
606 res = _FALSE;
607 goto exit;
608 }
609 if (!rtw_is_hw_init_completed(padapter)) {
610 res = _FALSE;
611 goto exit;
612 }
613
614 if ((check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING) == _TRUE) ||
615 (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)) {
616 /* Scan or linking is in progress, do nothing. */
617 res = _TRUE;
618
619
620 } else {
621 if (rtw_is_scan_deny(padapter)) {
622 RTW_INFO(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter));
623 indicate_wx_scan_complete_event(padapter);
624 return _SUCCESS;
625 }
626
627 _enter_critical_bh(&pmlmepriv->lock, &irqL);
628
629 res = rtw_sitesurvey_cmd(padapter, pparm);
630
631 _exit_critical_bh(&pmlmepriv->lock, &irqL);
632 }
633 exit:
634
635
636 return res;
637 }
638 #endif
639
640 #ifdef CONFIG_RTW_ACS
rtw_set_acs_sitesurvey(_adapter * adapter)641 u8 rtw_set_acs_sitesurvey(_adapter *adapter)
642 {
643 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
644 struct sitesurvey_parm parm;
645 u8 uch;
646 u8 ch_num = 0;
647 int i;
648 BAND_TYPE band;
649 u8 (*center_chs_num)(u8) = NULL;
650 u8 (*center_chs)(u8, u8) = NULL;
651 u8 ret = _FAIL;
652
653 if (!rtw_mi_get_ch_setting_union(adapter, &uch, NULL, NULL))
654 goto exit;
655
656 _rtw_memset(&parm, 0, sizeof(struct sitesurvey_parm));
657 parm.scan_mode = SCAN_PASSIVE;
658 parm.bw = CHANNEL_WIDTH_20;
659 parm.acs = 1;
660
661 for (band = BAND_ON_2_4G; band < BAND_MAX; band++) {
662 if (band == BAND_ON_2_4G) {
663 center_chs_num = center_chs_2g_num;
664 center_chs = center_chs_2g;
665 } else
666 #if CONFIG_IEEE80211_BAND_5GHZ
667 if (band == BAND_ON_5G) {
668 center_chs_num = center_chs_5g_num;
669 center_chs = center_chs_5g;
670 } else
671 #endif
672 {
673 center_chs_num = NULL;
674 center_chs = NULL;
675 }
676
677 if (!center_chs_num || !center_chs)
678 continue;
679
680 if (rfctl->ch_sel_within_same_band) {
681 if (rtw_is_2g_ch(uch) && band != BAND_ON_2_4G)
682 continue;
683 #if CONFIG_IEEE80211_BAND_5GHZ
684 if (rtw_is_5g_ch(uch) && band != BAND_ON_5G)
685 continue;
686 #endif
687 }
688
689 ch_num = center_chs_num(CHANNEL_WIDTH_20);
690 for (i = 0; i < ch_num && parm.ch_num < RTW_CHANNEL_SCAN_AMOUNT; i++) {
691 parm.ch[parm.ch_num].hw_value = center_chs(CHANNEL_WIDTH_20, i);
692 parm.ch[parm.ch_num].flags = RTW_IEEE80211_CHAN_PASSIVE_SCAN;
693 parm.ch_num++;
694 }
695 }
696
697 ret = rtw_set_802_11_bssid_list_scan(adapter, &parm);
698
699 exit:
700 return ret;
701 }
702 #endif /* CONFIG_RTW_ACS */
703
rtw_set_802_11_authentication_mode(_adapter * padapter,NDIS_802_11_AUTHENTICATION_MODE authmode)704 u8 rtw_set_802_11_authentication_mode(_adapter *padapter, NDIS_802_11_AUTHENTICATION_MODE authmode)
705 {
706 struct security_priv *psecuritypriv = &padapter->securitypriv;
707 int res;
708 u8 ret;
709
710
711
712 psecuritypriv->ndisauthtype = authmode;
713
714
715 if (psecuritypriv->ndisauthtype > 3)
716 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
717
718 #ifdef CONFIG_WAPI_SUPPORT
719 if (psecuritypriv->ndisauthtype == 6)
720 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
721 #endif
722
723 res = rtw_set_auth(padapter, psecuritypriv);
724
725 if (res == _SUCCESS)
726 ret = _TRUE;
727 else
728 ret = _FALSE;
729
730
731 return ret;
732 }
733
rtw_set_802_11_add_wep(_adapter * padapter,NDIS_802_11_WEP * wep)734 u8 rtw_set_802_11_add_wep(_adapter *padapter, NDIS_802_11_WEP *wep)
735 {
736
737 u8 bdefaultkey;
738 u8 btransmitkey;
739 sint keyid, res;
740 struct security_priv *psecuritypriv = &(padapter->securitypriv);
741 u8 ret = _SUCCESS;
742
743
744 bdefaultkey = (wep->KeyIndex & 0x40000000) > 0 ? _FALSE : _TRUE; /* for ??? */
745 btransmitkey = (wep->KeyIndex & 0x80000000) > 0 ? _TRUE : _FALSE; /* for ??? */
746 keyid = wep->KeyIndex & 0x3fffffff;
747
748 if (keyid >= 4) {
749 ret = _FALSE;
750 goto exit;
751 }
752
753 switch (wep->KeyLength) {
754 case 5:
755 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
756 break;
757 case 13:
758 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
759 break;
760 default:
761 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
762 break;
763 }
764
765
766 _rtw_memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]), &(wep->KeyMaterial), wep->KeyLength);
767
768 psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength;
769
770 psecuritypriv->dot11PrivacyKeyIndex = keyid;
771
772
773 res = rtw_set_key(padapter, psecuritypriv, keyid, 1, _TRUE);
774
775 if (res == _FAIL)
776 ret = _FALSE;
777 exit:
778
779
780 return ret;
781
782 }
783
784 /*
785 * rtw_get_cur_max_rate -
786 * @adapter: pointer to _adapter structure
787 *
788 * Return 0 or 100Kbps
789 */
rtw_get_cur_max_rate(_adapter * adapter)790 u16 rtw_get_cur_max_rate(_adapter *adapter)
791 {
792 int j;
793 int i = 0;
794 u16 rate = 0, max_rate = 0;
795 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
796 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
797 int sta_bssrate_len = 0;
798 unsigned char sta_bssrate[NumRates];
799 struct sta_info *psta = NULL;
800 u8 short_GI = 0;
801
802 #ifdef CONFIG_MP_INCLUDED
803 if (adapter->registrypriv.mp_mode == 1) {
804 if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
805 return 0;
806 }
807 #endif
808
809 if ((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) != _TRUE)
810 && (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE))
811 return 0;
812
813 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
814 if (psta == NULL)
815 return 0;
816
817 short_GI = query_ra_short_GI(psta, rtw_get_tx_bw_mode(adapter, psta));
818
819 #ifdef CONFIG_80211N_HT
820 if (is_supported_ht(psta->wireless_mode)) {
821 max_rate = rtw_ht_mcs_rate((psta->cmn.bw_mode == CHANNEL_WIDTH_40) ? 1 : 0
822 , short_GI
823 , psta->htpriv.ht_cap.supp_mcs_set
824 );
825 }
826 #ifdef CONFIG_80211AC_VHT
827 else if (is_supported_vht(psta->wireless_mode))
828 max_rate = ((rtw_vht_mcs_to_data_rate(psta->cmn.bw_mode, short_GI, pmlmepriv->vhtpriv.vht_highest_rate) + 1) >> 1) * 10;
829 #endif /* CONFIG_80211AC_VHT */
830 else
831 #endif /* CONFIG_80211N_HT */
832 {
833 /*station mode show :station && ap support rate; softap :show ap support rate*/
834 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
835 get_rate_set(adapter, sta_bssrate, &sta_bssrate_len);/*get sta rate and length*/
836
837
838 while ((pcur_bss->SupportedRates[i] != 0) && (pcur_bss->SupportedRates[i] != 0xFF)) {
839 rate = pcur_bss->SupportedRates[i] & 0x7F;/*AP support rates*/
840 /*RTW_INFO("%s rate=%02X \n", __func__, rate);*/
841
842 /*check STA support rate or not */
843 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
844 for (j = 0; j < sta_bssrate_len; j++) {
845 /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
846 if ((rate | IEEE80211_BASIC_RATE_MASK)
847 == (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
848 if (rate > max_rate) {
849 max_rate = rate;
850 }
851 break;
852 }
853 }
854 } else {
855
856 if (rate > max_rate)
857 max_rate = rate;
858
859 }
860 i++;
861 }
862
863 max_rate = max_rate * 10 / 2;
864 }
865 return max_rate;
866 }
867
868 /*
869 * rtw_set_scan_mode -
870 * @adapter: pointer to _adapter structure
871 * @scan_mode:
872 *
873 * Return _SUCCESS or _FAIL
874 */
rtw_set_scan_mode(_adapter * adapter,RT_SCAN_TYPE scan_mode)875 int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode)
876 {
877 if (scan_mode != SCAN_ACTIVE && scan_mode != SCAN_PASSIVE)
878 return _FAIL;
879
880 adapter->mlmepriv.scan_mode = scan_mode;
881
882 return _SUCCESS;
883 }
884
885 /*
886 * rtw_set_channel_plan -
887 * @adapter: pointer to _adapter structure
888 * @channel_plan:
889 *
890 * Return _SUCCESS or _FAIL
891 */
rtw_set_channel_plan(_adapter * adapter,u8 channel_plan,u8 chplan_6g,enum rtw_regd_inr inr)892 int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan, u8 chplan_6g, enum rtw_regd_inr inr)
893 {
894 struct registry_priv *regsty = adapter_to_regsty(adapter);
895
896 if (!REGSTY_REGD_SRC_FROM_OS(regsty))
897 return rtw_set_chplan_cmd(adapter, RTW_CMDF_WAIT_ACK, channel_plan, chplan_6g, inr);
898 RTW_WARN("%s(): not applied\n", __func__);
899 return _SUCCESS;
900 }
901
902 /*
903 * rtw_set_country -
904 * @adapter: pointer to _adapter structure
905 * @country_code: string of country code
906 *
907 * Return _SUCCESS or _FAIL
908 */
rtw_set_country(_adapter * adapter,const char * country_code,enum rtw_regd_inr inr)909 int rtw_set_country(_adapter *adapter, const char *country_code, enum rtw_regd_inr inr)
910 {
911 #ifdef CONFIG_RTW_IOCTL_SET_COUNTRY
912 struct registry_priv *regsty = adapter_to_regsty(adapter);
913
914 if (!REGSTY_REGD_SRC_FROM_OS(regsty))
915 return rtw_set_country_cmd(adapter, RTW_CMDF_WAIT_ACK, country_code, inr);
916 #endif
917 RTW_WARN("%s(): not applied\n", __func__);
918 return _SUCCESS;
919 }
920
921 /*
922 * rtw_set_band -
923 * @adapter: pointer to _adapter structure
924 * @band: band to set
925 *
926 * Return _SUCCESS or _FAIL
927 */
rtw_set_band(_adapter * adapter,u8 band)928 int rtw_set_band(_adapter *adapter, u8 band)
929 {
930 if (rtw_band_valid(band)) {
931 RTW_INFO(FUNC_ADPT_FMT" band:%d\n", FUNC_ADPT_ARG(adapter), band);
932 adapter->setband = band;
933 return _SUCCESS;
934 }
935
936 RTW_PRINT(FUNC_ADPT_FMT" band:%d fail\n", FUNC_ADPT_ARG(adapter), band);
937 return _FAIL;
938 }
939