--- /dev/null
+From patchwork Tue Mar 12 09:51:40 2019
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
+X-Patchwork-Id: 10848957
+X-Patchwork-Delegate: johannes@sipsolutions.net
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+To: linux-wireless@vger.kernel.org
+Cc: =?utf-8?q?Tomislav_Po=C5=BEega?= <pozega.tomislav@gmail.com>,
+ Daniel Golle <daniel@makrotopia.org>, Felix Fietkau <nbd@nbd.name>,
+ Mathias Kresin <dev@kresin.me>
+Subject: [PATCH v3 1/4] cfg80211: add ratelimited variants of err and warn
+Date: Tue, 12 Mar 2019 10:51:40 +0100
+Message-Id: <1552384303-29529-2-git-send-email-sgruszka@redhat.com>
+In-Reply-To: <1552384303-29529-1-git-send-email-sgruszka@redhat.com>
+References: <1552384303-29529-1-git-send-email-sgruszka@redhat.com>
+
+wiphy_{err,warn}_ratelimited will be used by rt2x00
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ include/net/cfg80211.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -6588,6 +6588,11 @@ int cfg80211_external_auth_request(struc
+ #define wiphy_info(wiphy, format, args...) \
+ dev_info(&(wiphy)->dev, format, ##args)
+
++#define wiphy_err_ratelimited(wiphy, format, args...) \
++ dev_err_ratelimited(&(wiphy)->dev, format, ##args)
++#define wiphy_warn_ratelimited(wiphy, format, args...) \
++ dev_warn_ratelimited(&(wiphy)->dev, format, ##args)
++
+ #define wiphy_debug(wiphy, format, args...) \
+ wiphy_printk(KERN_DEBUG, wiphy, format, ##args)
+
+++ /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
-X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
-X-Patchwork-Id: 10739037
-X-Patchwork-Delegate: kvalo@adurom.com
-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
-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, ®)) {
-+ 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 patchwork Tue Mar 12 09:51:41 2019
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
+X-Patchwork-Id: 10848959
+X-Patchwork-Delegate: kvalo@adurom.com
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+To: linux-wireless@vger.kernel.org
+Cc: =?utf-8?q?Tomislav_Po=C5=BEega?= <pozega.tomislav@gmail.com>,
+ Daniel Golle <daniel@makrotopia.org>, Felix Fietkau <nbd@nbd.name>,
+ Mathias Kresin <dev@kresin.me>
+Subject: [PATCH v3 2/4] rt2x00: use ratelimited variants dev_warn/dev_err
+Date: Tue, 12 Mar 2019 10:51:41 +0100
+Message-Id: <1552384303-29529-3-git-send-email-sgruszka@redhat.com>
+In-Reply-To: <1552384303-29529-1-git-send-email-sgruszka@redhat.com>
+References: <1552384303-29529-1-git-send-email-sgruszka@redhat.com>
+
+As reported by Randy we can overwhelm logs on some USB error conditions.
+To avoid that use dev_warn_ratelimited() and dev_err_ratelimitd().
+
+Reported-and-tested-by: Randy Oostdyk <linux-kernel@oostdyk.com>
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+@@ -69,10 +69,10 @@
+ printk(KERN_ERR KBUILD_MODNAME ": %s: Error - " fmt, \
+ __func__, ##__VA_ARGS__)
+ #define rt2x00_err(dev, fmt, ...) \
+- wiphy_err((dev)->hw->wiphy, "%s: Error - " fmt, \
++ wiphy_err_ratelimited((dev)->hw->wiphy, "%s: Error - " fmt, \
+ __func__, ##__VA_ARGS__)
+ #define rt2x00_warn(dev, fmt, ...) \
+- wiphy_warn((dev)->hw->wiphy, "%s: Warning - " fmt, \
++ wiphy_warn_ratelimited((dev)->hw->wiphy, "%s: Warning - " fmt, \
+ __func__, ##__VA_ARGS__)
+ #define rt2x00_info(dev, fmt, ...) \
+ wiphy_info((dev)->hw->wiphy, "%s: Info - " fmt, \
+++ /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
-X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
-X-Patchwork-Id: 10804439
-X-Patchwork-Delegate: kvalo@adurom.com
-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 patchwork Tue Mar 12 09:51:42 2019
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
+X-Patchwork-Id: 10848961
+X-Patchwork-Delegate: kvalo@adurom.com
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+To: linux-wireless@vger.kernel.org
+Cc: =?utf-8?q?Tomislav_Po=C5=BEega?= <pozega.tomislav@gmail.com>,
+ Daniel Golle <daniel@makrotopia.org>, Felix Fietkau <nbd@nbd.name>,
+ Mathias Kresin <dev@kresin.me>
+Subject: [PATCH v3 3/4] rt2x00: check number of EPROTO errors
+Date: Tue, 12 Mar 2019 10:51:42 +0100
+Message-Id: <1552384303-29529-4-git-send-email-sgruszka@redhat.com>
+In-Reply-To: <1552384303-29529-1-git-send-email-sgruszka@redhat.com>
+References: <1552384303-29529-1-git-send-email-sgruszka@redhat.com>
+
+Some USB host devices/drivers on some conditions can always return
+EPROTO error on submitted URBs. That can cause infinity loop in the
+rt2x00 driver.
+
+Since we can have single EPROTO errors we can not mark as device as
+removed to avoid infinity loop. However we can count consecutive
+EPROTO errors and mark device as removed if get lot of it.
+I choose number 10 as threshold.
+
+Reported-and-tested-by: Randy Oostdyk <linux-kernel@oostdyk.com>
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 +
+ drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 22 +++++++++++++++++++---
+ 2 files changed, 20 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+@@ -1017,6 +1017,7 @@ struct rt2x00_dev {
+ unsigned int extra_tx_headroom;
+
+ struct usb_anchor *anchor;
++ unsigned int num_proto_errs;
+
+ /* Clock for System On Chip devices. */
+ struct clk *clk;
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
+@@ -31,6 +31,22 @@
+ #include "rt2x00.h"
+ #include "rt2x00usb.h"
+
++static bool rt2x00usb_check_usb_error(struct rt2x00_dev *rt2x00dev, int status)
++{
++ if (status == -ENODEV || status == -ENOENT)
++ return true;
++
++ if (status == -EPROTO || status == -ETIMEDOUT)
++ rt2x00dev->num_proto_errs++;
++ else
++ rt2x00dev->num_proto_errs = 0;
++
++ if (rt2x00dev->num_proto_errs > 3)
++ return true;
++
++ return false;
++}
++
+ /*
+ * Interfacing with the HW.
+ */
+@@ -57,7 +73,7 @@ int rt2x00usb_vendor_request(struct rt2x
+ if (status >= 0)
+ return 0;
+
+- if (status == -ENODEV || status == -ENOENT) {
++ if (rt2x00usb_check_usb_error(rt2x00dev, status)) {
+ /* Device has disappeared. */
+ clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
+ break;
+@@ -321,7 +337,7 @@ static bool rt2x00usb_kick_tx_entry(stru
+
+ status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+ if (status) {
+- if (status == -ENODEV || status == -ENOENT)
++ if (rt2x00usb_check_usb_error(rt2x00dev, status))
+ clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
+ set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+ rt2x00lib_dmadone(entry);
+@@ -410,7 +426,7 @@ static bool rt2x00usb_kick_rx_entry(stru
+
+ status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+ if (status) {
+- if (status == -ENODEV || status == -ENOENT)
++ if (rt2x00usb_check_usb_error(rt2x00dev, status))
+ clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
+ set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+ rt2x00lib_dmadone(entry);
+++ /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
-X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
-X-Patchwork-Id: 10804441
-X-Patchwork-Delegate: kvalo@adurom.com
-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 patchwork Tue Mar 12 09:51:43 2019
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
+X-Patchwork-Id: 10848963
+X-Patchwork-Delegate: kvalo@adurom.com
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+To: linux-wireless@vger.kernel.org
+Cc: =?utf-8?q?Tomislav_Po=C5=BEega?= <pozega.tomislav@gmail.com>,
+ Daniel Golle <daniel@makrotopia.org>, Felix Fietkau <nbd@nbd.name>,
+ Mathias Kresin <dev@kresin.me>
+Subject: [PATCH v3 4/4] rt2x00: do not print error when queue is full
+Date: Tue, 12 Mar 2019 10:51:43 +0100
+Message-Id: <1552384303-29529-5-git-send-email-sgruszka@redhat.com>
+In-Reply-To: <1552384303-29529-1-git-send-email-sgruszka@redhat.com>
+References: <1552384303-29529-1-git-send-email-sgruszka@redhat.com>
+
+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
+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, ®)) {
++ 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 f6a9618198e190a2ba09ce3f0aa8e9ee1763bd38 Mon Sep 17 00:00:00 2001
-From: Stanislaw Gruszka <sgruszka@redhat.com>
-Date: Sat, 9 Feb 2019 12:08:34 +0100
-X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
-X-Patchwork-Id: 10804443
-X-Patchwork-Delegate: kvalo@adurom.com
-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 11f8ad1656035176bad9d89de7ea0e7fe6d82c32 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Sat, 9 Feb 2019 12:08:32 +0100
+X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
+X-Patchwork-Id: 10804439
+X-Patchwork-Delegate: kvalo@adurom.com
+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 175c2548332b45b144af673e70fdbb1a947d7aba Mon Sep 17 00:00:00 2001
-From: Stanislaw Gruszka <sgruszka@redhat.com>
-Date: Sat, 9 Feb 2019 12:08:35 +0100
-X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
-X-Patchwork-Id: 10804445
-X-Patchwork-Delegate: kvalo@adurom.com
-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 2bbea7645c3d095014a080db170941818650e141 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Sat, 9 Feb 2019 12:08:33 +0100
+X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
+X-Patchwork-Id: 10804441
+X-Patchwork-Delegate: kvalo@adurom.com
+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 6013a91f15c9dabd668d5736652b9bcfb0ef0378 Mon Sep 17 00:00:00 2001
-From: Stanislaw Gruszka <sgruszka@redhat.com>
-Date: Sat, 9 Feb 2019 12:08:36 +0100
-X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
-X-Patchwork-Id: 10804447
-X-Patchwork-Delegate: kvalo@adurom.com
-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 f6a9618198e190a2ba09ce3f0aa8e9ee1763bd38 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Sat, 9 Feb 2019 12:08:34 +0100
+X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
+X-Patchwork-Id: 10804443
+X-Patchwork-Delegate: kvalo@adurom.com
+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 2758f09b22bc08e89e0391486b2d707ad2479599 Mon Sep 17 00:00:00 2001
-From: Stanislaw Gruszka <sgruszka@redhat.com>
-Date: Sat, 9 Feb 2019 12:08:37 +0100
-X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
-X-Patchwork-Id: 10804449
-X-Patchwork-Delegate: kvalo@adurom.com
-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 175c2548332b45b144af673e70fdbb1a947d7aba Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Sat, 9 Feb 2019 12:08:35 +0100
+X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
+X-Patchwork-Id: 10804445
+X-Patchwork-Delegate: kvalo@adurom.com
+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 f44e145869bb517460648e4ed71b7e9001964d06 Mon Sep 17 00:00:00 2001
-From: Stanislaw Gruszka <sgruszka@redhat.com>
-Date: Sat, 9 Feb 2019 12:08:38 +0100
-X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
-X-Patchwork-Id: 10804451
-X-Patchwork-Delegate: kvalo@adurom.com
-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;
--- /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
+X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
+X-Patchwork-Id: 10804447
+X-Patchwork-Delegate: kvalo@adurom.com
+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
+X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
+X-Patchwork-Id: 10804449
+X-Patchwork-Delegate: kvalo@adurom.com
+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
+X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
+X-Patchwork-Id: 10804451
+X-Patchwork-Delegate: kvalo@adurom.com
+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;