mirror of https://gitee.com/openkylin/linux.git
iwlwifi: make TX seqno validation more efficient
Accessing the device in Tx path is not a good idea. Mirror the data in DRAM. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
8eb3871076
commit
68972c46f2
|
@ -217,6 +217,7 @@ struct iwl_pcie_txq_scratch_buf {
|
||||||
* @trans_pcie: pointer back to transport (for timer)
|
* @trans_pcie: pointer back to transport (for timer)
|
||||||
* @need_update: indicates need to update read/write index
|
* @need_update: indicates need to update read/write index
|
||||||
* @active: stores if queue is active
|
* @active: stores if queue is active
|
||||||
|
* @ampdu: true if this queue is an ampdu queue for an specific RA/TID
|
||||||
*
|
*
|
||||||
* A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
|
* A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
|
||||||
* descriptors) and required locking structures.
|
* descriptors) and required locking structures.
|
||||||
|
@ -232,6 +233,7 @@ struct iwl_txq {
|
||||||
struct iwl_trans_pcie *trans_pcie;
|
struct iwl_trans_pcie *trans_pcie;
|
||||||
u8 need_update;
|
u8 need_update;
|
||||||
u8 active;
|
u8 active;
|
||||||
|
bool ampdu;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline dma_addr_t
|
static inline dma_addr_t
|
||||||
|
|
|
@ -1073,6 +1073,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
|
||||||
|
|
||||||
/* enable aggregations for the queue */
|
/* enable aggregations for the queue */
|
||||||
iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
|
iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
|
||||||
|
trans_pcie->txq[txq_id].ampdu = true;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* disable aggregations for the queue, this will also make the
|
* disable aggregations for the queue, this will also make the
|
||||||
|
@ -1129,6 +1130,7 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
|
||||||
ARRAY_SIZE(zero_val));
|
ARRAY_SIZE(zero_val));
|
||||||
|
|
||||||
iwl_pcie_txq_unmap(trans, txq_id);
|
iwl_pcie_txq_unmap(trans, txq_id);
|
||||||
|
trans_pcie->txq[txq_id].ampdu = false;
|
||||||
|
|
||||||
IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
|
IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
|
||||||
}
|
}
|
||||||
|
@ -1599,7 +1601,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||||
u8 wait_write_ptr = 0;
|
u8 wait_write_ptr = 0;
|
||||||
__le16 fc = hdr->frame_control;
|
__le16 fc = hdr->frame_control;
|
||||||
u8 hdr_len = ieee80211_hdrlen(fc);
|
u8 hdr_len = ieee80211_hdrlen(fc);
|
||||||
u16 __maybe_unused wifi_seq;
|
u16 wifi_seq;
|
||||||
|
|
||||||
txq = &trans_pcie->txq[txq_id];
|
txq = &trans_pcie->txq[txq_id];
|
||||||
q = &txq->q;
|
q = &txq->q;
|
||||||
|
@ -1616,13 +1618,11 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||||
* the BA.
|
* the BA.
|
||||||
* Check here that the packets are in the right place on the ring.
|
* Check here that the packets are in the right place on the ring.
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
|
||||||
wifi_seq = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
|
wifi_seq = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
|
||||||
WARN_ONCE((iwl_read_prph(trans, SCD_AGGR_SEL) & BIT(txq_id)) &&
|
WARN_ONCE(trans_pcie->txq[txq_id].ampdu &&
|
||||||
((wifi_seq & 0xff) != q->write_ptr),
|
(wifi_seq & 0xff) != q->write_ptr,
|
||||||
"Q: %d WiFi Seq %d tfdNum %d",
|
"Q: %d WiFi Seq %d tfdNum %d",
|
||||||
txq_id, wifi_seq, q->write_ptr);
|
txq_id, wifi_seq, q->write_ptr);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Set up driver data for this TFD */
|
/* Set up driver data for this TFD */
|
||||||
txq->entries[q->write_ptr].skb = skb;
|
txq->entries[q->write_ptr].skb = skb;
|
||||||
|
|
Loading…
Reference in New Issue