wl12xx: Set different wake up conditions in case of suspend
authorEyal Shapira <eyal@wizery.com>
Thu, 2 Feb 2012 10:03:39 +0000 (12:03 +0200)
committerLuciano Coelho <coelho@ti.com>
Wed, 15 Feb 2012 06:38:33 +0000 (08:38 +0200)
Added ability to set different wake up conditions for suspend/resume.
Set default values to wake up every 3 DTIMs while suspended
and every 1 DTIM while resumed

Signed-off-by: Eyal Shapira <eyal@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/ps.c

index af2c312..bc96db0 100644 (file)
 #include "reg.h"
 #include "ps.h"
 
-int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif)
+int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+                                 u8 wake_up_event, u8 listen_interval)
 {
        struct acx_wake_up_condition *wake_up;
        int ret;
 
-       wl1271_debug(DEBUG_ACX, "acx wake up conditions");
+       wl1271_debug(DEBUG_ACX, "acx wake up conditions (wake_up_event %d listen_interval %d)",
+                    wake_up_event, listen_interval);
 
        wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
        if (!wake_up) {
@@ -48,8 +50,8 @@ int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif)
        }
 
        wake_up->role_id = wlvif->role_id;
-       wake_up->wake_up_event = wl->conf.conn.wake_up_event;
-       wake_up->listen_interval = wl->conf.conn.listen_interval;
+       wake_up->wake_up_event = wake_up_event;
+       wake_up->listen_interval = listen_interval;
 
        ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
                                   wake_up, sizeof(*wake_up));
index 0749df5..a28fc04 100644 (file)
@@ -1226,7 +1226,8 @@ enum {
 
 
 int wl1271_acx_wake_up_conditions(struct wl1271 *wl,
-                                 struct wl12xx_vif *wlvif);
+                                 struct wl12xx_vif *wlvif,
+                                 u8 wake_up_event, u8 listen_interval);
 int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth);
 int wl1271_acx_tx_power(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                        int power);
index 18637ee..80eafad 100644 (file)
@@ -819,6 +819,19 @@ struct conf_conn_settings {
        u8 listen_interval;
 
        /*
+        * Firmware wakeup conditions during suspend
+        * Range: CONF_WAKE_UP_EVENT_*
+        */
+       u8 suspend_wake_up_event;
+
+       /*
+        * Listen interval during suspend.
+        * Currently will be in DTIMs (1-10)
+        *
+        */
+       u8 suspend_listen_interval;
+
+       /*
         * Enable or disable the beacon filtering.
         *
         * Range: CONF_BCN_FILT_MODE_*
index aa5d512..fa61dfd 100644 (file)
@@ -221,6 +221,8 @@ static struct conf_drv_settings default_conf = {
        .conn = {
                .wake_up_event               = CONF_WAKE_UP_EVENT_DTIM,
                .listen_interval             = 1,
+               .suspend_wake_up_event       = CONF_WAKE_UP_EVENT_N_DTIM,
+               .suspend_listen_interval     = 3,
                .bcn_filt_mode               = CONF_BCN_FILT_MODE_ENABLED,
                .bcn_filt_ie_count           = 2,
                .bcn_filt_ie = {
@@ -1574,6 +1576,35 @@ static struct notifier_block wl1271_dev_notifier = {
 };
 
 #ifdef CONFIG_PM
+static int wl1271_configure_suspend_sta(struct wl1271 *wl,
+                                       struct wl12xx_vif *wlvif)
+{
+       int ret = 0;
+
+       mutex_lock(&wl->mutex);
+
+       if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+               goto out_unlock;
+
+       ret = wl1271_ps_elp_wakeup(wl);
+       if (ret < 0)
+               goto out_unlock;
+
+       ret = wl1271_acx_wake_up_conditions(wl, wlvif,
+                                   wl->conf.conn.suspend_wake_up_event,
+                                   wl->conf.conn.suspend_listen_interval);
+
+       if (ret < 0)
+               wl1271_error("suspend: set wake up conditions failed: %d", ret);
+
+
+       wl1271_ps_elp_sleep(wl);
+
+out_unlock:
+       mutex_unlock(&wl->mutex);
+       return ret;
+
+}
 
 static int wl1271_configure_suspend_ap(struct wl1271 *wl,
                                       struct wl12xx_vif *wlvif)
@@ -1601,6 +1632,8 @@ out_unlock:
 static int wl1271_configure_suspend(struct wl1271 *wl,
                                    struct wl12xx_vif *wlvif)
 {
+       if (wlvif->bss_type == BSS_TYPE_STA_BSS)
+               return wl1271_configure_suspend_sta(wl, wlvif);
        if (wlvif->bss_type == BSS_TYPE_AP_BSS)
                return wl1271_configure_suspend_ap(wl, wlvif);
        return 0;
@@ -1609,10 +1642,11 @@ static int wl1271_configure_suspend(struct wl1271 *wl,
 static void wl1271_configure_resume(struct wl1271 *wl,
                                    struct wl12xx_vif *wlvif)
 {
-       int ret;
+       int ret = 0;
        bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
+       bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
 
-       if (!is_ap)
+       if ((!is_ap) && (!is_sta))
                return;
 
        mutex_lock(&wl->mutex);
@@ -1620,7 +1654,18 @@ static void wl1271_configure_resume(struct wl1271 *wl,
        if (ret < 0)
                goto out;
 
-       wl1271_acx_beacon_filter_opt(wl, wlvif, false);
+       if (is_sta) {
+               ret = wl1271_acx_wake_up_conditions(wl, wlvif,
+                                   wl->conf.conn.wake_up_event,
+                                   wl->conf.conn.listen_interval);
+
+               if (ret < 0)
+                       wl1271_error("resume: wake up conditions failed: %d",
+                                    ret);
+
+       } else if (is_ap) {
+               ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
+       }
 
        wl1271_ps_elp_sleep(wl);
 out:
index e209e29..d197922 100644 (file)
@@ -170,7 +170,9 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                wl1271_debug(DEBUG_PSM, "entering psm (mode=%d,timeout=%u)",
                             mode, timeout);
 
-               ret = wl1271_acx_wake_up_conditions(wl, wlvif);
+               ret = wl1271_acx_wake_up_conditions(wl, wlvif,
+                                           wl->conf.conn.wake_up_event,
+                                           wl->conf.conn.listen_interval);
                if (ret < 0) {
                        wl1271_error("couldn't set wake up conditions");
                        return ret;