Commit 3b1c5a5307fb5277f395efdcf330c064d79df07d
Committed by
Johannes Berg
1 parent
9bdbf04db0
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
{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, |
net/wireless/mesh.c
... | ... | @@ -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 |