[PATCH v1] Bluetooth: btmtk: Trigger reset on firmware download failure

Chris Lu posted 1 patch 1 week, 2 days ago
drivers/bluetooth/btmtk.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
[PATCH v1] Bluetooth: btmtk: Trigger reset on firmware download failure
Posted by Chris Lu 1 week, 2 days ago
Initiate reset flow if MT79xx series BT failed to download firmware when
doing setup.
If driver is not able to get event after reset in the first section of
btmtk_usb_setup, the protocol is deemed unuable and driver will return to
prevent from repeatedly executing resets.

Signed-off-by: Chris Lu <chris.lu@mediatek.com>
---
 drivers/bluetooth/btmtk.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index a8c520dc09e1..8b1443b9e9cf 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -1333,7 +1333,7 @@ int btmtk_usb_setup(struct hci_dev *hdev)
 						btmtk_usb_hci_wmt_sync);
 		if (err < 0) {
 			bt_dev_err(hdev, "Failed to set up firmware (%d)", err);
-			return err;
+			goto reset_fw;
 		}
 
 		/* It's Device EndPoint Reset Option Register */
@@ -1353,7 +1353,7 @@ int btmtk_usb_setup(struct hci_dev *hdev)
 		err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
 		if (err < 0) {
 			bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
-			return err;
+			goto reset_fw;
 		}
 
 		hci_set_msft_opcode(hdev, 0xFD30);
@@ -1444,6 +1444,13 @@ int btmtk_usb_setup(struct hci_dev *hdev)
 	}
 	kfree_skb(skb);
 
+reset_fw:
+	if (btmtk_data->reset_sync) {
+		bt_dev_err(hdev, "Mediatek do firmware reset");
+		btmtk_reset_sync(hdev);
+		return err;
+	}
+
 done:
 	rettime = ktime_get();
 	delta = ktime_sub(rettime, calltime);
-- 
2.45.2
Re: [PATCH v1] Bluetooth: btmtk: Trigger reset on firmware download failure
Posted by Luiz Augusto von Dentz 1 week, 1 day ago
Hi Chris,

On Tue, Dec 9, 2025 at 7:06 AM Chris Lu <chris.lu@mediatek.com> wrote:
>
> Initiate reset flow if MT79xx series BT failed to download firmware when
> doing setup.
> If driver is not able to get event after reset in the first section of
> btmtk_usb_setup, the protocol is deemed unuable and driver will return to
> prevent from repeatedly executing resets.
>
> Signed-off-by: Chris Lu <chris.lu@mediatek.com>
> ---
>  drivers/bluetooth/btmtk.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
> index a8c520dc09e1..8b1443b9e9cf 100644
> --- a/drivers/bluetooth/btmtk.c
> +++ b/drivers/bluetooth/btmtk.c
> @@ -1333,7 +1333,7 @@ int btmtk_usb_setup(struct hci_dev *hdev)
>                                                 btmtk_usb_hci_wmt_sync);
>                 if (err < 0) {
>                         bt_dev_err(hdev, "Failed to set up firmware (%d)", err);
> -                       return err;
> +                       goto reset_fw;
>                 }
>
>                 /* It's Device EndPoint Reset Option Register */
> @@ -1353,7 +1353,7 @@ int btmtk_usb_setup(struct hci_dev *hdev)
>                 err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
>                 if (err < 0) {
>                         bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
> -                       return err;
> +                       goto reset_fw;
>                 }
>
>                 hci_set_msft_opcode(hdev, 0xFD30);
> @@ -1444,6 +1444,13 @@ int btmtk_usb_setup(struct hci_dev *hdev)
>         }
>         kfree_skb(skb);
>
> +reset_fw:
> +       if (btmtk_data->reset_sync) {
> +               bt_dev_err(hdev, "Mediatek do firmware reset");

This message is a bit cryptic to me, why do we need to print that you
will be doing a reset?

> +               btmtk_reset_sync(hdev);

This seems to be doing a hard reset, which I assume you are doing as
an attempt to recover by retrying to setup, but if it fails we may go
into a loop condition trying to setup so we better limit the number of
attempts.

> +               return err;
> +       }
> +
>  done:
>         rettime = ktime_get();
>         delta = ktime_sub(rettime, calltime);
> --
> 2.45.2
>


-- 
Luiz Augusto von Dentz
Re: [PATCH v1] Bluetooth: btmtk: Trigger reset on firmware download failure
Posted by Chris Lu (陸稚泓) 1 week ago
Hi Luiz,

Thanks for your review and response.

On Wed, 2025-12-10 at 16:09 -0500, Luiz Augusto von Dentz wrote:
> 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> Hi Chris,
> 
> On Tue, Dec 9, 2025 at 7:06 AM Chris Lu <chris.lu@mediatek.com>
> wrote:
> > 
> > Initiate reset flow if MT79xx series BT failed to download firmware
> > when
> > doing setup.
> > If driver is not able to get event after reset in the first section
> > of
> > btmtk_usb_setup, the protocol is deemed unuable and driver will
> > return to
> > prevent from repeatedly executing resets.
> > 
> > Signed-off-by: Chris Lu <chris.lu@mediatek.com>
> > ---
> >  drivers/bluetooth/btmtk.c | 11 +++++++++--
> >  1 file changed, 9 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
> > index a8c520dc09e1..8b1443b9e9cf 100644
> > --- a/drivers/bluetooth/btmtk.c
> > +++ b/drivers/bluetooth/btmtk.c
> > @@ -1333,7 +1333,7 @@ int btmtk_usb_setup(struct hci_dev *hdev)
> >                                                
> > btmtk_usb_hci_wmt_sync);
> >                 if (err < 0) {
> >                         bt_dev_err(hdev, "Failed to set up firmware
> > (%d)", err);
> > -                       return err;
> > +                       goto reset_fw;
> >                 }
> > 
> >                 /* It's Device EndPoint Reset Option Register */
> > @@ -1353,7 +1353,7 @@ int btmtk_usb_setup(struct hci_dev *hdev)
> >                 err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
> >                 if (err < 0) {
> >                         bt_dev_err(hdev, "Failed to send wmt func
> > ctrl (%d)", err);
> > -                       return err;
> > +                       goto reset_fw;
> >                 }
> > 
> >                 hci_set_msft_opcode(hdev, 0xFD30);
> > @@ -1444,6 +1444,13 @@ int btmtk_usb_setup(struct hci_dev *hdev)
> >         }
> >         kfree_skb(skb);
> > 
> > +reset_fw:
> > +       if (btmtk_data->reset_sync) {
> > +               bt_dev_err(hdev, "Mediatek do firmware reset");
> 
> This message is a bit cryptic to me, why do we need to print that you
> will be doing a reset?

Indeed, this log can only be interpreted by Mediatek engineers. I'll
update v2 to remove this line.

> 
> > +               btmtk_reset_sync(hdev);
> 
> This seems to be doing a hard reset, which I assume you are doing as
> an attempt to recover by retrying to setup, but if it fails we may go
> into a loop condition trying to setup so we better limit the number
> of
> attempts.

We only perform reset once when firmware download failed or 'wmt ctrl'
command failed.

Before downloading the firmware, driver will send pre-init commands to
get information such as chip id, after the reset, if those command
still can't work normally, it is considered a protocol issue that it
can't be further used. We'll not enter the reset flow again to avoid an
endless loop.

There is indeed a potential risk. If the pre-init commands are all fine
but firmware download continues to have problem, it could cause a loop
condition. Retry limit will be addressed in v2.

> 
> > +               return err;
> > +       }
> > +
> >  done:
> >         rettime = ktime_get();
> >         delta = ktime_sub(rettime, calltime);
> > --
> > 2.45.2
> > 
> 
> 
> --
> Luiz Augusto von Dentz

Thanks a lot!
Chris Lu