提交 8a8572a8 编写于 作者: V Vivek Natarajan 提交者: John W. Linville

ath9k_htc: Handle CONF_IDLE during unassociated state to save power.

Signed-off-by: NVivek Natarajan <vnatarajan@atheros.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 7b7b5e56
...@@ -379,6 +379,7 @@ struct ath9k_htc_priv { ...@@ -379,6 +379,7 @@ struct ath9k_htc_priv {
struct mutex htc_pm_lock; struct mutex htc_pm_lock;
unsigned long ps_usecount; unsigned long ps_usecount;
bool ps_enabled; bool ps_enabled;
bool ps_idle;
struct ath_led radio_led; struct ath_led radio_led;
struct ath_led assoc_led; struct ath_led assoc_led;
......
...@@ -94,8 +94,11 @@ void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv) ...@@ -94,8 +94,11 @@ void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv)
if (--priv->ps_usecount != 0) if (--priv->ps_usecount != 0)
goto unlock; goto unlock;
if (priv->ps_enabled) if (priv->ps_idle)
ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP);
else if (priv->ps_enabled)
ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP); ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP);
unlock: unlock:
mutex_unlock(&priv->htc_pm_lock); mutex_unlock(&priv->htc_pm_lock);
} }
...@@ -1096,7 +1099,7 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1096,7 +1099,7 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return 0; return 0;
} }
static int ath9k_htc_start(struct ieee80211_hw *hw) static int ath9k_htc_radio_enable(struct ieee80211_hw *hw)
{ {
struct ath9k_htc_priv *priv = hw->priv; struct ath9k_htc_priv *priv = hw->priv;
struct ath_hw *ah = priv->ah; struct ath_hw *ah = priv->ah;
...@@ -1112,8 +1115,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) ...@@ -1112,8 +1115,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
"Starting driver with initial channel: %d MHz\n", "Starting driver with initial channel: %d MHz\n",
curchan->center_freq); curchan->center_freq);
mutex_lock(&priv->mutex);
/* setup initial channel */ /* setup initial channel */
init_channel = ath9k_cmn_get_curchannel(hw, ah); init_channel = ath9k_cmn_get_curchannel(hw, ah);
...@@ -1126,7 +1127,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) ...@@ -1126,7 +1127,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
ath_print(common, ATH_DBG_FATAL, ath_print(common, ATH_DBG_FATAL,
"Unable to reset hardware; reset status %d " "Unable to reset hardware; reset status %d "
"(freq %u MHz)\n", ret, curchan->center_freq); "(freq %u MHz)\n", ret, curchan->center_freq);
goto mutex_unlock; return ret;
} }
ath_update_txpow(priv); ath_update_txpow(priv);
...@@ -1134,16 +1135,8 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) ...@@ -1134,16 +1135,8 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
mode = ath9k_htc_get_curmode(priv, init_channel); mode = ath9k_htc_get_curmode(priv, init_channel);
htc_mode = cpu_to_be16(mode); htc_mode = cpu_to_be16(mode);
WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode); WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
if (ret)
goto mutex_unlock;
WMI_CMD(WMI_ATH_INIT_CMDID); WMI_CMD(WMI_ATH_INIT_CMDID);
if (ret)
goto mutex_unlock;
WMI_CMD(WMI_START_RECV_CMDID); WMI_CMD(WMI_START_RECV_CMDID);
if (ret)
goto mutex_unlock;
ath9k_host_rx_init(priv); ath9k_host_rx_init(priv);
...@@ -1156,12 +1149,22 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) ...@@ -1156,12 +1149,22 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
ieee80211_wake_queues(hw); ieee80211_wake_queues(hw);
mutex_unlock: return ret;
}
static int ath9k_htc_start(struct ieee80211_hw *hw)
{
struct ath9k_htc_priv *priv = hw->priv;
int ret = 0;
mutex_lock(&priv->mutex);
ret = ath9k_htc_radio_enable(hw);
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
return ret; return ret;
} }
static void ath9k_htc_stop(struct ieee80211_hw *hw) static void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
{ {
struct ath9k_htc_priv *priv = hw->priv; struct ath9k_htc_priv *priv = hw->priv;
struct ath_hw *ah = priv->ah; struct ath_hw *ah = priv->ah;
...@@ -1169,11 +1172,8 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) ...@@ -1169,11 +1172,8 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
int ret = 0; int ret = 0;
u8 cmd_rsp; u8 cmd_rsp;
mutex_lock(&priv->mutex);
if (priv->op_flags & OP_INVALID) { if (priv->op_flags & OP_INVALID) {
ath_print(common, ATH_DBG_ANY, "Device not present\n"); ath_print(common, ATH_DBG_ANY, "Device not present\n");
mutex_unlock(&priv->mutex);
return; return;
} }
...@@ -1208,11 +1208,20 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) ...@@ -1208,11 +1208,20 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
} }
priv->op_flags |= OP_INVALID; priv->op_flags |= OP_INVALID;
mutex_unlock(&priv->mutex);
ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
} }
static void ath9k_htc_stop(struct ieee80211_hw *hw)
{
struct ath9k_htc_priv *priv = hw->priv;
mutex_lock(&priv->mutex);
ath9k_htc_radio_disable(hw);
mutex_unlock(&priv->mutex);
}
static int ath9k_htc_add_interface(struct ieee80211_hw *hw, static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
...@@ -1326,6 +1335,23 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) ...@@ -1326,6 +1335,23 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
if (changed & IEEE80211_CONF_CHANGE_IDLE) {
bool enable_radio = false;
bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
if (!idle && priv->ps_idle)
enable_radio = true;
priv->ps_idle = idle;
if (enable_radio) {
ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
ath9k_htc_radio_enable(hw);
ath_print(common, ATH_DBG_CONFIG,
"not-idle: enabling radio\n");
}
}
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
struct ieee80211_channel *curchan = hw->conf.channel; struct ieee80211_channel *curchan = hw->conf.channel;
int pos = curchan->hw_value; int pos = curchan->hw_value;
...@@ -1369,6 +1395,13 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) ...@@ -1369,6 +1395,13 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
} }
} }
if (priv->ps_idle) {
ath_print(common, ATH_DBG_CONFIG,
"idle: disabling radio\n");
ath9k_htc_radio_disable(hw);
}
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册