mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 13:26:48 +00:00
tx: send BAR after a sta waking up from PS
Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
@@ -400,6 +400,11 @@ mt76_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
{
|
||||
struct mt76_dev *dev = hw->priv;
|
||||
struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv;
|
||||
struct ieee80211_txq *txq = sta->txq[tid];
|
||||
struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv;
|
||||
|
||||
if (!txq)
|
||||
return -EINVAL;
|
||||
|
||||
switch (action) {
|
||||
case IEEE80211_AMPDU_RX_START:
|
||||
@@ -409,13 +414,13 @@ mt76_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx)+4, BIT(16 + tid));
|
||||
break;
|
||||
case IEEE80211_AMPDU_TX_OPERATIONAL:
|
||||
ieee80211_send_bar(vif, sta->addr, tid, msta->agg_ssn[tid]);
|
||||
ieee80211_send_bar(vif, sta->addr, tid, cpu_to_le16(mtxq->agg_ssn));
|
||||
break;
|
||||
case IEEE80211_AMPDU_TX_STOP_FLUSH:
|
||||
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
|
||||
break;
|
||||
case IEEE80211_AMPDU_TX_START:
|
||||
msta->agg_ssn[tid] = *ssn << 4;
|
||||
mtxq->agg_ssn = *ssn << 4;
|
||||
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
||||
break;
|
||||
case IEEE80211_AMPDU_TX_STOP_CONT:
|
||||
|
||||
@@ -210,7 +210,6 @@ struct mt76_vif {
|
||||
|
||||
struct mt76_sta {
|
||||
struct mt76_wcid wcid;
|
||||
u16 agg_ssn[IEEE80211_NUM_TIDS];
|
||||
|
||||
u32 status;
|
||||
int n_frames;
|
||||
@@ -222,6 +221,9 @@ struct mt76_txq {
|
||||
struct mt76_queue *hwq;
|
||||
|
||||
struct sk_buff_head retry_q;
|
||||
|
||||
u16 agg_ssn;
|
||||
bool send_bar;
|
||||
};
|
||||
|
||||
struct mt76_reg_pair {
|
||||
|
||||
@@ -187,6 +187,7 @@ static struct sk_buff *
|
||||
mt76_txq_dequeue(struct mt76_dev *dev, struct mt76_txq *mtxq, bool ps)
|
||||
{
|
||||
struct ieee80211_txq *txq = mtxq_to_txq(mtxq);
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = skb_dequeue(&mtxq->retry_q);
|
||||
@@ -199,7 +200,14 @@ mt76_txq_dequeue(struct mt76_dev *dev, struct mt76_txq *mtxq, bool ps)
|
||||
return skb;
|
||||
}
|
||||
|
||||
return ieee80211_tx_dequeue(dev->hw, txq);
|
||||
skb = ieee80211_tx_dequeue(dev->hw, txq);
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
hdr = (struct ieee80211_hdr *) skb->data;
|
||||
mtxq->agg_ssn = le16_to_cpu(hdr->seq_ctrl) + 0x10;
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -358,6 +366,17 @@ mt76_txq_schedule_list(struct mt76_dev *dev, struct mt76_queue *hwq)
|
||||
break;
|
||||
|
||||
mtxq = list_first_entry(&hwq->swq, struct mt76_txq, list);
|
||||
if (mtxq->send_bar) {
|
||||
struct ieee80211_txq *txq = mtxq_to_txq(mtxq);
|
||||
|
||||
mtxq->send_bar = false;
|
||||
spin_unlock_bh(&hwq->lock);
|
||||
ieee80211_send_bar(txq->vif, txq->sta->addr, txq->tid,
|
||||
mtxq->agg_ssn);
|
||||
spin_lock_bh(&hwq->lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
list_del_init(&mtxq->list);
|
||||
|
||||
cur = mt76_txq_send_burst(dev, hwq, mtxq, &empty);
|
||||
@@ -409,6 +428,7 @@ mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta)
|
||||
struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv;
|
||||
|
||||
spin_lock_bh(&mtxq->hwq->lock);
|
||||
mtxq->send_bar = true;
|
||||
if (!list_empty(&mtxq->list))
|
||||
list_del_init(&mtxq->list);
|
||||
spin_unlock_bh(&mtxq->hwq->lock);
|
||||
|
||||
Reference in New Issue
Block a user