Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+31 −25
Original line number Diff line number Diff line
@@ -1231,27 +1231,32 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
		if (local->queue_stop_reasons[q] ||
		    (!txpending && !skb_queue_empty(&local->pending[q]))) {
			if (unlikely(info->flags &
					IEEE80211_TX_INTFL_OFFCHAN_TX_OK &&
				     local->queue_stop_reasons[q] &
					~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL))) {
				     IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) {
				if (local->queue_stop_reasons[q] &
				    ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL)) {
					/*
				 * Drop off-channel frames if queues are stopped
				 * for any reason other than off-channel
				 * operation. Never queue them.
					 * Drop off-channel frames if queues
					 * are stopped for any reason other
					 * than off-channel operation. Never
					 * queue them.
					 */
					spin_unlock_irqrestore(
					&local->queue_stop_reason_lock, flags);
				ieee80211_purge_tx_queue(&local->hw, skbs);
						&local->queue_stop_reason_lock,
						flags);
					ieee80211_purge_tx_queue(&local->hw,
								 skbs);
					return true;
				}
			} else {

				/*
			 * Since queue is stopped, queue up frames for later
			 * transmission from the tx-pending tasklet when the
			 * queue is woken again.
				 * Since queue is stopped, queue up frames for
				 * later transmission from the tx-pending
				 * tasklet when the queue is woken again.
				 */
				if (txpending)
				skb_queue_splice_init(skbs, &local->pending[q]);
					skb_queue_splice_init(skbs,
							      &local->pending[q]);
				else
					skb_queue_splice_tail_init(skbs,
								   &local->pending[q]);
@@ -1260,6 +1265,7 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
						       flags);
				return false;
			}
		}
		spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);

		info->control.vif = vif;