Commit a120e912eb51e347f36c71b60a1d13af74d30e83
Committed by
John W. Linville
1 parent
a239a8b47c
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>
Showing 2 changed files with 7 additions and 5 deletions Side-by-side Diff
drivers/net/wireless/iwlwifi/iwl-5000.c
... | ... | @@ -1153,16 +1153,14 @@ |
1153 | 1153 | tx_resp->failure_frame); |
1154 | 1154 | |
1155 | 1155 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
1156 | - if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) | |
1157 | - iwl_free_tfds_in_queue(priv, sta_id, tid, freed); | |
1156 | + iwl_free_tfds_in_queue(priv, sta_id, tid, freed); | |
1158 | 1157 | |
1159 | 1158 | if (priv->mac80211_registered && |
1160 | 1159 | (iwl_queue_space(&txq->q) > txq->q.low_mark)) |
1161 | 1160 | iwl_wake_queue(priv, txq_id); |
1162 | 1161 | } |
1163 | 1162 | |
1164 | - if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) | |
1165 | - iwl_txq_check_empty(priv, sta_id, tid, txq_id); | |
1163 | + iwl_txq_check_empty(priv, sta_id, tid, txq_id); | |
1166 | 1164 | |
1167 | 1165 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) |
1168 | 1166 | IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); |
drivers/net/wireless/iwlwifi/iwl-tx.c
... | ... | @@ -1145,6 +1145,7 @@ |
1145 | 1145 | struct iwl_queue *q = &txq->q; |
1146 | 1146 | struct iwl_tx_info *tx_info; |
1147 | 1147 | int nfreed = 0; |
1148 | + struct ieee80211_hdr *hdr; | |
1148 | 1149 | |
1149 | 1150 | if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { |
1150 | 1151 | IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " |
1151 | 1152 | |
... | ... | @@ -1159,13 +1160,16 @@ |
1159 | 1160 | |
1160 | 1161 | tx_info = &txq->txb[txq->q.read_ptr]; |
1161 | 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 | 1167 | tx_info->skb[0] = NULL; |
1163 | 1168 | |
1164 | 1169 | if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) |
1165 | 1170 | priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq); |
1166 | 1171 | |
1167 | 1172 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); |
1168 | - nfreed++; | |
1169 | 1173 | } |
1170 | 1174 | return nfreed; |
1171 | 1175 | } |