[rt2x00-users] rt3290: WPDMA TX/RX busy after sysrq+reisub or a restart

Giedrius Statkevicius giedriuswork at gmail.com
Thu Dec 18 08:19:50 AEDT 2014

With this card I'm hitting a pretty annoying bug:
03:00.0 Network controller: Ralink corp. RT3290 Wireless 802.11n 1T/1R PCIe

On my current setup I am using NetworkManager and only after doing
sysrq+reisub I hit it. One time I've tried using connman and with that
after a simple restart it happens. In both cases only shutting down
completely and restarting helps to fix this. It still happens in
linux-next and originally I tested this on 3.17.7.

So, after sysrq+reisub with NM or just a restart with connman the card
stops working properly and the driver is spamming this inside dmesg:

[   25.393470] ieee80211 phy0: rt2800_wait_wpdma_ready: Error - WPDMA TX/RX busy [0x00000068]
[   26.494734] ieee80211 phy0: rt2800_wait_wpdma_ready: Error - WPDMA TX/RX busy [0x00000068]
[   26.494744] ieee80211 phy0: rt2800pci_set_device_state: Error - Device failed to enter state 4 (-5)

I tried loading rt2800pci with nohwcrypt parameter on but it still
happens. Next, I've tried to look more into the code.
rt2800_wait_wpdma_ready() is reading WPDMA_GLO_CFG_TX_DMA_BUSY and
WPDMA_GLO_CFG_RX_DMA_BUSY and returns -EIO if they are set to 1 after
trying a few times.

First I've tried increasing the timeout time in msleep() but it just
made my system freeze and the issue still persisted. So, then I've tried
the patch attached that from my experience writes 0 to those two
registers if one test fails in rt2800_wait_wpdma_ready(). My first idea
was to do this because I thought if this is a simple mistake of not
resetting the registers values then it should fix it.  But that didn't
help either. My questions are:

* Is the patch correct that it writes 0 to those two registers after one
  test fails? If no, I'll fix it up and try again. 

* Where could I find some technical documentation about this chip?

I'll try to look more into this bug.

 drivers/net/wireless/rt2x00/rt2800lib.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 81ee481..d1d8d30 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -494,6 +494,9 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
 		    !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
 			return 0;
+		rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
+		rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);

More information about the users mailing list