summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2026-07-27 15:04:26 +0000
committerFelix Fietkau <nbd@nbd.name>2026-08-01 14:49:43 +0000
commit6a4cabff1203791797683cf6be8f56bee983dc73 (patch)
tree72a27fd64e9c3b23dc3f49a687ecc9bf22e0b839
parent7c1924332e986019c6bcddf55c843361cccac73f (diff)
downloadlinux-6a4cabff1203791797683cf6be8f56bee983dc73.tar.gz
linux-6a4cabff1203791797683cf6be8f56bee983dc73.zip
wifi: mt76: mt7996: do not leave state behind after a failed WED attach
mt7996_mmio_wed_init() set dev->mt76.hwrro_mode and rx_token_size while building the WED configuration, before knowing whether the WED attach can succeed. A failed attach left the enlarged rx_token_size behind and reset hwrro_mode to MT76_HWRRO_OFF, clobbering the values that another RX datapath owner may have configured earlier in probe: on Airoha platforms with the wed_enable module parameter set, this broke the NPU offload configuration set up by mt76_npu_init() (NPU offload requires HW-RRO and a larger rx token space, and the attach always fails there since no SoC has both an Airoha NPU and MTK WED). Move both assignments after a successful attach, next to the existing success-only dma_dev/irq assignments. This is safe for the regular WED attach case: the first consumer of either field runs after probe continues (mtk_wed_device_attach() only invokes the init_buf callback; rx buffers are allocated via init_rx_buf from mtk_wed_start(), long after mt7996_mmio_wed_init() has returned). Within the WED configuration the HW-RRO checks were constant: the mode was assigned unconditionally right before them, and the hif2 path is only reachable after a successful main attach has set it. Resolve them to their constant values and drop the dead branches. Fixes: 377aa17d2aed ("wifi: mt76: mt7996: Add NPU offload support to MT7996 driver") Link: https://patch.msgid.link/20260727150434.1778520-7-nbd@nbd.name Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/mmio.c51
1 files changed, 19 insertions, 32 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
index ba064324a7cc..ac81be5fe023 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
@@ -493,9 +493,6 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
if (hif2 && !mtk_wed_device_active(&dev->mt76.mmio.wed))
return 0;
- dev->mt76.hwrro_mode = is_mt7996(&dev->mt76) ? MT76_HWRRO_V3
- : MT76_HWRRO_V3_1;
-
hif1_ofs = dev->hif2 ? MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0) : 0;
if (hif2)
@@ -520,23 +517,16 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
wed->wlan.wpdma_tx = wed->wlan.phy_base + hif1_ofs +
MT_TXQ_RING_BASE(0) +
MT7996_TXQ_BAND2 * MT_RING_SIZE;
- if (mt7996_has_hwrro(dev)) {
- if (is_mt7996(&dev->mt76)) {
- wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_EXT) - 1;
- wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
- MT_RXQ_RING_BASE(0) +
- MT7996_RXQ_TXFREE2 * MT_RING_SIZE;
- } else {
- wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_BAND1_EXT) - 1;
- wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
- MT_RXQ_RING_BASE(0) +
- MT7996_RXQ_MCU_WA_EXT * MT_RING_SIZE;
- }
+ if (is_mt7996(&dev->mt76)) {
+ wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_EXT) - 1;
+ wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
+ MT_RXQ_RING_BASE(0) +
+ MT7996_RXQ_TXFREE2 * MT_RING_SIZE;
} else {
+ wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_BAND1_EXT) - 1;
wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
MT_RXQ_RING_BASE(0) +
- MT7996_RXQ_MCU_WA_TRI * MT_RING_SIZE;
- wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_TRI) - 1;
+ MT7996_RXQ_MCU_WA_EXT * MT_RING_SIZE;
}
wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + hif1_ofs + MT_WFDMA0_GLO_CFG;
@@ -547,7 +537,7 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
wed->wlan.id = MT7996_DEVICE_ID_2;
wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
} else {
- wed->wlan.hw_rro = mt7996_has_hwrro(dev);
+ wed->wlan.hw_rro = true;
wed->wlan.wpdma_int = wed->wlan.phy_base + MT_INT_SOURCE_CSR;
wed->wlan.wpdma_mask = wed->wlan.phy_base + MT_INT_MASK_CSR;
wed->wlan.wpdma_tx = wed->wlan.phy_base + MT_TXQ_RING_BASE(0) +
@@ -600,23 +590,15 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND0) - 1;
wed->wlan.tx_tbit[1] = ffs(MT_INT_TX_DONE_BAND1) - 1;
if (is_mt7996(&dev->mt76)) {
- if (mt7996_has_hwrro(dev)) {
- wed->wlan.wpdma_txfree = wed->wlan.phy_base +
- MT_RXQ_RING_BASE(0) +
- MT7996_RXQ_TXFREE0 * MT_RING_SIZE;
- wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_MAIN) - 1;
- } else {
- wed->wlan.wpdma_txfree = wed->wlan.phy_base +
- MT_RXQ_RING_BASE(0) +
- MT7996_RXQ_MCU_WA_MAIN * MT_RING_SIZE;
- wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_MAIN) - 1;
- }
+ wed->wlan.wpdma_txfree = wed->wlan.phy_base +
+ MT_RXQ_RING_BASE(0) +
+ MT7996_RXQ_TXFREE0 * MT_RING_SIZE;
+ wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_MAIN) - 1;
} else {
wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_MAIN) - 1;
wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
MT7996_RXQ_MCU_WA_MAIN * MT_RING_SIZE;
}
- dev->mt76.rx_token_size = MT7996_TOKEN_SIZE + wed->wlan.rx_npkt;
if (dev->hif2 && is_mt7992(&dev->mt76))
wed->wlan.id = 0x7992;
@@ -639,9 +621,14 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
wed->wlan.reset_complete = mt76_wed_reset_complete;
}
- if (mtk_wed_device_attach(wed)) {
- dev->mt76.hwrro_mode = MT76_HWRRO_OFF;
+ if (mtk_wed_device_attach(wed))
return 0;
+
+ if (!hif2) {
+ dev->mt76.hwrro_mode = is_mt7996(&dev->mt76) ? MT76_HWRRO_V3
+ : MT76_HWRRO_V3_1;
+ dev->mt76.rx_token_size = MT7996_TOKEN_SIZE +
+ wed->wlan.rx_npkt;
}
*irq = wed->irq;