diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-scan.c | 65 |
1 files changed, 40 insertions, 25 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 6d02f41e8caa..e65a98d5d07f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -93,6 +93,19 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) | |||
93 | return ret; | 93 | return ret; |
94 | } | 94 | } |
95 | 95 | ||
96 | static void iwl_complete_scan(struct iwl_priv *priv, bool aborted) | ||
97 | { | ||
98 | /* check if scan was requested from mac80211 */ | ||
99 | if (priv->scan_request) { | ||
100 | IWL_DEBUG_SCAN(priv, "Complete scan in mac80211\n"); | ||
101 | ieee80211_scan_completed(priv->hw, aborted); | ||
102 | } | ||
103 | |||
104 | priv->is_internal_short_scan = false; | ||
105 | priv->scan_vif = NULL; | ||
106 | priv->scan_request = NULL; | ||
107 | } | ||
108 | |||
96 | static void iwl_do_scan_abort(struct iwl_priv *priv) | 109 | static void iwl_do_scan_abort(struct iwl_priv *priv) |
97 | { | 110 | { |
98 | int ret; | 111 | int ret; |
@@ -115,7 +128,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv) | |||
115 | clear_bit(STATUS_SCANNING, &priv->status); | 128 | clear_bit(STATUS_SCANNING, &priv->status); |
116 | clear_bit(STATUS_SCAN_HW, &priv->status); | 129 | clear_bit(STATUS_SCAN_HW, &priv->status); |
117 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | 130 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); |
118 | ieee80211_scan_completed(priv->hw, true); | 131 | iwl_complete_scan(priv, true); |
119 | } else | 132 | } else |
120 | IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n"); | 133 | IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n"); |
121 | } | 134 | } |
@@ -545,10 +558,11 @@ static void iwl_bg_scan_completed(struct work_struct *work) | |||
545 | { | 558 | { |
546 | struct iwl_priv *priv = | 559 | struct iwl_priv *priv = |
547 | container_of(work, struct iwl_priv, scan_completed); | 560 | container_of(work, struct iwl_priv, scan_completed); |
548 | bool internal = false, aborted; | 561 | bool aborted; |
549 | struct iwl_rxon_context *ctx; | 562 | struct iwl_rxon_context *ctx; |
550 | 563 | ||
551 | IWL_DEBUG_SCAN(priv, "SCAN complete scan\n"); | 564 | IWL_DEBUG_INFO(priv, "Completed %sscan.\n", |
565 | priv->is_internal_short_scan ? "internal short " : ""); | ||
552 | 566 | ||
553 | cancel_delayed_work(&priv->scan_check); | 567 | cancel_delayed_work(&priv->scan_check); |
554 | 568 | ||
@@ -558,37 +572,38 @@ static void iwl_bg_scan_completed(struct work_struct *work) | |||
558 | if (aborted) | 572 | if (aborted) |
559 | IWL_DEBUG_INFO(priv, "Aborted scan completed.\n"); | 573 | IWL_DEBUG_INFO(priv, "Aborted scan completed.\n"); |
560 | 574 | ||
561 | IWL_DEBUG_INFO(priv, "Setting scan to off\n"); | 575 | if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) { |
562 | 576 | IWL_DEBUG_INFO(priv, "Scan already completed.\n"); | |
563 | clear_bit(STATUS_SCANNING, &priv->status); | 577 | goto out; |
564 | |||
565 | if (priv->is_internal_short_scan) { | ||
566 | priv->is_internal_short_scan = false; | ||
567 | IWL_DEBUG_SCAN(priv, "internal short scan completed\n"); | ||
568 | internal = true; | ||
569 | } else if (priv->scan_request) { | ||
570 | priv->scan_request = NULL; | ||
571 | priv->scan_vif = NULL; | ||
572 | ieee80211_scan_completed(priv->hw, aborted); | ||
573 | } | 578 | } |
574 | 579 | ||
575 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 580 | if (priv->is_internal_short_scan && !aborted) { |
576 | goto out; | 581 | int err; |
577 | 582 | ||
578 | if (internal && priv->scan_request) { | 583 | /* Check if mac80211 requested scan during our internal scan */ |
579 | int err = iwl_scan_initiate(priv, priv->scan_vif, false, | 584 | if (priv->scan_request == NULL) |
580 | priv->scan_request->channels[0]->band); | 585 | goto out_complete; |
581 | 586 | ||
587 | /* If so request a new scan */ | ||
588 | err = iwl_scan_initiate(priv, priv->scan_vif, false, | ||
589 | priv->scan_request->channels[0]->band); | ||
582 | if (err) { | 590 | if (err) { |
583 | IWL_DEBUG_SCAN(priv, | 591 | IWL_DEBUG_SCAN(priv, |
584 | "failed to initiate pending scan: %d\n", err); | 592 | "failed to initiate pending scan: %d\n", err); |
585 | priv->scan_request = NULL; | 593 | aborted = true; |
586 | priv->scan_vif = NULL; | 594 | goto out_complete; |
587 | ieee80211_scan_completed(priv->hw, true); | 595 | } |
588 | } else | 596 | |
589 | goto out; | 597 | goto out; |
590 | } | 598 | } |
591 | 599 | ||
600 | out_complete: | ||
601 | iwl_complete_scan(priv, aborted); | ||
602 | |||
603 | /* Can we still talk to firmware ? */ | ||
604 | if (!iwl_is_ready_rf(priv)) | ||
605 | goto out; | ||
606 | |||
592 | /* Since setting the TXPOWER may have been deferred while | 607 | /* Since setting the TXPOWER may have been deferred while |
593 | * performing the scan, fire one off */ | 608 | * performing the scan, fire one off */ |
594 | iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); | 609 | iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); |