diff options
author | Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 2011-01-31 13:48:16 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-04 16:29:49 -0500 |
commit | f773e409b959677170b3cf1d573dafc4a0a3e34e (patch) | |
tree | 4a01fc250187eae100369cfd641392db0bc73a56 /drivers/net/wireless/zd1211rw | |
parent | c2fadcb3b16b294d7de509c42f1390f672510667 (diff) |
zd1211rw: fix ack_pending in filter_ack causing tx-packet ordering problem on monitor
For reasons not very clear yet to me, filter_ack leaves matching tx-packet
pending with 'ack_pending'. This causes tx-packet to be passed back to upper
layer after next packet has been transfered and tx-packets might end up
coming come out of monitor interface in wrong order vs. rx.
Because of this when enable AP-mode, hostapd monitor interface would get
packets in wrong order causing problems in WPA association.
So don't use mac->ack_pending when in AP-mode.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/zd1211rw')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index ab0d1b9a08ec..84ac95eb59fa 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -799,6 +799,13 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, | |||
799 | 799 | ||
800 | mac->ack_pending = 1; | 800 | mac->ack_pending = 1; |
801 | mac->ack_signal = stats->signal; | 801 | mac->ack_signal = stats->signal; |
802 | |||
803 | /* Prevent pending tx-packet on AP-mode */ | ||
804 | if (mac->type == NL80211_IFTYPE_AP) { | ||
805 | skb = __skb_dequeue(q); | ||
806 | zd_mac_tx_status(hw, skb, mac->ack_signal, NULL); | ||
807 | mac->ack_pending = 0; | ||
808 | } | ||
802 | } | 809 | } |
803 | 810 | ||
804 | spin_unlock_irqrestore(&q->lock, flags); | 811 | spin_unlock_irqrestore(&q->lock, flags); |