|
@@ -478,6 +478,20 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
|
|
|
sta->sta.addr, sta->sta.aid, ac);
|
|
|
if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
|
|
|
purge_old_ps_buffers(tx->local);
|
|
|
+
|
|
|
+ /* sync with ieee80211_sta_ps_deliver_wakeup */
|
|
|
+ spin_lock(&sta->ps_lock);
|
|
|
+ /*
|
|
|
+ * STA woke up the meantime and all the frames on ps_tx_buf have
|
|
|
+ * been queued to pending queue. No reordering can happen, go
|
|
|
+ * ahead and Tx the packet.
|
|
|
+ */
|
|
|
+ if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
|
|
|
+ !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
|
|
|
+ spin_unlock(&sta->ps_lock);
|
|
|
+ return TX_CONTINUE;
|
|
|
+ }
|
|
|
+
|
|
|
if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) {
|
|
|
struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]);
|
|
|
ps_dbg(tx->sdata,
|
|
@@ -492,6 +506,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
|
|
|
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
|
|
|
info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
|
|
|
skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb);
|
|
|
+ spin_unlock(&sta->ps_lock);
|
|
|
|
|
|
if (!timer_pending(&local->sta_cleanup))
|
|
|
mod_timer(&local->sta_cleanup,
|