Search Linux Wireless

issue with ath9k_htc and mesh mode powersave

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux