• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Scan implementation for XRadio drivers
3  *
4  * Copyright (c) 2013
5  * Xradio Technology Co., Ltd. <www.xradiotech.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 
12 #include <linux/sched.h>
13 #include "xradio.h"
14 #include "scan.h"
15 #include "sta.h"
16 #include "pm.h"
17 
18 static void xradio_scan_restart_delayed(struct xradio_vif *priv);
19 
20 #ifdef CONFIG_XRADIO_TESTMODE
xradio_advance_scan_start(struct xradio_common * hw_priv)21 static int xradio_advance_scan_start(struct xradio_common *hw_priv)
22 {
23 	int tmo = 0;
24 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
25 
26 	tmo += hw_priv->advanceScanElems.duration;
27 #ifdef CONFIG_PM
28 	xradio_pm_stay_awake(&hw_priv->pm_state, tmo * HZ / 1000);
29 #endif
30 	/* Invoke Advance Scan Duration Timeout Handler */
31 	queue_delayed_work(hw_priv->workqueue,
32 		&hw_priv->advance_scan_timeout, tmo * HZ / 1000);
33 	return 0;
34 }
35 #endif
36 
xradio_remove_wps_p2p_ie(struct wsm_template_frame * frame)37 static void xradio_remove_wps_p2p_ie(struct wsm_template_frame *frame)
38 {
39 	u8 *ies;
40 	u32 ies_len;
41 	u32 ie_len;
42 	u32 p2p_ie_len = 0;
43 	u32 wps_ie_len = 0;
44 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
45 
46 	ies = &frame->skb->data[sizeof(struct ieee80211_hdr_3addr)];
47 	ies_len = frame->skb->len - sizeof(struct ieee80211_hdr_3addr);
48 	while (ies_len >= 6) {
49 		ie_len = ies[1] + 2;
50 		ies_len -= ie_len;
51 		if ((ies[0] == WLAN_EID_VENDOR_SPECIFIC) &&
52 			  (ies[2] == 0x00 && ies[3] == 0x50 &&
53 			   ies[4] == 0xf2 && ies[5] == 0x04)) {
54 			wps_ie_len = ie_len;
55 			memmove(ies, ies + ie_len, ies_len);
56 		} else if ((ies[0] == WLAN_EID_VENDOR_SPECIFIC) &&
57 			   (ies[2] == 0x50 && ies[3] == 0x6f &&
58 			    ies[4] == 0x9a && ies[5] == 0x09)) {
59 			p2p_ie_len = ie_len;
60 			memmove(ies, ies + ie_len, ies_len);
61 		} else {
62 			ies += ie_len;
63 		}
64 	}
65 
66 	if (p2p_ie_len || wps_ie_len) {
67 		skb_trim(frame->skb, frame->skb->len - (p2p_ie_len + wps_ie_len));
68 	}
69 }
70 
71 #ifdef CONFIG_XRADIO_TESTMODE
xradio_disable_filtering(struct xradio_vif * priv)72 static int xradio_disable_filtering(struct xradio_vif *priv)
73 {
74 	int ret = 0;
75 	bool bssid_filtering = 0;
76 	struct wsm_rx_filter rx_filter;
77 	struct wsm_beacon_filter_control bf_control;
78 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
79 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
80 
81 	/* RX Filter Disable */
82 	rx_filter.promiscuous = 0;
83 	rx_filter.bssid = 0;
84 	rx_filter.fcs = 0;
85 	ret = wsm_set_rx_filter(hw_priv, &rx_filter, priv->if_id);
86 
87 	/* Beacon Filter Disable */
88 	bf_control.enabled = 0;
89 	bf_control.bcn_count = 1;
90 	if (!ret)
91 		ret = wsm_beacon_filter_control(hw_priv, &bf_control, priv->if_id);
92 
93 	/* BSSID Filter Disable */
94 	if (!ret)
95 		ret = wsm_set_bssid_filtering(hw_priv, bssid_filtering, priv->if_id);
96 
97 	return ret;
98 }
99 #endif
100 
xradio_scan_start(struct xradio_vif * priv,struct wsm_scan * scan)101 static int xradio_scan_start(struct xradio_vif *priv, struct wsm_scan *scan)
102 {
103 	int ret, i;
104 #ifdef FPGA_SETUP
105 	int tmo = SCAN_DEFAULT_TIMEOUT;
106 #else
107 	int tmo = SCAN_DEFAULT_TIMEOUT;
108 #endif
109 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
110 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
111 
112 	for (i = 0; i < scan->numOfChannels; ++i)
113 		tmo += scan->ch[i].maxChannelTime + 10;
114 
115 	atomic_set(&hw_priv->scan.in_progress, 1);
116 	atomic_set(&hw_priv->recent_scan, 1);
117 #ifdef CONFIG_PM
118 	xradio_pm_stay_awake(&hw_priv->pm_state, tmo * HZ / 1000);
119 #endif
120 	schedule_delayed_work(&hw_priv->scan.timeout, tmo * HZ / 1000);
121 #ifdef SCAN_FAILED_WORKAROUND_OF_FW_EXCEPTION
122 	hw_priv->scan.scan_failed_timestamp = jiffies;
123 #endif
124 #ifdef P2P_MULTIVIF
125 	ret = wsm_scan(hw_priv, scan, priv->if_id ? 1 : 0);
126 #else
127 	ret = wsm_scan(hw_priv, scan, priv->if_id);
128 #endif
129 	if (unlikely(ret)) {
130 		scan_printk(XRADIO_DBG_WARN, "%s, wsm_scan failed!\n", __func__);
131 		atomic_set(&hw_priv->scan.in_progress, 0);
132 		cancel_delayed_work(&hw_priv->scan.timeout);
133 		xradio_scan_restart_delayed(priv);
134 	}
135 	return ret;
136 }
137 
138 #ifdef ROAM_OFFLOAD
xradio_sched_scan_start(struct xradio_vif * priv,struct wsm_scan * scan)139 static int xradio_sched_scan_start(struct xradio_vif *priv,
140 					   struct wsm_scan *scan)
141 {
142 	int ret;
143 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
144 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
145 
146 	ret = wsm_scan(hw_priv, scan, priv->if_id);
147 	if (unlikely(ret)) {
148 		atomic_set(&hw_priv->scan.in_progress, 0);
149 		scan_printk(XRADIO_DBG_WARN, "%s, wsm_scan failed!\n", __func__);
150 	}
151 	return ret;
152 }
153 #endif /*ROAM_OFFLOAD*/
154 
xradio_hw_scan(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_scan_request * reqs)155 int xradio_hw_scan(struct ieee80211_hw *hw,
156 		   struct ieee80211_vif *vif,
157 		   struct ieee80211_scan_request *reqs)
158 {
159 	struct xradio_common *hw_priv = hw->priv;
160 	struct xradio_vif *priv = xrwl_get_vif_from_ieee80211(vif);
161 	struct wsm_template_frame frame = {
162 		.frame_type = WSM_FRAME_TYPE_PROBE_REQUEST,
163 	};
164 	int i;
165 #ifdef CONFIG_XRADIO_TESTMODE
166 	int ret = 0;
167 	u16 advance_scan_req_channel;
168 #endif
169 	int suspend_lock_state;
170 	struct cfg80211_scan_request *req = (struct cfg80211_scan_request *)(&(reqs->req));
171 
172 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
173 
174 	/* Scan when P2P_GO corrupt firmware MiniAP mode */
175 	if (priv->join_status == XRADIO_JOIN_STATUS_AP) {
176 		scan_printk(XRADIO_DBG_WARN, "%s, can't scan in AP mode!\n",
177 			    __func__);
178 		return -EOPNOTSUPP;
179 	}
180 
181 #ifdef HW_RESTART
182 	if (hw_priv->hw_restart) {
183 		scan_printk(XRADIO_DBG_NIY, "Ignoring scan in hw reset!\n");
184 		return -EBUSY;
185 	}
186 #endif
187 
188 	if (hw_priv->bh_error) {
189 		scan_printk(XRADIO_DBG_WARN, "Ignoring scan bh error occur!\n");
190 		return -EBUSY;
191 	}
192 
193 	if (!atomic_read(&priv->enabled)) {
194 		scan_printk(XRADIO_DBG_WARN, "Ignoring scan vif is not enable!\n");
195 		return -EBUSY;
196 	}
197 
198 	if (work_pending(&priv->offchannel_work) ||
199 			(hw_priv->roc_if_id != -1)) {
200 		scan_printk(XRADIO_DBG_WARN, "Offchannel work pending, "
201 			    "ignoring scan work %d\n",  hw_priv->roc_if_id);
202 		return -EBUSY;
203 	}
204 
205 	if (req->n_ssids == 1 && !req->ssids[0].ssid_len)
206 		req->n_ssids = 0;
207 
208 	scan_printk(XRADIO_DBG_NIY, "vif%d Scan request(%s-%dchs) for %d SSIDs.\n",
209 		priv->if_id, (req->channels[0]->band == NL80211_BAND_2GHZ) ? "2.4G" : "5G",
210 		req->n_channels, req->n_ssids);
211 
212 	if (xradio_is_bt_block(hw_priv)) {
213 		scan_printk(XRADIO_DBG_WARN, "%s:BT is busy, Delay scan!\n", __func__);
214 		return -EBUSY;
215 	}
216 
217 	/*delay multiple ssids scan of vif0 for 3s when connnetting to a node*/
218 	if (hw_priv->scan_delay_status[0] == XRADIO_SCAN_DELAY &&
219 	    req->n_ssids == 0 && priv->if_id == 0) {
220 		unsigned long timedelay = hw_priv->scan_delay_time[0] + SCAN_MAX_DELAY;
221 		if (time_before(jiffies, timedelay)) {
222 			scan_printk(XRADIO_DBG_NIY, "vif0 connectting, scan delay %ldms\n",
223 				(long)(timedelay - jiffies)*1000/HZ);
224 			return -EBUSY;
225 		}
226 		hw_priv->scan_delay_status[0] = XRADIO_SCAN_ALLOW;
227 	}
228 
229 	if (req->n_ssids > hw->wiphy->max_scan_ssids) {
230 		scan_printk(XRADIO_DBG_ERROR, "%s: ssids is too much(%d)\n",
231 			__func__, req->n_ssids);
232 		return -EINVAL;
233 	}
234 
235 	suspend_lock_state = atomic_cmpxchg(&hw_priv->suspend_lock_state,
236 								XRADIO_SUSPEND_LOCK_IDEL, XRADIO_SUSPEND_LOCK_OTHERS);
237 	if (suspend_lock_state == XRADIO_SUSPEND_LOCK_SUSPEND) {
238 		scan_printk(XRADIO_DBG_WARN,
239 			   "%s:refuse because of suspend\n", __func__);
240 		return -EBUSY;
241 	}
242 
243 	frame.skb = mac80211_probereq_data_get(hw, vif, NULL, 0, req->ie, req->ie_len);
244 	if (!frame.skb) {
245 		scan_printk(XRADIO_DBG_ERROR, "%s: mac80211_probereq_get failed!\n",
246 			__func__);
247 		atomic_set(&hw_priv->suspend_lock_state, XRADIO_SUSPEND_LOCK_IDEL);
248 		return -ENOMEM;
249 	}
250 
251 #ifdef ROAM_OFFLOAD
252 	if (priv->join_status != XRADIO_JOIN_STATUS_STA) {
253 		if (req->channels[0]->band == NL80211_BAND_2GHZ)
254 			hw_priv->num_scanchannels = 0;
255 		else
256 			hw_priv->num_scanchannels = hw_priv->num_2g_channels;
257 
258 		for (i = 0; i < req->n_channels; i++) {
259 			hw_priv->scan_channels[hw_priv->num_scanchannels + i].number = \
260 				req->channels[i]->hw_value;
261 			if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) {
262 				hw_priv->scan_channels[hw_priv->num_scanchannels \
263 							+ i].minChannelTime = 50;
264 				hw_priv->scan_channels[hw_priv->num_scanchannels \
265 							+ i].maxChannelTime = 110;
266 			} else {
267 				hw_priv->scan_channels[hw_priv->num_scanchannels \
268 						       + i].minChannelTime = 10;
269 				hw_priv->scan_channels[hw_priv->num_scanchannels \
270 						       + i].maxChannelTime = 40;
271 				hw_priv->scan_channels[hw_priv->num_scanchannels \
272 						       + i].number |= \
273 					XRADIO_SCAN_TYPE_ACTIVE;
274 			}
275 			hw_priv->scan_channels[hw_priv->num_scanchannels \
276 					       + i].txPowerLevel = \
277 					       req->channels[i]->max_power;
278 			if (req->channels[0]->band == NL80211_BAND_5GHZ)
279 				hw_priv->scan_channels[hw_priv->num_scanchannels \
280 						       + i].number |= XRADIO_SCAN_BAND_5G;
281 		}
282 		if (req->channels[0]->band == NL80211_BAND_2GHZ)
283 			hw_priv->num_2g_channels = req->n_channels;
284 		else
285 			hw_priv->num_5g_channels = req->n_channels;
286 	}
287 	hw_priv->num_scanchannels = hw_priv->num_2g_channels + \
288 				    hw_priv->num_5g_channels;
289 #endif /*ROAM_OFFLOAD*/
290 
291 	/* will be unlocked in xradio_scan_work() */
292 	down(&hw_priv->scan.lock);
293 	down(&hw_priv->conf_lock);
294 	atomic_set(&hw_priv->suspend_lock_state, XRADIO_SUSPEND_LOCK_IDEL);
295 
296 #ifdef CONFIG_XRADIO_TESTMODE
297 	/* Active Scan - Serving Channel Request Handling */
298 	advance_scan_req_channel = req->channels[0]->hw_value;
299 	if (hw_priv->enable_advance_scan &&
300 	    (hw_priv->advanceScanElems.scanMode ==
301 	     XRADIO_SCAN_MEASUREMENT_ACTIVE) &&
302 	    (priv->join_status == XRADIO_JOIN_STATUS_STA) &&
303 	    (hw_priv->channel->hw_value == advance_scan_req_channel)) {
304 		SYS_BUG(hw_priv->scan.req);
305 		/* wsm_lock_tx(hw_priv); */
306 		wsm_vif_lock_tx(priv);
307 		hw_priv->scan.if_id = priv->if_id;
308 		/* Disable Power Save */
309 		if (priv->powersave_mode.pmMode & WSM_PSM_PS) {
310 			struct wsm_set_pm pm = priv->powersave_mode;
311 			pm.pmMode = WSM_PSM_ACTIVE;
312 			wsm_set_pm(hw_priv, &pm, priv->if_id);
313 		}
314 		/* Disable Rx Beacon and Bssid filter */
315 		ret = xradio_disable_filtering(priv);
316 		if (ret)
317 			scan_printk(XRADIO_DBG_ERROR,
318 				    "%s: Disable BSSID or Beacon filtering "
319 				    "failed: %d.\n", __func__, ret);
320 		wsm_unlock_tx(hw_priv);
321 		up(&hw_priv->conf_lock);
322 		/* Transmit Probe Request with Broadcast SSID */
323 		xradio_tx(hw, frame.skb);
324 		/* Start Advance Scan Timer */
325 		xradio_advance_scan_start(hw_priv);
326 	} else {
327 #endif /* CONFIG_XRADIO_TESTMODE */
328 
329 		if (frame.skb) {
330 			int ret = 0;
331 			if (priv->if_id == 0)
332 				xradio_remove_wps_p2p_ie(&frame);
333 #ifdef P2P_MULTIVIF
334 			ret = wsm_set_template_frame(hw_priv, &frame, priv->if_id ? 1 : 0);
335 #else
336 			ret = wsm_set_template_frame(hw_priv, &frame, priv->if_id);
337 #endif
338 			if (ret) {
339 				up(&hw_priv->conf_lock);
340 				up(&hw_priv->scan.lock);
341 				dev_kfree_skb(frame.skb);
342 				scan_printk(XRADIO_DBG_ERROR,
343 					    "%s: wsm_set_template_frame failed: %d.\n",
344 					     __func__, ret);
345 				return ret;
346 			}
347 		}
348 
349 		wsm_vif_lock_tx(priv);
350 
351 		SYS_BUG(hw_priv->scan.req);
352 		hw_priv->scan.req     = req;
353 		hw_priv->scan.n_ssids = 0;
354 		hw_priv->scan.status  = 0;
355 		hw_priv->scan.begin   = &req->channels[0];
356 		hw_priv->scan.curr    = hw_priv->scan.begin;
357 		hw_priv->scan.end     = &req->channels[req->n_channels];
358 		hw_priv->scan.output_power = hw_priv->output_power;
359 		hw_priv->scan.if_id = priv->if_id;
360 		/* TODO:COMBO: Populate BIT4 in scanflags to decide on which MAC
361 		 * address the SCAN request will be sent */
362 
363 		for (i = 0; i < req->n_ssids; ++i) {
364 			struct wsm_ssid *dst = &hw_priv->scan.ssids[hw_priv->scan.n_ssids];
365 			SYS_BUG(req->ssids[i].ssid_len > sizeof(dst->ssid));
366 			memcpy(&dst->ssid[0], req->ssids[i].ssid, sizeof(dst->ssid));
367 			dst->length = req->ssids[i].ssid_len;
368 			++hw_priv->scan.n_ssids;
369 		}
370 
371 		up(&hw_priv->conf_lock);
372 
373 		if (frame.skb)
374 			dev_kfree_skb(frame.skb);
375 		queue_work(hw_priv->workqueue, &hw_priv->scan.work);
376 
377 #ifdef CONFIG_XRADIO_TESTMODE
378 	}
379 #endif
380 
381 	return 0;
382 }
383 
384 #ifdef ROAM_OFFLOAD
xradio_hw_sched_scan_start(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct cfg80211_sched_scan_request * req,struct ieee80211_sched_scan_ies * ies)385 int xradio_hw_sched_scan_start(struct ieee80211_hw *hw,
386 		   struct ieee80211_vif *vif,
387 		   struct cfg80211_sched_scan_request *req,
388 		   struct ieee80211_sched_scan_ies *ies)
389 {
390 	struct xradio_common *hw_priv = hw->priv;
391 	struct xradio_vif *priv = xrwl_get_vif_from_ieee80211(vif);
392 	struct wsm_template_frame frame = {
393 		.frame_type = WSM_FRAME_TYPE_PROBE_REQUEST,
394 	};
395 	int i;
396 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
397 
398 	scan_printk(XRADIO_DBG_WARN, "Scheduled scan request-->.\n");
399 	if (!priv->vif)
400 		return -EINVAL;
401 
402 	/* Scan when P2P_GO corrupt firmware MiniAP mode */
403 	if (priv->join_status == XRADIO_JOIN_STATUS_AP) {
404 		scan_printk(XRADIO_DBG_WARN, "%s, can't scan in AP mode!\n", __func__);
405 		return -EOPNOTSUPP;
406 	}
407 
408 #ifdef HW_RESTART
409 	if (hw_priv->hw_restart) {
410 		scan_printk(XRADIO_DBG_NIY, "Ignoring scan in hw reset!\n");
411 		return -EBUSY;
412 	}
413 #endif
414 
415 	if (hw_priv->bh_error) {
416 		scan_printk(XRADIO_DBG_WARN, "Ignoring scan bh error occur!\n");
417 		return -EBUSY;
418 	}
419 
420 	if (!atomic_read(&priv->enabled)) {
421 		scan_printk(XRADIO_DBG_WARN, "Ignoring scan vif is not enable!\n");
422 		return -EBUSY;
423 	}
424 
425 
426 	scan_printk(XRADIO_DBG_WARN,
427 		    "Scheduled scan: n_ssids %d, ssid[0].len = %d\n",
428 		    req->n_ssids, req->ssids[0].ssid_len);
429 	if (req->n_ssids == 1 && !req->ssids[0].ssid_len)
430 		req->n_ssids = 0;
431 
432 	scan_printk(XRADIO_DBG_NIY, "[SCAN] Scan request for %d SSIDs.\n",
433 		req->n_ssids);
434 
435 	if (req->n_ssids > hw->wiphy->max_scan_ssids) {
436 		scan_printk(XRADIO_DBG_ERROR, "%s: ssids is too much(%d)\n",
437 			__func__, req->n_ssids);
438 		return -EINVAL;
439 	}
440 
441 	frame.skb = mac80211_probereq_data_get(hw, priv->vif, NULL, 0,
442 			ies->ie[0], ies->len[0]);
443 	if (!frame.skb) {
444 		scan_printk(XRADIO_DBG_ERROR, "%s: mac80211_probereq_get failed!\n",
445 			__func__);
446 		return -ENOMEM;
447 	}
448 
449 	/* will be unlocked in xradio_scan_work() */
450 	down(&hw_priv->scan.lock);
451 	down(&hw_priv->conf_lock);
452 	if (frame.skb) {
453 		int ret;
454 		if (priv->if_id == 0)
455 			xradio_remove_wps_p2p_ie(&frame);
456 		ret = wsm_set_template_frame(hw_priv, &frame, priv->if_id);
457 		if (0 == ret) {
458 			/* Host want to be the probe responder. */
459 			ret = wsm_set_probe_responder(priv, true);
460 		}
461 		if (ret) {
462 			up(&hw_priv->conf_lock);
463 			up(&hw_priv->scan.lock);
464 			dev_kfree_skb(frame.skb);
465 			scan_printk(XRADIO_DBG_ERROR,
466 				    "%s: wsm_set_probe_responder failed: %d.\n",
467 					__func__, ret);
468 			return ret;
469 		}
470 	}
471 
472 	wsm_lock_tx(hw_priv);
473 	SYS_BUG(hw_priv->scan.req);
474 	hw_priv->scan.sched_req = req;
475 	hw_priv->scan.n_ssids = 0;
476 	hw_priv->scan.status = 0;
477 	hw_priv->scan.begin = &req->channels[0];
478 	hw_priv->scan.curr = hw_priv->scan.begin;
479 	hw_priv->scan.end = &req->channels[req->n_channels];
480 	hw_priv->scan.output_power = hw_priv->output_power;
481 
482 	for (i = 0; i < req->n_ssids; ++i) {
483 		u8 j;
484 		struct wsm_ssid *dst = &hw_priv->scan.ssids[hw_priv->scan.n_ssids];
485 		SYS_BUG(req->ssids[i].ssid_len > sizeof(dst->ssid));
486 		memcpy(&dst->ssid[0], req->ssids[i].ssid, sizeof(dst->ssid));
487 		dst->length = req->ssids[i].ssid_len;
488 		++hw_priv->scan.n_ssids;
489 		scan_printk(XRADIO_DBG_NIY, "SSID %d\n", i);
490 		for (j = 0; j < req->ssids[i].ssid_len; j++)
491 			scan_printk(XRADIO_DBG_NIY, "0x%x\n", req->ssids[i].ssid[j]);
492 	}
493 	up(&hw_priv->conf_lock);
494 
495 	if (frame.skb)
496 		dev_kfree_skb(frame.skb);
497 	queue_work(hw_priv->workqueue, &hw_priv->scan.swork);
498 	scan_printk(XRADIO_DBG_NIY, "<-- Scheduled scan request.\n");
499 	return 0;
500 }
501 #endif /*ROAM_OFFLOAD*/
502 
xradio_scan_work(struct work_struct * work)503 void xradio_scan_work(struct work_struct *work)
504 {
505 	struct xradio_common *hw_priv = container_of(work,
506 						struct xradio_common,
507 						scan.work);
508 	struct xradio_vif *priv;
509 	struct ieee80211_channel **it;
510 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0))
511 	struct cfg80211_scan_info info;
512 #endif
513 	struct wsm_scan scan = {
514 
515 #ifndef SUPPORT_HT40
516 
517 		.scanType = WSM_SCAN_TYPE_FOREGROUND,
518 
519 #endif
520 
521 		.scanFlags = 0, /* TODO:COMBO */
522 		/*.scanFlags = WSM_SCAN_FLAG_SPLIT_METHOD, */
523 	};
524 	bool first_run;
525 	int i;
526 	const u32 ProbeRequestTime  = 2;
527 	const u32 ChannelRemainTime = 15;
528 	u32 maxChannelTime;
529 #ifdef CONFIG_XRADIO_TESTMODE
530 	int ret = 0;
531 	u16 advance_scan_req_channel = hw_priv->scan.begin[0]->hw_value;
532 #endif
533 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
534 
535 	priv = __xrwl_hwpriv_to_vifpriv(hw_priv, hw_priv->scan.if_id);
536 
537 	/*TODO: COMBO: introduce locking so vif is not removed in meanwhile */
538 	if (!priv) {
539 		scan_printk(XRADIO_DBG_WARN, "interface removed, "
540 			"ignoring scan work\n");
541 		return;
542 	}
543 
544 #ifdef SUPPORT_HT40
545 
546 	SET_SCAN_TYPE(&scan.scanFlags, WSM_SCAN_TYPE_FOREGROUND);
547 
548 #endif
549 
550 #ifdef SUPPORT_HT40
551 
552 	if (priv->if_id)
553 		SET_SCAN_FLAG(&scan.scanFlags, WSM_FLAG_MAC_INSTANCE_1);
554 	else
555 		CLR_SCAN_FLAG(&scan.scanFlags, WSM_FLAG_MAC_INSTANCE_1);
556 
557 #else
558 
559 	if (priv->if_id)
560 		scan.scanFlags |= WSM_FLAG_MAC_INSTANCE_1;
561 	else
562 		scan.scanFlags &= ~WSM_FLAG_MAC_INSTANCE_1;
563 
564 #endif
565 
566 	/* No need to set WSM_SCAN_FLAG_FORCE_BACKGROUND in BSS_LOSS work.*/
567 	/*
568 	xradio_for_each_vif(hw_priv, vif, i) {
569 		if (!vif)
570 			continue;
571 		if (vif->bss_loss_status > XRADIO_BSS_LOSS_NONE)
572 			scan.scanFlags |= WSM_SCAN_FLAG_FORCE_BACKGROUND;
573 	} */
574 
575 	first_run = (hw_priv->scan.begin == hw_priv->scan.curr &&
576 			hw_priv->scan.begin != hw_priv->scan.end);
577 	if (first_run) {
578 		/* Firmware gets crazy if scan request is sent
579 		 * when STA is joined but not yet associated.
580 		 * Force unjoin in this case. */
581 		if (cancel_delayed_work_sync(&priv->join_timeout) > 0)
582 			xradio_join_timeout(&priv->join_timeout.work);
583 	}
584 
585 	down(&hw_priv->conf_lock);
586 	if (first_run) {
587 
588 #ifdef CONFIG_XRADIO_TESTMODE
589 		/* Passive Scan - Serving Channel Request Handling */
590 		if (hw_priv->enable_advance_scan &&
591 		   (hw_priv->advanceScanElems.scanMode ==
592 		    XRADIO_SCAN_MEASUREMENT_PASSIVE) &&
593 		   (priv->join_status == XRADIO_JOIN_STATUS_STA) &&
594 		   (hw_priv->channel->hw_value == advance_scan_req_channel)) {
595 			/* If Advance Scan Request is for Serving Channel Device
596 			 * should be Active and Filtering Should be Disable */
597 			if (priv->powersave_mode.pmMode & WSM_PSM_PS) {
598 				struct wsm_set_pm pm = priv->powersave_mode;
599 				pm.pmMode = WSM_PSM_ACTIVE;
600 				wsm_set_pm(hw_priv, &pm, priv->if_id);
601 			}
602 			/* Disable Rx Beacon and Bssid filter */
603 			ret = xradio_disable_filtering(priv);
604 			if (ret)
605 				scan_printk(XRADIO_DBG_ERROR, "%s: Disable BSSID or Beacon"
606 					    "filtering failed: %d.\n", __func__, ret);
607 		} else if (hw_priv->enable_advance_scan  &&
608 			   (hw_priv->advanceScanElems.scanMode ==
609 			    XRADIO_SCAN_MEASUREMENT_PASSIVE) &&
610 			   (priv->join_status == XRADIO_JOIN_STATUS_STA)) {
611 			if (priv->join_status == XRADIO_JOIN_STATUS_STA &&
612 			    !(priv->powersave_mode.pmMode & WSM_PSM_PS)) {
613 				struct wsm_set_pm pm = priv->powersave_mode;
614 				pm.pmMode = WSM_PSM_PS;
615 				xradio_set_pm(priv, &pm);
616 			}
617 		} else {
618 #endif
619 
620 #if 0
621 			if (priv->join_status == XRADIO_JOIN_STATUS_STA &&
622 			    !(priv->powersave_mode.pmMode & WSM_PSM_PS)) {
623 				struct wsm_set_pm pm = priv->powersave_mode;
624 				pm.pmMode = WSM_PSM_PS;
625 				xradio_set_pm(priv, &pm);
626 			} else
627 #endif
628 			if (priv->join_status == XRADIO_JOIN_STATUS_MONITOR) {
629 				/* FW bug: driver has to restart p2p-dev mode
630 				 * after scan */
631 				xradio_disable_listening(priv);
632 			}
633 #ifdef CONFIG_XRADIO_TESTMODE
634 		}
635 #endif
636 	}
637 
638 	if (!hw_priv->scan.req || (hw_priv->scan.curr == hw_priv->scan.end)) {
639 
640 #ifdef CONFIG_XRADIO_TESTMODE
641 		if (hw_priv->enable_advance_scan &&
642 		    (hw_priv->advanceScanElems.scanMode ==
643 		     XRADIO_SCAN_MEASUREMENT_PASSIVE) &&
644 		    (priv->join_status == XRADIO_JOIN_STATUS_STA) &&
645 		    (hw_priv->channel->hw_value == advance_scan_req_channel)) {
646 			/* WSM Lock should be held here for WSM APIs */
647 			wsm_vif_lock_tx(priv);
648 
649 			/* wsm_lock_tx(priv); */
650 			/* Once Duration is Over, enable filtering
651 			 * and Revert Back Power Save */
652 			if (priv->powersave_mode.pmMode & WSM_PSM_PS)
653 				wsm_set_pm(hw_priv, &priv->powersave_mode, priv->if_id);
654 			xradio_update_filtering(priv);
655 		} else if (!hw_priv->enable_advance_scan) {
656 #endif
657 			if (hw_priv->scan.output_power != hw_priv->output_power) {
658 			/* TODO:COMBO: Change when mac80211 implementation
659 			 * is available for output power also */
660 #ifdef P2P_MULTIVIF
661 				WARN_ON(wsm_set_output_power(hw_priv,
662 							     hw_priv->output_power * 10,
663 							     priv->if_id ? 1 : 0));
664 #else
665 				WARN_ON(wsm_set_output_power(hw_priv,
666 							     hw_priv->output_power * 10,
667 							     priv->if_id));
668 #endif
669 			}
670 #ifdef CONFIG_XRADIO_TESTMODE
671 		}
672 #endif
673 
674 #if 0
675 		if (priv->join_status == XRADIO_JOIN_STATUS_STA &&
676 		    !(priv->powersave_mode.pmMode & WSM_PSM_PS))
677 			xradio_set_pm(priv, &priv->powersave_mode);
678 #endif
679 
680 		if (hw_priv->scan.status < 0)
681 			scan_printk(XRADIO_DBG_ERROR, "Scan failed (%d).\n",
682 				    hw_priv->scan.status);
683 		else if (hw_priv->scan.req)
684 			scan_printk(XRADIO_DBG_NIY, "Scan completed.\n");
685 		else
686 			scan_printk(XRADIO_DBG_NIY, "Scan canceled.\n");
687 
688 		hw_priv->scan.req = NULL;
689 		xradio_scan_restart_delayed(priv);
690 #ifdef CONFIG_XRADIO_TESTMODE
691 		hw_priv->enable_advance_scan = false;
692 #endif /* CONFIG_XRADIO_TESTMODE */
693 		wsm_unlock_tx(hw_priv);
694 		up(&hw_priv->conf_lock);
695 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0))
696 		memset(&info, 0, sizeof(info));
697 		info.aborted = hw_priv->scan.status ? 1 : 0;
698 		mac80211_scan_completed(hw_priv->hw, &info);
699 #else
700 		mac80211_scan_completed(hw_priv->hw, hw_priv->scan.status ? 1 : 0);
701 #endif
702 		up(&hw_priv->scan.lock);
703 #ifdef SCAN_FAILED_WORKAROUND_OF_FW_EXCEPTION
704 		/*Timeout waiting for scan complete notification all the time,
705 		 * then driver restarts.*/
706 		if (hw_priv->scan.scan_failed_cnt >= 5) {
707 			scan_printk(XRADIO_DBG_ERROR, "%s:Too many scan timeout=%d",
708 					__func__, hw_priv->scan.scan_failed_cnt);
709 			hw_priv->bh_error = 1 ;
710 			hw_priv->scan.scan_failed_cnt = 0;
711 		}
712 #endif
713 		return;
714 
715 	} else {
716 		struct ieee80211_channel *first = *hw_priv->scan.curr;
717 		for (it = hw_priv->scan.curr + 1, i = 1;
718 		     it != hw_priv->scan.end && i < WSM_SCAN_MAX_NUM_OF_CHANNELS;
719 		     ++it, ++i) {
720 			if ((*it)->band != first->band)
721 				break;
722 			if (((*it)->flags ^ first->flags) & (IEEE80211_CHAN_NO_IR |
723 						IEEE80211_CHAN_RADAR))
724 				break;
725 			if (!(first->flags & (IEEE80211_CHAN_NO_IR |
726 						IEEE80211_CHAN_RADAR)) &&
727 			    (*it)->max_power != first->max_power)
728 				break;
729 		}
730 		scan.band = first->band;
731 
732 #ifdef SUPPORT_HT40
733 
734 		if (hw_priv->scan.req->no_cck)
735 			scan.TransmitRateEntry =
736 				((RATE_MODEM_LEGACY  << MODEMTYPE_SHIFT)
737 				| (RATE_BANDWIDTH_20M << BANDWIDTH_SHIFT)
738 				| (WSM_TRANSMIT_RATE_6 << 4));
739 		else
740 			scan.TransmitRateEntry =
741 				((RATE_MODEM_LEGACY  << MODEMTYPE_SHIFT)
742 				| (RATE_BANDWIDTH_20M << BANDWIDTH_SHIFT)
743 				| (WSM_TRANSMIT_RATE_1 << 4));
744 
745 #else
746 
747 		if (hw_priv->scan.req->no_cck)
748 			scan.maxTransmitRate = WSM_TRANSMIT_RATE_6;
749 		else
750 			scan.maxTransmitRate = WSM_TRANSMIT_RATE_1;
751 
752 #endif
753 
754 #ifdef CONFIG_XRADIO_TESTMODE
755 		if (hw_priv->enable_advance_scan) {
756 			if (hw_priv->advanceScanElems.scanMode ==
757 				XRADIO_SCAN_MEASUREMENT_PASSIVE)
758 				scan.numOfProbeRequests = 0;
759 			else
760 				scan.numOfProbeRequests = 1;
761 		} else {
762 #endif
763 			/* TODO: Is it optimal? */
764 			scan.numOfProbeRequests =
765 			    (first->flags & (IEEE80211_CHAN_NO_IR |
766 						IEEE80211_CHAN_RADAR)) ? 0 : 4;
767 #ifdef CONFIG_XRADIO_TESTMODE
768 		}
769 #endif /* CONFIG_XRADIO_TESTMODE */
770 
771 		scan.numOfSSIDs = hw_priv->scan.n_ssids;
772 		scan.ssids = &hw_priv->scan.ssids[0];
773 		scan.numOfChannels = it - hw_priv->scan.curr;
774 		/* TODO: Is it optimal? */
775 		scan.probeDelay = 200;
776 
777 		scan_printk(XRADIO_DBG_NIY, "Scan split ch(%d).\n", scan.numOfChannels);
778 		/* It is not stated in WSM specification, however
779 		 * FW team says that driver may not use FG scan
780 		 * when joined. */
781 		if (priv->join_status == XRADIO_JOIN_STATUS_STA) {
782 
783 #ifdef SUPPORT_HT40
784 
785 			SET_SCAN_TYPE(&scan.scanFlags, WSM_SCAN_TYPE_BACKGROUND);
786 			SET_SCAN_FLAG(&scan.scanFlags, WSM_SCAN_FLAG_FORCE_BACKGROUND);
787 
788 #else
789 
790 			scan.scanType = WSM_SCAN_TYPE_BACKGROUND;
791 			scan.scanFlags = WSM_SCAN_FLAG_FORCE_BACKGROUND;
792 
793 #endif
794 		}
795 		scan.ch = (struct wsm_scan_ch *)xr_kzalloc(
796 				sizeof(struct wsm_scan_ch) * (it - hw_priv->scan.curr), false);
797 		if (!scan.ch) {
798 			hw_priv->scan.status = -ENOMEM;
799 			scan_printk(XRADIO_DBG_ERROR, "xr_kzalloc wsm_scan_ch failed.\n");
800 			goto fail;
801 		}
802 		maxChannelTime = (scan.numOfSSIDs * scan.numOfProbeRequests *
803 				  ProbeRequestTime) + ChannelRemainTime;
804 		maxChannelTime = (maxChannelTime < 100) ? 100 : maxChannelTime;
805 		for (i = 0; i < scan.numOfChannels; ++i) {
806 			scan.ch[i].number = hw_priv->scan.curr[i]->hw_value;
807 
808 #ifdef CONFIG_XRADIO_TESTMODE
809 			if (hw_priv->enable_advance_scan) {
810 				scan.ch[i].minChannelTime = hw_priv->advanceScanElems.duration;
811 				scan.ch[i].maxChannelTime = hw_priv->advanceScanElems.duration;
812 			} else {
813 #endif
814 				if (hw_priv->scan.curr[i]->flags &
815 					(IEEE80211_CHAN_NO_IR |
816 						IEEE80211_CHAN_RADAR)) {
817 					scan.ch[i].minChannelTime = 50;
818 					scan.ch[i].maxChannelTime = 110;
819 				} else {
820 					scan.ch[i].minChannelTime = 50;
821 					scan.ch[i].maxChannelTime = maxChannelTime;
822 				}
823 
824 #ifdef CONFIG_XRADIO_TESTMODE
825 			}
826 #endif
827 		}
828 
829 #ifdef CONFIG_XRADIO_TESTMODE
830 		if (!hw_priv->enable_advance_scan) {
831 #endif
832 			if (!(first->flags & (IEEE80211_CHAN_NO_IR |
833 						IEEE80211_CHAN_RADAR)) &&
834 			    hw_priv->scan.output_power != first->max_power) {
835 			    hw_priv->scan.output_power = first->max_power;
836 				/* TODO:COMBO: Change after mac80211 implementation
837 				* complete */
838 #ifdef P2P_MULTIVIF
839 				WARN_ON(wsm_set_output_power(hw_priv,
840 							     hw_priv->scan.output_power * 10,
841 							     priv->if_id ? 1 : 0));
842 #else
843 				WARN_ON(wsm_set_output_power(hw_priv,
844 							     hw_priv->scan.output_power * 10,
845 							     priv->if_id));
846 #endif
847 			}
848 #ifdef CONFIG_XRADIO_TESTMODE
849 		}
850 #endif
851 
852 #ifdef CONFIG_XRADIO_TESTMODE
853 		if (hw_priv->enable_advance_scan &&
854 			(hw_priv->advanceScanElems.scanMode ==
855 				XRADIO_SCAN_MEASUREMENT_PASSIVE) &&
856 			(priv->join_status == XRADIO_JOIN_STATUS_STA) &&
857 			(hw_priv->channel->hw_value == advance_scan_req_channel)) {
858 				/* Start Advance Scan Timer */
859 				hw_priv->scan.status = xradio_advance_scan_start(hw_priv);
860 				wsm_unlock_tx(hw_priv);
861 		} else
862 #endif
863 			down(&hw_priv->scan.status_lock);
864 			hw_priv->scan.status = xradio_scan_start(priv, &scan);
865 
866 		kfree(scan.ch);
867 		if (WARN_ON(hw_priv->scan.status)) {
868 			scan_printk(XRADIO_DBG_ERROR, "scan failed, status=%d.\n",
869 				    hw_priv->scan.status);
870 			up(&hw_priv->scan.status_lock);
871 			goto fail;
872 		}
873 		up(&hw_priv->scan.status_lock);
874 		hw_priv->scan.curr = it;
875 	}
876 	up(&hw_priv->conf_lock);
877 	return;
878 
879 fail:
880 	hw_priv->scan.curr = hw_priv->scan.end;
881 	up(&hw_priv->conf_lock);
882 	if (queue_work(hw_priv->workqueue, &hw_priv->scan.work) <= 0)
883 		scan_printk(XRADIO_DBG_ERROR, "%s queue scan work failed\n", __func__);
884 	return;
885 }
886 
887 #ifdef ROAM_OFFLOAD
xradio_sched_scan_work(struct work_struct * work)888 void xradio_sched_scan_work(struct work_struct *work)
889 {
890 	struct xradio_common *hw_priv = container_of(work, struct xradio_common,
891 		scan.swork);
892 	struct wsm_scan scan;
893 	struct wsm_ssid scan_ssid;
894 	int i;
895 	struct xradio_vif *priv = NULL;
896 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
897 
898 	priv = xrwl_hwpriv_to_vifpriv(hw_priv, hw_priv->scan.if_id);
899 	if (unlikely(!priv)) {
900 		WARN_ON(1);
901 		return;
902 	}
903 
904 	spin_unlock(&priv->vif_lock);
905 	/* Firmware gets crazy if scan request is sent
906 	 * when STA is joined but not yet associated.
907 	 * Force unjoin in this case. */
908 	if (cancel_delayed_work_sync(&priv->join_timeout) > 0) {
909 		xradio_join_timeout(&priv->join_timeout.work);
910 	}
911 	down(&hw_priv->conf_lock);
912 	hw_priv->auto_scanning = 1;
913 	scan.band = 0;
914 
915 #ifdef SUPPORT_HT40
916 
917 	if (priv->join_status == XRADIO_JOIN_STATUS_STA) /* auto background */
918 		SET_SCAN_TYPE(&scan.scanFlags, WSM_SCAN_TYPE_AUTOBACKGROUND);
919 	else /* auto foreground */
920 		SET_SCAN_TYPE(&scan.scanFlags, WSM_SCAN_TYPE_AUTOFOREGROUND);
921 
922 	/* bit 0 set => forced background scan */
923 	CLR_SCAN_FLAG(&scan.scanFlags, SCANFLAG_MASK);
924 	SET_SCAN_FLAG(&scan.scanFlags, WSM_SCAN_FLAG_FORCE_BACKGROUND);
925 
926 #else
927 
928 	if (priv->join_status == XRADIO_JOIN_STATUS_STA)
929 		scan.scanType = 3; /* auto background */
930 	else
931 		scan.scanType = 2; /* auto foreground */
932 
933 	scan.scanFlags = 0x01; /* bit 0 set => forced background scan */
934 
935 #endif
936 
937 #ifdef SUPPORT_HT40
938 
939 	scan.TransmitRateEntry = ((RATE_MODEM_LEGACY  << MODEMTYPE_SHIFT)
940 				| (RATE_BANDWIDTH_20M << BANDWIDTH_SHIFT)
941 				| (AG_RATE_INDEX << 4));
942 
943 #else
944 
945 	scan.maxTransmitRate = WSM_TRANSMIT_RATE_6;
946 
947 #endif
948 
949 	scan.autoScanInterval = (0xba << 24)|(30 * 1024); /* 30 seconds, -70 rssi */
950 	scan.numOfProbeRequests = 1;
951 	/*scan.numOfChannels = 11;*/
952 	scan.numOfChannels = hw_priv->num_scanchannels;
953 	scan.numOfSSIDs = 1;
954 	scan.probeDelay = 100;
955 	scan_ssid.length = priv->ssid_length;
956 	memcpy(scan_ssid.ssid, priv->ssid, priv->ssid_length);
957 	scan.ssids = &scan_ssid;
958 
959 	scan.ch = xr_kzalloc(sizeof(struct wsm_scan_ch[scan.numOfChannels]), false);
960 	if (!scan.ch) {
961 		scan_printk(XRADIO_DBG_ERROR, "xr_kzalloc wsm_scan_ch failed.\n");
962 		hw_priv->scan.status = -ENOMEM;
963 		goto fail;
964 	}
965 
966 	for (i = 0; i < scan.numOfChannels; i++) {
967 		scan.ch[i].number = hw_priv->scan_channels[i].number;
968 		scan.ch[i].minChannelTime = hw_priv->scan_channels[i].minChannelTime;
969 		scan.ch[i].maxChannelTime = hw_priv->scan_channels[i].maxChannelTime;
970 		scan.ch[i].txPowerLevel = hw_priv->scan_channels[i].txPowerLevel;
971 	}
972 
973 #if 0
974 	for (i = 1; i <= scan.numOfChannels; i++) {
975 		scan.ch[i-1].number = i;
976 		scan.ch[i-1].minChannelTime = 10;
977 		scan.ch[i-1].maxChannelTime = 40;
978 	}
979 #endif
980 
981 	hw_priv->scan.status = xradio_sched_scan_start(priv, &scan);
982 	kfree(scan.ch);
983 	if (hw_priv->scan.status) {
984 		scan_printk(XRADIO_DBG_ERROR, "scan failed, status=%d.\n",
985 				    hw_priv->scan.status);
986 		goto fail;
987 	}
988 	up(&hw_priv->conf_lock);
989 	return;
990 
991 fail:
992 	up(&hw_priv->conf_lock);
993 	queue_work(hw_priv->workqueue, &hw_priv->scan.swork);
994 	return;
995 }
996 
xradio_hw_sched_scan_stop(struct xradio_common * hw_priv)997 void xradio_hw_sched_scan_stop(struct xradio_common *hw_priv)
998 {
999 	struct xradio_vif *priv = NULL;
1000 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1001 	priv = xrwl_hwpriv_to_vifpriv(hw_priv, hw_priv->scan.if_id);
1002 	if (unlikely(!priv))
1003 		return;
1004 
1005 	spin_unlock(&priv->vif_lock);
1006 	wsm_stop_scan(hw_priv, priv->if_id);
1007 
1008 	return;
1009 }
1010 #endif /*ROAM_OFFLOAD*/
1011 
1012 
xradio_scan_restart_delayed(struct xradio_vif * priv)1013 static void xradio_scan_restart_delayed(struct xradio_vif *priv)
1014 {
1015 	struct xradio_common *hw_priv = xrwl_vifpriv_to_hwpriv(priv);
1016 	struct xradio_vif *tmp_vif = NULL;
1017 	int i = 0;
1018 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1019 
1020 	if (priv->delayed_link_loss) {
1021 		int tmo = hw_priv->scan.direct_probe ? 0 : priv->cqm_beacon_loss_count;
1022 
1023 		priv->delayed_link_loss = 0;
1024 		/* Restart beacon loss timer and requeue
1025 		   BSS loss work. */
1026 		scan_printk(XRADIO_DBG_WARN, "[CQM] Requeue BSS loss in %d "
1027 			"beacons.\n", tmo);
1028 		cancel_delayed_work_sync(&priv->bss_loss_work);
1029 		queue_delayed_work(hw_priv->workqueue, &priv->bss_loss_work,
1030 			tmo * HZ / 10);
1031 
1032 	}
1033 
1034 	/* FW bug: driver has to restart p2p-dev mode after scan. */
1035 	if (priv->join_status == XRADIO_JOIN_STATUS_MONITOR) {
1036 		/*xradio_enable_listening(priv);*/
1037 		WARN_ON(1);
1038 		xradio_update_filtering(priv);
1039 		scan_printk(XRADIO_DBG_WARN, "driver has to restart "
1040 			"p2p-dev mode after scan");
1041 	}
1042 
1043 	for (i = 0; i < 2; i++) {
1044 		tmp_vif = __xrwl_hwpriv_to_vifpriv(hw_priv, i);
1045 		if (tmp_vif == NULL)
1046 			continue;
1047 		if (atomic_xchg(&tmp_vif->delayed_unjoin, 0)) {
1048 			if (queue_work(hw_priv->workqueue, &tmp_vif->unjoin_work) <= 0)
1049 				wsm_unlock_tx(hw_priv);
1050 		}
1051 	}
1052 }
1053 
xradio_scan_complete(struct xradio_common * hw_priv,int if_id)1054 static void xradio_scan_complete(struct xradio_common *hw_priv, int if_id)
1055 {
1056 	struct xradio_vif *priv;
1057 	atomic_xchg(&hw_priv->recent_scan, 0);
1058 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1059 
1060 	if (hw_priv->scan.direct_probe) {
1061 		down(&hw_priv->conf_lock);
1062 		priv = __xrwl_hwpriv_to_vifpriv(hw_priv, if_id);
1063 		if (priv) {
1064 			scan_printk(XRADIO_DBG_NIY, "Direct probe complete.\n");
1065 			xradio_scan_restart_delayed(priv);
1066 		} else {
1067 			scan_printk(XRADIO_DBG_WARN,
1068 				    "Direct probe complete without interface!\n");
1069 		}
1070 		up(&hw_priv->conf_lock);
1071 		hw_priv->scan.direct_probe = 0;
1072 		up(&hw_priv->scan.lock);
1073 		wsm_unlock_tx(hw_priv);
1074 	} else {
1075 		xradio_scan_work(&hw_priv->scan.work);
1076 	}
1077 }
1078 
xradio_scan_complete_cb(struct xradio_common * hw_priv,struct wsm_scan_complete * arg)1079 void xradio_scan_complete_cb(struct xradio_common *hw_priv,
1080 			struct wsm_scan_complete *arg)
1081 {
1082 	struct xradio_vif *priv = xrwl_hwpriv_to_vifpriv(hw_priv,
1083 					hw_priv->scan.if_id);
1084 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1085 
1086 	if (unlikely(!priv))
1087 		return;
1088 
1089 #ifdef ROAM_OFFLOAD
1090 	if (hw_priv->auto_scanning)
1091 		schedule_delayed_work(&hw_priv->scan.timeout, 0);
1092 #endif /*ROAM_OFFLOAD*/
1093 
1094 	if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED)) {
1095 		/* STA is stopped. */
1096 		spin_unlock(&priv->vif_lock);
1097 		scan_printk(XRADIO_DBG_WARN, "%s: priv->mode UNSPECIFIED.\n",
1098 			    __func__);
1099 		return;
1100 	}
1101 	spin_unlock(&priv->vif_lock);
1102 
1103 	down(&hw_priv->scan.status_lock);
1104 	if (hw_priv->scan.status == -ETIMEDOUT) {
1105 		up(&hw_priv->scan.status_lock);
1106 		scan_printk(XRADIO_DBG_WARN, "Scan timeout already occured. "
1107 			"Don't cancel work");
1108 	} else {
1109 		hw_priv->scan.status = 1;
1110 		up(&hw_priv->scan.status_lock);
1111 		if (cancel_delayed_work_sync(&hw_priv->scan.timeout) > 0)
1112 			schedule_delayed_work(&hw_priv->scan.timeout, 0);
1113 	}
1114 
1115 }
1116 
xradio_scan_timeout(struct work_struct * work)1117 void xradio_scan_timeout(struct work_struct *work)
1118 {
1119 	struct xradio_common *hw_priv =
1120 		container_of(work, struct xradio_common, scan.timeout.work);
1121 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1122 
1123 #ifdef ROAM_OFFLOAD
1124        if (hw_priv->auto_scanning == 0)
1125                up(&hw_priv->wsm_oper_lock);
1126 #else
1127        up(&hw_priv->wsm_oper_lock);
1128 #endif /*ROAM_OFFLOAD*/
1129 
1130 	if (likely(atomic_xchg(&hw_priv->scan.in_progress, 0))) {
1131 		down(&hw_priv->scan.status_lock);
1132 		if (hw_priv->scan.status > 0) {
1133 			hw_priv->scan.status = 0;
1134 			up(&hw_priv->scan.status_lock);
1135 #ifdef SCAN_FAILED_WORKAROUND_OF_FW_EXCEPTION
1136 			hw_priv->scan.scan_failed_cnt = 0;
1137 #endif
1138 		} else if (!hw_priv->scan.status) {
1139 			scan_printk(XRADIO_DBG_WARN, "Timeout waiting for scan "
1140 				    "complete notification.\n");
1141 #ifdef SCAN_FAILED_WORKAROUND_OF_FW_EXCEPTION
1142 			if (time_after(jiffies, (hw_priv->scan.scan_failed_timestamp +
1143 						SCAN_DEFAULT_TIMEOUT*HZ/1000))) {
1144 				if (!hw_priv->BT_active)
1145 					hw_priv->scan.scan_failed_cnt += 1;
1146 				scan_printk(XRADIO_DBG_WARN, "%s:scan timeout cnt=%d",
1147 					__func__, hw_priv->scan.scan_failed_cnt);
1148 			}
1149 #endif
1150 			hw_priv->scan.status = -ETIMEDOUT;
1151 			up(&hw_priv->scan.status_lock);
1152 			hw_priv->scan.curr   = hw_priv->scan.end;
1153 			WARN_ON(wsm_stop_scan(hw_priv, hw_priv->scan.if_id ? 1 : 0));
1154 		}
1155 		xradio_scan_complete(hw_priv, hw_priv->scan.if_id);
1156 #ifdef ROAM_OFFLOAD
1157 	} else if (hw_priv->auto_scanning) {
1158 		hw_priv->auto_scanning = 0;
1159 		mac80211_sched_scan_results(hw_priv->hw);
1160 #endif /*ROAM_OFFLOAD*/
1161 	}
1162 }
1163 
1164 #ifdef CONFIG_XRADIO_TESTMODE
xradio_advance_scan_timeout(struct work_struct * work)1165 void xradio_advance_scan_timeout(struct work_struct *work)
1166 {
1167 	struct xradio_common *hw_priv =
1168 		container_of(work, struct xradio_common, advance_scan_timeout.work);
1169 
1170 	struct xradio_vif *priv = xrwl_hwpriv_to_vifpriv(hw_priv,
1171 					hw_priv->scan.if_id);
1172 	scan_printk(XRADIO_DBG_TRC, "%s\n", __func__);
1173 
1174 	if (WARN_ON(!priv))
1175 		return;
1176 	spin_unlock(&priv->vif_lock);
1177 
1178 	hw_priv->scan.status = 0;
1179 	if (hw_priv->advanceScanElems.scanMode ==
1180 	    XRADIO_SCAN_MEASUREMENT_PASSIVE) {
1181 		/* Passive Scan on Serving Channel
1182 		 * Timer Expire */
1183 		xradio_scan_complete(hw_priv, hw_priv->scan.if_id);
1184 	} else {
1185 		/* Active Scan on Serving Channel
1186 		 * Timer Expire */
1187 		down(&hw_priv->conf_lock);
1188 		/*wsm_lock_tx(priv);*/
1189 		wsm_vif_lock_tx(priv);
1190 		/* Once Duration is Over, enable filtering
1191 		 * and Revert Back Power Save */
1192 		if ((priv->powersave_mode.pmMode & WSM_PSM_PS))
1193 			wsm_set_pm(hw_priv, &priv->powersave_mode, priv->if_id);
1194 		hw_priv->scan.req = NULL;
1195 		xradio_update_filtering(priv);
1196 		hw_priv->enable_advance_scan = false;
1197 		wsm_unlock_tx(hw_priv);
1198 		up(&hw_priv->conf_lock);
1199 		mac80211_scan_completed(hw_priv->hw,
1200 				 hw_priv->scan.status ? true : false);
1201 		up(&hw_priv->scan.lock);
1202 	}
1203 }
1204 #endif
1205 
xradio_probe_work(struct work_struct * work)1206 void xradio_probe_work(struct work_struct *work)
1207 {
1208 	struct xradio_common *hw_priv =
1209 		container_of(work, struct xradio_common, scan.probe_work.work);
1210 	struct xradio_vif *priv;
1211 	u8 queueId = xradio_queue_get_queue_id(hw_priv->pending_frame_id);
1212 	struct xradio_queue *queue = &hw_priv->tx_queue[queueId];
1213 	const struct xradio_txpriv *txpriv;
1214 	struct wsm_tx *wsm;
1215 	struct wsm_template_frame frame = {
1216 		.frame_type = WSM_FRAME_TYPE_PROBE_REQUEST,
1217 	};
1218 	struct wsm_ssid ssids[1] = {{
1219 		.length = 0,
1220 	} };
1221 	struct wsm_scan_ch ch[1] = {{
1222 		.minChannelTime = 50,
1223 		.maxChannelTime = 80,
1224 	} };
1225 	struct wsm_scan scan = {
1226 
1227 #ifdef SUPPORT_HT40
1228 
1229 		.scanFlags = 0,
1230 
1231 #else
1232 
1233 		.scanType = WSM_SCAN_TYPE_FOREGROUND,
1234 
1235 #endif
1236 
1237 		.numOfProbeRequests = 1,
1238 		.probeDelay = 0,
1239 		.numOfChannels = 1,
1240 		.ssids = ssids,
1241 		.ch = ch,
1242 	};
1243 	u8 *ies;
1244 	size_t ies_len;
1245 	int ret = 1;
1246 	scan_printk(XRADIO_DBG_NIY, "%s:Direct probe.\n", __func__);
1247 
1248 	SYS_BUG(queueId >= 4);
1249 	SYS_BUG(!hw_priv->channel);
1250 
1251 	down(&hw_priv->conf_lock);
1252 	if (unlikely(down_trylock(&hw_priv->scan.lock))) {
1253 		/* Scan is already in progress. Requeue self. */
1254 		schedule();
1255 		queue_delayed_work(hw_priv->workqueue, &hw_priv->scan.probe_work,
1256 				   HZ / 10);
1257 		up(&hw_priv->conf_lock);
1258 		return;
1259 	}
1260 
1261 	if (xradio_queue_get_skb(queue,	hw_priv->pending_frame_id,
1262 				     &frame.skb, &txpriv)) {
1263 		up(&hw_priv->scan.lock);
1264 		up(&hw_priv->conf_lock);
1265 		wsm_unlock_tx(hw_priv);
1266 		scan_printk(XRADIO_DBG_ERROR, "%s:xradio_queue_get_skb error!\n",
1267 			    __func__);
1268 		return;
1269 	}
1270 	priv = __xrwl_hwpriv_to_vifpriv(hw_priv, txpriv->if_id);
1271 	if (!priv) {
1272 		up(&hw_priv->scan.lock);
1273 		up(&hw_priv->conf_lock);
1274 		scan_printk(XRADIO_DBG_ERROR, "%s:priv error!\n", __func__);
1275 		return;
1276 	}
1277 	wsm = (struct wsm_tx *)frame.skb->data;
1278 
1279 #ifdef SUPPORT_HT40
1280 
1281 	scan.TransmitRateEntry = wsm->TxRateEntry;
1282 
1283 #else
1284 
1285 	scan.maxTransmitRate = wsm->maxTxRate;
1286 
1287 #endif
1288 
1289 	scan.band = (hw_priv->channel->band == NL80211_BAND_5GHZ) ?
1290 		     WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
1291 
1292 #ifdef SUPPORT_HT40
1293 
1294 	SET_SCAN_TYPE(&scan.scanFlags, WSM_SCAN_TYPE_FOREGROUND);
1295 	if (priv->join_status == XRADIO_JOIN_STATUS_STA) {
1296 		SET_SCAN_TYPE(&scan.scanFlags, WSM_SCAN_TYPE_BACKGROUND);
1297 		SET_SCAN_FLAG(&scan.scanFlags, WSM_SCAN_FLAG_FORCE_BACKGROUND);
1298 		if (priv->if_id)
1299 			SET_SCAN_FLAG(&scan.scanFlags, WSM_FLAG_MAC_INSTANCE_1);
1300 		else
1301 			CLR_SCAN_FLAG(&scan.scanFlags, WSM_FLAG_MAC_INSTANCE_1);
1302 	}
1303 
1304 #else
1305 
1306 	if (priv->join_status == XRADIO_JOIN_STATUS_STA) {
1307 		scan.scanType  = WSM_SCAN_TYPE_BACKGROUND;
1308 		scan.scanFlags = WSM_SCAN_FLAG_FORCE_BACKGROUND;
1309 		if (priv->if_id)
1310 			scan.scanFlags |= WSM_FLAG_MAC_INSTANCE_1;
1311 		else
1312 			scan.scanFlags &= ~WSM_FLAG_MAC_INSTANCE_1;
1313 	}
1314 
1315 #endif
1316 
1317 	/* No need to set WSM_SCAN_FLAG_FORCE_BACKGROUND in BSS_LOSS work.*/
1318 	 /*
1319 	xradio_for_each_vif(hw_priv, vif, i) {
1320 		if (!vif)
1321 			continue;
1322 		if (vif->bss_loss_status > XRADIO_BSS_LOSS_NONE)
1323 			scan.scanFlags |= WSM_SCAN_FLAG_FORCE_BACKGROUND;
1324 	} */
1325 
1326 	ch[0].number = hw_priv->channel->hw_value;
1327 	skb_pull(frame.skb, txpriv->offset);
1328 	ies = &frame.skb->data[sizeof(struct ieee80211_hdr_3addr)];
1329 	ies_len = frame.skb->len - sizeof(struct ieee80211_hdr_3addr);
1330 
1331 	if (ies_len) {
1332 		u8 *ssidie = (u8 *)cfg80211_find_ie(WLAN_EID_SSID, ies, ies_len);
1333 		if (ssidie && ssidie[1] && ssidie[1] <= sizeof(ssids[0].ssid)) {
1334 			u8 *nextie = &ssidie[2 + ssidie[1]];
1335 			/* Remove SSID from the IE list. It has to be provided
1336 			 * as a separate argument in xradio_scan_start call */
1337 
1338 			/* Store SSID localy */
1339 			ssids[0].length = ssidie[1];
1340 			memcpy(ssids[0].ssid, &ssidie[2], ssids[0].length);
1341 			scan.numOfSSIDs = 1;
1342 
1343 			/* Remove SSID from IE list */
1344 			ssidie[1] = 0;
1345 			memmove(&ssidie[2], nextie, &ies[ies_len] - nextie);
1346 			skb_trim(frame.skb, frame.skb->len - ssids[0].length);
1347 		}
1348 	}
1349 
1350 	if (priv->if_id == 0)
1351 		xradio_remove_wps_p2p_ie(&frame);
1352 
1353 	/* FW bug: driver has to restart p2p-dev mode after scan */
1354 	if (priv->join_status == XRADIO_JOIN_STATUS_MONITOR) {
1355 		WARN_ON(1);
1356 		/*xradio_disable_listening(priv);*/
1357 	}
1358 	ret = WARN_ON(wsm_set_template_frame(hw_priv, &frame,
1359 				priv->if_id));
1360 
1361 	hw_priv->scan.direct_probe = 1;
1362 	hw_priv->scan.if_id = priv->if_id;
1363 	if (!ret) {
1364 		wsm_flush_tx(hw_priv);
1365 		ret = WARN_ON(xradio_scan_start(priv, &scan));
1366 	}
1367 	up(&hw_priv->conf_lock);
1368 
1369 	skb_push(frame.skb, txpriv->offset);
1370 	if (!ret)
1371 		IEEE80211_SKB_CB(frame.skb)->flags |= IEEE80211_TX_STAT_ACK;
1372 #ifdef CONFIG_XRADIO_TESTMODE
1373 		SYS_BUG(xradio_queue_remove(hw_priv, queue,
1374 					    hw_priv->pending_frame_id));
1375 #else
1376 		SYS_BUG(xradio_queue_remove(queue, hw_priv->pending_frame_id));
1377 #endif
1378 
1379 	if (ret) {
1380 		hw_priv->scan.direct_probe = 0;
1381 		up(&hw_priv->scan.lock);
1382 		wsm_unlock_tx(hw_priv);
1383 	}
1384 
1385 	return;
1386 }
1387