rt2x00: Fix TX_STA_FIFO handling
authorHelmut Schaa <helmut.schaa@googlemail.com>
Mon, 14 Jun 2010 20:11:09 +0000 (22:11 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 15 Jun 2010 20:00:50 +0000 (16:00 -0400)
Currently rt2800pci will read TX_STA_FIFO until the previously read value
matches the current value. However, it is obvious that TX_STA_FIFO only
contains values that can easily be the same for multiple consecutive frames
(especially when communicating with only one other STA). Hence, we often
ended up with reading only the first entry and ignoring the rest.

One result was that when the TX_STA_FIFO contained multiple entires, only
the first one was read and properly handled while the others remained in the
tx queue.

Thus, drop this check but introduce a maximum number of reads. All legacy
drivers use the size of the tx ring as limit but state that the TX_STA_FIFO
has only 16 entries. So, let's just stick with the tx ring size for now.

Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/rt2x00/rt2800pci.c

index eeecedb..e870366 100644 (file)
@@ -813,29 +813,24 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
        struct txdone_entry_desc txdesc;
        u32 word;
        u32 reg;
-       u32 old_reg;
        int wcid, ack, pid, tx_wcid, tx_ack, tx_pid;
        u16 mcs, real_mcs;
+       int i;
 
        /*
-        * During each loop we will compare the freshly read
-        * TX_STA_FIFO register value with the value read from
-        * the previous loop. If the 2 values are equal then
-        * we should stop processing because the chance it
-        * quite big that the device has been unplugged and
-        * we risk going into an endless loop.
+        * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO
+        * at most X times and also stop processing once the TX_STA_FIFO_VALID
+        * flag is not set anymore.
+        *
+        * The legacy drivers use X=TX_RING_SIZE but state in a comment
+        * that the TX_STA_FIFO stack has a size of 16. We stick to our
+        * tx ring size for now.
         */
-       old_reg = 0;
-
-       while (1) {
+       for (i = 0; i < TX_ENTRIES; i++) {
                rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
                if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
                        break;
 
-               if (old_reg == reg)
-                       break;
-               old_reg = reg;
-
                wcid    = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
                ack     = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
                pid     = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);