[rt2x00-users] [bugzilla-daemon at bugzilla.kernel.org: [Bug 42828] rt2800pci unstable - chokes after too much I/O]

Stanislaw Gruszka sgruszka at redhat.com
Fri Nov 30 20:10:51 AEDT 2012

On Tue, Nov 27, 2012 at 03:39:16PM +0100, Helmut Schaa wrote:
> On Tue, Nov 27, 2012 at 1:32 PM, Stanislaw Gruszka <sgruszka at redhat.com> wrote:
> >> I think it might be better to just always report BAR frames as
> >> successful to mac80211
> >> from the rt2800 tx status code. Hence, the BAR resend code will never
> >> trigger for
> >> rt2x00 devices.
> >
> > This is what more or less commit be03d4a45c0 does, and that cause
> > problems on Francisco environment. I think problem happens when BAR
> > do not reach pear, so it do not sent BA, but we pretend it does.
> With be03d4a45c0 we don't even send out a BAR when an AMPDU fails. But AMPDU
> failure reporting works fine (in most cases but I won't got into
> detail here :D ).

Uhh, I was confused.

> So we can easily send out a BAR to flush the recipients reorder
> buffer. However, we
> cannot verify if the BAR fails or not, hence, I'd recommend to ignore
> the transmission
> state of BAR frames and report them back to mac80211 as successful to not end
> up sending BARs over and over again.
> Of course this has limitations since a BAR can easily be dropped on
> the air and we
> have no chance to verify that. But we could for example add a
> threshold of allowed
> AMPDU failures until the BA session gets torn down by mac80211 for example.

But will this work and is needed? If BAR will be drooped, and then will not
get BA from AMPDU, we will send another BAR, and with a bit of luck this
BAR will not be dropped. And if it does, we probably get out of range so
connection should be reestablished anyway.

I think fake BAR ack status should fix Francisco case, and probably does not
break Andreas case.

Below is yet another patch for this problem. Andreas, Francisco, please test.

Note: I don't wont you to perform extensive performance tests, just answer
of question: Does connection hangs with patch: yes or no?


diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 69097d1..1d11b01 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -276,6 +276,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+	struct ieee80211_hdr *hdr = (void *) entry->skb->data;
 	unsigned int header_length, i;
 	u8 rate_idx, rate_flags, retry_rates;
 	u8 skbdesc_flags = skbdesc->flags;
@@ -324,10 +325,13 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 	 * Determine if the frame has been successfully transmitted.
+	 *
+	 * FIXME: comment me. 
 	success =
 	    test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
-	    test_bit(TXDONE_UNKNOWN, &txdesc->flags);
+	    test_bit(TXDONE_UNKNOWN, &txdesc->flags) ||
+	    ieee80211_is_back_req(hdr->frame_control);
 	 * Update TX statistics.
@@ -391,6 +395,9 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 		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;
 		 * TODO: Need to tear down BA session here
 		 * if not successful.

More information about the users mailing list