issue with ath9k_htc and mesh mode powersave

From: Marco Porsch <hidden>
Date: 2012-11-13 19:55:43

Hi,

my name is Marco Porsch, I am currently implementing mesh mode powersave 
as part of mac80211 and some wireless drivers.

When testing with a ath9k_htc TL-WN721N and monitoring the power 
consumption on the USB cable, I see the following behaviour:

during normal mesh operation in powersave mode the power consumption 
rises to 120mA (~55mA is the usual current in PS mode without activity) 
and stays stuck at that level until ifdown. Mesh leave + join does not 
reset it to normal behaviour. Sometimes it only takes few seconds until 
the power consumption gets stuck; sometimes it works fine for multiple 
minutes.

I have no idea what is the reason for that behaviour.
No obvious debug output is given despite all ath9k debugs enabled. I can 
only suspect the hardware expects some managed-mode only event from the 
access point that we do not have there in mesh mode.
When looking at the NDA firmware I did not see anything related to power 
save mode that could help.

Do you have any idea what could be the reason for that behaviour? Or any 
hints for debugging the issue?


Regards,
Marco



PS:

For testing I use a simplistic "mesh awake window" implementation that 
queues waking up from sleep mode after beacon preparation and sets a 
timer for going to sleep again after the awake window is expired. I 
added a bool in_awake_window that blocks going to NETWORKSLEEP when set. 
The code looks like:
@@ -473,6 +495,14 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv,
  	ath9k_htc_send_buffered(priv, slot);
  	ath9k_htc_send_beacon(priv, slot);

+	/* mesh awake window */
+	if (priv->ah->opmode == NL80211_IFTYPE_MESH_POINT && priv->ps_enabled) {
+		priv->in_awake_window = true;
+		ieee80211_queue_work(priv->hw, &priv->ps_work);
+		mod_timer(&priv->awake_window_timer, jiffies +
+				usecs_to_jiffies(1024 * priv->awake_window) +
+				priv->ah->config.sw_beacon_response_time);
+	}
  }
When the timer expires it calls:
@@ -276,6 +284,14 @@ void ath9k_ps_work(struct work_struct *work)
  	ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
  }

+void ath9k_htc_mesh_awake_window_timer(unsigned long data)
+{
+	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) data;
+
+	priv->in_awake_window = false;
+	ieee80211_queue_work(priv->hw, &priv->ps_work);
+}
+

PPS:

Some further hacking revealed that reading AR_RTC_STATUS before and 
after REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN) shows the 
following

normal behaviour:

[ 301.655141] ath: phy0: AR_RTC_STATUS before: 02
[ 301.661079] ath: phy0: AR_RTC_STATUS after : 04

when being stuck it changes to:

[ 302.677066] ath: phy0: AR_RTC_STATUS before: 02
[ 302.683085] ath: phy0: AR_RTC_STATUS after : 02
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help