diff options
author | Arik Nemtsov <arik@wizery.com> | 2010-11-12 10:15:03 -0500 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-01-24 15:11:47 -0500 |
commit | 05285cf9b581af05813cfaa60e23227b009b7754 (patch) | |
tree | 9fc351f91f95680faf212ee715cdee25a867560c /drivers/net/wireless/wl12xx/cmd.c | |
parent | 98bdaabbbced007c7eb89cd373f9cb1640635b46 (diff) |
wl12xx: AP mode - workaround for FW bug on station remove
Sometimes an event indicating station removal is not sent up by
firmware. We work around this by always indicating success in when
a wait for the event timeouts.
Temporary workaround until a FW fix is introduced.
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Reviewed-by: Luciano Coelho <coelho@ti.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/cmd.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/cmd.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index f9c5ce91cb12..e28d9cab1185 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c | |||
@@ -222,7 +222,7 @@ int wl1271_cmd_ext_radio_parms(struct wl1271 *wl) | |||
222 | * Poll the mailbox event field until any of the bits in the mask is set or a | 222 | * Poll the mailbox event field until any of the bits in the mask is set or a |
223 | * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) | 223 | * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) |
224 | */ | 224 | */ |
225 | static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) | 225 | static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask) |
226 | { | 226 | { |
227 | u32 events_vector, event; | 227 | u32 events_vector, event; |
228 | unsigned long timeout; | 228 | unsigned long timeout; |
@@ -231,7 +231,8 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) | |||
231 | 231 | ||
232 | do { | 232 | do { |
233 | if (time_after(jiffies, timeout)) { | 233 | if (time_after(jiffies, timeout)) { |
234 | ieee80211_queue_work(wl->hw, &wl->recovery_work); | 234 | wl1271_debug(DEBUG_CMD, "timeout waiting for event %d", |
235 | (int)mask); | ||
235 | return -ETIMEDOUT; | 236 | return -ETIMEDOUT; |
236 | } | 237 | } |
237 | 238 | ||
@@ -249,6 +250,19 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) | |||
249 | return 0; | 250 | return 0; |
250 | } | 251 | } |
251 | 252 | ||
253 | static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) | ||
254 | { | ||
255 | int ret; | ||
256 | |||
257 | ret = wl1271_cmd_wait_for_event_or_timeout(wl, mask); | ||
258 | if (ret != 0) { | ||
259 | ieee80211_queue_work(wl->hw, &wl->recovery_work); | ||
260 | return ret; | ||
261 | } | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
252 | int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) | 266 | int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) |
253 | { | 267 | { |
254 | struct wl1271_cmd_join *join; | 268 | struct wl1271_cmd_join *join; |
@@ -1108,9 +1122,11 @@ int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid) | |||
1108 | goto out_free; | 1122 | goto out_free; |
1109 | } | 1123 | } |
1110 | 1124 | ||
1111 | ret = wl1271_cmd_wait_for_event(wl, STA_REMOVE_COMPLETE_EVENT_ID); | 1125 | /* |
1112 | if (ret < 0) | 1126 | * We are ok with a timeout here. The event is sometimes not sent |
1113 | wl1271_error("cmd remove sta event completion error"); | 1127 | * due to a firmware bug. |
1128 | */ | ||
1129 | wl1271_cmd_wait_for_event_or_timeout(wl, STA_REMOVE_COMPLETE_EVENT_ID); | ||
1114 | 1130 | ||
1115 | out_free: | 1131 | out_free: |
1116 | kfree(cmd); | 1132 | kfree(cmd); |