[PATCH 4.20 005/183] mt76x0u: fix suspend/resume

From: Greg Kroah-Hartman
Date: Mon Feb 25 2019 - 16:28:45 EST


4.20-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stanislaw Gruszka <sgruszka@xxxxxxxxxx>

commit d04ca383860bef90a0dab4eb397907f7f05e839e upstream.

We need to reset MCU and do other initializations on resume otherwise
MT7610U device will fail to initialize, what cause system hung due to
USB requests timeouts.

Patch fixes 4.19 -> 4.20 regression.

Cc: stable@xxxxxxxxxxxxxxx # 4.20+
Signed-off-by: Stanislaw Gruszka <sgruszka@xxxxxxxxxx>
Acked-by: Lorenzo Bianconi <lorenzo.bianconi@xxxxxxxxxx>
Signed-off-by: Kalle Valo <kvalo@xxxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 46 +++++++++++++++---------
1 file changed, 29 insertions(+), 17 deletions(-)

--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -159,39 +159,49 @@ static const struct ieee80211_ops mt76x0
.wake_tx_queue = mt76_wake_tx_queue,
};

-static int mt76x0u_register_device(struct mt76x02_dev *dev)
+static int mt76x0u_init_hardware(struct mt76x02_dev *dev)
{
- struct ieee80211_hw *hw = dev->mt76.hw;
int err;

- err = mt76u_alloc_queues(&dev->mt76);
- if (err < 0)
- goto out_err;
-
- err = mt76u_mcu_init_rx(&dev->mt76);
- if (err < 0)
- goto out_err;
-
mt76x0_chip_onoff(dev, true, true);
- if (!mt76x02_wait_for_mac(&dev->mt76)) {
- err = -ETIMEDOUT;
- goto out_err;
- }
+
+ if (!mt76x02_wait_for_mac(&dev->mt76))
+ return -ETIMEDOUT;

err = mt76x0u_mcu_init(dev);
if (err < 0)
- goto out_err;
+ return err;

mt76x0_init_usb_dma(dev);
err = mt76x0_init_hardware(dev);
if (err < 0)
- goto out_err;
+ return err;

mt76_rmw(dev, MT_US_CYC_CFG, MT_US_CYC_CNT, 0x1e);
mt76_wr(dev, MT_TXOP_CTRL_CFG,
FIELD_PREP(MT_TXOP_TRUN_EN, 0x3f) |
FIELD_PREP(MT_TXOP_EXT_CCA_DLY, 0x58));

+ return 0;
+}
+
+static int mt76x0u_register_device(struct mt76x02_dev *dev)
+{
+ struct ieee80211_hw *hw = dev->mt76.hw;
+ int err;
+
+ err = mt76u_alloc_queues(&dev->mt76);
+ if (err < 0)
+ goto out_err;
+
+ err = mt76u_mcu_init_rx(&dev->mt76);
+ if (err < 0)
+ goto out_err;
+
+ err = mt76x0u_init_hardware(dev);
+ if (err < 0)
+ goto out_err;
+
err = mt76x0_register_device(dev);
if (err < 0)
goto out_err;
@@ -300,6 +310,8 @@ static int __maybe_unused mt76x0_suspend

mt76u_stop_queues(&dev->mt76);
mt76x0u_mac_stop(dev);
+ clear_bit(MT76_STATE_MCU_RUNNING, &dev->mt76.state);
+ mt76x0_chip_onoff(dev, false, false);
usb_kill_urb(usb->mcu.res.urb);

return 0;
@@ -327,7 +339,7 @@ static int __maybe_unused mt76x0_resume(
tasklet_enable(&usb->rx_tasklet);
tasklet_enable(&usb->tx_tasklet);

- ret = mt76x0_init_hardware(dev);
+ ret = mt76x0u_init_hardware(dev);
if (ret)
goto err;