PageRenderTime 104ms CodeModel.GetById 15ms app.highlight 76ms RepoModel.GetById 1ms app.codeStats 1ms

/drivers/net/wireless/wl12xx/scan.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2
C | 589 lines | 439 code | 101 blank | 49 comment | 79 complexity | 4cbc2a71be5763e737c416d5fd19af25 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1/*
  2 * This file is part of wl1271
  3 *
  4 * Copyright (C) 2009-2010 Nokia Corporation
  5 *
  6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
  7 *
  8 * This program is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU General Public License
 10 * version 2 as published by the Free Software Foundation.
 11 *
 12 * This program is distributed in the hope that it will be useful, but
 13 * WITHOUT ANY WARRANTY; without even the implied warranty of
 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15 * General Public License for more details.
 16 *
 17 * You should have received a copy of the GNU General Public License
 18 * along with this program; if not, write to the Free Software
 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 20 * 02110-1301 USA
 21 *
 22 */
 23
 24#include <linux/ieee80211.h>
 25
 26#include "wl12xx.h"
 27#include "cmd.h"
 28#include "scan.h"
 29#include "acx.h"
 30#include "ps.h"
 31
 32void wl1271_scan_complete_work(struct work_struct *work)
 33{
 34	struct delayed_work *dwork;
 35	struct wl1271 *wl;
 36
 37	dwork = container_of(work, struct delayed_work, work);
 38	wl = container_of(dwork, struct wl1271, scan_complete_work);
 39
 40	wl1271_debug(DEBUG_SCAN, "Scanning complete");
 41
 42	mutex_lock(&wl->mutex);
 43
 44	if (wl->state == WL1271_STATE_OFF)
 45		goto out;
 46
 47	if (wl->scan.state == WL1271_SCAN_STATE_IDLE)
 48		goto out;
 49
 50	wl->scan.state = WL1271_SCAN_STATE_IDLE;
 51	memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
 52	wl->scan.req = NULL;
 53	ieee80211_scan_completed(wl->hw, false);
 54
 55	/* restore hardware connection monitoring template */
 56	if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) {
 57		if (wl1271_ps_elp_wakeup(wl) == 0) {
 58			wl1271_cmd_build_ap_probe_req(wl, wl->probereq);
 59			wl1271_ps_elp_sleep(wl);
 60		}
 61	}
 62
 63	if (wl->scan.failed) {
 64		wl1271_info("Scan completed due to error.");
 65		ieee80211_queue_work(wl->hw, &wl->recovery_work);
 66	}
 67
 68out:
 69	mutex_unlock(&wl->mutex);
 70
 71}
 72
 73
 74static int wl1271_get_scan_channels(struct wl1271 *wl,
 75				    struct cfg80211_scan_request *req,
 76				    struct basic_scan_channel_params *channels,
 77				    enum ieee80211_band band, bool passive)
 78{
 79	struct conf_scan_settings *c = &wl->conf.scan;
 80	int i, j;
 81	u32 flags;
 82
 83	for (i = 0, j = 0;
 84	     i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS;
 85	     i++) {
 86		flags = req->channels[i]->flags;
 87
 88		if (!test_bit(i, wl->scan.scanned_ch) &&
 89		    !(flags & IEEE80211_CHAN_DISABLED) &&
 90		    (req->channels[i]->band == band) &&
 91		    /*
 92		     * In passive scans, we scan all remaining
 93		     * channels, even if not marked as such.
 94		     * In active scans, we only scan channels not
 95		     * marked as passive.
 96		     */
 97		    (passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) {
 98			wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
 99				     req->channels[i]->band,
100				     req->channels[i]->center_freq);
101			wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X",
102				     req->channels[i]->hw_value,
103				     req->channels[i]->flags);
104			wl1271_debug(DEBUG_SCAN,
105				     "max_antenna_gain %d, max_power %d",
106				     req->channels[i]->max_antenna_gain,
107				     req->channels[i]->max_power);
108			wl1271_debug(DEBUG_SCAN, "beacon_found %d",
109				     req->channels[i]->beacon_found);
110
111			if (!passive) {
112				channels[j].min_duration =
113					cpu_to_le32(c->min_dwell_time_active);
114				channels[j].max_duration =
115					cpu_to_le32(c->max_dwell_time_active);
116			} else {
117				channels[j].min_duration =
118					cpu_to_le32(c->min_dwell_time_passive);
119				channels[j].max_duration =
120					cpu_to_le32(c->max_dwell_time_passive);
121			}
122			channels[j].early_termination = 0;
123			channels[j].tx_power_att = req->channels[i]->max_power;
124			channels[j].channel = req->channels[i]->hw_value;
125
126			memset(&channels[j].bssid_lsb, 0xff, 4);
127			memset(&channels[j].bssid_msb, 0xff, 2);
128
129			/* Mark the channels we already used */
130			set_bit(i, wl->scan.scanned_ch);
131
132			j++;
133		}
134	}
135
136	return j;
137}
138
139#define WL1271_NOTHING_TO_SCAN 1
140
141static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
142			     bool passive, u32 basic_rate)
143{
144	struct wl1271_cmd_scan *cmd;
145	struct wl1271_cmd_trigger_scan_to *trigger;
146	int ret;
147	u16 scan_options = 0;
148
149	/* skip active scans if we don't have SSIDs */
150	if (!passive && wl->scan.req->n_ssids == 0)
151		return WL1271_NOTHING_TO_SCAN;
152
153	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
154	trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
155	if (!cmd || !trigger) {
156		ret = -ENOMEM;
157		goto out;
158	}
159
160	/* We always use high priority scans */
161	scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH;
162
163	if (passive)
164		scan_options |= WL1271_SCAN_OPT_PASSIVE;
165
166	cmd->params.scan_options = cpu_to_le16(scan_options);
167
168	cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req,
169						    cmd->channels,
170						    band, passive);
171	if (cmd->params.n_ch == 0) {
172		ret = WL1271_NOTHING_TO_SCAN;
173		goto out;
174	}
175
176	cmd->params.tx_rate = cpu_to_le32(basic_rate);
177	cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
178	cmd->params.rx_filter_options =
179		cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
180
181	cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs;
182	cmd->params.tx_rate = cpu_to_le32(basic_rate);
183	cmd->params.tid_trigger = 0;
184	cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
185
186	if (band == IEEE80211_BAND_2GHZ)
187		cmd->params.band = WL1271_SCAN_BAND_2_4_GHZ;
188	else
189		cmd->params.band = WL1271_SCAN_BAND_5_GHZ;
190
191	if (wl->scan.ssid_len && wl->scan.ssid) {
192		cmd->params.ssid_len = wl->scan.ssid_len;
193		memcpy(cmd->params.ssid, wl->scan.ssid, wl->scan.ssid_len);
194	}
195
196	ret = wl1271_cmd_build_probe_req(wl, wl->scan.ssid, wl->scan.ssid_len,
197					 wl->scan.req->ie, wl->scan.req->ie_len,
198					 band);
199	if (ret < 0) {
200		wl1271_error("PROBE request template failed");
201		goto out;
202	}
203
204	/* disable the timeout */
205	trigger->timeout = 0;
206	ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
207			      sizeof(*trigger), 0);
208	if (ret < 0) {
209		wl1271_error("trigger scan to failed for hw scan");
210		goto out;
211	}
212
213	wl1271_dump(DEBUG_SCAN, "SCAN: ", cmd, sizeof(*cmd));
214
215	ret = wl1271_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd), 0);
216	if (ret < 0) {
217		wl1271_error("SCAN failed");
218		goto out;
219	}
220
221out:
222	kfree(cmd);
223	kfree(trigger);
224	return ret;
225}
226
227void wl1271_scan_stm(struct wl1271 *wl)
228{
229	int ret = 0;
230
231	switch (wl->scan.state) {
232	case WL1271_SCAN_STATE_IDLE:
233		break;
234
235	case WL1271_SCAN_STATE_2GHZ_ACTIVE:
236		ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, false,
237				       wl->conf.tx.basic_rate);
238		if (ret == WL1271_NOTHING_TO_SCAN) {
239			wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE;
240			wl1271_scan_stm(wl);
241		}
242
243		break;
244
245	case WL1271_SCAN_STATE_2GHZ_PASSIVE:
246		ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true,
247				       wl->conf.tx.basic_rate);
248		if (ret == WL1271_NOTHING_TO_SCAN) {
249			if (wl->enable_11a)
250				wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
251			else
252				wl->scan.state = WL1271_SCAN_STATE_DONE;
253			wl1271_scan_stm(wl);
254		}
255
256		break;
257
258	case WL1271_SCAN_STATE_5GHZ_ACTIVE:
259		ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, false,
260				       wl->conf.tx.basic_rate_5);
261		if (ret == WL1271_NOTHING_TO_SCAN) {
262			wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE;
263			wl1271_scan_stm(wl);
264		}
265
266		break;
267
268	case WL1271_SCAN_STATE_5GHZ_PASSIVE:
269		ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, true,
270				       wl->conf.tx.basic_rate_5);
271		if (ret == WL1271_NOTHING_TO_SCAN) {
272			wl->scan.state = WL1271_SCAN_STATE_DONE;
273			wl1271_scan_stm(wl);
274		}
275
276		break;
277
278	case WL1271_SCAN_STATE_DONE:
279		wl->scan.failed = false;
280		cancel_delayed_work(&wl->scan_complete_work);
281		ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
282					     msecs_to_jiffies(0));
283		break;
284
285	default:
286		wl1271_error("invalid scan state");
287		break;
288	}
289
290	if (ret < 0) {
291		cancel_delayed_work(&wl->scan_complete_work);
292		ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
293					     msecs_to_jiffies(0));
294	}
295}
296
297int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
298		struct cfg80211_scan_request *req)
299{
300	/*
301	 * cfg80211 should guarantee that we don't get more channels
302	 * than what we have registered.
303	 */
304	BUG_ON(req->n_channels > WL1271_MAX_CHANNELS);
305
306	if (wl->scan.state != WL1271_SCAN_STATE_IDLE)
307		return -EBUSY;
308
309	wl->scan.state = WL1271_SCAN_STATE_2GHZ_ACTIVE;
310
311	if (ssid_len && ssid) {
312		wl->scan.ssid_len = ssid_len;
313		memcpy(wl->scan.ssid, ssid, ssid_len);
314	} else {
315		wl->scan.ssid_len = 0;
316	}
317
318	wl->scan.req = req;
319	memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
320
321	/* we assume failure so that timeout scenarios are handled correctly */
322	wl->scan.failed = true;
323	ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
324				     msecs_to_jiffies(WL1271_SCAN_TIMEOUT));
325
326	wl1271_scan_stm(wl);
327
328	return 0;
329}
330
331static int
332wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
333				    struct cfg80211_sched_scan_request *req,
334				    struct conn_scan_ch_params *channels,
335				    u32 band, bool radar, bool passive,
336				    int start)
337{
338	struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
339	int i, j;
340	u32 flags;
341	bool force_passive = !req->n_ssids;
342
343	for (i = 0, j = start;
344	     i < req->n_channels && j < MAX_CHANNELS_ALL_BANDS;
345	     i++) {
346		flags = req->channels[i]->flags;
347
348		if (force_passive)
349			flags |= IEEE80211_CHAN_PASSIVE_SCAN;
350
351		if ((req->channels[i]->band == band) &&
352		    !(flags & IEEE80211_CHAN_DISABLED) &&
353		    (!!(flags & IEEE80211_CHAN_RADAR) == radar) &&
354		    /* if radar is set, we ignore the passive flag */
355		    (radar ||
356		     !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) {
357			wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
358				     req->channels[i]->band,
359				     req->channels[i]->center_freq);
360			wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X",
361				     req->channels[i]->hw_value,
362				     req->channels[i]->flags);
363			wl1271_debug(DEBUG_SCAN, "max_power %d",
364				     req->channels[i]->max_power);
365
366			if (flags & IEEE80211_CHAN_RADAR) {
367				channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS;
368				channels[j].passive_duration =
369					cpu_to_le16(c->dwell_time_dfs);
370			}
371			else if (flags & IEEE80211_CHAN_PASSIVE_SCAN) {
372				channels[j].passive_duration =
373					cpu_to_le16(c->dwell_time_passive);
374			} else {
375				channels[j].min_duration =
376					cpu_to_le16(c->min_dwell_time_active);
377				channels[j].max_duration =
378					cpu_to_le16(c->max_dwell_time_active);
379			}
380			channels[j].tx_power_att = req->channels[i]->max_power;
381			channels[j].channel = req->channels[i]->hw_value;
382
383			j++;
384		}
385	}
386
387	return j - start;
388}
389
390static int
391wl1271_scan_sched_scan_channels(struct wl1271 *wl,
392				struct cfg80211_sched_scan_request *req,
393				struct wl1271_cmd_sched_scan_config *cfg)
394{
395	int idx = 0;
396
397	cfg->passive[0] =
398		wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
399						    IEEE80211_BAND_2GHZ,
400						    false, true, idx);
401	idx += cfg->passive[0];
402
403	cfg->active[0] =
404		wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
405						    IEEE80211_BAND_2GHZ,
406						    false, false, idx);
407	/*
408	 * 5GHz channels always start at position 14, not immediately
409	 * after the last 2.4GHz channel
410	 */
411	idx = 14;
412
413	cfg->passive[1] =
414		wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
415						    IEEE80211_BAND_5GHZ,
416						    false, true, idx);
417	idx += cfg->passive[1];
418
419	cfg->dfs =
420		wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
421						    IEEE80211_BAND_5GHZ,
422						    true, true, idx);
423	idx += cfg->dfs;
424
425	cfg->active[1] =
426		wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
427						    IEEE80211_BAND_5GHZ,
428						    false, false, idx);
429	idx += cfg->active[1];
430
431	wl1271_debug(DEBUG_SCAN, "    2.4GHz: active %d passive %d",
432		     cfg->active[0], cfg->passive[0]);
433	wl1271_debug(DEBUG_SCAN, "    5GHz: active %d passive %d",
434		     cfg->active[1], cfg->passive[1]);
435	wl1271_debug(DEBUG_SCAN, "    DFS: %d", cfg->dfs);
436
437	return idx;
438}
439
440int wl1271_scan_sched_scan_config(struct wl1271 *wl,
441				  struct cfg80211_sched_scan_request *req,
442				  struct ieee80211_sched_scan_ies *ies)
443{
444	struct wl1271_cmd_sched_scan_config *cfg = NULL;
445	struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
446	int i, total_channels, ret;
447	bool force_passive = !req->n_ssids;
448
449	wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config");
450
451	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
452	if (!cfg)
453		return -ENOMEM;
454
455	cfg->rssi_threshold = c->rssi_threshold;
456	cfg->snr_threshold  = c->snr_threshold;
457	cfg->n_probe_reqs = c->num_probe_reqs;
458	/* cycles set to 0 it means infinite (until manually stopped) */
459	cfg->cycles = 0;
460	/* report APs when at least 1 is found */
461	cfg->report_after = 1;
462	/* don't stop scanning automatically when something is found */
463	cfg->terminate = 0;
464	cfg->tag = WL1271_SCAN_DEFAULT_TAG;
465	/* don't filter on BSS type */
466	cfg->bss_type = SCAN_BSS_TYPE_ANY;
467	/* currently NL80211 supports only a single interval */
468	for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++)
469		cfg->intervals[i] = cpu_to_le32(req->interval);
470
471	if (!force_passive && req->ssids[0].ssid_len && req->ssids[0].ssid) {
472		cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC;
473		cfg->ssid_len = req->ssids[0].ssid_len;
474		memcpy(cfg->ssid, req->ssids[0].ssid,
475		       req->ssids[0].ssid_len);
476	} else {
477		cfg->filter_type = SCAN_SSID_FILTER_ANY;
478		cfg->ssid_len = 0;
479	}
480
481	total_channels = wl1271_scan_sched_scan_channels(wl, req, cfg);
482	if (total_channels == 0) {
483		wl1271_error("scan channel list is empty");
484		ret = -EINVAL;
485		goto out;
486	}
487
488	if (!force_passive && cfg->active[0]) {
489		ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid,
490						 req->ssids[0].ssid_len,
491						 ies->ie[IEEE80211_BAND_2GHZ],
492						 ies->len[IEEE80211_BAND_2GHZ],
493						 IEEE80211_BAND_2GHZ);
494		if (ret < 0) {
495			wl1271_error("2.4GHz PROBE request template failed");
496			goto out;
497		}
498	}
499
500	if (!force_passive && cfg->active[1]) {
501		ret = wl1271_cmd_build_probe_req(wl,  req->ssids[0].ssid,
502						 req->ssids[0].ssid_len,
503						 ies->ie[IEEE80211_BAND_5GHZ],
504						 ies->len[IEEE80211_BAND_5GHZ],
505						 IEEE80211_BAND_5GHZ);
506		if (ret < 0) {
507			wl1271_error("5GHz PROBE request template failed");
508			goto out;
509		}
510	}
511
512	wl1271_dump(DEBUG_SCAN, "SCAN_CFG: ", cfg, sizeof(*cfg));
513
514	ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_CFG, cfg,
515			      sizeof(*cfg), 0);
516	if (ret < 0) {
517		wl1271_error("SCAN configuration failed");
518		goto out;
519	}
520out:
521	kfree(cfg);
522	return ret;
523}
524
525int wl1271_scan_sched_scan_start(struct wl1271 *wl)
526{
527	struct wl1271_cmd_sched_scan_start *start;
528	int ret = 0;
529
530	wl1271_debug(DEBUG_CMD, "cmd periodic scan start");
531
532	if (wl->bss_type != BSS_TYPE_STA_BSS)
533		return -EOPNOTSUPP;
534
535	if (!test_bit(WL1271_FLAG_IDLE, &wl->flags))
536		return -EBUSY;
537
538	start = kzalloc(sizeof(*start), GFP_KERNEL);
539	if (!start)
540		return -ENOMEM;
541
542	start->tag = WL1271_SCAN_DEFAULT_TAG;
543
544	ret = wl1271_cmd_send(wl, CMD_START_PERIODIC_SCAN, start,
545			      sizeof(*start), 0);
546	if (ret < 0) {
547		wl1271_error("failed to send scan start command");
548		goto out_free;
549	}
550
551out_free:
552	kfree(start);
553	return ret;
554}
555
556void wl1271_scan_sched_scan_results(struct wl1271 *wl)
557{
558	wl1271_debug(DEBUG_SCAN, "got periodic scan results");
559
560	ieee80211_sched_scan_results(wl->hw);
561}
562
563void wl1271_scan_sched_scan_stop(struct wl1271 *wl)
564{
565	struct wl1271_cmd_sched_scan_stop *stop;
566	int ret = 0;
567
568	wl1271_debug(DEBUG_CMD, "cmd periodic scan stop");
569
570	/* FIXME: what to do if alloc'ing to stop fails? */
571	stop = kzalloc(sizeof(*stop), GFP_KERNEL);
572	if (!stop) {
573		wl1271_error("failed to alloc memory to send sched scan stop");
574		return;
575	}
576
577	stop->tag = WL1271_SCAN_DEFAULT_TAG;
578
579	ret = wl1271_cmd_send(wl, CMD_STOP_PERIODIC_SCAN, stop,
580			      sizeof(*stop), 0);
581	if (ret < 0) {
582		wl1271_error("failed to send sched scan stop command");
583		goto out_free;
584	}
585	wl->sched_scanning = false;
586
587out_free:
588	kfree(stop);
589}