aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/cmd.c
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2010-11-12 10:15:03 -0500
committerLuciano Coelho <coelho@ti.com>2011-01-24 15:11:47 -0500
commit05285cf9b581af05813cfaa60e23227b009b7754 (patch)
tree9fc351f91f95680faf212ee715cdee25a867560c /drivers/net/wireless/wl12xx/cmd.c
parent98bdaabbbced007c7eb89cd373f9cb1640635b46 (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.c26
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 */
225static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) 225static 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
253static 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
252int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) 266int 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
1115out_free: 1131out_free:
1116 kfree(cmd); 1132 kfree(cmd);