2021-02-10 17:03:42

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH v4 2/6] Bluetooth: btintel: Move operational checks after version check

From: Luiz Augusto von Dentz <[email protected]>

In order to allow new firmware to be loaded it first needs to check if
the firmware version on file matches the one loaded if it doesn't then
it needs to revert to boorloader mode in order to load the new firmware.

Signed-off-by: Luiz Augusto von Dentz <[email protected]>
---
drivers/bluetooth/btintel.c | 22 +++++++++++
drivers/bluetooth/btusb.c | 74 +++++++++++++++----------------------
2 files changed, 52 insertions(+), 44 deletions(-)

diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index 89f85d54ca64..0d0f643f972a 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -949,6 +949,17 @@ int btintel_download_firmware(struct hci_dev *hdev,
return -EALREADY;
}

+ /* The firmware variant determines if the device is in bootloader
+ * mode or is running operational firmware. The value 0x06 identifies
+ * the bootloader and the value 0x23 identifies the operational
+ * firmware.
+ *
+ * If the firmware version has changed that means it needs to be reset
+ * to bootloader when operational so the new firmware can be loaded.
+ */
+ if (ver->fw_variant == 0x23)
+ return -EINVAL;
+
err = btintel_sfi_rsa_header_secure_send(hdev, fw);
if (err)
return err;
@@ -976,6 +987,17 @@ int btintel_download_firmware_newgen(struct hci_dev *hdev,
return -EALREADY;
}

+ /* The firmware variant determines if the device is in bootloader
+ * mode or is running operational firmware. The value 0x03 identifies
+ * the bootloader and the value 0x23 identifies the operational
+ * firmware.
+ *
+ * If the firmware version has changed that means it needs to be reset
+ * to bootloader when operational so the new firmware can be loaded.
+ */
+ if (ver->img_type == 0x03)
+ return -EINVAL;
+
/* iBT hardware variants 0x0b, 0x0c, 0x11, 0x12, 0x13, 0x14 support
* only RSA secure boot engine. Hence, the corresponding sfi file will
* have RSA header of 644 bytes followed by Command Buffer.
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index c92060e7472c..a44f3cf25790 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -2469,14 +2469,30 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
return -EILSEQ;
}

-static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
+static int btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
struct intel_boot_params *params,
char *fw_name, size_t len,
const char *suffix)
{
+ /* The hardware platform number has a fixed value of 0x37 and
+ * for now only accept this single value.
+ */
+ if (ver->hw_platform != 0x37)
+ return -EINVAL;
+
switch (ver->hw_variant) {
case 0x0b: /* SfP */
case 0x0c: /* WsP */
+ /* The firmware variant determines if the device is in
+ * bootloader mode or is running operational firmware.
+ *
+ * Version checking cannot be performed in these models since
+ * the firmware versioning depends on the firmware being in
+ * bootloader mode.
+ */
+ if (ver->fw_variant == 0x23)
+ return -EALREADY;
+
snprintf(fw_name, len, "intel/ibt-%u-%u.%s",
le16_to_cpu(ver->hw_variant),
le16_to_cpu(params->dev_revid),
@@ -2493,9 +2509,10 @@ static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
suffix);
break;
default:
- return false;
+ return -EINVAL;
}
- return true;
+
+ return 0;
}

static void btusb_setup_intel_newgen_get_fw_name(const struct intel_version_tlv *ver_tlv,
@@ -2550,7 +2567,6 @@ static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev,
if (ver->img_type == 0x03) {
clear_bit(BTUSB_BOOTLOADER, &data->flags);
btintel_check_bdaddr(hdev);
- return 0;
}

/* Check for supported iBT hardware variants of this firmware
@@ -2694,35 +2710,6 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
if (!ver || !params)
return -EINVAL;

- /* The hardware platform number has a fixed value of 0x37 and
- * for now only accept this single value.
- */
- if (ver->hw_platform != 0x37) {
- bt_dev_err(hdev, "Unsupported Intel hardware platform (%u)",
- ver->hw_platform);
- return -EINVAL;
- }
-
- /* Check for supported iBT hardware variants of this firmware
- * loading method.
- *
- * This check has been put in place to ensure correct forward
- * compatibility options when newer hardware variants come along.
- */
- switch (ver->hw_variant) {
- case 0x0b: /* SfP */
- case 0x0c: /* WsP */
- case 0x11: /* JfP */
- case 0x12: /* ThP */
- case 0x13: /* HrP */
- case 0x14: /* CcP */
- break;
- default:
- bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
- ver->hw_variant);
- return -EINVAL;
- }
-
btintel_version_info(hdev, ver);

/* The firmware variant determines if the device is in bootloader
@@ -2741,16 +2728,8 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
if (ver->fw_variant == 0x23) {
clear_bit(BTUSB_BOOTLOADER, &data->flags);
btintel_check_bdaddr(hdev);
- return 0;
- }
-
- /* If the device is not in bootloader mode, then the only possible
- * choice is to return an error and abort the device initialization.
- */
- if (ver->fw_variant != 0x06) {
- bt_dev_err(hdev, "Unsupported Intel firmware variant (%u)",
- ver->fw_variant);
- return -ENODEV;
+ /* Proceed to download to check if the version matches */
+ goto download;
}

/* Read the secure boot parameters to identify the operating
@@ -2778,6 +2757,7 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
}

+download:
/* With this Intel bootloader only the hardware variant and device
* revision information are used to select the right firmware for SfP
* and WsP.
@@ -2801,7 +2781,13 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
*/
err = btusb_setup_intel_new_get_fw_name(ver, params, fwname,
sizeof(fwname), "sfi");
- if (!err) {
+ if (err < 0) {
+ if (err == -EALREADY) {
+ /* Firmware has already been loaded */
+ set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
+ goto done;
+ }
+
bt_dev_err(hdev, "Unsupported Intel firmware naming");
return -EINVAL;
}
--
2.26.2


2021-02-10 19:13:20

by An, Tedd

[permalink] [raw]
Subject: Re: [PATCH v4 2/6] Bluetooth: btintel: Move operational checks after version check

On Wed, 2021-02-10 at 08:59 -0800, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <[email protected]>
>
> In order to allow new firmware to be loaded it first needs to check if
> the firmware version on file matches the one loaded if it doesn't then
> it needs to revert to boorloader mode in order to load the new firmware.
>
> Signed-off-by: Luiz Augusto von Dentz <[email protected]>
> ---
> drivers/bluetooth/btintel.c | 22 +++++++++++
> drivers/bluetooth/btusb.c | 74 +++++++++++++++----------------------
> 2 files changed, 52 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
> index 89f85d54ca64..0d0f643f972a 100644
> --- a/drivers/bluetooth/btintel.c
> +++ b/drivers/bluetooth/btintel.c
> @@ -949,6 +949,17 @@ int btintel_download_firmware(struct hci_dev *hdev,
> return -EALREADY;
> }
>
> + /* The firmware variant determines if the device is in bootloader
> + * mode or is running operational firmware. The value 0x06 identifies
> + * the bootloader and the value 0x23 identifies the operational
> + * firmware.
> + *
> + * If the firmware version has changed that means it needs to be reset
> + * to bootloader when operational so the new firmware can be loaded.
> + */
> + if (ver->fw_variant == 0x23)
> + return -EINVAL;
> +
> err = btintel_sfi_rsa_header_secure_send(hdev, fw);
> if (err)
> return err;
> @@ -976,6 +987,17 @@ int btintel_download_firmware_newgen(struct hci_dev *hdev,
> return -EALREADY;
> }
>
> + /* The firmware variant determines if the device is in bootloader
> + * mode or is running operational firmware. The value 0x03 identifies
> + * the bootloader and the value 0x23 identifies the operational
> + * firmware.
> + *
> + * If the firmware version has changed that means it needs to be reset
> + * to bootloader when operational so the new firmware can be loaded.
> + */
> + if (ver->img_type == 0x03)
> + return -EINVAL;
> +
> /* iBT hardware variants 0x0b, 0x0c, 0x11, 0x12, 0x13, 0x14 support
> * only RSA secure boot engine. Hence, the corresponding sfi file will
> * have RSA header of 644 bytes followed by Command Buffer.
> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> index c92060e7472c..a44f3cf25790 100644
> --- a/drivers/bluetooth/btusb.c
> +++ b/drivers/bluetooth/btusb.c
> @@ -2469,14 +2469,30 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
> return -EILSEQ;
> }
>
> -static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
> +static int btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
> struct intel_boot_params *params,
> char *fw_name, size_t len,
> const char *suffix)
> {
> + /* The hardware platform number has a fixed value of 0x37 and
> + * for now only accept this single value.
> + */
> + if (ver->hw_platform != 0x37)
> + return -EINVAL;
> +
> switch (ver->hw_variant) {
> case 0x0b: /* SfP */
> case 0x0c: /* WsP */
> + /* The firmware variant determines if the device is in
> + * bootloader mode or is running operational firmware.
> + *
> + * Version checking cannot be performed in these models since
> + * the firmware versioning depends on the firmware being in
> + * bootloader mode.
> + */
> + if (ver->fw_variant == 0x23)
> + return -EALREADY;
> +
> snprintf(fw_name, len, "intel/ibt-%u-%u.%s",
> le16_to_cpu(ver->hw_variant),
> le16_to_cpu(params->dev_revid),
> @@ -2493,9 +2509,10 @@ static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
> suffix);
> break;
> default:
> - return false;
> + return -EINVAL;
> }
> - return true;
> +
> + return 0;

There is one more place in btusb_setup_intel_new()@btusb.c to update the handling of return
value of this funcion, which is related to loading the DDC.
Code like this...

if (!err) {
bt_dev_err(hdev, "Unsupported Intel firmware naming");
} else {



> }
>
> static void btusb_setup_intel_newgen_get_fw_name(const struct intel_version_tlv *ver_tlv,
> @@ -2550,7 +2567,6 @@ static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev,
> if (ver->img_type == 0x03) {
> clear_bit(BTUSB_BOOTLOADER, &data->flags);
> btintel_check_bdaddr(hdev);
> - return 0;
> }
>
> /* Check for supported iBT hardware variants of this firmware
> @@ -2694,35 +2710,6 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
> if (!ver || !params)
> return -EINVAL;
>
> - /* The hardware platform number has a fixed value of 0x37 and
> - * for now only accept this single value.
> - */
> - if (ver->hw_platform != 0x37) {
> - bt_dev_err(hdev, "Unsupported Intel hardware platform (%u)",
> - ver->hw_platform);
> - return -EINVAL;
> - }
> -
> - /* Check for supported iBT hardware variants of this firmware
> - * loading method.
> - *
> - * This check has been put in place to ensure correct forward
> - * compatibility options when newer hardware variants come along.
> - */
> - switch (ver->hw_variant) {
> - case 0x0b: /* SfP */
> - case 0x0c: /* WsP */
> - case 0x11: /* JfP */
> - case 0x12: /* ThP */
> - case 0x13: /* HrP */
> - case 0x14: /* CcP */
> - break;
> - default:
> - bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
> - ver->hw_variant);
> - return -EINVAL;
> - }
> -
> btintel_version_info(hdev, ver);
>
> /* The firmware variant determines if the device is in bootloader
> @@ -2741,16 +2728,8 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
> if (ver->fw_variant == 0x23) {
> clear_bit(BTUSB_BOOTLOADER, &data->flags);
> btintel_check_bdaddr(hdev);
> - return 0;
> - }
> -
> - /* If the device is not in bootloader mode, then the only possible
> - * choice is to return an error and abort the device initialization.
> - */
> - if (ver->fw_variant != 0x06) {
> - bt_dev_err(hdev, "Unsupported Intel firmware variant (%u)",
> - ver->fw_variant);
> - return -ENODEV;
> + /* Proceed to download to check if the version matches */
> + goto download;
> }
>
> /* Read the secure boot parameters to identify the operating
> @@ -2778,6 +2757,7 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
> set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
> }
>
> +download:
> /* With this Intel bootloader only the hardware variant and device
> * revision information are used to select the right firmware for SfP
> * and WsP.
> @@ -2801,7 +2781,13 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
> */
> err = btusb_setup_intel_new_get_fw_name(ver, params, fwname,
> sizeof(fwname), "sfi");
> - if (!err) {
> + if (err < 0) {
> + if (err == -EALREADY) {
> + /* Firmware has already been loaded */
> + set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
> + goto done;
> + }
> +
> bt_dev_err(hdev, "Unsupported Intel firmware naming");
> return -EINVAL;
> }

2021-02-10 19:23:11

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH v4 2/6] Bluetooth: btintel: Move operational checks after version check

Hi Tedd,

On Wed, Feb 10, 2021 at 11:10 AM An, Tedd <[email protected]> wrote:
>
> On Wed, 2021-02-10 at 08:59 -0800, Luiz Augusto von Dentz wrote:
> > From: Luiz Augusto von Dentz <[email protected]>
> >
> > In order to allow new firmware to be loaded it first needs to check if
> > the firmware version on file matches the one loaded if it doesn't then
> > it needs to revert to boorloader mode in order to load the new firmware.
> >
> > Signed-off-by: Luiz Augusto von Dentz <[email protected]>
> > ---
> > drivers/bluetooth/btintel.c | 22 +++++++++++
> > drivers/bluetooth/btusb.c | 74 +++++++++++++++----------------------
> > 2 files changed, 52 insertions(+), 44 deletions(-)
> >
> > diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
> > index 89f85d54ca64..0d0f643f972a 100644
> > --- a/drivers/bluetooth/btintel.c
> > +++ b/drivers/bluetooth/btintel.c
> > @@ -949,6 +949,17 @@ int btintel_download_firmware(struct hci_dev *hdev,
> > return -EALREADY;
> > }
> >
> > + /* The firmware variant determines if the device is in bootloader
> > + * mode or is running operational firmware. The value 0x06 identifies
> > + * the bootloader and the value 0x23 identifies the operational
> > + * firmware.
> > + *
> > + * If the firmware version has changed that means it needs to be reset
> > + * to bootloader when operational so the new firmware can be loaded.
> > + */
> > + if (ver->fw_variant == 0x23)
> > + return -EINVAL;
> > +
> > err = btintel_sfi_rsa_header_secure_send(hdev, fw);
> > if (err)
> > return err;
> > @@ -976,6 +987,17 @@ int btintel_download_firmware_newgen(struct hci_dev *hdev,
> > return -EALREADY;
> > }
> >
> > + /* The firmware variant determines if the device is in bootloader
> > + * mode or is running operational firmware. The value 0x03 identifies
> > + * the bootloader and the value 0x23 identifies the operational
> > + * firmware.
> > + *
> > + * If the firmware version has changed that means it needs to be reset
> > + * to bootloader when operational so the new firmware can be loaded.
> > + */
> > + if (ver->img_type == 0x03)
> > + return -EINVAL;
> > +
> > /* iBT hardware variants 0x0b, 0x0c, 0x11, 0x12, 0x13, 0x14 support
> > * only RSA secure boot engine. Hence, the corresponding sfi file will
> > * have RSA header of 644 bytes followed by Command Buffer.
> > diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> > index c92060e7472c..a44f3cf25790 100644
> > --- a/drivers/bluetooth/btusb.c
> > +++ b/drivers/bluetooth/btusb.c
> > @@ -2469,14 +2469,30 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
> > return -EILSEQ;
> > }
> >
> > -static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
> > +static int btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
> > struct intel_boot_params *params,
> > char *fw_name, size_t len,
> > const char *suffix)
> > {
> > + /* The hardware platform number has a fixed value of 0x37 and
> > + * for now only accept this single value.
> > + */
> > + if (ver->hw_platform != 0x37)
> > + return -EINVAL;
> > +
> > switch (ver->hw_variant) {
> > case 0x0b: /* SfP */
> > case 0x0c: /* WsP */
> > + /* The firmware variant determines if the device is in
> > + * bootloader mode or is running operational firmware.
> > + *
> > + * Version checking cannot be performed in these models since
> > + * the firmware versioning depends on the firmware being in
> > + * bootloader mode.
> > + */
> > + if (ver->fw_variant == 0x23)
> > + return -EALREADY;
> > +
> > snprintf(fw_name, len, "intel/ibt-%u-%u.%s",
> > le16_to_cpu(ver->hw_variant),
> > le16_to_cpu(params->dev_revid),
> > @@ -2493,9 +2509,10 @@ static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
> > suffix);
> > break;
> > default:
> > - return false;
> > + return -EINVAL;
> > }
> > - return true;
> > +
> > + return 0;
>
> There is one more place in btusb_setup_intel_new()@btusb.c to update the handling of return
> value of this funcion, which is related to loading the DDC.
> Code like this...
>
> if (!err) {
> bt_dev_err(hdev, "Unsupported Intel firmware naming");
> } else {

This should never fail though since the first one would check if the
firmware name cannot be generated if would fail and never reach this
one, that said perhaps static analyzer will complain about not
checking the return here.

>
>
> > }
> >
> > static void btusb_setup_intel_newgen_get_fw_name(const struct intel_version_tlv *ver_tlv,
> > @@ -2550,7 +2567,6 @@ static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev,
> > if (ver->img_type == 0x03) {
> > clear_bit(BTUSB_BOOTLOADER, &data->flags);
> > btintel_check_bdaddr(hdev);
> > - return 0;
> > }
> >
> > /* Check for supported iBT hardware variants of this firmware
> > @@ -2694,35 +2710,6 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
> > if (!ver || !params)
> > return -EINVAL;
> >
> > - /* The hardware platform number has a fixed value of 0x37 and
> > - * for now only accept this single value.
> > - */
> > - if (ver->hw_platform != 0x37) {
> > - bt_dev_err(hdev, "Unsupported Intel hardware platform (%u)",
> > - ver->hw_platform);
> > - return -EINVAL;
> > - }
> > -
> > - /* Check for supported iBT hardware variants of this firmware
> > - * loading method.
> > - *
> > - * This check has been put in place to ensure correct forward
> > - * compatibility options when newer hardware variants come along.
> > - */
> > - switch (ver->hw_variant) {
> > - case 0x0b: /* SfP */
> > - case 0x0c: /* WsP */
> > - case 0x11: /* JfP */
> > - case 0x12: /* ThP */
> > - case 0x13: /* HrP */
> > - case 0x14: /* CcP */
> > - break;
> > - default:
> > - bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
> > - ver->hw_variant);
> > - return -EINVAL;
> > - }
> > -
> > btintel_version_info(hdev, ver);
> >
> > /* The firmware variant determines if the device is in bootloader
> > @@ -2741,16 +2728,8 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
> > if (ver->fw_variant == 0x23) {
> > clear_bit(BTUSB_BOOTLOADER, &data->flags);
> > btintel_check_bdaddr(hdev);
> > - return 0;
> > - }
> > -
> > - /* If the device is not in bootloader mode, then the only possible
> > - * choice is to return an error and abort the device initialization.
> > - */
> > - if (ver->fw_variant != 0x06) {
> > - bt_dev_err(hdev, "Unsupported Intel firmware variant (%u)",
> > - ver->fw_variant);
> > - return -ENODEV;
> > + /* Proceed to download to check if the version matches */
> > + goto download;
> > }
> >
> > /* Read the secure boot parameters to identify the operating
> > @@ -2778,6 +2757,7 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
> > set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
> > }
> >
> > +download:
> > /* With this Intel bootloader only the hardware variant and device
> > * revision information are used to select the right firmware for SfP
> > * and WsP.
> > @@ -2801,7 +2781,13 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
> > */
> > err = btusb_setup_intel_new_get_fw_name(ver, params, fwname,
> > sizeof(fwname), "sfi");
> > - if (!err) {
> > + if (err < 0) {
> > + if (err == -EALREADY) {
> > + /* Firmware has already been loaded */
> > + set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
> > + goto done;
> > + }
> > +
> > bt_dev_err(hdev, "Unsupported Intel firmware naming");
> > return -EINVAL;
> > }



--
Luiz Augusto von Dentz

2021-02-10 20:30:08

by An, Tedd

[permalink] [raw]
Subject: Re: [PATCH v4 2/6] Bluetooth: btintel: Move operational checks after version check

Hi Luiz,

On Wed, 2021-02-10 at 11:20 -0800, Luiz Augusto von Dentz wrote:
> Hi Tedd,
>
> On Wed, Feb 10, 2021 at 11:10 AM An, Tedd <[email protected]> wrote:
> > On Wed, 2021-02-10 at 08:59 -0800, Luiz Augusto von Dentz wrote:
> > > From: Luiz Augusto von Dentz <[email protected]>
> > >
> > > In order to allow new firmware to be loaded it first needs to check if
> > > the firmware version on file matches the one loaded if it doesn't then
> > > it needs to revert to boorloader mode in order to load the new firmware.
> > >
> > > Signed-off-by: Luiz Augusto von Dentz <[email protected]>
> > > ---
> > > drivers/bluetooth/btintel.c | 22 +++++++++++
> > > drivers/bluetooth/btusb.c | 74 +++++++++++++++----------------------
> > > 2 files changed, 52 insertions(+), 44 deletions(-)
> > >
> > > diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
> > > index 89f85d54ca64..0d0f643f972a 100644
> > > --- a/drivers/bluetooth/btintel.c
> > > +++ b/drivers/bluetooth/btintel.c
> > > @@ -949,6 +949,17 @@ int btintel_download_firmware(struct hci_dev *hdev,
> > > return -EALREADY;
> > > }
> > >
> > > + /* The firmware variant determines if the device is in bootloader
> > > + * mode or is running operational firmware. The value 0x06 identifies
> > > + * the bootloader and the value 0x23 identifies the operational
> > > + * firmware.
> > > + *
> > > + * If the firmware version has changed that means it needs to be reset
> > > + * to bootloader when operational so the new firmware can be loaded.
> > > + */
> > > + if (ver->fw_variant == 0x23)
> > > + return -EINVAL;
> > > +
> > > err = btintel_sfi_rsa_header_secure_send(hdev, fw);
> > > if (err)
> > > return err;
> > > @@ -976,6 +987,17 @@ int btintel_download_firmware_newgen(struct hci_dev *hdev,
> > > return -EALREADY;
> > > }
> > >
> > > + /* The firmware variant determines if the device is in bootloader
> > > + * mode or is running operational firmware. The value 0x03 identifies
> > > + * the bootloader and the value 0x23 identifies the operational
> > > + * firmware.
> > > + *
> > > + * If the firmware version has changed that means it needs to be reset
> > > + * to bootloader when operational so the new firmware can be loaded.
> > > + */
> > > + if (ver->img_type == 0x03)
> > > + return -EINVAL;
> > > +
> > > /* iBT hardware variants 0x0b, 0x0c, 0x11, 0x12, 0x13, 0x14 support
> > > * only RSA secure boot engine. Hence, the corresponding sfi file will
> > > * have RSA header of 644 bytes followed by Command Buffer.
> > > diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> > > index c92060e7472c..a44f3cf25790 100644
> > > --- a/drivers/bluetooth/btusb.c
> > > +++ b/drivers/bluetooth/btusb.c
> > > @@ -2469,14 +2469,30 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
> > > return -EILSEQ;
> > > }
> > >
> > > -static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
> > > +static int btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
> > > struct intel_boot_params *params,
> > > char *fw_name, size_t len,
> > > const char *suffix)
> > > {
> > > + /* The hardware platform number has a fixed value of 0x37 and
> > > + * for now only accept this single value.
> > > + */
> > > + if (ver->hw_platform != 0x37)
> > > + return -EINVAL;
> > > +
> > > switch (ver->hw_variant) {
> > > case 0x0b: /* SfP */
> > > case 0x0c: /* WsP */
> > > + /* The firmware variant determines if the device is in
> > > + * bootloader mode or is running operational firmware.
> > > + *
> > > + * Version checking cannot be performed in these models since
> > > + * the firmware versioning depends on the firmware being in
> > > + * bootloader mode.
> > > + */
> > > + if (ver->fw_variant == 0x23)
> > > + return -EALREADY;
> > > +
> > > snprintf(fw_name, len, "intel/ibt-%u-%u.%s",
> > > le16_to_cpu(ver->hw_variant),
> > > le16_to_cpu(params->dev_revid),
> > > @@ -2493,9 +2509,10 @@ static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
> > > suffix);
> > > break;
> > > default:
> > > - return false;
> > > + return -EINVAL;
> > > }
> > > - return true;
> > > +
> > > + return 0;
> >
> > There is one more place in btusb_setup_intel_new()@btusb.c to update the handling of return
> > value of this funcion, which is related to loading the DDC.
> > Code like this...
> >
> > if (!err) {
> > bt_dev_err(hdev, "Unsupported Intel firmware naming");
> > } else {
>
> This should never fail though since the first one would check if the
> firmware name cannot be generated if would fail and never reach this
> one, that said perhaps static analyzer will complain about not
> checking the return here.
>

It is not for failure case. For success case, it should get the DDC file name.
It gets correct name with err=0, which should be an error.


> >
> > > }
> > >
> > > static void btusb_setup_intel_newgen_get_fw_name(const struct intel_version_tlv *ver_tlv,
> > > @@ -2550,7 +2567,6 @@ static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev,
> > > if (ver->img_type == 0x03) {
> > > clear_bit(BTUSB_BOOTLOADER, &data->flags);
> > > btintel_check_bdaddr(hdev);
> > > - return 0;
> > > }
> > >
> > > /* Check for supported iBT hardware variants of this firmware
> > > @@ -2694,35 +2710,6 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
> > > if (!ver || !params)
> > > return -EINVAL;
> > >
> > > - /* The hardware platform number has a fixed value of 0x37 and
> > > - * for now only accept this single value.
> > > - */
> > > - if (ver->hw_platform != 0x37) {
> > > - bt_dev_err(hdev, "Unsupported Intel hardware platform (%u)",
> > > - ver->hw_platform);
> > > - return -EINVAL;
> > > - }
> > > -
> > > - /* Check for supported iBT hardware variants of this firmware
> > > - * loading method.
> > > - *
> > > - * This check has been put in place to ensure correct forward
> > > - * compatibility options when newer hardware variants come along.
> > > - */
> > > - switch (ver->hw_variant) {
> > > - case 0x0b: /* SfP */
> > > - case 0x0c: /* WsP */
> > > - case 0x11: /* JfP */
> > > - case 0x12: /* ThP */
> > > - case 0x13: /* HrP */
> > > - case 0x14: /* CcP */
> > > - break;
> > > - default:
> > > - bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
> > > - ver->hw_variant);
> > > - return -EINVAL;
> > > - }
> > > -
> > > btintel_version_info(hdev, ver);
> > >
> > > /* The firmware variant determines if the device is in bootloader
> > > @@ -2741,16 +2728,8 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
> > > if (ver->fw_variant == 0x23) {
> > > clear_bit(BTUSB_BOOTLOADER, &data->flags);
> > > btintel_check_bdaddr(hdev);
> > > - return 0;
> > > - }
> > > -
> > > - /* If the device is not in bootloader mode, then the only possible
> > > - * choice is to return an error and abort the device initialization.
> > > - */
> > > - if (ver->fw_variant != 0x06) {
> > > - bt_dev_err(hdev, "Unsupported Intel firmware variant (%u)",
> > > - ver->fw_variant);
> > > - return -ENODEV;
> > > + /* Proceed to download to check if the version matches */
> > > + goto download;
> > > }
> > >
> > > /* Read the secure boot parameters to identify the operating
> > > @@ -2778,6 +2757,7 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
> > > set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
> > > }
> > >
> > > +download:
> > > /* With this Intel bootloader only the hardware variant and device
> > > * revision information are used to select the right firmware for SfP
> > > * and WsP.
> > > @@ -2801,7 +2781,13 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
> > > */
> > > err = btusb_setup_intel_new_get_fw_name(ver, params, fwname,
> > > sizeof(fwname), "sfi");
> > > - if (!err) {
> > > + if (err < 0) {
> > > + if (err == -EALREADY) {
> > > + /* Firmware has already been loaded */
> > > + set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
> > > + goto done;
> > > + }
> > > +
> > > bt_dev_err(hdev, "Unsupported Intel firmware naming");
> > > return -EINVAL;
> > > }
>
>