mac80211: Enhancements to dynamic power save.
RFC 1/1 mac80211: Enhancements to dynamic power save.
This patch enables mac80211 to send a null frame and also to check for tim in the beacon if power save is enabled.
--- net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/mlme.c | 41 ++++++++++++++++++++++++++++++++++++++++- net/mac80211/scan.c | 2 +- net/mac80211/wext.c | 13 +++++++++---- 4 files changed, 53 insertions(+), 6 deletions(-)
net/mac80211/ieee80211_i.h +3 -0
@@ -986,6 +986,9 @@ u64 ieee80211_mandatory_rates(struct ieee80211_local *local,void ieee80211_dynamic_ps_enable_work (struct work_struct *work);void ieee80211_dynamic_ps_disable_work (struct work_struct *work);void ieee80211_dynamic_ps_timer (unsigned long data); +void ieee80211_send_nullfunc (struct ieee80211_local *local, +struct ieee80211_sub_if_data *sdata, +int powersave);void ieee80211_wake_queues_by_reason (struct ieee80211_hw *hw,enum queue_stop_reason reason);
net/mac80211/mlme.c +40 -1
75 lines not on this page · raw message
net/mac80211/scan.c +1 -1
@@ -395,7 +395,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,return RX_QUEUED ; } -static void ieee80211_send_nullfunc (struct ieee80211_local *local, +void ieee80211_send_nullfunc (struct ieee80211_local *local,struct ieee80211_sub_if_data *sdata,int powersave) {
net/mac80211/wext.c +9 -4
@@ -871,12 +871,17 @@ set:mod_timer (&local->dynamic_ps_timer, jiffies +msecs_to_jiffies (local->dynamic_ps_timeout)); else { -if (local->powersave) +if (local->powersave) { +ieee80211_send_nullfunc (local, sdata,1 ); conf->flags |=IEEE80211_CONF_PS ; -else + ret =ieee80211_hw_config (local, +IEEE80211_CONF_CHANGE_PS ); + }else { conf->flags &= ~IEEE80211_CONF_PS ; - ret =ieee80211_hw_config (local, -IEEE80211_CONF_CHANGE_PS ); + ret =ieee80211_hw_config (local, +IEEE80211_CONF_CHANGE_PS ); +ieee80211_send_nullfunc (local, sdata,0 ); + } } }
Signature · 1 line
1.6.0.1
Johannes Berg
maintainerQuoted 4 lines · Vivek Natarajan
This patch enables mac80211 to send a null frame and also to check for tim in the beacon if power save is enabled.
Signed-off-by Vivek Natarajan <[email protected]>
Looks good to me, to be sure, this is all dependent on !NO_STACK_PS, right?
johannes
Quoted 144 lines
--- net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/mlme.c | 41 ++++++++++++++++++++++++++++++++++++++++- net/mac80211/scan.c | 2 +- net/mac80211/wext.c | 13 +++++++++---- 4 files changed, 53 insertions(+), 6 deletions(-)net/mac80211/ieee80211_i.h +3
-0@@ -986,6 +986,9 @@ u64 ieee80211_mandatory_rates(struct ieee80211_local *local,void ieee80211_dynamic_ps_enable_work (struct work_struct *work);void ieee80211_dynamic_ps_disable_work (struct work_struct *work);void ieee80211_dynamic_ps_timer (unsigned long data); +void ieee80211_send_nullfunc (struct ieee80211_local *local, +struct ieee80211_sub_if_data *sdata, +int powersave);void ieee80211_wake_queues_by_reason (struct ieee80211_hw *hw,enum queue_stop_reason reason);net/mac80211/mlme.c +40
-1@@ -568,6 +568,30 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, } } +static bool check_tim (struct ieee802_11_elems *elems,u16 aid,bool *is_mc) +{ +u8 mask; +u8 index, indexn1, indexn2; +struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *) elems->tim; + + aid &=0x3fff ; + index = aid /8 ; + mask =1 << (aid &7 ); + +if (tim->bitmap_ctrl &0x01 ) + *is_mc = true; + + indexn1 = tim->bitmap_ctrl &0xfe ; + indexn2 = elems->tim_len + indexn1 -4 ; + +if (index < indexn1 || index > indexn2) +return false; + + index -= indexn1; + +return !!(tim->virtual_map[index] & mask); +} +static u32 ieee80211_handle_bss_capability (struct ieee80211_sub_if_data *sdata,u16 capab,bool erp_valid,u8 erp) {@@ -752,6 +776,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,mod_timer (&local->dynamic_ps_timer, jiffies +msecs_to_jiffies (local->dynamic_ps_timeout)); else { +ieee80211_send_nullfunc (local, sdata,1 ); conf->flags |=IEEE80211_CONF_PS ;ieee80211_hw_config (local,IEEE80211_CONF_CHANGE_PS );@@ -1729,7 +1754,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,struct ieee802_11_elems elems;struct ieee80211_local *local = sdata->local;u32 changed =0 ; -bool erp_valid; +bool erp_valid, directed_tim, is_mc = false;u8 erp_value =0 ;/* Process beacon from the current BSS */ @@ -1752,6 +1777,18 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,ieee80211_sta_wmm_params (local, ifsta, elems.wmm_param, elems.wmm_param_len); +if (!(local->hw.flags &IEEE80211_HW_NO_STACK_DYNAMIC_PS )) { + directed_tim =check_tim (&elems, ifsta->aid, &is_mc); + +if (directed_tim || is_mc) { +if (local->hw.conf.flags &&IEEE80211_CONF_PS ) { + local->hw.conf.flags &= ~IEEE80211_CONF_PS ; +ieee80211_hw_config (local, +IEEE80211_CONF_CHANGE_PS ); +ieee80211_send_nullfunc (local, sdata,0 ); + } + } + }if (elems.erp_info && elems.erp_info_len >=1 ) { erp_valid = true;@@ -2651,10 +2688,12 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)struct ieee80211_local *local = container_of(work, struct ieee80211_local, dynamic_ps_enable_work); +struct ieee80211_sub_if_data *sdata = local->scan_sdata;if (local->hw.conf.flags &IEEE80211_CONF_PS )return ; +ieee80211_send_nullfunc (local, sdata,1 ); local->hw.conf.flags |=IEEE80211_CONF_PS ;ieee80211_hw_config (local,IEEE80211_CONF_CHANGE_PS );net/mac80211/scan.c +1
-1@@ -395,7 +395,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,return RX_QUEUED ; } -static void ieee80211_send_nullfunc (struct ieee80211_local *local, +void ieee80211_send_nullfunc (struct ieee80211_local *local,struct ieee80211_sub_if_data *sdata,int powersave) {net/mac80211/wext.c +9
-4@@ -871,12 +871,17 @@ set:mod_timer (&local->dynamic_ps_timer, jiffies +msecs_to_jiffies (local->dynamic_ps_timeout)); else { -if (local->powersave) +if (local->powersave) { +ieee80211_send_nullfunc (local, sdata,1 ); conf->flags |=IEEE80211_CONF_PS ; -else + ret =ieee80211_hw_config (local, +IEEE80211_CONF_CHANGE_PS ); + }else { conf->flags &= ~IEEE80211_CONF_PS ; - ret =ieee80211_hw_config (local, -IEEE80211_CONF_CHANGE_PS ); + ret =ieee80211_hw_config (local, +IEEE80211_CONF_CHANGE_PS ); +ieee80211_send_nullfunc (local, sdata,0 ); + } } }
Quoted 8 lines · Johannes Berg
Quoted 4 lines · Vivek Natarajan
This patch enables mac80211 to send a null frame and also to check for tim in the beacon if power save is enabled.
Signed-off-by Vivek Natarajan <[email protected]>Looks good to me, to be sure, this is all dependent on !NO_STACK_PS, right?
Yes, it all depends on that flag. I will send these RFCs as patches.
Thanks,
Vivek.
Quoted 2 lines · Vivek Natarajan
This patch enables mac80211 to send a null frame and also to check for tim in the beacon if power save is enabled.
I would like to see a separate hw flag for disabling this feature. Not all drivers need this, for example iwlwifi.
Quoted 12 lines
net/mac80211/wext.c +2
-1@@ -871,12 +871,17 @@ set:mod_timer (&local->dynamic_ps_timer, jiffies +msecs_to_jiffies (local->dynamic_ps_timeout)); else { -if (local->powersave) +if (local->powersave) { +ieee80211_send_nullfunc (local, sdata,1 ); conf->flags |=IEEE80211_CONF_PS ;
net/mac80211/wext.c set: · line 883
Quoted 10 lines
net/mac80211/wext.c +6
-3-else + ret =ieee80211_hw_config (local, +IEEE80211_CONF_CHANGE_PS ); + }else { conf->flags &= ~IEEE80211_CONF_PS ; - ret =ieee80211_hw_config (local, -IEEE80211_CONF_CHANGE_PS ); + ret =ieee80211_hw_config (local, +IEEE80211_CONF_CHANGE_PS ); +ieee80211_send_nullfunc (local, sdata,0 );
Maybe add a helper function for checking the new flag I proposed and sending the null frame?
Signature · 1 line
Kalle Valo