rt2x00: Fix tx aggregation problems with some clients
authorHelmut Schaa <helmut.schaa@googlemail.com>
Mon, 28 Mar 2011 11:35:21 +0000 (13:35 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 4 Apr 2011 20:20:04 +0000 (16:20 -0400)
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 <helmut.schaa@googlemail.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00queue.h

index 59302faec3959901be3f3e0b7bcf7a838472194e..769c05c0cbaa27896e1c13e4780e9b9d0ddcb1a1 100644 (file)
@@ -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
index a98c43485239ffc6004f7c422271db2f15b4799b..83252d94c2b7c6dbe53a19c8cf2ea0374e7dc294 100644 (file)
@@ -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) {
index 0c8b0c6996799348f46710af9952920ed52e8434..6ae820093997c99f68829b77369cb2681923dd7e 100644 (file)
@@ -217,6 +217,7 @@ enum txdone_entry_desc_flags {
        TXDONE_FALLBACK,
        TXDONE_FAILURE,
        TXDONE_EXCESSIVE_RETRY,
+       TXDONE_AMPDU,
 };
 
 /**