rt2x00: Allow beacon update without scheduling a work
Helmut Schaa [Sun, 11 Jul 2010 10:27:26 +0000 (12:27 +0200)]
Since all rt2x00 PCI drivers use threaded interrupts now we don't need
to schedule a work just to update the beacon. The only place where the
beacon still gets updated in atomic context is from the set_tim
callback. Hence, move the work scheduling there.

Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00mac.c

index d3ebb41..e255725 100644 (file)
@@ -181,7 +181,7 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work)
 static void rt2x00lib_beacondone_iter(void *data, u8 *mac,
                                      struct ieee80211_vif *vif)
 {
-       struct rt2x00_intf *intf = vif_to_intf(vif);
+       struct rt2x00_dev *rt2x00dev = data;
 
        if (vif->type != NL80211_IFTYPE_AP &&
            vif->type != NL80211_IFTYPE_ADHOC &&
@@ -189,9 +189,7 @@ static void rt2x00lib_beacondone_iter(void *data, u8 *mac,
            vif->type != NL80211_IFTYPE_WDS)
                return;
 
-       spin_lock(&intf->lock);
-       intf->delayed_flags |= DELAYED_UPDATE_BEACON;
-       spin_unlock(&intf->lock);
+       rt2x00queue_update_beacon(rt2x00dev, vif, true);
 }
 
 void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
@@ -199,11 +197,10 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
        if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
                return;
 
-       ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw,
-                                                  rt2x00lib_beacondone_iter,
-                                                  rt2x00dev);
+       ieee80211_iterate_active_interfaces(rt2x00dev->hw,
+                                          rt2x00lib_beacondone_iter,
+                                          rt2x00dev);
 
-       ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
 
index bbce496..4d8d232 100644 (file)
@@ -433,12 +433,36 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
 
+static void rt2x00mac_set_tim_iter(void *data, u8 *mac,
+                                  struct ieee80211_vif *vif)
+{
+       struct rt2x00_intf *intf = vif_to_intf(vif);
+
+       if (vif->type != NL80211_IFTYPE_AP &&
+           vif->type != NL80211_IFTYPE_ADHOC &&
+           vif->type != NL80211_IFTYPE_MESH_POINT &&
+           vif->type != NL80211_IFTYPE_WDS)
+               return;
+
+       spin_lock(&intf->lock);
+       intf->delayed_flags |= DELAYED_UPDATE_BEACON;
+       spin_unlock(&intf->lock);
+}
+
 int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
                      bool set)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
 
-       rt2x00lib_beacondone(rt2x00dev);
+       if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+               return 0;
+
+       ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw,
+                                                  rt2x00mac_set_tim_iter,
+                                                  rt2x00dev);
+
+       /* queue work to upodate the beacon template */
+       ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work);
        return 0;
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_set_tim);