rt2800: partially restore old mmio txstatus behaviour
authorStanislaw Gruszka <sgruszka@redhat.com>
Wed, 27 Mar 2019 09:58:24 +0000 (10:58 +0100)
committerKalle Valo <kvalo@codeaurora.org>
Thu, 25 Apr 2019 16:43:03 +0000 (19:43 +0300)
Do not disable txstatus interrupt and add quota of processed tx statuses in
one tasklet. Quota is needed to allow to fed device with new frames during
processing of tx statuses.

Patch fixes about 15% performance degradation on some scenarios caused by
0b0d556e0ebb ("rt2800mmio: use txdone/txstatus routines from lib").

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ralink/rt2x00/rt2800lib.c
drivers/net/wireless/ralink/rt2x00/rt2800lib.h
drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
drivers/net/wireless/ralink/rt2x00/rt2800usb.c

index a03b5284a050952448f806d3e74cc164bea5a4a1..635aa67295291eedd53bf01faeabb2204157dc13 100644 (file)
@@ -1100,7 +1100,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
 }
 EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
 
-void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
+void rt2800_txdone(struct rt2x00_dev *rt2x00dev, unsigned int quota)
 {
        struct data_queue *queue;
        struct queue_entry *entry;
@@ -1108,7 +1108,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
        u8 qid;
        bool match;
 
-       while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
+       while (quota-- > 0 && kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
                /*
                 * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is
                 * guaranteed to be one of the TX QIDs .
index 0dff2c7b30105133122f60cac3417153f5eecc68..506c319070dd839493bbf395ec2076e3290f7713 100644 (file)
@@ -195,7 +195,7 @@ void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *tx
 
 void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
                         bool match);
-void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
+void rt2800_txdone(struct rt2x00_dev *rt2x00dev, unsigned int quota);
 void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev);
 bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev);
 
index ddb88cfeace21816c5490fba5a1f07b8a1787d6d..f7635a47dbcde3105f0be01e65380ca00a4a65c0 100644 (file)
@@ -255,20 +255,6 @@ void rt2800mmio_autowake_tasklet(unsigned long data)
 }
 EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet);
 
-static void rt2800mmio_txdone(struct rt2x00_dev *rt2x00dev)
-{
-       bool timeout = false;
-
-       while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) ||
-              (timeout = rt2800_txstatus_timeout(rt2x00dev))) {
-
-               rt2800_txdone(rt2x00dev);
-
-               if (timeout)
-                       rt2800_txdone_nostatus(rt2x00dev);
-       }
-}
-
 static bool rt2800mmio_fetch_txstatus(struct rt2x00_dev *rt2x00dev)
 {
        u32 status;
@@ -305,14 +291,11 @@ void rt2800mmio_txstatus_tasklet(unsigned long data)
 {
        struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
 
-       do {
-               rt2800mmio_txdone(rt2x00dev);
+       rt2800_txdone(rt2x00dev, 16);
 
-       } while (rt2800mmio_fetch_txstatus(rt2x00dev));
+       if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo))
+               tasklet_schedule(&rt2x00dev->txstatus_tasklet);
 
-       if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
-               rt2800mmio_enable_interrupt(rt2x00dev,
-                                           INT_SOURCE_CSR_TX_FIFO_STATUS);
 }
 EXPORT_SYMBOL_GPL(rt2800mmio_txstatus_tasklet);
 
@@ -339,8 +322,10 @@ irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance)
        mask = ~reg;
 
        if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) {
+               rt2x00_set_field32(&mask, INT_MASK_CSR_TX_FIFO_STATUS, 1);
                rt2800mmio_fetch_txstatus(rt2x00dev);
-               tasklet_schedule(&rt2x00dev->txstatus_tasklet);
+               if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo))
+                       tasklet_schedule(&rt2x00dev->txstatus_tasklet);
        }
 
        if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT))
@@ -500,7 +485,8 @@ void rt2800mmio_flush_queue(struct data_queue *queue, bool drop)
                 */
                if (tx_queue) {
                        tasklet_disable(&rt2x00dev->txstatus_tasklet);
-                       rt2800mmio_txdone(rt2x00dev);
+                       rt2800_txdone(rt2x00dev, UINT_MAX);
+                       rt2800_txdone_nostatus(rt2x00dev);
                        tasklet_enable(&rt2x00dev->txstatus_tasklet);
                }
 
index 091a607334bf72f1c34403f873f88a5888045f3e..9d1e73b642a83db454bfd0cd056191566a7b88e4 100644 (file)
@@ -480,7 +480,7 @@ static void rt2800usb_work_txdone(struct work_struct *work)
        while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) ||
               rt2800_txstatus_timeout(rt2x00dev)) {
 
-               rt2800_txdone(rt2x00dev);
+               rt2800_txdone(rt2x00dev, UINT_MAX);
 
                rt2800_txdone_nostatus(rt2x00dev);