diff options
author | Felix Fietkau <nbd@nbd.name> | 2019-02-24 23:16:45 +0100 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2019-02-26 10:28:19 +0100 |
commit | 72e5d479b8de4a3b3cbc01f9fcc4a6936f82414f (patch) | |
tree | 2e5d053a95c9f04d731915f260ea674429153af6 /drivers/net/wireless/mediatek | |
parent | 90f42f2d76d0ed29553cf0167bc8e86c22e5a214 (diff) | |
download | linux-72e5d479b8de4a3b3cbc01f9fcc4a6936f82414f.tar.gz |
mt76: mt76x02: issue watchdog reset on MCU request timeout
MCU request timeout usually indicates that the device is no longer responsive,
and it usually does not recover without a reset
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'drivers/net/wireless/mediatek')
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x02.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 28 |
3 files changed, 21 insertions, 9 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h index 3464b4ca2ea8..6915cce5def9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h @@ -98,6 +98,7 @@ struct mt76x02_dev { u32 tx_hang_reset; u8 tx_hang_check; + u8 mcu_timeout; struct mt76x02_calibration cal; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c index 4752c104abf3..6501b853b65c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c @@ -61,6 +61,7 @@ int mt76x02_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data, "MCU message %d (seq %d) timed out\n", cmd, seq); ret = -ETIMEDOUT; + dev->mcu_timeout = 1; break; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c index f0198eea2bb8..1229f19f2b02 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c @@ -494,18 +494,28 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev) static void mt76x02_check_tx_hang(struct mt76x02_dev *dev) { if (mt76x02_tx_hang(dev)) { - if (++dev->tx_hang_check < MT_TX_HANG_TH) - return; - - mt76x02_watchdog_reset(dev); - - dev->tx_hang_reset++; - dev->tx_hang_check = 0; - memset(dev->mt76.tx_dma_idx, 0xff, - sizeof(dev->mt76.tx_dma_idx)); + if (++dev->tx_hang_check >= MT_TX_HANG_TH) + goto restart; } else { dev->tx_hang_check = 0; } + + if (dev->mcu_timeout) + goto restart; + + return; + +restart: + mt76x02_watchdog_reset(dev); + + mutex_lock(&dev->mt76.mmio.mcu.mutex); + dev->mcu_timeout = 0; + mutex_unlock(&dev->mt76.mmio.mcu.mutex); + + dev->tx_hang_reset++; + dev->tx_hang_check = 0; + memset(dev->mt76.tx_dma_idx, 0xff, + sizeof(dev->mt76.tx_dma_idx)); } void mt76x02_wdt_work(struct work_struct *work) |