diff options
author | Juuso Oikarinen <juuso.oikarinen@nokia.com> | 2010-08-23 23:28:03 -0400 |
---|---|---|
committer | Luciano Coelho <luciano.coelho@nokia.com> | 2010-09-28 05:30:03 -0400 |
commit | c454f1d9a896d3519c756355b37bb39941093233 (patch) | |
tree | ad8f35ca3813f2a2462587a746cbc7b9bfe78208 /drivers | |
parent | 9987a9da3eda093ceeff14ad4926adb130a0d0ea (diff) |
wl1271: Move scan complete invocation into work function
The current scan implementation can jam, if the scan request ends up
containing no work. This can especially happen if there is a scan request
with only 11a band channels for HW that does not support 11a.
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')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_scan.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_scan.h | 1 |
4 files changed, 24 insertions, 5 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index 763ece823c54..272cff44ab53 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h | |||
@@ -416,6 +416,7 @@ struct wl1271 { | |||
416 | 416 | ||
417 | /* Are we currently scanning */ | 417 | /* Are we currently scanning */ |
418 | struct wl1271_scan scan; | 418 | struct wl1271_scan scan; |
419 | struct work_struct scan_complete_work; | ||
419 | 420 | ||
420 | /* Our association ID */ | 421 | /* Our association ID */ |
421 | u16 aid; | 422 | u16 aid; |
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 4b8f3662101f..0026e775bb0d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c | |||
@@ -634,6 +634,8 @@ static int wl1271_setup(struct wl1271 *wl) | |||
634 | 634 | ||
635 | INIT_WORK(&wl->irq_work, wl1271_irq_work); | 635 | INIT_WORK(&wl->irq_work, wl1271_irq_work); |
636 | INIT_WORK(&wl->tx_work, wl1271_tx_work); | 636 | INIT_WORK(&wl->tx_work, wl1271_tx_work); |
637 | INIT_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); | ||
638 | |||
637 | return 0; | 639 | return 0; |
638 | } | 640 | } |
639 | 641 | ||
@@ -962,6 +964,8 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, | |||
962 | struct wl1271 *wl = hw->priv; | 964 | struct wl1271 *wl = hw->priv; |
963 | int i; | 965 | int i; |
964 | 966 | ||
967 | cancel_work_sync(&wl->scan_complete_work); | ||
968 | |||
965 | mutex_lock(&wl->mutex); | 969 | mutex_lock(&wl->mutex); |
966 | wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); | 970 | wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); |
967 | 971 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c index 8d30150f3f46..9f1da82ed8d6 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c | |||
@@ -28,6 +28,23 @@ | |||
28 | #include "wl1271_scan.h" | 28 | #include "wl1271_scan.h" |
29 | #include "wl1271_acx.h" | 29 | #include "wl1271_acx.h" |
30 | 30 | ||
31 | void wl1271_scan_complete_work(struct work_struct *work) | ||
32 | { | ||
33 | struct wl1271 *wl = | ||
34 | container_of(work, struct wl1271, scan_complete_work); | ||
35 | |||
36 | wl1271_debug(DEBUG_SCAN, "Scanning complete"); | ||
37 | |||
38 | mutex_lock(&wl->mutex); | ||
39 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | ||
40 | kfree(wl->scan.scanned_ch); | ||
41 | wl->scan.scanned_ch = NULL; | ||
42 | mutex_unlock(&wl->mutex); | ||
43 | |||
44 | ieee80211_scan_completed(wl->hw, false); | ||
45 | } | ||
46 | |||
47 | |||
31 | static int wl1271_get_scan_channels(struct wl1271 *wl, | 48 | static int wl1271_get_scan_channels(struct wl1271 *wl, |
32 | struct cfg80211_scan_request *req, | 49 | struct cfg80211_scan_request *req, |
33 | struct basic_scan_channel_params *channels, | 50 | struct basic_scan_channel_params *channels, |
@@ -218,11 +235,7 @@ void wl1271_scan_stm(struct wl1271 *wl) | |||
218 | break; | 235 | break; |
219 | 236 | ||
220 | case WL1271_SCAN_STATE_DONE: | 237 | case WL1271_SCAN_STATE_DONE: |
221 | kfree(wl->scan.scanned_ch); | 238 | ieee80211_queue_work(wl->hw, &wl->scan_complete_work); |
222 | wl->scan.scanned_ch = NULL; | ||
223 | |||
224 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | ||
225 | ieee80211_scan_completed(wl->hw, false); | ||
226 | break; | 239 | break; |
227 | 240 | ||
228 | default: | 241 | default: |
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.h b/drivers/net/wireless/wl12xx/wl1271_scan.h index f1815700f5f9..1404e00dc963 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.h +++ b/drivers/net/wireless/wl12xx/wl1271_scan.h | |||
@@ -32,6 +32,7 @@ int wl1271_scan_build_probe_req(struct wl1271 *wl, | |||
32 | const u8 *ssid, size_t ssid_len, | 32 | const u8 *ssid, size_t ssid_len, |
33 | const u8 *ie, size_t ie_len, u8 band); | 33 | const u8 *ie, size_t ie_len, u8 band); |
34 | void wl1271_scan_stm(struct wl1271 *wl); | 34 | void wl1271_scan_stm(struct wl1271 *wl); |
35 | void wl1271_scan_complete_work(struct work_struct *work); | ||
35 | 36 | ||
36 | #define WL1271_SCAN_MAX_CHANNELS 24 | 37 | #define WL1271_SCAN_MAX_CHANNELS 24 |
37 | #define WL1271_SCAN_DEFAULT_TAG 1 | 38 | #define WL1271_SCAN_DEFAULT_TAG 1 |