aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/rt2x00/024-rt2800-partially-restore-old-mmio-txstatus-behaviour.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/rt2x00/024-rt2800-partially-restore-old-mmio-txstatus-behaviour.patch')
-rw-r--r--package/kernel/mac80211/patches/rt2x00/024-rt2800-partially-restore-old-mmio-txstatus-behaviour.patch128
1 files changed, 128 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/rt2x00/024-rt2800-partially-restore-old-mmio-txstatus-behaviour.patch b/package/kernel/mac80211/patches/rt2x00/024-rt2800-partially-restore-old-mmio-txstatus-behaviour.patch
new file mode 100644
index 0000000000..52314a79ae
--- /dev/null
+++ b/package/kernel/mac80211/patches/rt2x00/024-rt2800-partially-restore-old-mmio-txstatus-behaviour.patch
@@ -0,0 +1,128 @@
+From 91a5340db0526b7263bc8da14b120ea3129b5f28 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Sat, 9 Feb 2019 12:08:31 +0100
+X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
+X-Patchwork-Id: 10804437
+X-Patchwork-Delegate: kvalo@adurom.com
+Subject: [PATCH 21/28] rt2800: partially restore old mmio txstatus behaviour
+
+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 coused by
+0b0d556e0ebb ("rt2800mmio: use txdone/txstatus routines from lib").
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ .../net/wireless/ralink/rt2x00/rt2800lib.c | 4 +--
+ .../net/wireless/ralink/rt2x00/rt2800lib.h | 2 +-
+ .../net/wireless/ralink/rt2x00/rt2800mmio.c | 30 +++++--------------
+ .../net/wireless/ralink/rt2x00/rt2800usb.c | 2 +-
+ 4 files changed, 12 insertions(+), 26 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -1100,7 +1100,7 @@ void rt2800_txdone_entry(struct queue_en
+ }
+ 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 *rt
+ 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 .
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+@@ -195,7 +195,7 @@ void rt2800_process_rxwi(struct queue_en
+
+ 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);
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
+@@ -255,20 +255,6 @@ void rt2800mmio_autowake_tasklet(unsigne
+ }
+ 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(unsigne
+ {
+ 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
+ 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_
+ */
+ 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);
+ }
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+@@ -480,7 +480,7 @@ static void rt2800usb_work_txdone(struct
+ while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) ||
+ rt2800_txstatus_timeout(rt2x00dev)) {
+
+- rt2800_txdone(rt2x00dev);
++ rt2800_txdone(rt2x00dev, UINT_MAX);
+
+ rt2800_txdone_nostatus(rt2x00dev);
+