Patchwork [3.5.y.z,extended,stable] Patch "rt2x00: fix stop queue" has been added to staging queue

mail settings
Submitter Luis Henriques
Date Aug. 4, 2013, 9:49 a.m.
Message ID <>
Download mbox | patch
Permalink /patch/264504/
State New
Headers show


Luis Henriques - Aug. 4, 2013, 9:49 a.m.
This is a note to let you know that I have just added a patch titled

    rt2x00: fix stop queue

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see



From 5b7a49f4569e2f100d33307a448d1a59b1bc603c Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <>
Date: Sun, 28 Jul 2013 13:17:22 +0200
Subject: [PATCH] rt2x00: fix stop queue

commit e2288b66fe7ff0288382b2af671b4da558b44472 upstream.

Since we clear QUEUE_STARTED in rt2x00queue_stop_queue(), following
call to rt2x00queue_pause_queue() reduce to noop, i.e we do not
stop queue in mac80211.

To fix that introduce rt2x00queue_pause_queue_nocheck() function,
which will stop queue in mac80211 directly.

Note that rt2x00_start_queue() explicitly set QUEUE_PAUSED bit.

Note also that reordering operations i.e. first call to
rt2x00queue_pause_queue() and then clear QUEUE_STARTED bit, will race
with rt2x00queue_unpause_queue(), so calling ieee80211_stop_queue()
directly is the only available solution to fix the problem without
major rework.

Signed-off-by: Stanislaw Gruszka <>
Signed-off-by: John W. Linville <>
Signed-off-by: Luis Henriques <>
 drivers/net/wireless/rt2x00/rt2x00queue.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)



diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 2fd8301..6d0c651 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -877,13 +877,8 @@  void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index)
 	spin_unlock_irqrestore(&queue->index_lock, irqflags);

-void rt2x00queue_pause_queue(struct data_queue *queue)
+void rt2x00queue_pause_queue_nocheck(struct data_queue *queue)
-	if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
-	    !test_bit(QUEUE_STARTED, &queue->flags) ||
-	    test_and_set_bit(QUEUE_PAUSED, &queue->flags))
-		return;
 	switch (queue->qid) {
 	case QID_AC_VO:
 	case QID_AC_VI:
@@ -899,6 +894,15 @@  void rt2x00queue_pause_queue(struct data_queue *queue)
+void rt2x00queue_pause_queue(struct data_queue *queue)
+	if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
+	    !test_bit(QUEUE_STARTED, &queue->flags) ||
+	    test_and_set_bit(QUEUE_PAUSED, &queue->flags))
+		return;
+	rt2x00queue_pause_queue_nocheck(queue);

 void rt2x00queue_unpause_queue(struct data_queue *queue)
@@ -960,7 +964,7 @@  void rt2x00queue_stop_queue(struct data_queue *queue)

-	rt2x00queue_pause_queue(queue);
+	rt2x00queue_pause_queue_nocheck(queue);