summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShanyu Zhao <shanyu.zhao@intel.com>2010-06-01 17:13:58 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-02 10:26:49 -0700
commitcf50b2cde07046a88a19d5ef100421be7efc4e5a (patch)
tree9598cb33abca9fb72d4220534851f5dbb4805153
parentbcc8f887cba250b5b6f3d9d783f1d137cd4374b4 (diff)
downloadlwn-cf50b2cde07046a88a19d5ef100421be7efc4e5a.tar.gz
lwn-cf50b2cde07046a88a19d5ef100421be7efc4e5a.zip
iwlagn: verify flow id in compressed BA packet
commit b561e8274f75831ee87e4ea378cbb1f9f050a51a upstream. The flow id (scd_flow) in a compressed BA packet should match the txq_id of the queue from which the aggregated packets were sent. However, in some hardware like the 1000 series, sometimes the flow id is 0 for the txq_id (10 to 19). This can cause the annoying message: [ 2213.306191] iwlagn 0000:01:00.0: Received BA when not expected [ 2213.310178] iwlagn 0000:01:00.0: Read index for DMA queue txq id (0), index 5, is out of range [0-256] 7 7. And even worse, if agg->wait_for_ba is true when the bad BA is arriving, this can cause system hang due to NULL pointer dereference because the code is operating in a wrong tx queue! Signed-off-by: Shanyu Zhao <shanyu.zhao@intel.com> Signed-off-by: Pradeep Kulkarni <pradeepx.kulkarni@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index e0ce039d9300..2f531210b581 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1553,6 +1553,11 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
sta_id = ba_resp->sta_id;
tid = ba_resp->tid;
agg = &priv->stations[sta_id].tid[tid].agg;
+ if (unlikely(agg->txq_id != scd_flow)) {
+ IWL_ERR(priv, "BA scd_flow %d does not match txq_id %d\n",
+ scd_flow, agg->txq_id);
+ return;
+ }
/* Find index just before block-ack window */
index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);