| From foo@baz Fri Mar 16 15:43:17 CET 2018 |
| From: Adiel Aloni <adiel.aloni@intel.com> |
| Date: Fri, 1 Dec 2017 13:50:53 +0200 |
| Subject: mac80211_hwsim: enforce PS_MANUAL_POLL to be set after PS_ENABLED |
| |
| From: Adiel Aloni <adiel.aloni@intel.com> |
| |
| |
| [ Upstream commit e16ea4bb516bc21ea2202f2107718b29218bea59 ] |
| |
| Enforce using PS_MANUAL_POLL in ps hwsim debugfs to trigger a poll, |
| only if PS_ENABLED was set before. |
| This is required due to commit c9491367b759 ("mac80211: always update the |
| PM state of a peer on MGMT / DATA frames") that enforces the ap to |
| check only mgmt/data frames ps bit, and then update station's power save |
| accordingly. |
| When sending only ps-poll (control frame) the ap will not be aware that |
| the station entered power save. |
| Setting ps enable before triggering ps_poll, will send NDP with PM bit |
| enabled first. |
| |
| Signed-off-by: Adiel Aloni <adiel.aloni@intel.com> |
| Signed-off-by: Luca Coelho <luciano.coelho@intel.com> |
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/wireless/mac80211_hwsim.c | 17 +++++++++++------ |
| 1 file changed, 11 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/net/wireless/mac80211_hwsim.c |
| +++ b/drivers/net/wireless/mac80211_hwsim.c |
| @@ -727,16 +727,21 @@ static int hwsim_fops_ps_write(void *dat |
| val != PS_MANUAL_POLL) |
| return -EINVAL; |
| |
| - old_ps = data->ps; |
| - data->ps = val; |
| - |
| - local_bh_disable(); |
| if (val == PS_MANUAL_POLL) { |
| + if (data->ps != PS_ENABLED) |
| + return -EINVAL; |
| + local_bh_disable(); |
| ieee80211_iterate_active_interfaces_atomic( |
| data->hw, IEEE80211_IFACE_ITER_NORMAL, |
| hwsim_send_ps_poll, data); |
| - data->ps_poll_pending = true; |
| - } else if (old_ps == PS_DISABLED && val != PS_DISABLED) { |
| + local_bh_enable(); |
| + return 0; |
| + } |
| + old_ps = data->ps; |
| + data->ps = val; |
| + |
| + local_bh_disable(); |
| + if (old_ps == PS_DISABLED && val != PS_DISABLED) { |
| ieee80211_iterate_active_interfaces_atomic( |
| data->hw, IEEE80211_IFACE_ITER_NORMAL, |
| hwsim_send_nullfunc_ps, data); |