mt76x02: improve mac error check/reset reliability
authorFelix Fietkau <nbd@nbd.name>
Mon, 31 Jan 2022 10:35:34 +0000 (11:35 +0100)
committerFelix Fietkau <nbd@nbd.name>
Thu, 3 Feb 2022 13:34:35 +0000 (14:34 +0100)
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>
drivers/net/wireless/mediatek/mt76/mt76x02.h
drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
drivers/net/wireless/mediatek/mt76/mt76x02_regs.h

index 44d1a92..3232083 100644 (file)
@@ -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;
index a404fd7..dc2aeaa 100644 (file)
@@ -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->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");
 
-       dev_err(dev->mt76.dev, "mac specific condition occurred\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);
index fa7872a..fe0c5e3 100644 (file)
 #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