aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-tx.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-10-24 02:48:49 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-10-31 19:02:23 -0400
commit3fd07a1e5aba89d4be3696c46cb7297f1873195a (patch)
tree48a6c3b68e30136af93c48d35bd1ce08a9237c4d /drivers/net/wireless/iwlwifi/iwl-tx.c
parent8b30b1fe368ab03049435884c11c5c50e4c4ef0b (diff)
iwlwifi: refactor TX response flow
This patch utilize 5000 new TX response command which contains all necessary information and avoids back referencing to the original TX frame. It also change handling of software queue tracking 4965 flow is aligned with changes as much as possible. Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Reviewed-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-tx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c39
1 files changed, 20 insertions, 19 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 6cf4a7c428dd..cfa78260c594 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -895,9 +895,9 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
895 priv->stations[sta_id].tid[tid].tfds_in_queue++; 895 priv->stations[sta_id].tid[tid].tfds_in_queue++;
896 } 896 }
897 897
898 /* Descriptor for chosen Tx queue */
899 txq = &priv->txq[txq_id]; 898 txq = &priv->txq[txq_id];
900 q = &txq->q; 899 q = &txq->q;
900 txq->swq_id = swq_id;
901 901
902 spin_lock_irqsave(&priv->lock, flags); 902 spin_lock_irqsave(&priv->lock, flags);
903 903
@@ -1023,7 +1023,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
1023 iwl_txq_update_write_ptr(priv, txq); 1023 iwl_txq_update_write_ptr(priv, txq);
1024 spin_unlock_irqrestore(&priv->lock, flags); 1024 spin_unlock_irqrestore(&priv->lock, flags);
1025 } else { 1025 } else {
1026 ieee80211_stop_queue(priv->hw, swq_id); 1026 ieee80211_stop_queue(priv->hw, txq->swq_id);
1027 } 1027 }
1028 } 1028 }
1029 1029
@@ -1395,8 +1395,8 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id)
1395 case IWL_EMPTYING_HW_QUEUE_DELBA: 1395 case IWL_EMPTYING_HW_QUEUE_DELBA:
1396 /* We are reclaiming the last packet of the */ 1396 /* We are reclaiming the last packet of the */
1397 /* aggregated HW queue */ 1397 /* aggregated HW queue */
1398 if (txq_id == tid_data->agg.txq_id && 1398 if ((txq_id == tid_data->agg.txq_id) &&
1399 q->read_ptr == q->write_ptr) { 1399 (q->read_ptr == q->write_ptr)) {
1400 u16 ssn = SEQ_TO_SN(tid_data->seq_number); 1400 u16 ssn = SEQ_TO_SN(tid_data->seq_number);
1401 int tx_fifo = default_tid_to_tx_fifo[tid]; 1401 int tx_fifo = default_tid_to_tx_fifo[tid];
1402 IWL_DEBUG_HT("HW queue empty: continue DELBA flow\n"); 1402 IWL_DEBUG_HT("HW queue empty: continue DELBA flow\n");
@@ -1447,7 +1447,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1447 IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl); 1447 IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
1448 1448
1449 /* Calculate shift to align block-ack bits with our Tx window bits */ 1449 /* Calculate shift to align block-ack bits with our Tx window bits */
1450 sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl>>4); 1450 sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4);
1451 if (sh < 0) /* tbw something is wrong with indices */ 1451 if (sh < 0) /* tbw something is wrong with indices */
1452 sh += 0x100; 1452 sh += 0x100;
1453 1453
@@ -1497,9 +1497,11 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1497{ 1497{
1498 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 1498 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
1499 struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; 1499 struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
1500 int index;
1501 struct iwl_tx_queue *txq = NULL; 1500 struct iwl_tx_queue *txq = NULL;
1502 struct iwl_ht_agg *agg; 1501 struct iwl_ht_agg *agg;
1502 int index;
1503 int sta_id;
1504 int tid;
1503 1505
1504 /* "flow" corresponds to Tx queue */ 1506 /* "flow" corresponds to Tx queue */
1505 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); 1507 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
@@ -1514,14 +1516,16 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1514 } 1516 }
1515 1517
1516 txq = &priv->txq[scd_flow]; 1518 txq = &priv->txq[scd_flow];
1517 agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg; 1519 sta_id = ba_resp->sta_id;
1520 tid = ba_resp->tid;
1521 agg = &priv->stations[sta_id].tid[tid].agg;
1518 1522
1519 /* Find index just before block-ack window */ 1523 /* Find index just before block-ack window */
1520 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); 1524 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
1521 1525
1522 /* TODO: Need to get this copy more safely - now good for debug */ 1526 /* TODO: Need to get this copy more safely - now good for debug */
1523 1527
1524 IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %pM, " 1528 IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d] Received from %pM, "
1525 "sta_id = %d\n", 1529 "sta_id = %d\n",
1526 agg->wait_for_ba, 1530 agg->wait_for_ba,
1527 (u8 *) &ba_resp->sta_addr_lo32, 1531 (u8 *) &ba_resp->sta_addr_lo32,
@@ -1545,18 +1549,15 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1545 * transmitted ... if not, it's too late anyway). */ 1549 * transmitted ... if not, it's too late anyway). */
1546 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { 1550 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
1547 /* calculate mac80211 ampdu sw queue to wake */ 1551 /* calculate mac80211 ampdu sw queue to wake */
1548 int ampdu_q =
1549 scd_flow - priv->hw_params.first_ampdu_q + priv->hw->queues;
1550 int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); 1552 int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
1551 priv->stations[ba_resp->sta_id]. 1553 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
1552 tid[ba_resp->tid].tfds_in_queue -= freed; 1554
1553 if (iwl_queue_space(&txq->q) > txq->q.low_mark && 1555 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1554 priv->mac80211_registered && 1556 priv->mac80211_registered &&
1555 agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) 1557 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
1556 ieee80211_wake_queue(priv->hw, ampdu_q); 1558 ieee80211_wake_queue(priv->hw, txq->swq_id);
1557 1559
1558 iwl_txq_check_empty(priv, ba_resp->sta_id, 1560 iwl_txq_check_empty(priv, sta_id, tid, scd_flow);
1559 ba_resp->tid, scd_flow);
1560 } 1561 }
1561} 1562}
1562EXPORT_SYMBOL(iwl_rx_reply_compressed_ba); 1563EXPORT_SYMBOL(iwl_rx_reply_compressed_ba);