ath6kl: make sure WLAN power save is enabled during suspend
authorChilam Ng <chilamng@qca.qualcomm.com>
Wed, 5 Oct 2011 07:12:52 +0000 (10:12 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Fri, 11 Nov 2011 10:50:55 +0000 (12:50 +0200)
Power save is enabled during ath6kl init. But when user space disables power
save, the system will go into suspend with power save disabled. The ath6kl
driver will now explicitly enable power save prior to entering suspend and
restore its previous setting upon resume

Signed-off-by: Chilam Ng <chilamng@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/hif-ops.h
drivers/net/wireless/ath/ath6kl/hif.h
drivers/net/wireless/ath/ath6kl/main.c
drivers/net/wireless/ath/ath6kl/sdio.c
drivers/net/wireless/ath/ath6kl/wmi.h

index f03cc4a6fbc1dfe6aa8cf6bcb547e8fb307af77e..2acfa7fadd078ac44dac26f9d6da26f426bfd4ff 100644 (file)
@@ -1421,6 +1421,13 @@ static int ar6k_cfg80211_suspend(struct wiphy *wiphy,
 
        return ath6kl_hif_suspend(ar);
 }
+
+static int ar6k_cfg80211_resume(struct wiphy *wiphy)
+{
+       struct ath6kl *ar = wiphy_priv(wiphy);
+
+       return ath6kl_hif_resume(ar);
+}
 #endif
 
 static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
@@ -1832,6 +1839,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
        CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
 #ifdef CONFIG_PM
        .suspend = ar6k_cfg80211_suspend,
+       .resume = ar6k_cfg80211_resume,
 #endif
        .set_channel = ath6kl_set_channel,
        .add_beacon = ath6kl_add_beacon,
index d6c898f3d0b325a79ed968897f6cec9bdfd968a2..21b1575dd9f3ae69c20a75bb277cade0b76ae875 100644 (file)
@@ -74,4 +74,8 @@ static inline int ath6kl_hif_suspend(struct ath6kl *ar)
        return ar->hif_ops->suspend(ar);
 }
 
+static inline int ath6kl_hif_resume(struct ath6kl *ar)
+{
+       return ar->hif_ops->resume(ar);
+}
 #endif
index 797e2d1d9bf9f41ede26891e1ac1eef0f673be5c..906fde95bdd4ad88946c37f3319e92939fabccfc 100644 (file)
@@ -203,6 +203,7 @@ struct ath6kl_hif_ops {
                            struct hif_scatter_req *scat_req);
        void (*cleanup_scatter)(struct ath6kl *ar);
        int (*suspend)(struct ath6kl *ar);
+       int (*resume)(struct ath6kl *ar);
 };
 
 #endif
index adb16354cc4d82eb3e6e98b6488f46e721825074..e6937565a489fdedefd5e32820c158f8046543a4 100644 (file)
@@ -959,6 +959,13 @@ void ath6kl_deep_sleep_enable(struct ath6kl *ar)
                       "during suspend\n");
 
        ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED);
+
+       /* save the current power mode before enabling power save */
+       ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
+
+       if (ath6kl_wmi_powermode_cmd(ar->wmi, REC_POWER) != 0)
+               ath6kl_warn("ath6kl_deep_sleep_enable: "
+                       "wmi_powermode_cmd failed\n");
 }
 
 /* WMI Event handlers */
index 7695c2974d2c6c508c36dfaed30577b76349ad38..9b8ee1f53787cdbc6a83a4a3719b4ec471176cbc 100644 (file)
@@ -743,6 +743,18 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar)
        return 0;
 }
 
+static int ath6kl_sdio_resume(struct ath6kl *ar)
+{
+       if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
+               if (ath6kl_wmi_powermode_cmd(ar->wmi,
+                       ar->wmi->saved_pwr_mode) != 0)
+                       ath6kl_warn("ath6kl_sdio_resume: "
+                               "wmi_powermode_cmd failed\n");
+       }
+
+       return 0;
+}
+
 static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
        .read_write_sync = ath6kl_sdio_read_write_sync,
        .write_async = ath6kl_sdio_write_async,
@@ -754,6 +766,7 @@ static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
        .scat_req_rw = ath6kl_sdio_async_rw_scatter,
        .cleanup_scatter = ath6kl_sdio_cleanup_scatter,
        .suspend = ath6kl_sdio_suspend,
+       .resume = ath6kl_sdio_resume,
 };
 
 static int ath6kl_sdio_probe(struct sdio_func *func,
index f8e644d54aa78a042fab20328e33001fe7eea560..1600e7c878a4796e567a50c98f9ebe95a775d8cc 100644 (file)
@@ -132,6 +132,7 @@ struct wmi {
 
        u8 *last_mgmt_tx_frame;
        size_t last_mgmt_tx_frame_len;
+       u8 saved_pwr_mode;
 };
 
 struct host_app_area {