Skip to content

Commit

Permalink
mac80211: Fix incorrect num_sta_ps decrement in ap_sta_ps_end
Browse files Browse the repository at this point in the history
If the driver blocked this specific STA with the help of
ieee80211_sta_block_awake we won't clear WLAN_STA_PS_STA later but
still decrement num_sta_ps. Hence, the next data frame from this
STA will trigger ap_sta_ps_end again and also decrement num_sta_ps
again leading to an incorrect num_sta_ps counter.

This can result in problems with powersaving clients not waking up
from PS because the TIM calculation might be skipped due to the
incorrect num_sta_ps counter.

Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Helmut Schaa authored and John W. Linville committed Jan 30, 2012
1 parent 2ab694d commit 608383b
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 7 deletions.
8 changes: 2 additions & 6 deletions net/mac80211/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1145,19 +1145,15 @@ static void ap_sta_ps_start(struct sta_info *sta)

static void ap_sta_ps_end(struct sta_info *sta)
{
struct ieee80211_sub_if_data *sdata = sta->sdata;

atomic_dec(&sdata->bss->num_sta_ps);

#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n",
sdata->name, sta->sta.addr, sta->sta.aid);
sta->sdata->name, sta->sta.addr, sta->sta.aid);
#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */

if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n",
sdata->name, sta->sta.addr, sta->sta.aid);
sta->sdata->name, sta->sta.addr, sta->sta.aid);
#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
return;
}
Expand Down
4 changes: 3 additions & 1 deletion net/mac80211/sta_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -997,9 +997,11 @@ EXPORT_SYMBOL(ieee80211_find_sta);
static void clear_sta_ps_flags(void *_sta)
{
struct sta_info *sta = _sta;
struct ieee80211_sub_if_data *sdata = sta->sdata;

clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
clear_sta_flag(sta, WLAN_STA_PS_STA);
if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA))
atomic_dec(&sdata->bss->num_sta_ps);
}

/* powersave support code */
Expand Down

0 comments on commit 608383b

Please sign in to comment.