]> git.openpandora.org Git - pandora-wifi.git/commitdiff
wl1251: Handle failing PS entry
authorYuri Ershov <ext-yuri.ershov@nokia.com>
Wed, 27 Oct 2010 13:21:09 +0000 (17:21 +0400)
committerGrazvydas Ignotas <notasas@gmail.com>
Sun, 31 Oct 2010 20:10:34 +0000 (22:10 +0200)
It is possible, that the nullfunc message used to indicate to the
associated-to AP that we are going to power save fails to reach the
intended recipient. In that case, the STA and AP can become out of sync,
resulting in connection loss.

This patch adds code to attempt to recover from such failure by
resending the nullfunc.

Also fixed one compiler warning.

Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Yuri Ershov <ext-yuri.ershov@nokia.com>
drivers/net/wireless/wl12xx/wl1251.h
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 4a353e17ec7b700f94821a6ac07660880cbf7eb9..a851e7d6c5cd00e1318c12154a32b21a095df935 100644 (file)
@@ -365,6 +365,8 @@ struct wl1251 {
        /* PSM mode requested */
        bool psm_requested;
 
+       u8 ps_entry_retry;
+
        u16 beacon_int;
        u8 dtim_period;
 
index 447fb202a6ac724910fb3a9870f222ad5858bdbb..f2ec4161e929672d9e7748f5a99c0b3b95cf59a4 100644 (file)
@@ -301,7 +301,8 @@ 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 |
-               BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID;
+               BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID |
+               PS_REPORT_EVENT_ID;
 
        ret = wl1251_event_unmask(wl);
        if (ret < 0) {
index 6743690a86d6bc12131f051532e99f891472f045..8fed56bb23c31b4a283777f1da02a8fb64f8fe4f 100644 (file)
@@ -46,6 +46,38 @@ static int wl1251_event_scan_complete(struct wl1251 *wl,
        return 0;
 }
 
+#define WL1251_PS_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 ENTER_POWER_SAVE_FAIL:
+               if (!wl->psm) {
+                       wl->ps_entry_retry = 0;
+                       break;
+               }
+
+               if (wl->ps_entry_retry < WL1251_PS_ENTRY_RETRIES) {
+                       ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+                       wl->ps_entry_retry++;
+               } else {
+                       wl1251_error("Power save entry failed, giving up");
+                       wl->ps_entry_retry = 0;
+               }
+               break;
+       case ENTER_POWER_SAVE_SUCCESS:
+       default:
+               wl->ps_entry_retry = 0;
+               break;
+       }
+
+       return 0;
+}
+
 static void wl1251_event_mbox_dump(struct event_mailbox *mbox)
 {
        wl1251_debug(DEBUG_EVENT, "MBOX DUMP:");
@@ -79,6 +111,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_ID");
+               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");
                /* need to unlock mutex to avoid deadlocking with rtnl */
index ec456474a84260cd5bfba4f85ee4b150bec17188..e2ce0b1a92c2620fe4bd9a0fc8a6ddfa7d8b28f0 100644 (file)
@@ -75,6 +75,13 @@ enum {
        EVENT_MBOX_ALL_EVENT_ID                  = 0x7fffffff,
 };
 
+enum {
+       ENTER_POWER_SAVE_FAIL =  0,
+       ENTER_POWER_SAVE_SUCCESS,
+       EXIT_POWER_SAVE_FAIL,
+       EXIT_POWER_SAVE_SUCCESS
+};
+
 struct event_debug_report {
        u8 debug_event_id;
        u8 num_params;
index 049f6c83d3c98c7edfe553236f34e4bfe5e80563..2f7c65c2372522ffecaf9a07a62b41af76fdca4b 100644 (file)
@@ -503,6 +503,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
        wl->next_tx_complete = 0;
        wl->elp = false;
        wl->psm = 0;
+       wl->ps_entry_retry = 0;
        wl->tx_queue_stopped = false;
        wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
        wl->channel = WL1251_DEFAULT_CHANNEL;
@@ -1357,6 +1358,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
        wl->elp = false;
        wl->psm = 0;
        wl->psm_requested = false;
+       wl->ps_entry_retry = 0;
        wl->tx_queue_stopped = false;
        wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
        wl->beacon_int = WL1251_DEFAULT_BEACON_INT;