Re: Compat-wireless-3.2-rc6-3 is broken for rt2860 device
From: Andreas Hartmann <hidden>
Date: 2012-01-23 17:47:07
Am Mon, 23 Jan 2012 17:36:57 +0100 schrieb Helmut Schaa [off-list ref]:
On Mon, Jan 23, 2012 at 5:03 PM, Andreas Hartmann [off-list ref] wrote:quoted
Helmut Schaa schrieb:quoted
On Fri, Jan 20, 2012 at 8:29 AM, Andreas Hartmann [off-list ref] wrote:quoted
All in one: Your workaround was a good idea, but unfortunately it doesn't "solve" / workaround the problem introduced with the patch "mac80211: retry sending failed BAR frames later instead of tearing down aggr" [1]. I don't know off any other solution at this time as to revert it.Ok, so we've got at least one hw issue here: rt2800 is not able to report correct ACK state of BARs :( The interesting bit is that the legacy drivers tear the BA session down as soon as the first AMPDU subframe failed. That's the same behavior as mac80211 had before the mentioned patch. So, let's assume the generic way Felix implemented works for other devices (like ath9k) we could go with a workaround inside rt2x00 to tear down the BA session as soon as the first AMPDU frame failed. Mind to try that one (not even compile tested though :) ).hdr is missing. I tried to derive it like this: struct ieee80211_hdr *hdr=(void*)entry->skb->data;Looks correct but you should put it right before the ieee80211_is_data_qos check not at the start of the function ...
I did it like this:
--- drivers/net/wireless/rt2x00/rt2x00dev.c.orig 2012-01-23 16:50:03.188718671 +0100
+++ drivers/net/wireless/rt2x00/rt2x00dev.c 2012-01-23 18:11:56.248553764 +0100@@ -388,8 +388,17 @@ 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; + struct ieee80211_hdr *hdr = (void*) entry->skb->data; + if (!success && tx_info->control.sta != NULL && ieee80211_is_data_qos(hdr->frame_control)) { + /* + * Tear down BA session + */ + struct ieee80211_sta *sta = tx_info->control.sta; + u8 *qc = ieee80211_get_qos_ctl(hdr); + int tid = *qc & IEEE80211_QOS_CTL_TID_MASK; + + ieee80211_stop_tx_ba_session(sta, tid); + } } if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
but the machine does crash anyway. Could hdr be null, too? Andreas