diff options
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_boot.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_cmd.c | 38 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_cmd.h | 1 |
3 files changed, 36 insertions, 6 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index 4195298b5ab..2c7e5612d5b 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c @@ -410,7 +410,8 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl) /* unmask required mbox events */ wl->event_mask = BSS_LOSE_EVENT_ID | SCAN_COMPLETE_EVENT_ID | - PS_REPORT_EVENT_ID; + PS_REPORT_EVENT_ID | + JOIN_EVENT_COMPLETE_ID; ret = wl1271_event_unmask(wl); if (ret < 0) { diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index efd94f2c316..e677f979ca6 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c @@ -34,6 +34,7 @@ #include "wl1271_acx.h" #include "wl12xx_80211.h" #include "wl1271_cmd.h" +#include "wl1271_event.h" /* * send command to firmware @@ -248,6 +249,35 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) return ret; } +/* + * 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) +{ + u32 events_vector, event; + unsigned long timeout; + + timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); + + do { + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + + msleep(1); + + /* read from both event fields */ + wl1271_read(wl, wl->mbox_ptr[0], &events_vector, + sizeof(events_vector), false); + event = events_vector & mask; + wl1271_read(wl, wl->mbox_ptr[1], &events_vector, + sizeof(events_vector), false); + event |= events_vector & mask; + } while (!event); + + return 0; +} + int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) { static bool do_cal = true; @@ -318,11 +348,9 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) goto out_free; } - /* - * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to - * simplify locking we just sleep instead, for now - */ - msleep(10); + ret = wl1271_cmd_wait_for_event(wl, JOIN_EVENT_COMPLETE_ID); + if (ret < 0) + wl1271_error("cmd join event completion error"); out_free: kfree(join); diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h index 6324bbf3684..bdd7a3d8ece 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.h +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h @@ -123,6 +123,7 @@ enum cmd_templ { /* unit ms */ #define WL1271_COMMAND_TIMEOUT 2000 #define WL1271_CMD_TEMPL_MAX_SIZE 252 +#define WL1271_EVENT_TIMEOUT 100 struct wl1271_cmd_header { __le16 id; |