From 9dd5beb7f0393049ae3076adc77bd2920ff7d8da Mon Sep 17 00:00:00 2001 From: Rex Lu Date: Tue, 9 Sep 2025 11:45:15 +0200 Subject: [PATCH] wifi: mt76: mt7996: Introduce the capability to reset MT7992 WED device This is a preliminary patch to enable WED support for MT7992 Kite chipset supported by MT7996 driver. Co-developed-by: Sujuan Chen Signed-off-by: Sujuan Chen Co-developed-by: Benjamin Lin Signed-off-by: Benjamin Lin Signed-off-by: Rex Lu Co-developed-by: Lorenzo Bianconi Signed-off-by: Lorenzo Bianconi Link: https://patch.msgid.link/20250909-mt7996-rro-rework-v5-7-7d66f6eb7795@kernel.org Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt7996/init.c | 6 ++-- .../net/wireless/mediatek/mt76/mt7996/mac.c | 30 +++++++++++++++++++ .../wireless/mediatek/mt76/mt7996/mt7996.h | 1 + 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c index 93144b5e95647..73a55eea53587 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c @@ -756,9 +756,9 @@ void mt7996_wfsys_reset(struct mt7996_dev *dev) msleep(20); } -#ifdef CONFIG_NET_MEDIATEK_SOC_WED -static void mt7996_rro_hw_init(struct mt7996_dev *dev) +void mt7996_rro_hw_init(struct mt7996_dev *dev) { +#ifdef CONFIG_NET_MEDIATEK_SOC_WED struct mtk_wed_device *wed = &dev->mt76.mmio.wed; u32 reg = MT_RRO_ADDR_ELEM_SEG_ADDR0; int i; @@ -838,8 +838,8 @@ static void mt7996_rro_hw_init(struct mt7996_dev *dev) /* interrupt enable */ mt76_wr(dev, MT_RRO_HOST_INT_ENA, MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA); -} #endif +} static int mt7996_wed_rro_init(struct mt7996_dev *dev) { diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c index 8a75d7a7b0c04..8aeea7ecc0dad 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c @@ -1913,6 +1913,32 @@ mt7996_mac_restart(struct mt7996_dev *dev) if (ret) goto out; + if (mtk_wed_device_active(&dev->mt76.mmio.wed) && dev->has_rro) { + u32 wed_irq_mask = dev->mt76.mmio.irqmask | + MT_INT_RRO_RX_DONE | + MT_INT_TX_DONE_BAND2; + + mt7996_rro_hw_init(dev); + mt76_for_each_q_rx(&dev->mt76, i) { + if (mt76_queue_is_wed_rro_ind(&dev->mt76.q_rx[i]) || + mt76_queue_is_wed_rro_msdu_pg(&dev->mt76.q_rx[i])) + mt76_queue_rx_reset(dev, i); + } + + mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask); + mtk_wed_device_start_hw_rro(&dev->mt76.mmio.wed, wed_irq_mask, + false); + mt7996_irq_enable(dev, wed_irq_mask); + mt7996_irq_disable(dev, 0); + } + + if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2)) { + mt76_wr(dev, MT_INT_PCIE1_MASK_CSR, + MT_INT_TX_RX_DONE_EXT); + mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, + MT_INT_TX_RX_DONE_EXT); + } + /* set the necessary init items */ ret = mt7996_mcu_set_eeprom(dev); if (ret) @@ -2125,6 +2151,10 @@ void mt7996_mac_reset_work(struct work_struct *work) mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask); + if (is_mt7992(&dev->mt76) && dev->has_rro) + mt76_wr(dev, MT_RRO_3_0_EMU_CONF, + MT_RRO_3_0_EMU_CONF_EN_MASK); + mtk_wed_device_start_hw_rro(&dev->mt76.mmio.wed, wed_irq_mask, true); mt7996_irq_enable(dev, wed_irq_mask); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index 094ea070369a8..9af3382003bcf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -569,6 +569,7 @@ extern struct pci_driver mt7996_hif_driver; struct mt7996_dev *mt7996_mmio_probe(struct device *pdev, void __iomem *mem_base, u32 device_id); +void mt7996_rro_hw_init(struct mt7996_dev *dev); void mt7996_wfsys_reset(struct mt7996_dev *dev); irqreturn_t mt7996_irq_handler(int irq, void *dev_instance); u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif_link *link); -- 2.47.3