[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