|
@@ -117,8 +117,8 @@ static void free_sta_work(struct work_struct *wk)
|
|
|
|
|
|
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
|
|
|
local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
|
|
|
- __skb_queue_purge(&sta->ps_tx_buf[ac]);
|
|
|
- __skb_queue_purge(&sta->tx_filtered[ac]);
|
|
|
+ ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]);
|
|
|
+ ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]);
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_MAC80211_MESH
|
|
@@ -141,7 +141,7 @@ static void free_sta_work(struct work_struct *wk)
|
|
|
tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
|
|
|
if (!tid_tx)
|
|
|
continue;
|
|
|
- __skb_queue_purge(&tid_tx->pending);
|
|
|
+ ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending);
|
|
|
kfree(tid_tx);
|
|
|
}
|
|
|
|
|
@@ -961,6 +961,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
|
|
|
struct ieee80211_local *local = sdata->local;
|
|
|
struct sk_buff_head pending;
|
|
|
int filtered = 0, buffered = 0, ac;
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
clear_sta_flag(sta, WLAN_STA_SP);
|
|
|
|
|
@@ -976,12 +977,16 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
|
|
|
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
|
|
|
int count = skb_queue_len(&pending), tmp;
|
|
|
|
|
|
+ spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags);
|
|
|
skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending);
|
|
|
+ spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags);
|
|
|
tmp = skb_queue_len(&pending);
|
|
|
filtered += tmp - count;
|
|
|
count = tmp;
|
|
|
|
|
|
+ spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags);
|
|
|
skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending);
|
|
|
+ spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags);
|
|
|
tmp = skb_queue_len(&pending);
|
|
|
buffered += tmp - count;
|
|
|
}
|