diff options
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mcu.c')
| -rw-r--r-- | drivers/net/wireless/mediatek/mt76/mcu.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mcu.c b/drivers/net/wireless/mediatek/mt76/mcu.c index a8cafa39a56d..535c3d8a9cc0 100644 --- a/drivers/net/wireless/mediatek/mt76/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mcu.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: ISC +// SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (C) 2019 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> */ @@ -73,14 +73,31 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, bool wait_resp, struct sk_buff **ret_skb) { + unsigned int retry = 0; + struct sk_buff *orig_skb = NULL; unsigned long expires; int ret, seq; + if (mt76_is_sdio(dev)) + if (test_bit(MT76_RESET, &dev->phy.state) && atomic_read(&dev->bus_hung)) + return -EIO; + if (ret_skb) *ret_skb = NULL; 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 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; @@ -94,6 +111,14 @@ 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) && + orig_skb && retry++ < dev->mcu_ops->max_retry) { + dev_err(dev->dev, "Retry message %08x (seq %d)\n", + cmd, seq); + skb = orig_skb; + goto retry; + } + ret = dev->mcu_ops->mcu_parse_response(dev, cmd, skb, seq); if (!ret && ret_skb) *ret_skb = skb; @@ -101,7 +126,9 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, dev_kfree_skb(skb); } while (ret == -EAGAIN); + out: + dev_kfree_skb(orig_skb); mutex_unlock(&dev->mcu.mutex); return ret; |
