|
@@ -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,6 +117,13 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ 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 (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) {
|
|
|
wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
|
|
|
|