Commit 34b69548 authored by Felix Fietkau's avatar Felix Fietkau Committed by Kalle Valo
Browse files

wifi: mt76: do not increase mcu skb refcount if retry is not supported

If mcu_skb_prepare_msg is not implemented, incrementing skb refcount does not
work for mcu message retry. In some cases (e.g. on SDIO), shared skbs can trigger
a BUG_ON, crashing the system.
Fix this by only incrementing refcount if retry is actually supported.

Fixes: 3688c18b ("wifi: mt76: mt7915: retry mcu messages")
Closes: https://lore.kernel.org/r/d907b13a-f8be-4cb8-a0bb-560a21278041@notapiano/


Reported-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> #KernelCI
Tested-by: default avatarAlper Nebi Yasak <alpernebiyasak@gmail.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://patch.msgid.link/20240917110942.22077-1-nbd@nbd.name
parent 5575058b
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -84,13 +84,16 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
	mutex_lock(&dev->mcu.mutex);

	if (dev->mcu_ops->mcu_skb_prepare_msg) {
		orig_skb = skb;
		ret = dev->mcu_ops->mcu_skb_prepare_msg(dev, skb, cmd, &seq);
		if (ret < 0)
			goto out;
	}

retry:
	orig_skb = skb_get(skb);
	/* orig skb might be needed for retry, mcu_skb_send_msg consumes it */
	if (orig_skb)
		skb_get(orig_skb);
	ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq);
	if (ret < 0)
		goto out;
@@ -105,7 +108,7 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
	do {
		skb = mt76_mcu_get_response(dev, expires);
		if (!skb && !test_bit(MT76_MCU_RESET, &dev->phy.state) &&
		    retry++ < dev->mcu_ops->max_retry) {
		    orig_skb && retry++ < dev->mcu_ops->max_retry) {
			dev_err(dev->dev, "Retry message %08x (seq %d)\n",
				cmd, seq);
			skb = orig_skb;