mt76x02: improve mac error check/reset reliability
On AP mode devices, check beacon tx counters to detect MAC errors. When an error is detected, stop the MAC before resetting it Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
@@ -104,6 +104,7 @@ struct mt76x02_dev {
|
||||
|
||||
u32 tx_hang_reset;
|
||||
u8 tx_hang_check;
|
||||
u8 beacon_hang_check;
|
||||
u8 mcu_timeout;
|
||||
|
||||
struct mt76x02_calibration cal;
|
||||
|
||||
@@ -1040,12 +1040,26 @@ EXPORT_SYMBOL_GPL(mt76x02_update_channel);
|
||||
|
||||
static void mt76x02_check_mac_err(struct mt76x02_dev *dev)
|
||||
{
|
||||
u32 val = mt76_rr(dev, 0x10f4);
|
||||
if (dev->mt76.beacon_mask) {
|
||||
if (mt76_rr(dev, MT_TX_STA_0) & MT_TX_STA_0_BEACONS) {
|
||||
dev->beacon_hang_check = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(val & BIT(29)) || !(val & (BIT(7) | BIT(5))))
|
||||
return;
|
||||
if (++dev->beacon_hang_check < 10)
|
||||
return;
|
||||
|
||||
dev_err(dev->mt76.dev, "mac specific condition occurred\n");
|
||||
dev->beacon_hang_check = 0;
|
||||
} else {
|
||||
u32 val = mt76_rr(dev, 0x10f4);
|
||||
if (!(val & BIT(29)) || !(val & (BIT(7) | BIT(5))))
|
||||
return;
|
||||
}
|
||||
|
||||
dev_err(dev->mt76.dev, "MAC error detected\n");
|
||||
|
||||
mt76_wr(dev, MT_MAC_SYS_CTRL, 0);
|
||||
mt76x02_wait_for_txrx_idle(&dev->mt76);
|
||||
|
||||
mt76_set(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_RESET_CSR);
|
||||
udelay(10);
|
||||
@@ -1178,8 +1192,7 @@ void mt76x02_mac_work(struct work_struct *work)
|
||||
dev->mt76.aggr_stats[idx++] += val >> 16;
|
||||
}
|
||||
|
||||
if (!dev->mt76.beacon_mask)
|
||||
mt76x02_check_mac_err(dev);
|
||||
mt76x02_check_mac_err(dev);
|
||||
|
||||
if (dev->ed_monitor)
|
||||
mt76x02_edcca_check(dev);
|
||||
|
||||
@@ -571,6 +571,8 @@
|
||||
#define MT_RX_STAT_2_OVERFLOW_ERRORS GENMASK(31, 16)
|
||||
|
||||
#define MT_TX_STA_0 0x170c
|
||||
#define MT_TX_STA_0_BEACONS GENMASK(31, 16)
|
||||
|
||||
#define MT_TX_STA_1 0x1710
|
||||
#define MT_TX_STA_2 0x1714
|
||||
|
||||
|
||||
Reference in New Issue
Block a user