diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/libertas/assoc.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/debugfs.c | 169 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/dev.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/scan.c | 145 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/scan.h | 69 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/wext.c | 3 |
6 files changed, 76 insertions, 316 deletions
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index 7fe37bedf313..707b7ff592ec 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c | |||
@@ -38,7 +38,7 @@ static int assoc_helper_essid(struct lbs_private *priv, | |||
38 | escape_essid(assoc_req->ssid, assoc_req->ssid_len)); | 38 | escape_essid(assoc_req->ssid, assoc_req->ssid_len)); |
39 | if (assoc_req->mode == IW_MODE_INFRA) { | 39 | if (assoc_req->mode == IW_MODE_INFRA) { |
40 | lbs_send_specific_ssid_scan(priv, assoc_req->ssid, | 40 | lbs_send_specific_ssid_scan(priv, assoc_req->ssid, |
41 | assoc_req->ssid_len, 0); | 41 | assoc_req->ssid_len); |
42 | 42 | ||
43 | bss = lbs_find_ssid_in_list(priv, assoc_req->ssid, | 43 | bss = lbs_find_ssid_in_list(priv, assoc_req->ssid, |
44 | assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel); | 44 | assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel); |
@@ -53,7 +53,7 @@ static int assoc_helper_essid(struct lbs_private *priv, | |||
53 | * scan data will cause us to join a non-existant adhoc network | 53 | * scan data will cause us to join a non-existant adhoc network |
54 | */ | 54 | */ |
55 | lbs_send_specific_ssid_scan(priv, assoc_req->ssid, | 55 | lbs_send_specific_ssid_scan(priv, assoc_req->ssid, |
56 | assoc_req->ssid_len, 1); | 56 | assoc_req->ssid_len); |
57 | 57 | ||
58 | /* Search for the requested SSID in the scan table */ | 58 | /* Search for the requested SSID in the scan table */ |
59 | bss = lbs_find_ssid_in_list(priv, assoc_req->ssid, | 59 | bss = lbs_find_ssid_in_list(priv, assoc_req->ssid, |
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index b600f2439b57..8f88786b036f 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c | |||
@@ -164,173 +164,6 @@ out_unlock: | |||
164 | return ret; | 164 | return ret; |
165 | } | 165 | } |
166 | 166 | ||
167 | static ssize_t lbs_extscan(struct file *file, const char __user *userbuf, | ||
168 | size_t count, loff_t *ppos) | ||
169 | { | ||
170 | struct lbs_private *priv = file->private_data; | ||
171 | ssize_t res, buf_size; | ||
172 | union iwreq_data wrqu; | ||
173 | unsigned long addr = get_zeroed_page(GFP_KERNEL); | ||
174 | char *buf = (char *)addr; | ||
175 | |||
176 | buf_size = min(count, len - 1); | ||
177 | if (copy_from_user(buf, userbuf, buf_size)) { | ||
178 | res = -EFAULT; | ||
179 | goto out_unlock; | ||
180 | } | ||
181 | |||
182 | lbs_send_specific_ssid_scan(priv, buf, strlen(buf)-1, 0); | ||
183 | |||
184 | memset(&wrqu, 0, sizeof(union iwreq_data)); | ||
185 | wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); | ||
186 | |||
187 | out_unlock: | ||
188 | free_page(addr); | ||
189 | return count; | ||
190 | } | ||
191 | |||
192 | static void lbs_parse_bssid(char *buf, size_t count, | ||
193 | struct lbs_ioctl_user_scan_cfg *scan_cfg) | ||
194 | { | ||
195 | char *hold; | ||
196 | unsigned int mac[ETH_ALEN]; | ||
197 | |||
198 | hold = strstr(buf, "bssid="); | ||
199 | if (!hold) | ||
200 | return; | ||
201 | hold += 6; | ||
202 | sscanf(hold, "%02x:%02x:%02x:%02x:%02x:%02x", | ||
203 | mac, mac+1, mac+2, mac+3, mac+4, mac+5); | ||
204 | memcpy(scan_cfg->bssid, mac, ETH_ALEN); | ||
205 | } | ||
206 | |||
207 | static void lbs_parse_ssid(char *buf, size_t count, | ||
208 | struct lbs_ioctl_user_scan_cfg *scan_cfg) | ||
209 | { | ||
210 | char *hold, *end; | ||
211 | ssize_t size; | ||
212 | |||
213 | hold = strstr(buf, "ssid="); | ||
214 | if (!hold) | ||
215 | return; | ||
216 | hold += 5; | ||
217 | end = strchr(hold, ' '); | ||
218 | if (!end) | ||
219 | end = buf + count - 1; | ||
220 | |||
221 | size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold)); | ||
222 | strncpy(scan_cfg->ssid, hold, size); | ||
223 | |||
224 | return; | ||
225 | } | ||
226 | |||
227 | static int lbs_parse_clear(char *buf, size_t count, const char *tag) | ||
228 | { | ||
229 | char *hold; | ||
230 | int val; | ||
231 | |||
232 | hold = strstr(buf, tag); | ||
233 | if (!hold) | ||
234 | return 0; | ||
235 | hold += strlen(tag); | ||
236 | sscanf(hold, "%d", &val); | ||
237 | |||
238 | if (val != 0) | ||
239 | val = 1; | ||
240 | |||
241 | return val; | ||
242 | } | ||
243 | |||
244 | static int lbs_parse_dur(char *buf, size_t count, | ||
245 | struct lbs_ioctl_user_scan_cfg *scan_cfg) | ||
246 | { | ||
247 | char *hold; | ||
248 | int val; | ||
249 | |||
250 | hold = strstr(buf, "dur="); | ||
251 | if (!hold) | ||
252 | return 0; | ||
253 | hold += 4; | ||
254 | sscanf(hold, "%d", &val); | ||
255 | |||
256 | return val; | ||
257 | } | ||
258 | |||
259 | static void lbs_parse_type(char *buf, size_t count, | ||
260 | struct lbs_ioctl_user_scan_cfg *scan_cfg) | ||
261 | { | ||
262 | char *hold; | ||
263 | int val; | ||
264 | |||
265 | hold = strstr(buf, "type="); | ||
266 | if (!hold) | ||
267 | return; | ||
268 | hold += 5; | ||
269 | sscanf(hold, "%d", &val); | ||
270 | |||
271 | /* type=1,2 or 3 */ | ||
272 | if (val < 1 || val > 3) | ||
273 | return; | ||
274 | |||
275 | scan_cfg->bsstype = val; | ||
276 | |||
277 | return; | ||
278 | } | ||
279 | |||
280 | static ssize_t lbs_setuserscan(struct file *file, | ||
281 | const char __user *userbuf, | ||
282 | size_t count, loff_t *ppos) | ||
283 | { | ||
284 | struct lbs_private *priv = file->private_data; | ||
285 | ssize_t res, buf_size; | ||
286 | struct lbs_ioctl_user_scan_cfg *scan_cfg; | ||
287 | union iwreq_data wrqu; | ||
288 | int dur; | ||
289 | char *buf = (char *)get_zeroed_page(GFP_KERNEL); | ||
290 | |||
291 | if (!buf) | ||
292 | return -ENOMEM; | ||
293 | |||
294 | buf_size = min(count, len - 1); | ||
295 | if (copy_from_user(buf, userbuf, buf_size)) { | ||
296 | res = -EFAULT; | ||
297 | goto out_buf; | ||
298 | } | ||
299 | |||
300 | scan_cfg = kzalloc(sizeof(struct lbs_ioctl_user_scan_cfg), GFP_KERNEL); | ||
301 | if (!scan_cfg) { | ||
302 | res = -ENOMEM; | ||
303 | goto out_buf; | ||
304 | } | ||
305 | res = count; | ||
306 | |||
307 | scan_cfg->bsstype = LBS_SCAN_BSS_TYPE_ANY; | ||
308 | |||
309 | dur = lbs_parse_dur(buf, count, scan_cfg); | ||
310 | lbs_parse_bssid(buf, count, scan_cfg); | ||
311 | scan_cfg->clear_bssid = lbs_parse_clear(buf, count, "clear_bssid="); | ||
312 | lbs_parse_ssid(buf, count, scan_cfg); | ||
313 | scan_cfg->clear_ssid = lbs_parse_clear(buf, count, "clear_ssid="); | ||
314 | lbs_parse_type(buf, count, scan_cfg); | ||
315 | |||
316 | lbs_scan_networks(priv, scan_cfg, 1); | ||
317 | wait_event_interruptible(priv->cmd_pending, | ||
318 | priv->surpriseremoved || !priv->scan_channel); | ||
319 | |||
320 | if (priv->surpriseremoved) | ||
321 | goto out_scan_cfg; | ||
322 | |||
323 | memset(&wrqu, 0x00, sizeof(union iwreq_data)); | ||
324 | wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); | ||
325 | |||
326 | out_scan_cfg: | ||
327 | kfree(scan_cfg); | ||
328 | out_buf: | ||
329 | free_page((unsigned long)buf); | ||
330 | return res; | ||
331 | } | ||
332 | |||
333 | |||
334 | /* | 167 | /* |
335 | * When calling CMD_802_11_SUBSCRIBE_EVENT with CMD_ACT_GET, me might | 168 | * When calling CMD_802_11_SUBSCRIBE_EVENT with CMD_ACT_GET, me might |
336 | * get a bunch of vendor-specific TLVs (a.k.a. IEs) back from the | 169 | * get a bunch of vendor-specific TLVs (a.k.a. IEs) back from the |
@@ -857,8 +690,6 @@ static struct lbs_debugfs_files debugfs_files[] = { | |||
857 | write_file_dummy), }, | 690 | write_file_dummy), }, |
858 | { "sleepparams", 0644, FOPS(lbs_sleepparams_read, | 691 | { "sleepparams", 0644, FOPS(lbs_sleepparams_read, |
859 | lbs_sleepparams_write), }, | 692 | lbs_sleepparams_write), }, |
860 | { "extscan", 0600, FOPS(NULL, lbs_extscan), }, | ||
861 | { "setuserscan", 0600, FOPS(NULL, lbs_setuserscan), }, | ||
862 | }; | 693 | }; |
863 | 694 | ||
864 | static struct lbs_debugfs_files debugfs_events_files[] = { | 695 | static struct lbs_debugfs_files debugfs_events_files[] = { |
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index fd1fcc748010..ff2c046ca73f 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h | |||
@@ -149,6 +149,8 @@ struct lbs_private { | |||
149 | struct work_struct sync_channel; | 149 | struct work_struct sync_channel; |
150 | /* remember which channel was scanned last, != 0 if currently scanning */ | 150 | /* remember which channel was scanned last, != 0 if currently scanning */ |
151 | int scan_channel; | 151 | int scan_channel; |
152 | u8 scan_ssid[IW_ESSID_MAX_SIZE + 1]; | ||
153 | u8 scan_ssid_len; | ||
152 | 154 | ||
153 | /** Hardware access */ | 155 | /** Hardware access */ |
154 | int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb); | 156 | int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb); |
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 99f11a56d84e..0598541451d8 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c | |||
@@ -260,24 +260,12 @@ done: | |||
260 | 260 | ||
261 | 261 | ||
262 | 262 | ||
263 | |||
264 | /*********************************************************************/ | 263 | /*********************************************************************/ |
265 | /* */ | 264 | /* */ |
266 | /* Main scanning support */ | 265 | /* Main scanning support */ |
267 | /* */ | 266 | /* */ |
268 | /*********************************************************************/ | 267 | /*********************************************************************/ |
269 | 268 | ||
270 | void lbs_scan_worker(struct work_struct *work) | ||
271 | { | ||
272 | struct lbs_private *priv = | ||
273 | container_of(work, struct lbs_private, scan_work.work); | ||
274 | |||
275 | lbs_deb_enter(LBS_DEB_SCAN); | ||
276 | lbs_scan_networks(priv, NULL, 0); | ||
277 | lbs_deb_leave(LBS_DEB_SCAN); | ||
278 | } | ||
279 | |||
280 | |||
281 | /** | 269 | /** |
282 | * @brief Create a channel list for the driver to scan based on region info | 270 | * @brief Create a channel list for the driver to scan based on region info |
283 | * | 271 | * |
@@ -289,17 +277,11 @@ void lbs_scan_worker(struct work_struct *work) | |||
289 | * | 277 | * |
290 | * @param priv A pointer to struct lbs_private structure | 278 | * @param priv A pointer to struct lbs_private structure |
291 | * @param scanchanlist Output parameter: resulting channel list to scan | 279 | * @param scanchanlist Output parameter: resulting channel list to scan |
292 | * @param filteredscan Flag indicating whether or not a BSSID or SSID filter | ||
293 | * is being sent in the command to firmware. Used to | ||
294 | * increase the number of channels sent in a scan | ||
295 | * command and to disable the firmware channel scan | ||
296 | * filter. | ||
297 | * | 280 | * |
298 | * @return void | 281 | * @return void |
299 | */ | 282 | */ |
300 | static int lbs_scan_create_channel_list(struct lbs_private *priv, | 283 | static int lbs_scan_create_channel_list(struct lbs_private *priv, |
301 | struct chanscanparamset *scanchanlist, | 284 | struct chanscanparamset *scanchanlist) |
302 | uint8_t filteredscan) | ||
303 | { | 285 | { |
304 | struct region_channel *scanregion; | 286 | struct region_channel *scanregion; |
305 | struct chan_freq_power *cfp; | 287 | struct chan_freq_power *cfp; |
@@ -354,9 +336,6 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv, | |||
354 | } | 336 | } |
355 | 337 | ||
356 | chan->channumber = cfp->channel; | 338 | chan->channumber = cfp->channel; |
357 | |||
358 | if (filteredscan) | ||
359 | chan->chanscanmode.disablechanfilt = 1; | ||
360 | } | 339 | } |
361 | } | 340 | } |
362 | return chanidx; | 341 | return chanidx; |
@@ -370,15 +349,14 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv, | |||
370 | * length 06 00 | 349 | * length 06 00 |
371 | * ssid 4d 4e 54 45 53 54 | 350 | * ssid 4d 4e 54 45 53 54 |
372 | */ | 351 | */ |
373 | static int lbs_scan_add_ssid_tlv(uint8_t *tlv, | 352 | static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv) |
374 | const struct lbs_ioctl_user_scan_cfg *user_cfg) | ||
375 | { | 353 | { |
376 | struct mrvlietypes_ssidparamset *ssid_tlv = (void *)tlv; | 354 | struct mrvlietypes_ssidparamset *ssid_tlv = (void *)tlv; |
377 | 355 | ||
378 | ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID); | 356 | ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID); |
379 | ssid_tlv->header.len = cpu_to_le16(user_cfg->ssid_len); | 357 | ssid_tlv->header.len = cpu_to_le16(priv->scan_ssid_len); |
380 | memcpy(ssid_tlv->ssid, user_cfg->ssid, user_cfg->ssid_len); | 358 | memcpy(ssid_tlv->ssid, priv->scan_ssid, priv->scan_ssid_len); |
381 | return sizeof(ssid_tlv->header) + user_cfg->ssid_len; | 359 | return sizeof(ssid_tlv->header) + priv->scan_ssid_len; |
382 | } | 360 | } |
383 | 361 | ||
384 | 362 | ||
@@ -461,8 +439,7 @@ static int lbs_scan_add_rates_tlv(uint8_t *tlv) | |||
461 | * for a bunch of channels. | 439 | * for a bunch of channels. |
462 | */ | 440 | */ |
463 | static int lbs_do_scan(struct lbs_private *priv, uint8_t bsstype, | 441 | static int lbs_do_scan(struct lbs_private *priv, uint8_t bsstype, |
464 | struct chanscanparamset *chan_list, int chan_count, | 442 | struct chanscanparamset *chan_list, int chan_count) |
465 | const struct lbs_ioctl_user_scan_cfg *user_cfg) | ||
466 | { | 443 | { |
467 | int ret = -ENOMEM; | 444 | int ret = -ENOMEM; |
468 | struct cmd_ds_802_11_scan *scan_cmd; | 445 | struct cmd_ds_802_11_scan *scan_cmd; |
@@ -477,13 +454,13 @@ static int lbs_do_scan(struct lbs_private *priv, uint8_t bsstype, | |||
477 | goto out; | 454 | goto out; |
478 | 455 | ||
479 | tlv = scan_cmd->tlvbuffer; | 456 | tlv = scan_cmd->tlvbuffer; |
480 | if (user_cfg) | 457 | /* TODO: do we need to scan for a specific BSSID? |
481 | memcpy(scan_cmd->bssid, user_cfg->bssid, ETH_ALEN); | 458 | memcpy(scan_cmd->bssid, priv->scan_bssid, ETH_ALEN); */ |
482 | scan_cmd->bsstype = bsstype; | 459 | scan_cmd->bsstype = bsstype; |
483 | 460 | ||
484 | /* add TLVs */ | 461 | /* add TLVs */ |
485 | if (user_cfg && user_cfg->ssid_len) | 462 | if (priv->scan_ssid_len) |
486 | tlv += lbs_scan_add_ssid_tlv(tlv, user_cfg); | 463 | tlv += lbs_scan_add_ssid_tlv(priv, tlv); |
487 | if (chan_list && chan_count) | 464 | if (chan_list && chan_count) |
488 | tlv += lbs_scan_add_chanlist_tlv(tlv, chan_list, chan_count); | 465 | tlv += lbs_scan_add_chanlist_tlv(tlv, chan_list, chan_count); |
489 | tlv += lbs_scan_add_rates_tlv(tlv); | 466 | tlv += lbs_scan_add_rates_tlv(tlv); |
@@ -516,14 +493,11 @@ out: | |||
516 | * update the internal driver scan table | 493 | * update the internal driver scan table |
517 | * | 494 | * |
518 | * @param priv A pointer to struct lbs_private structure | 495 | * @param priv A pointer to struct lbs_private structure |
519 | * @param puserscanin Pointer to the input configuration for the requested | 496 | * @param full_scan Do a full-scan (blocking) |
520 | * scan. | ||
521 | * | 497 | * |
522 | * @return 0 or < 0 if error | 498 | * @return 0 or < 0 if error |
523 | */ | 499 | */ |
524 | int lbs_scan_networks(struct lbs_private *priv, | 500 | static int lbs_scan_networks(struct lbs_private *priv, int full_scan) |
525 | const struct lbs_ioctl_user_scan_cfg *user_cfg, | ||
526 | int full_scan) | ||
527 | { | 501 | { |
528 | int ret = -ENOMEM; | 502 | int ret = -ENOMEM; |
529 | struct chanscanparamset *chan_list; | 503 | struct chanscanparamset *chan_list; |
@@ -531,7 +505,6 @@ int lbs_scan_networks(struct lbs_private *priv, | |||
531 | int chan_count; | 505 | int chan_count; |
532 | uint8_t bsstype = CMD_BSS_TYPE_ANY; | 506 | uint8_t bsstype = CMD_BSS_TYPE_ANY; |
533 | int numchannels = MRVDRV_CHANNELS_PER_SCAN_CMD; | 507 | int numchannels = MRVDRV_CHANNELS_PER_SCAN_CMD; |
534 | int filteredscan = 0; | ||
535 | union iwreq_data wrqu; | 508 | union iwreq_data wrqu; |
536 | #ifdef CONFIG_LIBERTAS_DEBUG | 509 | #ifdef CONFIG_LIBERTAS_DEBUG |
537 | struct bss_descriptor *iter; | 510 | struct bss_descriptor *iter; |
@@ -547,17 +520,16 @@ int lbs_scan_networks(struct lbs_private *priv, | |||
547 | if (full_scan && delayed_work_pending(&priv->scan_work)) | 520 | if (full_scan && delayed_work_pending(&priv->scan_work)) |
548 | cancel_delayed_work(&priv->scan_work); | 521 | cancel_delayed_work(&priv->scan_work); |
549 | 522 | ||
550 | /* Determine same scan parameters */ | 523 | /* User-specified bsstype or channel list |
524 | TODO: this can be implemented if some user-space application | ||
525 | need the feature. Formerly, it was accessible from debugfs, | ||
526 | but then nowhere used. | ||
551 | if (user_cfg) { | 527 | if (user_cfg) { |
552 | if (user_cfg->bsstype) | 528 | if (user_cfg->bsstype) |
553 | bsstype = user_cfg->bsstype; | 529 | bsstype = user_cfg->bsstype; |
554 | if (!is_zero_ether_addr(user_cfg->bssid)) { | 530 | } */ |
555 | numchannels = MRVDRV_MAX_CHANNELS_PER_SCAN; | 531 | |
556 | filteredscan = 1; | 532 | lbs_deb_scan("numchannels %d, bsstype %d\n", numchannels, bsstype); |
557 | } | ||
558 | } | ||
559 | lbs_deb_scan("numchannels %d, bsstype %d, filteredscan %d\n", | ||
560 | numchannels, bsstype, filteredscan); | ||
561 | 533 | ||
562 | /* Create list of channels to scan */ | 534 | /* Create list of channels to scan */ |
563 | chan_list = kzalloc(sizeof(struct chanscanparamset) * | 535 | chan_list = kzalloc(sizeof(struct chanscanparamset) * |
@@ -568,7 +540,7 @@ int lbs_scan_networks(struct lbs_private *priv, | |||
568 | } | 540 | } |
569 | 541 | ||
570 | /* We want to scan all channels */ | 542 | /* We want to scan all channels */ |
571 | chan_count = lbs_scan_create_channel_list(priv, chan_list, filteredscan); | 543 | chan_count = lbs_scan_create_channel_list(priv, chan_list); |
572 | 544 | ||
573 | netif_stop_queue(priv->dev); | 545 | netif_stop_queue(priv->dev); |
574 | netif_carrier_off(priv->dev); | 546 | netif_carrier_off(priv->dev); |
@@ -597,7 +569,7 @@ int lbs_scan_networks(struct lbs_private *priv, | |||
597 | lbs_deb_scan("scanning %d of %d channels\n", | 569 | lbs_deb_scan("scanning %d of %d channels\n", |
598 | to_scan, chan_count); | 570 | to_scan, chan_count); |
599 | ret = lbs_do_scan(priv, bsstype, curr_chans, | 571 | ret = lbs_do_scan(priv, bsstype, curr_chans, |
600 | to_scan, user_cfg); | 572 | to_scan); |
601 | if (ret) { | 573 | if (ret) { |
602 | lbs_pr_err("SCAN_CMD failed\n"); | 574 | lbs_pr_err("SCAN_CMD failed\n"); |
603 | goto out2; | 575 | goto out2; |
@@ -658,6 +630,17 @@ out: | |||
658 | 630 | ||
659 | 631 | ||
660 | 632 | ||
633 | void lbs_scan_worker(struct work_struct *work) | ||
634 | { | ||
635 | struct lbs_private *priv = | ||
636 | container_of(work, struct lbs_private, scan_work.work); | ||
637 | |||
638 | lbs_deb_enter(LBS_DEB_SCAN); | ||
639 | lbs_scan_networks(priv, 0); | ||
640 | lbs_deb_leave(LBS_DEB_SCAN); | ||
641 | } | ||
642 | |||
643 | |||
661 | /*********************************************************************/ | 644 | /*********************************************************************/ |
662 | /* */ | 645 | /* */ |
663 | /* Result interpretation */ | 646 | /* Result interpretation */ |
@@ -1068,7 +1051,7 @@ static struct bss_descriptor *lbs_find_best_ssid_in_list(struct lbs_private *pri | |||
1068 | } | 1051 | } |
1069 | 1052 | ||
1070 | /** | 1053 | /** |
1071 | * @brief Find the AP with specific ssid in the scan list | 1054 | * @brief Find the best AP |
1072 | * | 1055 | * |
1073 | * Used from association worker. | 1056 | * Used from association worker. |
1074 | * | 1057 | * |
@@ -1086,7 +1069,8 @@ int lbs_find_best_network_ssid(struct lbs_private *priv, uint8_t *out_ssid, | |||
1086 | 1069 | ||
1087 | lbs_deb_enter(LBS_DEB_SCAN); | 1070 | lbs_deb_enter(LBS_DEB_SCAN); |
1088 | 1071 | ||
1089 | lbs_scan_networks(priv, NULL, 1); | 1072 | priv->scan_ssid_len = 0; |
1073 | lbs_scan_networks(priv, 1); | ||
1090 | if (priv->surpriseremoved) | 1074 | if (priv->surpriseremoved) |
1091 | goto out; | 1075 | goto out; |
1092 | 1076 | ||
@@ -1112,29 +1096,24 @@ out: | |||
1112 | * @param priv A pointer to struct lbs_private structure | 1096 | * @param priv A pointer to struct lbs_private structure |
1113 | * @param ssid A pointer to the SSID to scan for | 1097 | * @param ssid A pointer to the SSID to scan for |
1114 | * @param ssid_len Length of the SSID | 1098 | * @param ssid_len Length of the SSID |
1115 | * @param clear_ssid Should existing scan results with this SSID | ||
1116 | * be cleared? | ||
1117 | * | 1099 | * |
1118 | * @return 0-success, otherwise fail | 1100 | * @return 0-success, otherwise fail |
1119 | */ | 1101 | */ |
1120 | int lbs_send_specific_ssid_scan(struct lbs_private *priv, uint8_t *ssid, | 1102 | int lbs_send_specific_ssid_scan(struct lbs_private *priv, uint8_t *ssid, |
1121 | uint8_t ssid_len, uint8_t clear_ssid) | 1103 | uint8_t ssid_len) |
1122 | { | 1104 | { |
1123 | struct lbs_ioctl_user_scan_cfg scancfg; | ||
1124 | int ret = 0; | 1105 | int ret = 0; |
1125 | 1106 | ||
1126 | lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s', clear %d", | 1107 | lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s'\n", |
1127 | escape_essid(ssid, ssid_len), clear_ssid); | 1108 | escape_essid(ssid, ssid_len)); |
1128 | 1109 | ||
1129 | if (!ssid_len) | 1110 | if (!ssid_len) |
1130 | goto out; | 1111 | goto out; |
1131 | 1112 | ||
1132 | memset(&scancfg, 0x00, sizeof(scancfg)); | 1113 | memcpy(priv->scan_ssid, ssid, ssid_len); |
1133 | memcpy(scancfg.ssid, ssid, ssid_len); | 1114 | priv->scan_ssid_len = ssid_len; |
1134 | scancfg.ssid_len = ssid_len; | ||
1135 | scancfg.clear_ssid = clear_ssid; | ||
1136 | 1115 | ||
1137 | lbs_scan_networks(priv, &scancfg, 1); | 1116 | lbs_scan_networks(priv, 1); |
1138 | if (priv->surpriseremoved) { | 1117 | if (priv->surpriseremoved) { |
1139 | ret = -1; | 1118 | ret = -1; |
1140 | goto out; | 1119 | goto out; |
@@ -1317,27 +1296,36 @@ out: | |||
1317 | * @return 0 --success, otherwise fail | 1296 | * @return 0 --success, otherwise fail |
1318 | */ | 1297 | */ |
1319 | int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, | 1298 | int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, |
1320 | struct iw_param *wrqu, char *extra) | 1299 | union iwreq_data *wrqu, char *extra) |
1321 | { | 1300 | { |
1322 | struct lbs_private *priv = dev->priv; | 1301 | struct lbs_private *priv = dev->priv; |
1302 | int ret = 0; | ||
1323 | 1303 | ||
1324 | lbs_deb_enter(LBS_DEB_SCAN); | 1304 | lbs_deb_enter(LBS_DEB_WEXT); |
1325 | 1305 | ||
1326 | if (!netif_running(dev)) | 1306 | if (!netif_running(dev)) { |
1327 | return -ENETDOWN; | 1307 | ret = -ENETDOWN; |
1308 | goto out; | ||
1309 | } | ||
1328 | 1310 | ||
1329 | /* mac80211 does this: | 1311 | /* mac80211 does this: |
1330 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1312 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1331 | if (sdata->type != IEEE80211_IF_TYPE_xxx) | 1313 | if (sdata->type != IEEE80211_IF_TYPE_xxx) { |
1332 | return -EOPNOTSUPP; | 1314 | ret = -EOPNOTSUPP; |
1315 | goto out; | ||
1316 | } | ||
1317 | */ | ||
1333 | 1318 | ||
1334 | if (wrqu->data.length == sizeof(struct iw_scan_req) && | 1319 | if (wrqu->data.length == sizeof(struct iw_scan_req) && |
1335 | wrqu->data.flags & IW_SCAN_THIS_ESSID) { | 1320 | wrqu->data.flags & IW_SCAN_THIS_ESSID) { |
1336 | req = (struct iw_scan_req *)extra; | 1321 | struct iw_scan_req *req = (struct iw_scan_req *)extra; |
1337 | ssid = req->essid; | 1322 | priv->scan_ssid_len = req->essid_len; |
1338 | ssid_len = req->essid_len; | 1323 | memcpy(priv->scan_ssid, req->essid, priv->scan_ssid_len); |
1324 | lbs_deb_wext("set_scan, essid '%s'\n", | ||
1325 | escape_essid(priv->scan_ssid, priv->scan_ssid_len)); | ||
1326 | } else { | ||
1327 | priv->scan_ssid_len = 0; | ||
1339 | } | 1328 | } |
1340 | */ | ||
1341 | 1329 | ||
1342 | if (!delayed_work_pending(&priv->scan_work)) | 1330 | if (!delayed_work_pending(&priv->scan_work)) |
1343 | queue_delayed_work(priv->work_thread, &priv->scan_work, | 1331 | queue_delayed_work(priv->work_thread, &priv->scan_work, |
@@ -1346,10 +1334,11 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, | |||
1346 | priv->scan_channel = -1; | 1334 | priv->scan_channel = -1; |
1347 | 1335 | ||
1348 | if (priv->surpriseremoved) | 1336 | if (priv->surpriseremoved) |
1349 | return -EIO; | 1337 | ret = -EIO; |
1350 | 1338 | ||
1351 | lbs_deb_leave(LBS_DEB_SCAN); | 1339 | out: |
1352 | return 0; | 1340 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); |
1341 | return ret; | ||
1353 | } | 1342 | } |
1354 | 1343 | ||
1355 | 1344 | ||
@@ -1374,7 +1363,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, | |||
1374 | struct bss_descriptor *iter_bss; | 1363 | struct bss_descriptor *iter_bss; |
1375 | struct bss_descriptor *safe; | 1364 | struct bss_descriptor *safe; |
1376 | 1365 | ||
1377 | lbs_deb_enter(LBS_DEB_SCAN); | 1366 | lbs_deb_enter(LBS_DEB_WEXT); |
1378 | 1367 | ||
1379 | /* iwlist should wait until the current scan is finished */ | 1368 | /* iwlist should wait until the current scan is finished */ |
1380 | if (priv->scan_channel) | 1369 | if (priv->scan_channel) |
@@ -1418,7 +1407,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, | |||
1418 | dwrq->length = (ev - extra); | 1407 | dwrq->length = (ev - extra); |
1419 | dwrq->flags = 0; | 1408 | dwrq->flags = 0; |
1420 | 1409 | ||
1421 | lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", err); | 1410 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", err); |
1422 | return err; | 1411 | return err; |
1423 | } | 1412 | } |
1424 | 1413 | ||
diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h index 10d1196acf78..c50c8b74714b 100644 --- a/drivers/net/wireless/libertas/scan.h +++ b/drivers/net/wireless/libertas/scan.h | |||
@@ -12,8 +12,6 @@ | |||
12 | 12 | ||
13 | /** | 13 | /** |
14 | * @brief Maximum number of channels that can be sent in a setuserscan ioctl | 14 | * @brief Maximum number of channels that can be sent in a setuserscan ioctl |
15 | * | ||
16 | * @sa lbs_ioctl_user_scan_cfg | ||
17 | */ | 15 | */ |
18 | #define LBS_IOCTL_USER_SCAN_CHAN_MAX 50 | 16 | #define LBS_IOCTL_USER_SCAN_CHAN_MAX 50 |
19 | 17 | ||
@@ -27,60 +25,6 @@ | |||
27 | #define LBS_SCAN_BSS_TYPE_ANY 3 | 25 | #define LBS_SCAN_BSS_TYPE_ANY 3 |
28 | 26 | ||
29 | /** | 27 | /** |
30 | * @brief IOCTL channel sub-structure sent in lbs_ioctl_user_scan_cfg | ||
31 | * | ||
32 | * Multiple instances of this structure are included in the IOCTL command | ||
33 | * to configure a instance of a scan on the specific channel. | ||
34 | */ | ||
35 | struct lbs_ioctl_user_scan_chan { | ||
36 | u8 channumber; //!< channel Number to scan | ||
37 | u8 radiotype; //!< Radio type: 'B/G' band = 0, 'A' band = 1 | ||
38 | u8 scantype; //!< Scan type: Active = 0, Passive = 1 | ||
39 | u16 scantime; //!< Scan duration in milliseconds; if 0 default used | ||
40 | }; | ||
41 | |||
42 | /** | ||
43 | * @brief IOCTL input structure to configure an immediate scan cmd to firmware | ||
44 | * | ||
45 | * Used in the setuserscan (LBS_SET_USER_SCAN) private ioctl. Specifies | ||
46 | * a number of parameters to be used in general for the scan as well | ||
47 | * as a channel list (lbs_ioctl_user_scan_chan) for each scan period | ||
48 | * desired. | ||
49 | * | ||
50 | * @sa lbs_set_user_scan_ioctl | ||
51 | */ | ||
52 | struct lbs_ioctl_user_scan_cfg { | ||
53 | /** | ||
54 | * @brief BSS type to be sent in the firmware command | ||
55 | * | ||
56 | * Field can be used to restrict the types of networks returned in the | ||
57 | * scan. valid settings are: | ||
58 | * | ||
59 | * - LBS_SCAN_BSS_TYPE_BSS (infrastructure) | ||
60 | * - LBS_SCAN_BSS_TYPE_IBSS (adhoc) | ||
61 | * - LBS_SCAN_BSS_TYPE_ANY (unrestricted, adhoc and infrastructure) | ||
62 | */ | ||
63 | u8 bsstype; | ||
64 | |||
65 | /** | ||
66 | * @brief BSSID filter sent in the firmware command to limit the results | ||
67 | */ | ||
68 | u8 bssid[ETH_ALEN]; | ||
69 | |||
70 | /* Clear existing scan results matching this BSSID */ | ||
71 | u8 clear_bssid; | ||
72 | |||
73 | /** | ||
74 | * @brief SSID filter sent in the firmware command to limit the results | ||
75 | */ | ||
76 | char ssid[IW_ESSID_MAX_SIZE]; | ||
77 | u8 ssid_len; | ||
78 | |||
79 | /* Clear existing scan results matching this SSID */ | ||
80 | u8 clear_ssid; | ||
81 | }; | ||
82 | |||
83 | /** | ||
84 | * @brief Structure used to store information for each beacon/probe response | 28 | * @brief Structure used to store information for each beacon/probe response |
85 | */ | 29 | */ |
86 | struct bss_descriptor { | 30 | struct bss_descriptor { |
@@ -136,21 +80,12 @@ int lbs_find_best_network_ssid(struct lbs_private *priv, u8 *out_ssid, | |||
136 | u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode); | 80 | u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode); |
137 | 81 | ||
138 | int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid, | 82 | int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid, |
139 | u8 ssid_len, u8 clear_ssid); | 83 | u8 ssid_len); |
140 | |||
141 | int lbs_scan_networks(struct lbs_private *priv, | ||
142 | const struct lbs_ioctl_user_scan_cfg *puserscanin, | ||
143 | int full_scan); | ||
144 | |||
145 | struct ifreq; | ||
146 | 84 | ||
147 | struct iw_point; | ||
148 | struct iw_param; | ||
149 | struct iw_request_info; | ||
150 | int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, | 85 | int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, |
151 | struct iw_point *dwrq, char *extra); | 86 | struct iw_point *dwrq, char *extra); |
152 | int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, | 87 | int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, |
153 | struct iw_param *vwrq, char *extra); | 88 | union iwreq_data *wrqu, char *extra); |
154 | 89 | ||
155 | void lbs_scan_worker(struct work_struct *work); | 90 | void lbs_scan_worker(struct work_struct *work); |
156 | 91 | ||
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index e8bfc26b10a4..cded4bb69164 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c | |||
@@ -579,6 +579,9 @@ static int lbs_get_range(struct net_device *dev, struct iw_request_info *info, | |||
579 | range->num_bitrates); | 579 | range->num_bitrates); |
580 | 580 | ||
581 | range->num_frequency = 0; | 581 | range->num_frequency = 0; |
582 | |||
583 | range->scan_capa = IW_SCAN_CAPA_ESSID; | ||
584 | |||
582 | if (priv->enable11d && | 585 | if (priv->enable11d && |
583 | (priv->connect_status == LBS_CONNECTED || | 586 | (priv->connect_status == LBS_CONNECTED || |
584 | priv->mesh_connect_status == LBS_CONNECTED)) { | 587 | priv->mesh_connect_status == LBS_CONNECTED)) { |