aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2010-01-17 01:47:59 +0100
committerJohn W. Linville <linville@tuxdriver.com>2010-01-19 16:25:21 -0500
commitc6fcf6bcfc3cfc1c00cc7fd9610cfa2b1a18041f (patch)
tree301713d3f65f3cc9cb99e374c655d6f8bf99c741 /net/mac80211/tx.c
parentmac80211: move control.hw_key assignment (diff)
downloadlinux-dev-c6fcf6bcfc3cfc1c00cc7fd9610cfa2b1a18041f.tar.xz
linux-dev-c6fcf6bcfc3cfc1c00cc7fd9610cfa2b1a18041f.zip
mac80211: re-enable re-transmission of filtered frames
In an earlier commit, mac80211: disable software retry for now Pavel Roskin reported a problem that seems to be due to software retry of already transmitted frames. It turns out that we've never done that correctly, but due to some recent changes it now crashes in the TX code. I've added a comment in the patch that explains the problem better and also points to possible solutions -- which I can't implement right now. I disabled software retry of failed/filtered frames because it was broken. With the work of the previous patches, it now becomes fairly easy to re-enable it by adding a flag indicating that the frame shouldn't be modified, but still running it through the transmit handlers to populate the control information. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e3d8ff533ee6..da557b0d0114 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1285,6 +1285,7 @@ static int __ieee80211_tx(struct ieee80211_local *local,
static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
{
struct sk_buff *skb = tx->skb;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
ieee80211_tx_result res = TX_DROP;
#define CALL_TXH(txh) \
@@ -1299,9 +1300,13 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
CALL_TXH(ieee80211_tx_h_ps_buf);
CALL_TXH(ieee80211_tx_h_select_key);
CALL_TXH(ieee80211_tx_h_sta);
- CALL_TXH(ieee80211_tx_h_michael_mic_add);
if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL))
CALL_TXH(ieee80211_tx_h_rate_ctrl);
+
+ if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION))
+ goto txh_done;
+
+ CALL_TXH(ieee80211_tx_h_michael_mic_add);
CALL_TXH(ieee80211_tx_h_sequence);
CALL_TXH(ieee80211_tx_h_fragment);
/* handlers after fragment must be aware of tx info fragmentation! */