aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaja Mani <rmani@qca.qualcomm.com>2012-03-21 05:33:38 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2012-03-26 09:07:40 -0400
commit40abc2defbca6a6d7fde49082586430350d0a535 (patch)
tree64e436a139d706cd8f6088481321eb0ab231c98f
parent055bde493fc9a41b6b3e45381b454c18e2045d5b (diff)
ath6kl: Optimize target power in deep sleep suspend
Adding below steps helps to get good power numbers in deep sleep suspend path, * Disable WOW mode. * Flush data packets and wait for all control packets. to be cleared in TX path before deep sleep suspend. * Set host sleep mode to SLEEP. Below steps are added to perform the recovery action while the system resume from deep sleep, * Set host sleep mode to AWAKE. * Reset scan parameters to default value. In addition, Debug prints are added to track deep sleep suspend/resume state. Signed-off-by: Raja Mani <rmani@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c98
1 files changed, 81 insertions, 17 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index e3c4c404ba11..80910286d1b8 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -2130,6 +2130,77 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
2130 return 0; 2130 return 0;
2131} 2131}
2132 2132
2133static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
2134{
2135 struct ath6kl_vif *vif;
2136 int ret;
2137
2138 vif = ath6kl_vif_first(ar);
2139 if (!vif)
2140 return -EIO;
2141
2142 if (!ath6kl_cfg80211_ready(vif))
2143 return -EIO;
2144
2145 ath6kl_cfg80211_stop_all(ar);
2146
2147 /* Save the current power mode before enabling power save */
2148 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2149
2150 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
2151 if (ret)
2152 return ret;
2153
2154 /* Disable WOW mode */
2155 ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
2156 ATH6KL_WOW_MODE_DISABLE,
2157 0, 0);
2158 if (ret)
2159 return ret;
2160
2161 /* Flush all non control pkts in TX path */
2162 ath6kl_tx_data_cleanup(ar);
2163
2164 ret = ath6kl_cfg80211_host_sleep(ar, vif);
2165 if (ret)
2166 return ret;
2167
2168 return 0;
2169}
2170
2171static int ath6kl_cfg80211_deepsleep_resume(struct ath6kl *ar)
2172{
2173 struct ath6kl_vif *vif;
2174 int ret;
2175
2176 vif = ath6kl_vif_first(ar);
2177
2178 if (!vif)
2179 return -EIO;
2180
2181 if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
2182 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
2183 ar->wmi->saved_pwr_mode);
2184 if (ret)
2185 return ret;
2186 }
2187
2188 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2189 ATH6KL_HOST_MODE_AWAKE);
2190 if (ret)
2191 return ret;
2192
2193 ar->state = ATH6KL_STATE_ON;
2194
2195 /* Reset scan parameter to default values */
2196 ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2197 0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2198 if (ret)
2199 return ret;
2200
2201 return 0;
2202}
2203
2133int ath6kl_cfg80211_suspend(struct ath6kl *ar, 2204int ath6kl_cfg80211_suspend(struct ath6kl *ar,
2134 enum ath6kl_cfg_suspend_mode mode, 2205 enum ath6kl_cfg_suspend_mode mode,
2135 struct cfg80211_wowlan *wow) 2206 struct cfg80211_wowlan *wow)
@@ -2158,15 +2229,12 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
2158 2229
2159 case ATH6KL_CFG_SUSPEND_DEEPSLEEP: 2230 case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
2160 2231
2161 ath6kl_cfg80211_stop_all(ar); 2232 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep suspend\n");
2162
2163 /* save the current power mode before enabling power save */
2164 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2165 2233
2166 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER); 2234 ret = ath6kl_cfg80211_deepsleep_suspend(ar);
2167 if (ret) { 2235 if (ret) {
2168 ath6kl_warn("wmi powermode command failed during suspend: %d\n", 2236 ath6kl_err("deepsleep suspend failed: %d\n", ret);
2169 ret); 2237 return ret;
2170 } 2238 }
2171 2239
2172 ar->state = ATH6KL_STATE_DEEPSLEEP; 2240 ar->state = ATH6KL_STATE_DEEPSLEEP;
@@ -2227,17 +2295,13 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar)
2227 break; 2295 break;
2228 2296
2229 case ATH6KL_STATE_DEEPSLEEP: 2297 case ATH6KL_STATE_DEEPSLEEP:
2230 if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) { 2298 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep resume\n");
2231 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
2232 ar->wmi->saved_pwr_mode);
2233 if (ret) {
2234 ath6kl_warn("wmi powermode command failed during resume: %d\n",
2235 ret);
2236 }
2237 }
2238
2239 ar->state = ATH6KL_STATE_ON;
2240 2299
2300 ret = ath6kl_cfg80211_deepsleep_resume(ar);
2301 if (ret) {
2302 ath6kl_warn("deep sleep resume failed: %d\n", ret);
2303 return ret;
2304 }
2241 break; 2305 break;
2242 2306
2243 case ATH6KL_STATE_CUTPOWER: 2307 case ATH6KL_STATE_CUTPOWER: