aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/htc_drv_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/htc_drv_main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c84
1 files changed, 59 insertions, 25 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index ec7bcc8696ec..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}
@@ -153,7 +156,6 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
153 ath_print(common, ATH_DBG_FATAL, 156 ath_print(common, ATH_DBG_FATAL,
154 "Unable to reset channel (%u Mhz) " 157 "Unable to reset channel (%u Mhz) "
155 "reset status %d\n", channel->center_freq, ret); 158 "reset status %d\n", channel->center_freq, ret);
156 ath9k_htc_ps_restore(priv);
157 goto err; 159 goto err;
158 } 160 }
159 161
@@ -1097,7 +1099,7 @@ fail_tx:
1097 return 0; 1099 return 0;
1098} 1100}
1099 1101
1100static int ath9k_htc_start(struct ieee80211_hw *hw) 1102static int ath9k_htc_radio_enable(struct ieee80211_hw *hw)
1101{ 1103{
1102 struct ath9k_htc_priv *priv = hw->priv; 1104 struct ath9k_htc_priv *priv = hw->priv;
1103 struct ath_hw *ah = priv->ah; 1105 struct ath_hw *ah = priv->ah;
@@ -1113,8 +1115,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
1113 "Starting driver with initial channel: %d MHz\n", 1115 "Starting driver with initial channel: %d MHz\n",
1114 curchan->center_freq); 1116 curchan->center_freq);
1115 1117
1116 mutex_lock(&priv->mutex);
1117
1118 /* setup initial channel */ 1118 /* setup initial channel */
1119 init_channel = ath9k_cmn_get_curchannel(hw, ah); 1119 init_channel = ath9k_cmn_get_curchannel(hw, ah);
1120 1120
@@ -1127,7 +1127,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
1127 ath_print(common, ATH_DBG_FATAL, 1127 ath_print(common, ATH_DBG_FATAL,
1128 "Unable to reset hardware; reset status %d " 1128 "Unable to reset hardware; reset status %d "
1129 "(freq %u MHz)\n", ret, curchan->center_freq); 1129 "(freq %u MHz)\n", ret, curchan->center_freq);
1130 goto mutex_unlock; 1130 return ret;
1131 } 1131 }
1132 1132
1133 ath_update_txpow(priv); 1133 ath_update_txpow(priv);
@@ -1135,16 +1135,8 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
1135 mode = ath9k_htc_get_curmode(priv, init_channel); 1135 mode = ath9k_htc_get_curmode(priv, init_channel);
1136 htc_mode = cpu_to_be16(mode); 1136 htc_mode = cpu_to_be16(mode);
1137 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode); 1137 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
1138 if (ret)
1139 goto mutex_unlock;
1140
1141 WMI_CMD(WMI_ATH_INIT_CMDID); 1138 WMI_CMD(WMI_ATH_INIT_CMDID);
1142 if (ret)
1143 goto mutex_unlock;
1144
1145 WMI_CMD(WMI_START_RECV_CMDID); 1139 WMI_CMD(WMI_START_RECV_CMDID);
1146 if (ret)
1147 goto mutex_unlock;
1148 1140
1149 ath9k_host_rx_init(priv); 1141 ath9k_host_rx_init(priv);
1150 1142
@@ -1157,12 +1149,22 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
1157 1149
1158 ieee80211_wake_queues(hw); 1150 ieee80211_wake_queues(hw);
1159 1151
1160mutex_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);
1161 mutex_unlock(&priv->mutex); 1162 mutex_unlock(&priv->mutex);
1163
1162 return ret; 1164 return ret;
1163} 1165}
1164 1166
1165static void ath9k_htc_stop(struct ieee80211_hw *hw) 1167static void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
1166{ 1168{
1167 struct ath9k_htc_priv *priv = hw->priv; 1169 struct ath9k_htc_priv *priv = hw->priv;
1168 struct ath_hw *ah = priv->ah; 1170 struct ath_hw *ah = priv->ah;
@@ -1170,14 +1172,18 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1170 int ret = 0; 1172 int ret = 0;
1171 u8 cmd_rsp; 1173 u8 cmd_rsp;
1172 1174
1173 mutex_lock(&priv->mutex);
1174
1175 if (priv->op_flags & OP_INVALID) { 1175 if (priv->op_flags & OP_INVALID) {
1176 ath_print(common, ATH_DBG_ANY, "Device not present\n"); 1176 ath_print(common, ATH_DBG_ANY, "Device not present\n");
1177 mutex_unlock(&priv->mutex);
1178 return; 1177 return;
1179 } 1178 }
1180 1179
1180 /* Cancel all the running timers/work .. */
1181 cancel_work_sync(&priv->ps_work);
1182 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1183 cancel_delayed_work_sync(&priv->ath9k_aggr_work);
1184 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1185 ath9k_led_stop_brightness(priv);
1186
1181 ath9k_htc_ps_wakeup(priv); 1187 ath9k_htc_ps_wakeup(priv);
1182 htc_stop(priv->htc); 1188 htc_stop(priv->htc);
1183 WMI_CMD(WMI_DISABLE_INTR_CMDID); 1189 WMI_CMD(WMI_DISABLE_INTR_CMDID);
@@ -1189,11 +1195,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1189 ath9k_htc_ps_restore(priv); 1195 ath9k_htc_ps_restore(priv);
1190 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); 1196 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1191 1197
1192 cancel_work_sync(&priv->ps_work);
1193 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1194 cancel_delayed_work_sync(&priv->ath9k_aggr_work);
1195 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1196 ath9k_led_stop_brightness(priv);
1197 skb_queue_purge(&priv->tx_queue); 1198 skb_queue_purge(&priv->tx_queue);
1198 1199
1199 /* Remove monitor interface here */ 1200 /* Remove monitor interface here */
@@ -1207,11 +1208,20 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1207 } 1208 }
1208 1209
1209 priv->op_flags |= OP_INVALID; 1210 priv->op_flags |= OP_INVALID;
1210 mutex_unlock(&priv->mutex);
1211 1211
1212 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); 1212 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
1213} 1213}
1214 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
1215static int ath9k_htc_add_interface(struct ieee80211_hw *hw, 1225static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1216 struct ieee80211_vif *vif) 1226 struct ieee80211_vif *vif)
1217{ 1227{
@@ -1325,6 +1335,23 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1325 1335
1326 mutex_lock(&priv->mutex); 1336 mutex_lock(&priv->mutex);
1327 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
1328 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 1355 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1329 struct ieee80211_channel *curchan = hw->conf.channel; 1356 struct ieee80211_channel *curchan = hw->conf.channel;
1330 int pos = curchan->hw_value; 1357 int pos = curchan->hw_value;
@@ -1368,6 +1395,13 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1368 } 1395 }
1369 } 1396 }
1370 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
1371 mutex_unlock(&priv->mutex); 1405 mutex_unlock(&priv->mutex);
1372 1406
1373 return 0; 1407 return 0;