forked from Minki/linux
mt76: implement processing of BlockAckReq frames
Avoids timeouts on reordered A-MPDU rx frames
Fixes: aee5b8cf24
("mt76: implement A-MPDU rx reordering in the driver code")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
d71ef28636
commit
17cf68b702
@ -113,6 +113,33 @@ mt76_rx_aggr_reorder_work(struct work_struct *work)
|
|||||||
local_bh_enable();
|
local_bh_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mt76_rx_aggr_check_ctl(struct sk_buff *skb, struct sk_buff_head *frames)
|
||||||
|
{
|
||||||
|
struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
|
||||||
|
struct ieee80211_bar *bar = (struct ieee80211_bar *) skb->data;
|
||||||
|
struct mt76_wcid *wcid = status->wcid;
|
||||||
|
struct mt76_rx_tid *tid;
|
||||||
|
u16 seqno;
|
||||||
|
|
||||||
|
if (!ieee80211_is_ctl(bar->frame_control))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!ieee80211_is_back_req(bar->frame_control))
|
||||||
|
return;
|
||||||
|
|
||||||
|
status->tid = le16_to_cpu(bar->control) >> 12;
|
||||||
|
seqno = le16_to_cpu(bar->start_seq_num) >> 4;
|
||||||
|
tid = rcu_dereference(wcid->aggr[status->tid]);
|
||||||
|
if (!tid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
spin_lock_bh(&tid->lock);
|
||||||
|
mt76_rx_aggr_release_frames(tid, frames, seqno);
|
||||||
|
mt76_rx_aggr_release_head(tid, frames);
|
||||||
|
spin_unlock_bh(&tid->lock);
|
||||||
|
}
|
||||||
|
|
||||||
void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
|
void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
|
||||||
{
|
{
|
||||||
struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
|
struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
|
||||||
@ -126,9 +153,14 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
|
|||||||
__skb_queue_tail(frames, skb);
|
__skb_queue_tail(frames, skb);
|
||||||
|
|
||||||
sta = wcid_to_sta(wcid);
|
sta = wcid_to_sta(wcid);
|
||||||
if (!sta || !status->aggr)
|
if (!sta)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!status->aggr) {
|
||||||
|
mt76_rx_aggr_check_ctl(skb, frames);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tid = rcu_dereference(wcid->aggr[status->tid]);
|
tid = rcu_dereference(wcid->aggr[status->tid]);
|
||||||
if (!tid)
|
if (!tid)
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user