aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2010-10-26 07:24:38 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-11-15 13:25:19 -0500
commitb739a42c921dcb0ae92cc14032b7f75dcba88e3b (patch)
tree85cc1cf771a013f2e040c1edcb90b4fe315e3df7 /drivers/net/wireless/wl12xx
parentfb2382c75b1292aff0ebc8e209b0cb9ba70bb2cf (diff)
wl1271: Fix scan failure detection
In scan_complete_work, because the mutex is released before accessing the scan->failed flag, it is possible for unfounded hardware recovery rounds to be executed. Fix this. Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com> Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c17
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_scan.c5
2 files changed, 17 insertions, 5 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 63036b53f9e..bec2b3d7878 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -1056,6 +1056,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
1056 wl->scan.state = WL1271_SCAN_STATE_IDLE; 1056 wl->scan.state = WL1271_SCAN_STATE_IDLE;
1057 kfree(wl->scan.scanned_ch); 1057 kfree(wl->scan.scanned_ch);
1058 wl->scan.scanned_ch = NULL; 1058 wl->scan.scanned_ch = NULL;
1059 wl->scan.req = NULL;
1059 ieee80211_scan_completed(wl->hw, true); 1060 ieee80211_scan_completed(wl->hw, true);
1060 } 1061 }
1061 1062
@@ -1676,6 +1677,16 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
1676 1677
1677 mutex_lock(&wl->mutex); 1678 mutex_lock(&wl->mutex);
1678 1679
1680 if (wl->state == WL1271_STATE_OFF) {
1681 /*
1682 * We cannot return -EBUSY here because cfg80211 will expect
1683 * a call to ieee80211_scan_completed if we do - in this case
1684 * there won't be any call.
1685 */
1686 ret = -EAGAIN;
1687 goto out;
1688 }
1689
1679 ret = wl1271_ps_elp_wakeup(wl, false); 1690 ret = wl1271_ps_elp_wakeup(wl, false);
1680 if (ret < 0) 1691 if (ret < 0)
1681 goto out; 1692 goto out;
@@ -2093,14 +2104,14 @@ static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx,
2093{ 2104{
2094 struct wl1271 *wl = hw->priv; 2105 struct wl1271 *wl = hw->priv;
2095 struct ieee80211_conf *conf = &hw->conf; 2106 struct ieee80211_conf *conf = &hw->conf;
2096 2107
2097 if (idx != 0) 2108 if (idx != 0)
2098 return -ENOENT; 2109 return -ENOENT;
2099 2110
2100 survey->channel = conf->channel; 2111 survey->channel = conf->channel;
2101 survey->filled = SURVEY_INFO_NOISE_DBM; 2112 survey->filled = SURVEY_INFO_NOISE_DBM;
2102 survey->noise = wl->noise; 2113 survey->noise = wl->noise;
2103 2114
2104 return 0; 2115 return 0;
2105} 2116}
2106 2117
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c
index 909bb47995b..e0661a543a3 100644
--- a/drivers/net/wireless/wl12xx/wl1271_scan.c
+++ b/drivers/net/wireless/wl12xx/wl1271_scan.c
@@ -48,14 +48,15 @@ void wl1271_scan_complete_work(struct work_struct *work)
48 wl->scan.state = WL1271_SCAN_STATE_IDLE; 48 wl->scan.state = WL1271_SCAN_STATE_IDLE;
49 kfree(wl->scan.scanned_ch); 49 kfree(wl->scan.scanned_ch);
50 wl->scan.scanned_ch = NULL; 50 wl->scan.scanned_ch = NULL;
51 mutex_unlock(&wl->mutex); 51 wl->scan.req = NULL;
52
53 ieee80211_scan_completed(wl->hw, false); 52 ieee80211_scan_completed(wl->hw, false);
54 53
55 if (wl->scan.failed) { 54 if (wl->scan.failed) {
56 wl1271_info("Scan completed due to error."); 55 wl1271_info("Scan completed due to error.");
57 ieee80211_queue_work(wl->hw, &wl->recovery_work); 56 ieee80211_queue_work(wl->hw, &wl->recovery_work);
58 } 57 }
58 mutex_unlock(&wl->mutex);
59
59} 60}
60 61
61 62