|
@@ -2130,6 +2130,77 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
|
|
|
+{
|
|
|
+ struct ath6kl_vif *vif;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ vif = ath6kl_vif_first(ar);
|
|
|
+ if (!vif)
|
|
|
+ return -EIO;
|
|
|
+
|
|
|
+ if (!ath6kl_cfg80211_ready(vif))
|
|
|
+ return -EIO;
|
|
|
+
|
|
|
+ ath6kl_cfg80211_stop_all(ar);
|
|
|
+
|
|
|
+ /* Save the current power mode before enabling power save */
|
|
|
+ ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
|
|
|
+
|
|
|
+ ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ /* Disable WOW mode */
|
|
|
+ ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
|
|
|
+ ATH6KL_WOW_MODE_DISABLE,
|
|
|
+ 0, 0);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ /* Flush all non control pkts in TX path */
|
|
|
+ ath6kl_tx_data_cleanup(ar);
|
|
|
+
|
|
|
+ ret = ath6kl_cfg80211_host_sleep(ar, vif);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int ath6kl_cfg80211_deepsleep_resume(struct ath6kl *ar)
|
|
|
+{
|
|
|
+ struct ath6kl_vif *vif;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ vif = ath6kl_vif_first(ar);
|
|
|
+
|
|
|
+ if (!vif)
|
|
|
+ return -EIO;
|
|
|
+
|
|
|
+ if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
|
|
|
+ ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
|
|
|
+ ar->wmi->saved_pwr_mode);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
|
|
|
+ ATH6KL_HOST_MODE_AWAKE);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ ar->state = ATH6KL_STATE_ON;
|
|
|
+
|
|
|
+ /* Reset scan parameter to default values */
|
|
|
+ ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
|
|
|
+ 0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
int ath6kl_cfg80211_suspend(struct ath6kl *ar,
|
|
|
enum ath6kl_cfg_suspend_mode mode,
|
|
|
struct cfg80211_wowlan *wow)
|
|
@@ -2158,15 +2229,12 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
|
|
|
|
|
|
case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
|
|
|
|
|
|
- ath6kl_cfg80211_stop_all(ar);
|
|
|
-
|
|
|
- /* save the current power mode before enabling power save */
|
|
|
- ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
|
|
|
+ ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep suspend\n");
|
|
|
|
|
|
- ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
|
|
|
+ ret = ath6kl_cfg80211_deepsleep_suspend(ar);
|
|
|
if (ret) {
|
|
|
- ath6kl_warn("wmi powermode command failed during suspend: %d\n",
|
|
|
- ret);
|
|
|
+ ath6kl_err("deepsleep suspend failed: %d\n", ret);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
ar->state = ATH6KL_STATE_DEEPSLEEP;
|
|
@@ -2227,17 +2295,13 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar)
|
|
|
break;
|
|
|
|
|
|
case ATH6KL_STATE_DEEPSLEEP:
|
|
|
- if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
|
|
|
- ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
|
|
|
- ar->wmi->saved_pwr_mode);
|
|
|
- if (ret) {
|
|
|
- ath6kl_warn("wmi powermode command failed during resume: %d\n",
|
|
|
- ret);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- ar->state = ATH6KL_STATE_ON;
|
|
|
+ ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep resume\n");
|
|
|
|
|
|
+ ret = ath6kl_cfg80211_deepsleep_resume(ar);
|
|
|
+ if (ret) {
|
|
|
+ ath6kl_warn("deep sleep resume failed: %d\n", ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
break;
|
|
|
|
|
|
case ATH6KL_STATE_CUTPOWER:
|