The timers and work structs for dynamic powersave are used only
for managed interfaces, so move them to ieee80211_if_managed and
deal with them only in sections of code specifically dealing with
managed mode interfaces.

Signed-off-by: Seth Forshee <seth.fors...@canonical.com>
---
 net/mac80211/ieee80211_i.h | 11 +++---
 net/mac80211/iface.c       |  3 --
 net/mac80211/main.c        |  7 ----
 net/mac80211/mlme.c        | 89 +++++++++++++++++++++++++++++++---------------
 net/mac80211/offchannel.c  |  6 ++--
 net/mac80211/pm.c          | 17 +++++----
 net/mac80211/rx.c          | 10 +-----
 net/mac80211/status.c      |  4 +--
 net/mac80211/tx.c          |  4 +--
 net/mac80211/util.c        | 11 ++++++
 10 files changed, 94 insertions(+), 68 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ed5bf8b..785d1b8 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -387,10 +387,13 @@ struct ieee80211_if_managed {
        struct timer_list conn_mon_timer;
        struct timer_list bcn_mon_timer;
        struct timer_list chswitch_timer;
+       struct timer_list dynamic_ps_timer;
        struct work_struct monitor_work;
        struct work_struct chswitch_work;
        struct work_struct beacon_connection_loss_work;
        struct work_struct csa_connection_drop_work;
+       struct work_struct dynamic_ps_enable_work;
+       struct work_struct dynamic_ps_disable_work;
 
        unsigned long beacon_timeout;
        unsigned long probe_timeout;
@@ -1188,9 +1191,6 @@ struct ieee80211_local {
         * interface (and monitors) in PS, this then points there.
         */
        struct ieee80211_sub_if_data *ps_sdata;
-       struct work_struct dynamic_ps_enable_work;
-       struct work_struct dynamic_ps_disable_work;
-       struct timer_list dynamic_ps_timer;
        struct notifier_block network_latency_notifier;
        struct notifier_block ifa_notifier;
        struct notifier_block ifa6_notifier;
@@ -1363,6 +1363,7 @@ void ieee80211_send_pspoll(struct ieee80211_local *local,
                           struct ieee80211_sub_if_data *sdata);
 void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency);
 void ieee80211_recalc_ps_vif(struct ieee80211_sub_if_data *sdata);
+void ieee80211_mgd_notify_rx(struct ieee80211_rx_data *rx);
 int ieee80211_max_network_latency(struct notifier_block *nb,
                                  unsigned long data, void *dummy);
 int ieee80211_set_arp_filter(struct ieee80211_sub_if_data *sdata);
@@ -1594,6 +1595,7 @@ static inline int __ieee80211_resume(struct ieee80211_hw 
*hw)
 extern void *mac80211_wiphy_privid; /* for wiphy privid */
 u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
                        enum nl80211_iftype type);
+void ieee80211_notify_rx(struct ieee80211_rx_data *rx);
 int ieee80211_frame_duration(enum ieee80211_band band, size_t len,
                             int rate, int erp, int short_preamble,
                             int shift);
@@ -1654,9 +1656,6 @@ static inline void ieee802_11_parse_elems(const u8 
*start, size_t len,
        ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0);
 }
 
-void ieee80211_dynamic_ps_enable_work(struct work_struct *work);
-void ieee80211_dynamic_ps_disable_work(struct work_struct *work);
-void ieee80211_dynamic_ps_timer(unsigned long data);
 void ieee80211_send_nullfunc(struct ieee80211_local *local,
                             struct ieee80211_sub_if_data *sdata,
                             int powersave);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 7aa9f9d..784b651 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -816,9 +816,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data 
*sdata,
                netif_addr_unlock_bh(sdata->dev);
        }
 
-       del_timer_sync(&local->dynamic_ps_timer);
-       cancel_work_sync(&local->dynamic_ps_enable_work);
-
        cancel_work_sync(&sdata->recalc_smps);
        sdata->vif.csa_active = false;
        cancel_work_sync(&sdata->csa_finalize_work);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index fa34cd2..4ab607c 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -614,13 +614,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t 
priv_data_len,
        INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter);
        local->smps_mode = IEEE80211_SMPS_OFF;
 
-       INIT_WORK(&local->dynamic_ps_enable_work,
-                 ieee80211_dynamic_ps_enable_work);
-       INIT_WORK(&local->dynamic_ps_disable_work,
-                 ieee80211_dynamic_ps_disable_work);
-       setup_timer(&local->dynamic_ps_timer,
-                   ieee80211_dynamic_ps_timer, (unsigned long) local);
-
        INIT_WORK(&local->sched_scan_stopped_work,
                  ieee80211_sched_scan_stopped_work);
 
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 900ead3..4ec8c0a 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1139,6 +1139,7 @@ static void ieee80211_enable_ps(struct ieee80211_local 
*local,
                                struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_conf *conf = &local->hw.conf;
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
        /*
         * If we are scanning right now then the parameters will
@@ -1149,7 +1150,7 @@ static void ieee80211_enable_ps(struct ieee80211_local 
*local,
 
        if (conf->dynamic_ps_timeout > 0 &&
            !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) {
-               mod_timer(&local->dynamic_ps_timer, jiffies +
+               mod_timer(&ifmgd->dynamic_ps_timer, jiffies +
                          msecs_to_jiffies(conf->dynamic_ps_timeout));
        } else {
                if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
@@ -1164,17 +1165,19 @@ static void ieee80211_enable_ps(struct ieee80211_local 
*local,
        }
 }
 
-static void ieee80211_change_ps(struct ieee80211_local *local)
+static void ieee80211_change_ps(struct ieee80211_sub_if_data *sdata, bool 
ps_enable)
 {
+       struct ieee80211_local *local = sdata->local;
        struct ieee80211_conf *conf = &local->hw.conf;
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
-       if (local->ps_sdata) {
-               ieee80211_enable_ps(local, local->ps_sdata);
+       if (ps_enable) {
+               ieee80211_enable_ps(local, sdata);
        } else if (conf->flags & IEEE80211_CONF_PS) {
                conf->flags &= ~IEEE80211_CONF_PS;
                ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
-               del_timer_sync(&local->dynamic_ps_timer);
-               cancel_work_sync(&local->dynamic_ps_enable_work);
+               del_timer_sync(&ifmgd->dynamic_ps_timer);
+               cancel_work_sync(&ifmgd->dynamic_ps_enable_work);
        }
 }
 
@@ -1211,7 +1214,7 @@ static bool ieee80211_powersave_allowed(struct 
ieee80211_sub_if_data *sdata)
 /* need to hold RTNL or interface lock */
 void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
 {
-       struct ieee80211_sub_if_data *sdata, *found = NULL;
+       struct ieee80211_sub_if_data *sdata, *old_ps_sdata, *found = NULL;
        int count = 0;
        int timeout;
 
@@ -1220,6 +1223,8 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, 
s32 latency)
                return;
        }
 
+       old_ps_sdata = local->ps_sdata;
+
        list_for_each_entry(sdata, &local->interfaces, list) {
                if (!ieee80211_sdata_running(sdata))
                        continue;
@@ -1284,7 +1289,10 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, 
s32 latency)
                local->ps_sdata = NULL;
        }
 
-       ieee80211_change_ps(local);
+       if (local->ps_sdata)
+               ieee80211_change_ps(local->ps_sdata, true);
+       else if (old_ps_sdata)
+               ieee80211_change_ps(old_ps_sdata, false);
 }
 
 void ieee80211_recalc_ps_vif(struct ieee80211_sub_if_data *sdata)
@@ -1297,11 +1305,12 @@ void ieee80211_recalc_ps_vif(struct 
ieee80211_sub_if_data *sdata)
        }
 }
 
-void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
+static void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
 {
-       struct ieee80211_local *local =
-               container_of(work, struct ieee80211_local,
-                            dynamic_ps_disable_work);
+       struct ieee80211_sub_if_data *sdata =
+               container_of(work, struct ieee80211_sub_if_data,
+                            u.mgd.dynamic_ps_disable_work);
+       struct ieee80211_local *local = sdata->local;
 
        if (local->hw.conf.flags & IEEE80211_CONF_PS) {
                local->hw.conf.flags &= ~IEEE80211_CONF_PS;
@@ -1313,29 +1322,27 @@ void ieee80211_dynamic_ps_disable_work(struct 
work_struct *work)
                                        IEEE80211_QUEUE_STOP_REASON_PS);
 }
 
-void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
+static void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
 {
-       struct ieee80211_local *local =
-               container_of(work, struct ieee80211_local,
-                            dynamic_ps_enable_work);
-       struct ieee80211_sub_if_data *sdata = local->ps_sdata;
-       struct ieee80211_if_managed *ifmgd;
+       struct ieee80211_sub_if_data *sdata =
+               container_of(work, struct ieee80211_sub_if_data,
+                            u.mgd.dynamic_ps_enable_work);
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        unsigned long flags;
        int q;
 
        /* can only happen when PS was just disabled anyway */
-       if (!sdata)
+       if (!local->ps_sdata)
                return;
 
-       ifmgd = &sdata->u.mgd;
-
        if (local->hw.conf.flags & IEEE80211_CONF_PS)
                return;
 
        if (local->hw.conf.dynamic_ps_timeout > 0) {
                /* don't enter PS if TX frames are pending */
                if (drv_tx_frames_pending(local)) {
-                       mod_timer(&local->dynamic_ps_timer, jiffies +
+                       mod_timer(&ifmgd->dynamic_ps_timer, jiffies +
                                  msecs_to_jiffies(
                                  local->hw.conf.dynamic_ps_timeout));
                        return;
@@ -1351,7 +1358,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct 
*work)
                        if (local->queue_stop_reasons[q]) {
                                
spin_unlock_irqrestore(&local->queue_stop_reason_lock,
                                                       flags);
-                               mod_timer(&local->dynamic_ps_timer, jiffies +
+                               mod_timer(&ifmgd->dynamic_ps_timer, jiffies +
                                          msecs_to_jiffies(
                                          local->hw.conf.dynamic_ps_timeout));
                                return;
@@ -1363,7 +1370,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct 
*work)
        if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
            !(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
                if (drv_tx_frames_pending(local)) {
-                       mod_timer(&local->dynamic_ps_timer, jiffies +
+                       mod_timer(&ifmgd->dynamic_ps_timer, jiffies +
                                  msecs_to_jiffies(
                                  local->hw.conf.dynamic_ps_timeout));
                } else {
@@ -1382,14 +1389,30 @@ void ieee80211_dynamic_ps_enable_work(struct 
work_struct *work)
        }
 }
 
-void ieee80211_dynamic_ps_timer(unsigned long data)
+static void ieee80211_dynamic_ps_timer(unsigned long data)
 {
-       struct ieee80211_local *local = (void *) data;
+       struct ieee80211_sub_if_data *sdata = (void *)data;
+       struct ieee80211_local *local = sdata->local;
 
        if (local->quiescing || local->suspended)
                return;
 
-       ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work);
+       ieee80211_queue_work(&local->hw, &sdata->u.mgd.dynamic_ps_enable_work);
+}
+
+void ieee80211_mgd_notify_rx(struct ieee80211_rx_data *rx)
+{
+       struct ieee80211_sub_if_data *sdata = rx->sdata;
+       struct ieee80211_local *local = rx->local;
+
+       if (local->ps_sdata && local->hw.conf.dynamic_ps_timeout > 0 &&
+           !is_multicast_ether_addr(
+                   ((struct ethhdr *)rx->skb->data)->h_dest) &&
+           (!local->scanning &&
+            !test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))) {
+                       mod_timer(&sdata->u.mgd.dynamic_ps_timer, jiffies +
+                        msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
+       }
 }
 
 void ieee80211_dfs_cac_timer_work(struct work_struct *work)
@@ -1719,8 +1742,8 @@ static void ieee80211_set_disassoc(struct 
ieee80211_sub_if_data *sdata,
 
        sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
 
-       del_timer_sync(&local->dynamic_ps_timer);
-       cancel_work_sync(&local->dynamic_ps_enable_work);
+       del_timer_sync(&ifmgd->dynamic_ps_timer);
+       cancel_work_sync(&ifmgd->dynamic_ps_enable_work);
 
        /* Disable ARP filtering */
        if (sdata->vif.bss_conf.arp_addr_cnt)
@@ -3506,6 +3529,10 @@ void ieee80211_sta_setup_sdata(struct 
ieee80211_sub_if_data *sdata)
        INIT_WORK(&ifmgd->csa_connection_drop_work,
                  ieee80211_csa_connection_drop_work);
        INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_mgd_work);
+       INIT_WORK(&ifmgd->dynamic_ps_enable_work,
+                 ieee80211_dynamic_ps_enable_work);
+       INIT_WORK(&ifmgd->dynamic_ps_disable_work,
+                 ieee80211_dynamic_ps_disable_work);
        setup_timer(&ifmgd->timer, ieee80211_sta_timer,
                    (unsigned long) sdata);
        setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer,
@@ -3514,6 +3541,8 @@ void ieee80211_sta_setup_sdata(struct 
ieee80211_sub_if_data *sdata)
                    (unsigned long) sdata);
        setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer,
                    (unsigned long) sdata);
+       setup_timer(&ifmgd->dynamic_ps_timer, ieee80211_dynamic_ps_timer,
+                   (unsigned long) sdata);
 
        ifmgd->flags = 0;
        ifmgd->powersave = sdata->wdev.ps;
@@ -4361,6 +4390,7 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data 
*sdata)
        cancel_work_sync(&ifmgd->request_smps_work);
        cancel_work_sync(&ifmgd->csa_connection_drop_work);
        cancel_work_sync(&ifmgd->chswitch_work);
+       cancel_work_sync(&ifmgd->dynamic_ps_enable_work);
 
        sdata_lock(sdata);
        if (ifmgd->assoc_data) {
@@ -4371,6 +4401,7 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data 
*sdata)
        if (ifmgd->auth_data)
                ieee80211_destroy_auth_data(sdata, false);
        del_timer_sync(&ifmgd->timer);
+       del_timer_sync(&ifmgd->dynamic_ps_timer);
        sdata_unlock(sdata);
 }
 
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 0c2a294..2049a0a 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -33,11 +33,11 @@ static void ieee80211_offchannel_ps_enable(struct 
ieee80211_sub_if_data *sdata)
 
        /* FIXME: what to do when local->pspolling is true? */
 
-       del_timer_sync(&local->dynamic_ps_timer);
+       del_timer_sync(&ifmgd->dynamic_ps_timer);
        del_timer_sync(&ifmgd->bcn_mon_timer);
        del_timer_sync(&ifmgd->conn_mon_timer);
 
-       cancel_work_sync(&local->dynamic_ps_enable_work);
+       cancel_work_sync(&ifmgd->dynamic_ps_enable_work);
 
        if (local->hw.conf.flags & IEEE80211_CONF_PS) {
                local->offchannel_ps_enabled = true;
@@ -94,7 +94,7 @@ static void ieee80211_offchannel_ps_disable(struct 
ieee80211_sub_if_data *sdata)
                 * the AP that we are awake.
                 */
                ieee80211_send_nullfunc(local, sdata, 0);
-               mod_timer(&local->dynamic_ps_timer, jiffies +
+               mod_timer(&sdata->u.mgd.dynamic_ps_timer, jiffies +
                          msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
        }
 
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 3401262..894c497 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -52,13 +52,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct 
cfg80211_wowlan *wowlan)
        /* Don't try to run timers while suspended. */
        del_timer_sync(&local->sta_cleanup);
 
-        /*
-        * Note that this particular timer doesn't need to be
-        * restarted at resume.
-        */
-       cancel_work_sync(&local->dynamic_ps_enable_work);
-       del_timer_sync(&local->dynamic_ps_timer);
-
        local->wowlan = wowlan && local->open_count;
        if (local->wowlan) {
                int err = drv_suspend(local, wowlan);
@@ -106,6 +99,16 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct 
cfg80211_wowlan *wowlan)
                    sdata->vif.type == NL80211_IFTYPE_MONITOR)
                        continue;
 
+               if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+                       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+                        /*
+                        * Note that this particular timer doesn't need to be
+                        * restarted at resume.
+                        */
+                       cancel_work_sync(&ifmgd->dynamic_ps_enable_work);
+                       del_timer_sync(&ifmgd->dynamic_ps_timer);
+               }
+
                drv_remove_interface(local, sdata);
        }
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 2dfa755..5707566 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2212,7 +2212,6 @@ static ieee80211_rx_result debug_noinline
 ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
 {
        struct ieee80211_sub_if_data *sdata = rx->sdata;
-       struct ieee80211_local *local = rx->local;
        struct net_device *dev = sdata->dev;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
        __le16 fc = hdr->frame_control;
@@ -2258,14 +2257,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
        dev->stats.rx_packets++;
        dev->stats.rx_bytes += rx->skb->len;
 
-       if (local->ps_sdata && local->hw.conf.dynamic_ps_timeout > 0 &&
-           !is_multicast_ether_addr(
-                   ((struct ethhdr *)rx->skb->data)->h_dest) &&
-           (!local->scanning &&
-            !test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))) {
-                       mod_timer(&local->dynamic_ps_timer, jiffies +
-                        msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
-       }
+       ieee80211_notify_rx(rx);
 
        ieee80211_deliver_skb(rx);
 
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 1ee85c4..3298fe9 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -740,8 +740,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct 
sk_buff *skb)
                        local->ps_sdata->u.mgd.flags |=
                                        IEEE80211_STA_NULLFUNC_ACKED;
                } else
-                       mod_timer(&local->dynamic_ps_timer, jiffies +
-                                       msecs_to_jiffies(10));
+                       mod_timer(&local->ps_sdata->u.mgd.dynamic_ps_timer,
+                                 jiffies + msecs_to_jiffies(10));
        }
 
        ieee80211_report_used_skb(local, skb, false);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 6d59e21..0ffc2066 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -253,14 +253,14 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
                                                IEEE80211_QUEUE_STOP_REASON_PS);
                ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
                ieee80211_queue_work(&local->hw,
-                                    &local->dynamic_ps_disable_work);
+                                    &ifmgd->dynamic_ps_disable_work);
        }
 
        /* Don't restart the timer if we're not disassociated */
        if (!ifmgd->associated)
                return TX_CONTINUE;
 
-       mod_timer(&local->dynamic_ps_timer, jiffies +
+       mod_timer(&ifmgd->dynamic_ps_timer, jiffies +
                  msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
 
        return TX_CONTINUE;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 875e172..010cd2c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -95,6 +95,17 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t 
len,
        return NULL;
 }
 
+void ieee80211_notify_rx(struct ieee80211_rx_data *rx)
+{
+       switch(rx->sdata->vif.type) {
+       case NL80211_IFTYPE_MONITOR:
+               ieee80211_mgd_notify_rx(rx);
+               break;
+       default:
+               break;
+       }
+}
+
 void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx)
 {
        struct sk_buff *skb;
-- 
1.8.3.2


_______________________________________________
b43-dev mailing list
b43-dev@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/b43-dev

Reply via email to