Commit a7679ed5 authored by Seth Forshee's avatar Seth Forshee Committed by Johannes Berg

mac80211: Ensure off-channel frames don't get queued

Commit 6c17b77b (mac80211: Fix tx queue
handling during scans) contains a bug that causes off-channel frames to
get queued when they should be handed down to the driver for transmit.
Prevent this from happening.
Reported-by: default avatarFabio Rossi <rossi.f@inwind.it>
Signed-off-by: default avatarSeth Forshee <seth.forshee@canonical.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 163df6cf
...@@ -1231,27 +1231,32 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local, ...@@ -1231,27 +1231,32 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
if (local->queue_stop_reasons[q] || if (local->queue_stop_reasons[q] ||
(!txpending && !skb_queue_empty(&local->pending[q]))) { (!txpending && !skb_queue_empty(&local->pending[q]))) {
if (unlikely(info->flags & if (unlikely(info->flags &
IEEE80211_TX_INTFL_OFFCHAN_TX_OK && IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) {
local->queue_stop_reasons[q] & if (local->queue_stop_reasons[q] &
~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL))) { ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL)) {
/* /*
* Drop off-channel frames if queues are stopped * Drop off-channel frames if queues
* for any reason other than off-channel * are stopped for any reason other
* operation. Never queue them. * than off-channel operation. Never
* queue them.
*/ */
spin_unlock_irqrestore( spin_unlock_irqrestore(
&local->queue_stop_reason_lock, flags); &local->queue_stop_reason_lock,
ieee80211_purge_tx_queue(&local->hw, skbs); flags);
ieee80211_purge_tx_queue(&local->hw,
skbs);
return true; return true;
} }
} else {
/* /*
* Since queue is stopped, queue up frames for later * Since queue is stopped, queue up frames for
* transmission from the tx-pending tasklet when the * later transmission from the tx-pending
* queue is woken again. * tasklet when the queue is woken again.
*/ */
if (txpending) if (txpending)
skb_queue_splice_init(skbs, &local->pending[q]); skb_queue_splice_init(skbs,
&local->pending[q]);
else else
skb_queue_splice_tail_init(skbs, skb_queue_splice_tail_init(skbs,
&local->pending[q]); &local->pending[q]);
...@@ -1260,6 +1265,7 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local, ...@@ -1260,6 +1265,7 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
flags); flags);
return false; return false;
} }
}
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
info->control.vif = vif; info->control.vif = vif;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment