mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 13:26:48 +00:00
mt7603: improve recovery from MCU hang
Fix forcing watchdog reset after a MCU hang Run watchdog work immediately after a failed channel change Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
@@ -27,6 +27,7 @@ mt7603_reset_read(struct seq_file *s, void *data)
|
||||
[RESET_CAUSE_RX_BUSY] = "RX DMA busy stuck",
|
||||
[RESET_CAUSE_RX_PSE_BUSY] = "RX PSE busy stuck",
|
||||
[RESET_CAUSE_BEACON_STUCK] = "Beacon stuck",
|
||||
[RESET_CAUSE_MCU_HANG] = "MCU hang",
|
||||
};
|
||||
int i;
|
||||
|
||||
|
||||
@@ -1375,12 +1375,16 @@ void mt7603_mac_work(struct work_struct *work)
|
||||
mt7603_watchdog_check(dev, &dev->beacon_check,
|
||||
RESET_CAUSE_BEACON_STUCK,
|
||||
NULL) ||
|
||||
mt7603_watchdog_check(dev, &dev->mcu_hang,
|
||||
RESET_CAUSE_MCU_HANG,
|
||||
NULL) ||
|
||||
dev->pse_reset_failed) {
|
||||
dev->beacon_check = 0;
|
||||
dev->tx_dma_check = 0;
|
||||
dev->tx_hang_check = 0;
|
||||
dev->rx_dma_check = 0;
|
||||
dev->rx_pse_check = 0;
|
||||
dev->mcu_hang = 0;
|
||||
dev->rx_dma_idx = ~0;
|
||||
memset(dev->tx_dma_idx, 0xff, sizeof(dev->tx_dma_idx));
|
||||
reset = true;
|
||||
|
||||
+8
-3
@@ -27,11 +27,10 @@ mt7603_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct mt7603_dev *dev = hw->priv;
|
||||
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work,
|
||||
MT7603_WATCHDOG_TIME);
|
||||
mt7603_mac_start(dev);
|
||||
dev->survey_time = ktime_get_boottime();
|
||||
set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
|
||||
mt7603_mac_work(&dev->mac_work.work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -130,6 +129,7 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def)
|
||||
u8 *rssi_data = (u8 *) dev->mt76.eeprom.data;
|
||||
int idx, ret;
|
||||
u8 bw = MT_BW_20;
|
||||
bool failed = true;
|
||||
|
||||
cancel_delayed_work_sync(&dev->mac_work);
|
||||
|
||||
@@ -145,8 +145,10 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def)
|
||||
dev->mt76.chandef = *def;
|
||||
mt76_rmw_field(dev, MT_AGG_BWCR, MT_AGG_BWCR_BW, bw);
|
||||
ret = mt7603_mcu_set_channel(dev);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
failed = true;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (def->chan->band == NL80211_BAND_5GHZ) {
|
||||
idx = 1;
|
||||
@@ -182,6 +184,9 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def)
|
||||
out:
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
|
||||
if (failed)
|
||||
mt7603_mac_work(&dev->mac_work.work);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -130,7 +130,7 @@ mt7603_mcu_msg_send(struct mt7603_dev *dev, struct sk_buff *skb, int cmd, int qu
|
||||
dev_err(mdev->dev,
|
||||
"MCU message %d (seq %d) timed out\n",
|
||||
cmd, seq);
|
||||
dev->tx_dma_check = MT7603_WATCHDOG_TIMEOUT;
|
||||
dev->mcu_hang = MT7603_WATCHDOG_TIMEOUT;
|
||||
ret = -ETIMEDOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ enum mt7603_reset_cause {
|
||||
RESET_CAUSE_RX_BUSY,
|
||||
RESET_CAUSE_BEACON_STUCK,
|
||||
RESET_CAUSE_RX_PSE_BUSY,
|
||||
RESET_CAUSE_MCU_HANG,
|
||||
__RESET_CAUSE_MAX
|
||||
};
|
||||
|
||||
@@ -124,6 +125,7 @@ struct mt7603_dev {
|
||||
u8 tx_dma_check;
|
||||
u8 rx_dma_check;
|
||||
u8 rx_pse_check;
|
||||
u8 mcu_hang;
|
||||
u8 pse_reset_failed;
|
||||
|
||||
u16 tx_dma_idx[4];
|
||||
|
||||
Reference in New Issue
Block a user