wl1271: Remove beacon-loss-ind from PSM entry failure handling
[pandora-kernel.git] / drivers / net / wireless / wl12xx / wl1271_event.c
index 31d396b..8d0c18d 100644 (file)
@@ -68,6 +68,43 @@ static int wl1271_event_scan_complete(struct wl1271 *wl,
        return 0;
 }
 
+static int wl1271_event_ps_report(struct wl1271 *wl,
+                                 struct event_mailbox *mbox,
+                                 bool *beacon_loss)
+{
+       int ret = 0;
+
+       wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status);
+
+       switch (mbox->ps_status) {
+       case EVENT_ENTER_POWER_SAVE_FAIL:
+               if (!wl->psm) {
+                       wl->psm_entry_retry = 0;
+                       break;
+               }
+
+               if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) {
+                       wl->psm_entry_retry++;
+                       ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+               } else {
+                       wl1271_error("PSM entry failed, giving up.\n");
+                       wl->psm_entry_retry = 0;
+               }
+               break;
+       case EVENT_ENTER_POWER_SAVE_SUCCESS:
+               wl->psm_entry_retry = 0;
+               break;
+       case EVENT_EXIT_POWER_SAVE_FAIL:
+               wl1271_info("PSM exit failed");
+               break;
+       case EVENT_EXIT_POWER_SAVE_SUCCESS:
+       default:
+               break;
+       }
+
+       return ret;
+}
+
 static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
 {
        wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
@@ -79,6 +116,7 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
 {
        int ret;
        u32 vector;
+       bool beacon_loss = false;
 
        wl1271_event_mbox_dump(mbox);
 
@@ -101,7 +139,25 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
                wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
 
                /* indicate to the stack, that beacons have been lost */
+               beacon_loss = true;
+       }
+
+       if (vector & PS_REPORT_EVENT_ID) {
+               wl1271_debug(DEBUG_EVENT, "PS_REPORT_EVENT");
+               ret = wl1271_event_ps_report(wl, mbox, &beacon_loss);
+               if (ret < 0)
+                       return ret;
+       }
+
+       if (beacon_loss) {
+               /* Obviously, it's dangerous to release the mutex while
+                  we are holding many of the variables in the wl struct.
+                  That's why it's done last in the function, and care must
+                  be taken that nothing more is done after this function
+                  returns. */
+               mutex_unlock(&wl->mutex);
                ieee80211_beacon_loss(wl->vif);
+               mutex_lock(&wl->mutex);
        }
 
        return 0;
@@ -127,7 +183,7 @@ void wl1271_event_mbox_config(struct wl1271 *wl)
                     wl->mbox_ptr[0], wl->mbox_ptr[1]);
 }
 
-int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num, bool do_ack)
+int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
 {
        struct event_mailbox mbox;
        int ret;
@@ -147,9 +203,7 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num, bool do_ack)
                return ret;
 
        /* then we let the firmware know it can go on...*/
-       if (do_ack)
-               wl1271_spi_write32(wl, ACX_REG_INTERRUPT_TRIG,
-                                  INTR_TRIG_EVENT_ACK);
+       wl1271_spi_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
 
        return 0;
 }