2010-04-27 07:35:50

by Vivek Natarajan

[permalink] [raw]
Subject: [PATCH 1/2] ath9k_htc: Handle CONF_IDLE during unassociated state to save power.

Signed-off-by: Vivek Natarajan <[email protected]>
---
drivers/net/wireless/ath/ath9k/htc.h | 1 +
drivers/net/wireless/ath/ath9k/htc_drv_main.c | 71 ++++++++++++++++++-------
2 files changed, 53 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index b771e20..1ae18bb 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -379,6 +379,7 @@ struct ath9k_htc_priv {
struct mutex htc_pm_lock;
unsigned long ps_usecount;
bool ps_enabled;
+ bool ps_idle;

struct ath_led radio_led;
struct ath_led assoc_led;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 9c9f3e0..26d5f22 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)
if (--priv->ps_usecount != 0)
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);
+
unlock:
mutex_unlock(&priv->htc_pm_lock);
}
@@ -1097,7 +1100,7 @@ fail_tx:
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 ath_hw *ah = priv->ah;
@@ -1113,8 +1116,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
"Starting driver with initial channel: %d MHz\n",
curchan->center_freq);

- mutex_lock(&priv->mutex);
-
/* setup initial channel */
init_channel = ath9k_cmn_get_curchannel(hw, ah);

@@ -1127,7 +1128,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
ath_print(common, ATH_DBG_FATAL,
"Unable to reset hardware; reset status %d "
"(freq %u MHz)\n", ret, curchan->center_freq);
- goto mutex_unlock;
+ return ret;
}

ath_update_txpow(priv);
@@ -1135,16 +1136,8 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
mode = ath9k_htc_get_curmode(priv, init_channel);
htc_mode = cpu_to_be16(mode);
WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
- if (ret)
- goto mutex_unlock;
-
WMI_CMD(WMI_ATH_INIT_CMDID);
- if (ret)
- goto mutex_unlock;
-
WMI_CMD(WMI_START_RECV_CMDID);
- if (ret)
- goto mutex_unlock;

ath9k_host_rx_init(priv);

@@ -1157,12 +1150,22 @@ static int ath9k_htc_start(struct ieee80211_hw *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);
+
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 ath_hw *ah = priv->ah;
@@ -1170,11 +1173,8 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
int ret = 0;
u8 cmd_rsp;

- mutex_lock(&priv->mutex);
-
if (priv->op_flags & OP_INVALID) {
ath_print(common, ATH_DBG_ANY, "Device not present\n");
- mutex_unlock(&priv->mutex);
return;
}

@@ -1209,11 +1209,20 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
}

priv->op_flags |= OP_INVALID;
- mutex_unlock(&priv->mutex);

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,
struct ieee80211_vif *vif)
{
@@ -1327,6 +1336,23 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)

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) {
struct ieee80211_channel *curchan = hw->conf.channel;
int pos = curchan->hw_value;
@@ -1370,6 +1396,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);

return 0;
--
1.7.0.5



2010-04-27 07:35:59

by Vivek Natarajan

[permalink] [raw]
Subject: [PATCH 2/2] ath9k: Avoid corrupt frames being forwarded to mac80211.

If bit 29 is set, MAC H/W can attempt to decrypt the received aggregate
with WEP or TKIP, eventhough the received frame may be a CRC failed
corrupted frame. If this bit is set, H/W obeys key type in keycache.
If it is not set and if the key type in keycache is neither open nor
AES, H/W forces key type to be open. But bit 29 should be set to 1
for AsyncFIFO feature to encrypt/decrypt the aggregate with WEP or TKIP.

Cc: [email protected]
Reported-by: Johan Hovold <[email protected]>
Signed-off-by: Vivek Natarajan <[email protected]>
Signed-off-by: Ranga Rao Ravuri <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar5008_initvals.h | 2 +-
drivers/net/wireless/ath/ath9k/ar9002_initvals.h | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h
index cd953f6..025c31a 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h
@@ -249,7 +249,7 @@ static const u32 ar5416Common[][2] = {
{ 0x00008258, 0x00000000 },
{ 0x0000825c, 0x400000ff },
{ 0x00008260, 0x00080922 },
- { 0x00008264, 0xa8000010 },
+ { 0x00008264, 0x88000010 },
{ 0x00008270, 0x00000000 },
{ 0x00008274, 0x40000000 },
{ 0x00008278, 0x003e4180 },
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
index f06313d..dae7f33 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
@@ -793,7 +793,7 @@ static const u32 ar9280Common_9280_2[][2] = {
{ 0x00008258, 0x00000000 },
{ 0x0000825c, 0x400000ff },
{ 0x00008260, 0x00080922 },
- { 0x00008264, 0xa8a00010 },
+ { 0x00008264, 0x88a00010 },
{ 0x00008270, 0x00000000 },
{ 0x00008274, 0x40000000 },
{ 0x00008278, 0x003e4180 },
@@ -1963,7 +1963,7 @@ static const u32 ar9285Common_9285[][2] = {
{ 0x00008258, 0x00000000 },
{ 0x0000825c, 0x400000ff },
{ 0x00008260, 0x00080922 },
- { 0x00008264, 0xa8a00010 },
+ { 0x00008264, 0x88a00010 },
{ 0x00008270, 0x00000000 },
{ 0x00008274, 0x40000000 },
{ 0x00008278, 0x003e4180 },
@@ -3185,7 +3185,7 @@ static const u32 ar9287Common_9287_1_0[][2] = {
{ 0x00008258, 0x00000000 },
{ 0x0000825c, 0x400000ff },
{ 0x00008260, 0x00080922 },
- { 0x00008264, 0xa8a00010 },
+ { 0x00008264, 0x88a00010 },
{ 0x00008270, 0x00000000 },
{ 0x00008274, 0x40000000 },
{ 0x00008278, 0x003e4180 },
@@ -4973,7 +4973,7 @@ static const u32 ar9271Common_9271[][2] = {
{ 0x00008258, 0x00000000 },
{ 0x0000825c, 0x400000ff },
{ 0x00008260, 0x00080922 },
- { 0x00008264, 0xa8a00010 },
+ { 0x00008264, 0x88a00010 },
{ 0x00008270, 0x00000000 },
{ 0x00008274, 0x40000000 },
{ 0x00008278, 0x003e4180 },
--
1.7.0.5


2010-06-03 22:42:29

by Greg KH

[permalink] [raw]
Subject: Re: [stable] [PATCH 2/2] ath9k: Avoid corrupt frames being forwarded to mac80211.

On Tue, Apr 27, 2010 at 01:05:38PM +0530, Vivek Natarajan wrote:
> If bit 29 is set, MAC H/W can attempt to decrypt the received aggregate
> with WEP or TKIP, eventhough the received frame may be a CRC failed
> corrupted frame. If this bit is set, H/W obeys key type in keycache.
> If it is not set and if the key type in keycache is neither open nor
> AES, H/W forces key type to be open. But bit 29 should be set to 1
> for AsyncFIFO feature to encrypt/decrypt the aggregate with WEP or TKIP.
>
> Cc: [email protected]
> Reported-by: Johan Hovold <[email protected]>
> Signed-off-by: Vivek Natarajan <[email protected]>
> Signed-off-by: Ranga Rao Ravuri <[email protected]>
> ---
> drivers/net/wireless/ath/ath9k/ar5008_initvals.h | 2 +-
> drivers/net/wireless/ath/ath9k/ar9002_initvals.h | 8 ++++----

This is now upstream in Linus's tree, but does not apply to the .32,
.32, or .34 kernel trees due to the file movements in this area. I
tried to apply this by hand, but didn't get it correct.

Can someone please send me a properly backported version of this patch
to apply to the -stable tree?

thanks,

greg k-h

2010-06-03 22:52:53

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [stable] [PATCH 2/2] ath9k: Avoid corrupt frames being forwarded to mac80211.

On Thu, Jun 3, 2010 at 3:17 PM, Greg KH <[email protected]> wrote:
> On Tue, Apr 27, 2010 at 01:05:38PM +0530, Vivek Natarajan wrote:
>> If bit 29 is set, MAC H/W can attempt to decrypt the received aggregate
>> with WEP or TKIP, eventhough the received frame may be a CRC failed
>> corrupted frame. If this bit is set, H/W obeys key type in keycache.
>> If it is not set and if the key type in keycache is neither open nor
>> AES, H/W forces key type to be open.  But bit 29 should be set to 1
>> for AsyncFIFO feature to encrypt/decrypt the aggregate with WEP or TKIP.
>>
>> Cc: [email protected]
>> Reported-by: Johan Hovold <[email protected]>
>> Signed-off-by: Vivek Natarajan <[email protected]>
>> Signed-off-by: Ranga Rao Ravuri <[email protected]>
>> ---
>>  drivers/net/wireless/ath/ath9k/ar5008_initvals.h |    2 +-
>>  drivers/net/wireless/ath/ath9k/ar9002_initvals.h |    8 ++++----
>
> This is now upstream in Linus's tree, but does not apply to the .32,
> .32, or .34 kernel trees due to the file movements in this area.  I
> tried to apply this by hand, but didn't get it correct.
>
> Can someone please send me a properly backported version of this patch
> to apply to the -stable tree?

I've stashed this here for book keeping:

http://wireless.kernel.org/en/developers/stable-pending

Luis