summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2012-02-01 15:01:32 (GMT)
committerJohn W. Linville <linville@tuxdriver.com>2012-02-01 20:26:00 (GMT)
commit3d29dd9b5b160ba4542a9b8f869a220559e633a0 (patch)
tree300ef96f8681c3b853686b11b04062f3045860f2 /drivers/net/wireless/iwlwifi/iwl-agn-tx.c
parenta6c84622b7fa3ea5417a9d1d0ce0bc3e7fbe3be1 (diff)
downloadlinux-fsl-qoriq-3d29dd9b5b160ba4542a9b8f869a220559e633a0.tar.xz
iwlwifi: don't mess up QoS counters with non-QoS frames
In my AMPDU rework, I rely on the sequence numbers of frames. But I didn't check that the frame has a valid tid before updating the tracking counters. As a result, the Tx queues were stalled. People who hit this bug saw that we simply didn't let any data out. This bug was introduced in 3.3. This patch fixes that and checks that the frame is a QoS frame before looking at its tid and changing the counters. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-tx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 339e8d9..63bbc60 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -91,6 +91,7 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
tx_cmd->tid_tspec = qc[0] & 0xf;
tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
} else {
+ tx_cmd->tid_tspec = IWL_TID_NON_QOS;
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
else
@@ -808,6 +809,8 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
u32 status = le16_to_cpu(tx_resp->status.status);
int i;
+ WARN_ON(tid == IWL_TID_NON_QOS);
+
if (agg->wait_for_ba)
IWL_DEBUG_TX_REPLY(priv,
"got tx response w/o block-ack\n");
@@ -1035,10 +1038,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
}
__skb_queue_head_init(&skbs);
- priv->tid_data[sta_id][tid].next_reclaimed = next_reclaimed;
- IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d",
- next_reclaimed);
+ if (tid != IWL_TID_NON_QOS) {
+ priv->tid_data[sta_id][tid].next_reclaimed =
+ next_reclaimed;
+ IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d",
+ next_reclaimed);
+ }
/*we can free until ssn % q.n_bd not inclusive */
WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id,