From: Helmut Schaa Date: Mon, 28 Mar 2011 11:35:21 +0000 (+0200) Subject: rt2x00: Fix tx aggregation problems with some clients X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=f16d2db704b873d34cec54f992637f3579e10e08;p=openwrt%2Fstaging%2Fblogic.git rt2x00: Fix tx aggregation problems with some clients Some clients seem to rely upon the reception of BlockAckReqs to flush their rx reorder buffer. In order to fix aggregation for these clients rt2x00 should send a BlockAckReq if the transmission of an AMPDU subframe fails. Introduce a new flag TXDONE_AMPDU to indicate that this is an AMPDU subframe and pass IEEE80211_TX_STAT_AMPDU_NO_BACK to mac80211 if an AMPDU subframe failed during transmission. This fixes aggregation problems with Intel 5100 Windows STAs (and maybe others as well). Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 59302faec395..769c05c0cbaa 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -687,6 +687,9 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status) mcs = real_mcs; } + if (aggr == 1 || ampdu == 1) + __set_bit(TXDONE_AMPDU, &txdesc.flags); + /* * Ralink has a retry mechanism using a global fallback * table. We setup this fallback table to try the immediate diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index a98c43485239..83252d94c2b7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -353,10 +353,14 @@ void rt2x00lib_txdone(struct queue_entry *entry, * which would allow the rc algorithm to better decide on * which rates are suitable. */ - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + if (test_bit(TXDONE_AMPDU, &txdesc->flags) || + tx_info->flags & IEEE80211_TX_CTL_AMPDU) { tx_info->flags |= IEEE80211_TX_STAT_AMPDU; tx_info->status.ampdu_len = 1; tx_info->status.ampdu_ack_len = success ? 1 : 0; + + if (!success) + tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; } if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 0c8b0c699679..6ae820093997 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -217,6 +217,7 @@ enum txdone_entry_desc_flags { TXDONE_FALLBACK, TXDONE_FAILURE, TXDONE_EXCESSIVE_RETRY, + TXDONE_AMPDU, }; /**