Lines Matching full:scan
3 * Scan implementation for ST-Ericsson CW1200 mac80211 drivers
11 #include "scan.h"
17 static int cw1200_scan_start(struct cw1200_common *priv, struct wsm_scan *scan) in cw1200_scan_start() argument
30 wiphy_dbg(priv->hw->wiphy, "[SCAN] hw req, type %d, %d channels, flags: 0x%x.\n", in cw1200_scan_start()
31 scan->type, scan->num_channels, scan->flags); in cw1200_scan_start()
33 for (i = 0; i < scan->num_channels; ++i) in cw1200_scan_start()
34 tmo += scan->ch[i].max_chan_time + 10; in cw1200_scan_start()
37 atomic_set(&priv->scan.in_progress, 1); in cw1200_scan_start()
40 queue_delayed_work(priv->workqueue, &priv->scan.timeout, in cw1200_scan_start()
42 ret = wsm_scan(priv, scan); in cw1200_scan_start()
44 atomic_set(&priv->scan.in_progress, 0); in cw1200_scan_start()
45 cancel_delayed_work_sync(&priv->scan.timeout); in cw1200_scan_start()
65 /* Scan when P2P_GO corrupt firmware MiniAP mode */ in cw1200_hw_scan()
72 wiphy_dbg(hw->wiphy, "[SCAN] Scan request for %d SSIDs.\n", in cw1200_hw_scan()
79 down(&priv->scan.lock); in cw1200_hw_scan()
86 up(&priv->scan.lock); in cw1200_hw_scan()
101 up(&priv->scan.lock); in cw1200_hw_scan()
107 BUG_ON(priv->scan.req); in cw1200_hw_scan()
108 priv->scan.req = req; in cw1200_hw_scan()
109 priv->scan.n_ssids = 0; in cw1200_hw_scan()
110 priv->scan.status = 0; in cw1200_hw_scan()
111 priv->scan.begin = &req->channels[0]; in cw1200_hw_scan()
112 priv->scan.curr = priv->scan.begin; in cw1200_hw_scan()
113 priv->scan.end = &req->channels[req->n_channels]; in cw1200_hw_scan()
114 priv->scan.output_power = priv->output_power; in cw1200_hw_scan()
117 struct wsm_ssid *dst = &priv->scan.ssids[priv->scan.n_ssids]; in cw1200_hw_scan()
120 ++priv->scan.n_ssids; in cw1200_hw_scan()
126 queue_work(priv->workqueue, &priv->scan.work); in cw1200_hw_scan()
133 scan.work); in cw1200_scan_work()
135 struct wsm_scan scan = { in cw1200_scan_work() local
139 bool first_run = (priv->scan.begin == priv->scan.curr && in cw1200_scan_work()
140 priv->scan.begin != priv->scan.end); in cw1200_scan_work()
144 /* Firmware gets crazy if scan request is sent in cw1200_scan_work()
162 * after scan in cw1200_scan_work()
168 if (!priv->scan.req || (priv->scan.curr == priv->scan.end)) { in cw1200_scan_work()
170 .aborted = priv->scan.status ? 1 : 0, in cw1200_scan_work()
173 if (priv->scan.output_power != priv->output_power) in cw1200_scan_work()
179 if (priv->scan.status < 0) in cw1200_scan_work()
181 "[SCAN] Scan failed (%d).\n", in cw1200_scan_work()
182 priv->scan.status); in cw1200_scan_work()
183 else if (priv->scan.req) in cw1200_scan_work()
185 "[SCAN] Scan completed.\n"); in cw1200_scan_work()
188 "[SCAN] Scan canceled.\n"); in cw1200_scan_work()
190 priv->scan.req = NULL; in cw1200_scan_work()
195 up(&priv->scan.lock); in cw1200_scan_work()
198 struct ieee80211_channel *first = *priv->scan.curr; in cw1200_scan_work()
199 for (it = priv->scan.curr + 1, i = 1; in cw1200_scan_work()
200 it != priv->scan.end && i < WSM_SCAN_MAX_NUM_OF_CHANNELS; in cw1200_scan_work()
211 scan.band = first->band; in cw1200_scan_work()
213 if (priv->scan.req->no_cck) in cw1200_scan_work()
214 scan.max_tx_rate = WSM_TRANSMIT_RATE_6; in cw1200_scan_work()
216 scan.max_tx_rate = WSM_TRANSMIT_RATE_1; in cw1200_scan_work()
217 scan.num_probes = in cw1200_scan_work()
219 scan.num_ssids = priv->scan.n_ssids; in cw1200_scan_work()
220 scan.ssids = &priv->scan.ssids[0]; in cw1200_scan_work()
221 scan.num_channels = it - priv->scan.curr; in cw1200_scan_work()
223 scan.probe_delay = 100; in cw1200_scan_work()
225 * FW team says that driver may not use FG scan in cw1200_scan_work()
229 scan.type = WSM_SCAN_TYPE_BACKGROUND; in cw1200_scan_work()
230 scan.flags = WSM_SCAN_FLAG_FORCE_BACKGROUND; in cw1200_scan_work()
232 scan.ch = kcalloc(it - priv->scan.curr, in cw1200_scan_work()
235 if (!scan.ch) { in cw1200_scan_work()
236 priv->scan.status = -ENOMEM; in cw1200_scan_work()
239 for (i = 0; i < scan.num_channels; ++i) { in cw1200_scan_work()
240 scan.ch[i].number = priv->scan.curr[i]->hw_value; in cw1200_scan_work()
241 if (priv->scan.curr[i]->flags & IEEE80211_CHAN_NO_IR) { in cw1200_scan_work()
242 scan.ch[i].min_chan_time = 50; in cw1200_scan_work()
243 scan.ch[i].max_chan_time = 100; in cw1200_scan_work()
245 scan.ch[i].min_chan_time = 10; in cw1200_scan_work()
246 scan.ch[i].max_chan_time = 25; in cw1200_scan_work()
250 priv->scan.output_power != first->max_power) { in cw1200_scan_work()
251 priv->scan.output_power = first->max_power; in cw1200_scan_work()
253 priv->scan.output_power * 10); in cw1200_scan_work()
255 priv->scan.status = cw1200_scan_start(priv, &scan); in cw1200_scan_work()
256 kfree(scan.ch); in cw1200_scan_work()
257 if (priv->scan.status) in cw1200_scan_work()
259 priv->scan.curr = it; in cw1200_scan_work()
265 priv->scan.curr = priv->scan.end; in cw1200_scan_work()
267 queue_work(priv->workqueue, &priv->scan.work); in cw1200_scan_work()
273 /* FW bug: driver has to restart p2p-dev mode after scan. */ in cw1200_scan_restart_delayed()
293 if (priv->scan.direct_probe) { in cw1200_scan_complete()
294 wiphy_dbg(priv->hw->wiphy, "[SCAN] Direct probe complete.\n"); in cw1200_scan_complete()
296 priv->scan.direct_probe = 0; in cw1200_scan_complete()
297 up(&priv->scan.lock); in cw1200_scan_complete()
300 cw1200_scan_work(&priv->scan.work); in cw1200_scan_complete()
310 if (cancel_delayed_work_sync(&priv->scan.timeout) > 0) { in cw1200_scan_failed_cb()
311 priv->scan.status = -EIO; in cw1200_scan_failed_cb()
312 queue_delayed_work(priv->workqueue, &priv->scan.timeout, 0); in cw1200_scan_failed_cb()
324 if (cancel_delayed_work_sync(&priv->scan.timeout) > 0) { in cw1200_scan_complete_cb()
325 priv->scan.status = 1; in cw1200_scan_complete_cb()
326 queue_delayed_work(priv->workqueue, &priv->scan.timeout, 0); in cw1200_scan_complete_cb()
341 container_of(work, struct cw1200_common, scan.timeout.work); in cw1200_scan_timeout()
342 if (atomic_xchg(&priv->scan.in_progress, 0)) { in cw1200_scan_timeout()
343 if (priv->scan.status > 0) { in cw1200_scan_timeout()
344 priv->scan.status = 0; in cw1200_scan_timeout()
345 } else if (!priv->scan.status) { in cw1200_scan_timeout()
347 "Timeout waiting for scan complete notification.\n"); in cw1200_scan_timeout()
348 priv->scan.status = -ETIMEDOUT; in cw1200_scan_timeout()
349 priv->scan.curr = priv->scan.end; in cw1200_scan_timeout()
359 container_of(work, struct cw1200_common, scan.probe_work.work); in cw1200_probe_work()
374 struct wsm_scan scan = { in cw1200_probe_work() local
386 wiphy_dbg(priv->hw->wiphy, "[SCAN] Direct probe work.\n"); in cw1200_probe_work()
389 if (down_trylock(&priv->scan.lock)) { in cw1200_probe_work()
390 /* Scan is already in progress. Requeue self. */ in cw1200_probe_work()
392 queue_delayed_work(priv->workqueue, &priv->scan.probe_work, in cw1200_probe_work()
401 up(&priv->scan.lock); in cw1200_probe_work()
407 scan.max_tx_rate = wsm->max_tx_rate; in cw1200_probe_work()
408 scan.band = (priv->channel->band == NL80211_BAND_5GHZ) ? in cw1200_probe_work()
412 scan.type = WSM_SCAN_TYPE_BACKGROUND; in cw1200_probe_work()
413 scan.flags = WSM_SCAN_FLAG_FORCE_BACKGROUND; in cw1200_probe_work()
434 scan.num_ssids = 1; in cw1200_probe_work()
443 /* FW bug: driver has to restart p2p-dev mode after scan */ in cw1200_probe_work()
447 priv->scan.direct_probe = 1; in cw1200_probe_work()
450 ret = cw1200_scan_start(priv, &scan); in cw1200_probe_work()
460 priv->scan.direct_probe = 0; in cw1200_probe_work()
461 up(&priv->scan.lock); in cw1200_probe_work()