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