PKG_NAME:=mac80211
PKG_VERSION:=4.19.23-1
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v4.19.23/
PKG_HASH:=703e940b542eb56067fcd847a7c69398dcc9829f34472647eea4211cb2ab3b83
--- /dev/null
+From f483039cf51acf30494cd754194562c22cf98764 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 22 Aug 2018 13:41:26 +0300
+Subject: [PATCH 01/28] rt2x00: use simple_read_from_buffer()
+
+The problem with this copy_to_user() calls is that they don't ensure
+that "size" is less than the "length" which the user provided.
+
+Obviously, this is debugfs and "size" is normally going to be very small
+so it probably doesn't matter, but this is the correct thing to do.
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../net/wireless/ralink/rt2x00/rt2x00debug.c | 18 +++---------------
+ 1 file changed, 3 insertions(+), 15 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
+@@ -464,11 +464,7 @@ static ssize_t rt2x00debug_read_##__name
+ \
+ size = sprintf(line, __format, value); \
+ \
+- if (copy_to_user(buf, line, size)) \
+- return -EFAULT; \
+- \
+- *offset += size; \
+- return size; \
++ return simple_read_from_buffer(buf, length, offset, line, size); \
+ }
+
+ #define RT2X00DEBUGFS_OPS_WRITE(__name, __type) \
+@@ -545,11 +541,7 @@ static ssize_t rt2x00debug_read_dev_flag
+
+ size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->flags);
+
+- if (copy_to_user(buf, line, size))
+- return -EFAULT;
+-
+- *offset += size;
+- return size;
++ return simple_read_from_buffer(buf, length, offset, line, size);
+ }
+
+ static const struct file_operations rt2x00debug_fop_dev_flags = {
+@@ -574,11 +566,7 @@ static ssize_t rt2x00debug_read_cap_flag
+
+ size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->cap_flags);
+
+- if (copy_to_user(buf, line, size))
+- return -EFAULT;
+-
+- *offset += size;
+- return size;
++ return simple_read_from_buffer(buf, length, offset, line, size);
+ }
+
+ static const struct file_operations rt2x00debug_fop_cap_flags = {
-From 0381bfbc400ce4c3000b0b31c577ad9e8071e4f6 Mon Sep 17 00:00:00 2001
+From 5c656c71b1bf5611ce8262bab338104e04d10b8d Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
-Date: Fri, 18 May 2018 12:25:08 +0200
-Subject: [PATCH 1/5] rt2800: move usb specific txdone/txstatus routines to
+Date: Wed, 26 Sep 2018 12:24:53 +0200
+Subject: [PATCH 02/28] rt2800: move usb specific txdone/txstatus routines to
rt2800lib
In order to reuse usb txdone/txstatus routines for mmio, move them
to common rt2800lib.c file.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../net/wireless/ralink/rt2x00/rt2800lib.c | 138 +++++++++++++++++
.../net/wireless/ralink/rt2x00/rt2800lib.h | 3 +
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -960,6 +960,47 @@ static void rt2800_rate_from_status(stru
+@@ -957,6 +957,47 @@ static void rt2800_rate_from_status(stru
skbdesc->tx_rate_flags = flags;
}
void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
bool match)
{
-@@ -1062,6 +1103,103 @@ void rt2800_txdone_entry(struct queue_en
+@@ -1059,6 +1100,103 @@ void rt2800_txdone_entry(struct queue_en
}
EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
{
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
-@@ -206,6 +206,9 @@ void rt2800_process_rxwi(struct queue_en
+@@ -195,6 +195,9 @@ void rt2800_process_rxwi(struct queue_en
void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
bool match);
-From 7993486bbab17f8916993710a8660eb47fd991e9 Mon Sep 17 00:00:00 2001
+From 0b0d556e0ebb6c966bc993e21a22a156812d8fdf Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
-Date: Mon, 9 Jul 2018 16:07:42 +0200
-Subject: [PATCH 2/5] rt2800mmio: use txdone/txstatus routines from lib
+Date: Wed, 26 Sep 2018 12:24:54 +0200
+Subject: [PATCH 03/28] rt2800mmio: use txdone/txstatus routines from lib
Use usb txdone/txstatus routines (now in rt2800libc) for mmio devices.
patch where I also implement read status FIFO register in the tasklet.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../net/wireless/ralink/rt2x00/rt2800mmio.c | 180 +-----------------
.../net/wireless/ralink/rt2x00/rt2x00queue.c | 1 +
-From b5d6e37ea15949a126907050d8cfa4408153a0cd Mon Sep 17 00:00:00 2001
+From 5022efb50f625d11fdf18b1fee0f64ebb1863664 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
-Date: Fri, 18 May 2018 12:25:10 +0200
-Subject: [PATCH 3/5] rt2x00: do not check for txstatus timeout every time on
+Date: Wed, 26 Sep 2018 12:24:55 +0200
+Subject: [PATCH 04/28] rt2x00: do not check for txstatus timeout every time on
tasklet
Do not check for tx status timeout everytime we perform txstatus tasklet.
Perform check once per half a second.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 7 +++++++
drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 3 ++-
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -1161,11 +1161,18 @@ bool rt2800_txstatus_timeout(struct rt2x
+@@ -1158,11 +1158,18 @@ bool rt2800_txstatus_timeout(struct rt2x
struct data_queue *queue;
struct queue_entry *entry;
rt2800mmio_enable_interrupt(rt2x00dev,
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-@@ -988,6 +988,8 @@ struct rt2x00_dev {
+@@ -980,6 +980,8 @@ struct rt2x00_dev {
*/
DECLARE_KFIFO_PTR(txstatus_fifo, u32);
-From feb87977b6d251fb01a329905719e45908f6c939 Mon Sep 17 00:00:00 2001
+From adf26a356f132e35093585521ea3e36cd185af83 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
-Date: Fri, 10 Aug 2018 12:31:55 +0200
-Subject: [PATCH 4/5] rt2x00: use different txstatus timeouts when flushing
+Date: Wed, 26 Sep 2018 12:24:56 +0200
+Subject: [PATCH 05/28] rt2x00: use different txstatus timeouts when flushing
Use different tx status timeouts for normal operation and when flushing.
This increase timeout to 2s for normal operation as when there are bad
on such bad conditions.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../net/wireless/ralink/rt2x00/rt2800lib.c | 31 +++++++++++++------
drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 +
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -1140,36 +1140,47 @@ void rt2800_txdone(struct rt2x00_dev *rt
+@@ -1137,36 +1137,47 @@ void rt2800_txdone(struct rt2x00_dev *rt
}
EXPORT_SYMBOL_GPL(rt2800_txdone);
return true;
}
-@@ -1198,7 +1209,7 @@ void rt2800_txdone_nostatus(struct rt2x0
+@@ -1195,7 +1206,7 @@ void rt2800_txdone_nostatus(struct rt2x0
break;
if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) ||
break;
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-@@ -667,6 +667,7 @@ enum rt2x00_state_flags {
+@@ -665,6 +665,7 @@ enum rt2x00_state_flags {
DEVICE_STATE_STARTED,
DEVICE_STATE_ENABLED_RADIO,
DEVICE_STATE_SCANNING,
-From 0d9fbb738a5eadc7abc8060f43ebcc71f6324c07 Mon Sep 17 00:00:00 2001
+From 0240564430c0697d8fde3743d70346a922466b36 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
-Date: Tue, 14 Aug 2018 08:58:48 +0200
-Subject: [PATCH 5/5] rt2800: flush and txstatus rework for rt2800mmio
+Date: Wed, 26 Sep 2018 12:24:57 +0200
+Subject: [PATCH 06/28] rt2800: flush and txstatus rework for rt2800mmio
Implement custom rt2800mmio flush routine and change txstatus
routine to read TX_STA_FIFO also in the tasklet.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
- .../net/wireless/ralink/rt2x00/rt2800lib.c | 14 +-
- .../net/wireless/ralink/rt2x00/rt2800mmio.c | 120 +++++++++++++-----
+ .../net/wireless/ralink/rt2x00/rt2800lib.c | 14 +--
+ .../net/wireless/ralink/rt2x00/rt2800mmio.c | 118 +++++++++++++-----
.../net/wireless/ralink/rt2x00/rt2800mmio.h | 1 +
.../net/wireless/ralink/rt2x00/rt2800pci.c | 2 +-
- 4 files changed, 99 insertions(+), 38 deletions(-)
+ 4 files changed, 97 insertions(+), 38 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -1150,7 +1150,7 @@ static inline bool rt2800_entry_txstatus
+@@ -1147,7 +1147,7 @@ static inline bool rt2800_entry_txstatus
return false;
if (test_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags))
else
tout = msecs_to_jiffies(2000);
-@@ -1166,15 +1166,13 @@ bool rt2800_txstatus_timeout(struct rt2x
+@@ -1163,15 +1163,13 @@ bool rt2800_txstatus_timeout(struct rt2x
{
struct data_queue *queue;
struct queue_entry *entry;
if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT))
tasklet_hi_schedule(&rt2x00dev->pretbtt_tasklet);
-@@ -453,6 +466,55 @@ void rt2800mmio_kick_queue(struct data_q
+@@ -453,6 +466,53 @@ void rt2800mmio_kick_queue(struct data_q
}
EXPORT_SYMBOL_GPL(rt2800mmio_kick_queue);
+ bool tx_queue = false;
+ unsigned int i;
+
-+ //printk("FLUSH queue %d len %d drop %d\n", queue->qid, queue->length, drop);
-+
+ switch (queue->qid) {
+ case QID_AC_VO:
+ case QID_AC_VI:
+ tasklet_disable(&rt2x00dev->txstatus_tasklet);
+ rt2800mmio_txdone(rt2x00dev);
+ tasklet_enable(&rt2x00dev->txstatus_tasklet);
-+ }
++ }
+
+ /*
+ * Wait for a little while to give the driver
--- /dev/null
+From 6eba8fd2235237784dfd01da55c3210d493aebdb Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
+Date: Mon, 22 Oct 2018 22:44:34 +0200
+Subject: [PATCH 07/28] rt2x00: rt2400pci: mark expected switch fall-through
+
+In preparation to enabling -Wimplicit-fallthrough, mark switch cases
+where we are expecting to fall through.
+
+Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2400pci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
+@@ -1302,7 +1302,7 @@ static void rt2400pci_txdone(struct rt2x
+ break;
+ case 2: /* Failure, excessive retries */
+ __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags);
+- /* Don't break, this is a failed frame! */
++ /* Fall through - this is a failed frame! */
+ default: /* Failure */
+ __set_bit(TXDONE_FAILURE, &txdesc.flags);
+ }
--- /dev/null
+From 10bb92217747c3384a01ebec005faa2f5e72bbd8 Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
+Date: Mon, 22 Oct 2018 22:45:19 +0200
+Subject: [PATCH 08/28] rt2x00: rt2500pci: mark expected switch fall-through
+
+In preparation to enabling -Wimplicit-fallthrough, mark switch cases
+where we are expecting to fall through.
+
+Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2500pci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
+@@ -1430,7 +1430,7 @@ static void rt2500pci_txdone(struct rt2x
+ break;
+ case 2: /* Failure, excessive retries */
+ __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags);
+- /* Don't break, this is a failed frame! */
++ /* Fall through - this is a failed frame! */
+ default: /* Failure */
+ __set_bit(TXDONE_FAILURE, &txdesc.flags);
+ }
--- /dev/null
+From 916e6bbcfcff6cc5d7d33bba8557a30f3af50326 Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
+Date: Mon, 22 Oct 2018 22:46:03 +0200
+Subject: [PATCH 09/28] rt2x00: rt2800lib: mark expected switch fall-throughs
+
+In preparation to enabling -Wimplicit-fallthrough, mark switch cases
+where we are expecting to fall through.
+
+Addresses-Coverity-ID: 145198 ("Missing break in switch")
+Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -2482,6 +2482,7 @@ static void rt2800_config_channel_rf3052
+ switch (rt2x00dev->default_ant.tx_chain_num) {
+ case 1:
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
++ /* fall through */
+ case 2:
+ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
+ break;
+@@ -2490,6 +2491,7 @@ static void rt2800_config_channel_rf3052
+ switch (rt2x00dev->default_ant.rx_chain_num) {
+ case 1:
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
++ /* fall through */
+ case 2:
+ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
+ break;
+@@ -9457,8 +9459,10 @@ static int rt2800_probe_hw_mode(struct r
+ switch (rx_chains) {
+ case 3:
+ spec->ht.mcs.rx_mask[2] = 0xff;
++ /* fall through */
+ case 2:
+ spec->ht.mcs.rx_mask[1] = 0xff;
++ /* fall through */
+ case 1:
+ spec->ht.mcs.rx_mask[0] = 0xff;
+ spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */
--- /dev/null
+From 641dd8068ecb078e7d12efe465df202bc16ca5eb Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
+Date: Mon, 22 Oct 2018 22:46:47 +0200
+Subject: [PATCH 10/28] rt2x00: rt61pci: mark expected switch fall-through
+
+In preparation to enabling -Wimplicit-fallthrough, mark switch cases
+where we are expecting to fall through.
+
+Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt61pci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
+@@ -2226,7 +2226,7 @@ static void rt61pci_txdone(struct rt2x00
+ break;
+ case 6: /* Failure, excessive retries */
+ __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags);
+- /* Don't break, this is a failed frame! */
++ /* Fall through - this is a failed frame! */
+ default: /* Failure */
+ __set_bit(TXDONE_FAILURE, &txdesc.flags);
+ }
--- /dev/null
+From 750afb08ca71310fcf0c4e2cb1565c63b8235b60 Mon Sep 17 00:00:00 2001
+From: Luis Chamberlain <mcgrof@kernel.org>
+Date: Fri, 4 Jan 2019 09:23:09 +0100
+Subject: [PATCH 11/28] cross-tree: phase out dma_zalloc_coherent()
+
+We already need to zero out memory for dma_alloc_coherent(), as such
+using dma_zalloc_coherent() is superflous. Phase it out.
+
+This change was generated with the following Coccinelle SmPL patch:
+
+@ replace_dma_zalloc_coherent @
+expression dev, size, data, handle, flags;
+@@
+
+-dma_zalloc_coherent(dev, size, handle, flags)
++dma_alloc_coherent(dev, size, handle, flags)
+
+Suggested-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
+[hch: re-ran the script on the latest tree]
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00mmio.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.c
+@@ -119,9 +119,9 @@ static int rt2x00mmio_alloc_queue_dma(st
+ /*
+ * Allocate DMA memory for descriptor and buffer.
+ */
+- addr = dma_zalloc_coherent(rt2x00dev->dev,
+- queue->limit * queue->desc_size, &dma,
+- GFP_KERNEL);
++ addr = dma_alloc_coherent(rt2x00dev->dev,
++ queue->limit * queue->desc_size, &dma,
++ GFP_KERNEL);
+ if (!addr)
+ return -ENOMEM;
+
--- /dev/null
+From c2e28ef7711ffcb083474ee5f154264c6ec1ec07 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= <pozega.tomislav@gmail.com>
+Date: Thu, 27 Dec 2018 15:05:25 +0100
+Subject: [PATCH 12/28] rt2x00: reduce tx power to nominal level on RT6352
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Current implementation of RT6352 support provides too high tx power
+at least on iPA/eLNA devices. Reduce amplification of variable gain
+amplifier by 6dB to match board target power of 17dBm.
+Transmited signal strength with this patch is similar to that of
+stock firmware or pandorabox firmware. Throughput measured with iperf
+improves. Device tested: Xiaomi Miwifi Mini.
+
+Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -5477,7 +5477,7 @@ static int rt2800_init_registers(struct
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+ rt2800_register_write(rt2x00dev, MIMO_PS_CFG, 0x00000002);
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x00150F0F);
+- rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x06060606);
++ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000);
+ rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0);
+ rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0);
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C);
--- /dev/null
+From a4296994eb8061ee3455721a296c387c639bf635 Mon Sep 17 00:00:00 2001
+From: Bernd Edlinger <bernd.edlinger@hotmail.de>
+Date: Tue, 15 Jan 2019 14:01:29 +0000
+Subject: [PATCH 13/28] rt2x00: Work around a firmware bug with shared keys
+
+Apparently the rt2x61 firmware fails temporarily to decode
+broadcast packets if the shared keys are not assigned
+in the "correct" sequence. At the same time unicast
+packets work fine, since they are encrypted with the
+pairwise key.
+
+At least with WPA2 CCMP mode the shared keys are
+set in the following sequence: keyidx=1, 2, 1, 2.
+After a while only keyidx 2 gets decrypted, and
+keyidx 1 is ignored, probably because there is never
+a keyidx 3.
+
+Symptoms are arping -b works for 10 minutes, since
+keyidx=2 is used for broadcast, and then it stops
+working for 10 minutes, because keyidx=1 is used.
+That failure mode repeats forever.
+
+Note, the firmware does not even know which keyidx
+corresponds to which hw_key_idx so the firmware is
+trying to be smarter than the driver, which is bound
+to fail.
+
+As workaround the function rt61pci_config_shared_key
+requests software decryption of the shared keys,
+by returning EOPNOTSUPP. However, pairwise keys are
+still handled by hardware which works just fine.
+
+Signed-off-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
+Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt61pci.c | 93 +-------------------
+ 1 file changed, 4 insertions(+), 89 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
+@@ -321,97 +321,12 @@ static int rt61pci_config_shared_key(str
+ struct rt2x00lib_crypto *crypto,
+ struct ieee80211_key_conf *key)
+ {
+- struct hw_key_entry key_entry;
+- struct rt2x00_field32 field;
+- u32 mask;
+- u32 reg;
+-
+- if (crypto->cmd == SET_KEY) {
+- /*
+- * rt2x00lib can't determine the correct free
+- * key_idx for shared keys. We have 1 register
+- * with key valid bits. The goal is simple, read
+- * the register, if that is full we have no slots
+- * left.
+- * Note that each BSS is allowed to have up to 4
+- * shared keys, so put a mask over the allowed
+- * entries.
+- */
+- mask = (0xf << crypto->bssidx);
+-
+- reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR0);
+- reg &= mask;
+-
+- if (reg && reg == mask)
+- return -ENOSPC;
+-
+- key->hw_key_idx += reg ? ffz(reg) : 0;
+-
+- /*
+- * Upload key to hardware
+- */
+- memcpy(key_entry.key, crypto->key,
+- sizeof(key_entry.key));
+- memcpy(key_entry.tx_mic, crypto->tx_mic,
+- sizeof(key_entry.tx_mic));
+- memcpy(key_entry.rx_mic, crypto->rx_mic,
+- sizeof(key_entry.rx_mic));
+-
+- reg = SHARED_KEY_ENTRY(key->hw_key_idx);
+- rt2x00mmio_register_multiwrite(rt2x00dev, reg,
+- &key_entry, sizeof(key_entry));
+-
+- /*
+- * The cipher types are stored over 2 registers.
+- * bssidx 0 and 1 keys are stored in SEC_CSR1 and
+- * bssidx 1 and 2 keys are stored in SEC_CSR5.
+- * Using the correct defines correctly will cause overhead,
+- * so just calculate the correct offset.
+- */
+- if (key->hw_key_idx < 8) {
+- field.bit_offset = (3 * key->hw_key_idx);
+- field.bit_mask = 0x7 << field.bit_offset;
+-
+- reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR1);
+- rt2x00_set_field32(®, field, crypto->cipher);
+- rt2x00mmio_register_write(rt2x00dev, SEC_CSR1, reg);
+- } else {
+- field.bit_offset = (3 * (key->hw_key_idx - 8));
+- field.bit_mask = 0x7 << field.bit_offset;
+-
+- reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR5);
+- rt2x00_set_field32(®, field, crypto->cipher);
+- rt2x00mmio_register_write(rt2x00dev, SEC_CSR5, reg);
+- }
+-
+- /*
+- * The driver does not support the IV/EIV generation
+- * in hardware. However it doesn't support the IV/EIV
+- * inside the ieee80211 frame either, but requires it
+- * to be provided separately for the descriptor.
+- * rt2x00lib will cut the IV/EIV data out of all frames
+- * given to us by mac80211, but we must tell mac80211
+- * to generate the IV/EIV data.
+- */
+- key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+- }
+-
+ /*
+- * SEC_CSR0 contains only single-bit fields to indicate
+- * a particular key is valid. Because using the FIELD32()
+- * defines directly will cause a lot of overhead, we use
+- * a calculation to determine the correct bit directly.
++ * Let the software handle the shared keys,
++ * since the hardware decryption does not work reliably,
++ * because the firmware does not know the key's keyidx.
+ */
+- mask = 1 << key->hw_key_idx;
+-
+- reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR0);
+- if (crypto->cmd == SET_KEY)
+- reg |= mask;
+- else if (crypto->cmd == DISABLE_KEY)
+- reg &= ~mask;
+- rt2x00mmio_register_write(rt2x00dev, SEC_CSR0, reg);
+-
+- return 0;
++ return -EOPNOTSUPP;
+ }
+
+ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
--- /dev/null
+From 2587791d57588562c21e5ef7e678f02ab2f3eb82 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Tue, 22 Jan 2019 16:21:34 +0100
+Subject: [PATCH 14/28] rt2x00: no need to check return value of debugfs_create
+ functions
+
+When calling debugfs functions, there is no need to ever check the
+return value. The function can work or not, but the code logic should
+never do something different based on this.
+
+Cc: Stanislaw Gruszka <sgruszka@redhat.com>
+Cc: Helmut Schaa <helmut.schaa@googlemail.com>
+Cc: Kalle Valo <kvalo@codeaurora.org>
+Cc: linux-wireless@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../net/wireless/ralink/rt2x00/rt2x00debug.c | 27 -------------------
+ 1 file changed, 27 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
+@@ -656,36 +656,24 @@ void rt2x00debug_register(struct rt2x00_
+ intf->driver_folder =
+ debugfs_create_dir(intf->rt2x00dev->ops->name,
+ rt2x00dev->hw->wiphy->debugfsdir);
+- if (IS_ERR(intf->driver_folder) || !intf->driver_folder)
+- goto exit;
+
+ intf->driver_entry =
+ rt2x00debug_create_file_driver("driver", intf, &intf->driver_blob);
+- if (IS_ERR(intf->driver_entry) || !intf->driver_entry)
+- goto exit;
+
+ intf->chipset_entry =
+ rt2x00debug_create_file_chipset("chipset",
+ intf, &intf->chipset_blob);
+- if (IS_ERR(intf->chipset_entry) || !intf->chipset_entry)
+- goto exit;
+
+ intf->dev_flags = debugfs_create_file("dev_flags", 0400,
+ intf->driver_folder, intf,
+ &rt2x00debug_fop_dev_flags);
+- if (IS_ERR(intf->dev_flags) || !intf->dev_flags)
+- goto exit;
+
+ intf->cap_flags = debugfs_create_file("cap_flags", 0400,
+ intf->driver_folder, intf,
+ &rt2x00debug_fop_cap_flags);
+- if (IS_ERR(intf->cap_flags) || !intf->cap_flags)
+- goto exit;
+
+ intf->register_folder =
+ debugfs_create_dir("register", intf->driver_folder);
+- if (IS_ERR(intf->register_folder) || !intf->register_folder)
+- goto exit;
+
+ #define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name) \
+ ({ \
+@@ -695,9 +683,6 @@ void rt2x00debug_register(struct rt2x00_
+ 0600, \
+ (__intf)->register_folder, \
+ &(__intf)->offset_##__name); \
+- if (IS_ERR((__intf)->__name##_off_entry) || \
+- !(__intf)->__name##_off_entry) \
+- goto exit; \
+ \
+ (__intf)->__name##_val_entry = \
+ debugfs_create_file(__stringify(__name) "_value", \
+@@ -705,9 +690,6 @@ void rt2x00debug_register(struct rt2x00_
+ (__intf)->register_folder, \
+ (__intf), \
+ &rt2x00debug_fop_##__name); \
+- if (IS_ERR((__intf)->__name##_val_entry) || \
+- !(__intf)->__name##_val_entry) \
+- goto exit; \
+ } \
+ })
+
+@@ -721,15 +703,10 @@ void rt2x00debug_register(struct rt2x00_
+
+ intf->queue_folder =
+ debugfs_create_dir("queue", intf->driver_folder);
+- if (IS_ERR(intf->queue_folder) || !intf->queue_folder)
+- goto exit;
+
+ intf->queue_frame_dump_entry =
+ debugfs_create_file("dump", 0400, intf->queue_folder,
+ intf, &rt2x00debug_fop_queue_dump);
+- if (IS_ERR(intf->queue_frame_dump_entry)
+- || !intf->queue_frame_dump_entry)
+- goto exit;
+
+ skb_queue_head_init(&intf->frame_dump_skbqueue);
+ init_waitqueue_head(&intf->frame_dump_waitqueue);
+@@ -747,10 +724,6 @@ void rt2x00debug_register(struct rt2x00_
+ #endif
+
+ return;
+-
+-exit:
+- rt2x00debug_deregister(rt2x00dev);
+- rt2x00_err(rt2x00dev, "Failed to register debug handler\n");
+ }
+
+ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
--- /dev/null
+From 0bffbc98e6999bba38d8185a0ddb1ee77369eaec Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= <pozega.tomislav@gmail.com>
+Date: Wed, 13 Feb 2019 11:09:12 +0100
+Subject: [PATCH 15/28] rt2x00: remove unneeded check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Remove band check from rf53xx channel config routine since all chips
+using it are single band.
+
+Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ .../net/wireless/ralink/rt2x00/rt2800lib.c | 103 +++++++++---------
+ 1 file changed, 50 insertions(+), 53 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -2966,6 +2966,7 @@ static void rt2800_config_channel_rf53xx
+ struct channel_info *info)
+ {
+ u8 rfcsr;
++ int idx = rf->channel-1;
+
+ rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
+ rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3);
+@@ -3003,60 +3004,56 @@ static void rt2800_config_channel_rf53xx
+
+ rt2800_freq_cal_mode1(rt2x00dev);
+
+- if (rf->channel <= 14) {
+- int idx = rf->channel-1;
++ if (rt2x00_has_cap_bt_coexist(rt2x00dev)) {
++ if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
++ /* r55/r59 value array of channel 1~14 */
++ static const char r55_bt_rev[] = {0x83, 0x83,
++ 0x83, 0x73, 0x73, 0x63, 0x53, 0x53,
++ 0x53, 0x43, 0x43, 0x43, 0x43, 0x43};
++ static const char r59_bt_rev[] = {0x0e, 0x0e,
++ 0x0e, 0x0e, 0x0e, 0x0b, 0x0a, 0x09,
++ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07};
++
++ rt2800_rfcsr_write(rt2x00dev, 55,
++ r55_bt_rev[idx]);
++ rt2800_rfcsr_write(rt2x00dev, 59,
++ r59_bt_rev[idx]);
++ } else {
++ static const char r59_bt[] = {0x8b, 0x8b, 0x8b,
++ 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x89,
++ 0x88, 0x88, 0x86, 0x85, 0x84};
+
+- if (rt2x00_has_cap_bt_coexist(rt2x00dev)) {
+- if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
+- /* r55/r59 value array of channel 1~14 */
+- static const char r55_bt_rev[] = {0x83, 0x83,
+- 0x83, 0x73, 0x73, 0x63, 0x53, 0x53,
+- 0x53, 0x43, 0x43, 0x43, 0x43, 0x43};
+- static const char r59_bt_rev[] = {0x0e, 0x0e,
+- 0x0e, 0x0e, 0x0e, 0x0b, 0x0a, 0x09,
+- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07};
+-
+- rt2800_rfcsr_write(rt2x00dev, 55,
+- r55_bt_rev[idx]);
+- rt2800_rfcsr_write(rt2x00dev, 59,
+- r59_bt_rev[idx]);
+- } else {
+- static const char r59_bt[] = {0x8b, 0x8b, 0x8b,
+- 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x89,
+- 0x88, 0x88, 0x86, 0x85, 0x84};
++ rt2800_rfcsr_write(rt2x00dev, 59, r59_bt[idx]);
++ }
++ } else {
++ if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
++ static const char r55_nonbt_rev[] = {0x23, 0x23,
++ 0x23, 0x23, 0x13, 0x13, 0x03, 0x03,
++ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
++ static const char r59_nonbt_rev[] = {0x07, 0x07,
++ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
++ 0x07, 0x07, 0x06, 0x05, 0x04, 0x04};
++
++ rt2800_rfcsr_write(rt2x00dev, 55,
++ r55_nonbt_rev[idx]);
++ rt2800_rfcsr_write(rt2x00dev, 59,
++ r59_nonbt_rev[idx]);
++ } else if (rt2x00_rt(rt2x00dev, RT5390) ||
++ rt2x00_rt(rt2x00dev, RT5392) ||
++ rt2x00_rt(rt2x00dev, RT6352)) {
++ static const char r59_non_bt[] = {0x8f, 0x8f,
++ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d,
++ 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86};
++
++ rt2800_rfcsr_write(rt2x00dev, 59,
++ r59_non_bt[idx]);
++ } else if (rt2x00_rt(rt2x00dev, RT5350)) {
++ static const char r59_non_bt[] = {0x0b, 0x0b,
++ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a,
++ 0x0a, 0x09, 0x08, 0x07, 0x07, 0x06};
+
+- rt2800_rfcsr_write(rt2x00dev, 59, r59_bt[idx]);
+- }
+- } else {
+- if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
+- static const char r55_nonbt_rev[] = {0x23, 0x23,
+- 0x23, 0x23, 0x13, 0x13, 0x03, 0x03,
+- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
+- static const char r59_nonbt_rev[] = {0x07, 0x07,
+- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+- 0x07, 0x07, 0x06, 0x05, 0x04, 0x04};
+-
+- rt2800_rfcsr_write(rt2x00dev, 55,
+- r55_nonbt_rev[idx]);
+- rt2800_rfcsr_write(rt2x00dev, 59,
+- r59_nonbt_rev[idx]);
+- } else if (rt2x00_rt(rt2x00dev, RT5390) ||
+- rt2x00_rt(rt2x00dev, RT5392) ||
+- rt2x00_rt(rt2x00dev, RT6352)) {
+- static const char r59_non_bt[] = {0x8f, 0x8f,
+- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d,
+- 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86};
+-
+- rt2800_rfcsr_write(rt2x00dev, 59,
+- r59_non_bt[idx]);
+- } else if (rt2x00_rt(rt2x00dev, RT5350)) {
+- static const char r59_non_bt[] = {0x0b, 0x0b,
+- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a,
+- 0x0a, 0x09, 0x08, 0x07, 0x07, 0x06};
+-
+- rt2800_rfcsr_write(rt2x00dev, 59,
+- r59_non_bt[idx]);
+- }
++ rt2800_rfcsr_write(rt2x00dev, 59,
++ r59_non_bt[idx]);
+ }
+ }
+ }
--- /dev/null
+From dce31f739d4c901725a23c7939d7e04d4c2eacac Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= <pozega.tomislav@gmail.com>
+Date: Wed, 13 Feb 2019 11:09:13 +0100
+Subject: [PATCH 16/28] rt2x00: remove confusing AGC register
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Register 66 was causing issues on RT6352 if set to the same value as
+in MTK driver. With 1c reg value device was working fine in both HT20
+and HT40 modes.
+
+Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -3983,11 +3983,7 @@ static void rt2800_config_channel(struct
+ rt2800_bbp_write(rt2x00dev, 196, reg);
+
+ /* AGC init */
+- if (rt2x00_rt(rt2x00dev, RT6352))
+- reg = 0x04;
+- else
+- reg = rf->channel <= 14 ? 0x1c : 0x24;
+-
++ reg = rf->channel <= 14 ? 0x1c : 0x24;
+ reg += 2 * rt2x00dev->lna_gain;
+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
+
--- /dev/null
+From 9c9bf1af644ad16fca1fd601cfc3a2a2c6bbc58b Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 13 Feb 2019 11:09:14 +0100
+Subject: [PATCH 17/28] rt2800: enable TX_PIN_CFG_LNA_PE_ bits per band
+
+Do not enable TX_PIN_CFG_LNA_PE_A* bits for 2.4GHz band and
+vice versa TX_PIN_CFG_LNA_PE_G* bits for 5GHz.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -3893,18 +3893,24 @@ static void rt2800_config_channel(struct
+ switch (rt2x00dev->default_ant.rx_chain_num) {
+ case 3:
+ /* Turn on tertiary LNAs */
+- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN, 1);
+- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN, 1);
++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN,
++ rf->channel > 14);
++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN,
++ rf->channel <= 14);
+ /* fall-through */
+ case 2:
+ /* Turn on secondary LNAs */
+- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1);
+- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1);
++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN,
++ rf->channel > 14);
++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN,
++ rf->channel <= 14);
+ /* fall-through */
+ case 1:
+ /* Turn on primary LNAs */
+- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1);
+- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN,
++ rf->channel > 14);
++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN,
++ rf->channel <= 14);
+ break;
+ }
+
--- /dev/null
+From 4c0475ad8b73072b5b638163c2eb8309310406ed Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 13 Feb 2019 11:09:15 +0100
+Subject: [PATCH 18/28] rt2800: enable TX_PIN_CFG_RFRX_EN only for MT7620
+
+The TX_PIN_CFG_RFRX_EN bit was not set on other devices than MT7620,
+restore old behavaviour since setting this bit maight not be
+correct for older devices.
+
+Fixes: 41977e86c984 ("rt2x00: add support for MT7620")
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -3858,10 +3858,12 @@ static void rt2800_config_channel(struct
+ if (rt2x00_rt(rt2x00dev, RT3572))
+ rt2800_rfcsr_write(rt2x00dev, 8, 0);
+
+- if (rt2x00_rt(rt2x00dev, RT6352))
++ if (rt2x00_rt(rt2x00dev, RT6352)) {
+ tx_pin = rt2800_register_read(rt2x00dev, TX_PIN_CFG);
+- else
++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFRX_EN, 1);
++ } else {
+ tx_pin = 0;
++ }
+
+ switch (rt2x00dev->default_ant.tx_chain_num) {
+ case 3:
+@@ -3916,7 +3918,6 @@ static void rt2800_config_channel(struct
+
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
+- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFRX_EN, 1); /* mt7620 */
+
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
+
--- /dev/null
+From cb77f0f92f596a2ef54246db7321e319305e8156 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 13 Feb 2019 11:09:16 +0100
+Subject: [PATCH 19/28] rt2800: comment and simplify AGC init for RT6352
+
+We do not need separate lines for calculating register values.
+Also add comment that value is different than in vendor driver.
+
+Suggested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -3989,9 +3989,12 @@ static void rt2800_config_channel(struct
+ rt2800_bbp_write(rt2x00dev, 195, 141);
+ rt2800_bbp_write(rt2x00dev, 196, reg);
+
+- /* AGC init */
+- reg = rf->channel <= 14 ? 0x1c : 0x24;
+- reg += 2 * rt2x00dev->lna_gain;
++ /* AGC init.
++ * Despite the vendor driver using different values here for
++ * RT6352 chip, we use 0x1c for now. This may have to be changed
++ * once TSSI got implemented.
++ */
++ reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain;
+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
+
+ rt2800_iq_calibrate(rt2x00dev, rf->channel);
--- /dev/null
+From 1a8a8989b779e51e4652a30e9f22c36a1b6ffc4b Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Thu, 20 Dec 2018 16:16:11 +0100
+Subject: [PATCH 20/28] rt2x00: do not print error when queue is full
+
+For unknown reasons printk() on some context can cause CPU hung on
+embedded MT7620 AP/router MIPS platforms. What can result on wifi
+disconnects.
+
+This patch move queue full messages to debug level what is consistent
+with other mac80211 drivers which drop packet silently if tx queue is
+full. This make MT7620 OpenWRT routers more stable, what was reported
+by various users.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
+@@ -671,7 +671,7 @@ int rt2x00queue_write_tx_frame(struct da
+ spin_lock(&queue->tx_lock);
+
+ if (unlikely(rt2x00queue_full(queue))) {
+- rt2x00_err(queue->rt2x00dev, "Dropping frame due to full tx queue %d\n",
++ rt2x00_dbg(queue->rt2x00dev, "Dropping frame due to full tx queue %d\n",
+ queue->qid);
+ ret = -ENOBUFS;
+ goto out;
--- /dev/null
+From 91a5340db0526b7263bc8da14b120ea3129b5f28 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Sat, 9 Feb 2019 12:08:31 +0100
+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, ®)) {
++ while (quota-- > 0 && kfifo_get(&rt2x00dev->txstatus_fifo, ®)) {
+ /*
+ * 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);
+
--- /dev/null
+From 11f8ad1656035176bad9d89de7ea0e7fe6d82c32 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Sat, 9 Feb 2019 12:08:32 +0100
+Subject: [PATCH 22/28] rt2800: new flush implementation for SoC devices
+
+Use new flush_queue() calback for SoC devices, what was already done for
+PCIe devices.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800soc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
+@@ -203,7 +203,7 @@ static const struct rt2x00lib_ops rt2800
+ .start_queue = rt2800mmio_start_queue,
+ .kick_queue = rt2800mmio_kick_queue,
+ .stop_queue = rt2800mmio_stop_queue,
+- .flush_queue = rt2x00mmio_flush_queue,
++ .flush_queue = rt2800mmio_flush_queue,
+ .write_tx_desc = rt2800mmio_write_tx_desc,
+ .write_tx_data = rt2800_write_tx_data,
+ .write_beacon = rt2800_write_beacon,
--- /dev/null
+From 2bbea7645c3d095014a080db170941818650e141 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Sat, 9 Feb 2019 12:08:33 +0100
+Subject: [PATCH 23/28] rt2800: move txstatus pending routine
+
+Move rt2800usb_txstatus_pending routine to rt2800lib. It will be reused
+by rt2800mmio code.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ .../net/wireless/ralink/rt2x00/rt2800lib.c | 17 ++++++++++++++
+ .../net/wireless/ralink/rt2x00/rt2800lib.h | 1 +
+ .../net/wireless/ralink/rt2x00/rt2800usb.c | 22 +++----------------
+ 3 files changed, 21 insertions(+), 19 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -1183,6 +1183,23 @@ bool rt2800_txstatus_timeout(struct rt2x
+ }
+ EXPORT_SYMBOL_GPL(rt2800_txstatus_timeout);
+
++/*
++ * test if there is an entry in any TX queue for which DMA is done
++ * but the TX status has not been returned yet
++ */
++bool rt2800_txstatus_pending(struct rt2x00_dev *rt2x00dev)
++{
++ struct data_queue *queue;
++
++ tx_queue_for_each(rt2x00dev, queue) {
++ if (rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE) !=
++ rt2x00queue_get_entry(queue, Q_INDEX_DONE))
++ return true;
++ }
++ return false;
++}
++EXPORT_SYMBOL_GPL(rt2800_txstatus_pending);
++
+ void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev)
+ {
+ struct data_queue *queue;
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+@@ -198,6 +198,7 @@ void rt2800_txdone_entry(struct queue_en
+ 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);
++bool rt2800_txstatus_pending(struct rt2x00_dev *rt2x00dev);
+
+ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
+ void rt2800_clear_beacon(struct queue_entry *entry);
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+@@ -100,22 +100,6 @@ static void rt2800usb_stop_queue(struct
+ }
+ }
+
+-/*
+- * test if there is an entry in any TX queue for which DMA is done
+- * but the TX status has not been returned yet
+- */
+-static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev)
+-{
+- struct data_queue *queue;
+-
+- tx_queue_for_each(rt2x00dev, queue) {
+- if (rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE) !=
+- rt2x00queue_get_entry(queue, Q_INDEX_DONE))
+- return true;
+- }
+- return false;
+-}
+-
+ #define TXSTATUS_READ_INTERVAL 1000000
+
+ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
+@@ -145,7 +129,7 @@ static bool rt2800usb_tx_sta_fifo_read_c
+ if (rt2800_txstatus_timeout(rt2x00dev))
+ queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
+
+- if (rt2800usb_txstatus_pending(rt2x00dev)) {
++ if (rt2800_txstatus_pending(rt2x00dev)) {
+ /* Read register after 1 ms */
+ hrtimer_start(&rt2x00dev->txstatus_timer,
+ TXSTATUS_READ_INTERVAL,
+@@ -160,7 +144,7 @@ stop_reading:
+ * clear_bit someone could do rt2x00usb_interrupt_txdone, so recheck
+ * here again if status reading is needed.
+ */
+- if (rt2800usb_txstatus_pending(rt2x00dev) &&
++ if (rt2800_txstatus_pending(rt2x00dev) &&
+ !test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags))
+ return true;
+ else
+@@ -489,7 +473,7 @@ static void rt2800usb_work_txdone(struct
+ * if the medium is busy, thus the TX_STA_FIFO entry is
+ * also delayed -> use a timer to retrieve it.
+ */
+- if (rt2800usb_txstatus_pending(rt2x00dev))
++ if (rt2800_txstatus_pending(rt2x00dev))
+ rt2800usb_async_read_tx_status(rt2x00dev);
+ }
+ }
--- /dev/null
+From f6a9618198e190a2ba09ce3f0aa8e9ee1763bd38 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Sat, 9 Feb 2019 12:08:34 +0100
+Subject: [PATCH 24/28] rt2800mmio: fetch tx status changes
+
+Prepare to use rt2800mmio_fetch_txstatus() in concurrent manner and drop
+return value since is not longer needed.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
+@@ -255,12 +255,12 @@ void rt2800mmio_autowake_tasklet(unsigne
+ }
+ EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet);
+
+-static bool rt2800mmio_fetch_txstatus(struct rt2x00_dev *rt2x00dev)
++static void rt2800mmio_fetch_txstatus(struct rt2x00_dev *rt2x00dev)
+ {
+ u32 status;
+- bool more = false;
++ unsigned long flags;
+
+- /* FIXEME: rewrite this comment
++ /*
+ * The TX_FIFO_STATUS interrupt needs special care. We should
+ * read TX_STA_FIFO but we should do it immediately as otherwise
+ * the register can overflow and we would lose status reports.
+@@ -271,20 +271,21 @@ static bool rt2800mmio_fetch_txstatus(st
+ * because we can schedule the tasklet multiple times (when the
+ * interrupt fires again during tx status processing).
+ *
+- * txstatus tasklet is called with INT_SOURCE_CSR_TX_FIFO_STATUS
+- * disabled so have only one producer and one consumer - we don't
+- * need to lock the kfifo.
++ * We also read statuses from tx status timeout timer, use
++ * lock to prevent concurent writes to fifo.
+ */
++
++ spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags);
++
+ while (!kfifo_is_full(&rt2x00dev->txstatus_fifo)) {
+ status = rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO);
+ if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
+ break;
+
+ kfifo_put(&rt2x00dev->txstatus_fifo, status);
+- more = true;
+ }
+
+- return more;
++ spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags);
+ }
+
+ void rt2800mmio_txstatus_tasklet(unsigned long data)
--- /dev/null
+From 175c2548332b45b144af673e70fdbb1a947d7aba Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Sat, 9 Feb 2019 12:08:35 +0100
+Subject: [PATCH 25/28] rt2800mmio: use timer and work for handling tx statuses
+ timeouts
+
+Sometimes we can get into situation when there are pending statuses,
+but we do not get INT_SOURCE_CSR_TX_FIFO_STATUS. Handle this situation
+by arming timeout timer and read statuses (it will fix case when
+we just do not have irq) and queue work to handle case we missed
+statues from hardware FIFO.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ .../net/wireless/ralink/rt2x00/rt2800mmio.c | 81 +++++++++++++++++--
+ .../net/wireless/ralink/rt2x00/rt2800mmio.h | 1 +
+ .../net/wireless/ralink/rt2x00/rt2800pci.c | 2 +-
+ .../net/wireless/ralink/rt2x00/rt2800soc.c | 2 +-
+ .../net/wireless/ralink/rt2x00/rt2x00dev.c | 4 +
+ 5 files changed, 82 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
+@@ -426,6 +426,9 @@ void rt2800mmio_start_queue(struct data_
+ }
+ EXPORT_SYMBOL_GPL(rt2800mmio_start_queue);
+
++/* 200 ms */
++#define TXSTATUS_TIMEOUT 200000000
++
+ void rt2800mmio_kick_queue(struct data_queue *queue)
+ {
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+@@ -440,6 +443,8 @@ void rt2800mmio_kick_queue(struct data_q
+ entry = rt2x00queue_get_entry(queue, Q_INDEX);
+ rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(queue->qid),
+ entry->entry_idx);
++ hrtimer_start(&rt2x00dev->txstatus_timer,
++ TXSTATUS_TIMEOUT, HRTIMER_MODE_REL);
+ break;
+ case QID_MGMT:
+ entry = rt2x00queue_get_entry(queue, Q_INDEX);
+@@ -484,12 +489,8 @@ void rt2800mmio_flush_queue(struct data_
+ * For TX queues schedule completion tasklet to catch
+ * tx status timeouts, othewise just wait.
+ */
+- if (tx_queue) {
+- tasklet_disable(&rt2x00dev->txstatus_tasklet);
+- rt2800_txdone(rt2x00dev, UINT_MAX);
+- rt2800_txdone_nostatus(rt2x00dev);
+- tasklet_enable(&rt2x00dev->txstatus_tasklet);
+- }
++ if (tx_queue)
++ queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
+
+ /*
+ * Wait for a little while to give the driver
+@@ -627,6 +628,10 @@ void rt2800mmio_clear_entry(struct queue
+ word = rt2x00_desc_read(entry_priv->desc, 1);
+ rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1);
+ rt2x00_desc_write(entry_priv->desc, 1, word);
++
++ /* If last entry stop txstatus timer */
++ if (entry->queue->length == 1)
++ hrtimer_cancel(&rt2x00dev->txstatus_timer);
+ }
+ }
+ EXPORT_SYMBOL_GPL(rt2800mmio_clear_entry);
+@@ -759,6 +764,70 @@ int rt2800mmio_enable_radio(struct rt2x0
+ }
+ EXPORT_SYMBOL_GPL(rt2800mmio_enable_radio);
+
++static void rt2800mmio_work_txdone(struct work_struct *work)
++{
++ struct rt2x00_dev *rt2x00dev =
++ container_of(work, struct rt2x00_dev, txdone_work);
++
++ if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
++ return;
++
++ while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) ||
++ rt2800_txstatus_timeout(rt2x00dev)) {
++
++ tasklet_disable(&rt2x00dev->txstatus_tasklet);
++ rt2800_txdone(rt2x00dev, UINT_MAX);
++ rt2800_txdone_nostatus(rt2x00dev);
++ tasklet_enable(&rt2x00dev->txstatus_tasklet);
++ }
++
++ if (rt2800_txstatus_pending(rt2x00dev))
++ hrtimer_start(&rt2x00dev->txstatus_timer,
++ TXSTATUS_TIMEOUT, HRTIMER_MODE_REL);
++}
++
++static enum hrtimer_restart rt2800mmio_tx_sta_fifo_timeout(struct hrtimer *timer)
++{
++ struct rt2x00_dev *rt2x00dev =
++ container_of(timer, struct rt2x00_dev, txstatus_timer);
++
++ if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
++ goto out;
++
++ if (!rt2800_txstatus_pending(rt2x00dev))
++ goto out;
++
++ rt2800mmio_fetch_txstatus(rt2x00dev);
++ if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo))
++ tasklet_schedule(&rt2x00dev->txstatus_tasklet);
++ else
++ queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
++out:
++ return HRTIMER_NORESTART;
++}
++
++int rt2800mmio_probe_hw(struct rt2x00_dev *rt2x00dev)
++{
++ int retval;
++
++ retval = rt2800_probe_hw(rt2x00dev);
++ if (retval)
++ return retval;
++
++ /*
++ * Set txstatus timer function.
++ */
++ rt2x00dev->txstatus_timer.function = rt2800mmio_tx_sta_fifo_timeout;
++
++ /*
++ * Overwrite TX done handler
++ */
++ INIT_WORK(&rt2x00dev->txdone_work, rt2800mmio_work_txdone);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(rt2800mmio_probe_hw);
++
+ MODULE_AUTHOR(DRV_PROJECT);
+ MODULE_VERSION(DRV_VERSION);
+ MODULE_DESCRIPTION("rt2800 MMIO library");
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h
+@@ -153,6 +153,7 @@ void rt2800mmio_stop_queue(struct data_q
+ void rt2800mmio_queue_init(struct data_queue *queue);
+
+ /* Initialization functions */
++int rt2800mmio_probe_hw(struct rt2x00_dev *rt2x00dev);
+ bool rt2800mmio_get_entry_state(struct queue_entry *entry);
+ void rt2800mmio_clear_entry(struct queue_entry *entry);
+ int rt2800mmio_init_queues(struct rt2x00_dev *rt2x00dev);
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
+@@ -346,7 +346,7 @@ static const struct rt2x00lib_ops rt2800
+ .tbtt_tasklet = rt2800mmio_tbtt_tasklet,
+ .rxdone_tasklet = rt2800mmio_rxdone_tasklet,
+ .autowake_tasklet = rt2800mmio_autowake_tasklet,
+- .probe_hw = rt2800_probe_hw,
++ .probe_hw = rt2800mmio_probe_hw,
+ .get_firmware_name = rt2800pci_get_firmware_name,
+ .check_firmware = rt2800_check_firmware,
+ .load_firmware = rt2800_load_firmware,
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
+@@ -185,7 +185,7 @@ static const struct rt2x00lib_ops rt2800
+ .tbtt_tasklet = rt2800mmio_tbtt_tasklet,
+ .rxdone_tasklet = rt2800mmio_rxdone_tasklet,
+ .autowake_tasklet = rt2800mmio_autowake_tasklet,
+- .probe_hw = rt2800_probe_hw,
++ .probe_hw = rt2800mmio_probe_hw,
+ .get_firmware_name = rt2800soc_get_firmware_name,
+ .check_firmware = rt2800soc_check_firmware,
+ .load_firmware = rt2800soc_load_firmware,
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -1391,6 +1391,8 @@ int rt2x00lib_probe_dev(struct rt2x00_de
+ mutex_init(&rt2x00dev->conf_mutex);
+ INIT_LIST_HEAD(&rt2x00dev->bar_list);
+ spin_lock_init(&rt2x00dev->bar_list_lock);
++ hrtimer_init(&rt2x00dev->txstatus_timer, CLOCK_MONOTONIC,
++ HRTIMER_MODE_REL);
+
+ set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
+
+@@ -1515,6 +1517,8 @@ void rt2x00lib_remove_dev(struct rt2x00_
+ cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
+ cancel_work_sync(&rt2x00dev->sleep_work);
+
++ hrtimer_cancel(&rt2x00dev->txstatus_timer);
++
+ /*
+ * Kill the tx status tasklet.
+ */
--- /dev/null
+From 6013a91f15c9dabd668d5736652b9bcfb0ef0378 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Sat, 9 Feb 2019 12:08:36 +0100
+Subject: [PATCH 26/28] rt2x00: remove last_nostatus_check
+
+We do not any longer check txstatus timeout from tasklet, so do not need
+this optimization.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 9 ---------
+ drivers/net/wireless/ralink/rt2x00/rt2x00.h | 2 --
+ drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 1 -
+ 3 files changed, 12 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -1164,15 +1164,6 @@ bool rt2800_txstatus_timeout(struct rt2x
+ struct data_queue *queue;
+ struct queue_entry *entry;
+
+- if (!test_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags)) {
+- unsigned long tout = msecs_to_jiffies(1000);
+-
+- if (time_before(jiffies, rt2x00dev->last_nostatus_check + tout))
+- return false;
+- }
+-
+- rt2x00dev->last_nostatus_check = jiffies;
+-
+ tx_queue_for_each(rt2x00dev, queue) {
+ entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
+ if (rt2800_entry_txstatus_timeout(rt2x00dev, entry))
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+@@ -981,8 +981,6 @@ struct rt2x00_dev {
+ */
+ DECLARE_KFIFO_PTR(txstatus_fifo, u32);
+
+- unsigned long last_nostatus_check;
+-
+ /*
+ * Timer to ensure tx status reports are read (rt2800usb).
+ */
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
+@@ -1039,7 +1039,6 @@ void rt2x00queue_start_queues(struct rt2
+ */
+ tx_queue_for_each(rt2x00dev, queue)
+ rt2x00queue_start_queue(queue);
+- rt2x00dev->last_nostatus_check = jiffies;
+
+ rt2x00queue_start_queue(rt2x00dev->rx);
+ }
--- /dev/null
+From 2758f09b22bc08e89e0391486b2d707ad2479599 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Sat, 9 Feb 2019 12:08:37 +0100
+Subject: [PATCH 27/28] rt2x00: remove not used entry field
+
+Remove not used any longer queue_entry field and flag.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00queue.h | 3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
+@@ -361,7 +361,6 @@ enum queue_entry_flags {
+ ENTRY_DATA_PENDING,
+ ENTRY_DATA_IO_FAILED,
+ ENTRY_DATA_STATUS_PENDING,
+- ENTRY_DATA_STATUS_SET,
+ };
+
+ /**
+@@ -387,8 +386,6 @@ struct queue_entry {
+
+ unsigned int entry_idx;
+
+- u32 status;
+-
+ void *priv_data;
+ };
+
--- /dev/null
+From f44e145869bb517460648e4ed71b7e9001964d06 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Sat, 9 Feb 2019 12:08:38 +0100
+Subject: [PATCH 28/28] rt2x00mmio: remove legacy comment
+
+Remove comment about fields that ware removed.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00mmio.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.h
+@@ -80,8 +80,6 @@ int rt2x00mmio_regbusy_read(struct rt2x0
+ *
+ * @desc: Pointer to device descriptor
+ * @desc_dma: DMA pointer to &desc.
+- * @data: Pointer to device's entry memory.
+- * @data_dma: DMA pointer to &data.
+ */
+ struct queue_entry_priv_mmio {
+ __le32 *desc;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -9409,6 +9409,7 @@ static int rt2800_probe_rt(struct rt2x00
+@@ -9578,6 +9578,7 @@ static int rt2800_probe_rt(struct rt2x00
case RT3390:
case RT3572:
case RT3593:
#define RF5362 0x5362
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8987,6 +8987,66 @@ static const struct rf_channel rf_vals_3
+@@ -9154,6 +9154,66 @@ static const struct rf_channel rf_vals_3
{14, 0xF0, 2, 0x18},
};
static const struct rf_channel rf_vals_5592_xtal20[] = {
/* Channel, N, K, mod, R */
{1, 482, 4, 10, 3},
-@@ -9250,6 +9310,11 @@ static int rt2800_probe_hw_mode(struct r
+@@ -9417,6 +9477,11 @@ static int rt2800_probe_hw_mode(struct r
spec->channels = rf_vals_3x;
break;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -4884,6 +4884,7 @@ void rt2800_vco_calibration(struct rt2x0
+@@ -5051,6 +5051,7 @@ void rt2800_vco_calibration(struct rt2x0
case RF3053:
case RF3070:
case RF3290:
case RF5350:
case RF5360:
case RF5362:
-@@ -9432,6 +9433,7 @@ static int rt2800_probe_hw_mode(struct r
+@@ -9601,6 +9602,7 @@ static int rt2800_probe_hw_mode(struct r
case RF3053:
case RF3070:
case RF3290:
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -2716,6 +2716,211 @@ static void rt2800_config_channel_rf3053
+@@ -2880,6 +2880,211 @@ static void rt2800_config_channel_rf3053
}
}
#define POWER_BOUND 0x27
#define POWER_BOUND_5G 0x2b
-@@ -3573,6 +3778,9 @@ static void rt2800_config_channel(struct
+@@ -3734,6 +3939,9 @@ static void rt2800_config_channel(struct
case RF3322:
rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
break;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8910,6 +8910,7 @@ static int rt2800_init_eeprom(struct rt2
+@@ -9077,6 +9077,7 @@ static int rt2800_init_eeprom(struct rt2
case RF3290:
case RF3320:
case RF3322:
#define RX_FILTER_CFG 0x1400
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -5512,6 +5512,12 @@ static int rt2800_init_registers(struct
+@@ -5679,6 +5679,12 @@ static int rt2800_init_registers(struct
rt2800_register_write(rt2x00dev, TX_SW_CFG2,
0x00000000);
}
} else if (rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392) ||
rt2x00_rt(rt2x00dev, RT6352)) {
-@@ -5725,6 +5731,11 @@ static int rt2800_init_registers(struct
+@@ -5892,6 +5898,11 @@ static int rt2800_init_registers(struct
reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002;
rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -6352,6 +6352,47 @@ static void rt2800_init_bbp_3593(struct
+@@ -6519,6 +6519,47 @@ static void rt2800_init_bbp_3593(struct
rt2800_bbp_write(rt2x00dev, 103, 0xc0);
}
static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
{
int ant, div_mode;
-@@ -6796,6 +6837,9 @@ static void rt2800_init_bbp(struct rt2x0
+@@ -6963,6 +7004,9 @@ static void rt2800_init_bbp(struct rt2x0
case RT3593:
rt2800_init_bbp_3593(rt2x00dev);
return;
#define RFCSR2_TX2_EN_MT7620 FIELD8(0x20)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -7711,6 +7711,144 @@ static void rt2800_init_rfcsr_5350(struc
+@@ -7878,6 +7878,144 @@ static void rt2800_init_rfcsr_5350(struc
rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
}
static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
{
rt2800_rf_init_calibration(rt2x00dev, 2);
-@@ -8553,6 +8691,9 @@ static void rt2800_init_rfcsr(struct rt2
+@@ -8720,6 +8858,9 @@ static void rt2800_init_rfcsr(struct rt2
case RT3390:
rt2800_init_rfcsr_3390(rt2x00dev);
break;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -9087,6 +9087,8 @@ static int rt2800_init_eeprom(struct rt2
+@@ -9254,6 +9254,8 @@ static int rt2800_init_eeprom(struct rt2
rf = rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID);
else if (rt2x00_rt(rt2x00dev, RT3352))
rf = RF3322;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -3741,6 +3741,36 @@ static char rt2800_txpower_to_dev(struct
+@@ -3902,6 +3902,36 @@ static char rt2800_txpower_to_dev(struct
return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER);
}
static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf,
struct rf_channel *rf,
-@@ -3759,6 +3789,12 @@ static void rt2800_config_channel(struct
+@@ -3920,6 +3950,12 @@ static void rt2800_config_channel(struct
rt2800_txpower_to_dev(rt2x00dev, rf->channel,
info->default_power3);
switch (rt2x00dev->chip.rf) {
case RF2020:
case RF3020:
-@@ -3863,6 +3899,15 @@ static void rt2800_config_channel(struct
+@@ -4024,6 +4060,15 @@ static void rt2800_config_channel(struct
rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
rt2800_bbp_write(rt2x00dev, 77, 0x98);
} else {
rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
-@@ -3876,6 +3921,7 @@ static void rt2800_config_channel(struct
+@@ -4037,6 +4082,7 @@ static void rt2800_config_channel(struct
!rt2x00_rt(rt2x00dev, RT6352)) {
if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
rt2800_bbp_write(rt2x00dev, 82, 0x62);
rt2800_bbp_write(rt2x00dev, 75, 0x46);
} else {
if (rt2x00_rt(rt2x00dev, RT3593))
-@@ -3884,19 +3930,22 @@ static void rt2800_config_channel(struct
+@@ -4045,19 +4091,22 @@ static void rt2800_config_channel(struct
rt2800_bbp_write(rt2x00dev, 82, 0x84);
rt2800_bbp_write(rt2x00dev, 75, 0x50);
}
rt2800_bbp_write(rt2x00dev, 83, 0x9a);
if (rt2x00_has_cap_external_lna_a(rt2x00dev))
-@@ -4022,6 +4071,23 @@ static void rt2800_config_channel(struct
+@@ -4190,6 +4239,23 @@ static void rt2800_config_channel(struct
rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -3728,13 +3728,15 @@ static char rt2800_txpower_to_dev(struct
+@@ -3889,13 +3889,15 @@ static char rt2800_txpower_to_dev(struct
unsigned int channel,
char txpower)
{
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -5114,7 +5114,8 @@ static void rt2800_config_txpower(struct
+@@ -5281,7 +5281,8 @@ static void rt2800_config_txpower(struct
struct ieee80211_channel *chan,
int power_level)
{
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8969,7 +8969,8 @@ static u8 rt2800_get_txmixer_gain_24g(st
+@@ -9136,7 +9136,8 @@ static u8 rt2800_get_txmixer_gain_24g(st
{
u16 word;
return 0;
word = rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG);
-@@ -8983,7 +8984,8 @@ static u8 rt2800_get_txmixer_gain_5g(str
+@@ -9150,7 +9151,8 @@ static u8 rt2800_get_txmixer_gain_5g(str
{
u16 word;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -2020,7 +2020,8 @@ void rt2800_config_ant(struct rt2x00_dev
+@@ -2182,7 +2182,8 @@ void rt2800_config_ant(struct rt2x00_dev
rt2800_bbp_write(rt2x00dev, 3, r3);
rt2800_bbp_write(rt2x00dev, 1, r1);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -2043,7 +2043,8 @@ static void rt2800_config_lna_gain(struc
+@@ -2205,7 +2205,8 @@ static void rt2800_config_lna_gain(struc
eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_LNA);
lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
} else if (libconf->rf.channel <= 128) {
eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2);
lna_gain = rt2x00_get_field16(eeprom,
EEPROM_EXT_LNA2_A1);
-@@ -2053,7 +2054,8 @@ static void rt2800_config_lna_gain(struc
+@@ -2215,7 +2216,8 @@ static void rt2800_config_lna_gain(struc
EEPROM_RSSI_BG2_LNA_A1);
}
} else {
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -5367,7 +5367,8 @@ static u8 rt2800_get_default_vgc(struct
+@@ -5534,7 +5534,8 @@ static u8 rt2800_get_default_vgc(struct
else
vgc = 0x2e + rt2x00dev->lna_gain;
} else { /* 5GHZ band */
vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3;
else if (rt2x00_rt(rt2x00dev, RT5592))
vgc = 0x24 + (2 * rt2x00dev->lna_gain);
-@@ -5387,7 +5388,8 @@ static inline void rt2800_set_vgc(struct
+@@ -5554,7 +5555,8 @@ static inline void rt2800_set_vgc(struct
{
if (qual->vgc_level != vgc_level) {
if (rt2x00_rt(rt2x00dev, RT3572) ||
rt2800_bbp_write_with_rx_chain(rt2x00dev, 66,
vgc_level);
} else if (rt2x00_rt(rt2x00dev, RT5592)) {
-@@ -5434,6 +5436,11 @@ void rt2800_link_tuner(struct rt2x00_dev
+@@ -5601,6 +5603,11 @@ void rt2800_link_tuner(struct rt2x00_dev
}
break;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -9102,7 +9102,8 @@ static int rt2800_validate_eeprom(struct
+@@ -9269,7 +9269,8 @@ static int rt2800_validate_eeprom(struct
word = rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
-@@ -9122,7 +9123,8 @@ static int rt2800_validate_eeprom(struct
+@@ -9289,7 +9290,8 @@ static int rt2800_validate_eeprom(struct
word = rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
-@@ -9130,7 +9132,8 @@ static int rt2800_validate_eeprom(struct
+@@ -9297,7 +9299,8 @@ static int rt2800_validate_eeprom(struct
}
rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -4357,6 +4357,9 @@ static u8 rt2800_compensate_txpower(stru
+@@ -4524,6 +4524,9 @@ static u8 rt2800_compensate_txpower(stru
if (rt2x00_rt(rt2x00dev, RT3593))
return min_t(u8, txpower, 0xc);
.drv_init_registers = rt2800mmio_init_registers,
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-@@ -702,6 +702,7 @@ enum rt2x00_capability_flags {
+@@ -703,6 +703,7 @@ enum rt2x00_capability_flags {
REQUIRE_HT_TX_DESC,
REQUIRE_PS_AUTOWAKE,
REQUIRE_DELAYED_RFKILL,
/*
* Capabilities
-@@ -977,6 +978,11 @@ struct rt2x00_dev {
+@@ -978,6 +979,11 @@ struct rt2x00_dev {
const struct firmware *fw;
/*
DECLARE_KFIFO_PTR(txstatus_fifo, u32);
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -1421,6 +1421,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
+@@ -1423,6 +1423,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
/*
* Let the driver probe the device to detect the capabilities.
*/
-@@ -1562,6 +1566,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
+@@ -1566,6 +1570,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
* Free the driver data.
*/
kfree(rt2x00dev->drv_data);
#include "rt2x00.h"
#include "rt2800lib.h"
-@@ -9291,6 +9292,17 @@ static int rt2800_init_eeprom(struct rt2
+@@ -9458,6 +9459,17 @@ static int rt2800_init_eeprom(struct rt2
rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
* EEPROM LNA
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -4123,6 +4123,61 @@ static void rt2800_config_channel(struct
+@@ -4290,6 +4290,61 @@ static void rt2800_config_channel(struct
rt2800_iq_calibrate(rt2x00dev, rf->channel);
}
bbp = rt2800_bbp_read(rt2x00dev, 4);
rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
rt2800_bbp_write(rt2x00dev, 4, bbp);
-@@ -9320,7 +9375,8 @@ static int rt2800_init_eeprom(struct rt2
+@@ -9487,7 +9542,8 @@ static int rt2800_init_eeprom(struct rt2
*/
eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1);
if (rt2x00_get_field16(eeprom,
EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352))
__set_bit(CAPABILITY_EXTERNAL_PA_TX0,
-@@ -9331,6 +9387,18 @@ static int rt2800_init_eeprom(struct rt2
+@@ -9498,6 +9554,18 @@ static int rt2800_init_eeprom(struct rt2
&rt2x00dev->cap_flags);
}
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -4136,38 +4136,22 @@ static void rt2800_config_channel(struct
+@@ -4303,38 +4303,22 @@ static void rt2800_config_channel(struct
reg |= 0x00000101;
rt2800_register_write(rt2x00dev, RF_BYPASS3, reg);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8336,6 +8336,58 @@ static void rt2800_init_rfcsr_5592(struc
+@@ -8349,6 +8349,58 @@ static void rt2800_init_rfcsr_5592(struc
rt2800_led_open_drain_enable(rt2x00dev);
}
}
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
-@@ -242,6 +242,7 @@ void rt2800_link_tuner(struct rt2x00_dev
+@@ -243,6 +243,7 @@ void rt2800_link_tuner(struct rt2x00_dev
const u32 count);
void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev);
void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8388,6 +8388,160 @@ void rt2800_rf_self_txdc_cal(struct rt2x
+@@ -8401,6 +8401,160 @@ void rt2800_rf_self_txdc_cal(struct rt2x
}
EXPORT_SYMBOL_GPL(rt2800_rf_self_txdc_cal);
rt2800_bw_filter_calibration(rt2x00dev, false);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
-@@ -243,6 +243,8 @@ void rt2800_link_tuner(struct rt2x00_dev
+@@ -244,6 +244,8 @@ void rt2800_link_tuner(struct rt2x00_dev
void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev);
void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev);
void rt2800_rf_self_txdc_cal(struct rt2x00_dev *rt2x00dev);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8542,6 +8542,71 @@ void rt2800_r_calibration(struct rt2x00_
+@@ -8555,6 +8555,71 @@ void rt2800_r_calibration(struct rt2x00_
}
EXPORT_SYMBOL_GPL(rt2800_r_calibration);
}
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
-@@ -245,6 +245,7 @@ void rt2800_vco_calibration(struct rt2x0
+@@ -246,6 +246,7 @@ void rt2800_vco_calibration(struct rt2x0
void rt2800_rf_self_txdc_cal(struct rt2x00_dev *rt2x00dev);
int rt2800_calcrcalibrationcode(struct rt2x00_dev *rt2x00dev, int d1, int d2);
void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8607,6 +8607,386 @@ void rt2800_rxdcoc_calibration(struct rt
+@@ -8620,6 +8620,386 @@ void rt2800_rxdcoc_calibration(struct rt
}
EXPORT_SYMBOL_GPL(rt2800_rxdcoc_calibration);
static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
-@@ -246,6 +246,7 @@ void rt2800_rf_self_txdc_cal(struct rt2x
+@@ -247,6 +247,7 @@ void rt2800_rf_self_txdc_cal(struct rt2x
int rt2800_calcrcalibrationcode(struct rt2x00_dev *rt2x00dev, int d1, int d2);
void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev);
void rt2800_rxdcoc_calibration(struct rt2x00_dev *rt2x00dev);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -8987,6 +8987,957 @@ restore_value:
+@@ -9000,6 +9000,957 @@ restore_value:
}
EXPORT_SYMBOL_GPL(rt2800_rxiq_calibration);
/* RT2800 driver data structure */
struct rt2800_drv_data {
-@@ -247,6 +257,7 @@ int rt2800_calcrcalibrationcode(struct r
+@@ -248,6 +258,7 @@ int rt2800_calcrcalibrationcode(struct r
void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev);
void rt2800_rxdcoc_calibration(struct rt2x00_dev *rt2x00dev);
void rt2800_rxiq_calibration(struct rt2x00_dev *rt2x00dev);
+++ /dev/null
-From patchwork Thu Dec 27 14:05:25 2018
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: Tom Psyborg <pozega.tomislav@gmail.com>
-X-Patchwork-Id: 10743705
-X-Patchwork-Delegate: kvalo@adurom.com
-Return-Path: <linux-wireless-owner@kernel.org>
-Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org
- [172.30.200.125])
- by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2BC1913B5
- for <patchwork-linux-wireless@patchwork.kernel.org>;
- Thu, 27 Dec 2018 14:06:03 +0000 (UTC)
-Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1])
- by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1C758289EC
- for <patchwork-linux-wireless@patchwork.kernel.org>;
- Thu, 27 Dec 2018 14:06:03 +0000 (UTC)
-Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486)
- id 0E022289ED; Thu, 27 Dec 2018 14:06:03 +0000 (UTC)
-X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on
- pdx-wl-mail.web.codeaurora.org
-X-Spam-Level:
-X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED,
- DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI
- autolearn=ham version=3.3.1
-Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
- by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AE551289C6
- for <patchwork-linux-wireless@patchwork.kernel.org>;
- Thu, 27 Dec 2018 14:06:02 +0000 (UTC)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S1729690AbeL0OFk (ORCPT
- <rfc822;patchwork-linux-wireless@patchwork.kernel.org>);
- Thu, 27 Dec 2018 09:05:40 -0500
-Received: from mail-wr1-f66.google.com ([209.85.221.66]:40863 "EHLO
- mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S1729469AbeL0OFk (ORCPT
- <rfc822;linux-wireless@vger.kernel.org>);
- Thu, 27 Dec 2018 09:05:40 -0500
-Received: by mail-wr1-f66.google.com with SMTP id p4so18360549wrt.7
- for <linux-wireless@vger.kernel.org>;
- Thu, 27 Dec 2018 06:05:39 -0800 (PST)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20161025;
- h=from:to:cc:subject:date:message-id:mime-version
- :content-transfer-encoding;
- bh=if95ASzOCk1n4rkrJMt0dbDI3WwTIiBNPf8RvdMIJm8=;
- b=N78BHSW85OAzpxBdY2OozZyZYjAg6qKOe0l4D2qxSMPfU6K1kgB9f8YZs5Owl9wPyh
- RC88Px2yQIdVDsFm3Kww1hEalZ+bN2zLqb5+mOWGMXJyEz7VHfWg6+hpYTjHMVohLkg5
- /+OqTEwl8P17YhXJ0KdEk0aHkt4uSi19pLqD+Jp6SzPPnIY+mx6ODeIAWHi3VH6alfre
- plMwZa2EAMcOUCDCygy5ShCJWhXhdeL51VIfYowahUv7xowfw7o5b1+ZihX/DoKGuvHC
- hNQAg9QvDOj6lqHyynD9V0pMgGYSVx2g6MPA8uH3vceV1/vgSkaWTxboyiUylHrlMdIo
- xZCQ==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20161025;
- h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version
- :content-transfer-encoding;
- bh=if95ASzOCk1n4rkrJMt0dbDI3WwTIiBNPf8RvdMIJm8=;
- b=EyuukiKyMQhAsnvAdNATiSxgngxugcTEOlzcC2eOk78pzv8aNJdhWE3+cJLyh1ctj1
- Z/BoIXM298pOrkekyhEZsOnxwGO1p6mrgCBXdoANHvMk93fKtlYT8zNkMZdk6zdXSqBw
- bSm8fD5pgGqoLBJH0swL1lrRkHUXSsBsQgCg1YQegfYoWCgdhAnKYmj3OJca5jqfTlJq
- pL84CtNEgx9GiXNvsaTU8LeFmKU4GVoMmewsR9WRmw9zSoouDXciq0DHtAoBeElHlCjZ
- /8LJQvSLqhONn5xIcFjUdsq3KcqZkCQedwF8WkwVgcA8uksMyKKH0Fj5txHAkeXIyHX3
- IhpA==
-X-Gm-Message-State: AJcUukdCD27qMfzN5D3LfBblTlOINVVf3zsHMXqUaYwCxv/GoSStqEqb
- ha65rhfifdjaR9/NVSakmWv3ZuEByO4=
-X-Google-Smtp-Source:
- ALg8bN4sgpNxIiBIAhaU8qSDeso9A0BqyR3EIwbO8UwBaShVrZZ2nAmG7p6zo63420r8KRFPizaXQA==
-X-Received: by 2002:a5d:47d1:: with SMTP id
- l17mr21936207wrs.319.1545919538745;
- Thu, 27 Dec 2018 06:05:38 -0800 (PST)
-Received: from localhost.localdomain ([31.147.208.18])
- by smtp.googlemail.com with ESMTPSA id
- p6sm38219239wrx.50.2018.12.27.06.05.37
- (version=TLS1 cipher=AES128-SHA bits=128/128);
- Thu, 27 Dec 2018 06:05:38 -0800 (PST)
-From: =?utf-8?q?Tomislav_Po=C5=BEega?= <pozega.tomislav@gmail.com>
-To: linux-wireless@vger.kernel.org
-Cc: kvalo@codeaurora.org, hauke@hauke-m.de, nbd@nbd.name,
- john@phrozen.org, sgruszka@redhat.com, daniel@makrotopia.org
-Subject: [PATCH 1/2] rt2x00: reduce tx power to nominal level on RT6352
-Date: Thu, 27 Dec 2018 15:05:25 +0100
-Message-Id: <1545919526-4074-1-git-send-email-pozega.tomislav@gmail.com>
-X-Mailer: git-send-email 1.7.0.4
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Sender: linux-wireless-owner@vger.kernel.org
-Precedence: bulk
-List-ID: <linux-wireless.vger.kernel.org>
-X-Mailing-List: linux-wireless@vger.kernel.org
-X-Virus-Scanned: ClamAV using ClamSMTP
-
-Current implementation of RT6352 support provides too high tx power
-at least on iPA/eLNA devices. Reduce amplification of variable gain
-amplifier by 6dB to match board target power of 17dBm.
-Transmited signal strength with this patch is similar to that of
-stock firmware or pandorabox firmware. Throughput measured with iperf
-improves. Device tested: Xiaomi Miwifi Mini.
-
-Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
----
- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -5814,7 +5814,7 @@ static int rt2800_init_registers(struct
- rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
- rt2800_register_write(rt2x00dev, MIMO_PS_CFG, 0x00000002);
- rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x00150F0F);
-- rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x06060606);
-+ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000);
- rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0);
- rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0);
- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C);