in btintel.c [1806:1969]
static int btintel_download_fw(struct hci_dev *hdev,
struct intel_version *ver,
struct intel_boot_params *params,
u32 *boot_param)
{
const struct firmware *fw;
char fwname[64];
int err;
ktime_t calltime;
if (!ver || !params)
return -EINVAL;
/* 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.
*
* 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->fw_variant == 0x23) {
btintel_clear_flag(hdev, INTEL_BOOTLOADER);
btintel_check_bdaddr(hdev);
/* SfP and WsP don't seem to update the firmware version on file
* so version checking is currently possible.
*/
switch (ver->hw_variant) {
case 0x0b: /* SfP */
case 0x0c: /* WsP */
return 0;
}
/* Proceed to download to check if the version matches */
goto download;
}
/* Read the secure boot parameters to identify the operating
* details of the bootloader.
*/
err = btintel_read_boot_params(hdev, params);
if (err)
return err;
/* 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 (params->limited_cce != 0x00) {
bt_dev_err(hdev, "Unsupported Intel firmware loading method (%u)",
params->limited_cce);
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(¶ms->otp_bdaddr, BDADDR_ANY)) {
bt_dev_info(hdev, "No device address configured");
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.
*
* The firmware filename is ibt-<hw_variant>-<dev_revid>.sfi.
*
* Currently the supported hardware variants are:
* 11 (0x0b) for iBT3.0 (LnP/SfP)
* 12 (0x0c) for iBT3.5 (WsP)
*
* For ThP/JfP and for future SKU's, the FW name varies based on HW
* variant, HW revision and FW revision, as these are dependent on CNVi
* and RF Combination.
*
* 17 (0x11) for iBT3.5 (JfP)
* 18 (0x12) for iBT3.5 (ThP)
*
* The firmware file name for these will be
* ibt-<hw_variant>-<hw_revision>-<fw_revision>.sfi.
*
*/
err = btintel_get_fw_name(ver, params, fwname, sizeof(fwname), "sfi");
if (err < 0) {
if (!btintel_test_flag(hdev, INTEL_BOOTLOADER)) {
/* Firmware has already been loaded */
btintel_set_flag(hdev, INTEL_FIRMWARE_LOADED);
return 0;
}
bt_dev_err(hdev, "Unsupported Intel firmware naming");
return -EINVAL;
}
err = firmware_request_nowarn(&fw, fwname, &hdev->dev);
if (err < 0) {
if (!btintel_test_flag(hdev, INTEL_BOOTLOADER)) {
/* Firmware has already been loaded */
btintel_set_flag(hdev, INTEL_FIRMWARE_LOADED);
return 0;
}
bt_dev_err(hdev, "Failed to load Intel firmware file %s (%d)",
fwname, 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;
}
calltime = ktime_get();
btintel_set_flag(hdev, INTEL_DOWNLOADING);
/* Start firmware downloading and get boot parameter */
err = btintel_download_firmware(hdev, ver, fw, boot_param);
if (err < 0) {
if (err == -EALREADY) {
/* Firmware has already been loaded */
btintel_set_flag(hdev, INTEL_FIRMWARE_LOADED);
err = 0;
goto done;
}
/* When FW download fails, send Intel Reset to retry
* FW download.
*/
btintel_reset_to_bootloader(hdev);
goto done;
}
/* 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
* INTEL_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 = btintel_download_wait(hdev, calltime, 5000);
if (err == -ETIMEDOUT)
btintel_reset_to_bootloader(hdev);
done:
release_firmware(fw);
return err;
}