[rt2x00-users] [PATCH] rt2x00: Implement set_tim callback for rt73usb (non-working, RFC)

Stefan Steuerwald salsasepp at googlemail.com
Wed Jul 8 19:23:18 EST 2009


Reference: http://rt2x00.serialmonkey.com/phpBB/viewtopic.php?f=5&t=5486&start=0

Ivo, thank you for your pointers, not sure I understand your comment
about the update_beacon callback.

I have hacked something that shows the right sequence of things in
debug output. We see the set_tim(set=true) callback, followed by
set_tim(set=false) after the station wakes up (woken by other means
than TIM in this case):

[  297.543056] wlan0: STA 00:13:e8:f8:7b:b5 aid 1 enters power save mode
[  297.603252] STA 00:13:e8:f8:7b:b5 aid 1: PS buffer (entries before 0)
[  297.603263] rt73usb_set_tim (set=1)
[  297.603659] STA 00:13:e8:f8:7b:b5 aid 1: PS buffer (entries before 1)
[  297.724799] rt73usb_set_tim (set=0)
[  297.725040] wlan0: STA 00:13:e8:f8:7b:b5 aid 1 exits power save mode
[  297.725050] wlan0: STA 00:13:e8:f8:7b:b5 aid 1 sending 0 filtered/2
PS frames since STA not sleeping anymore

However, it "schedules while atomic", when calling
rt73usb_write_beacon(). Blatantly bad.
How would I do this correctly (I am clueless about kernel locking things)?

Thank you,
  Stefan.

---

diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c
b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 44e5b32..12d3b9a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -537,6 +537,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,

 	return 0;
 }
+EXPORT_SYMBOL_GPL(rt2x00queue_update_beacon);

 struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
 					 const enum data_queue_qid queue)
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c
b/drivers/net/wireless/rt2x00/rt73usb.c
index c188488..87672f6 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -34,6 +34,7 @@

 #include "rt2x00.h"
 #include "rt2x00usb.h"
+#include "rt2x00lib.h"
 #include "rt73usb.h"

 /*
@@ -2168,6 +2169,31 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 /*
  * IEEE80211 stack callback functions.
  */
+
+/* this needs to be moved to rt2x00lib */
+static void rt73usb_set_tim_iter(void *data, u8 *mac,
+				      struct ieee80211_vif *vif)
+{
+	struct rt2x00_dev *rt2x00dev = data;
+
+	if (vif->type == NL80211_IFTYPE_AP) {
+		printk(KERN_DEBUG "rt73usb updating beacon");
+		rt2x00queue_update_beacon(rt2x00dev, vif, true);
+	}
+}
+
+static int rt73usb_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+		bool set)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+
+	printk(KERN_DEBUG "rt73usb_set_tim (set=%d)", set);
+	ieee80211_iterate_active_interfaces(rt2x00dev->hw,
+			rt73usb_set_tim_iter,
+			rt2x00dev);
+	return 0;
+}
+
 static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
 			   const struct ieee80211_tx_queue_params *params)
 {
@@ -2247,6 +2273,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
 	.remove_interface	= rt2x00mac_remove_interface,
 	.config			= rt2x00mac_config,
 	.configure_filter	= rt2x00mac_configure_filter,
+	.set_tim		= rt73usb_set_tim,
 	.set_key		= rt2x00mac_set_key,
 	.get_stats		= rt2x00mac_get_stats,
 	.bss_info_changed	= rt2x00mac_bss_info_changed,



More information about the users mailing list