diff options
author | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2010-02-19 18:47:32 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-02-22 11:15:50 -0500 |
commit | a239a8b47cc0e5e6d7416a89f340beac06d5edaa (patch) | |
tree | 1001bd0ec9f66cdc6a056f9373297bff327933eb /drivers/net/wireless/iwlwifi | |
parent | 5e2f75b8993a0d83d469388b50716dd5551f2eb4 (diff) |
iwlwifi: error checking for number of tfds in queue
When receive reply_tx and ready to decrement the count for number of
tfds in queue, do error checking to prevent error condition and
tfds_in_queue become negative number.
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
CC: stable@kernel.org
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 16 |
4 files changed, 20 insertions, 4 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 9b4b8b5c7574..31462813bac0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -2008,7 +2008,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2008 | IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " | 2008 | IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " |
2009 | "%d index %d\n", scd_ssn , index); | 2009 | "%d index %d\n", scd_ssn , index); |
2010 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); | 2010 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
2011 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 2011 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); |
2012 | 2012 | ||
2013 | if (priv->mac80211_registered && | 2013 | if (priv->mac80211_registered && |
2014 | (iwl_queue_space(&txq->q) > txq->q.low_mark) && | 2014 | (iwl_queue_space(&txq->q) > txq->q.low_mark) && |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index de45f308b744..f27c514886a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -1125,7 +1125,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1125 | scd_ssn , index, txq_id, txq->swq_id); | 1125 | scd_ssn , index, txq_id, txq->swq_id); |
1126 | 1126 | ||
1127 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); | 1127 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
1128 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 1128 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); |
1129 | 1129 | ||
1130 | if (priv->mac80211_registered && | 1130 | if (priv->mac80211_registered && |
1131 | (iwl_queue_space(&txq->q) > txq->q.low_mark) && | 1131 | (iwl_queue_space(&txq->q) > txq->q.low_mark) && |
@@ -1154,7 +1154,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1154 | 1154 | ||
1155 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); | 1155 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
1156 | if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) | 1156 | if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) |
1157 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 1157 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); |
1158 | 1158 | ||
1159 | if (priv->mac80211_registered && | 1159 | if (priv->mac80211_registered && |
1160 | (iwl_queue_space(&txq->q) > txq->q.low_mark)) | 1160 | (iwl_queue_space(&txq->q) > txq->q.low_mark)) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 675b7df632fc..fe37d6a6bf97 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -446,6 +446,8 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv); | |||
446 | int iwl_hw_tx_queue_init(struct iwl_priv *priv, | 446 | int iwl_hw_tx_queue_init(struct iwl_priv *priv, |
447 | struct iwl_tx_queue *txq); | 447 | struct iwl_tx_queue *txq); |
448 | int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); | 448 | int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
449 | void iwl_free_tfds_in_queue(struct iwl_priv *priv, | ||
450 | int sta_id, int tid, int freed); | ||
449 | int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, | 451 | int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, |
450 | int slots_num, u32 txq_id); | 452 | int slots_num, u32 txq_id); |
451 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); | 453 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 87ce2bd292c7..72136c8f51da 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -120,6 +120,20 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) | |||
120 | EXPORT_SYMBOL(iwl_txq_update_write_ptr); | 120 | EXPORT_SYMBOL(iwl_txq_update_write_ptr); |
121 | 121 | ||
122 | 122 | ||
123 | void iwl_free_tfds_in_queue(struct iwl_priv *priv, | ||
124 | int sta_id, int tid, int freed) | ||
125 | { | ||
126 | if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) | ||
127 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | ||
128 | else { | ||
129 | IWL_ERR(priv, "free more than tfds_in_queue (%u:%d)\n", | ||
130 | priv->stations[sta_id].tid[tid].tfds_in_queue, | ||
131 | freed); | ||
132 | priv->stations[sta_id].tid[tid].tfds_in_queue = 0; | ||
133 | } | ||
134 | } | ||
135 | EXPORT_SYMBOL(iwl_free_tfds_in_queue); | ||
136 | |||
123 | /** | 137 | /** |
124 | * iwl_tx_queue_free - Deallocate DMA queue. | 138 | * iwl_tx_queue_free - Deallocate DMA queue. |
125 | * @txq: Transmit queue to deallocate. | 139 | * @txq: Transmit queue to deallocate. |
@@ -1559,7 +1573,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1559 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { | 1573 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { |
1560 | /* calculate mac80211 ampdu sw queue to wake */ | 1574 | /* calculate mac80211 ampdu sw queue to wake */ |
1561 | int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); | 1575 | int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); |
1562 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 1576 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); |
1563 | 1577 | ||
1564 | if ((iwl_queue_space(&txq->q) > txq->q.low_mark) && | 1578 | if ((iwl_queue_space(&txq->q) > txq->q.low_mark) && |
1565 | priv->mac80211_registered && | 1579 | priv->mac80211_registered && |