mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 13:26:48 +00:00
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: 3688c18b65ae ("wifi: mt76: mt7915: retry mcu messages")
Reported-by: Nícolas F. R. A. Prado <[email protected]> #KernelCI
Tested-by: Alper Nebi Yasak <[email protected]>
Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
@@ -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);
|
mutex_lock(&dev->mcu.mutex);
|
||||||
|
|
||||||
if (dev->mcu_ops->mcu_skb_prepare_msg) {
|
if (dev->mcu_ops->mcu_skb_prepare_msg) {
|
||||||
|
orig_skb = skb;
|
||||||
ret = dev->mcu_ops->mcu_skb_prepare_msg(dev, skb, cmd, &seq);
|
ret = dev->mcu_ops->mcu_skb_prepare_msg(dev, skb, cmd, &seq);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
retry:
|
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);
|
ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -105,7 +108,7 @@ retry:
|
|||||||
do {
|
do {
|
||||||
skb = mt76_mcu_get_response(dev, expires);
|
skb = mt76_mcu_get_response(dev, expires);
|
||||||
if (!skb && !test_bit(MT76_MCU_RESET, &dev->phy.state) &&
|
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",
|
dev_err(dev->dev, "Retry message %08x (seq %d)\n",
|
||||||
cmd, seq);
|
cmd, seq);
|
||||||
skb = orig_skb;
|
skb = orig_skb;
|
||||||
|
|||||||
Reference in New Issue
Block a user