• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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