wl1251: wait for join command complete event
authorGrazvydas Ignotas <notasas@gmail.com>
Mon, 16 Aug 2010 16:37:28 +0000 (19:37 +0300)
committerGrazvydas Ignotas <notasas@gmail.com>
Tue, 17 Aug 2010 14:37:25 +0000 (17:37 +0300)
Poll for join command completion instead of waiting blindly for 10
msecs. There is a timeout of 100 msecs, if the command doesn't complete
by then, we return an error code.

Based on wl1271 patch 99d84c1de8fdf5f9b09f07fdbc628857a040bf8b
by Luciano Coelho.

Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
drivers/net/wireless/wl12xx/wl1251_boot.c
drivers/net/wireless/wl12xx/wl1251_event.c
drivers/net/wireless/wl12xx/wl1251_event.h
drivers/net/wireless/wl12xx/wl1251_main.c

index f6a7111..447fb20 100644 (file)
@@ -301,7 +301,7 @@ int wl1251_boot_run_firmware(struct wl1251 *wl)
                ROAMING_TRIGGER_LOW_RSSI_EVENT_ID |
                ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID |
                REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID |
                ROAMING_TRIGGER_LOW_RSSI_EVENT_ID |
                ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID |
                REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID |
-               BT_PTA_PREDICTION_EVENT_ID;
+               BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID;
 
        ret = wl1251_event_unmask(wl);
        if (ret < 0) {
 
        ret = wl1251_event_unmask(wl);
        if (ret < 0) {
index 020d764..e093a1c 100644 (file)
@@ -97,6 +97,35 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
        return 0;
 }
 
        return 0;
 }
 
+/*
+ * Poll the mailbox event field until any of the bits in the mask is set or a
+ * timeout occurs (WL1251_EVENT_TIMEOUT in msecs)
+ */
+int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms)
+{
+       u32 events_vector, event;
+       unsigned long timeout;
+
+       timeout = jiffies + msecs_to_jiffies(timeout_ms);
+
+       do {
+               if (time_after(jiffies, timeout))
+                       return -ETIMEDOUT;
+
+               msleep(1);
+
+               /* read from both event fields */
+               wl1251_mem_read(wl, wl->mbox_ptr[0], &events_vector,
+                               sizeof(events_vector));
+               event = events_vector & mask;
+               wl1251_mem_read(wl, wl->mbox_ptr[1], &events_vector,
+                               sizeof(events_vector));
+               event |= events_vector & mask;
+       } while (!event);
+
+       return 0;
+}
+
 int wl1251_event_unmask(struct wl1251 *wl)
 {
        int ret;
 int wl1251_event_unmask(struct wl1251 *wl)
 {
        int ret;
index f48a2b6..ec45647 100644 (file)
@@ -117,5 +117,6 @@ struct event_mailbox {
 int wl1251_event_unmask(struct wl1251 *wl);
 void wl1251_event_mbox_config(struct wl1251 *wl);
 int wl1251_event_handle(struct wl1251 *wl, u8 mbox);
 int wl1251_event_unmask(struct wl1251 *wl);
 void wl1251_event_mbox_config(struct wl1251 *wl);
 int wl1251_event_handle(struct wl1251 *wl, u8 mbox);
+int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms);
 
 #endif
 
 #endif
index 00b3624..c835cd5 100644 (file)
@@ -341,11 +341,9 @@ static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel,
        if (ret < 0)
                goto out;
 
        if (ret < 0)
                goto out;
 
-       /*
-        * FIXME: we should wait for JOIN_EVENT_COMPLETE_ID but to simplify
-        * locking we just sleep instead, for now
-        */
-       msleep(10);
+       ret = wl1251_event_wait(wl, JOIN_EVENT_COMPLETE_ID, 100);
+       if (ret < 0)
+               wl1251_warning("join timeout");
 
 out:
        return ret;
 
 out:
        return ret;