return -1;
 }
 
+/**
+ * ieee80211_tu_to_usec - convert time units (TU) to microseconds
+ * @tu: the TUs
+ */
+static inline unsigned long ieee80211_tu_to_usec(unsigned long tu)
+{
+       return 1024 * tu;
+}
+
 #endif /* LINUX_IEEE80211_H */
 
        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;
 
        int user_power_level; /* in dBm */
        int power_constr_level; /* in dBm */
 int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason);
 void ieee80211_send_pspoll(struct ieee80211_local *local,
                           struct ieee80211_sub_if_data *sdata);
-void ieee80211_recalc_ps(struct ieee80211_local *local);
+void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency);
+int ieee80211_max_network_latency(struct notifier_block *nb,
+                                 unsigned long data, void *dummy);
 
 /* IBSS code */
 int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata);
 
                ieee80211_set_wmm_default(sdata);
        }
 
-       ieee80211_recalc_ps(local);
+       ieee80211_recalc_ps(local, -1);
 
        /*
         * ieee80211_sta_work is disabled while network interface
                hw_reconf_flags = 0;
        }
 
-       ieee80211_recalc_ps(local);
+       ieee80211_recalc_ps(local, -1);
 
        /* do after stop to avoid reconfiguring when we stop anyway */
        if (hw_reconf_flags)
 
 #include <linux/wireless.h>
 #include <linux/rtnetlink.h>
 #include <linux/bitmap.h>
+#include <linux/pm_qos_params.h>
 #include <net/net_namespace.h>
 #include <net/cfg80211.h>
 
                }
        }
 
+       local->network_latency_notifier.notifier_call =
+               ieee80211_max_network_latency;
+       result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY,
+                                    &local->network_latency_notifier);
+
+       if (result) {
+               rtnl_lock();
+               goto fail_pm_qos;
+       }
+
        return 0;
 
-fail_wep:
+ fail_pm_qos:
+       ieee80211_led_exit(local);
+       ieee80211_remove_interfaces(local);
+ fail_wep:
        rate_control_deinitialize(local);
-fail_rate:
+ fail_rate:
        unregister_netdevice(local->mdev);
        local->mdev = NULL;
-fail_dev:
+ fail_dev:
        rtnl_unlock();
        sta_info_stop(local);
-fail_sta_info:
+ fail_sta_info:
        debugfs_hw_del(local);
        destroy_workqueue(local->hw.workqueue);
-fail_workqueue:
+ fail_workqueue:
        if (local->mdev)
                free_netdev(local->mdev);
-fail_mdev_alloc:
+ fail_mdev_alloc:
        wiphy_unregister(local->hw.wiphy);
-fail_wiphy_register:
+ fail_wiphy_register:
        kfree(local->int_scan_req.channels);
        return result;
 }
        tasklet_kill(&local->tx_pending_tasklet);
        tasklet_kill(&local->tasklet);
 
+       pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
+                              &local->network_latency_notifier);
+
        rtnl_lock();
 
        /*
 
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
+#include <linux/pm_qos_params.h>
 #include <net/mac80211.h>
 #include <asm/unaligned.h>
 
 }
 
 /* need to hold RTNL or interface lock */
-void ieee80211_recalc_ps(struct ieee80211_local *local)
+void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
 {
        struct ieee80211_sub_if_data *sdata, *found = NULL;
        int count = 0;
                count++;
        }
 
-       if (count == 1 && found->u.mgd.powersave)
-               local->ps_sdata = found;
-       else
+       if (count == 1 && found->u.mgd.powersave) {
+               s32 beaconint_us;
+
+               if (latency < 0)
+                       latency = pm_qos_requirement(PM_QOS_NETWORK_LATENCY);
+
+               beaconint_us = ieee80211_tu_to_usec(
+                                       found->vif.bss_conf.beacon_int);
+
+               if (beaconint_us > latency)
+                       local->ps_sdata = NULL;
+               else
+                       local->ps_sdata = found;
+       } else {
                local->ps_sdata = NULL;
+       }
 
        ieee80211_change_ps(local);
 }
                ieee80211_restart_sta_timer(sdata);
        rcu_read_unlock();
 }
+
+int ieee80211_max_network_latency(struct notifier_block *nb,
+                                 unsigned long data, void *dummy)
+{
+       s32 latency_usec = (s32) data;
+       struct ieee80211_local *local =
+               container_of(nb, struct ieee80211_local,
+                            network_latency_notifier);
+
+       mutex_lock(&local->iflist_mtx);
+       ieee80211_recalc_ps(local, latency_usec);
+       mutex_unlock(&local->iflist_mtx);
+
+       return 0;
+}
 
                ieee80211_hw_config(local,
                                    IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT);
 
-       ieee80211_recalc_ps(local);
+       ieee80211_recalc_ps(local, -1);
 
        return 0;
 }