aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2012-07-04 07:10:02 -0400
committerLuis Henriques <luis.henriques@canonical.com>2012-07-23 05:50:31 -0400
commitbabf7ddc991e4c7d735be6e8bc607864e1366f89 (patch)
tree6227741daa2fb965a84503b51b3672e45b46e1fe
parent9ada357d838e02b5ea399ed637889e5ebb2436cc (diff)
rt2x00usb: fix indexes ordering on RX queue kick
BugLink: http://bugs.launchpad.net/bugs/1026850 commit efd821182cec8c92babef6e00a95066d3252fda4 upstream. On rt2x00_dmastart() we increase index specified by Q_INDEX and on rt2x00_dmadone() we increase index specified by Q_INDEX_DONE. So entries between Q_INDEX_DONE and Q_INDEX are those we currently process in the hardware. Entries between Q_INDEX and Q_INDEX_DONE are those we can submit to the hardware. According to that fix rt2x00usb_kick_queue(), as we need to submit RX entries that are not processed by the hardware. It worked before only for empty queue, otherwise was broken. Note that for TX queues indexes ordering are ok. We need to kick entries that have filled skb, but was not submitted to the hardware, i.e. started from Q_INDEX_DONE and have ENTRY_DATA_PENDING bit set. From practical standpoint this fixes RX queue stall, usually reproducible in AP mode, like for example reported here: https://bugzilla.redhat.com/show_bug.cgi?id=828824 Reported-and-tested-by: Franco Miceli <fmiceli@plan.ceibal.edu.uy> Reported-and-tested-by: Tom Horsley <horsley1953@gmail.com> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com>
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 54f0b1345fc..99fa4161440 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -426,8 +426,8 @@ void rt2x00usb_kick_queue(struct data_queue *queue)
426 case QID_RX: 426 case QID_RX:
427 if (!rt2x00queue_full(queue)) 427 if (!rt2x00queue_full(queue))
428 rt2x00queue_for_each_entry(queue, 428 rt2x00queue_for_each_entry(queue,
429 Q_INDEX_DONE,
430 Q_INDEX, 429 Q_INDEX,
430 Q_INDEX_DONE,
431 NULL, 431 NULL,
432 rt2x00usb_kick_rx_entry); 432 rt2x00usb_kick_rx_entry);
433 break; 433 break;