mt76: mt7615: fix hardware error recovery for mt7663
authorFelix Fietkau <nbd@nbd.name>
Thu, 15 Apr 2021 18:57:42 +0000 (20:57 +0200)
committerFelix Fietkau <nbd@nbd.name>
Wed, 21 Apr 2021 09:42:22 +0000 (11:42 +0200)
MT7663 uses different bits for communicating reset commands/status between MCU
and host. Also add an extra initial reset command.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7615/dma.c
drivers/net/wireless/mediatek/mt76/mt7615/mmio.c
drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
drivers/net/wireless/mediatek/mt76/mt7615/regs.h

index 0ec1c52..642b4ea 100644 (file)
@@ -187,14 +187,19 @@ void mt7615_dma_start(struct mt7615_dev *dev)
        if (is_mt7622(&dev->mt76))
                mt7622_dma_sched_init(dev);
 
-       if (is_mt7663(&dev->mt76))
+       if (is_mt7663(&dev->mt76)) {
                mt7663_dma_sched_init(dev);
+
+               mt76_wr(dev, MT_MCU2HOST_INT_ENABLE, MT7663_MCU_CMD_ERROR_MASK);
+       }
+
 }
 
 int mt7615_dma_init(struct mt7615_dev *dev)
 {
        int rx_ring_size = MT7615_RX_RING_SIZE;
        int rx_buf_size = MT_RX_BUF_SIZE;
+       u32 mask;
        int ret;
 
        /* Increase buffer size to receive large VHT MPDUs */
@@ -269,8 +274,14 @@ int mt7615_dma_init(struct mt7615_dev *dev)
                  MT_WPDMA_GLO_CFG_RX_DMA_BUSY, 0, 1000);
 
        /* enable interrupts for TX/RX rings */
-       mt7615_irq_enable(dev, MT_INT_RX_DONE_ALL | mt7615_tx_mcu_int_mask(dev) |
-                              MT_INT_MCU_CMD);
+
+       mask = MT_INT_RX_DONE_ALL | mt7615_tx_mcu_int_mask(dev);
+       if (is_mt7663(&dev->mt76))
+           mask |= MT7663_INT_MCU_CMD;
+       else
+           mask |= MT_INT_MCU_CMD;
+
+       mt7615_irq_enable(dev, mask);
 
        mt7615_dma_start(dev);
 
index eaa2275..be93e7a 100644 (file)
@@ -105,6 +105,7 @@ static void mt7615_irq_tasklet(struct tasklet_struct *t)
 {
        struct mt7615_dev *dev = from_tasklet(dev, t, irq_tasklet);
        u32 intr, mask = 0, tx_mcu_mask = mt7615_tx_mcu_int_mask(dev);
+       u32 mcu_int;
 
        mt76_wr(dev, MT_INT_MASK_CSR, 0);
 
@@ -128,15 +129,23 @@ static void mt7615_irq_tasklet(struct tasklet_struct *t)
        if (intr & MT_INT_RX_DONE(1))
                napi_schedule(&dev->mt76.napi[1]);
 
-       if (intr & MT_INT_MCU_CMD) {
-               u32 val = mt76_rr(dev, MT_MCU_CMD);
+       if (!(intr & (MT_INT_MCU_CMD | MT7663_INT_MCU_CMD)))
+               return;
 
-               if (val & MT_MCU_CMD_ERROR_MASK) {
-                       dev->reset_state = val;
-                       ieee80211_queue_work(mt76_hw(dev), &dev->reset_work);
-                       wake_up(&dev->reset_wait);
-               }
+       if (is_mt7663(&dev->mt76)) {
+               mcu_int = mt76_rr(dev, MT_MCU2HOST_INT_STATUS);
+               mcu_int &= MT7663_MCU_CMD_ERROR_MASK;
+       } else {
+               mcu_int = mt76_rr(dev, MT_MCU_CMD);
+               mcu_int &= MT_MCU_CMD_ERROR_MASK;
        }
+
+       if (!mcu_int)
+               return;
+
+       dev->reset_state = mcu_int;
+       ieee80211_queue_work(mt76_hw(dev), &dev->reset_work);
+       wake_up(&dev->reset_wait);
 }
 
 static u32 __mt7615_reg_addr(struct mt7615_dev *dev, u32 addr)
index a03484e..49540b0 100644 (file)
@@ -47,6 +47,12 @@ static int mt7615_init_hardware(struct mt7615_dev *dev)
        if (ret < 0)
                return ret;
 
+       if (is_mt7663(&dev->mt76)) {
+               /* Reset RGU */
+               mt76_clear(dev, MT_MCU_CIRQ_IRQ_SEL(4), BIT(1));
+               mt76_set(dev, MT_MCU_CIRQ_IRQ_SEL(4), BIT(1));
+       }
+
        ret = mt7615_dma_init(dev);
        if (ret)
                return ret;
index 8cd79e8..d20962c 100644 (file)
@@ -210,7 +210,12 @@ EXPORT_SYMBOL_GPL(mt7615_dma_reset);
 static void
 mt7615_hif_int_event_trigger(struct mt7615_dev *dev, u8 event)
 {
-       mt76_wr(dev, MT_MCU_INT_EVENT, event);
+       u32 reg = MT_MCU_INT_EVENT;
+
+       if (is_mt7663(&dev->mt76))
+               reg = MT7663_MCU_INT_EVENT;
+
+       mt76_wr(dev, reg, event);
 
        mt7622_trigger_hif_int(dev, true);
        mt7622_trigger_hif_int(dev, false);
index 190a026..63c081b 100644 (file)
@@ -61,6 +61,11 @@ enum mt7615_reg_base {
 #define MT_MCU_PCIE_REMAP_2_BASE       GENMASK(31, 19)
 #define MT_PCIE_REMAP_BASE_2           ((dev)->reg_map[MT_PCIE_REMAP_BASE2])
 
+#define MT_MCU_CIRQ_BASE               0xc0000
+#define MT_MCU_CIRQ(ofs)               (MT_MCU_CIRQ_BASE + (ofs))
+
+#define MT_MCU_CIRQ_IRQ_SEL(n)         MT_MCU_CIRQ((n) << 2)
+
 #define MT_HIF(ofs)                    ((dev)->reg_map[MT_HIF_BASE] + (ofs))
 #define MT_HIF_RST                     MT_HIF(0x100)
 #define MT_HIF_LOGIC_RST_N             BIT(4)
@@ -88,6 +93,10 @@ enum mt7615_reg_base {
 #define MT_CFG_LPCR_HOST_FW_OWN                BIT(0)
 #define MT_CFG_LPCR_HOST_DRV_OWN       BIT(1)
 
+#define MT_MCU2HOST_INT_STATUS         MT_HIF(0x1f0)
+#define MT_MCU2HOST_INT_ENABLE         MT_HIF(0x1f4)
+
+#define MT7663_MCU_INT_EVENT           MT_HIF(0x108)
 #define MT_MCU_INT_EVENT               MT_HIF(0x1f8)
 #define MT_MCU_INT_EVENT_PDMA_STOPPED  BIT(0)
 #define MT_MCU_INT_EVENT_PDMA_INIT     BIT(1)
@@ -102,6 +111,7 @@ enum mt7615_reg_base {
 #define MT_INT_RX_DONE_ALL             GENMASK(1, 0)
 #define MT_INT_TX_DONE_ALL             GENMASK(19, 4)
 #define MT_INT_TX_DONE(_n)             BIT((_n) + 4)
+#define MT7663_INT_MCU_CMD             BIT(29)
 #define MT_INT_MCU_CMD                 BIT(30)
 
 #define MT_WPDMA_GLO_CFG               MT_HIF(0x208)
@@ -138,6 +148,7 @@ enum mt7615_reg_base {
 #define MT_MCU_CMD_PDMA_ERROR          BIT(27)
 #define MT_MCU_CMD_PCIE_ERROR          BIT(28)
 #define MT_MCU_CMD_ERROR_MASK          (GENMASK(5, 1) | GENMASK(28, 24))
+#define MT7663_MCU_CMD_ERROR_MASK      GENMASK(5, 2)
 
 #define MT_TX_RING_BASE                        MT_HIF(0x300)
 #define MT_RX_RING_BASE                        MT_HIF(0x400)