Commit 24047e2c authored by Christian Lamparter's avatar Christian Lamparter Committed by John W. Linville

carl9170: 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
carl9170 should set IEEE80211_TX_STAT_AMPDU_NO_BACK to generate a
BlockAckReq if the transmission of an AMPDU subframe fails.

This fixes aggregation problems with Intel 5100 Windows STAs (and maybe
others as well).
Signed-off-by: default avatarChristian Lamparter <chunkeey@googlemail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 0263aa45
...@@ -443,6 +443,7 @@ struct carl9170_ba_stats { ...@@ -443,6 +443,7 @@ struct carl9170_ba_stats {
u8 ampdu_len; u8 ampdu_len;
u8 ampdu_ack_len; u8 ampdu_ack_len;
bool clear; bool clear;
bool req;
}; };
struct carl9170_sta_info { struct carl9170_sta_info {
......
...@@ -1355,6 +1355,7 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, ...@@ -1355,6 +1355,7 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw,
tid_info = rcu_dereference(sta_info->agg[tid]); tid_info = rcu_dereference(sta_info->agg[tid]);
sta_info->stats[tid].clear = true; sta_info->stats[tid].clear = true;
sta_info->stats[tid].req = false;
if (tid_info) { if (tid_info) {
bitmap_zero(tid_info->bitmap, CARL9170_BAW_SIZE); bitmap_zero(tid_info->bitmap, CARL9170_BAW_SIZE);
......
...@@ -383,6 +383,7 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, ...@@ -383,6 +383,7 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
if (sta_info->stats[tid].clear) { if (sta_info->stats[tid].clear) {
sta_info->stats[tid].clear = false; sta_info->stats[tid].clear = false;
sta_info->stats[tid].req = false;
sta_info->stats[tid].ampdu_len = 0; sta_info->stats[tid].ampdu_len = 0;
sta_info->stats[tid].ampdu_ack_len = 0; sta_info->stats[tid].ampdu_ack_len = 0;
} }
...@@ -391,10 +392,16 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, ...@@ -391,10 +392,16 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
if (txinfo->status.rates[0].count == 1) if (txinfo->status.rates[0].count == 1)
sta_info->stats[tid].ampdu_ack_len++; sta_info->stats[tid].ampdu_ack_len++;
if (!(txinfo->flags & IEEE80211_TX_STAT_ACK))
sta_info->stats[tid].req = true;
if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) { if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) {
super->s.rix = sta_info->stats[tid].ampdu_len; super->s.rix = sta_info->stats[tid].ampdu_len;
super->s.cnt = sta_info->stats[tid].ampdu_ack_len; super->s.cnt = sta_info->stats[tid].ampdu_ack_len;
txinfo->flags |= IEEE80211_TX_STAT_AMPDU; txinfo->flags |= IEEE80211_TX_STAT_AMPDU;
if (sta_info->stats[tid].req)
txinfo->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
sta_info->stats[tid].clear = true; sta_info->stats[tid].clear = true;
} }
spin_unlock_bh(&tid_info->lock); spin_unlock_bh(&tid_info->lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment