summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Monroe <chad@monroe.io>2026-07-24 12:48:08 +0000
committerFelix Fietkau <nbd@nbd.name>2026-08-01 14:49:42 +0000
commit496ea8ceb2113d0fdeb1b37437d3a4d282162b2f (patch)
tree4edda190bf634cd8babcbd1cf34a6e2838e19af6
parent98aff74779da9f417386c589c36848e9c568f0f9 (diff)
downloadlinux-496ea8ceb2113d0fdeb1b37437d3a4d282162b2f.tar.gz
linux-496ea8ceb2113d0fdeb1b37437d3a4d282162b2f.zip
wifi: mt76: mt7915: trigger L1 SER on PLE MDP RIOC hang
WM firmware can enter a partial failure state where RX is hung. Detect this condition by monitoring SER_PLE_ERR_1 for MDP_RIOC_HANG_ERR and trigger L1 SER to restore operation. Use transition detection on the error bit to fire only once per new occurrence, preventing an infinite SER loop when the bit remains set across checks. Signed-off-by: Chad Monroe <chad@monroe.io> Suggested-by: Ryder Lee <ryder.lee@mediatek.com> Link: https://patch.msgid.link/20260724124813.3961474-24-nbd@nbd.name Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mac.c13
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h1
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/regs.h1
3 files changed, 14 insertions, 1 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 350d4573ced2..df6359c88b18 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1934,7 +1934,7 @@ void mt7915_mac_update_stats(struct mt7915_phy *phy)
static void mt7915_mac_severe_check(struct mt7915_phy *phy)
{
struct mt7915_dev *dev = phy->dev;
- u32 trb;
+ u32 trb, ple_err;
if (!phy->omac_mask)
return;
@@ -1954,6 +1954,17 @@ static void mt7915_mac_severe_check(struct mt7915_phy *phy)
phy->mt76->band_idx);
phy->trb_ts = trb;
+
+ ple_err = mt76_rr(dev, MT_SWDEF_PLE1_STATS);
+ if ((ple_err & MT_SWDEF_PLE1_MDP_RIOC_HANG_ERR) &&
+ !(dev->ple1_sts & MT_SWDEF_PLE1_MDP_RIOC_HANG_ERR)) {
+ dev_warn(dev->mt76.dev,
+ "band%d: PLE error 0x%x detected, triggering L1 SER\n",
+ phy->mt76->band_idx, ple_err);
+ mt7915_mcu_set_ser(dev, SER_RECOVER, SER_SET_RECOVER_L1,
+ phy->mt76->band_idx);
+ }
+ dev->ple1_sts = ple_err;
}
void mt7915_mac_sta_rc_work(struct work_struct *work)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 92e0f9f0169c..0f7e871dc7a1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -296,6 +296,7 @@ struct mt7915_dev {
spinlock_t reg_lock;
u32 hw_pattern;
+ u32 ple1_sts;
bool dbdc_support;
bool flash_mode;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
index 307bf6a75674..dc7bb9a1f223 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
@@ -1044,6 +1044,7 @@ enum offs_rev {
#define MT_SWDEF_SER_STATS MT_SWDEF(0x040)
#define MT_SWDEF_PLE_STATS MT_SWDEF(0x044)
#define MT_SWDEF_PLE1_STATS MT_SWDEF(0x048)
+#define MT_SWDEF_PLE1_MDP_RIOC_HANG_ERR BIT(3)
#define MT_SWDEF_PLE_AMSDU_STATS MT_SWDEF(0x04C)
#define MT_SWDEF_PSE_STATS MT_SWDEF(0x050)
#define MT_SWDEF_PSE1_STATS MT_SWDEF(0x054)