xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852bs/core/rtw_scan.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2019 - 2020 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 #include <drv_types.h>
16 
17 /*rtw_mlme.c*/
rtw_init_sitesurvey_parm(_adapter * padapter,struct sitesurvey_parm * pparm)18 void rtw_init_sitesurvey_parm(_adapter *padapter, struct sitesurvey_parm *pparm)
19 {
20 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
21 
22 	_rtw_memset(pparm, 0, sizeof(struct sitesurvey_parm));
23 	pparm->scan_mode = pmlmepriv->scan_mode;
24 }
25 
26 #ifdef CONFIG_SET_SCAN_DENY_TIMER
rtw_is_scan_deny(_adapter * adapter)27 inline bool rtw_is_scan_deny(_adapter *adapter)
28 {
29 	struct mlme_priv *mlmepriv = &adapter->mlmepriv;
30 	return (ATOMIC_READ(&mlmepriv->set_scan_deny) != 0) ? _TRUE : _FALSE;
31 }
rtw_clear_scan_deny(_adapter * adapter)32 inline void rtw_clear_scan_deny(_adapter *adapter)
33 {
34 	struct mlme_priv *mlmepriv = &adapter->mlmepriv;
35 	ATOMIC_SET(&mlmepriv->set_scan_deny, 0);
36 	if (0)
37 		RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
38 }
39 
rtw_set_scan_deny_timer_hdl(void * ctx)40 void rtw_set_scan_deny_timer_hdl(void *ctx)
41 {
42 	_adapter *adapter = (_adapter *)ctx;
43 
44 	rtw_clear_scan_deny(adapter);
45 }
rtw_set_scan_deny(_adapter * adapter,u32 ms)46 void rtw_set_scan_deny(_adapter *adapter, u32 ms)
47 {
48 	struct mlme_priv *mlmepriv = &adapter->mlmepriv;
49 	if (0)
50 		RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
51 	ATOMIC_SET(&mlmepriv->set_scan_deny, 1);
52 	_set_timer(&mlmepriv->set_scan_deny_timer, ms);
53 }
54 #endif
55 
rtw_drv_scan_by_self(_adapter * padapter,u8 reason)56 void rtw_drv_scan_by_self(_adapter *padapter, u8 reason)
57 {
58 	struct sitesurvey_parm parm;
59 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
60 	int i;
61 #if 1
62 	u8 ssc_chk;
63 
64 	ssc_chk = rtw_sitesurvey_condition_check(padapter, _FALSE);
65 	if( ssc_chk == SS_DENY_BUSY_TRAFFIC) {
66 		#ifdef CONFIG_LAYER2_ROAMING
67 		if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE) && pmlmepriv->need_to_roam == _TRUE) {
68 			RTW_INFO(FUNC_ADPT_FMT" need to roam, don't care BusyTraffic\n", FUNC_ADPT_ARG(padapter));
69 		 } else
70 		#endif
71 		{
72 			RTW_INFO(FUNC_ADPT_FMT" exit BusyTraffic\n", FUNC_ADPT_ARG(padapter));
73 			goto exit;
74 		}
75 	} else if (ssc_chk != SS_ALLOW) {
76 		goto exit;
77 	}
78 
79 	if (!rtw_is_adapter_up(padapter))
80 		goto exit;
81 #else
82 	if (rtw_is_scan_deny(padapter))
83 		goto exit;
84 
85 	if (!rtw_is_adapter_up(padapter))
86 		goto exit;
87 
88 	if (rtw_mi_busy_traffic_check(padapter)) {
89 #ifdef CONFIG_LAYER2_ROAMING
90 		if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE) && pmlmepriv->need_to_roam == _TRUE) {
91 			RTW_INFO("need to roam, don't care BusyTraffic\n");
92 		} else
93 #endif
94 		{
95 			RTW_INFO(FUNC_ADPT_FMT" exit BusyTraffic\n", FUNC_ADPT_ARG(padapter));
96 			goto exit;
97 		}
98 	}
99 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) && check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
100 		RTW_INFO(FUNC_ADPT_FMT" WIFI_AP_STATE && WIFI_UNDER_WPS\n", FUNC_ADPT_ARG(padapter));
101 		goto exit;
102 	}
103 	if (check_fwstate(pmlmepriv, (WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING)) == _TRUE) {
104 		RTW_INFO(FUNC_ADPT_FMT" WIFI_UNDER_SURVEY|WIFI_UNDER_LINKING\n", FUNC_ADPT_ARG(padapter));
105 		goto exit;
106 	}
107 
108 #ifdef CONFIG_CONCURRENT_MODE
109 	if (rtw_mi_buddy_check_fwstate(padapter, (WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING | WIFI_UNDER_WPS))) {
110 		RTW_INFO(FUNC_ADPT_FMT", but buddy_intf is under scanning or linking or wps_phase\n", FUNC_ADPT_ARG(padapter));
111 		goto exit;
112 	}
113 #endif
114 #endif
115 
116 	RTW_INFO(FUNC_ADPT_FMT" reason:0x%02x\n", FUNC_ADPT_ARG(padapter), reason);
117 
118 	/* only for 20/40 BSS */
119 	if (reason == RTW_AUTO_SCAN_REASON_2040_BSS) {
120 		rtw_init_sitesurvey_parm(padapter, &parm);
121 		for (i=0;i<14;i++) {
122 			parm.ch[i].hw_value = i + 1;
123 			parm.ch[i].flags = RTW_IEEE80211_CHAN_PASSIVE_SCAN;
124 		}
125 		parm.ch_num = 14;
126 		rtw_sitesurvey_cmd(padapter, &parm);
127 		goto exit;
128 	}
129 
130 #ifdef CONFIG_RTW_MBO
131 #if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K)
132 	if ((reason == RTW_AUTO_SCAN_REASON_ROAM)
133 		&& (rtw_roam_nb_scan_list_set(padapter, &parm)))
134 		goto exit;
135 #endif
136 #endif
137 
138 	rtw_sitesurvey_cmd(padapter, NULL);
139 exit:
140 	return;
141 }
142 
143 #ifdef CONFIG_RTW_ACS
rtw_set_acs_sitesurvey(_adapter * adapter)144 u8 rtw_set_acs_sitesurvey(_adapter *adapter)
145 {
146 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
147 	struct sitesurvey_parm parm;
148 	u8 uch;
149 	u8 ch_num = 0;
150 	int i;
151 	enum band_type band;
152 	u8 (*center_chs_num)(u8) = NULL;
153 	u8 (*center_chs)(u8, u8) = NULL;
154 	u8 ret = _FAIL;
155 
156 	if (!rtw_mi_get_ch_setting_union(adapter, &uch, NULL, NULL))
157 		goto exit;
158 
159 	_rtw_memset(&parm, 0, sizeof(struct sitesurvey_parm));
160 	parm.scan_mode = RTW_PHL_SCAN_PASSIVE;
161 	parm.bw = CHANNEL_WIDTH_20;
162 	parm.acs = 1;
163 
164 	for (band = BAND_ON_24G; band < BAND_MAX; band++) {
165 		if (band == BAND_ON_24G) {
166 			center_chs_num = center_chs_2g_num;
167 			center_chs = center_chs_2g;
168 		} else
169 		#if CONFIG_IEEE80211_BAND_5GHZ
170 		if (band == BAND_ON_5G) {
171 			center_chs_num = center_chs_5g_num;
172 			center_chs = center_chs_5g;
173 		} else
174 		#endif
175 		{
176 			center_chs_num = NULL;
177 			center_chs = NULL;
178 		}
179 
180 		if (!center_chs_num || !center_chs)
181 			continue;
182 
183 		if (rfctl->ch_sel_within_same_band) {
184 			if (rtw_is_2g_ch(uch) && band != BAND_ON_24G)
185 				continue;
186 			#if CONFIG_IEEE80211_BAND_5GHZ
187 			if (rtw_is_5g_ch(uch) && band != BAND_ON_5G)
188 				continue;
189 			#endif
190 		}
191 
192 		ch_num = center_chs_num(CHANNEL_WIDTH_20);
193 		for (i = 0; i < ch_num && parm.ch_num < RTW_CHANNEL_SCAN_AMOUNT; i++) {
194 			parm.ch[parm.ch_num].hw_value = center_chs(CHANNEL_WIDTH_20, i);
195 			parm.ch[parm.ch_num].flags = RTW_IEEE80211_CHAN_PASSIVE_SCAN;
196 			parm.ch_num++;
197 		}
198 	}
199 
200 	ret = rtw_sitesurvey_cmd(adapter, &parm);
201 
202 exit:
203 	return ret;
204 }
205 #endif /* CONFIG_RTW_ACS */
206 
_rtw_wait_scan_done(_adapter * adapter,u32 timeout_ms)207 static u32 _rtw_wait_scan_done(_adapter *adapter, u32 timeout_ms)
208 {
209 	systime start;
210 	u32 pass_ms;
211 	struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
212 	struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
213 	u8 abort_timeout = false;
214 
215 	start = rtw_get_current_time();
216 
217 	while ((rtw_cfg80211_get_is_roch(adapter) == _TRUE || check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY))
218 	       && rtw_get_passing_time_ms(start) <= timeout_ms) {
219 
220 		if (RTW_CANNOT_RUN(adapter_to_dvobj(adapter)))
221 			break;
222 
223 		RTW_INFO(FUNC_NDEV_FMT"fw_state=WIFI_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev));
224 		rtw_msleep_os(20);
225 		abort_timeout = true;
226 	}
227 
228 	if (_TRUE == abort_timeout && check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)) {
229 		if (!RTW_CANNOT_RUN(adapter_to_dvobj(adapter)))
230 			RTW_ERR(FUNC_NDEV_FMT"waiting for scan_abort time out!\n",
231 					FUNC_NDEV_ARG(adapter->pnetdev));
232 		pmlmeext->scan_abort_to = _TRUE;
233 		#ifdef CONFIG_PLATFORM_MSTAR
234 		/*_clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY);*/
235 		/*set_survey_timer(pmlmeext, 0);*/
236 		mlme_set_scan_to_timer(pmlmepriv, 50);
237 		#endif
238 		rtw_indicate_scan_done(adapter, _TRUE);
239 	}
240 
241 	pmlmeext->scan_abort = _FALSE;
242 	RTW_INFO(FUNC_ADPT_FMT "- %s....scan_abort:%d\n",
243 		FUNC_ADPT_ARG(adapter), __func__, pmlmeext->scan_abort);
244 	pass_ms = rtw_get_passing_time_ms(start);
245 
246 	RTW_INFO("%s scan timeout value:%d ms, total take:%d ms\n",
247 				__func__, timeout_ms, pass_ms);
248 	return pass_ms;
249 }
250 
251 /*
252 * timeout_ms > 0:rtw_scan_abort_timeout , = 0:rtw_scan_wait_completed
253 */
rtw_scan_abort(_adapter * adapter,u32 timeout_ms)254 u32 rtw_scan_abort(_adapter *adapter, u32 timeout_ms)
255 {
256 	struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
257 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
258 	enum rtw_phl_status psts = RTW_PHL_STATUS_FAILURE;
259 	u32 pass_ms = 0;
260 
261 	if (rtw_cfg80211_get_is_roch(adapter) == _TRUE || check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)) {
262 		pmlmeext->scan_abort = _TRUE;
263 		RTW_INFO(FUNC_ADPT_FMT "- %s....scan_abort:%d\n",
264 			FUNC_ADPT_ARG(adapter), __func__, pmlmeext->scan_abort);
265 		rtw_sctx_init(&pmlmeext->sitesurvey_res.sctx, timeout_ms);
266 
267 		#ifdef CONFIG_CMD_SCAN
268 		if (pmlmeext->sitesurvey_res.scan_param)
269 			psts = rtw_phl_cmd_scan_cancel(adapter_to_dvobj(adapter)->phl,
270 					pmlmeext->sitesurvey_res.scan_param);
271 		#else
272 		psts = rtw_phl_scan_cancel(adapter_to_dvobj(adapter)->phl);
273 		#endif
274 
275 		if (psts == RTW_PHL_STATUS_SUCCESS)
276 			rtw_sctx_wait(&pmlmeext->sitesurvey_res.sctx, __func__);
277 		pass_ms = _rtw_wait_scan_done(adapter, timeout_ms);
278 	}
279 	return pass_ms;
280 }
281 
rtw_scan_abort_no_wait(_adapter * adapter)282 void rtw_scan_abort_no_wait(_adapter *adapter)
283 {
284 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
285 
286 	#ifdef CONFIG_CMD_SCAN
287 	if (pmlmeext->sitesurvey_res.scan_param)
288 		rtw_phl_cmd_scan_cancel(adapter_to_dvobj(adapter)->phl,
289 			pmlmeext->sitesurvey_res.scan_param);
290 	#else
291 	rtw_phl_scan_cancel(adapter_to_dvobj(adapter)->phl);
292 	#endif
293 }
294 
295 /*
296 * rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey
297 * @adapter: pointer to _adapter structure
298 */
rtw_scan_timeout_handler(void * ctx)299 void rtw_scan_timeout_handler(void *ctx)
300 {
301 	_adapter *adapter = (_adapter *)ctx;
302 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
303 	RTW_INFO(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
304 
305 	rtw_scan_abort_no_wait(adapter);
306 #if 0
307 	_rtw_spinlock_bh(&pmlmepriv->lock);
308 	_clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY);
309 	_rtw_spinunlock_bh(&pmlmepriv->lock);
310 
311 	#ifdef CONFIG_IOCTL_CFG80211
312 	rtw_cfg80211_surveydone_event_callback(adapter);
313 	#endif /* CONFIG_IOCTL_CFG80211 */
314 	rtw_indicate_scan_done(adapter, _TRUE);
315 #endif
316 }
317 
_rtw_scan_abort_check(_adapter * adapter,const char * caller)318 static inline bool _rtw_scan_abort_check(_adapter *adapter, const char *caller)
319 {
320 	struct	mlme_priv *pmlmepriv = &adapter->mlmepriv;
321 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
322 	struct submit_ctx *sctx = &pmlmeext->sitesurvey_res.sctx;
323 
324 	RTW_INFO(FUNC_ADPT_FMT "- %s....scan_abort:%d\n",
325 			FUNC_ADPT_ARG(adapter), __func__, pmlmeext->scan_abort);
326 
327 	if (pmlmeext->scan_abort == _FALSE)
328 		return _FALSE;
329 
330 	if (pmlmeext->scan_abort_to) {
331 		RTW_ERR("%s scan abort timeout\n", caller);
332 		rtw_warn_on(1);
333 	}
334 	_cancel_timer_ex(&pmlmepriv->scan_to_timer);
335 	pmlmeext->scan_abort = _FALSE;
336 	pmlmeext->scan_abort_to = _FALSE;
337 	if (sctx) {
338 		RTW_INFO("%s scan abort .....(%d ms)\n", caller, rtw_get_passing_time_ms(sctx->submit_time));
339 		rtw_sctx_done(&sctx);
340 	}
341 	return _TRUE;
342 }
alloc_network(struct mlme_priv * pmlmepriv)343 static struct wlan_network *alloc_network(struct	mlme_priv *pmlmepriv) /* (_queue	*free_queue) */
344 {
345 	struct	wlan_network	*pnetwork;
346 	pnetwork = _rtw_alloc_network(pmlmepriv);
347 	return pnetwork;
348 }
349 
update_current_network(_adapter * adapter,WLAN_BSSID_EX * pnetwork)350 static void update_current_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork)
351 {
352 	struct	mlme_priv *pmlmepriv = &(adapter->mlmepriv);
353 
354 	if ((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork))) {
355 
356 		/* if(pmlmepriv->cur_network.network.IELength<= pnetwork->IELength) */
357 		{
358 			rtw_update_network(&(pmlmepriv->cur_network.network), pnetwork, adapter, _TRUE);
359 			rtw_update_protection(adapter, (pmlmepriv->cur_network.network.IEs) + sizeof(NDIS_802_11_FIXED_IEs),
360 				      pmlmepriv->cur_network.network.IELength);
361 		}
362 	}
363 }
364 
365 /*Caller must hold pmlmepriv->lock first.*/
update_scanned_network(_adapter * adapter,WLAN_BSSID_EX * target)366 static bool update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target)
367 {
368 	_list	*plist, *phead;
369 	u32	bssid_ex_sz;
370 	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
371 #ifdef CONFIG_P2P
372 	struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
373 #endif /* CONFIG_P2P */
374 	_queue	*queue	= &(pmlmepriv->scanned_queue);
375 	struct wlan_network	*pnetwork = NULL;
376 	struct wlan_network	*choice = NULL;
377 	int target_find = 0;
378 	bool update_ie = _FALSE;
379 
380 	_rtw_spinlock_bh(&queue->lock);
381 	phead = get_list_head(queue);
382 	plist = get_next(phead);
383 
384 #if 0
385 	RTW_INFO("%s => ssid:%s , rssi:%ld , ss:%d\n",
386 		__func__, target->Ssid.Ssid, target->PhyInfo.rssi, target->PhyInfo.SignalStrength);
387 #endif
388 
389 	while (1) {
390 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
391 			break;
392 
393 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
394 
395 #ifdef CONFIG_P2P
396 		if (_rtw_memcmp(pnetwork->network.MacAddress, target->MacAddress, ETH_ALEN) &&
397 		    _rtw_memcmp(pnetwork->network.Ssid.Ssid, "DIRECT-", 7) &&
398 		    rtw_get_p2p_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_,
399 				   pnetwork->network.IELength - _FIXED_IE_LENGTH_,
400 				   NULL, NULL)) {
401 			target_find = 1;
402 			break;
403 		}
404 #endif
405 
406 		if (is_same_network(&(pnetwork->network), target)) {
407 			target_find = 1;
408 			break;
409 		}
410 
411 		if (rtw_roam_flags(adapter)) {
412 			/* TODO: don't  select netowrk in the same ess as choice if it's new enough*/
413 		}
414 		if (pnetwork->fixed) {
415 			plist = get_next(plist);
416 			continue;
417 		}
418 
419 #ifdef CONFIG_RSSI_PRIORITY
420 		if ((choice == NULL) || (pnetwork->network.PhyInfo.SignalStrength < choice->network.PhyInfo.SignalStrength))
421 			#ifdef CONFIG_RTW_MESH
422 			if (!MLME_IS_MESH(adapter) || !MLME_IS_ASOC(adapter)
423 				|| !rtw_bss_is_same_mbss(&pmlmepriv->cur_network.network, &pnetwork->network))
424 			#endif
425 				choice = pnetwork;
426 #else
427 		if (choice == NULL || rtw_time_after(choice->last_scanned, pnetwork->last_scanned))
428 			#ifdef CONFIG_RTW_MESH
429 			if (!MLME_IS_MESH(adapter) || !MLME_IS_ASOC(adapter)
430 				|| !rtw_bss_is_same_mbss(&pmlmepriv->cur_network.network, &pnetwork->network))
431 			#endif
432 				choice = pnetwork;
433 #endif
434 		plist = get_next(plist);
435 
436 	}
437 
438 
439 	/* If we didn't find a match, then get a new network slot to initialize
440 	 * with this beacon's information */
441 	/* if (rtw_end_of_queue_search(phead,plist)== _TRUE) { */
442 	if (!target_find) {
443 		if (_rtw_queue_empty(&(pmlmepriv->free_bss_pool)) == _TRUE) {
444 			/* If there are no more slots, expire the choice */
445 			/* list_del_init(&choice->list); */
446 			pnetwork = choice;
447 			if (pnetwork == NULL)
448 				goto unlock_scan_queue;
449 
450 #ifdef CONFIG_RSSI_PRIORITY
451 			RTW_DBG("%s => ssid:%s ,bssid:"MAC_FMT"  will be deleted from scanned_queue (rssi:%d , ss:%d)\n",
452 			__func__, pnetwork->network.Ssid.Ssid, MAC_ARG(pnetwork->network.MacAddress),
453 			pnetwork->network.PhyInfo.rssi, pnetwork->network.PhyInfo.SignalStrength);
454 #else
455 			RTW_DBG("%s => ssid:%s ,bssid:"MAC_FMT" will be deleted from scanned_queue\n",
456 			__func__, pnetwork->network.Ssid.Ssid, MAC_ARG(pnetwork->network.MacAddress));
457 #endif
458 
459 			_rtw_memcpy(&(pnetwork->network), target,  get_WLAN_BSSID_EX_sz(target));
460 			/* pnetwork->last_scanned = rtw_get_current_time(); */
461 			/* variable initialize */
462 			pnetwork->fixed = _FALSE;
463 			pnetwork->last_scanned = rtw_get_current_time();
464 			#if defined(CONFIG_RTW_MESH) && CONFIG_RTW_MESH_ACNODE_PREVENT
465 			pnetwork->acnode_stime = 0;
466 			pnetwork->acnode_notify_etime = 0;
467 			#endif
468 
469 			pnetwork->network_type = 0;
470 			pnetwork->aid = 0;
471 			pnetwork->join_res = 0;
472 
473 			/* bss info not receving from the right channel */
474 			if (pnetwork->network.PhyInfo.SignalQuality == 101)
475 				pnetwork->network.PhyInfo.SignalQuality = 0;
476 		} else {
477 			/* Otherwise just pull from the free list */
478 
479 			pnetwork = alloc_network(pmlmepriv); /* will update scan_time */
480 			if (pnetwork == NULL)
481 				goto unlock_scan_queue;
482 
483 			bssid_ex_sz = get_WLAN_BSSID_EX_sz(target);
484 			target->Length = bssid_ex_sz;
485 
486 			_rtw_memcpy(&(pnetwork->network), target, bssid_ex_sz);
487 
488 			pnetwork->last_scanned = rtw_get_current_time();
489 
490 			/* bss info not receving from the right channel */
491 			if (pnetwork->network.PhyInfo.SignalQuality == 101)
492 				pnetwork->network.PhyInfo.SignalQuality = 0;
493 
494 			rtw_list_insert_tail(&(pnetwork->list), &(queue->queue));
495 
496 		}
497 	} else {
498 		/* we have an entry and we are going to update it. But this entry may
499 		 * be already expired. In this case we do the same as we found a new
500 		 * net and call the new_net handler
501 		 */
502 		#if defined(CONFIG_RTW_MESH) && CONFIG_RTW_MESH_ACNODE_PREVENT
503 		systime last_scanned = pnetwork->last_scanned;
504 		#endif
505 
506 		pnetwork->last_scanned = rtw_get_current_time();
507 
508 		/* target.Reserved[0]==BSS_TYPE_BCN, means that scanned network is a bcn frame. */
509 		if ((pnetwork->network.IELength > target->IELength) && (target->Reserved[0] == BSS_TYPE_BCN))
510 			update_ie = _FALSE;
511 
512 		if (MLME_IS_MESH(adapter)
513 			/* probe resp(3) > beacon(1) > probe req(2) */
514 			|| (target->Reserved[0] != BSS_TYPE_PROB_REQ
515 				&& target->Reserved[0] >= pnetwork->network.Reserved[0])
516 		)
517 			update_ie = _TRUE;
518 		else
519 			update_ie = _FALSE;
520 
521 		#if defined(CONFIG_RTW_MESH) && CONFIG_RTW_MESH_ACNODE_PREVENT
522 		if (!MLME_IS_MESH(adapter) || !MLME_IS_ASOC(adapter)
523 			|| pnetwork->network.Configuration.DSConfig != target->Configuration.DSConfig
524 			|| rtw_get_passing_time_ms(last_scanned) > adapter->mesh_cfg.peer_sel_policy.scanr_exp_ms
525 			|| !rtw_bss_is_same_mbss(&pnetwork->network, target)
526 		) {
527 			pnetwork->acnode_stime = 0;
528 			pnetwork->acnode_notify_etime = 0;
529 		}
530 		#endif
531 		rtw_update_network(&(pnetwork->network), target, adapter, update_ie);
532 	}
533 
534 	#if defined(CONFIG_RTW_MESH) && CONFIG_RTW_MESH_ACNODE_PREVENT
535 	if (MLME_IS_MESH(adapter) && MLME_IS_ASOC(adapter))
536 		rtw_mesh_update_scanned_acnode_status(adapter, pnetwork);
537 	#endif
538 
539 unlock_scan_queue:
540 	_rtw_spinunlock_bh(&queue->lock);
541 
542 #ifdef CONFIG_RTW_MESH
543 	if (pnetwork && MLME_IS_MESH(adapter)
544 		&& check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
545 		&& !check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)
546 	)
547 		rtw_chk_candidate_peer_notify(adapter, pnetwork);
548 #endif
549 
550 	return update_ie;
551 }
552 
add_network(_adapter * adapter,WLAN_BSSID_EX * pnetwork)553 static void add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork)
554 {
555 	bool update_ie;
556 	/* _queue *queue = &(pmlmepriv->scanned_queue); */
557 	/* _rtw_spinlock_bh(&queue->lock); */
558 
559 #if defined(CONFIG_P2P) && defined(CONFIG_P2P_REMOVE_GROUP_INFO)
560 	if (adapter->registrypriv.wifi_spec == 0)
561 		rtw_bss_ex_del_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO);
562 #endif
563 
564 #ifdef CONFIG_IGNORE_GO_AND_LOW_RSSI_IN_SCAN_LIST
565 	if (adapter->registrypriv.ignore_go_in_scan) {
566 		if(rtw_chk_p2p_wildcard_ssid(pnetwork) == _SUCCESS ||
567 			rtw_chk_p2p_ie(pnetwork) == _SUCCESS)
568 			return;
569 	}
570 	/*100 was follow n & ac IC setting SignalStrength rang was 0~100*/
571 	if(adapter->registrypriv->ignore_low_rssi_in_scan != 0xff &&
572 		pnetwork->PhyInfo.rssi < (adapter->registrypriv->ignore_low_rssi_in_scan - 100))
573 		return;
574 #endif /*CONFIG_IGNORE_GO_AND_LOW_RSSI_IN_SCAN_LIST*/
575 
576 	if (!rtw_hw_chk_wl_func(adapter_to_dvobj(adapter), WL_FUNC_MIRACAST))
577 		rtw_bss_ex_del_wfd_ie(pnetwork);
578 
579 	/* Wi-Fi driver will update the current network if the scan result of the connected AP be updated by scan. */
580 	update_ie = update_scanned_network(adapter, pnetwork);
581 
582 	if (update_ie)
583 		update_current_network(adapter, pnetwork);
584 
585 	/* _rtw_spinunlock_bh(&queue->lock); */
586 
587 }
588 
589 #ifdef CONFIG_STA_MULTIPLE_BSSID
rtw_gen_new_bssid(const u8 * bssid,u8 max_bssid_ind,u8 mbssid_index,u8 * new_bssid)590 static inline void rtw_gen_new_bssid(const u8 *bssid, u8 max_bssid_ind,
591 					  u8 mbssid_index, u8 *new_bssid)
592 {
593 	u8 i = 0;
594 	u8 max_num = 1;
595 	u8 B;
596 	u8 new_a5;
597 
598 	for (i = 0; i < max_bssid_ind; i++)
599 		max_num = max_num * 2;
600 	/*RTW_INFO("%s, max_num=%d\n", __func__, max_num);*/
601 	/*RTW_INFO("%s, %02x,%02x,%02x,%02x,%02x,%02x \n", __func__, bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);*/
602 
603 	B = bssid[5] % max_num;
604 
605 	new_a5 = bssid[5] - B + ((B + mbssid_index) % max_num);
606 
607 	new_bssid[0] = bssid[0];
608 	new_bssid[1] = bssid[1];
609 	new_bssid[2] = bssid[2];
610 	new_bssid[3] = bssid[3];
611 	new_bssid[4] = bssid[4];
612 	new_bssid[5] = new_a5;
613 
614 	/*RTW_INFO("%s, %02x,%02x,%02x,%02x,%02x,%02x \n", __func__, new_bssid[0], new_bssid[1], new_bssid[2], new_bssid[3], new_bssid[4], new_bssid[5]);*/
615 }
616 
add_mbssid_network(_adapter * padapter,WLAN_BSSID_EX * ref_bss)617 void add_mbssid_network(_adapter *padapter, WLAN_BSSID_EX *ref_bss)
618 {
619 	WLAN_BSSID_EX *pbss;
620 	u32 sub_ies_len;
621 	u8 *mbssid_ie_ptr = NULL;
622 	PNDIS_802_11_VARIABLE_IEs pIE, sub_pie;
623 	u8 max_bssid_indicator;
624 	int i,j;
625 	u8* mbssid_ie;
626 	sint mbssid_len;
627 	u8 mbssid_index;
628 	u8 copy_ie_offset;
629 	u32 copy_ie_len = 0;
630 
631 	mbssid_ie = rtw_get_ie(ref_bss->IEs + _BEACON_IE_OFFSET_
632 		                              , WLAN_EID_MULTIPLE_BSSID
633 		                              , &mbssid_len
634 		                              , (ref_bss->IELength- _BEACON_IE_OFFSET_));
635 	if (!mbssid_ie)
636 		return;
637 #if 0
638 	else
639 		RTW_PRINT_DUMP("mbssid_ie: ", (const u8 *)mbssid_ie, mbssid_len);
640 #endif
641 
642 	mbssid_ie_ptr = mbssid_ie;
643 	max_bssid_indicator = GET_MBSSID_MAX_BSSID_INDOCATOR(mbssid_ie_ptr);
644 	/*RTW_INFO("%s, max_bssid_indicator=%d\n", __func__, max_bssid_indicator);*/
645 	mbssid_ie_ptr = mbssid_ie_ptr + MBSSID_MAX_BSSID_INDICATOR_OFFSET;
646 
647 	for (i = 0; i + 1 < mbssid_len;) {
648 		pIE = (PNDIS_802_11_VARIABLE_IEs)(mbssid_ie_ptr + i);
649 
650 		switch (pIE->ElementID) {
651 		case MBSSID_NONTRANSMITTED_BSSID_PROFILE_ID:
652 			sub_ies_len = pIE->Length;
653 			pbss = (WLAN_BSSID_EX *)rtw_zmalloc(sizeof(WLAN_BSSID_EX));
654 			if (pbss) {
655 				_rtw_memcpy(pbss, ref_bss, sizeof(WLAN_BSSID_EX));
656 				_rtw_memset(pbss->IEs, 0, MAX_IE_SZ);
657 				copy_ie_len =  _TIMESTAMP_ + _BEACON_ITERVAL_;
658 				_rtw_memcpy(pbss->IEs, ref_bss->IEs, copy_ie_len);
659 			} else {
660 				return;
661 			}
662 
663 			for (j = 0; j + 1 < sub_ies_len;) {
664 				sub_pie = (PNDIS_802_11_VARIABLE_IEs)(pIE->data + j);
665 				switch (sub_pie->ElementID) {
666 				case WLAN_EID_NON_TX_BSSID_CAP:
667 					/*RTW_INFO("%s, sub_pie->Length=%d\n", __func__, sub_pie->Length);*/
668 					/*RTW_PRINT_DUMP("WLAN_EID_NON_TX_BSSID_CAP: ", (const u8 *)sub_pie->data, sub_pie->Length);*/
669 					copy_ie_offset =  _TIMESTAMP_ + _BEACON_ITERVAL_;
670 					_rtw_memcpy(pbss->IEs + copy_ie_offset, sub_pie->data, sub_pie->Length);
671 					break;
672 				case WLAN_EID_SSID:
673 					/*RTW_PRINT_DUMP("WLAN_EID_SSID: ", (const u8 *)sub_pie->data, sub_pie->Length);*/
674 					/*RTW_INFO("%s, ref_bss->IELength=%d\n", __func__, ref_bss->IELength);*/
675 					/*RTW_PRINT_DUMP("A ref_bss->IEs: ", (const u8 *)ref_bss->IEs, ref_bss->IELength);*/
676 					copy_ie_offset =  _TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_;
677 					copy_ie_len =  WLAN_IE_ID_LEN + WLAN_IE_LEN_LEN;
678 					_rtw_memcpy(pbss->IEs + copy_ie_offset, sub_pie, copy_ie_len);
679 
680 					copy_ie_offset = copy_ie_offset + WLAN_IE_ID_LEN + WLAN_IE_LEN_LEN;
681 					_rtw_memcpy(pbss->IEs + copy_ie_offset, sub_pie->data, sub_pie->Length);
682 					_rtw_memcpy(pbss->IEs + copy_ie_offset + sub_pie->Length
683 						                , ref_bss->IEs + copy_ie_offset + ref_bss->Ssid.SsidLength
684 						                , ref_bss->IELength - (copy_ie_offset + ref_bss->Ssid.SsidLength));
685 
686 					pbss->IELength = ref_bss->IELength + (sub_pie->Length - ref_bss->Ssid.SsidLength);
687 					/*RTW_INFO("%s, ref_bss->Ssid.SsidLength=%d\n", __func__, ref_bss->Ssid.SsidLength);*/
688 					/*RTW_INFO("%s, sub_pie->Length=%d\n", __func__, sub_pie->Length);*/
689 					/*RTW_INFO("%s, pbss->IELength=%d\n", __func__, pbss->IELength);*/
690 					/*RTW_PRINT_DUMP("B pbss->IEs: ", (const u8 *)pbss->IEs, pbss->IELength);*/
691 
692 					_rtw_memset(pbss->Ssid.Ssid, 0, pbss->Ssid.SsidLength);
693 					_rtw_memcpy(pbss->Ssid.Ssid, sub_pie->data, sub_pie->Length);
694 					pbss->Ssid.SsidLength = sub_pie->Length;
695 					break;
696 				case WLAN_EID_MULTI_BSSID_IDX:
697 					/*RTW_INFO("%s, sub_pie->Length=%d\n", __func__, sub_pie->Length);*/
698 					/*RTW_PRINT_DUMP("WLAN_EID_MULTI_BSSID_IDX: ", (const u8 *)sub_pie->data, sub_pie->Length);*/
699 					_rtw_memcpy(&mbssid_index, sub_pie->data, sub_pie->Length);
700 					/*RTW_INFO("%s,mbssid_index=%d\n", __func__, mbssid_index);*/
701 					rtw_gen_new_bssid(ref_bss->MacAddress, max_bssid_indicator
702 						                          , mbssid_index, pbss->MacAddress);
703 					pbss->mbssid_index = mbssid_index;
704 					break;
705 				default:
706 					break;
707 				}
708 
709 				j += (sub_pie->Length + WLAN_IE_ID_LEN + WLAN_IE_LEN_LEN);
710 				/*RTW_INFO("%s, j=%d\n", __func__, j);*/
711 			}
712 			pbss->is_mbssid = _TRUE;
713 			add_network(padapter, pbss);
714 			rtw_mfree((u8 *)pbss, sizeof(WLAN_BSSID_EX));
715 			break;
716 		case MBSSID_VENDOR_SPECIFIC_ID:
717 			break;
718 		default:
719 			break;
720 		}
721 
722 		i += (pIE->Length + WLAN_IE_ID_LEN + WLAN_IE_LEN_LEN);
723 		/*RTW_INFO("%s, i=%d\n", __func__, i);*/
724 	}
725 }
726 #endif
727 
rtw_survey_event_callback(_adapter * adapter,u8 * pbuf)728 void rtw_survey_event_callback(_adapter	*adapter, u8 *pbuf)
729 {
730 	u32 len;
731 	u8 val8;
732 	WLAN_BSSID_EX *pnetwork;
733 	struct	mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
734 
735 	pnetwork = (WLAN_BSSID_EX *)pbuf;
736 
737 	len = get_WLAN_BSSID_EX_sz(pnetwork);
738 	if (len > (sizeof(WLAN_BSSID_EX))) {
739 		return;
740 	}
741 
742 #ifdef CONFIG_RTW_80211K
743     	val8 = 0;
744 	rtw_hal_get_hwreg(adapter, HW_VAR_FREECNT, &val8);
745 
746 	/* use TSF if no free run counter */
747 	if (val8==0)
748 		pnetwork->PhyInfo.free_cnt = (u32)rtw_hal_get_tsftr_by_port(
749 			adapter, rtw_hal_get_port(adapter));
750 #endif
751 
752 	if (pnetwork->InfrastructureMode == Ndis802_11Infrastructure) {
753 		if (MLME_IS_SCAN(adapter)) {
754 			adapter->mlmeextpriv.sitesurvey_res.activate_ch_cnt
755 				+= rtw_process_beacon_hint(adapter, pnetwork);
756 		}
757 	}
758 
759 	_rtw_spinlock_bh(&pmlmepriv->lock);
760 
761 	/* update IBSS_network 's timestamp */
762 	if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) {
763 		if (_rtw_memcmp(&(pmlmepriv->cur_network.network.MacAddress), pnetwork->MacAddress, ETH_ALEN)) {
764 			struct wlan_network *ibss_wlan = NULL;
765 
766 			_rtw_memcpy(pmlmepriv->cur_network.network.IEs, pnetwork->IEs, 8);
767 			_rtw_spinlock_bh(&(pmlmepriv->scanned_queue.lock));
768 			ibss_wlan = _rtw_find_network(&pmlmepriv->scanned_queue,  pnetwork->MacAddress);
769 			if (ibss_wlan) {
770 				_rtw_memcpy(ibss_wlan->network.IEs , pnetwork->IEs, 8);
771 				_rtw_spinunlock_bh(&(pmlmepriv->scanned_queue.lock));
772 				goto exit;
773 			}
774 			_rtw_spinunlock_bh(&(pmlmepriv->scanned_queue.lock));
775 		}
776 	}
777 
778 	/* lock pmlmepriv->lock when you accessing network_q */
779 	if ((check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)) == _FALSE) {
780 		if (pnetwork->Ssid.Ssid[0] == 0)
781 			pnetwork->Ssid.SsidLength = 0;
782 		add_network(adapter, pnetwork);
783 #ifdef CONFIG_STA_MULTIPLE_BSSID
784 		add_mbssid_network(adapter, pnetwork);
785 #endif
786 	}
787 
788 exit:
789 	_rtw_spinunlock_bh(&pmlmepriv->lock);
790 
791 
792 	return;
793 }
794 
rtw_surveydone_event_callback(_adapter * adapter,u8 * pbuf)795 void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf)
796 {
797 	struct surveydone_event *parm = (struct surveydone_event *)pbuf;
798 	struct	mlme_priv	*pmlmepriv = &adapter->mlmepriv;
799 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
800 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
801 
802 	_rtw_spinlock_bh(&pmlmepriv->lock);
803 	if (pmlmepriv->wps_probe_req_ie) {
804 		u32 free_len = pmlmepriv->wps_probe_req_ie_len;
805 		pmlmepriv->wps_probe_req_ie_len = 0;
806 		rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
807 		pmlmepriv->wps_probe_req_ie = NULL;
808 	}
809 
810 	if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _FALSE) {
811 		RTW_INFO(FUNC_ADPT_FMT" fw_state:0x%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
812 		/* rtw_warn_on(1); */
813 	}
814 
815 	_clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY);
816 	_rtw_spinunlock_bh(&pmlmepriv->lock);
817 
818 	_cancel_timer_ex(&pmlmepriv->scan_to_timer);
819 
820 	_rtw_spinlock_bh(&pmlmepriv->lock);
821 	#ifdef CONFIG_SIGNAL_STAT_PROCESS
822 	rtw_set_signal_stat_timer(&adapter->recvinfo);
823 	#endif
824 	if (pmlmepriv->to_join == _TRUE) {
825 		if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) {
826 			if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE) {
827 				set_fwstate(pmlmepriv, WIFI_UNDER_LINKING);
828 
829 				if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS) {
830 					/*_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);*/
831 					set_assoc_timer(pmlmepriv, MAX_JOIN_TIMEOUT);
832 				}
833 				else {
834 					WLAN_BSSID_EX    *pdev_network = &(adapter->registrypriv.dev_network);
835 					u8 *pibss = adapter->registrypriv.dev_network.MacAddress;
836 
837 					/* pmlmepriv->fw_state ^= WIFI_UNDER_SURVEY; */ /* because don't set assoc_timer */
838 					_clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY);
839 
840 
841 					_rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
842 					_rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
843 
844 					rtw_update_registrypriv_dev_network(adapter);
845 					rtw_generate_random_ibss(pibss);
846 
847 					/*pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;*/
848 					init_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
849 
850 					if (rtw_create_ibss_cmd(adapter, 0) != _SUCCESS)
851 						RTW_ERR("rtw_create_ibss_cmd FAIL\n");
852 
853 					pmlmepriv->to_join = _FALSE;
854 				}
855 			}
856 		} else {
857 			int s_ret;
858 			set_fwstate(pmlmepriv, WIFI_UNDER_LINKING);
859 			pmlmepriv->to_join = _FALSE;
860 			s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
861 			if (_SUCCESS == s_ret) {
862 				/*_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);*/
863 				set_assoc_timer(pmlmepriv, MAX_JOIN_TIMEOUT);
864 			} else if (s_ret == 2) { /* there is no need to wait for join */
865 				_clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING);
866 				rtw_indicate_connect(adapter);
867 			} else {
868 				RTW_INFO("try_to_join, but select scanning queue fail, to_roam:%d\n", rtw_to_roam(adapter));
869 
870 				if (rtw_to_roam(adapter) != 0) {
871 					struct sitesurvey_parm scan_parm;
872 					u8 ssc_chk = rtw_sitesurvey_condition_check(adapter, _FALSE);
873 
874 					rtw_init_sitesurvey_parm(adapter, &scan_parm);
875 					_rtw_memcpy(&scan_parm.ssid[0], &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
876 					scan_parm.ssid_num = 1;
877 
878 					if (rtw_dec_to_roam(adapter) == 0
879 						|| (ssc_chk != SS_ALLOW && ssc_chk != SS_DENY_BUSY_TRAFFIC)
880 						|| _SUCCESS != rtw_sitesurvey_cmd(adapter, &scan_parm)
881 					   ) {
882 						rtw_set_to_roam(adapter, 0);
883 						if (MLME_IS_ASOC(adapter) == _TRUE)
884 							rtw_free_assoc_resources(adapter, _TRUE);
885 						rtw_indicate_disconnect(adapter, 0, _FALSE);
886 					} else
887 						pmlmepriv->to_join = _TRUE;
888 				} else
889 					rtw_indicate_disconnect(adapter, 0, _FALSE);
890 				_clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING);
891 			}
892 		}
893 	} else {
894 		if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)
895                 #if (defined(CONFIG_RTW_WNM) && defined(CONFIG_RTW_80211R))
896                         || rtw_wnm_btm_roam_triggered(adapter)
897                 #endif
898 		) {
899 			if (MLME_IS_STA(adapter)
900 			    && check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
901 				if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) {
902 #ifdef CONFIG_RTW_80211R
903 					rtw_ft_start_roam(adapter,
904 						(u8 *)pmlmepriv->roam_network->network.MacAddress);
905 #else
906 					receive_disconnect(adapter, pmlmepriv->cur_network.network.MacAddress
907 						, WLAN_REASON_ACTIVE_ROAM, _FALSE);
908 					pmlmeinfo->disconnect_occurred_time = rtw_systime_to_ms(rtw_get_current_time());
909 					pmlmeinfo->disconnect_code = DISCONNECTION_BY_DRIVER_DUE_TO_ROAMING;
910 					pmlmeinfo->wifi_reason_code = WLAN_REASON_UNSPECIFIED;
911 #endif
912 				}
913 			}
914 		}
915 	}
916 
917 	RTW_INFO("scan complete in %dms\n",rtw_get_passing_time_ms(pmlmepriv->scan_start_time));
918 
919 	_rtw_spinunlock_bh(&pmlmepriv->lock);
920 
921 #ifdef CONFIG_P2P_PS
922 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
923 		p2p_ps_wk_cmd(adapter, P2P_PS_SCAN_DONE, 0);
924 #endif /* CONFIG_P2P_PS */
925 
926 	rtw_mi_os_xmit_schedule(adapter);
927 #ifdef CONFIG_DRVEXT_MODULE_WSC
928 	drvext_surveydone_callback(&adapter->drvextpriv);
929 #endif
930 
931 #ifdef DBG_CONFIG_ERROR_DETECT
932 	{
933 		struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
934 		if (pmlmeext->sitesurvey_res.bss_cnt == 0) {
935 			/* rtw_hal_sreset_reset(adapter); */
936 		}
937 	}
938 #endif
939 
940 #ifdef CONFIG_IOCTL_CFG80211
941 	rtw_cfg80211_surveydone_event_callback(adapter);
942 #endif /* CONFIG_IOCTL_CFG80211 */
943 
944 	rtw_indicate_scan_done(adapter, pmlmeext->scan_abort);
945 
946 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_IOCTL_CFG80211)
947 	rtw_cfg80211_indicate_scan_done_for_buddy(adapter, _FALSE);
948 #endif
949 
950 	if (parm->activate_ch_cnt) {
951 		#ifdef CONFIG_IOCTL_CFG80211
952 		struct get_chplan_resp *chplan;
953 
954 		if (rtw_get_chplan_cmd(adapter, RTW_CMDF_DIRECTLY, &chplan) != _SUCCESS
955 			|| rtw_regd_change_complete_async(adapter_to_wiphy(adapter), chplan) != _SUCCESS)
956 			rtw_warn_on(1);
957 		#endif
958 
959 		op_class_pref_apply_regulatory(adapter, REG_BEACON_HINT);
960 		rtw_nlrtw_reg_beacon_hint_event(adapter);
961 	}
962 
963 #ifdef CONFIG_RTW_MESH
964 	#if CONFIG_RTW_MESH_OFFCH_CAND
965 	if (rtw_mesh_offch_candidate_accepted(adapter)) {
966 		u8 ch;
967 
968 		ch = rtw_mesh_select_operating_ch(adapter);
969 		if (ch && pmlmepriv->cur_network.network.Configuration.DSConfig != ch) {
970 			u8 ifbmp = rtw_mi_get_ap_mesh_ifbmp(adapter);
971 
972 			if (ifbmp) {
973 				/* switch to selected channel */
974 				rtw_change_bss_chbw_cmd(adapter, RTW_CMDF_DIRECTLY, ifbmp, 0, ch, REQ_BW_ORI, REQ_OFFSET_NONE);
975 				issue_probereq_ex(adapter, &pmlmepriv->cur_network.network.mesh_id, NULL, 0, 0, 0, 0);
976 			} else
977 				rtw_warn_on(1);
978 		}
979 	}
980 	#endif
981 #endif /* CONFIG_RTW_MESH */
982 
983 #ifdef CONFIG_RTW_ACS
984 	if (parm->acs) {
985 		u8 ifbmp = rtw_mi_get_ap_mesh_ifbmp(adapter);
986 
987 		if (ifbmp)
988 			rtw_change_bss_chbw_cmd(adapter, RTW_CMDF_DIRECTLY, ifbmp, 0, REQ_CH_INT_INFO, REQ_BW_ORI, REQ_OFFSET_NONE);
989 	}
990 #endif
991 }
992 
_rtw_sitesurvey_condition_check(const char * caller,_adapter * adapter,bool check_sc_interval)993 u8 _rtw_sitesurvey_condition_check(const char *caller, _adapter *adapter, bool check_sc_interval)
994 {
995 	u8 ss_condition = SS_ALLOW;
996 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
997 	struct registry_priv *registry_par = &adapter->registrypriv;
998 
999 
1000 #ifdef CONFIG_MP_INCLUDED
1001 	if (rtw_mp_mode_check(adapter)) {
1002 		RTW_INFO("%s ("ADPT_FMT") MP mode block Scan request\n", caller, ADPT_ARG(adapter));
1003 		ss_condition = SS_DENY_MP_MODE;
1004 		goto _exit;
1005 	}
1006 #endif
1007 
1008 #ifdef DBG_LA_MODE
1009 	if(registry_par->la_mode_en == 1 && MLME_IS_ASOC(adapter)) {
1010 		RTW_INFO("%s ("ADPT_FMT") LA debug mode block Scan request\n", caller, ADPT_ARG(adapter));
1011 		ss_condition = SS_DENY_LA_MODE;
1012 		goto _exit;
1013 	}
1014 #endif
1015 
1016 #ifdef CONFIG_IOCTL_CFG80211
1017 	if (adapter_wdev_data(adapter)->block_scan == _TRUE) {
1018 		RTW_INFO("%s ("ADPT_FMT") wdev_priv.block_scan is set\n", caller, ADPT_ARG(adapter));
1019 		ss_condition = SS_DENY_BLOCK_SCAN;
1020 		goto _exit;
1021 	}
1022 #endif
1023 
1024 	if (adapter_to_dvobj(adapter)->scan_deny == _TRUE) {
1025 		RTW_INFO("%s ("ADPT_FMT") tpt mode, scan deny!\n", caller, ADPT_ARG(adapter));
1026 		ss_condition = SS_DENY_BLOCK_SCAN;
1027 		goto _exit;
1028 	}
1029 
1030 	if (rtw_is_scan_deny(adapter)) {
1031 		RTW_INFO("%s ("ADPT_FMT") : scan deny\n", caller, ADPT_ARG(adapter));
1032 		ss_condition = SS_DENY_BY_DRV;
1033 		goto _exit;
1034 	}
1035 
1036 	#if 0 /*GEORGIA_TODO_FIXIT*/
1037 	if (adapter_to_rfctl(adapter)->adaptivity_en
1038 	    && rtw_hal_get_phy_edcca_flag(adapter)
1039 	    && rtw_is_2g_ch(GET_PHL_COM(adapter_to_dvobj(adapter))->current_channel)) {
1040 		RTW_WARN(FUNC_ADPT_FMT": Adaptivity block scan! (ch=%u)\n",
1041 			 FUNC_ADPT_ARG(adapter),
1042 			 GET_PHL_COM(adapter_to_dvobj(adapter))->current_channel);
1043 		ss_condition = SS_DENY_ADAPTIVITY;
1044 		goto _exit;
1045 	}
1046 	#endif
1047 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE)){
1048 		if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
1049 			RTW_INFO("%s ("ADPT_FMT") : scan abort!! AP mode process WPS\n", caller, ADPT_ARG(adapter));
1050 			ss_condition = SS_DENY_SELF_AP_UNDER_WPS;
1051 			goto _exit;
1052 		} else if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) {
1053 			RTW_INFO("%s ("ADPT_FMT") : scan abort!!AP mode under linking (fwstate=0x%x)\n",
1054 				caller, ADPT_ARG(adapter), pmlmepriv->fw_state);
1055 			ss_condition = SS_DENY_SELF_AP_UNDER_LINKING;
1056 			goto _exit;
1057 		} else if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) {
1058 			RTW_INFO("%s ("ADPT_FMT") : scan abort!!AP mode under survey (fwstate=0x%x)\n",
1059 				caller, ADPT_ARG(adapter), pmlmepriv->fw_state);
1060 			ss_condition = SS_DENY_SELF_AP_UNDER_SURVEY;
1061 			goto _exit;
1062 		}
1063 	} else {
1064 		if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) {
1065 			RTW_INFO("%s ("ADPT_FMT") : scan abort!!STA mode under linking (fwstate=0x%x)\n",
1066 				caller, ADPT_ARG(adapter), pmlmepriv->fw_state);
1067 			ss_condition = SS_DENY_SELF_STA_UNDER_LINKING;
1068 			goto _exit;
1069 		} else if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) {
1070 			RTW_INFO("%s ("ADPT_FMT") : scan abort!!STA mode under survey (fwstate=0x%x)\n",
1071 				caller, ADPT_ARG(adapter), pmlmepriv->fw_state);
1072 			ss_condition = SS_DENY_SELF_STA_UNDER_SURVEY;
1073 			goto _exit;
1074 		}
1075 	}
1076 
1077 #ifdef CONFIG_CONCURRENT_MODE
1078 	if (rtw_mi_buddy_check_fwstate(adapter, WIFI_UNDER_LINKING | WIFI_UNDER_WPS)) {
1079 		RTW_INFO("%s ("ADPT_FMT") : scan abort!! buddy_intf under linking or wps\n", caller, ADPT_ARG(adapter));
1080 		ss_condition = SS_DENY_BUDDY_UNDER_LINK_WPS;
1081 		goto _exit;
1082 
1083 	} else if (rtw_mi_buddy_check_fwstate(adapter, WIFI_UNDER_SURVEY)) {
1084 		RTW_INFO("%s ("ADPT_FMT") : scan abort!! buddy_intf under survey\n", caller, ADPT_ARG(adapter));
1085 		ss_condition = SS_DENY_BUDDY_UNDER_SURVEY;
1086 		goto _exit;
1087 	}
1088 #endif /* CONFIG_CONCURRENT_MODE */
1089 
1090 #ifdef RTW_BUSY_DENY_SCAN
1091 	/*
1092 	 * busy traffic check
1093 	 * Rules:
1094 	 * 1. If (scan interval <= BUSY_TRAFFIC_SCAN_DENY_PERIOD) always allow
1095 	 *    scan, otherwise goto rule 2.
1096 	 * 2. Deny scan if any interface is busy, otherwise allow scan.
1097 	 */
1098 	if (pmlmepriv->lastscantime
1099 	    && (rtw_get_passing_time_ms(pmlmepriv->lastscantime) >
1100 		registry_par->scan_interval_thr)
1101 	    && rtw_mi_busy_traffic_check(adapter)) {
1102 		RTW_WARN("%s ("ADPT_FMT") : scan abort!! BusyTraffic\n",
1103 			 caller, ADPT_ARG(adapter));
1104 		ss_condition = SS_DENY_BUSY_TRAFFIC;
1105 		goto _exit;
1106 	}
1107 #endif /* RTW_BUSY_DENY_SCAN */
1108 
1109 _exit:
1110 	return ss_condition;
1111 }
1112 
1113 
1114 /*rtw_mlme_ext.c*/
sitesurvey_set_offch_state(_adapter * adapter,u8 scan_state)1115 void sitesurvey_set_offch_state(_adapter *adapter, u8 scan_state)
1116 {
1117 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
1118 
1119 	_rtw_mutex_lock_interruptible(&rfctl->offch_mutex);
1120 
1121 	switch (scan_state) {
1122 	case SCAN_DISABLE:
1123 	case SCAN_BACK_OP:
1124 		rfctl->offch_state = OFFCHS_NONE;
1125 		break;
1126 	case SCAN_START:
1127 	case SCAN_LEAVING_OP:
1128 		rfctl->offch_state = OFFCHS_LEAVING_OP;
1129 		break;
1130 	case SCAN_ENTER:
1131 	case SCAN_LEAVE_OP:
1132 		rfctl->offch_state = OFFCHS_LEAVE_OP;
1133 		break;
1134 	case SCAN_COMPLETE:
1135 	case SCAN_BACKING_OP:
1136 		rfctl->offch_state = OFFCHS_BACKING_OP;
1137 		break;
1138 	default:
1139 		break;
1140 	}
1141 
1142 	_rtw_mutex_unlock(&rfctl->offch_mutex);
1143 }
rtw_scan_sparse(_adapter * adapter,struct rtw_ieee80211_channel * ch,u8 ch_num)1144 static u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num)
1145 {
1146 	/* interval larger than this is treated as backgroud scan */
1147 #ifndef RTW_SCAN_SPARSE_BG_INTERVAL_MS
1148 #define RTW_SCAN_SPARSE_BG_INTERVAL_MS 12000
1149 #endif
1150 
1151 #ifndef RTW_SCAN_SPARSE_CH_NUM_MIRACAST
1152 #define RTW_SCAN_SPARSE_CH_NUM_MIRACAST 1
1153 #endif
1154 #ifndef RTW_SCAN_SPARSE_CH_NUM_BG
1155 #define RTW_SCAN_SPARSE_CH_NUM_BG 4
1156 #endif
1157 
1158 #define SCAN_SPARSE_CH_NUM_INVALID 255
1159 
1160 	static u8 token = 255;
1161 	u32 interval;
1162 	bool busy_traffic = _FALSE;
1163 	bool miracast_enabled = _FALSE;
1164 	bool bg_scan = _FALSE;
1165 	u8 max_allow_ch = SCAN_SPARSE_CH_NUM_INVALID;
1166 	u8 scan_division_num;
1167 	u8 ret_num = ch_num;
1168 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
1169 
1170 	if (mlmeext->last_scan_time == 0)
1171 		mlmeext->last_scan_time = rtw_get_current_time();
1172 
1173 	interval = rtw_get_passing_time_ms(mlmeext->last_scan_time);
1174 
1175 
1176 	if (rtw_mi_busy_traffic_check(adapter))
1177 		busy_traffic = _TRUE;
1178 
1179 	if (rtw_mi_check_miracast_enabled(adapter))
1180 		miracast_enabled = _TRUE;
1181 
1182 	if (interval > RTW_SCAN_SPARSE_BG_INTERVAL_MS)
1183 		bg_scan = _TRUE;
1184 
1185 	/* max_allow_ch by conditions*/
1186 
1187 #if RTW_SCAN_SPARSE_MIRACAST
1188 	if (miracast_enabled == _TRUE && busy_traffic == _TRUE)
1189 		max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_MIRACAST);
1190 #endif
1191 
1192 #if RTW_SCAN_SPARSE_BG
1193 	if (bg_scan == _TRUE)
1194 		max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_BG);
1195 #endif
1196 
1197 
1198 	if (max_allow_ch != SCAN_SPARSE_CH_NUM_INVALID) {
1199 		int i;
1200 		int k = 0;
1201 
1202 		scan_division_num = (ch_num / max_allow_ch) + ((ch_num % max_allow_ch) ? 1 : 0);
1203 		token = (token + 1) % scan_division_num;
1204 
1205 		if (0)
1206 			RTW_INFO("scan_division_num:%u, token:%u\n", scan_division_num, token);
1207 
1208 		for (i = 0; i < ch_num; i++) {
1209 			if (ch[i].hw_value && (i % scan_division_num) == token
1210 			   ) {
1211 				if (i != k)
1212 					_rtw_memcpy(&ch[k], &ch[i], sizeof(struct rtw_ieee80211_channel));
1213 				k++;
1214 			}
1215 		}
1216 
1217 		_rtw_memset(&ch[k], 0, sizeof(struct rtw_ieee80211_channel));
1218 
1219 		ret_num = k;
1220 		mlmeext->last_scan_time = rtw_get_current_time();
1221 	}
1222 
1223 	return ret_num;
1224 }
1225 
rtw_scan_ch_decision(_adapter * padapter,struct rtw_ieee80211_channel * out,u32 out_num,struct rtw_ieee80211_channel * in,u32 in_num,bool no_sparse)1226 static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
1227 		u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num, bool no_sparse)
1228 {
1229 	int i, j;
1230 	int set_idx;
1231 	u8 chan;
1232 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
1233 	struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(padapter));
1234 
1235 	/* clear first */
1236 	_rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel) * out_num);
1237 
1238 	/* acquire channels from in */
1239 	j = 0;
1240 	for (i = 0; i < in_num; i++) {
1241 
1242 		if (0)
1243 			RTW_INFO(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
1244 
1245 		if (!in[i].hw_value || (in[i].flags & RTW_IEEE80211_CHAN_DISABLED))
1246 			continue;
1247 		if (rtw_mlme_band_check(padapter, in[i].hw_value) == _FALSE)
1248 			continue;
1249 
1250 		set_idx = rtw_chset_search_ch(rfctl->channel_set, in[i].hw_value);
1251 		if (set_idx >= 0) {
1252 			if (j >= out_num) {
1253 				RTW_PRINT(FUNC_ADPT_FMT" out_num:%u not enough\n",
1254 					  FUNC_ADPT_ARG(padapter), out_num);
1255 				break;
1256 			}
1257 
1258 			_rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
1259 
1260 			if (rfctl->channel_set[set_idx].flags & (RTW_CHF_NO_IR | RTW_CHF_DFS))
1261 				out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
1262 
1263 			j++;
1264 		}
1265 		if (j >= out_num)
1266 			break;
1267 	}
1268 
1269 	/* if out is empty, use channel_set as default */
1270 	if (j == 0) {
1271 		for (i = 0; i < rfctl->max_chan_nums; i++) {
1272 			chan = rfctl->channel_set[i].ChannelNum;
1273 			if (rtw_mlme_band_check(padapter, chan) == _TRUE) {
1274 				if (rtw_mlme_ignore_chan(padapter, chan) == _TRUE)
1275 					continue;
1276 
1277 				if (0)
1278 					RTW_INFO(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), chan);
1279 
1280 				if (j >= out_num) {
1281 					RTW_PRINT(FUNC_ADPT_FMT" out_num:%u not enough\n",
1282 						FUNC_ADPT_ARG(padapter), out_num);
1283 					break;
1284 				}
1285 
1286 				out[j].hw_value = chan;
1287 
1288 				if (rfctl->channel_set[i].flags & (RTW_CHF_NO_IR | RTW_CHF_DFS))
1289 					out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
1290 
1291 				j++;
1292 			}
1293 		}
1294 	}
1295 
1296 	if (!no_sparse
1297 		&& !regsty->wifi_spec
1298 		&& j > 6 /* assume ch_num > 6 is normal scan */
1299 	) {
1300 		/* scan_sparse */
1301 		j = rtw_scan_sparse(padapter, out, j);
1302 	}
1303 
1304 	return j;
1305 }
1306 #ifdef CONFIG_SCAN_BACKOP
rtw_scan_backop_decision(_adapter * adapter)1307 u8 rtw_scan_backop_decision(_adapter *adapter)
1308 {
1309 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
1310 	struct mi_state mstate;
1311 	u8 backop_flags = 0;
1312 
1313 	rtw_mi_status(adapter, &mstate);
1314 
1315 	if ((MSTATE_STA_LD_NUM(&mstate) && mlmeext_chk_scan_backop_flags_sta(mlmeext, SS_BACKOP_EN))
1316 		|| (MSTATE_STA_NUM(&mstate) && mlmeext_chk_scan_backop_flags_sta(mlmeext, SS_BACKOP_EN_NL)))
1317 		backop_flags |= mlmeext_scan_backop_flags_sta(mlmeext);
1318 
1319 #ifdef CONFIG_AP_MODE
1320 	if ((MSTATE_AP_LD_NUM(&mstate) && mlmeext_chk_scan_backop_flags_ap(mlmeext, SS_BACKOP_EN))
1321 		|| (MSTATE_AP_NUM(&mstate) && mlmeext_chk_scan_backop_flags_ap(mlmeext, SS_BACKOP_EN_NL)))
1322 		backop_flags |= mlmeext_scan_backop_flags_ap(mlmeext);
1323 #endif
1324 
1325 #ifdef CONFIG_RTW_MESH
1326 	if ((MSTATE_MESH_LD_NUM(&mstate) && mlmeext_chk_scan_backop_flags_mesh(mlmeext, SS_BACKOP_EN))
1327 		|| (MSTATE_MESH_NUM(&mstate) && mlmeext_chk_scan_backop_flags_mesh(mlmeext, SS_BACKOP_EN_NL)))
1328 		backop_flags |= mlmeext_scan_backop_flags_mesh(mlmeext);
1329 #endif
1330 
1331 	return backop_flags;
1332 }
1333 #endif
1334 
1335 #if 0 /*#ifndef CONFIG_PHL_ARCH*/
1336 void survey_timer_hdl(void *ctx)
1337 {
1338 	_adapter *padapter = (_adapter *)ctx;
1339 	struct cmd_obj *cmd;
1340 	struct sitesurvey_parm *psurveyPara;
1341 	struct cmd_priv *pcmdpriv = &adapter_to_dvobj(padapter)->cmdpriv;
1342 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1343 
1344 	if (mlmeext_scan_state(pmlmeext) > SCAN_DISABLE) {
1345 		cmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
1346 		if (cmd == NULL) {
1347 			rtw_warn_on(1);
1348 			goto exit;
1349 		}
1350 		cmd->padapter = padapter;
1351 
1352 		psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm));
1353 		if (psurveyPara == NULL) {
1354 			rtw_warn_on(1);
1355 			rtw_mfree((unsigned char *)cmd, sizeof(struct cmd_obj));
1356 			goto exit;
1357 		}
1358 
1359 		init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, CMD_SITE_SURVEY);
1360 		rtw_enqueue_cmd(pcmdpriv, cmd);
1361 	}
1362 
1363 exit:
1364 	return;
1365 }
1366 
1367 static const char *const _scan_state_str[] = {
1368 	"SCAN_DISABLE",
1369 	"SCAN_START",
1370 	"SCAN_PS_ANNC_WAIT",
1371 	"SCAN_ENTER",
1372 	"SCAN_PROCESS",
1373 	"SCAN_BACKING_OP",
1374 	"SCAN_BACK_OP",
1375 	"SCAN_LEAVING_OP",
1376 	"SCAN_LEAVE_OP",
1377 	"SCAN_SW_ANTDIV_BL",
1378 	"SCAN_TO_P2P_LISTEN",
1379 	"SCAN_P2P_LISTEN",
1380 	"SCAN_COMPLETE",
1381 	"SCAN_STATE_MAX",
1382 };
1383 
1384 void rtw_survey_cmd_callback(_adapter *padapter ,  struct cmd_obj *pcmd)
1385 {
1386 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
1387 
1388 
1389 	if (pcmd->res == H2C_DROPPED) {
1390 		/* TODO: cancel timer and do timeout handler directly... */
1391 		/* need to make timeout handlerOS independent */
1392 		mlme_set_scan_to_timer(pmlmepriv, 1);
1393 	} else if (pcmd->res != H2C_SUCCESS) {
1394 		mlme_set_scan_to_timer(pmlmepriv, 1);
1395 	}
1396 
1397 	/* free cmd */
1398 	rtw_free_cmd_obj(pcmd);
1399 
1400 }
1401 
1402 const char *scan_state_str(u8 state)
1403 {
1404 	state = (state >= SCAN_STATE_MAX) ? SCAN_STATE_MAX : state;
1405 	return _scan_state_str[state];
1406 }
1407 
1408 static bool scan_abort_hdl(_adapter *adapter)
1409 {
1410 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
1411 	struct ss_res *ss = &pmlmeext->sitesurvey_res;
1412 #ifdef CONFIG_P2P
1413 	struct wifidirect_info *pwdinfo = &adapter->wdinfo;
1414 #endif
1415 	bool ret = _FALSE;
1416 
1417 	if (pmlmeext->scan_abort == _TRUE) {
1418 #ifdef CONFIG_P2P
1419 		if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) {
1420 			rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
1421 			ss->channel_idx = 3;
1422 			RTW_INFO("%s idx:%d, cnt:%u\n", __FUNCTION__
1423 				 , ss->channel_idx
1424 				 , pwdinfo->find_phase_state_exchange_cnt
1425 				);
1426 		} else
1427 #endif
1428 		{
1429 			ss->channel_idx = ss->ch_num;
1430 			RTW_INFO("%s idx:%d\n", __FUNCTION__
1431 				 , ss->channel_idx
1432 				);
1433 		}
1434 		pmlmeext->scan_abort = _FALSE;
1435 		ret = _TRUE;
1436 	}
1437 
1438 	return ret;
1439 }
1440 
1441 static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm)
1442 {
1443 	struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
1444 	RT_CHANNEL_INFO *chset = adapter_to_chset(adapter);
1445 	int i;
1446 
1447 	ss->bss_cnt = 0;
1448 	ss->activate_ch_cnt = 0;
1449 	ss->channel_idx = 0;
1450 	ss->force_ssid_scan = 0;
1451 	ss->igi_scan = 0;
1452 	ss->igi_before_scan = 0;
1453 #ifdef CONFIG_SCAN_BACKOP
1454 	ss->scan_cnt = 0;
1455 #endif
1456 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
1457 	ss->is_sw_antdiv_bl_scan = 0;
1458 #endif
1459 	ss->ssid_num = 0;
1460 	for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
1461 		if (parm->ssid[i].SsidLength) {
1462 			_rtw_memcpy(ss->ssid[i].Ssid, parm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
1463 			ss->ssid[i].SsidLength = parm->ssid[i].SsidLength;
1464 			ss->ssid_num++;
1465 		} else
1466 			ss->ssid[i].SsidLength = 0;
1467 	}
1468 
1469 	ss->ch_num = rtw_scan_ch_decision(adapter
1470 					, ss->ch, RTW_CHANNEL_SCAN_AMOUNT
1471 					, parm->ch, parm->ch_num
1472 					, parm->acs
1473 				);
1474 
1475 	for (i = 0; i < MAX_CHANNEL_NUM; i++)
1476 		chset[i].hidden_bss_cnt = 0;
1477 
1478 	ss->bw = parm->bw;
1479 	ss->igi = parm->igi;
1480 	ss->token = parm->token;
1481 	ss->duration = parm->duration;
1482 	ss->scan_mode = parm->scan_mode;
1483 	ss->token = parm->token;
1484 	ss->acs = parm->acs;
1485 }
1486 
1487 static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch,
1488 					enum rtw_phl_scan_type *type)
1489 {
1490 	u8 next_state;
1491 	u8 scan_ch = 0;
1492 	enum rtw_phl_scan_type stype = RTW_PHL_SCAN_PASSIVE;
1493 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1494 	struct ss_res *ss = &pmlmeext->sitesurvey_res;
1495 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
1496 	int ch_set_idx;
1497 #ifdef CONFIG_P2P
1498 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1499 #endif
1500 #ifdef CONFIG_SCAN_BACKOP
1501 	u8 backop_flags = 0;
1502 #endif
1503 
1504 	/* handle scan abort request */
1505 	scan_abort_hdl(padapter);
1506 
1507 #ifdef CONFIG_P2P
1508 	if (pwdinfo->rx_invitereq_info.scan_op_ch_only || pwdinfo->p2p_info.scan_op_ch_only) {
1509 		if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
1510 			scan_ch = pwdinfo->rx_invitereq_info.operation_ch[ss->channel_idx];
1511 		else
1512 			scan_ch = pwdinfo->p2p_info.operation_ch[ss->channel_idx];
1513 		stype = RTW_PHL_SCAN_ACTIVE;
1514 	} else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
1515 		/*
1516 		* Commented by Albert 2011/06/03
1517 		* The driver is in the find phase, it should go through the social channel.
1518 		*/
1519 		scan_ch = pwdinfo->social_chan[ss->channel_idx];
1520 		ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, scan_ch);
1521 		if (ch_set_idx >= 0)
1522 			stype = rfctl->channel_set[ch_set_idx].flags & RTW_CHF_NO_IR ? RTW_PHL_SCAN_PASSIVE : RTW_PHL_SCAN_ACTIVE;
1523 		else
1524 			stype = RTW_PHL_SCAN_ACTIVE;
1525 	} else
1526 #endif /* CONFIG_P2P */
1527 	{
1528 		struct rtw_ieee80211_channel *ch;
1529 
1530 		#ifdef CONFIG_SCAN_BACKOP
1531 		backop_flags = rtw_scan_backop_decision(padapter);
1532 		#endif
1533 
1534 		#ifdef CONFIG_SCAN_BACKOP
1535 		if (!(backop_flags && ss->scan_cnt >= ss->scan_cnt_max))
1536 		#endif
1537 		{
1538 			#ifdef CONFIG_RTW_WIFI_HAL
1539 			if (adapter_to_dvobj(padapter)->nodfs) {
1540 				while (ss->channel_idx < ss->ch_num && rtw_chset_is_dfs_ch(rfctl->channel_set, ss->ch[ss->channel_idx].hw_value))
1541 					ss->channel_idx++;
1542 			} else
1543 			#endif
1544 			if (ss->channel_idx != 0 && ss->force_ssid_scan == 0
1545 				&& pmlmeext->sitesurvey_res.ssid_num
1546 				&& (ss->ch[ss->channel_idx - 1].flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN)
1547 			) {
1548 				ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, ss->ch[ss->channel_idx - 1].hw_value);
1549 				if (ch_set_idx != -1 && rfctl->channel_set[ch_set_idx].hidden_bss_cnt
1550 					&& (!IS_DFS_SLAVE_WITH_RD(rfctl)
1551 						|| rtw_rfctl_dfs_domain_unknown(rfctl)
1552 						|| !CH_IS_NON_OCP(&rfctl->channel_set[ch_set_idx]))
1553 				) {
1554 					ss->channel_idx--;
1555 					ss->force_ssid_scan = 1;
1556 				}
1557 			} else
1558 				ss->force_ssid_scan = 0;
1559 		}
1560 
1561 		if (ss->channel_idx < ss->ch_num) {
1562 			ch = &ss->ch[ss->channel_idx];
1563 			scan_ch = ch->hw_value;
1564 
1565 			#if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
1566 			if (IS_ACS_ENABLE(padapter) && rtw_is_acs_passiv_scan(padapter))
1567 				stype = RTW_PHL_SCAN_PASSIVE;
1568 			else
1569 			#endif /*CONFIG_RTW_ACS*/
1570 				stype = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? RTW_PHL_SCAN_PASSIVE : RTW_PHL_SCAN_ACTIVE;
1571 		}
1572 	}
1573 
1574 	if (scan_ch != 0) {
1575 		next_state = SCAN_PROCESS;
1576 
1577 		#ifdef CONFIG_SCAN_BACKOP
1578 		if (backop_flags) {
1579 			if (ss->scan_cnt < ss->scan_cnt_max)
1580 				ss->scan_cnt++;
1581 			else {
1582 				mlmeext_assign_scan_backop_flags(pmlmeext, backop_flags);
1583 				next_state = SCAN_BACKING_OP;
1584 			}
1585 		}
1586 		#endif
1587 
1588 	} else if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) {
1589 		/* go p2p listen */
1590 		next_state = SCAN_TO_P2P_LISTEN;
1591 
1592 #ifdef CONFIG_ANTENNA_DIVERSITY
1593 	} else if (rtw_hal_antdiv_before_linked(padapter)) {
1594 		/* go sw antdiv before link */
1595 		next_state = SCAN_SW_ANTDIV_BL;
1596 #endif
1597 	} else {
1598 		next_state = SCAN_COMPLETE;
1599 
1600 #if defined(DBG_SCAN_SW_ANTDIV_BL)
1601 		{
1602 			/* for SCAN_SW_ANTDIV_BL state testing */
1603 			struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1604 			int i;
1605 			bool is_linked = _FALSE;
1606 
1607 			for (i = 0; i < dvobj->iface_nums; i++) {
1608 				if (rtw_linked_check(dvobj->padapters[i]))
1609 					is_linked = _TRUE;
1610 			}
1611 
1612 			if (!is_linked) {
1613 				static bool fake_sw_antdiv_bl_state = 0;
1614 
1615 				if (fake_sw_antdiv_bl_state == 0) {
1616 					next_state = SCAN_SW_ANTDIV_BL;
1617 					fake_sw_antdiv_bl_state = 1;
1618 				} else
1619 					fake_sw_antdiv_bl_state = 0;
1620 			}
1621 		}
1622 #endif /* defined(DBG_SCAN_SW_ANTDIV_BL) */
1623 	}
1624 
1625 #ifdef CONFIG_SCAN_BACKOP
1626 	if (next_state != SCAN_PROCESS)
1627 		ss->scan_cnt = 0;
1628 #endif
1629 
1630 
1631 #ifdef DBG_FIXED_CHAN
1632 	if (pmlmeext->fixed_chan != 0xff && next_state == SCAN_PROCESS)
1633 		scan_ch = pmlmeext->fixed_chan;
1634 #endif
1635 
1636 	if (ch)
1637 		*ch = scan_ch;
1638 	if (type)
1639 		*type = stype;
1640 
1641 	return next_state;
1642 }
1643 
1644 void site_survey(_adapter *padapter, u8 survey_channel,
1645 	enum rtw_phl_scan_type ScanType)
1646 {
1647 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1648 	struct ss_res *ss = &pmlmeext->sitesurvey_res;
1649 	u8 ssid_scan = 0;
1650 
1651 #ifdef CONFIG_P2P
1652 #ifndef CONFIG_IOCTL_CFG80211
1653 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1654 #endif
1655 #endif
1656 
1657 	if (survey_channel != 0) {
1658 		set_channel_bwmode(padapter,
1659 				survey_channel,
1660 				CHAN_OFFSET_NO_EXT,
1661 				CHANNEL_WIDTH_20,
1662 				_FALSE);
1663 
1664 		if (ScanType == RTW_PHL_SCAN_PASSIVE && ss->force_ssid_scan)
1665 			ssid_scan = 1;
1666 		else if (ScanType == RTW_PHL_SCAN_ACTIVE) {
1667 #ifdef CONFIG_P2P
1668 			#ifdef CONFIG_IOCTL_CFG80211
1669 			if (rtw_cfg80211_is_p2p_scan(padapter))
1670 			#else
1671 			if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
1672 				|| rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
1673 			#endif
1674 			{
1675 				issue_probereq_p2p(padapter, NULL);
1676 				issue_probereq_p2p(padapter, NULL);
1677 				issue_probereq_p2p(padapter, NULL);
1678 			} else
1679 #endif /* CONFIG_P2P */
1680 			{
1681 				if (pmlmeext->sitesurvey_res.scan_mode == RTW_PHL_SCAN_ACTIVE) {
1682 					/* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
1683 					if (padapter->registrypriv.wifi_spec)
1684 						issue_probereq(padapter, NULL, NULL);
1685 					else
1686 						issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
1687 					issue_probereq(padapter, NULL, NULL);
1688 				}
1689 
1690 				ssid_scan = 1;
1691 			}
1692 		}
1693 
1694 		if (ssid_scan) {
1695 			int i;
1696 
1697 			for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
1698 				if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
1699 					/* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
1700 					if (padapter->registrypriv.wifi_spec)
1701 						issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
1702 					else
1703 						issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
1704 					issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
1705 				}
1706 			}
1707 		}
1708 	} else {
1709 		/* channel number is 0 or this channel is not valid. */
1710 		rtw_warn_on(1);
1711 	}
1712 
1713 	return;
1714 }
1715 
1716 void survey_done_set_ch_bw(_adapter *padapter)
1717 {
1718 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1719 	u8 cur_channel = 0;
1720 	u8 cur_bwmode;
1721 	u8 cur_ch_offset;
1722 
1723 	if (rtw_mi_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0) {
1724 		if (0)
1725 			RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n",
1726 				FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
1727 	} else {
1728 #ifdef CONFIG_P2P
1729 		struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1730 		_adapter *iface;
1731 		int i;
1732 
1733 		for (i = 0; i < dvobj->iface_nums; i++) {
1734 			iface = dvobj->padapters[i];
1735 			if (!iface)
1736 				continue;
1737 
1738 #ifdef CONFIG_IOCTL_CFG80211
1739 			if (iface->wdinfo.driver_interface == DRIVER_CFG80211 && !adapter_wdev_data(iface)->p2p_enabled)
1740 				continue;
1741 #endif
1742 
1743 			if (rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_LISTEN)) {
1744 				cur_channel = iface->wdinfo.listen_channel;
1745 				cur_bwmode = CHANNEL_WIDTH_20;
1746 				cur_ch_offset = CHAN_OFFSET_NO_EXT;
1747 				if (0)
1748 					RTW_INFO(FUNC_ADPT_FMT" back to "ADPT_FMT"'s listen ch - ch:%u, bw:%u, offset:%u\n",
1749 						FUNC_ADPT_ARG(padapter), ADPT_ARG(iface), cur_channel, cur_bwmode, cur_ch_offset);
1750 				break;
1751 			}
1752 		}
1753 #endif /* CONFIG_P2P */
1754 
1755 		if (cur_channel == 0) {
1756 			cur_channel = pmlmeext->chandef.chan;
1757 			cur_bwmode = pmlmeext->chandef.bw;
1758 			cur_ch_offset = pmlmeext->chandef.offset;
1759 			if (0)
1760 				RTW_INFO(FUNC_ADPT_FMT" back to ch:%u, bw:%u, offset:%u\n",
1761 					FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
1762 		}
1763 	}
1764 	set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode, _FALSE);
1765 }
1766 
1767 void sitesurvey_set_igi(_adapter *adapter)
1768 {
1769 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
1770 	struct ss_res *ss = &mlmeext->sitesurvey_res;
1771 	u8 igi;
1772 #ifdef CONFIG_P2P
1773 	struct wifidirect_info *pwdinfo = &adapter->wdinfo;
1774 #endif
1775 
1776 	switch (mlmeext_scan_state(mlmeext)) {
1777 	case SCAN_ENTER:
1778 		#ifdef CONFIG_P2P
1779 		#ifdef CONFIG_IOCTL_CFG80211
1780 		if (pwdinfo->driver_interface == DRIVER_CFG80211 && rtw_cfg80211_is_p2p_scan(adapter))
1781 			igi = 0x30;
1782 		else
1783 		#endif /* CONFIG_IOCTL_CFG80211 */
1784 		if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1785 			igi = 0x28;
1786 		else
1787 		#endif /* CONFIG_P2P */
1788 
1789 		if (ss->igi)
1790 			igi = ss->igi;
1791 		else
1792 		#if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
1793 		if (IS_ACS_ENABLE(adapter) && rtw_is_acs_igi_valid(adapter))
1794 			igi = rtw_acs_get_adv_igi(adapter);
1795 		else
1796 		#endif /*CONFIG_RTW_ACS*/
1797 			igi = 0x1e;
1798 
1799 		/* record IGI status */
1800 		ss->igi_scan = igi;
1801 		rtw_hal_get_phydm_var(adapter, HAL_PHYDM_IGI, &ss->igi_before_scan, NULL);
1802 
1803 		/* disable DIG and set IGI for scan */
1804 		rtw_hal_set_phydm_var(adapter, HAL_PHYDM_IGI, &igi, _FALSE);
1805 		break;
1806 	case SCAN_COMPLETE:
1807 	case SCAN_TO_P2P_LISTEN:
1808 		/* enable DIG and restore IGI */
1809 		igi = 0xff;
1810 		rtw_hal_set_phydm_var(adapter, HAL_PHYDM_IGI, &igi, _FALSE);
1811 		break;
1812 #ifdef CONFIG_SCAN_BACKOP
1813 	case SCAN_BACKING_OP:
1814 		/* write IGI for op channel when DIG is not enabled */
1815 		rtw_hal_set_phydm_var(adapter, HAL_PHYDM_IGI_W, &ss->igi_before_scan, _FALSE);
1816 		break;
1817 	case SCAN_LEAVE_OP:
1818 		/* write IGI for scan when DIG is not enabled */
1819 		rtw_hal_set_phydm_var(adapter, HAL_PHYDM_IGI_W, &ss->igi_scan, _FALSE);
1820 		break;
1821 #endif /* CONFIG_SCAN_BACKOP */
1822 	default:
1823 		rtw_warn_on(1);
1824 		break;
1825 	}
1826 }
1827 void sitesurvey_set_msr(_adapter *adapter, bool enter)
1828 {
1829 	u8 network_type;
1830 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
1831 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1832 
1833 	if (enter) {
1834 		/* set MSR to no link state */
1835 		network_type = _HW_STATE_NOLINK_;
1836 	} else {
1837 		network_type = pmlmeinfo->state & 0x3;
1838 	}
1839 }
1840 
1841 u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
1842 {
1843 	struct sitesurvey_parm	*pparm = (struct sitesurvey_parm *)pbuf;
1844 #ifdef DBG_CHECK_FW_PS_STATE
1845 	struct dvobj_priv *dvobj = padapter->dvobj;
1846 	struct debug_priv *pdbgpriv = &dvobj->drv_dbg;
1847 #endif
1848 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1849 	struct ss_res *ss = &pmlmeext->sitesurvey_res;
1850 #ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
1851 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
1852 #endif
1853 	u8 val8;
1854 
1855 #ifdef CONFIG_P2P
1856 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1857 #endif
1858 
1859 #ifdef DBG_CHECK_FW_PS_STATE
1860 	if (rtw_fw_ps_state(padapter) == _FAIL) {
1861 		RTW_INFO("scan without leave 32k\n");
1862 		pdbgpriv->dbg_scan_pwr_state_cnt++;
1863 	}
1864 #endif /* DBG_CHECK_FW_PS_STATE */
1865 
1866 	/* increase channel idx */
1867 	if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS))
1868 		ss->channel_idx++;
1869 
1870 	/* update scan state to next state (assigned by previous cmd hdl) */
1871 	if (mlmeext_scan_state(pmlmeext) != mlmeext_scan_next_state(pmlmeext))
1872 		mlmeext_set_scan_state(pmlmeext, mlmeext_scan_next_state(pmlmeext));
1873 
1874 operation_by_state:
1875 	switch (mlmeext_scan_state(pmlmeext)) {
1876 
1877 	case SCAN_DISABLE:
1878 		/*
1879 		* SW parameter initialization
1880 		*/
1881 
1882 		sitesurvey_res_reset(padapter, pparm);
1883 		mlmeext_set_scan_state(pmlmeext, SCAN_START);
1884 		goto operation_by_state;
1885 
1886 	case SCAN_START:
1887 #ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
1888 		if ((pwdev_priv->pno_mac_addr[0] != 0xFF)
1889 			    && (MLME_IS_STA(padapter))
1890 	    	    && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _FALSE)) {
1891 			u16 seq_num;
1892 
1893 			rtw_hal_pno_random_gen_mac_addr(padapter);
1894 			rtw_hal_set_hw_mac_addr(padapter, pwdev_priv->pno_mac_addr);
1895 			get_random_bytes(&seq_num, 2);
1896 			pwdev_priv->pno_scan_seq_num = seq_num & 0xFFF;
1897 			RTW_INFO("%s pno_scan_seq_num %d\n", __func__,
1898 				 pwdev_priv->pno_scan_seq_num);
1899 		}
1900 #endif
1901 
1902 		/*
1903 		* prepare to leave operating channel
1904 		*/
1905 
1906 		/* apply rx ampdu setting */
1907 		if (ss->rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
1908 			|| ss->rx_ampdu_size != RX_AMPDU_SIZE_INVALID)
1909 			rtw_rx_ampdu_apply(padapter);
1910 
1911 		/* clear HW TX queue before scan */
1912 		rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
1913 
1914 		rtw_hal_macid_sleep_all_used(padapter);
1915 
1916 		/* power save state announcement */
1917 		if (rtw_ps_annc(padapter, 1)) {
1918 			mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
1919 			mlmeext_set_scan_next_state(pmlmeext, SCAN_ENTER);
1920 			set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
1921 		} else {
1922 			mlmeext_set_scan_state(pmlmeext, SCAN_ENTER);
1923 			goto operation_by_state;
1924 		}
1925 
1926 		break;
1927 
1928 	case SCAN_ENTER:
1929 		/*
1930 		* HW register and DM setting for enter scan
1931 		*/
1932 
1933 		rtw_phydm_ability_backup(padapter);
1934 
1935 		sitesurvey_set_igi(padapter);
1936 
1937 		/* config dynamic functions for off channel */
1938 		rtw_phydm_func_for_offchannel(padapter);
1939 		/* set network type to no link state */
1940 		sitesurvey_set_msr(padapter, _TRUE);
1941 
1942 		val8 = 1; /* under site survey */
1943 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
1944 
1945 		mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
1946 		goto operation_by_state;
1947 
1948 	case SCAN_PROCESS: {
1949 		u8 scan_ch;
1950 		enum rtw_phl_scan_type stype;
1951 		u8 next_state;
1952 		u32 scan_ms;
1953 
1954 #ifdef CONFIG_RTW_ACS
1955 		if (IS_ACS_ENABLE(padapter))
1956 			rtw_acs_get_rst(padapter);
1957 #endif
1958 
1959 		next_state = sitesurvey_pick_ch_behavior(padapter, &scan_ch, &stype);
1960 
1961 		if (next_state != SCAN_PROCESS) {
1962 			mlmeext_set_scan_state(pmlmeext, next_state);
1963 			goto operation_by_state;
1964 		}
1965 
1966 		/* still SCAN_PROCESS state */
1967 		#ifdef DBG_SITESURVEY
1968 			#ifdef CONFIG_P2P
1969 			RTW_INFO(FUNC_ADPT_FMT" %s ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c%c\n"
1970 				, FUNC_ADPT_ARG(padapter)
1971 				, mlmeext_scan_state_str(pmlmeext)
1972 				, scan_ch
1973 				, pwdinfo->find_phase_state_exchange_cnt, ss->channel_idx
1974 				, rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
1975 				, stype ? 'A' : 'P', ss->scan_mode ? 'A' : 'P'
1976 				, ss->ssid[0].SsidLength ? 'S' : ' '
1977 				, ss->force_ssid_scan ? 'F' : ' '
1978 			);
1979 			#else
1980 			RTW_INFO(FUNC_ADPT_FMT" %s ch:%u (idx:%d) at %dms, %c%c%c%c\n"
1981 				, FUNC_ADPT_ARG(padapter)
1982 				, mlmeext_scan_state_str(pmlmeext)
1983 				, scan_ch
1984 				, ss->channel_idx
1985 				, rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
1986 				, stype ? 'A' : 'P', ss->scan_mode ? 'A' : 'P'
1987 				, ss->ssid[0].SsidLength ? 'S' : ' '
1988 				, ss->force_ssid_scan ? 'F' : ' '
1989 			);
1990 			#endif /* CONFIG_P2P */
1991 		#endif /*DBG_SITESURVEY*/
1992 #ifdef DBG_FIXED_CHAN
1993 		if (pmlmeext->fixed_chan != 0xff)
1994 			RTW_INFO(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
1995 #endif
1996 
1997 		site_survey(padapter, scan_ch, stype);
1998 
1999 #if defined(CONFIG_ATMEL_RC_PATCH)
2000 		if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
2001 			scan_ms = 20;
2002 		else
2003 			scan_ms = 40;
2004 #else
2005 		#if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
2006 		if (IS_ACS_ENABLE(padapter) && rtw_is_acs_st_valid(padapter))
2007 			scan_ms = rtw_acs_get_adv_st(padapter);
2008 		else
2009 		#endif /*CONFIG_RTW_ACS*/
2010 			scan_ms = ss->scan_ch_ms;
2011 #endif
2012 
2013 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
2014 		if (ss->is_sw_antdiv_bl_scan)
2015 			scan_ms = scan_ms / 2;
2016 #endif
2017 
2018 #ifdef CONFIG_RTW_ACS
2019 		if (IS_ACS_ENABLE(padapter)) {
2020 			if (pparm->token)
2021 				rtw_acs_trigger(padapter, scan_ms, scan_ch, NHM_PID_IEEE_11K_HIGH);
2022 			else
2023 				rtw_acs_trigger(padapter, scan_ms, scan_ch, NHM_PID_ACS);
2024 		}
2025 #endif
2026 
2027 		set_survey_timer(pmlmeext, scan_ms);
2028 		break;
2029 	}
2030 
2031 #ifdef CONFIG_SCAN_BACKOP
2032 	case SCAN_BACKING_OP: {
2033 		u8 back_ch, back_bw, back_ch_offset;
2034 		u8 need_ch_setting_union = _TRUE;
2035 
2036 		if (need_ch_setting_union) {
2037 			if (rtw_mi_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0) {
2038 				rtw_warn_on(1);
2039 				back_ch = pmlmeext->chandef.chan;
2040 				back_bw = pmlmeext->chandef.bw;
2041 				back_ch_offset = pmlmeext->chandef.offset;
2042 			}
2043 		}
2044 
2045 		#ifdef DBG_SITESURVEY
2046 			RTW_INFO(FUNC_ADPT_FMT" %s ch:%u, bw:%u, offset:%u at %dms\n"
2047 				 , FUNC_ADPT_ARG(padapter)
2048 				 , mlmeext_scan_state_str(pmlmeext)
2049 				 , back_ch, back_bw, back_ch_offset
2050 				, rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
2051 				);
2052 		#endif /*DBG_SITESURVEY*/
2053 		set_channel_bwmode(padapter, back_ch, back_ch_offset, back_bw, _FALSE);
2054 
2055 		sitesurvey_set_msr(padapter, _FALSE);
2056 
2057 		val8 = 0; /* survey done */
2058 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
2059 
2060 		if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
2061 			sitesurvey_set_igi(padapter);
2062 			rtw_hal_macid_wakeup_all_used(padapter);
2063 			rtw_ps_annc(padapter, 0);
2064 		}
2065 
2066 		mlmeext_set_scan_state(pmlmeext, SCAN_BACK_OP);
2067 		ss->backop_time = rtw_get_current_time();
2068 
2069 		if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_TX_RESUME))
2070 			rtw_mi_os_xmit_schedule(padapter);
2071 
2072 		goto operation_by_state;
2073 	}
2074 
2075 	case SCAN_BACK_OP:
2076 		if (rtw_get_passing_time_ms(ss->backop_time) >= ss->backop_ms
2077 		    || pmlmeext->scan_abort
2078 		   ) {
2079 			mlmeext_set_scan_state(pmlmeext, SCAN_LEAVING_OP);
2080 			goto operation_by_state;
2081 		}
2082 		set_survey_timer(pmlmeext, 50);
2083 		break;
2084 
2085 	case SCAN_LEAVING_OP:
2086 		/*
2087 		 * prepare to leave operating channel
2088 		 */
2089 
2090 		/* clear HW TX queue before scan */
2091 		rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
2092 
2093 		rtw_hal_macid_sleep_all_used(padapter);
2094 		if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)
2095 			&& rtw_ps_annc(padapter, 1)
2096 		) {
2097 			mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
2098 			mlmeext_set_scan_next_state(pmlmeext, SCAN_LEAVE_OP);
2099 			set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
2100 		} else {
2101 			mlmeext_set_scan_state(pmlmeext, SCAN_LEAVE_OP);
2102 			goto operation_by_state;
2103 		}
2104 
2105 		break;
2106 
2107 	case SCAN_LEAVE_OP:
2108 		/*
2109 		* HW register and DM setting for enter scan
2110 		*/
2111 
2112 		if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC))
2113 			sitesurvey_set_igi(padapter);
2114 
2115 		sitesurvey_set_msr(padapter, _TRUE);
2116 
2117 		val8 = 1; /* under site survey */
2118 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
2119 
2120 		mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
2121 		goto operation_by_state;
2122 
2123 #endif /* CONFIG_SCAN_BACKOP */
2124 
2125 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
2126 	case SCAN_SW_ANTDIV_BL:
2127 		/*
2128 		* 20100721
2129 		* For SW antenna diversity before link, it needs to switch to another antenna and scan again.
2130 		* It compares the scan result and select better one to do connection.
2131 		*/
2132 		ss->bss_cnt = 0;
2133 		ss->channel_idx = 0;
2134 		ss->is_sw_antdiv_bl_scan = 1;
2135 
2136 		mlmeext_set_scan_next_state(pmlmeext, SCAN_PROCESS);
2137 		set_survey_timer(pmlmeext, ss->scan_ch_ms);
2138 		break;
2139 #endif
2140 
2141 #ifdef CONFIG_P2P
2142 	case SCAN_TO_P2P_LISTEN:
2143 		/*
2144 		* Set the P2P State to the listen state of find phase
2145 		* and set the current channel to the listen channel
2146 		*/
2147 		set_channel_bwmode(padapter,
2148 				pwdinfo->listen_channel,
2149 				CHAN_OFFSET_NO_EXT,
2150 				CHANNEL_WIDTH_20,
2151 				_FALSE);
2152 		rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
2153 
2154 		/* turn on phy-dynamic functions */
2155 		rtw_phydm_ability_restore(padapter);
2156 
2157 		sitesurvey_set_igi(padapter);
2158 
2159 		mlmeext_set_scan_state(pmlmeext, SCAN_P2P_LISTEN);
2160 		_set_timer(&pwdinfo->find_phase_timer, (u32)((u32)pwdinfo->listen_dwell * 100));
2161 		break;
2162 
2163 	case SCAN_P2P_LISTEN:
2164 		mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
2165 		ss->channel_idx = 0;
2166 		goto operation_by_state;
2167 #endif /* CONFIG_P2P */
2168 
2169 	case SCAN_COMPLETE:
2170 #ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
2171 		rtw_hal_set_hw_mac_addr(padapter, adapter_mac_addr(padapter));
2172 #endif
2173 #ifdef CONFIG_P2P
2174 		if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
2175 		    || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
2176 		   ) {
2177 #ifdef CONFIG_CONCURRENT_MODE
2178 			if (pwdinfo->driver_interface == DRIVER_WEXT) {
2179 				if (rtw_mi_check_status(padapter, MI_LINKED))
2180 					_set_timer(&pwdinfo->ap_p2p_switch_timer, 500);
2181 			}
2182 #endif
2183 
2184 			rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
2185 		}
2186 		rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
2187 #endif /* CONFIG_P2P */
2188 
2189 		/* switch channel */
2190 		survey_done_set_ch_bw(padapter);
2191 
2192 		sitesurvey_set_msr(padapter, _FALSE);
2193 
2194 		val8 = 0; /* survey done */
2195 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
2196 
2197 		/* turn on phy-dynamic functions */
2198 		rtw_phydm_ability_restore(padapter);
2199 
2200 		sitesurvey_set_igi(padapter);
2201 		rtw_hal_macid_wakeup_all_used(padapter);
2202 		rtw_ps_annc(padapter, 0);
2203 
2204 		/* apply rx ampdu setting */
2205 		rtw_rx_ampdu_apply(padapter);
2206 
2207 		mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
2208 
2209 		report_surveydone_event(padapter, ss->acs);
2210 #ifdef CONFIG_RTW_ACS
2211 		if (IS_ACS_ENABLE(padapter))
2212 			rtw_acs_select_best_chan(padapter);
2213 #endif
2214 
2215 		issue_action_BSSCoexistPacket(padapter);
2216 		issue_action_BSSCoexistPacket(padapter);
2217 		issue_action_BSSCoexistPacket(padapter);
2218 
2219 #ifdef CONFIG_RTW_80211K
2220 		if (ss->token)
2221 			rm_post_event(padapter, ss->token, RM_EV_survey_done);
2222 #endif /* CONFIG_RTW_80211K */
2223 
2224 		break;
2225 	}
2226 
2227 	return H2C_SUCCESS;
2228 }
2229 #else
sitesurvey_cmd_hdl(_adapter * padapter,u8 * pbuf)2230 u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
2231 {
2232 	RTW_ERR("%s executed??\n", __func__);
2233 	rtw_warn_on(1);
2234 	return 0;
2235 }
rtw_survey_cmd_callback(_adapter * padapter,struct cmd_obj * pcmd)2236 void rtw_survey_cmd_callback(_adapter  *padapter, struct cmd_obj *pcmd)
2237 {
2238 	RTW_ERR("%s executed??\n", __func__);
2239 	rtw_warn_on(1);
2240 }
2241 
2242 /* remain on channel priv */
2243 #define ROCH_CH_READY	0x1
2244 
2245 struct scan_priv {
2246 	_adapter *padapter;
2247 
2248 	/* for remain on channel callback */
2249 	struct wireless_dev *wdev;
2250 	struct ieee80211_channel channel;
2251 	u8 channel_type;
2252 	unsigned int duration;
2253 	u64 cookie;
2254 
2255 	u8 restore_ch;
2256 
2257 	u8 roch_step;
2258 #ifdef CONFIG_RTW_80211K
2259 	u32 rrm_token;	/* 80211k use it to identify caller */
2260 #endif
2261 };
2262 
2263 #ifdef CONFIG_CMD_SCAN
_alloc_phl_param(_adapter * adapter,u8 scan_ch_num)2264 static struct rtw_phl_scan_param *_alloc_phl_param(_adapter *adapter, u8 scan_ch_num)
2265 {
2266 	struct rtw_phl_scan_param *phl_param = NULL;
2267 	struct scan_priv *scan_priv = NULL;
2268 
2269 	if (scan_ch_num == 0) {
2270 		RTW_ERR("%s scan_ch_num = 0\n", __func__);
2271 		goto _err_exit;
2272 	}
2273 	/*create mem of PHL Scan parameter*/
2274 	phl_param = rtw_zmalloc(sizeof(*phl_param));
2275 	if (phl_param == NULL) {
2276 		RTW_ERR("%s alloc phl_param fail\n", __func__);
2277 		goto _err_exit;
2278 	}
2279 
2280 	scan_priv = rtw_zmalloc(sizeof(*scan_priv));
2281 	if (scan_priv == NULL) {
2282 		RTW_ERR("%s alloc scan_priv fail\n", __func__);
2283 		goto _err_scanpriv;
2284 	}
2285 	scan_priv->padapter = adapter;
2286 	phl_param->priv = scan_priv;
2287 	phl_param->wifi_role = adapter->phl_role;
2288 	phl_param->back_op_mode = SCAN_BKOP_NONE;
2289 
2290 	phl_param->ch_sz = sizeof(struct phl_scan_channel) * (scan_ch_num + 1);
2291 	phl_param->ch = rtw_zmalloc(phl_param->ch_sz);
2292 	if (phl_param->ch == NULL) {
2293 		RTW_ERR("%s: alloc phl scan ch fail\n", __func__);
2294 		goto _err_param_ch;
2295 	}
2296 
2297 	return phl_param;
2298 
2299 _err_param_ch:
2300 	if (scan_priv)
2301 		rtw_mfree(scan_priv, sizeof(*scan_priv));
2302 _err_scanpriv:
2303 	if (phl_param)
2304 		rtw_mfree(phl_param, sizeof(*phl_param));
2305 _err_exit:
2306 	rtw_warn_on(1);
2307 	return phl_param;
2308 }
2309 
_free_phl_param(_adapter * adapter,struct rtw_phl_scan_param * phl_param)2310 static u8 _free_phl_param(_adapter *adapter, struct rtw_phl_scan_param *phl_param)
2311 {
2312 	u8 res = _FAIL;
2313 
2314 	if (!phl_param)
2315 		return res;
2316 
2317 	if (phl_param->ch)
2318 		rtw_mfree(phl_param->ch, phl_param->ch_sz);
2319 	if (phl_param->priv)
2320 		rtw_mfree(phl_param->priv, sizeof(struct scan_priv));
2321 	rtw_mfree(phl_param, sizeof(struct rtw_phl_scan_param));
2322 
2323 	res = _SUCCESS;
2324 	return res;
2325 }
2326 #endif /*CONFIG_CMD_SCAN*/
scan_issue_pbreq_cb(void * priv,struct rtw_phl_scan_param * param)2327 static int scan_issue_pbreq_cb(void *priv, struct rtw_phl_scan_param *param)
2328 {
2329 	struct scan_priv *scan_priv = (struct scan_priv *)priv;
2330 	_adapter *padapter = scan_priv->padapter;
2331 	NDIS_802_11_SSID ssid;
2332 	int i;
2333 
2334 
2335 	/* active scan behavior */
2336 	if (padapter->registrypriv.wifi_spec)
2337 		issue_probereq(padapter, NULL, NULL);
2338 	else
2339 		issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
2340 
2341 	issue_probereq(padapter, NULL, NULL);
2342 
2343 	for (i = 0; i < param->ssid_num; i++) {
2344 		if (param->ssid[i].ssid_len == 0)
2345 			continue;
2346 
2347 		ssid.SsidLength = param->ssid[i].ssid_len;
2348 		_rtw_memcpy(ssid.Ssid, &param->ssid[i].ssid, ssid.SsidLength);
2349 		/* IOT issue,
2350 		 * Send one probe req without WPS IE,
2351 		 * when not wifi_spec
2352 		 */
2353 		if (padapter->registrypriv.wifi_spec)
2354 			issue_probereq(padapter, &ssid, NULL);
2355 		else
2356 			issue_probereq_ex(padapter, &ssid, NULL, 0, 0, 0, 0);
2357 
2358 		issue_probereq(padapter, &ssid, NULL);
2359 	}
2360 	return 0;
2361 }
2362 
scan_complete_cb(void * priv,struct rtw_phl_scan_param * param)2363 static int scan_complete_cb(void *priv, struct rtw_phl_scan_param *param)
2364 {
2365 	struct scan_priv *scan_priv = (struct scan_priv *)priv;
2366 	_adapter *padapter = scan_priv->padapter;
2367 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
2368 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2369 	bool acs = _FALSE;
2370 	int ret = _FAIL;
2371 
2372 	if (!rtw_is_adapter_up(padapter))
2373 		goto _exit;
2374 
2375 	mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
2376 
2377 	report_surveydone_event(padapter, acs, RTW_CMDF_DIRECTLY);
2378 	ret = _SUCCESS;
2379 
2380 _exit:
2381 	RTW_INFO(FUNC_ADPT_FMT" takes %d ms to scan %d/%d channels\n",
2382 			FUNC_ADPT_ARG(padapter), param->total_scan_time,
2383 			#ifdef CONFIG_CMD_SCAN
2384 			param->ch_idx,
2385 			#else
2386 			param->ch_idx + 1,
2387 			#endif
2388 			param->ch_num);
2389 	_rtw_scan_abort_check(padapter, __func__);
2390 
2391 #ifdef CONFIG_CMD_SCAN
2392 	_free_phl_param(padapter, param);
2393 	pmlmeext->sitesurvey_res.scan_param = NULL;
2394 #else
2395 	rtw_mfree(scan_priv, sizeof(*scan_priv));
2396 #endif
2397 
2398 	return ret;
2399 }
2400 
scan_start_cb(void * priv,struct rtw_phl_scan_param * param)2401 static int scan_start_cb(void *priv, struct rtw_phl_scan_param *param)
2402 {
2403 	struct scan_priv *scan_priv = (struct scan_priv *)priv;
2404 	_adapter *padapter = scan_priv->padapter;
2405 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2406 
2407 	pmlmeext->sitesurvey_res.bss_cnt = 0;
2408 	pmlmeext->sitesurvey_res.activate_ch_cnt = 0;
2409 	//TODO remove
2410 	mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
2411 	#ifdef CONFIG_CMD_SCAN
2412 	pmlmeext->sitesurvey_res.scan_param = param;
2413 	#endif
2414 	return 0;
2415 }
2416 
2417 #ifdef CONFIG_P2P
scan_issue_p2p_pbreq_cb(void * priv,struct rtw_phl_scan_param * param)2418 static int scan_issue_p2p_pbreq_cb(void *priv, struct rtw_phl_scan_param *param)
2419 {
2420 	struct scan_priv *scan_priv = (struct scan_priv *)priv;
2421 	_adapter *padapter = scan_priv->padapter;
2422 
2423 	issue_probereq_p2p(padapter, NULL);
2424 	issue_probereq_p2p(padapter, NULL);
2425 	issue_probereq_p2p(padapter, NULL);
2426 	return 0;
2427 }
2428 #endif
2429 
scan_ch_ready_cb(void * priv,struct rtw_phl_scan_param * param)2430 static int scan_ch_ready_cb(void *priv, struct rtw_phl_scan_param *param)
2431 {
2432 	struct scan_priv *scan_priv = (struct scan_priv *)priv;
2433 	_adapter *padapter = scan_priv->padapter;
2434 
2435 	RTW_INFO("%s ch:%d\n", __func__, param->scan_ch->channel);
2436 	return 0;
2437 }
2438 
_ps_announce(_adapter * adapter,bool ps)2439 static inline void _ps_announce(_adapter *adapter, bool ps)
2440 {
2441 	RTW_INFO(FUNC_ADPT_FMT" issue_null(%d)\n", FUNC_ADPT_ARG(adapter), ps);
2442 	if (MLME_IS_STA(adapter)) {
2443 		if (is_client_associated_to_ap(adapter) == _TRUE) {
2444 			/*issue_nulldata(adapter, NULL, ps, 3, 500);*/
2445 			issue_nulldata(adapter, NULL, ps, 1, 0);
2446 		}
2447 	}
2448 	#ifdef CONFIG_RTW_MESH
2449 	else if (MLME_IS_MESH(adapter)) {
2450 		rtw_mesh_ps_annc(adapter, ps);
2451 	}
2452 	#endif
2453 }
2454 
scan_issu_null_data_cb(void * priv,u8 ridx,bool ps)2455 u8 scan_issu_null_data_cb(void *priv, u8 ridx, bool ps)
2456 {
2457 	#ifdef CONFIG_CMD_SCAN
2458 	struct dvobj_priv *obj = (struct dvobj_priv *)priv;
2459 	#else
2460 	struct scan_priv *scan_priv = (struct scan_priv *)priv;
2461 	_adapter *padapter = scan_priv->padapter;
2462 	struct dvobj_priv *obj = adapter_to_dvobj(padapter);
2463 	#endif
2464 	_adapter *iface = NULL;
2465 
2466 	if (ridx >= CONFIG_IFACE_NUMBER) {
2467 		RTW_ERR("%s ridx:%d invalid\n", __func__, ridx);
2468 		rtw_warn_on(1);
2469 		goto _error;
2470 	}
2471 
2472 	iface = obj->padapters[ridx];
2473 	if (!rtw_is_adapter_up(iface))
2474 		goto _error;
2475 
2476 	_ps_announce(iface, ps);
2477 
2478 	return _SUCCESS;
2479 _error:
2480 	return _FAIL;
2481 }
2482 
2483 static struct rtw_phl_scan_ops scan_ops_cb = {
2484 	.scan_start = scan_start_cb,
2485 	.scan_ch_ready = scan_ch_ready_cb,
2486 	.scan_complete = scan_complete_cb,
2487 	.scan_issue_pbreq = scan_issue_pbreq_cb,
2488 	.scan_issue_null_data = scan_issu_null_data_cb
2489 };
2490 
2491 #ifdef CONFIG_P2P
2492 static struct rtw_phl_scan_ops scan_ops_p2p_cb = {
2493 	.scan_start = scan_start_cb,
2494 	.scan_ch_ready = scan_ch_ready_cb,
2495 	.scan_complete = scan_complete_cb,
2496 	.scan_issue_pbreq = scan_issue_p2p_pbreq_cb,
2497 	.scan_issue_null_data = scan_issu_null_data_cb
2498 };
2499 #endif
2500 
2501 #ifdef CONFIG_RTW_80211K
scan_complete_rrm_cb(void * priv,struct rtw_phl_scan_param * param)2502 static int scan_complete_rrm_cb(void *priv, struct rtw_phl_scan_param *param)
2503 {
2504 	struct scan_priv *scan_priv = (struct scan_priv *)priv;
2505 	_adapter *padapter = scan_priv->padapter;
2506 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2507 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2508 	int ret = _FAIL;
2509 
2510 	if (!rtw_is_adapter_up(padapter))
2511 		goto _exit;
2512 
2513 	mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
2514 	_rtw_spinlock_bh(&pmlmepriv->lock);
2515 	_clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY);
2516 	_rtw_spinunlock_bh(&pmlmepriv->lock);
2517 
2518 	/* inform RRM scan complete */
2519 	rm_post_event(padapter, scan_priv->rrm_token, RM_EV_survey_done);
2520 	ret = _SUCCESS;
2521 
2522 _exit:
2523 	RTW_INFO(FUNC_ADPT_FMT" takes %d ms to scan %d/%d channels\n",
2524 		FUNC_ADPT_ARG(padapter), param->total_scan_time,
2525 		param->ch_idx + 1, param->ch_num);
2526 	_rtw_scan_abort_check(padapter, __func__);
2527 
2528 #ifdef CONFIG_CMD_SCAN
2529 	_free_phl_param(padapter, param);
2530 	pmlmeext->sitesurvey_res.scan_param = NULL;
2531 #else
2532 	rtw_mfree(scan_priv, sizeof(*scan_priv));
2533 #endif
2534 	return ret;
2535 }
2536 
2537 static struct rtw_phl_scan_ops scan_ops_rrm_cb = {
2538 	.scan_start = scan_start_cb,
2539 	.scan_ch_ready = scan_ch_ready_cb,
2540 	.scan_complete = scan_complete_rrm_cb,
2541 	.scan_issue_pbreq = scan_issue_pbreq_cb,
2542 	.scan_issue_null_data = scan_issu_null_data_cb
2543 };
2544 #endif /* CONFIG_RTW_80211K */
2545 
2546 #ifndef SCAN_PER_CH_EX_TIME
2547 #define SCAN_PER_CH_EX_TIME	40 /*8852bs sw ch ov*/
2548 #endif /*SCAN_PER_CH_EX_TIME*/
rtw_scan_timeout_decision(_adapter * padapter)2549 static u32 rtw_scan_timeout_decision(_adapter *padapter)
2550 {
2551 	u8 max_chan_num;
2552 	u8 issue_null_time;
2553 	u16 scan_ms;
2554 	u16 p_ch_ex_time;
2555 	u32 non_op_buf;
2556 	u32 back_op_times = 0;
2557 
2558 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2559 	struct ss_res *ss = &pmlmeext->sitesurvey_res;
2560 	#ifdef CONFIG_SCAN_BACKOP
2561 	u8 backop_cout = 0;
2562 	#endif /*CONFIG_SCAN_BACKOP*/
2563 
2564 	if (padapter->registrypriv.scan_pch_ex_time != 0)
2565 		p_ch_ex_time = padapter->registrypriv.scan_pch_ex_time;
2566 	else
2567 		p_ch_ex_time = SCAN_PER_CH_EX_TIME;
2568 
2569 	/*issue null time,null(0)+null(1),undefine flag phl sleep 50ms*/
2570 	issue_null_time = 10;
2571 	#ifndef RTW_WKARD_TX_NULL_WD_RP
2572 	issue_null_time += 50;
2573 	#endif /*RTW_WKARD_TX_NULL_WD_RP*/
2574 
2575 	if (is_supported_5g(padapter->registrypriv.band_type)
2576 		&& is_supported_24g(padapter->registrypriv.band_type))
2577 		max_chan_num = MAX_CHANNEL_NUM_2G_5G;/* dual band */
2578 	else
2579 		max_chan_num = MAX_CHANNEL_NUM_2G;/*single band*/
2580 
2581 	#ifdef CONFIG_SCAN_BACKOP
2582 	backop_cout = max_chan_num / ss->scan_cnt_max;
2583 	/* delay 50ms to protect nulldata(1) */
2584 	if (rtw_scan_backop_decision(padapter))
2585 		back_op_times = backop_cout * (ss->backop_ms + p_ch_ex_time + issue_null_time);
2586 	#endif
2587 
2588 	if (ss->duration)
2589 		scan_ms = ss->duration;
2590 	else
2591 	#if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
2592 	if (IS_ACS_ENABLE(padapter) && rtw_is_acs_st_valid(padapter))
2593 		scan_ms = rtw_acs_get_adv_st(padapter);
2594 	else
2595 	#endif /*CONFIG_RTW_ACS*/
2596 		scan_ms = ss->scan_ch_ms;
2597 
2598 	/*non op channel buffer time + scan start/done issue null*/
2599 	non_op_buf = max_chan_num * p_ch_ex_time + issue_null_time;
2600 
2601 	ss->scan_timeout_ms = (scan_ms * max_chan_num) + back_op_times + non_op_buf;
2602 	#ifdef DBG_SITESURVEY
2603 	RTW_INFO("%s, max_chan_num(%d), p_ch_ex_time(%d), \
2604 		 ss->scan_cnt_max=%d issue_null_time=%d\n" \
2605 		 , __func__, max_chan_num, p_ch_ex_time,
2606 		 ss->scan_cnt_max, issue_null_time);
2607 	RTW_INFO("%s , scan_timeout_ms = %d (ms), scan_ms=%d (ms), \
2608 		back_op_times=%d (ms), ss->duration=%d (ms)\n" \
2609 		, __func__, ss->scan_timeout_ms, scan_ms, back_op_times, ss->duration);
2610 	#endif /*DBG_SITESURVEY*/
2611 
2612 	return ss->scan_timeout_ms;
2613 }
2614 
2615 /*
2616 rtw_sitesurvey_cmd(~)
2617 	### NOTE:#### (!!!!)
2618 	MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock
2619 */
2620 #ifdef CONFIG_CMD_SCAN
scan_channel_list_filled(_adapter * padapter,struct rtw_phl_scan_param * phl_param,struct sitesurvey_parm * param)2621 static void scan_channel_list_filled(_adapter *padapter,
2622 	struct rtw_phl_scan_param *phl_param, struct sitesurvey_parm *param)
2623 {
2624 	struct phl_scan_channel *phl_ch = phl_param->ch;
2625 	u8 i = 0;
2626 
2627 	for (i = 0; i < param->ch_num; i++) {
2628 		phl_ch[i].channel = param->ch[i].hw_value;
2629 		phl_ch[i].scan_mode = NORMAL_SCAN_MODE;
2630 		phl_ch[i].bw = param->bw;
2631 		phl_ch[i].duration = param->duration;
2632 
2633 		if (param->ch[i].flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN)
2634 			phl_ch[i].type = RTW_PHL_SCAN_PASSIVE;
2635 		else
2636 			phl_ch[i].type = RTW_PHL_SCAN_ACTIVE;
2637 	}
2638 	phl_param->ch_num = param->ch_num;
2639 }
2640 
2641 #ifdef RTW_WKARD_CMD_SCAN_EXTEND_ACTIVE_SCAN
2642 /*
2643  * Count extended active scan time(ms) and add time to
2644  * struct mlme_ext_priv.sitesurvey_res.scan_timeout_ms.
2645  *
2646  * Return extended active scan time which unit is ms.
2647  */
_scan_ext_act_time_count(struct _ADAPTER * a,struct rtw_phl_scan_param * scan)2648 static u32 _scan_ext_act_time_count(struct _ADAPTER *a,
2649 				    struct rtw_phl_scan_param *scan)
2650 {
2651 	struct ss_res *ss = &a->mlmeextpriv.sitesurvey_res;
2652 	u16 ext_time = 0;
2653 	int i;
2654 
2655 
2656 	for (i = 0; i < scan->ch_num; i++) {
2657 		if (scan->ch[i].ext_act_scan == EXT_ACT_SCAN_ENABLE)
2658 			ext_time += scan->ext_act_scan_period;
2659 	}
2660 #ifdef DBG_SITESURVEY
2661 	RTW_PRINT(FUNC_ADPT_FMT ": Add extend active scan time %u ms to total "
2662 		  "scan time (from %u to %u)\n",
2663 		  FUNC_ADPT_ARG(a), ext_time, ss->scan_timeout_ms,
2664 		  ext_time + ss->scan_timeout_ms);
2665 #endif /* DBG_SITESURVEY */
2666 	ss->scan_timeout_ms += ext_time;
2667 
2668 	return ext_time;
2669 }
2670 #endif /* RTW_WKARD_CMD_SCAN_EXTEND_ACTIVE_SCAN */
2671 
rtw_sitesurvey_cmd(_adapter * padapter,struct sitesurvey_parm * pparm)2672 u8 rtw_sitesurvey_cmd(_adapter *padapter, struct sitesurvey_parm *pparm)
2673 {
2674 	u8 res = _FAIL;
2675 	u8 i;
2676 	u32 scan_timeout_ms;
2677 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2678 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2679 	struct rtw_phl_scan_param *phl_param = NULL;
2680 	struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT] = {0};
2681 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
2682 	struct sitesurvey_parm *tmp_parm = NULL;
2683 	struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
2684 	struct ss_res *ss = &mlmeext->sitesurvey_res;
2685 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
2686 #ifdef CONFIG_RTW_80211K
2687 	struct scan_priv *scan_priv = NULL;
2688 #endif
2689 
2690 	if (pparm == NULL) {
2691 		tmp_parm = rtw_zmalloc(sizeof(struct sitesurvey_parm));
2692 		if (tmp_parm == NULL) {
2693 			RTW_ERR("%s alloc tmp_parm fail\n", __func__);
2694 			goto _err_exit;
2695 		}
2696 		rtw_init_sitesurvey_parm(padapter, tmp_parm);
2697 		pparm = tmp_parm;
2698 	}
2699 
2700 	/* backup original ch list */
2701 	_rtw_memcpy(ch, pparm->ch,
2702 		sizeof(struct rtw_ieee80211_channel) * pparm->ch_num);
2703 
2704 	/* modify ch list according to chanel plan */
2705 	pparm->ch_num = rtw_scan_ch_decision(padapter,
2706 					pparm->ch, RTW_CHANNEL_SCAN_AMOUNT,
2707 					ch, pparm->ch_num, pparm->acs);
2708 
2709 	if (pparm->duration == 0)
2710 		pparm->duration = ss->scan_ch_ms; /* ms */
2711 
2712 	/*create mem of PHL Scan parameter*/
2713 	phl_param = _alloc_phl_param(padapter, pparm->ch_num);
2714 	if (phl_param == NULL) {
2715 		RTW_ERR("%s alloc phl_param fail\n", __func__);
2716 		goto _err_param;
2717 	}
2718 
2719 	/* STEP_1 transfer to rtw channel list to phl channel list */
2720 	scan_channel_list_filled(padapter, phl_param, pparm);
2721 
2722 	/* STEP_2 copy the ssid info to phl param */
2723 	phl_param->ssid_num = rtw_min(pparm->ssid_num, SCAN_SSID_AMOUNT);
2724 	for (i = 0; i < phl_param->ssid_num; ++i) {
2725 		phl_param->ssid[i].ssid_len = pparm->ssid[i].SsidLength;
2726 		_rtw_memcpy(&phl_param->ssid[i].ssid, &pparm->ssid[i].Ssid, phl_param->ssid[i].ssid_len);
2727 	}
2728 #ifdef RTW_WKARD_CMD_SCAN_EXTEND_ACTIVE_SCAN
2729 	/* STEP_2.1 set EXT_ACT_SCAN_ENABLE for hidden AP scan */
2730 	if (phl_param->ssid[0].ssid_len) {
2731 		phl_param->ext_act_scan_period = RTW_EXTEND_ACTIVE_SCAN_PERIOD;
2732 		for (i = 0; i < phl_param->ch_num; i++) {
2733 			int chset_idx;
2734 			chset_idx = rtw_chset_search_ch(rfctl->channel_set,
2735 							phl_param->ch[i].channel);
2736 			if (chset_idx < 0) {
2737 				RTW_ERR(FUNC_ADPT_FMT ": cann't find ch %u in chset!\n",
2738 					FUNC_ADPT_ARG(padapter), phl_param->ch[i].channel);
2739 				continue;
2740 			}
2741 
2742 			if ((phl_param->ch[i].type == RTW_PHL_SCAN_PASSIVE)
2743 			    && (!IS_DFS_SLAVE_WITH_RD(rfctl)
2744 				|| rtw_rfctl_dfs_domain_unknown(rfctl)
2745 				|| !CH_IS_NON_OCP(&rfctl->channel_set[chset_idx])))
2746 				phl_param->ch[i].ext_act_scan = EXT_ACT_SCAN_ENABLE;
2747 		}
2748 	}
2749 #endif /* RTW_WKARD_CMD_SCAN_EXTEND_ACTIVE_SCAN */
2750 
2751 	/* STEP_3 set ops according to scan_type */
2752 	switch (pparm->scan_type) {
2753 	#ifdef CONFIG_P2P
2754 	case RTW_SCAN_P2P:
2755 		phl_param->ops = &scan_ops_p2p_cb;
2756 	break;
2757 	#endif
2758 
2759 	#ifdef CONFIG_RTW_80211K
2760 	case RTW_SCAN_RRM:
2761 		phl_param->ops = &scan_ops_rrm_cb;
2762 		scan_priv = (struct scan_priv *)phl_param->priv;
2763 		scan_priv->rrm_token = pparm->rrm_token;
2764 		ss->token = pparm->rrm_token;
2765 	break;
2766 	#endif
2767 
2768 	case RTW_SCAN_NORMAL:
2769 	default:
2770 		phl_param->ops = &scan_ops_cb;
2771 #ifdef CONFIG_SCAN_BACKOP
2772 		if (rtw_scan_backop_decision(padapter)) {
2773 			phl_param->back_op_ch_dur_ms = ss->backop_ms;
2774 			phl_param->back_op_mode = SCAN_BKOP_CNT;
2775 			phl_param->back_op_ch_cnt = ss->scan_cnt_max;
2776 		} else {
2777 			phl_param->back_op_mode = SCAN_BKOP_NONE;
2778 		}
2779 #else
2780 		phl_param->back_op_mode = SCAN_BKOP_NONE;
2781 #endif /* CONFIG_SCAN_BACKOP */
2782 	break;
2783 	}
2784 
2785 	/* STEP_4 reset variables for each scan */
2786 	for (i = 0; i < MAX_CHANNEL_NUM; i++)
2787 		rfctl->channel_set[i].hidden_bss_cnt = 0;
2788 
2789 	set_fwstate(pmlmepriv, WIFI_UNDER_SURVEY);
2790 
2791 	if(rtw_phl_cmd_scan_request(dvobj->phl, phl_param, true) != RTW_PHL_STATUS_SUCCESS) {
2792 		RTW_ERR("%s request scam_cmd failed\n", __func__);
2793 		_clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY);
2794 		goto _err_req_param;
2795 	}
2796 
2797 	pmlmeext->sitesurvey_res.scan_param = phl_param;
2798 	rtw_free_network_queue(padapter, _FALSE);
2799 
2800 	pmlmepriv->scan_start_time = rtw_get_current_time();
2801 	scan_timeout_ms = rtw_scan_timeout_decision(padapter);
2802 #ifdef RTW_WKARD_CMD_SCAN_EXTEND_ACTIVE_SCAN
2803 	scan_timeout_ms += _scan_ext_act_time_count(padapter, phl_param);
2804 #endif /* RTW_WKARD_CMD_SCAN_EXTEND_ACTIVE_SCAN */
2805 	mlme_set_scan_to_timer(pmlmepriv,scan_timeout_ms);
2806 
2807 	rtw_led_control(padapter, LED_CTL_SITE_SURVEY);
2808 	if (tmp_parm)
2809 		rtw_mfree(tmp_parm, sizeof(*tmp_parm));
2810 	res = _SUCCESS;
2811 	return res;
2812 
2813 _err_req_param:
2814 	_free_phl_param(padapter, phl_param);
2815 _err_param:
2816 	if (tmp_parm)
2817 		rtw_mfree(tmp_parm, sizeof(*tmp_parm));
2818 _err_exit:
2819 	rtw_warn_on(1);
2820 	return res;
2821 }
2822 
2823 #else /*!CONFIG_CMD_SCAN*/
2824 
2825 /**
2826  * prepare phl_channel list according to SCAN type
2827  *
2828  */
scan_channel_list_preparation(_adapter * padapter,struct rtw_phl_scan_param * dst,struct sitesurvey_parm * src)2829 static int scan_channel_list_preparation(_adapter *padapter,
2830 	struct rtw_phl_scan_param *dst, struct sitesurvey_parm *src)
2831 {
2832 	struct phl_scan_channel *phl_ch = NULL;
2833 	int phl_ch_sz = 0;
2834 	int i;
2835 
2836 	phl_ch_sz = sizeof(struct phl_scan_channel) * (src->ch_num + 1);
2837 
2838 	phl_ch = rtw_malloc(phl_ch_sz);
2839 	if (phl_ch == NULL) {
2840 		RTW_ERR("scan: alloc phl scan ch fail\n");
2841 		return -1;
2842 	}
2843 	_rtw_memset(phl_ch, 0, phl_ch_sz);
2844 
2845 	i = 0;
2846 	while (i < src->ch_num) {
2847 
2848 		phl_ch[i].channel = src->ch[i].hw_value;
2849 		phl_ch[i].scan_mode = NORMAL_SCAN_MODE;
2850 		phl_ch[i].bw = src->bw;
2851 		phl_ch[i].duration = src->duration;
2852 
2853 		if (src->ch[i].flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) {
2854 			phl_ch[i].type = RTW_PHL_SCAN_PASSIVE;
2855 
2856 		} else {
2857 			phl_ch[i].type = RTW_PHL_SCAN_ACTIVE;
2858 
2859 			/* reduce scan time in active channel */
2860 			if (src->scan_type == RTW_SCAN_NORMAL)
2861 				phl_ch[i].duration = src->duration >> 1;
2862 		}
2863 		i++;
2864 	}
2865 
2866 	dst->ch = phl_ch;
2867 	dst->ch_sz = phl_ch_sz;
2868 	dst->ch_num = src->ch_num;
2869 
2870 	return 0;
2871 }
2872 
rtw_site_survey_fsm(_adapter * padapter,struct cmd_obj * pcmd)2873 u32 rtw_site_survey_fsm(_adapter *padapter, struct cmd_obj *pcmd)
2874 {
2875 	u32 res = RTW_PHL_STATUS_FAILURE;
2876 	struct scan_priv *scan_priv;
2877 	struct rtw_phl_scan_param *phl_param;
2878 	struct sitesurvey_parm *rtw_param;
2879 	struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
2880 	u8 i;
2881 
2882 	scan_priv = rtw_malloc(sizeof(*scan_priv));
2883 	if (scan_priv == NULL) {
2884 		RTW_ERR("scan: %s alloc scan_priv fail\n", __func__);
2885 		return RTW_PHL_STATUS_FAILURE;
2886 	}
2887 	_rtw_memset(scan_priv, 0, sizeof(*scan_priv));
2888 	scan_priv->padapter = padapter;
2889 	rtw_param = (struct sitesurvey_parm *)pcmd->parmbuf;
2890 
2891 	if (rtw_param->duration == 0)
2892 		rtw_param->duration = SURVEY_TO; /* ms */
2893 
2894 	/* backup original ch list */
2895 	_rtw_memcpy(ch, rtw_param->ch,
2896 		sizeof(struct rtw_ieee80211_channel) *
2897 		rtw_param->ch_num);
2898 
2899 	/* modify ch list according to chanel plan */
2900 	rtw_param->ch_num = rtw_scan_ch_decision(padapter,
2901 				rtw_param->ch, RTW_CHANNEL_SCAN_AMOUNT,
2902 				ch, rtw_param->ch_num, rtw_param->acs);
2903 
2904 	phl_param = rtw_malloc(sizeof(*phl_param));
2905 	if (phl_param == NULL) {
2906 		RTW_ERR("scan: %s alloc param fail\n", __func__);
2907 		if (scan_priv)
2908 			rtw_mfree(scan_priv, sizeof(*scan_priv));
2909 			return RTW_PHL_STATUS_FAILURE;
2910 		}
2911 	_rtw_memset(phl_param, 0, sizeof(*phl_param));
2912 
2913 	/* transfer to rtw channel list to phl channel list */
2914 	scan_channel_list_preparation(padapter, phl_param, rtw_param);
2915 
2916 	/* copy the ssid info to phl param */
2917 	phl_param->ssid_num = rtw_min(rtw_param->ssid_num, SCAN_SSID_AMOUNT);
2918 	for (i = 0; i < phl_param->ssid_num; ++i) {
2919 		phl_param->ssid[i].ssid_len = rtw_param->ssid[i].SsidLength;
2920 		_rtw_memcpy(&phl_param->ssid[i].ssid, &rtw_param->ssid[i].Ssid, phl_param->ssid[i].ssid_len);
2921 	}
2922 
2923 	switch (rtw_param->scan_type) {
2924 #ifdef CONFIG_P2P
2925 	case RTW_SCAN_P2P:
2926 		phl_param->ops = &scan_ops_p2p_cb;
2927 	break;
2928 #endif
2929 #ifdef CONFIG_RTW_80211K
2930 	case RTW_SCAN_RRM:
2931 		phl_param->ops = &scan_ops_rrm_cb;
2932 		if (rtw_param->ch_num > 13) {
2933 			phl_param->back_op_mode = SCAN_BKOP_CNT;
2934 			phl_param->back_op_ch_cnt = 3;
2935 		}
2936 	break;
2937 #endif
2938 	case RTW_SCAN_NORMAL:
2939 	default:
2940 		phl_param->ops = &scan_ops_cb;
2941 		phl_param->back_op_mode = SCAN_BKOP_CNT;
2942 		phl_param->back_op_ch_cnt = 3;
2943 		break;
2944 	}
2945 	phl_param->priv = scan_priv;
2946 	phl_param->wifi_role = padapter->phl_role;
2947 
2948 	res = rtw_phl_scan_request(adapter_to_dvobj(padapter)->phl, phl_param, TO_TAIL);
2949 	rtw_mfree(phl_param->ch, phl_param->ch_sz);
2950 	rtw_mfree(phl_param, sizeof(*phl_param));
2951 
2952 	return res;
2953 }
2954 
rtw_sitesurvey_cmd(_adapter * padapter,struct sitesurvey_parm * pparm)2955 u8 rtw_sitesurvey_cmd(_adapter *padapter, struct sitesurvey_parm *pparm)
2956 {
2957 	u8 res = _FAIL;
2958 	struct cmd_obj *cmd;
2959 	struct sitesurvey_parm	*psurveyPara;
2960 	struct cmd_priv	*pcmdpriv = &adapter_to_dvobj(padapter)->cmdpriv;
2961 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
2962 
2963 #ifdef CONFIG_LPS
2964 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
2965 		rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 0);
2966 #endif
2967 
2968 #ifdef CONFIG_P2P_PS
2969 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
2970 		p2p_ps_wk_cmd(padapter, P2P_PS_SCAN, 1);
2971 #endif /* CONFIG_P2P_PS */
2972 
2973 	cmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
2974 	if (cmd == NULL)
2975 		return _FAIL;
2976 	cmd->padapter = padapter;
2977 
2978 	psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm));
2979 	if (psurveyPara == NULL) {
2980 		rtw_mfree((unsigned char *) cmd, sizeof(struct cmd_obj));
2981 		return _FAIL;
2982 	}
2983 
2984 	if (pparm)
2985 		_rtw_memcpy(psurveyPara, pparm, sizeof(struct sitesurvey_parm));
2986 	else
2987 		psurveyPara->scan_mode = pmlmepriv->scan_mode;
2988 
2989 	rtw_free_network_queue(padapter, _FALSE);
2990 
2991 	init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, CMD_SITE_SURVEY);
2992 
2993 	set_fwstate(pmlmepriv, WIFI_UNDER_SURVEY);
2994 
2995 
2996 	res = rtw_enqueue_cmd(pcmdpriv, cmd);
2997 
2998 	if (res == _SUCCESS) {
2999 		u32 scan_timeout_ms;
3000 
3001 		pmlmepriv->scan_start_time = rtw_get_current_time();
3002 		scan_timeout_ms = rtw_scan_timeout_decision(padapter);
3003 		mlme_set_scan_to_timer(pmlmepriv,scan_timeout_ms);
3004 
3005 		rtw_led_control(padapter, LED_CTL_SITE_SURVEY);
3006 	} else {
3007 		_clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY);
3008 	}
3009 
3010 
3011 	return res;
3012 }
3013 #endif/*CONFIG_CMD_SCAN*/
3014 
3015 
3016 /* inform caller phl_scan are ready on remain channel */
roch_ready_cb(void * priv,struct rtw_phl_scan_param * param)3017 static int roch_ready_cb(void *priv, struct rtw_phl_scan_param *param)
3018 {
3019 	struct scan_priv *scan_priv = (struct scan_priv *)priv;
3020 	_adapter *padapter = scan_priv->padapter;
3021 	struct cfg80211_roch_info *pcfg80211_rochinfo =
3022 		&padapter->cfg80211_rochinfo;
3023 
3024 	RTW_INFO("%s cookie:0x%llx\n", __func__,
3025 		pcfg80211_rochinfo->remain_on_ch_cookie);
3026 
3027 	if ((scan_priv->roch_step & ROCH_CH_READY))
3028 		return 0;
3029 
3030 	scan_priv->roch_step |= ROCH_CH_READY;
3031 
3032 	rtw_cfg80211_ready_on_channel(
3033 		scan_priv->wdev,
3034 		scan_priv->cookie,
3035 		&scan_priv->channel,
3036 		scan_priv->channel_type,
3037 		scan_priv->duration,
3038 		GFP_KERNEL);
3039 	return 0;
3040 }
3041 
roch_off_ch_tx_cb(void * priv,struct rtw_phl_scan_param * param,void * data)3042 static int roch_off_ch_tx_cb(void *priv,
3043 	struct rtw_phl_scan_param *param, void *data)
3044 {
3045 	struct scan_priv *scan_priv = (struct scan_priv *)priv;
3046 	struct dvobj_priv *dvobj = adapter_to_dvobj(scan_priv->padapter);
3047 
3048 #ifdef CONFIG_CMD_SCAN
3049 	RTW_ERR("CMD_SCAN call %s\n", __func__);
3050 	rtw_warn_on(1);
3051 #else
3052 	phl_cmd_complete_job(dvobj->phl, (struct phl_cmd_job *)data);
3053 #endif
3054 	return 0;
3055 }
3056 
3057 #ifdef CONFIG_P2P
p2p_roch_complete_cb(void * priv,struct rtw_phl_scan_param * param)3058 static int p2p_roch_complete_cb(void *priv, struct rtw_phl_scan_param *param)
3059 {
3060 	struct scan_priv *scan_priv = (struct scan_priv *)priv;
3061 	_adapter *padapter = scan_priv->padapter;
3062 	int ret = _FAIL;
3063 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
3064 	struct cfg80211_roch_info *pcfg80211_rochinfo =
3065 		&padapter->cfg80211_rochinfo;
3066 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3067 
3068 	if (!rtw_is_adapter_up(padapter))
3069 		goto _exit;
3070 
3071 	mlmeext_set_scan_state(&padapter->mlmeextpriv, SCAN_DISABLE);
3072 
3073 	/* roch_ready() and roch_complete() MUST be a PAIR
3074 	 * otherwise will caurse wpa_supplicant hang!!!
3075 	 * This case may happen when someone cancel remain on ch
3076 	 * before it really start. (called roch_ready()).
3077 	 */
3078 	if (!(scan_priv->roch_step & ROCH_CH_READY))
3079 		roch_ready_cb(priv, param);
3080 
3081 #ifndef CONFIG_CMD_SCAN
3082 	rtw_back_opch(padapter);
3083 #endif
3084 #ifdef CONFIG_DEBUG_CFG80211
3085 	RTW_INFO("%s, role=%d\n", __func__, rtw_p2p_role(pwdinfo));
3086 #endif
3087 
3088 	rtw_cfg80211_set_is_roch(padapter, _FALSE);
3089 	pcfg80211_rochinfo->ro_ch_wdev = NULL;
3090 	rtw_cfg80211_set_last_ro_ch_time(padapter);
3091 
3092 	ret = _SUCCESS;
3093 _exit:
3094 	/* callback to cfg80211 */
3095 	rtw_cfg80211_remain_on_channel_expired(scan_priv->wdev
3096 		, scan_priv->cookie
3097 		, &scan_priv->channel
3098 		, scan_priv->channel_type, GFP_KERNEL);
3099 
3100 	RTW_INFO("cfg80211_remain_on_channel_expired cookie:0x%llx\n"
3101 		, pcfg80211_rochinfo->remain_on_ch_cookie);
3102 
3103 	RTW_INFO(FUNC_ADPT_FMT" takes %d ms to scan %d/%d channels\n",
3104 			FUNC_ADPT_ARG(padapter), param->total_scan_time,
3105 			#ifdef CONFIG_CMD_SCAN
3106 			param->ch_idx,
3107 			#else
3108 			param->ch_idx + 1,
3109 			#endif
3110 			param->ch_num);
3111 	_rtw_scan_abort_check(padapter, __func__);
3112 
3113 #ifdef CONFIG_CMD_SCAN
3114 	_free_phl_param(padapter, param);
3115 	padapter->mlmeextpriv.sitesurvey_res.scan_param = NULL;
3116 #else
3117 	rtw_mfree(scan_priv, sizeof(*scan_priv));
3118 #endif
3119 	return ret;
3120 }
3121 
p2p_roch_start_cb(void * priv,struct rtw_phl_scan_param * param)3122 static int p2p_roch_start_cb(void *priv, struct rtw_phl_scan_param *param)
3123 {
3124 	struct scan_priv *scan_priv = (struct scan_priv *)priv;
3125 	_adapter *padapter = scan_priv->padapter;
3126 	struct cfg80211_roch_info *pcfg80211_rochinfo;
3127 
3128 	pcfg80211_rochinfo = &padapter->cfg80211_rochinfo;
3129 
3130 	//TODO remove
3131 	mlmeext_set_scan_state(&padapter->mlmeextpriv, SCAN_PROCESS);
3132 
3133 	rtw_cfg80211_set_is_roch(padapter, _TRUE);
3134 	pcfg80211_rochinfo->ro_ch_wdev = scan_priv->wdev;
3135 	pcfg80211_rochinfo->remain_on_ch_cookie = scan_priv->cookie;
3136 	pcfg80211_rochinfo->duration = scan_priv->duration;
3137 	rtw_cfg80211_set_last_ro_ch_time(padapter);
3138 	_rtw_memcpy(&pcfg80211_rochinfo->remain_on_ch_channel,
3139 		&scan_priv->channel, sizeof(struct ieee80211_channel));
3140 	#if (KERNEL_VERSION(3, 8, 0) > LINUX_VERSION_CODE)
3141 	pcfg80211_rochinfo->remain_on_ch_type = scan_priv->channel_type;
3142 	#endif
3143 	pcfg80211_rochinfo->restore_channel = scan_priv->restore_ch;
3144 
3145 	#ifdef CONFIG_CMD_SCAN
3146 	padapter->mlmeextpriv.sitesurvey_res.scan_param = param;
3147 	#endif
3148 
3149 	return 0;
3150 }
3151 #endif
3152 
roch_start_cb(void * priv,struct rtw_phl_scan_param * param)3153 static int roch_start_cb(void *priv, struct rtw_phl_scan_param *param)
3154 {
3155 	struct scan_priv *scan_priv = (struct scan_priv *)priv;
3156 	_adapter *padapter = scan_priv->padapter;
3157 
3158 	mlmeext_set_scan_state(&padapter->mlmeextpriv, SCAN_PROCESS);
3159 	rtw_cfg80211_set_is_roch(padapter, _TRUE);
3160 	#ifdef CONFIG_CMD_SCAN
3161 	padapter->mlmeextpriv.sitesurvey_res.scan_param = param;
3162 	#endif
3163 
3164 	return 0;
3165 }
3166 
roch_complete_cb(void * priv,struct rtw_phl_scan_param * param)3167 static int roch_complete_cb(void *priv, struct rtw_phl_scan_param *param)
3168 {
3169 	struct scan_priv *scan_priv = (struct scan_priv *)priv;
3170 	_adapter *padapter = scan_priv->padapter;
3171 	struct cfg80211_roch_info *pcfg80211_rochinfo =
3172 		&padapter->cfg80211_rochinfo;
3173 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3174 	int ret = _FAIL;
3175 
3176 	if (!rtw_is_adapter_up(padapter))
3177 		goto _exit;
3178 
3179 	mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
3180 
3181 	/* roch_ready() and roch_complete() MUST be a PAIR
3182 	 * otherwise will caurse wpa_supplicant hang!!!
3183 	 * This case may happen when someone cancel remain on ch
3184 	 * before it really start. (called roch_ready()).
3185 	 */
3186 	if (!(scan_priv->roch_step & ROCH_CH_READY))
3187 		roch_ready_cb(priv, param);
3188 
3189 	rtw_cfg80211_set_is_roch(padapter, _FALSE);
3190 
3191 	ret = _SUCCESS;
3192 
3193 _exit:
3194 	/* callback to cfg80211 */
3195 	rtw_cfg80211_remain_on_channel_expired(scan_priv->wdev
3196 		, scan_priv->cookie
3197 		, &scan_priv->channel
3198 		, scan_priv->channel_type, GFP_KERNEL);
3199 
3200 	RTW_INFO("cfg80211_remain_on_channel_expired cookie:0x%llx\n"
3201 		, pcfg80211_rochinfo->remain_on_ch_cookie);
3202 
3203 	RTW_INFO(FUNC_ADPT_FMT" takes %d ms to scan %d/%d channels\n",
3204 			FUNC_ADPT_ARG(padapter), param->total_scan_time,
3205 			#ifdef CONFIG_CMD_SCAN
3206 			param->ch_idx,
3207 			#else
3208 			param->ch_idx + 1,
3209 			#endif
3210 			param->ch_num);
3211 	_rtw_scan_abort_check(padapter, __func__);
3212 
3213 #ifdef CONFIG_CMD_SCAN
3214 	_free_phl_param(padapter, param);
3215 	pmlmeext->sitesurvey_res.scan_param = NULL;
3216 #else
3217 	rtw_mfree(scan_priv, sizeof(*scan_priv));
3218 #endif
3219 	return ret;
3220 }
3221 
3222 #ifdef CONFIG_P2P
3223 /* p2p remain on channel */
3224 static struct rtw_phl_scan_ops p2p_remain_ops_cb = {
3225 	.scan_start = p2p_roch_start_cb,
3226 	.scan_ch_ready = roch_ready_cb,
3227 	.scan_off_ch_tx = roch_off_ch_tx_cb,
3228 	.scan_complete = p2p_roch_complete_cb,
3229 	.scan_issue_null_data = scan_issu_null_data_cb
3230 };
3231 #endif
3232 
3233 /* normal remain on channel */
3234 static struct rtw_phl_scan_ops remain_ops_cb = {
3235 	.scan_start = roch_start_cb,
3236 	.scan_ch_ready = roch_ready_cb,
3237 	.scan_off_ch_tx = roch_off_ch_tx_cb,
3238 	.scan_complete = roch_complete_cb,
3239 	.scan_issue_null_data = scan_issu_null_data_cb
3240 };
3241 
3242 #ifdef CONFIG_IOCTL_CFG80211
roch_stay_in_cur_chan(_adapter * padapter)3243 static u8 roch_stay_in_cur_chan(_adapter *padapter)
3244 {
3245 	int i;
3246 	_adapter *iface;
3247 	struct mlme_priv *pmlmepriv;
3248 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3249 	u8 rst = _FALSE;
3250 
3251 	for (i = 0; i < dvobj->iface_nums; i++) {
3252 		iface = dvobj->padapters[i];
3253 		if (iface) {
3254 			pmlmepriv = &iface->mlmepriv;
3255 
3256 			if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS | WIFI_UNDER_KEY_HANDSHAKE) == _TRUE) {
3257 				RTW_INFO(ADPT_FMT"- WIFI_UNDER_LINKING |WIFI_UNDER_WPS | WIFI_UNDER_KEY_HANDSHAKE (mlme state:0x%x)\n",
3258 						ADPT_ARG(iface), get_fwstate(&iface->mlmepriv));
3259 				rst = _TRUE;
3260 				break;
3261 			}
3262 			#ifdef CONFIG_AP_MODE
3263 			if (MLME_IS_AP(iface) || MLME_IS_MESH(iface)) {
3264 				if (rtw_ap_sta_states_check(iface) == _TRUE) {
3265 					rst = _TRUE;
3266 					break;
3267 				}
3268 			}
3269 			#endif
3270 		}
3271 	}
3272 
3273 	return rst;
3274 }
3275 
3276 #ifdef CONFIG_CMD_SCAN
rtw_phl_remain_on_ch_cmd(_adapter * padapter,u64 cookie,struct wireless_dev * wdev,struct ieee80211_channel * ch,u8 ch_type,unsigned int duration,struct back_op_param * bkop_parm,u8 is_p2p)3277 u8 rtw_phl_remain_on_ch_cmd(_adapter *padapter,
3278 	u64 cookie, struct wireless_dev *wdev,
3279 	struct ieee80211_channel *ch, u8 ch_type,
3280 	unsigned int duration, struct back_op_param *bkop_parm,
3281 	u8 is_p2p)
3282 {
3283 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3284 	struct rtw_phl_scan_param *phl_param = NULL;
3285 	struct scan_priv *scan_priv = NULL;
3286 	u16 remain_ch;
3287 	u8 chan_num;
3288 	u8 res = _FAIL;
3289 
3290 	/* prepare remain channel - check channel */
3291 	remain_ch = (u16)ieee80211_frequency_to_channel(ch->center_freq);
3292 	if (roch_stay_in_cur_chan(padapter) == _TRUE) { /*???*/
3293 		remain_ch = rtw_mi_get_union_chan(padapter);
3294 		RTW_INFO(FUNC_ADPT_FMT" stay in union ch:%d\n",
3295 			FUNC_ADPT_ARG(padapter), remain_ch);
3296 	}
3297 	chan_num = 1;
3298 
3299 	phl_param = _alloc_phl_param(padapter, chan_num);
3300 	if (phl_param == NULL) {
3301 		RTW_ERR("%s alloc phl_param fail\n", __func__);
3302 		goto _err_exit;
3303 	}
3304 
3305 	/*** fill phl parameter - scan_priv ***/
3306 	scan_priv = (struct scan_priv *)phl_param->priv;
3307 	scan_priv->padapter = padapter;
3308 	scan_priv->wdev = wdev;
3309 	_rtw_memcpy(&scan_priv->channel, ch, sizeof(*ch));
3310 	scan_priv->channel_type = ch_type;
3311 	scan_priv->cookie = cookie;
3312 	scan_priv->duration = duration;
3313 	scan_priv->restore_ch = rtw_get_oper_ch(padapter);
3314 
3315 	/* fill phl param - chan */
3316 	phl_param->ch->channel = remain_ch;
3317 	phl_param->ch->duration = duration;
3318 	phl_param->ch->scan_mode = P2P_LISTEN_MODE;
3319 	phl_param->ch->bw = CHANNEL_WIDTH_20;
3320 	phl_param->ch_num = chan_num;
3321 
3322 	/* fill back op param */
3323 	phl_param->back_op_mode = SCAN_BKOP_TIMER;
3324 	phl_param->back_op_ch_cnt = 1;
3325 	phl_param->back_op_ch_dur_ms = bkop_parm->on_ch_dur;/*op_ch time*/
3326 	phl_param->back_op_off_ch_dur_ms = bkop_parm->off_ch_dur;/*ro_ch time*/
3327 	phl_param->back_op_off_ch_ext_dur_ms = bkop_parm->off_ch_ext_dur;
3328 
3329 #ifdef CONFIG_P2P
3330 	/* set ops according to is_p2p */
3331 	if (is_p2p)
3332 		phl_param->ops = &p2p_remain_ops_cb;
3333 	else
3334 #endif
3335 		phl_param->ops = &remain_ops_cb;
3336 
3337 	if(rtw_phl_cmd_scan_request(dvobj->phl, phl_param, true) == RTW_PHL_STATUS_FAILURE) {
3338 		RTW_ERR("%s request scam_cmd failed\n", __func__);
3339 		goto _err_req_param;
3340 	}
3341 
3342 
3343 	RTW_INFO(FUNC_ADPT_FMT" ch:%u duration:%d, cookie:0x%llx\n"
3344 			, FUNC_ADPT_ARG(padapter), remain_ch,	duration, cookie);
3345 	res = _SUCCESS;
3346 	return res;
3347 
3348 _err_req_param:
3349 	_free_phl_param(padapter, phl_param);
3350 _err_exit:
3351 	rtw_warn_on(1);
3352 	return res;
3353 }
3354 
3355 #else
rtw_phl_remain_on_ch_cmd(_adapter * padapter,u64 cookie,struct wireless_dev * wdev,struct ieee80211_channel * ch,u8 ch_type,unsigned int duration,struct back_op_param * bkop_parm,u8 is_p2p)3356 u8 rtw_phl_remain_on_ch_cmd(_adapter *padapter,
3357 	u64 cookie, struct wireless_dev *wdev,
3358 	struct ieee80211_channel *ch, u8 ch_type,
3359 	unsigned int duration, struct back_op_param *bkop_parm,
3360 	u8 is_p2p)
3361 {
3362 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3363 	struct rtw_phl_scan_param phl_param;
3364 	struct scan_priv *scan_priv;
3365 	struct phl_scan_channel phl_ch;
3366 	int phl_ch_sz = 0;
3367 	u16 remain_ch;
3368 	u8 res = _FAIL;
3369 
3370 	_rtw_memset(&phl_param, 0, sizeof(phl_param));
3371 
3372 	scan_priv = rtw_malloc(sizeof(*scan_priv));
3373 	if (scan_priv == NULL) {
3374 		RTW_ERR("scan: %s alloc scan_priv fail\n", __func__);
3375 		return res;
3376 	}
3377 	_rtw_memset(scan_priv, 0, sizeof(*scan_priv));
3378 
3379 	scan_priv->padapter = padapter;
3380 	scan_priv->wdev = wdev;
3381 	_rtw_memcpy(&scan_priv->channel, ch, sizeof(*ch));
3382 	scan_priv->channel_type = ch_type;
3383 
3384 	scan_priv->cookie = cookie;
3385 	scan_priv->duration = duration;
3386 	scan_priv->restore_ch = rtw_get_oper_ch(padapter);
3387 
3388 	phl_param.priv = scan_priv;
3389 
3390 	/* check channel */
3391 	remain_ch = (u16)ieee80211_frequency_to_channel(ch->center_freq);
3392 
3393 	if (roch_stay_in_cur_chan(padapter) == _TRUE) {
3394 		remain_ch = rtw_mi_get_union_chan(padapter);
3395 		RTW_INFO(FUNC_ADPT_FMT" stay in union ch:%d\n",
3396 			FUNC_ADPT_ARG(padapter), remain_ch);
3397 	}
3398 
3399 	/* prepare remain channel */
3400 	phl_ch_sz = sizeof(struct phl_scan_channel);
3401 	_rtw_memset(&phl_ch, 0, phl_ch_sz);
3402 
3403 	phl_ch.channel = remain_ch;
3404 	phl_ch.duration = scan_priv->duration;
3405 	phl_ch.scan_mode = NORMAL_SCAN_MODE;
3406 	phl_ch.bw = CHANNEL_WIDTH_20;
3407 
3408 	phl_param.ch = &phl_ch;
3409 	phl_param.ch_sz = phl_ch_sz;
3410 	phl_param.ch_num = 1;
3411 	phl_param.wifi_role = padapter->phl_role;
3412 
3413 	phl_param.back_op_mode = SCAN_BKOP_TIMER;
3414 	phl_param.back_op_ch_dur_ms = bkop_parm->on_ch_dur;
3415 	phl_param.back_op_off_ch_dur_ms = bkop_parm->off_ch_dur;
3416 	phl_param.back_op_off_ch_ext_dur_ms = bkop_parm->off_ch_ext_dur;
3417 
3418 #ifdef CONFIG_P2P
3419 	if (is_p2p)
3420 		phl_param.ops = &p2p_remain_ops_cb;
3421 	else
3422 #endif
3423 		phl_param.ops = &remain_ops_cb;
3424 
3425 	RTW_INFO(FUNC_ADPT_FMT" ch:%u duration:%d, cookie:0x%llx\n"
3426 		, FUNC_ADPT_ARG(padapter), phl_ch.channel,
3427 		scan_priv->duration, cookie);
3428 
3429 	/* sent message to request phl scan
3430 	 * IMMEDIATE imply cancelling previous scan request if has
3431 	 */
3432 	rtw_phl_scan_request(dvobj->phl, &phl_param, IMMEDIATE);
3433 
3434 	/* scan_priv will be cancelled in roch_complete_cb */
3435 	res = _SUCCESS;
3436 	return res;
3437 }
3438 #endif
3439 #endif /*CONFIG_IOCTL_CFG80211*/
3440 
3441 #endif /*CONFIG_PHL_ARCH*/
3442