Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af0fe2c2 authored by Felix Fietkau's avatar Felix Fietkau Committed by Greg Kroah-Hartman
Browse files

wifi: mt76: mt7603: rework/fix rx pse hang check



[ Upstream commit baa19b2e4b7bbb509a7ca7939c8785477dcd40ee ]

It turns out that the code in mt7603_rx_pse_busy() does not detect actual
hardware hangs, it only checks for busy conditions in PSE.
A reset should only be performed if these conditions are true and if there
is no rx activity as well.
Reset the counter whenever a rx interrupt occurs. In order to also deal with
a fully loaded CPU that leaves interrupts disabled with continuous NAPI
polling, also check for pending rx interrupts in the function itself.

Fixes: c8846e10 ("mt76: add driver for MT7603E and MT7628/7688")
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent a2e99dbd
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -39,11 +39,13 @@ irqreturn_t mt7603_irq_handler(int irq, void *dev_instance)
	}

	if (intr & MT_INT_RX_DONE(0)) {
		dev->rx_pse_check = 0;
		mt7603_irq_disable(dev, MT_INT_RX_DONE(0));
		napi_schedule(&dev->mt76.napi[0]);
	}

	if (intr & MT_INT_RX_DONE(1)) {
		dev->rx_pse_check = 0;
		mt7603_irq_disable(dev, MT_INT_RX_DONE(1));
		napi_schedule(&dev->mt76.napi[1]);
	}
+16 −7
Original line number Diff line number Diff line
@@ -1416,20 +1416,29 @@ static bool mt7603_rx_pse_busy(struct mt7603_dev *dev)
{
	u32 addr, val;

	if (mt76_rr(dev, MT_MCU_DEBUG_RESET) & MT_MCU_DEBUG_RESET_QUEUES)
		return true;

	if (mt7603_rx_fifo_busy(dev))
		return false;
		goto out;

	addr = mt7603_reg_map(dev, MT_CLIENT_BASE_PHYS_ADDR + MT_CLIENT_STATUS);
	mt76_wr(dev, addr, 3);
	val = mt76_rr(dev, addr) >> 16;

	if (is_mt7628(dev) && (val & 0x4001) == 0x4001)
		return true;
	if (!(val & BIT(0)))
		return false;

	if (is_mt7628(dev))
		val &= 0xa000;
	else
		val &= 0x8000;
	if (!val)
		return false;

	return (val & 0x8001) == 0x8001 || (val & 0xe001) == 0xe001;
out:
	if (mt76_rr(dev, MT_INT_SOURCE_CSR) &
	    (MT_INT_RX_DONE(0) | MT_INT_RX_DONE(1)))
		return false;

	return true;
}

static bool