diff options
author | Marco Porsch <marco@cozybit.com> | 2013-01-07 10:04:52 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-01-16 16:48:04 -0500 |
commit | 3b1c5a5307fb5277f395efdcf330c064d79df07d (patch) | |
tree | 9aca9007c05a70a0bce2c18c3c60fcfda1b7923d /net/wireless/nl80211.c | |
parent | 9bdbf04db099c11bbbaea9dcea7465c508531fb8 (diff) |
{cfg,nl}80211: mesh power mode primitives and userspace access
Add the nl80211_mesh_power_mode enumeration which holds possible
values for the mesh power mode. These modes are unknown, active,
light sleep and deep sleep.
Add power_mode entry to the mesh config structure to hold the
user-configured default mesh power mode. This value will be used
for new peer links.
Add the dot11MeshAwakeWindowDuration value to the mesh config.
The awake window is a duration in TU describing how long the STA
will stay awake after transmitting its beacon in PS mode.
Add access routines to:
- get/set local link-specific power mode (STA)
- get remote STA's link-specific power mode (STA)
- get remote STA's non-peer power mode (STA)
- get/set default mesh power mode (mesh config)
- get/set mesh awake window duration (mesh config)
All config changes may be done at mesh runtime and take effect
immediately.
Signed-off-by: Marco Porsch <marco@cozybit.com>
Signed-off-by: Ivan Bezyazychnyy <ivan.bezyazychnyy@gmail.com>
Signed-off-by: Mike Krinkin <krinkin.m.u@gmail.com>
[fix commit message line length, error handling in set station]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d5842eb35aec..1a7a710fe9bf 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -3001,6 +3001,18 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, | |||
3001 | nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS, | 3001 | nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS, |
3002 | sinfo->beacon_loss_count)) | 3002 | sinfo->beacon_loss_count)) |
3003 | goto nla_put_failure; | 3003 | goto nla_put_failure; |
3004 | if ((sinfo->filled & STATION_INFO_LOCAL_PM) && | ||
3005 | nla_put_u32(msg, NL80211_STA_INFO_LOCAL_PM, | ||
3006 | sinfo->local_pm)) | ||
3007 | goto nla_put_failure; | ||
3008 | if ((sinfo->filled & STATION_INFO_PEER_PM) && | ||
3009 | nla_put_u32(msg, NL80211_STA_INFO_PEER_PM, | ||
3010 | sinfo->peer_pm)) | ||
3011 | goto nla_put_failure; | ||
3012 | if ((sinfo->filled & STATION_INFO_NONPEER_PM) && | ||
3013 | nla_put_u32(msg, NL80211_STA_INFO_NONPEER_PM, | ||
3014 | sinfo->nonpeer_pm)) | ||
3015 | goto nla_put_failure; | ||
3004 | if (sinfo->filled & STATION_INFO_BSS_PARAM) { | 3016 | if (sinfo->filled & STATION_INFO_BSS_PARAM) { |
3005 | bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM); | 3017 | bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM); |
3006 | if (!bss_param) | 3018 | if (!bss_param) |
@@ -3206,6 +3218,17 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
3206 | params.plink_state = | 3218 | params.plink_state = |
3207 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]); | 3219 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]); |
3208 | 3220 | ||
3221 | if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) { | ||
3222 | enum nl80211_mesh_power_mode pm = nla_get_u32( | ||
3223 | info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]); | ||
3224 | |||
3225 | if (pm <= NL80211_MESH_POWER_UNKNOWN || | ||
3226 | pm > NL80211_MESH_POWER_MAX) | ||
3227 | return -EINVAL; | ||
3228 | |||
3229 | params.local_pm = pm; | ||
3230 | } | ||
3231 | |||
3209 | switch (dev->ieee80211_ptr->iftype) { | 3232 | switch (dev->ieee80211_ptr->iftype) { |
3210 | case NL80211_IFTYPE_AP: | 3233 | case NL80211_IFTYPE_AP: |
3211 | case NL80211_IFTYPE_AP_VLAN: | 3234 | case NL80211_IFTYPE_AP_VLAN: |
@@ -3213,6 +3236,8 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
3213 | /* disallow mesh-specific things */ | 3236 | /* disallow mesh-specific things */ |
3214 | if (params.plink_action) | 3237 | if (params.plink_action) |
3215 | return -EINVAL; | 3238 | return -EINVAL; |
3239 | if (params.local_pm) | ||
3240 | return -EINVAL; | ||
3216 | 3241 | ||
3217 | /* TDLS can't be set, ... */ | 3242 | /* TDLS can't be set, ... */ |
3218 | if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) | 3243 | if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) |
@@ -3265,6 +3290,8 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
3265 | /* disallow things sta doesn't support */ | 3290 | /* disallow things sta doesn't support */ |
3266 | if (params.plink_action) | 3291 | if (params.plink_action) |
3267 | return -EINVAL; | 3292 | return -EINVAL; |
3293 | if (params.local_pm) | ||
3294 | return -EINVAL; | ||
3268 | /* reject any changes other than AUTHORIZED */ | 3295 | /* reject any changes other than AUTHORIZED */ |
3269 | if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED)) | 3296 | if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED)) |
3270 | return -EINVAL; | 3297 | return -EINVAL; |
@@ -3922,7 +3949,11 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, | |||
3922 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL, | 3949 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL, |
3923 | cur_params.dot11MeshHWMProotInterval) || | 3950 | cur_params.dot11MeshHWMProotInterval) || |
3924 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, | 3951 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, |
3925 | cur_params.dot11MeshHWMPconfirmationInterval)) | 3952 | cur_params.dot11MeshHWMPconfirmationInterval) || |
3953 | nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE, | ||
3954 | cur_params.power_mode) || | ||
3955 | nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW, | ||
3956 | cur_params.dot11MeshAwakeWindowDuration)) | ||
3926 | goto nla_put_failure; | 3957 | goto nla_put_failure; |
3927 | nla_nest_end(msg, pinfoattr); | 3958 | nla_nest_end(msg, pinfoattr); |
3928 | genlmsg_end(msg, hdr); | 3959 | genlmsg_end(msg, hdr); |
@@ -3961,6 +3992,8 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A | |||
3961 | [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 }, | 3992 | [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 }, |
3962 | [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 }, | 3993 | [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 }, |
3963 | [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 }, | 3994 | [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 }, |
3995 | [NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U32 }, | ||
3996 | [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 }, | ||
3964 | }; | 3997 | }; |
3965 | 3998 | ||
3966 | static const struct nla_policy | 3999 | static const struct nla_policy |
@@ -4088,6 +4121,14 @@ do { \ | |||
4088 | 1, 65535, mask, | 4121 | 1, 65535, mask, |
4089 | NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, | 4122 | NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, |
4090 | nla_get_u16); | 4123 | nla_get_u16); |
4124 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode, | ||
4125 | NL80211_MESH_POWER_ACTIVE, | ||
4126 | NL80211_MESH_POWER_MAX, | ||
4127 | mask, NL80211_MESHCONF_POWER_MODE, | ||
4128 | nla_get_u32); | ||
4129 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, | ||
4130 | 0, 65535, mask, | ||
4131 | NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16); | ||
4091 | if (mask_out) | 4132 | if (mask_out) |
4092 | *mask_out = mask; | 4133 | *mask_out = mask; |
4093 | 4134 | ||