summaryrefslogtreecommitdiff
path: root/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-07-01 23:26:57 +0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 23:01:51 +0400
commitbc92afd92088ab41223383cc6863ab4792533c54 (patch)
treea31d14843f5a63a4a4561bb2ac59e83f4550433c /net/wireless
parentf21293549f60f88c74fcb9944737f11048896dc4 (diff)
downloadlinux-bc92afd92088ab41223383cc6863ab4792533c54.tar.xz
cfg80211: implement iwpower
Just on/off and timeout, and with a hacky cfg80211 method until we figure out what we want, though this is probably sufficient as we want to use pm_qos for wifi everywhere. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/Kconfig16
-rw-r--r--net/wireless/core.c11
-rw-r--r--net/wireless/wext-compat.c60
3 files changed, 86 insertions, 1 deletions
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index 040263118a20..c6031d5b135f 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -26,6 +26,22 @@ config CFG80211_REG_DEBUG
If unsure, say N.
+config CFG80211_DEFAULT_PS
+ bool "enable powersave by default"
+ depends on CFG80211
+ default y
+ help
+ This option enables powersave mode by default.
+
+ If this causes your applications to misbehave you should fix your
+ applications instead -- they need to register their network
+ latency requirement, see Documentation/power/pm_qos_interface.txt.
+
+config CFG80211_DEFAULT_PS_VALUE
+ int
+ default 1 if CFG80211_DEFAULT_PS
+ default 0
+
config CFG80211_DEBUGFS
bool "cfg80211 DebugFS entries"
depends on CFG80211 && DEBUG_FS
diff --git a/net/wireless/core.c b/net/wireless/core.c
index e2f80dd0e4a6..413d291d07d7 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -550,12 +550,21 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
}
wdev->netdev = dev;
wdev->sme_state = CFG80211_SME_IDLE;
+ mutex_unlock(&rdev->devlist_mtx);
#ifdef CONFIG_WIRELESS_EXT
wdev->wext.default_key = -1;
wdev->wext.default_mgmt_key = -1;
wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
+ wdev->wext.ps = CONFIG_CFG80211_DEFAULT_PS_VALUE;
+ wdev->wext.ps_timeout = 500;
+ if (rdev->ops->set_power_mgmt)
+ if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
+ wdev->wext.ps,
+ wdev->wext.ps_timeout)) {
+ /* assume this means it's off */
+ wdev->wext.ps = false;
+ }
#endif
- mutex_unlock(&rdev->devlist_mtx);
break;
case NETDEV_GOING_DOWN:
if (!wdev->ssid_len)
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 02f052fc1808..2e1ab78fb0d7 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -987,3 +987,63 @@ int cfg80211_wext_giwauth(struct net_device *dev,
return -EOPNOTSUPP;
}
EXPORT_SYMBOL_GPL(cfg80211_wext_giwauth);
+
+int cfg80211_wext_siwpower(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *wrq, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+ bool ps = wdev->wext.ps;
+ int timeout = wdev->wext.ps_timeout;
+ int err;
+
+ if (wdev->iftype != NL80211_IFTYPE_STATION)
+ return -EINVAL;
+
+ if (!rdev->ops->set_power_mgmt)
+ return -EOPNOTSUPP;
+
+ if (wrq->disabled) {
+ ps = false;
+ } else {
+ switch (wrq->flags & IW_POWER_MODE) {
+ case IW_POWER_ON: /* If not specified */
+ case IW_POWER_MODE: /* If set all mask */
+ case IW_POWER_ALL_R: /* If explicitely state all */
+ ps = true;
+ break;
+ default: /* Otherwise we ignore */
+ return -EINVAL;
+ }
+
+ if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT))
+ return -EINVAL;
+
+ if (wrq->flags & IW_POWER_TIMEOUT)
+ timeout = wrq->value / 1000;
+ }
+
+ err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, ps, timeout);
+ if (err)
+ return err;
+
+ wdev->wext.ps = ps;
+ wdev->wext.ps_timeout = timeout;
+
+ return 0;
+
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwpower);
+
+int cfg80211_wext_giwpower(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *wrq, char *extra)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ wrq->disabled = !wdev->wext.ps;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);