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>
This commit is contained in:
Arik Nemtsov 2010-11-12 17:15:03 +02:00 committed by Luciano Coelho
parent 98bdaabbbc
commit 05285cf9b5
1 changed files with 21 additions and 5 deletions

View File

@ -222,7 +222,7 @@ int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
* Poll the mailbox event field until any of the bits in the mask is set or a
* timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
*/
static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask)
{
u32 events_vector, event;
unsigned long timeout;
@ -231,7 +231,8 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
do {
if (time_after(jiffies, timeout)) {
ieee80211_queue_work(wl->hw, &wl->recovery_work);
wl1271_debug(DEBUG_CMD, "timeout waiting for event %d",
(int)mask);
return -ETIMEDOUT;
}
@ -249,6 +250,19 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
return 0;
}
static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
{
int ret;
ret = wl1271_cmd_wait_for_event_or_timeout(wl, mask);
if (ret != 0) {
ieee80211_queue_work(wl->hw, &wl->recovery_work);
return ret;
}
return 0;
}
int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
{
struct wl1271_cmd_join *join;
@ -1108,9 +1122,11 @@ int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid)
goto out_free;
}
ret = wl1271_cmd_wait_for_event(wl, STA_REMOVE_COMPLETE_EVENT_ID);
if (ret < 0)
wl1271_error("cmd remove sta event completion error");
/*
* We are ok with a timeout here. The event is sometimes not sent
* due to a firmware bug.
*/
wl1271_cmd_wait_for_event_or_timeout(wl, STA_REMOVE_COMPLETE_EVENT_ID);
out_free:
kfree(cmd);