mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-17 22:05:08 +00:00
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>
This commit is contained in:
parent
7b7b5e56d7
commit
8a8572a821
@ -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)
|
|||||||
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 @@ fail_tx:
|
|||||||
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)
|
|||||||
"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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
ieee80211_wake_queues(hw);
|
ieee80211_wake_queues(hw);
|
||||||
|
|
||||||
mutex_unlock:
|
|
||||||
mutex_unlock(&priv->mutex);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ath9k_htc_stop(struct ieee80211_hw *hw)
|
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);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user