aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-07-01 15:26:57 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 15:01:51 -0400
commitbc92afd92088ab41223383cc6863ab4792533c54 (patch)
treea31d14843f5a63a4a4561bb2ac59e83f4550433c /net
parentf21293549f60f88c74fcb9944737f11048896dc4 (diff)
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')
-rw-r--r--net/mac80211/Kconfig16
-rw-r--r--net/mac80211/cfg.c26
-rw-r--r--net/mac80211/mlme.c5
-rw-r--r--net/mac80211/wext.c70
-rw-r--r--net/wireless/Kconfig16
-rw-r--r--net/wireless/core.c11
-rw-r--r--net/wireless/wext-compat.c60
7 files changed, 114 insertions, 90 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index ba2643a43c73..41a32cd919af 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -14,22 +14,6 @@ config MAC80211
14comment "CFG80211 needs to be enabled for MAC80211" 14comment "CFG80211 needs to be enabled for MAC80211"
15 depends on CFG80211=n 15 depends on CFG80211=n
16 16
17config MAC80211_DEFAULT_PS
18 bool "enable powersave by default"
19 depends on MAC80211
20 default y
21 help
22 This option enables powersave mode by default.
23
24 If this causes your applications to misbehave you should fix your
25 applications instead -- they need to register their network
26 latency requirement, see Documentation/power/pm_qos_interface.txt.
27
28config MAC80211_DEFAULT_PS_VALUE
29 int
30 default 1 if MAC80211_DEFAULT_PS
31 default 0
32
33menu "Rate control algorithm selection" 17menu "Rate control algorithm selection"
34 depends on MAC80211 != n 18 depends on MAC80211 != n
35 19
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 03de4024597a..8c7b2cdbeeda 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1388,6 +1388,31 @@ int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len)
1388} 1388}
1389#endif 1389#endif
1390 1390
1391static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1392 bool enabled, int timeout)
1393{
1394 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1395 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1396 struct ieee80211_conf *conf = &local->hw.conf;
1397
1398 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
1399 return -EOPNOTSUPP;
1400
1401 if (enabled == sdata->u.mgd.powersave &&
1402 timeout == conf->dynamic_ps_timeout)
1403 return 0;
1404
1405 sdata->u.mgd.powersave = enabled;
1406 conf->dynamic_ps_timeout = timeout;
1407
1408 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
1409 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
1410
1411 ieee80211_recalc_ps(local, -1);
1412
1413 return 0;
1414}
1415
1391struct cfg80211_ops mac80211_config_ops = { 1416struct cfg80211_ops mac80211_config_ops = {
1392 .add_virtual_intf = ieee80211_add_iface, 1417 .add_virtual_intf = ieee80211_add_iface,
1393 .del_virtual_intf = ieee80211_del_iface, 1418 .del_virtual_intf = ieee80211_del_iface,
@@ -1431,4 +1456,5 @@ struct cfg80211_ops mac80211_config_ops = {
1431 .get_tx_power = ieee80211_get_tx_power, 1456 .get_tx_power = ieee80211_get_tx_power,
1432 .rfkill_poll = ieee80211_rfkill_poll, 1457 .rfkill_poll = ieee80211_rfkill_poll,
1433 CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) 1458 CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
1459 .set_power_mgmt = ieee80211_set_power_mgmt,
1434}; 1460};
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index fbb93a70ddc7..2a7860009f9c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2360,11 +2360,6 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
2360 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED; 2360 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED;
2361 2361
2362 hw_flags = sdata->local->hw.flags; 2362 hw_flags = sdata->local->hw.flags;
2363
2364 if (hw_flags & IEEE80211_HW_SUPPORTS_PS) {
2365 ifmgd->powersave = CONFIG_MAC80211_DEFAULT_PS_VALUE;
2366 sdata->local->hw.conf.dynamic_ps_timeout = 500;
2367 }
2368} 2363}
2369 2364
2370/* configuration hooks */ 2365/* configuration hooks */
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index d4e61dc903e8..f77929802c7a 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -255,72 +255,6 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev,
255 return 0; 255 return 0;
256} 256}
257 257
258static int ieee80211_ioctl_siwpower(struct net_device *dev,
259 struct iw_request_info *info,
260 struct iw_param *wrq,
261 char *extra)
262{
263 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
264 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
265 struct ieee80211_conf *conf = &local->hw.conf;
266 int timeout = 0;
267 bool ps;
268
269 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
270 return -EOPNOTSUPP;
271
272 if (sdata->vif.type != NL80211_IFTYPE_STATION)
273 return -EINVAL;
274
275 if (wrq->disabled) {
276 ps = false;
277 timeout = 0;
278 goto set;
279 }
280
281 switch (wrq->flags & IW_POWER_MODE) {
282 case IW_POWER_ON: /* If not specified */
283 case IW_POWER_MODE: /* If set all mask */
284 case IW_POWER_ALL_R: /* If explicitely state all */
285 ps = true;
286 break;
287 default: /* Otherwise we ignore */
288 return -EINVAL;
289 }
290
291 if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT))
292 return -EINVAL;
293
294 if (wrq->flags & IW_POWER_TIMEOUT)
295 timeout = wrq->value / 1000;
296
297 set:
298 if (ps == sdata->u.mgd.powersave && timeout == conf->dynamic_ps_timeout)
299 return 0;
300
301 sdata->u.mgd.powersave = ps;
302 conf->dynamic_ps_timeout = timeout;
303
304 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
305 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
306
307 ieee80211_recalc_ps(local, -1);
308
309 return 0;
310}
311
312static int ieee80211_ioctl_giwpower(struct net_device *dev,
313 struct iw_request_info *info,
314 union iwreq_data *wrqu,
315 char *extra)
316{
317 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
318
319 wrqu->power.disabled = !sdata->u.mgd.powersave;
320
321 return 0;
322}
323
324/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ 258/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
325static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev) 259static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev)
326{ 260{
@@ -436,8 +370,8 @@ static const iw_handler ieee80211_handler[] =
436 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */ 370 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */
437 (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */ 371 (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */
438 (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */ 372 (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */
439 (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */ 373 (iw_handler) cfg80211_wext_siwpower, /* SIOCSIWPOWER */
440 (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */ 374 (iw_handler) cfg80211_wext_giwpower, /* SIOCGIWPOWER */
441 (iw_handler) NULL, /* -- hole -- */ 375 (iw_handler) NULL, /* -- hole -- */
442 (iw_handler) NULL, /* -- hole -- */ 376 (iw_handler) NULL, /* -- hole -- */
443 (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */ 377 (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */
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
26 26
27 If unsure, say N. 27 If unsure, say N.
28 28
29config CFG80211_DEFAULT_PS
30 bool "enable powersave by default"
31 depends on CFG80211
32 default y
33 help
34 This option enables powersave mode by default.
35
36 If this causes your applications to misbehave you should fix your
37 applications instead -- they need to register their network
38 latency requirement, see Documentation/power/pm_qos_interface.txt.
39
40config CFG80211_DEFAULT_PS_VALUE
41 int
42 default 1 if CFG80211_DEFAULT_PS
43 default 0
44
29config CFG80211_DEBUGFS 45config CFG80211_DEBUGFS
30 bool "cfg80211 DebugFS entries" 46 bool "cfg80211 DebugFS entries"
31 depends on CFG80211 && DEBUG_FS 47 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,
550 } 550 }
551 wdev->netdev = dev; 551 wdev->netdev = dev;
552 wdev->sme_state = CFG80211_SME_IDLE; 552 wdev->sme_state = CFG80211_SME_IDLE;
553 mutex_unlock(&rdev->devlist_mtx);
553#ifdef CONFIG_WIRELESS_EXT 554#ifdef CONFIG_WIRELESS_EXT
554 wdev->wext.default_key = -1; 555 wdev->wext.default_key = -1;
555 wdev->wext.default_mgmt_key = -1; 556 wdev->wext.default_mgmt_key = -1;
556 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; 557 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
558 wdev->wext.ps = CONFIG_CFG80211_DEFAULT_PS_VALUE;
559 wdev->wext.ps_timeout = 500;
560 if (rdev->ops->set_power_mgmt)
561 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
562 wdev->wext.ps,
563 wdev->wext.ps_timeout)) {
564 /* assume this means it's off */
565 wdev->wext.ps = false;
566 }
557#endif 567#endif
558 mutex_unlock(&rdev->devlist_mtx);
559 break; 568 break;
560 case NETDEV_GOING_DOWN: 569 case NETDEV_GOING_DOWN:
561 if (!wdev->ssid_len) 570 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,
987 return -EOPNOTSUPP; 987 return -EOPNOTSUPP;
988} 988}
989EXPORT_SYMBOL_GPL(cfg80211_wext_giwauth); 989EXPORT_SYMBOL_GPL(cfg80211_wext_giwauth);
990
991int cfg80211_wext_siwpower(struct net_device *dev,
992 struct iw_request_info *info,
993 struct iw_param *wrq, char *extra)
994{
995 struct wireless_dev *wdev = dev->ieee80211_ptr;
996 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
997 bool ps = wdev->wext.ps;
998 int timeout = wdev->wext.ps_timeout;
999 int err;
1000
1001 if (wdev->iftype != NL80211_IFTYPE_STATION)
1002 return -EINVAL;
1003
1004 if (!rdev->ops->set_power_mgmt)
1005 return -EOPNOTSUPP;
1006
1007 if (wrq->disabled) {
1008 ps = false;
1009 } else {
1010 switch (wrq->flags & IW_POWER_MODE) {
1011 case IW_POWER_ON: /* If not specified */
1012 case IW_POWER_MODE: /* If set all mask */
1013 case IW_POWER_ALL_R: /* If explicitely state all */
1014 ps = true;
1015 break;
1016 default: /* Otherwise we ignore */
1017 return -EINVAL;
1018 }
1019
1020 if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT))
1021 return -EINVAL;
1022
1023 if (wrq->flags & IW_POWER_TIMEOUT)
1024 timeout = wrq->value / 1000;
1025 }
1026
1027 err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, ps, timeout);
1028 if (err)
1029 return err;
1030
1031 wdev->wext.ps = ps;
1032 wdev->wext.ps_timeout = timeout;
1033
1034 return 0;
1035
1036}
1037EXPORT_SYMBOL_GPL(cfg80211_wext_siwpower);
1038
1039int cfg80211_wext_giwpower(struct net_device *dev,
1040 struct iw_request_info *info,
1041 struct iw_param *wrq, char *extra)
1042{
1043 struct wireless_dev *wdev = dev->ieee80211_ptr;
1044
1045 wrq->disabled = !wdev->wext.ps;
1046
1047 return 0;
1048}
1049EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);