aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/htc_drv_main.c
diff options
context:
space:
mode:
authorVivek Natarajan <vnatarajan@atheros.com>2010-04-27 03:35:37 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-27 16:09:21 -0400
commit8a8572a821e5763525f5e4ac104bc28fd798fd5e (patch)
treea44cbed64f207cd8edc982e7ae0873e6aedd2252 /drivers/net/wireless/ath/ath9k/htc_drv_main.c
parent7b7b5e56d7bdfdd0eb5ea13e6c9613b16b8eac46 (diff)
ath9k_htc: Handle CONF_IDLE during unassociated state to save power.
Signed-off-by: Vivek Natarajan <vnatarajan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/htc_drv_main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c71
1 files changed, 52 insertions, 19 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 644776a51ac0..ca7f3a78eb11 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -94,8 +94,11 @@ void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv)
94 if (--priv->ps_usecount != 0) 94 if (--priv->ps_usecount != 0)
95 goto unlock; 95 goto unlock;
96 96
97 if (priv->ps_enabled) 97 if (priv->ps_idle)
98 ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP);
99 else if (priv->ps_enabled)
98 ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP); 100 ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP);
101
99unlock: 102unlock:
100 mutex_unlock(&priv->htc_pm_lock); 103 mutex_unlock(&priv->htc_pm_lock);
101} 104}
@@ -1096,7 +1099,7 @@ fail_tx:
1096 return 0; 1099 return 0;
1097} 1100}
1098 1101
1099static int ath9k_htc_start(struct ieee80211_hw *hw) 1102static int ath9k_htc_radio_enable(struct ieee80211_hw *hw)
1100{ 1103{
1101 struct ath9k_htc_priv *priv = hw->priv; 1104 struct ath9k_htc_priv *priv = hw->priv;
1102 struct ath_hw *ah = priv->ah; 1105 struct ath_hw *ah = priv->ah;
@@ -1112,8 +1115,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
1112 "Starting driver with initial channel: %d MHz\n", 1115 "Starting driver with initial channel: %d MHz\n",
1113 curchan->center_freq); 1116 curchan->center_freq);
1114 1117
1115 mutex_lock(&priv->mutex);
1116
1117 /* setup initial channel */ 1118 /* setup initial channel */
1118 init_channel = ath9k_cmn_get_curchannel(hw, ah); 1119 init_channel = ath9k_cmn_get_curchannel(hw, ah);
1119 1120
@@ -1126,7 +1127,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
1126 ath_print(common, ATH_DBG_FATAL, 1127 ath_print(common, ATH_DBG_FATAL,
1127 "Unable to reset hardware; reset status %d " 1128 "Unable to reset hardware; reset status %d "
1128 "(freq %u MHz)\n", ret, curchan->center_freq); 1129 "(freq %u MHz)\n", ret, curchan->center_freq);
1129 goto mutex_unlock; 1130 return ret;
1130 } 1131 }
1131 1132
1132 ath_update_txpow(priv); 1133 ath_update_txpow(priv);
@@ -1134,16 +1135,8 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
1134 mode = ath9k_htc_get_curmode(priv, init_channel); 1135 mode = ath9k_htc_get_curmode(priv, init_channel);
1135 htc_mode = cpu_to_be16(mode); 1136 htc_mode = cpu_to_be16(mode);
1136 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode); 1137 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
1137 if (ret)
1138 goto mutex_unlock;
1139
1140 WMI_CMD(WMI_ATH_INIT_CMDID); 1138 WMI_CMD(WMI_ATH_INIT_CMDID);
1141 if (ret)
1142 goto mutex_unlock;
1143
1144 WMI_CMD(WMI_START_RECV_CMDID); 1139 WMI_CMD(WMI_START_RECV_CMDID);
1145 if (ret)
1146 goto mutex_unlock;
1147 1140
1148 ath9k_host_rx_init(priv); 1141 ath9k_host_rx_init(priv);
1149 1142
@@ -1156,12 +1149,22 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
1156 1149
1157 ieee80211_wake_queues(hw); 1150 ieee80211_wake_queues(hw);
1158 1151
1159mutex_unlock: 1152 return ret;
1153}
1154
1155static int ath9k_htc_start(struct ieee80211_hw *hw)
1156{
1157 struct ath9k_htc_priv *priv = hw->priv;
1158 int ret = 0;
1159
1160 mutex_lock(&priv->mutex);
1161 ret = ath9k_htc_radio_enable(hw);
1160 mutex_unlock(&priv->mutex); 1162 mutex_unlock(&priv->mutex);
1163
1161 return ret; 1164 return ret;
1162} 1165}
1163 1166
1164static void ath9k_htc_stop(struct ieee80211_hw *hw) 1167static void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
1165{ 1168{
1166 struct ath9k_htc_priv *priv = hw->priv; 1169 struct ath9k_htc_priv *priv = hw->priv;
1167 struct ath_hw *ah = priv->ah; 1170 struct ath_hw *ah = priv->ah;
@@ -1169,11 +1172,8 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1169 int ret = 0; 1172 int ret = 0;
1170 u8 cmd_rsp; 1173 u8 cmd_rsp;
1171 1174
1172 mutex_lock(&priv->mutex);
1173
1174 if (priv->op_flags & OP_INVALID) { 1175 if (priv->op_flags & OP_INVALID) {
1175 ath_print(common, ATH_DBG_ANY, "Device not present\n"); 1176 ath_print(common, ATH_DBG_ANY, "Device not present\n");
1176 mutex_unlock(&priv->mutex);
1177 return; 1177 return;
1178 } 1178 }
1179 1179
@@ -1208,11 +1208,20 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1208 } 1208 }
1209 1209
1210 priv->op_flags |= OP_INVALID; 1210 priv->op_flags |= OP_INVALID;
1211 mutex_unlock(&priv->mutex);
1212 1211
1213 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); 1212 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
1214} 1213}
1215 1214
1215static void ath9k_htc_stop(struct ieee80211_hw *hw)
1216{
1217 struct ath9k_htc_priv *priv = hw->priv;
1218
1219 mutex_lock(&priv->mutex);
1220 ath9k_htc_radio_disable(hw);
1221 mutex_unlock(&priv->mutex);
1222}
1223
1224
1216static int ath9k_htc_add_interface(struct ieee80211_hw *hw, 1225static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1217 struct ieee80211_vif *vif) 1226 struct ieee80211_vif *vif)
1218{ 1227{
@@ -1326,6 +1335,23 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1326 1335
1327 mutex_lock(&priv->mutex); 1336 mutex_lock(&priv->mutex);
1328 1337
1338 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1339 bool enable_radio = false;
1340 bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1341
1342 if (!idle && priv->ps_idle)
1343 enable_radio = true;
1344
1345 priv->ps_idle = idle;
1346
1347 if (enable_radio) {
1348 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1349 ath9k_htc_radio_enable(hw);
1350 ath_print(common, ATH_DBG_CONFIG,
1351 "not-idle: enabling radio\n");
1352 }
1353 }
1354
1329 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 1355 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1330 struct ieee80211_channel *curchan = hw->conf.channel; 1356 struct ieee80211_channel *curchan = hw->conf.channel;
1331 int pos = curchan->hw_value; 1357 int pos = curchan->hw_value;
@@ -1369,6 +1395,13 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1369 } 1395 }
1370 } 1396 }
1371 1397
1398 if (priv->ps_idle) {
1399 ath_print(common, ATH_DBG_CONFIG,
1400 "idle: disabling radio\n");
1401 ath9k_htc_radio_disable(hw);
1402 }
1403
1404
1372 mutex_unlock(&priv->mutex); 1405 mutex_unlock(&priv->mutex);
1373 1406
1374 return 0; 1407 return 0;