diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2008-10-24 02:48:49 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-10-31 19:02:23 -0400 |
commit | 3fd07a1e5aba89d4be3696c46cb7297f1873195a (patch) | |
tree | 48a6c3b68e30136af93c48d35bd1ce08a9237c4d /drivers/net/wireless/iwlwifi/iwl-tx.c | |
parent | 8b30b1fe368ab03049435884c11c5c50e4c4ef0b (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.c | 39 |
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 | } |
1562 | EXPORT_SYMBOL(iwl_rx_reply_compressed_ba); | 1563 | EXPORT_SYMBOL(iwl_rx_reply_compressed_ba); |