mac80211: fix PS-poll response, race
When a station queries us for a PS-poll response, we wrongly queue the frame on the virtual interface's queue rather than the pending queue. Additionally, fix a race condition where we could potentially send multiple frames to the sleeping station due to using a station flag rather than a packet flag. When converting to a packet flag, we can also convert p54 and remove the filter clearing we added for it. (Also remove a now dead function) Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Reported-by: Bob Copeland <me@bobcopeland.com> Tested-by: Bob Copeland <me@bobcopeland.com> Cc: Christian Lamparter <chunkeey@web.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:

committed by
John W. Linville

parent
91a3bd7615
commit
3fa52056f3
@@ -30,7 +30,6 @@
|
||||
* @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP.
|
||||
* @WLAN_STA_WME: Station is a QoS-STA.
|
||||
* @WLAN_STA_WDS: Station is one of our WDS peers.
|
||||
* @WLAN_STA_PSPOLL: Station has just PS-polled us.
|
||||
* @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
|
||||
* IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
|
||||
* frame to this station is transmitted.
|
||||
@@ -47,7 +46,6 @@ enum ieee80211_sta_info_flags {
|
||||
WLAN_STA_ASSOC_AP = 1<<5,
|
||||
WLAN_STA_WME = 1<<6,
|
||||
WLAN_STA_WDS = 1<<7,
|
||||
WLAN_STA_PSPOLL = 1<<8,
|
||||
WLAN_STA_CLEAR_PS_FILT = 1<<9,
|
||||
WLAN_STA_MFP = 1<<10,
|
||||
WLAN_STA_SUSPEND = 1<<11
|
||||
@@ -359,17 +357,6 @@ static inline void clear_sta_flags(struct sta_info *sta, const u32 flags)
|
||||
spin_unlock_irqrestore(&sta->flaglock, irqfl);
|
||||
}
|
||||
|
||||
static inline void set_and_clear_sta_flags(struct sta_info *sta,
|
||||
const u32 set, const u32 clear)
|
||||
{
|
||||
unsigned long irqfl;
|
||||
|
||||
spin_lock_irqsave(&sta->flaglock, irqfl);
|
||||
sta->flags |= set;
|
||||
sta->flags &= ~clear;
|
||||
spin_unlock_irqrestore(&sta->flaglock, irqfl);
|
||||
}
|
||||
|
||||
static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags)
|
||||
{
|
||||
u32 ret;
|
||||
|
Reference in New Issue
Block a user