mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 09:20:13 -04:00
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: 377aa17d2a ("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>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
} else {
|
||||
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_MCU_WA_TRI * MT_RING_SIZE;
|
||||
wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_TRI) - 1;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user