From: Kiran K <kiran.k@intel.com>
To: linux-bluetooth@vger.kernel.org
Cc: ravishankar.srivatsa@intel.com, chethan.tumkur.narayan@intel.com,
sathish.narasimman@intel.com, Kiran K <kiran.k@intel.com>
Subject: [PATCH v8 4/5] Bluetooth: btusb: Helper function to download firmware to Intel adapters
Date: Thu, 19 Nov 2020 17:09:42 +0530 [thread overview]
Message-ID: <20201119113943.13839-4-kiran.k@intel.com> (raw)
In-Reply-To: <20201119113943.13839-1-kiran.k@intel.com>
Define a helper function to download firmware for new generation Intel
controllers
Signed-off-by: Kiran K <kiran.k@intel.com>
---
drivers/bluetooth/btusb.c | 165 ++++++++++++++++++++++++++++++++++++++
1 file changed, 165 insertions(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 579dd1343057..b3d470ec2622 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -2398,6 +2398,167 @@ static void btusb_setup_intel_newgen_get_fw_name(const struct intel_version_tlv
suffix);
}
+static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev,
+ struct intel_version_tlv *ver,
+ u32 *boot_param)
+{
+ const struct firmware *fw;
+ char fwname[64];
+ int err;
+ struct btusb_data *data = hci_get_drvdata(hdev);
+
+ if (!ver || !boot_param)
+ return -EINVAL;
+
+ /* The hardware platform number has a fixed value of 0x37 and
+ * for now only accept this single value.
+ */
+ if (INTEL_HW_PLATFORM(ver->cnvi_bt) != 0x37) {
+ bt_dev_err(hdev, "Unsupported Intel hardware platform (0x%2x)",
+ INTEL_HW_PLATFORM(ver->cnvi_bt));
+ return -EINVAL;
+ }
+
+ /* 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.
+ *
+ * When the operational firmware is already present, then only
+ * the check for valid Bluetooth device address is needed. This
+ * determines if the device will be added as configured or
+ * unconfigured controller.
+ *
+ * It is not possible to use the Secure Boot Parameters in this
+ * case since that command is only available in bootloader mode.
+ */
+ 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
+ * loading method.
+ *
+ * This check has been put in place to ensure correct forward
+ * compatibility options when newer hardware variants come along.
+ */
+ switch (INTEL_HW_VARIANT(ver->cnvi_bt)) {
+ case 0x17: /* TyP */
+ case 0x18: /* Slr */
+ case 0x19: /* Slr-F */
+ break;
+ default:
+ bt_dev_err(hdev, "Unsupported Intel hardware variant (0x%x)",
+ INTEL_HW_VARIANT(ver->cnvi_bt));
+ return -EINVAL;
+ }
+
+ /* 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->img_type != 0x01) {
+ bt_dev_err(hdev, "Unsupported Intel firmware variant (0x%x)",
+ ver->img_type);
+ return -ENODEV;
+ }
+
+ /* It is required that every single firmware fragment is acknowledged
+ * with a command complete event. If the boot parameters indicate
+ * that this bootloader does not send them, then abort the setup.
+ */
+ if (ver->limited_cce != 0x00) {
+ bt_dev_err(hdev, "Unsupported Intel firmware loading method (0x%x)",
+ ver->limited_cce);
+ return -EINVAL;
+ }
+
+ /* Secure boot engine type should be either 1 (ECDSA) or 0 (RSA) */
+ if (ver->sbe_type > 0x01) {
+ bt_dev_err(hdev, "Unsupported Intel secure boot engine type (0x%x)",
+ ver->sbe_type);
+ return -EINVAL;
+ }
+
+ /* If the OTP has no valid Bluetooth device address, then there will
+ * also be no valid address for the operational firmware.
+ */
+ if (!bacmp(&ver->otp_bd_addr, BDADDR_ANY)) {
+ bt_dev_info(hdev, "No device address configured");
+ set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
+ }
+
+ btusb_setup_intel_newgen_get_fw_name(ver, fwname, sizeof(fwname), "sfi");
+ err = request_firmware(&fw, fwname, &hdev->dev);
+ if (err < 0) {
+ bt_dev_err(hdev, "Failed to load Intel firmware file (%d)", err);
+ return err;
+ }
+
+ bt_dev_info(hdev, "Found device firmware: %s", fwname);
+
+ if (fw->size < 644) {
+ bt_dev_err(hdev, "Invalid size of firmware file (%zu)",
+ fw->size);
+ err = -EBADF;
+ goto done;
+ }
+
+ set_bit(BTUSB_DOWNLOADING, &data->flags);
+
+ /* Start firmware downloading and get boot parameter */
+ err = btintel_download_firmware_newgen(hdev, fw, boot_param,
+ INTEL_HW_VARIANT(ver->cnvi_bt),
+ ver->sbe_type);
+ if (err < 0) {
+ /* When FW download fails, send Intel Reset to retry
+ * FW download.
+ */
+ btintel_reset_to_bootloader(hdev);
+ goto done;
+ }
+ set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
+
+ bt_dev_info(hdev, "Waiting for firmware download to complete");
+
+ /* Before switching the device into operational mode and with that
+ * booting the loaded firmware, wait for the bootloader notification
+ * that all fragments have been successfully received.
+ *
+ * When the event processing receives the notification, then the
+ * BTUSB_DOWNLOADING flag will be cleared.
+ *
+ * The firmware loading should not take longer than 5 seconds
+ * and thus just timeout if that happens and fail the setup
+ * of this device.
+ */
+ err = wait_on_bit_timeout(&data->flags, BTUSB_DOWNLOADING,
+ TASK_INTERRUPTIBLE,
+ msecs_to_jiffies(5000));
+ if (err == -EINTR) {
+ bt_dev_err(hdev, "Firmware loading interrupted");
+ goto done;
+ }
+
+ if (err) {
+ bt_dev_err(hdev, "Firmware loading timeout");
+ err = -ETIMEDOUT;
+ btintel_reset_to_bootloader(hdev);
+ goto done;
+ }
+
+ if (test_bit(BTUSB_FIRMWARE_FAILED, &data->flags)) {
+ bt_dev_err(hdev, "Firmware loading failed");
+ err = -ENOEXEC;
+ goto done;
+ }
+
+done:
+ release_firmware(fw);
+ return err;
+}
+
static int btusb_intel_download_firmware(struct hci_dev *hdev,
struct intel_version *ver,
struct intel_boot_params *params,
@@ -2766,6 +2927,10 @@ static int btusb_setup_intel_newgen(struct hci_dev *hdev)
btintel_version_info_tlv(hdev, &version);
+ err = btusb_intel_download_firmware_newgen(hdev, &version, &boot_param);
+ if (err)
+ return err;
+
/* check if controller is already having an operational firmware */
if (version.img_type == 0x03)
goto finish;
--
2.17.1
next prev parent reply other threads:[~2020-11-19 11:38 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-19 11:39 [PATCH v8 1/5] Bluetooth: btintel: Fix endianness issue for TLV version information Kiran K
2020-11-19 11:39 ` [PATCH v8 2/5] Bluetooth: btusb: Add *setup* function for new generation Intel controllers Kiran K
2020-12-03 13:53 ` Marcel Holtmann
2020-11-19 11:39 ` [PATCH v8 3/5] Bluetooth: btusb: Define a function to construct firmware filename Kiran K
2020-12-03 13:55 ` Marcel Holtmann
2020-11-19 11:39 ` Kiran K [this message]
2020-12-03 13:55 ` [PATCH v8 4/5] Bluetooth: btusb: Helper function to download firmware to Intel adapters Marcel Holtmann
2020-11-19 11:39 ` [PATCH v8 5/5] Bluetooth: btusb: Map Typhoon peak controller to BTUSB_INTEL_NEWGEN Kiran K
2020-12-03 13:54 ` Marcel Holtmann
2020-11-21 1:31 ` [v8,1/5] Bluetooth: btintel: Fix endianness issue for TLV version information bluez.test.bot
2020-12-03 13:55 ` [PATCH v8 1/5] " Marcel Holtmann
-- strict thread matches above, loose matches on Subject: below --
2020-11-19 11:34 Kiran K
2020-11-19 11:34 ` [PATCH v8 4/5] Bluetooth: btusb: Helper function to download firmware to Intel adapters Kiran K
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201119113943.13839-4-kiran.k@intel.com \
--to=kiran.k@intel.com \
--cc=chethan.tumkur.narayan@intel.com \
--cc=linux-bluetooth@vger.kernel.org \
--cc=ravishankar.srivatsa@intel.com \
--cc=sathish.narasimman@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.