diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2010-02-19 18:47:33 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-02-22 11:15:50 -0500 |
commit | a120e912eb51e347f36c71b60a1d13af74d30e83 (patch) | |
tree | d07795748f9ccbd53958f24671fab60eb8c1bf48 | |
parent | a239a8b47cc0e5e6d7416a89f340beac06d5edaa (diff) |
iwlwifi: sanity check before counting number of tfds can be free
Check the frame control for ieee80211_is_data_qos() is true before
counting the number of tfds can be free, the tfds_in_queue only
increment when ieee80211_is_data_qos() is true before transmit; so it
should only decrement if the type match.
Remove ieee80211_is_data_qos check for frame_ctrl in tx_resp to avoid
invalid information pass from uCode.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
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>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 6 |
2 files changed, 7 insertions, 5 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index f27c514886a5..cffaae772d51 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -1153,16 +1153,14 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1153 | tx_resp->failure_frame); | 1153 | tx_resp->failure_frame); |
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 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); |
1157 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); | ||
1158 | 1157 | ||
1159 | if (priv->mac80211_registered && | 1158 | if (priv->mac80211_registered && |
1160 | (iwl_queue_space(&txq->q) > txq->q.low_mark)) | 1159 | (iwl_queue_space(&txq->q) > txq->q.low_mark)) |
1161 | iwl_wake_queue(priv, txq_id); | 1160 | iwl_wake_queue(priv, txq_id); |
1162 | } | 1161 | } |
1163 | 1162 | ||
1164 | if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) | 1163 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); |
1165 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | ||
1166 | 1164 | ||
1167 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 1165 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) |
1168 | IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); | 1166 | IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 72136c8f51da..8f4071562857 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -1145,6 +1145,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | |||
1145 | struct iwl_queue *q = &txq->q; | 1145 | struct iwl_queue *q = &txq->q; |
1146 | struct iwl_tx_info *tx_info; | 1146 | struct iwl_tx_info *tx_info; |
1147 | int nfreed = 0; | 1147 | int nfreed = 0; |
1148 | struct ieee80211_hdr *hdr; | ||
1148 | 1149 | ||
1149 | if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { | 1150 | if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { |
1150 | IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " | 1151 | IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " |
@@ -1159,13 +1160,16 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | |||
1159 | 1160 | ||
1160 | tx_info = &txq->txb[txq->q.read_ptr]; | 1161 | tx_info = &txq->txb[txq->q.read_ptr]; |
1161 | iwl_tx_status(priv, tx_info->skb[0]); | 1162 | iwl_tx_status(priv, tx_info->skb[0]); |
1163 | |||
1164 | hdr = (struct ieee80211_hdr *)tx_info->skb[0]->data; | ||
1165 | if (hdr && ieee80211_is_data_qos(hdr->frame_control)) | ||
1166 | nfreed++; | ||
1162 | tx_info->skb[0] = NULL; | 1167 | tx_info->skb[0] = NULL; |
1163 | 1168 | ||
1164 | if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) | 1169 | if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) |
1165 | priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq); | 1170 | priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq); |
1166 | 1171 | ||
1167 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); | 1172 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); |
1168 | nfreed++; | ||
1169 | } | 1173 | } |
1170 | return nfreed; | 1174 | return nfreed; |
1171 | } | 1175 | } |