Commit a120e912eb51e347f36c71b60a1d13af74d30e83

Authored by Stanislaw Gruszka
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 }