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 | } |
