diff options
author | Shanyu Zhao <shanyu.zhao@intel.com> | 2010-06-01 17:13:58 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-02 10:30:18 -0700 |
commit | 8483d9b94a15bae1dd9bcd03ef84726ec6a03536 (patch) | |
tree | d9eae1a62767f90f994b3b80a6087617b8e97af5 /drivers | |
parent | caf785bc19966cedc0ba3ee43526e0af43bd001a (diff) |
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 5 |
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 c243df77a83a..ca3053801638 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -1635,6 +1635,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); |