wl1251: fix NULL pointer dereference
[cascardo/linux.git] / drivers / net / wireless / ti / wl1251 / event.c
index 74ae8e1..db01053 100644 (file)
@@ -46,6 +46,43 @@ static int wl1251_event_scan_complete(struct wl1251 *wl,
        return ret;
 }
 
+#define WL1251_PSM_ENTRY_RETRIES  3
+static int wl1251_event_ps_report(struct wl1251 *wl,
+                                 struct event_mailbox *mbox)
+{
+       int ret = 0;
+
+       wl1251_debug(DEBUG_EVENT, "ps status: %x", mbox->ps_status);
+
+       switch (mbox->ps_status) {
+       case EVENT_ENTER_POWER_SAVE_FAIL:
+               wl1251_debug(DEBUG_PSM, "PSM entry failed");
+
+               if (wl->station_mode != STATION_POWER_SAVE_MODE) {
+                       /* remain in active mode */
+                       wl->psm_entry_retry = 0;
+                       break;
+               }
+
+               if (wl->psm_entry_retry < WL1251_PSM_ENTRY_RETRIES) {
+                       wl->psm_entry_retry++;
+                       ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+               } else {
+                       wl1251_error("Power save entry failed, giving up");
+                       wl->psm_entry_retry = 0;
+               }
+               break;
+       case EVENT_ENTER_POWER_SAVE_SUCCESS:
+       case EVENT_EXIT_POWER_SAVE_FAIL:
+       case EVENT_EXIT_POWER_SAVE_SUCCESS:
+       default:
+               wl->psm_entry_retry = 0;
+               break;
+       }
+
+       return 0;
+}
+
 static void wl1251_event_mbox_dump(struct event_mailbox *mbox)
 {
        wl1251_debug(DEBUG_EVENT, "MBOX DUMP:");
@@ -80,7 +117,14 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
                }
        }
 
-       if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) {
+       if (vector & PS_REPORT_EVENT_ID) {
+               wl1251_debug(DEBUG_EVENT, "PS_REPORT_EVENT");
+               ret = wl1251_event_ps_report(wl, mbox);
+               if (ret < 0)
+                       return ret;
+       }
+
+       if (wl->vif && vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) {
                wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
 
                /* indicate to the stack, that beacons have been lost */