aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-tx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 00da5e152d46..8f4071562857 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)
120EXPORT_SYMBOL(iwl_txq_update_write_ptr); 120EXPORT_SYMBOL(iwl_txq_update_write_ptr);
121 121
122 122
123void 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}
135EXPORT_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.
@@ -407,13 +421,14 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
407 int txq_id; 421 int txq_id;
408 422
409 /* Tx queues */ 423 /* Tx queues */
410 if (priv->txq) 424 if (priv->txq) {
411 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; 425 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
412 txq_id++) 426 txq_id++)
413 if (txq_id == IWL_CMD_QUEUE_NUM) 427 if (txq_id == IWL_CMD_QUEUE_NUM)
414 iwl_cmd_queue_free(priv); 428 iwl_cmd_queue_free(priv);
415 else 429 else
416 iwl_tx_queue_free(priv, txq_id); 430 iwl_tx_queue_free(priv, txq_id);
431 }
417 iwl_free_dma_ptr(priv, &priv->kw); 432 iwl_free_dma_ptr(priv, &priv->kw);
418 433
419 iwl_free_dma_ptr(priv, &priv->scd_bc_tbls); 434 iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
@@ -1130,6 +1145,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
1130 struct iwl_queue *q = &txq->q; 1145 struct iwl_queue *q = &txq->q;
1131 struct iwl_tx_info *tx_info; 1146 struct iwl_tx_info *tx_info;
1132 int nfreed = 0; 1147 int nfreed = 0;
1148 struct ieee80211_hdr *hdr;
1133 1149
1134 if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { 1150 if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
1135 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, "
@@ -1144,13 +1160,16 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
1144 1160
1145 tx_info = &txq->txb[txq->q.read_ptr]; 1161 tx_info = &txq->txb[txq->q.read_ptr];
1146 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++;
1147 tx_info->skb[0] = NULL; 1167 tx_info->skb[0] = NULL;
1148 1168
1149 if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) 1169 if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
1150 priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq); 1170 priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
1151 1171
1152 priv->cfg->ops->lib->txq_free_tfd(priv, txq); 1172 priv->cfg->ops->lib->txq_free_tfd(priv, txq);
1153 nfreed++;
1154 } 1173 }
1155 return nfreed; 1174 return nfreed;
1156} 1175}
@@ -1558,7 +1577,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1558 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { 1577 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
1559 /* calculate mac80211 ampdu sw queue to wake */ 1578 /* calculate mac80211 ampdu sw queue to wake */
1560 int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); 1579 int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
1561 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 1580 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
1562 1581
1563 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) && 1582 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1564 priv->mac80211_registered && 1583 priv->mac80211_registered &&