mac80211: Fix ps-qos network latency handling
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>
Wed, 9 Jun 2010 06:51:52 +0000 (09:51 +0300)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 15 Jun 2010 20:00:48 +0000 (16:00 -0400)
The ps-qos latency handling is broken. It uses predetermined latency values
to select specific dynamic PS timeouts. With common AP configurations, these
values overlap with beacon interval and are therefore essentially useless
(for network latencies less than the beacon interval, PSM is disabled.)

This patch remedies the problem by replacing the predetermined network latency
values with one high value (1900ms) which is used to go trigger full psm. For
backwards compatibility, the value 2000ms is still mapped to a dynamic ps
timeout of 100ms.

Currently also the mac80211 internal value for storing user space configured
dynamic PSM values is incorrectly in the driver visible ieee80211_conf struct.
Move it to the ieee80211_local struct.

Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/net/mac80211.h
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/main.c
net/mac80211/mlme.c

index 3a47877f4965993bff651bc5724a4b45c103ec9c..fe1a3a603375a50c89cf35e57d6bd9fe2a2bbf56 100644 (file)
@@ -695,9 +695,6 @@ enum ieee80211_smps_mode {
  * @dynamic_ps_timeout: The dynamic powersave timeout (in ms), see the
  *     powersave documentation below. This variable is valid only when
  *     the CONF_PS flag is set.
- * @dynamic_ps_forced_timeout: The dynamic powersave timeout (in ms) configured
- *     by cfg80211 (essentially, wext) If set, this value overrules the value
- *     chosen by mac80211 based on ps qos network latency.
  *
  * @power_level: requested transmit power (in dBm)
  *
@@ -717,7 +714,7 @@ enum ieee80211_smps_mode {
  */
 struct ieee80211_conf {
        u32 flags;
-       int power_level, dynamic_ps_timeout, dynamic_ps_forced_timeout;
+       int power_level, dynamic_ps_timeout;
        int max_sleep_period;
 
        u16 listen_interval;
index 59f597d0c6a05fa9262db9538c6a9afa583c25cd..003b6addf5facbdc0ae0f314170d562b046b2058 100644 (file)
@@ -1446,7 +1446,6 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_conf *conf = &local->hw.conf;
 
        if (sdata->vif.type != NL80211_IFTYPE_STATION)
                return -EOPNOTSUPP;
@@ -1455,11 +1454,11 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
                return -EOPNOTSUPP;
 
        if (enabled == sdata->u.mgd.powersave &&
-           timeout == conf->dynamic_ps_forced_timeout)
+           timeout == local->dynamic_ps_forced_timeout)
                return 0;
 
        sdata->u.mgd.powersave = enabled;
-       conf->dynamic_ps_forced_timeout = timeout;
+       local->dynamic_ps_forced_timeout = timeout;
 
        /* no change, but if automatic follow powersave */
        mutex_lock(&sdata->u.mgd.mtx);
index 9b3c3f971d280d970e7005c7e7c671a8efe3f0f4..fb5430188e8707d881996604b80cb51cca0c1701 100644 (file)
@@ -850,6 +850,12 @@ struct ieee80211_local {
        struct notifier_block network_latency_notifier;
        struct notifier_block ifa_notifier;
 
+       /*
+        * The dynamic ps timeout configured from user space via WEXT -
+        * this will override whatever chosen by mac80211 internally.
+        */
+       int dynamic_ps_forced_timeout;
+
        int user_power_level; /* in dBm */
        int power_constr_level; /* in dBm */
 
index a1bf46c64b936d0ec304676d518cd20ec87f64a8..edf7aff93268ad18670f90f9d59cca54eae1ce3a 100644 (file)
@@ -630,7 +630,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 
        local->hw.conf.listen_interval = local->hw.max_listen_interval;
 
-       local->hw.conf.dynamic_ps_forced_timeout = -1;
+       local->dynamic_ps_forced_timeout = -1;
 
        result = sta_info_start(local);
        if (result < 0)
index 74479c2d12d4ca753677f390ed89552453e6dd42..1c0d8fce08ddccfed3b055e6aa18c428a5dc3231 100644 (file)
@@ -561,23 +561,19 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
                beaconint_us = ieee80211_tu_to_usec(
                                        found->vif.bss_conf.beacon_int);
 
-               timeout = local->hw.conf.dynamic_ps_forced_timeout;
+               timeout = local->dynamic_ps_forced_timeout;
                if (timeout < 0) {
                        /*
+                        * Go to full PSM if the user configures a very low
+                        * latency requirement.
                         * The 2 second value is there for compatibility until
                         * the PM_QOS_NETWORK_LATENCY is configured with real
                         * values.
                         */
-                       if (latency == 2000000000)
-                               timeout = 100;
-                       else if (latency <= 50000)
-                               timeout = 300;
-                       else if (latency <= 100000)
-                               timeout = 100;
-                       else if (latency <= 500000)
-                               timeout = 50;
-                       else
+                       if (latency > 1900000000 && latency != 2000000000)
                                timeout = 0;
+                       else
+                               timeout = 100;
                }
                local->hw.conf.dynamic_ps_timeout = timeout;