diff options
Diffstat (limited to 'drivers/net/wireless/libertas/scan.c')
-rw-r--r-- | drivers/net/wireless/libertas/scan.c | 139 |
1 files changed, 80 insertions, 59 deletions
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 8d4e1ee27395..e2e9ebcd8340 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c | |||
@@ -314,6 +314,16 @@ static void wlan_scan_create_channel_list(wlan_private * priv, | |||
314 | } | 314 | } |
315 | } | 315 | } |
316 | 316 | ||
317 | |||
318 | /* Delayed partial scan worker */ | ||
319 | void libertas_scan_worker(struct work_struct *work) | ||
320 | { | ||
321 | wlan_private *priv = container_of(work, wlan_private, scan_work.work); | ||
322 | |||
323 | wlan_scan_networks(priv, NULL, 0); | ||
324 | } | ||
325 | |||
326 | |||
317 | /** | 327 | /** |
318 | * @brief Construct a wlan_scan_cmd_config structure to use in issue scan cmds | 328 | * @brief Construct a wlan_scan_cmd_config structure to use in issue scan cmds |
319 | * | 329 | * |
@@ -408,7 +418,6 @@ wlan_scan_setup_scan_config(wlan_private * priv, | |||
408 | *pscancurrentonly = 0; | 418 | *pscancurrentonly = 0; |
409 | 419 | ||
410 | if (puserscanin) { | 420 | if (puserscanin) { |
411 | |||
412 | /* Set the bss type scan filter, use adapter setting if unset */ | 421 | /* Set the bss type scan filter, use adapter setting if unset */ |
413 | pscancfgout->bsstype = | 422 | pscancfgout->bsstype = |
414 | puserscanin->bsstype ? puserscanin->bsstype : CMD_BSS_TYPE_ANY; | 423 | puserscanin->bsstype ? puserscanin->bsstype : CMD_BSS_TYPE_ANY; |
@@ -468,59 +477,57 @@ wlan_scan_setup_scan_config(wlan_private * priv, | |||
468 | */ | 477 | */ |
469 | *ppchantlvout = (struct mrvlietypes_chanlistparamset *) ptlvpos; | 478 | *ppchantlvout = (struct mrvlietypes_chanlistparamset *) ptlvpos; |
470 | 479 | ||
471 | if (puserscanin && puserscanin->chanlist[0].channumber) { | 480 | if (!puserscanin || !puserscanin->chanlist[0].channumber) { |
481 | /* Create a default channel scan list */ | ||
482 | lbs_deb_scan("Scan: Creating full region channel list\n"); | ||
483 | wlan_scan_create_channel_list(priv, pscanchanlist, | ||
484 | *pfilteredscan); | ||
485 | goto out; | ||
486 | } | ||
472 | 487 | ||
473 | lbs_deb_scan("Scan: Using supplied channel list\n"); | 488 | lbs_deb_scan("Scan: Using supplied channel list\n"); |
489 | for (chanidx = 0; | ||
490 | chanidx < WLAN_IOCTL_USER_SCAN_CHAN_MAX | ||
491 | && puserscanin->chanlist[chanidx].channumber; chanidx++) { | ||
474 | 492 | ||
475 | for (chanidx = 0; | 493 | channel = puserscanin->chanlist[chanidx].channumber; |
476 | chanidx < WLAN_IOCTL_USER_SCAN_CHAN_MAX | 494 | (pscanchanlist + chanidx)->channumber = channel; |
477 | && puserscanin->chanlist[chanidx].channumber; chanidx++) { | ||
478 | 495 | ||
479 | channel = puserscanin->chanlist[chanidx].channumber; | 496 | radiotype = puserscanin->chanlist[chanidx].radiotype; |
480 | (pscanchanlist + chanidx)->channumber = channel; | 497 | (pscanchanlist + chanidx)->radiotype = radiotype; |
481 | 498 | ||
482 | radiotype = puserscanin->chanlist[chanidx].radiotype; | 499 | scantype = puserscanin->chanlist[chanidx].scantype; |
483 | (pscanchanlist + chanidx)->radiotype = radiotype; | ||
484 | 500 | ||
485 | scantype = puserscanin->chanlist[chanidx].scantype; | 501 | if (scantype == CMD_SCAN_TYPE_PASSIVE) { |
502 | (pscanchanlist + | ||
503 | chanidx)->chanscanmode.passivescan = 1; | ||
504 | } else { | ||
505 | (pscanchanlist + | ||
506 | chanidx)->chanscanmode.passivescan = 0; | ||
507 | } | ||
486 | 508 | ||
509 | if (puserscanin->chanlist[chanidx].scantime) { | ||
510 | scandur = puserscanin->chanlist[chanidx].scantime; | ||
511 | } else { | ||
487 | if (scantype == CMD_SCAN_TYPE_PASSIVE) { | 512 | if (scantype == CMD_SCAN_TYPE_PASSIVE) { |
488 | (pscanchanlist + | 513 | scandur = MRVDRV_PASSIVE_SCAN_CHAN_TIME; |
489 | chanidx)->chanscanmode.passivescan = 1; | ||
490 | } else { | ||
491 | (pscanchanlist + | ||
492 | chanidx)->chanscanmode.passivescan = 0; | ||
493 | } | ||
494 | |||
495 | if (puserscanin->chanlist[chanidx].scantime) { | ||
496 | scandur = | ||
497 | puserscanin->chanlist[chanidx].scantime; | ||
498 | } else { | 514 | } else { |
499 | if (scantype == CMD_SCAN_TYPE_PASSIVE) { | 515 | scandur = MRVDRV_ACTIVE_SCAN_CHAN_TIME; |
500 | scandur = MRVDRV_PASSIVE_SCAN_CHAN_TIME; | ||
501 | } else { | ||
502 | scandur = MRVDRV_ACTIVE_SCAN_CHAN_TIME; | ||
503 | } | ||
504 | } | 516 | } |
505 | |||
506 | (pscanchanlist + chanidx)->minscantime = | ||
507 | cpu_to_le16(scandur); | ||
508 | (pscanchanlist + chanidx)->maxscantime = | ||
509 | cpu_to_le16(scandur); | ||
510 | } | 517 | } |
511 | 518 | ||
512 | /* Check if we are only scanning the current channel */ | 519 | (pscanchanlist + chanidx)->minscantime = |
513 | if ((chanidx == 1) && (puserscanin->chanlist[0].channumber | 520 | cpu_to_le16(scandur); |
514 | == | 521 | (pscanchanlist + chanidx)->maxscantime = |
515 | priv->adapter->curbssparams.channel)) { | 522 | cpu_to_le16(scandur); |
516 | *pscancurrentonly = 1; | 523 | } |
517 | lbs_deb_scan("Scan: Scanning current channel only"); | ||
518 | } | ||
519 | 524 | ||
520 | } else { | 525 | /* Check if we are only scanning the current channel */ |
521 | lbs_deb_scan("Scan: Creating full region channel list\n"); | 526 | if ((chanidx == 1) && |
522 | wlan_scan_create_channel_list(priv, pscanchanlist, | 527 | (puserscanin->chanlist[0].channumber == |
523 | *pfilteredscan); | 528 | priv->adapter->curbssparams.channel)) { |
529 | *pscancurrentonly = 1; | ||
530 | lbs_deb_scan("Scan: Scanning current channel only"); | ||
524 | } | 531 | } |
525 | 532 | ||
526 | out: | 533 | out: |
@@ -604,12 +611,12 @@ static int wlan_scan_channel_list(wlan_private * priv, | |||
604 | while (tlvidx < maxchanperscan && ptmpchan->channumber | 611 | while (tlvidx < maxchanperscan && ptmpchan->channumber |
605 | && !doneearly && scanned < 2) { | 612 | && !doneearly && scanned < 2) { |
606 | 613 | ||
607 | lbs_deb_scan( | 614 | lbs_deb_scan("Scan: Chan(%3d), Radio(%d), mode(%d,%d), " |
608 | "Scan: Chan(%3d), Radio(%d), mode(%d,%d), Dur(%d)\n", | 615 | "Dur(%d)\n", |
609 | ptmpchan->channumber, ptmpchan->radiotype, | 616 | ptmpchan->channumber, ptmpchan->radiotype, |
610 | ptmpchan->chanscanmode.passivescan, | 617 | ptmpchan->chanscanmode.passivescan, |
611 | ptmpchan->chanscanmode.disablechanfilt, | 618 | ptmpchan->chanscanmode.disablechanfilt, |
612 | ptmpchan->maxscantime); | 619 | ptmpchan->maxscantime); |
613 | 620 | ||
614 | /* Copy the current channel TLV to the command being prepared */ | 621 | /* Copy the current channel TLV to the command being prepared */ |
615 | memcpy(pchantlvout->chanscanparam + tlvidx, | 622 | memcpy(pchantlvout->chanscanparam + tlvidx, |
@@ -678,9 +685,18 @@ static int wlan_scan_channel_list(wlan_private * priv, | |||
678 | done: | 685 | done: |
679 | priv->adapter->last_scanned_channel = ptmpchan->channumber; | 686 | priv->adapter->last_scanned_channel = ptmpchan->channumber; |
680 | 687 | ||
681 | /* Tell userspace the scan table has been updated */ | 688 | if (priv->adapter->last_scanned_channel) { |
682 | memset(&wrqu, 0, sizeof(union iwreq_data)); | 689 | /* Schedule the next part of the partial scan */ |
683 | wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); | 690 | if (!full_scan && !priv->adapter->surpriseremoved) { |
691 | cancel_delayed_work(&priv->scan_work); | ||
692 | queue_delayed_work(priv->work_thread, &priv->scan_work, | ||
693 | msecs_to_jiffies(300)); | ||
694 | } | ||
695 | } else { | ||
696 | /* All done, tell userspace the scan table has been updated */ | ||
697 | memset(&wrqu, 0, sizeof(union iwreq_data)); | ||
698 | wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); | ||
699 | } | ||
684 | 700 | ||
685 | lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); | 701 | lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); |
686 | return ret; | 702 | return ret; |
@@ -747,8 +763,8 @@ clear_selected_scan_list_entries(wlan_adapter * adapter, | |||
747 | * @return 0 or < 0 if error | 763 | * @return 0 or < 0 if error |
748 | */ | 764 | */ |
749 | int wlan_scan_networks(wlan_private * priv, | 765 | int wlan_scan_networks(wlan_private * priv, |
750 | const struct wlan_ioctl_user_scan_cfg * puserscanin, | 766 | const struct wlan_ioctl_user_scan_cfg * puserscanin, |
751 | int full_scan) | 767 | int full_scan) |
752 | { | 768 | { |
753 | wlan_adapter * adapter = priv->adapter; | 769 | wlan_adapter * adapter = priv->adapter; |
754 | struct mrvlietypes_chanlistparamset *pchantlvout; | 770 | struct mrvlietypes_chanlistparamset *pchantlvout; |
@@ -763,7 +779,13 @@ int wlan_scan_networks(wlan_private * priv, | |||
763 | int i = 0; | 779 | int i = 0; |
764 | #endif | 780 | #endif |
765 | 781 | ||
766 | lbs_deb_enter(LBS_DEB_ASSOC); | 782 | lbs_deb_enter(LBS_DEB_SCAN); |
783 | |||
784 | /* Cancel any partial outstanding partial scans if this scan | ||
785 | * is a full scan. | ||
786 | */ | ||
787 | if (full_scan && delayed_work_pending(&priv->scan_work)) | ||
788 | cancel_delayed_work(&priv->scan_work); | ||
767 | 789 | ||
768 | scan_chan_list = kzalloc(sizeof(struct chanscanparamset) * | 790 | scan_chan_list = kzalloc(sizeof(struct chanscanparamset) * |
769 | WLAN_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL); | 791 | WLAN_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL); |
@@ -1289,7 +1311,10 @@ int libertas_set_scan(struct net_device *dev, struct iw_request_info *info, | |||
1289 | 1311 | ||
1290 | lbs_deb_enter(LBS_DEB_SCAN); | 1312 | lbs_deb_enter(LBS_DEB_SCAN); |
1291 | 1313 | ||
1292 | wlan_scan_networks(priv, NULL, 0); | 1314 | if (!delayed_work_pending(&priv->scan_work)) { |
1315 | queue_delayed_work(priv->work_thread, &priv->scan_work, | ||
1316 | msecs_to_jiffies(50)); | ||
1317 | } | ||
1293 | 1318 | ||
1294 | if (adapter->surpriseremoved) | 1319 | if (adapter->surpriseremoved) |
1295 | return -1; | 1320 | return -1; |
@@ -1508,10 +1533,6 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, | |||
1508 | 1533 | ||
1509 | lbs_deb_enter(LBS_DEB_ASSOC); | 1534 | lbs_deb_enter(LBS_DEB_ASSOC); |
1510 | 1535 | ||
1511 | /* If we've got an uncompleted scan, schedule the next part */ | ||
1512 | if (!adapter->nr_cmd_pending && adapter->last_scanned_channel) | ||
1513 | wlan_scan_networks(priv, NULL, 0); | ||
1514 | |||
1515 | /* Update RSSI if current BSS is a locally created ad-hoc BSS */ | 1536 | /* Update RSSI if current BSS is a locally created ad-hoc BSS */ |
1516 | if ((adapter->mode == IW_MODE_ADHOC) && adapter->adhoccreate) { | 1537 | if ((adapter->mode == IW_MODE_ADHOC) && adapter->adhoccreate) { |
1517 | libertas_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, | 1538 | libertas_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, |