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 
wl1271_scan_complete_work(struct work_struct * work)32 void 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 	kfree(wl->scan.scanned_ch);
52 	wl->scan.scanned_ch = NULL;
53 	wl->scan.req = NULL;
54 	ieee80211_scan_completed(wl->hw, false);
55 
56 	/* restore hardware connection monitoring template */
57 	if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) {
58 		if (wl1271_ps_elp_wakeup(wl) == 0) {
59 			wl1271_cmd_build_ap_probe_req(wl, wl->probereq);
60 			wl1271_ps_elp_sleep(wl);
61 		}
62 	}
63 
64 	if (wl->scan.failed) {
65 		wl1271_info("Scan completed due to error.");
66 		ieee80211_queue_work(wl->hw, &wl->recovery_work);
67 	}
68 
69 out:
70 	mutex_unlock(&wl->mutex);
71 
72 }
73 
74 
wl1271_get_scan_channels(struct wl1271 * wl,struct cfg80211_scan_request * req,struct basic_scan_channel_params * channels,enum ieee80211_band band,bool passive)75 static int wl1271_get_scan_channels(struct wl1271 *wl,
76 				    struct cfg80211_scan_request *req,
77 				    struct basic_scan_channel_params *channels,
78 				    enum ieee80211_band band, bool passive)
79 {
80 	struct conf_scan_settings *c = &wl->conf.scan;
81 	int i, j;
82 	u32 flags;
83 
84 	for (i = 0, j = 0;
85 	     i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS;
86 	     i++) {
87 
88 		flags = req->channels[i]->flags;
89 
90 		if (!wl->scan.scanned_ch[i] &&
91 		    !(flags & IEEE80211_CHAN_DISABLED) &&
92 		    ((!!(flags & IEEE80211_CHAN_PASSIVE_SCAN)) == passive) &&
93 		    (req->channels[i]->band == band)) {
94 
95 			wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
96 				     req->channels[i]->band,
97 				     req->channels[i]->center_freq);
98 			wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X",
99 				     req->channels[i]->hw_value,
100 				     req->channels[i]->flags);
101 			wl1271_debug(DEBUG_SCAN,
102 				     "max_antenna_gain %d, max_power %d",
103 				     req->channels[i]->max_antenna_gain,
104 				     req->channels[i]->max_power);
105 			wl1271_debug(DEBUG_SCAN, "beacon_found %d",
106 				     req->channels[i]->beacon_found);
107 
108 			if (!passive) {
109 				channels[j].min_duration =
110 					cpu_to_le32(c->min_dwell_time_active);
111 				channels[j].max_duration =
112 					cpu_to_le32(c->max_dwell_time_active);
113 			} else {
114 				channels[j].min_duration =
115 					cpu_to_le32(c->min_dwell_time_passive);
116 				channels[j].max_duration =
117 					cpu_to_le32(c->max_dwell_time_passive);
118 			}
119 			channels[j].early_termination = 0;
120 			channels[j].tx_power_att = req->channels[i]->max_power;
121 			channels[j].channel = req->channels[i]->hw_value;
122 
123 			memset(&channels[j].bssid_lsb, 0xff, 4);
124 			memset(&channels[j].bssid_msb, 0xff, 2);
125 
126 			/* Mark the channels we already used */
127 			wl->scan.scanned_ch[i] = true;
128 
129 			j++;
130 		}
131 	}
132 
133 	return j;
134 }
135 
136 #define WL1271_NOTHING_TO_SCAN 1
137 
wl1271_scan_send(struct wl1271 * wl,enum ieee80211_band band,bool passive,u32 basic_rate)138 static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
139 			     bool passive, u32 basic_rate)
140 {
141 	struct wl1271_cmd_scan *cmd;
142 	struct wl1271_cmd_trigger_scan_to *trigger;
143 	int ret;
144 	u16 scan_options = 0;
145 
146 	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
147 	trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
148 	if (!cmd || !trigger) {
149 		ret = -ENOMEM;
150 		goto out;
151 	}
152 
153 	/* We always use high priority scans */
154 	scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH;
155 
156 	/* No SSIDs means that we have a forced passive scan */
157 	if (passive || wl->scan.req->n_ssids == 0)
158 		scan_options |= WL1271_SCAN_OPT_PASSIVE;
159 
160 	cmd->params.scan_options = cpu_to_le16(scan_options);
161 
162 	cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req,
163 						    cmd->channels,
164 						    band, passive);
165 	if (cmd->params.n_ch == 0) {
166 		ret = WL1271_NOTHING_TO_SCAN;
167 		goto out;
168 	}
169 
170 	cmd->params.tx_rate = cpu_to_le32(basic_rate);
171 	cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
172 	cmd->params.rx_filter_options =
173 		cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
174 
175 	cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs;
176 	cmd->params.tx_rate = cpu_to_le32(basic_rate);
177 	cmd->params.tid_trigger = 0;
178 	cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
179 
180 	if (band == IEEE80211_BAND_2GHZ)
181 		cmd->params.band = WL1271_SCAN_BAND_2_4_GHZ;
182 	else
183 		cmd->params.band = WL1271_SCAN_BAND_5_GHZ;
184 
185 	if (wl->scan.ssid_len && wl->scan.ssid) {
186 		cmd->params.ssid_len = wl->scan.ssid_len;
187 		memcpy(cmd->params.ssid, wl->scan.ssid, wl->scan.ssid_len);
188 	}
189 
190 	ret = wl1271_cmd_build_probe_req(wl, wl->scan.ssid, wl->scan.ssid_len,
191 					 wl->scan.req->ie, wl->scan.req->ie_len,
192 					 band);
193 	if (ret < 0) {
194 		wl1271_error("PROBE request template failed");
195 		goto out;
196 	}
197 
198 	/* disable the timeout */
199 	trigger->timeout = 0;
200 	ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
201 			      sizeof(*trigger), 0);
202 	if (ret < 0) {
203 		wl1271_error("trigger scan to failed for hw scan");
204 		goto out;
205 	}
206 
207 	wl1271_dump(DEBUG_SCAN, "SCAN: ", cmd, sizeof(*cmd));
208 
209 	ret = wl1271_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd), 0);
210 	if (ret < 0) {
211 		wl1271_error("SCAN failed");
212 		goto out;
213 	}
214 
215 out:
216 	kfree(cmd);
217 	kfree(trigger);
218 	return ret;
219 }
220 
wl1271_scan_stm(struct wl1271 * wl)221 void wl1271_scan_stm(struct wl1271 *wl)
222 {
223 	int ret = 0;
224 
225 	switch (wl->scan.state) {
226 	case WL1271_SCAN_STATE_IDLE:
227 		break;
228 
229 	case WL1271_SCAN_STATE_2GHZ_ACTIVE:
230 		ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, false,
231 				       wl->conf.tx.basic_rate);
232 		if (ret == WL1271_NOTHING_TO_SCAN) {
233 			wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE;
234 			wl1271_scan_stm(wl);
235 		}
236 
237 		break;
238 
239 	case WL1271_SCAN_STATE_2GHZ_PASSIVE:
240 		ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true,
241 				       wl->conf.tx.basic_rate);
242 		if (ret == WL1271_NOTHING_TO_SCAN) {
243 			if (wl->enable_11a)
244 				wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
245 			else
246 				wl->scan.state = WL1271_SCAN_STATE_DONE;
247 			wl1271_scan_stm(wl);
248 		}
249 
250 		break;
251 
252 	case WL1271_SCAN_STATE_5GHZ_ACTIVE:
253 		ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, false,
254 				       wl->conf.tx.basic_rate_5);
255 		if (ret == WL1271_NOTHING_TO_SCAN) {
256 			wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE;
257 			wl1271_scan_stm(wl);
258 		}
259 
260 		break;
261 
262 	case WL1271_SCAN_STATE_5GHZ_PASSIVE:
263 		ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, true,
264 				       wl->conf.tx.basic_rate_5);
265 		if (ret == WL1271_NOTHING_TO_SCAN) {
266 			wl->scan.state = WL1271_SCAN_STATE_DONE;
267 			wl1271_scan_stm(wl);
268 		}
269 
270 		break;
271 
272 	case WL1271_SCAN_STATE_DONE:
273 		wl->scan.failed = false;
274 		cancel_delayed_work(&wl->scan_complete_work);
275 		ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
276 					     msecs_to_jiffies(0));
277 		break;
278 
279 	default:
280 		wl1271_error("invalid scan state");
281 		break;
282 	}
283 
284 	if (ret < 0) {
285 		cancel_delayed_work(&wl->scan_complete_work);
286 		ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
287 					     msecs_to_jiffies(0));
288 	}
289 }
290 
wl1271_scan(struct wl1271 * wl,const u8 * ssid,size_t ssid_len,struct cfg80211_scan_request * req)291 int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
292 		struct cfg80211_scan_request *req)
293 {
294 	if (wl->scan.state != WL1271_SCAN_STATE_IDLE)
295 		return -EBUSY;
296 
297 	wl->scan.state = WL1271_SCAN_STATE_2GHZ_ACTIVE;
298 
299 	if (ssid_len && ssid) {
300 		wl->scan.ssid_len = ssid_len;
301 		memcpy(wl->scan.ssid, ssid, ssid_len);
302 	} else {
303 		wl->scan.ssid_len = 0;
304 	}
305 
306 	wl->scan.req = req;
307 
308 	wl->scan.scanned_ch = kcalloc(req->n_channels,
309 				      sizeof(*wl->scan.scanned_ch),
310 				      GFP_KERNEL);
311 	/* we assume failure so that timeout scenarios are handled correctly */
312 	wl->scan.failed = true;
313 	ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
314 				     msecs_to_jiffies(WL1271_SCAN_TIMEOUT));
315 
316 	wl1271_scan_stm(wl);
317 
318 	return 0;
319 }
320