Commit 3b1c5a5307fb5277f395efdcf330c064d79df07d

Authored by Marco Porsch
Committed by Johannes Berg
1 parent 9bdbf04db0

{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>

Showing 4 changed files with 113 additions and 1 deletions Side-by-side Diff

include/net/cfg80211.h
... ... @@ -610,6 +610,8 @@
610 610 * @sta_modify_mask: bitmap indicating which parameters changed
611 611 * (for those that don't have a natural "no change" value),
612 612 * see &enum station_parameters_apply_mask
  613 + * @local_pm: local link-specific mesh power save mode (no change when set
  614 + * to unknown)
613 615 */
614 616 struct station_parameters {
615 617 u8 *supported_rates;
... ... @@ -625,6 +627,7 @@
625 627 struct ieee80211_vht_cap *vht_capa;
626 628 u8 uapsd_queues;
627 629 u8 max_sp;
  630 + enum nl80211_mesh_power_mode local_pm;
628 631 };
629 632  
630 633 /**
... ... @@ -655,6 +658,9 @@
655 658 * @STATION_INFO_STA_FLAGS: @sta_flags filled
656 659 * @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count filled
657 660 * @STATION_INFO_T_OFFSET: @t_offset filled
  661 + * @STATION_INFO_LOCAL_PM: @local_pm filled
  662 + * @STATION_INFO_PEER_PM: @peer_pm filled
  663 + * @STATION_INFO_NONPEER_PM: @nonpeer_pm filled
658 664 */
659 665 enum station_info_flags {
660 666 STATION_INFO_INACTIVE_TIME = 1<<0,
... ... @@ -678,6 +684,9 @@
678 684 STATION_INFO_STA_FLAGS = 1<<18,
679 685 STATION_INFO_BEACON_LOSS_COUNT = 1<<19,
680 686 STATION_INFO_T_OFFSET = 1<<20,
  687 + STATION_INFO_LOCAL_PM = 1<<21,
  688 + STATION_INFO_PEER_PM = 1<<22,
  689 + STATION_INFO_NONPEER_PM = 1<<23,
681 690 };
682 691  
683 692 /**
... ... @@ -791,6 +800,9 @@
791 800 * @sta_flags: station flags mask & values
792 801 * @beacon_loss_count: Number of times beacon loss event has triggered.
793 802 * @t_offset: Time offset of the station relative to this host.
  803 + * @local_pm: local mesh STA power save mode
  804 + * @peer_pm: peer mesh STA power save mode
  805 + * @nonpeer_pm: non-peer mesh STA power save mode
794 806 */
795 807 struct station_info {
796 808 u32 filled;
... ... @@ -820,6 +832,9 @@
820 832  
821 833 u32 beacon_loss_count;
822 834 s64 t_offset;
  835 + enum nl80211_mesh_power_mode local_pm;
  836 + enum nl80211_mesh_power_mode peer_pm;
  837 + enum nl80211_mesh_power_mode nonpeer_pm;
823 838  
824 839 /*
825 840 * Note: Add a new enum station_info_flags value for each new field and
... ... @@ -995,6 +1010,10 @@
995 1010 * @dot11MeshHWMPconfirmationInterval: The minimum interval of time (in TUs)
996 1011 * during which a mesh STA can send only one Action frame containing
997 1012 * a PREQ element for root path confirmation.
  1013 + * @power_mode: The default mesh power save mode which will be the initial
  1014 + * setting for new peer links.
  1015 + * @dot11MeshAwakeWindowDuration: The duration in TUs the STA will remain awake
  1016 + * after transmitting its beacon.
998 1017 */
999 1018 struct mesh_config {
1000 1019 u16 dot11MeshRetryTimeout;
... ... @@ -1022,6 +1041,8 @@
1022 1041 u32 dot11MeshHWMPactivePathToRootTimeout;
1023 1042 u16 dot11MeshHWMProotInterval;
1024 1043 u16 dot11MeshHWMPconfirmationInterval;
  1044 + enum nl80211_mesh_power_mode power_mode;
  1045 + u16 dot11MeshAwakeWindowDuration;
1025 1046 };
1026 1047  
1027 1048 /**
include/uapi/linux/nl80211.h
... ... @@ -1310,6 +1310,9 @@
1310 1310 * if not given in START_AP 0 is assumed, if not given in SET_BSS
1311 1311 * no change is made.
1312 1312 *
  1313 + * @NL80211_ATTR_LOCAL_MESH_POWER_MODE: local mesh STA link-specific power mode
  1314 + * defined in &enum nl80211_mesh_power_mode.
  1315 + *
1313 1316 * @NL80211_ATTR_MAX: highest attribute number currently defined
1314 1317 * @__NL80211_ATTR_AFTER_LAST: internal use
1315 1318 */
... ... @@ -1580,6 +1583,8 @@
1580 1583 NL80211_ATTR_P2P_CTWINDOW,
1581 1584 NL80211_ATTR_P2P_OPPPS,
1582 1585  
  1586 + NL80211_ATTR_LOCAL_MESH_POWER_MODE,
  1587 +
1583 1588 /* add attributes here, update the policy in nl80211.c */
1584 1589  
1585 1590 __NL80211_ATTR_AFTER_LAST,
... ... @@ -1838,6 +1843,10 @@
1838 1843 * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update.
1839 1844 * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32)
1840 1845 * @NL80211_STA_INFO_T_OFFSET: timing offset with respect to this STA (s64)
  1846 + * @NL80211_STA_INFO_LOCAL_PM: local mesh STA link-specific power mode
  1847 + * @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode
  1848 + * @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards
  1849 + * non-peer STA
1841 1850 * @__NL80211_STA_INFO_AFTER_LAST: internal
1842 1851 * @NL80211_STA_INFO_MAX: highest possible station info attribute
1843 1852 */
... ... @@ -1862,6 +1871,9 @@
1862 1871 NL80211_STA_INFO_STA_FLAGS,
1863 1872 NL80211_STA_INFO_BEACON_LOSS,
1864 1873 NL80211_STA_INFO_T_OFFSET,
  1874 + NL80211_STA_INFO_LOCAL_PM,
  1875 + NL80211_STA_INFO_PEER_PM,
  1876 + NL80211_STA_INFO_NONPEER_PM,
1865 1877  
1866 1878 /* keep last */
1867 1879 __NL80211_STA_INFO_AFTER_LAST,
... ... @@ -2253,6 +2265,34 @@
2253 2265 };
2254 2266  
2255 2267 /**
  2268 + * enum nl80211_mesh_power_mode - mesh power save modes
  2269 + *
  2270 + * @NL80211_MESH_POWER_UNKNOWN: The mesh power mode of the mesh STA is
  2271 + * not known or has not been set yet.
  2272 + * @NL80211_MESH_POWER_ACTIVE: Active mesh power mode. The mesh STA is
  2273 + * in Awake state all the time.
  2274 + * @NL80211_MESH_POWER_LIGHT_SLEEP: Light sleep mode. The mesh STA will
  2275 + * alternate between Active and Doze states, but will wake up for
  2276 + * neighbor's beacons.
  2277 + * @NL80211_MESH_POWER_DEEP_SLEEP: Deep sleep mode. The mesh STA will
  2278 + * alternate between Active and Doze states, but may not wake up
  2279 + * for neighbor's beacons.
  2280 + *
  2281 + * @__NL80211_MESH_POWER_AFTER_LAST - internal use
  2282 + * @NL80211_MESH_POWER_MAX - highest possible power save level
  2283 + */
  2284 +
  2285 +enum nl80211_mesh_power_mode {
  2286 + NL80211_MESH_POWER_UNKNOWN,
  2287 + NL80211_MESH_POWER_ACTIVE,
  2288 + NL80211_MESH_POWER_LIGHT_SLEEP,
  2289 + NL80211_MESH_POWER_DEEP_SLEEP,
  2290 +
  2291 + __NL80211_MESH_POWER_AFTER_LAST,
  2292 + NL80211_MESH_POWER_MAX = __NL80211_MESH_POWER_AFTER_LAST - 1
  2293 +};
  2294 +
  2295 +/**
2256 2296 * enum nl80211_meshconf_params - mesh configuration parameters
2257 2297 *
2258 2298 * Mesh configuration parameters. These can be changed while the mesh is
... ... @@ -2346,6 +2386,11 @@
2346 2386 * (in TUs) during which a mesh STA can send only one Action frame
2347 2387 * containing a PREQ element for root path confirmation.
2348 2388 *
  2389 + * @NL80211_MESHCONF_POWER_MODE: Default mesh power mode for new peer links.
  2390 + * type &enum nl80211_mesh_power_mode (u32)
  2391 + *
  2392 + * @NL80211_MESHCONF_AWAKE_WINDOW: awake window duration (in TUs)
  2393 + *
2349 2394 * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
2350 2395 */
2351 2396 enum nl80211_meshconf_params {
... ... @@ -2375,6 +2420,8 @@
2375 2420 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
2376 2421 NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
2377 2422 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
  2423 + NL80211_MESHCONF_POWER_MODE,
  2424 + NL80211_MESHCONF_AWAKE_WINDOW,
2378 2425  
2379 2426 /* keep last */
2380 2427 __NL80211_MESHCONF_ATTR_AFTER_LAST,
... ... @@ -46,6 +46,7 @@
46 46  
47 47 #define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units (=TUs) */
48 48 #define MESH_DEFAULT_DTIM_PERIOD 2
  49 +#define MESH_DEFAULT_AWAKE_WINDOW 10 /* in 1024 us units (=TUs) */
49 50  
50 51 const struct mesh_config default_mesh_config = {
51 52 .dot11MeshRetryTimeout = MESH_RET_T,
... ... @@ -72,6 +73,8 @@
72 73 .dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT,
73 74 .dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL,
74 75 .dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL,
  76 + .power_mode = NL80211_MESH_POWER_ACTIVE,
  77 + .dot11MeshAwakeWindowDuration = MESH_DEFAULT_AWAKE_WINDOW,
75 78 };
76 79  
77 80 const struct mesh_setup default_mesh_setup = {
net/wireless/nl80211.c
... ... @@ -3001,6 +3001,18 @@
3001 3001 nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS,
3002 3002 sinfo->beacon_loss_count))
3003 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 3016 if (sinfo->filled & STATION_INFO_BSS_PARAM) {
3005 3017 bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
3006 3018 if (!bss_param)
... ... @@ -3206,6 +3218,17 @@
3206 3218 params.plink_state =
3207 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 3232 switch (dev->ieee80211_ptr->iftype) {
3210 3233 case NL80211_IFTYPE_AP:
3211 3234 case NL80211_IFTYPE_AP_VLAN:
... ... @@ -3213,6 +3236,8 @@
3213 3236 /* disallow mesh-specific things */
3214 3237 if (params.plink_action)
3215 3238 return -EINVAL;
  3239 + if (params.local_pm)
  3240 + return -EINVAL;
3216 3241  
3217 3242 /* TDLS can't be set, ... */
3218 3243 if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
... ... @@ -3265,6 +3290,8 @@
3265 3290 /* disallow things sta doesn't support */
3266 3291 if (params.plink_action)
3267 3292 return -EINVAL;
  3293 + if (params.local_pm)
  3294 + return -EINVAL;
3268 3295 /* reject any changes other than AUTHORIZED */
3269 3296 if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
3270 3297 return -EINVAL;
... ... @@ -3922,7 +3949,11 @@
3922 3949 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
3923 3950 cur_params.dot11MeshHWMProotInterval) ||
3924 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 3957 goto nla_put_failure;
3927 3958 nla_nest_end(msg, pinfoattr);
3928 3959 genlmsg_end(msg, hdr);
... ... @@ -3961,6 +3992,8 @@
3961 3992 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
3962 3993 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 },
3963 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 3999 static const struct nla_policy
... ... @@ -4088,6 +4121,14 @@
4088 4121 1, 65535, mask,
4089 4122 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
4090 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 4132 if (mask_out)
4092 4133 *mask_out = mask;
4093 4134