/* For some Intel based controllers, the default Bluetooth device * address 00:03:19:9E:8B:00 can be found. These controllers are * fully operational, but have the danger of duplicate addresses * and that in turn can cause problems with Bluetooth operation.
*/ if (!bacmp(&bda->bdaddr, BDADDR_INTEL)) {
bt_dev_err(hdev, "Found Intel default device address (%pMR)",
&bda->bdaddr);
hci_set_quirk(hdev, HCI_QUIRK_INVALID_BDADDR);
}
staticint btintel_set_diag_mfg(struct hci_dev *hdev, bool enable)
{ int err, ret;
err = btintel_enter_mfg(hdev); if (err) return err;
ret = btintel_set_diag(hdev, enable);
err = btintel_exit_mfg(hdev, false, false); if (err) return err;
return ret;
}
staticint btintel_set_diag_combined(struct hci_dev *hdev, bool enable)
{ int ret;
/* Legacy ROM device needs to be in the manufacturer mode to apply * diagnostic setting * * This flag is set after reading the Intel version.
*/ if (btintel_test_flag(hdev, INTEL_ROM_LEGACY))
ret = btintel_set_diag_mfg(hdev, enable); else
ret = btintel_set_diag(hdev, enable);
int btintel_version_info(struct hci_dev *hdev, struct intel_version *ver)
{ constchar *variant;
/* 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 0x07: /* WP - Legacy ROM */ case 0x08: /* StP - Legacy ROM */ 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;
}
switch (ver->fw_variant) { case 0x01:
variant = "Legacy ROM 2.5"; break; case 0x06:
variant = "Bootloader"; break; case 0x22:
variant = "Legacy ROM 2.x"; break; case 0x23:
variant = "Firmware"; break; default:
bt_dev_err(hdev, "Unsupported firmware variant(%02x)", ver->fw_variant); return -EINVAL;
}
/* DDC file contains one or more DDC structure which has * Length (1 byte), DDC ID (2 bytes), and DDC value (Length - 2).
*/ while (fw->size > fw_ptr - fw->data) {
u8 cmd_plen = fw_ptr[0] + sizeof(u8);
int btintel_version_info_tlv(struct hci_dev *hdev, struct intel_version_tlv *version)
{ constchar *variant;
/* The hardware platform number has a fixed value of 0x37 and * for now only accept this single value.
*/ if (INTEL_HW_PLATFORM(version->cnvi_bt) != 0x37) {
bt_dev_err(hdev, "Unsupported Intel hardware platform (0x%2x)",
INTEL_HW_PLATFORM(version->cnvi_bt)); 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 (INTEL_HW_VARIANT(version->cnvi_bt)) { case 0x17: /* TyP */ case 0x18: /* Slr */ case 0x19: /* Slr-F */ case 0x1b: /* Mgr */ case 0x1c: /* Gale Peak (GaP) */ case 0x1d: /* BlazarU (BzrU) */ case 0x1e: /* BlazarI (Bzr) */ case 0x1f: /* Scorpious Peak */ case 0x22: /* BlazarIW (BzrIW) */ break; default:
bt_dev_err(hdev, "Unsupported Intel hardware variant (0x%x)",
INTEL_HW_VARIANT(version->cnvi_bt)); return -EINVAL;
}
switch (version->img_type) { case BTINTEL_IMG_BOOTLOADER:
variant = "Bootloader"; /* 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 (version->limited_cce != 0x00) {
bt_dev_err(hdev, "Unsupported Intel firmware loading method (0x%x)",
version->limited_cce); return -EINVAL;
}
/* Secure boot engine type should be either 1 (ECDSA) or 0 (RSA) */ if (version->sbe_type > 0x01) {
bt_dev_err(hdev, "Unsupported Intel secure boot engine type (0x%x)",
version->sbe_type); return -EINVAL;
}
bt_dev_info(hdev, "Device revision is %u", version->dev_rev_id);
bt_dev_info(hdev, "Secure boot is %s",
str_enabled_disabled(version->secure_boot));
bt_dev_info(hdev, "OTP lock is %s",
str_enabled_disabled(version->otp_lock));
bt_dev_info(hdev, "API lock is %s",
str_enabled_disabled(version->api_lock));
bt_dev_info(hdev, "Debug lock is %s",
str_enabled_disabled(version->debug_lock));
bt_dev_info(hdev, "Minimum firmware build %u week %u %u",
version->min_fw_build_nn, version->min_fw_build_cw,
2000 + version->min_fw_build_yy); break; case BTINTEL_IMG_IML:
variant = "Intermediate loader"; break; case BTINTEL_IMG_OP:
variant = "Firmware"; break; default:
bt_dev_err(hdev, "Unsupported image type(%02x)", version->img_type); return -EINVAL;
}
int btintel_parse_version_tlv(struct hci_dev *hdev, struct intel_version_tlv *version, struct sk_buff *skb)
{ /* Consume Command Complete Status field */
skb_pull(skb, 1);
/* Event parameters contain multiple TLVs. Read each of them * and only keep the required data. Also, it use existing legacy * version field like hw_platform, hw_variant, and fw_variant * to keep the existing setup flow
*/ while (skb->len) { struct intel_tlv *tlv;
/* Make sure skb has a minimum length of the header */ if (skb->len < sizeof(*tlv)) return -EINVAL;
tlv = (struct intel_tlv *)skb->data;
/* Make sure skb has a enough data */ if (skb->len < tlv->len + sizeof(*tlv)) return -EINVAL;
switch (tlv->type) { case INTEL_TLV_CNVI_TOP:
version->cnvi_top = get_unaligned_le32(tlv->val); break; case INTEL_TLV_CNVR_TOP:
version->cnvr_top = get_unaligned_le32(tlv->val); break; case INTEL_TLV_CNVI_BT:
version->cnvi_bt = get_unaligned_le32(tlv->val); break; case INTEL_TLV_CNVR_BT:
version->cnvr_bt = get_unaligned_le32(tlv->val); break; case INTEL_TLV_DEV_REV_ID:
version->dev_rev_id = get_unaligned_le16(tlv->val); break; case INTEL_TLV_IMAGE_TYPE:
version->img_type = tlv->val[0]; break; case INTEL_TLV_TIME_STAMP: /* If image type is Operational firmware (0x03), then * running FW Calendar Week and Year information can * be extracted from Timestamp information
*/
version->min_fw_build_cw = tlv->val[0];
version->min_fw_build_yy = tlv->val[1];
version->timestamp = get_unaligned_le16(tlv->val); break; case INTEL_TLV_BUILD_TYPE:
version->build_type = tlv->val[0]; break; case INTEL_TLV_BUILD_NUM: /* If image type is Operational firmware (0x03), then * running FW build number can be extracted from the * Build information
*/
version->min_fw_build_nn = tlv->val[0];
version->build_num = get_unaligned_le32(tlv->val); break; case INTEL_TLV_SECURE_BOOT:
version->secure_boot = tlv->val[0]; break; case INTEL_TLV_OTP_LOCK:
version->otp_lock = tlv->val[0]; break; case INTEL_TLV_API_LOCK:
version->api_lock = tlv->val[0]; break; case INTEL_TLV_DEBUG_LOCK:
version->debug_lock = tlv->val[0]; break; case INTEL_TLV_MIN_FW:
version->min_fw_build_nn = tlv->val[0];
version->min_fw_build_cw = tlv->val[1];
version->min_fw_build_yy = tlv->val[2]; break; case INTEL_TLV_LIMITED_CCE:
version->limited_cce = tlv->val[0]; break; case INTEL_TLV_SBE_TYPE:
version->sbe_type = tlv->val[0]; break; case INTEL_TLV_OTP_BDADDR:
memcpy(&version->otp_bd_addr, tlv->val, sizeof(bdaddr_t)); break; case INTEL_TLV_GIT_SHA1:
version->git_sha1 = get_unaligned_le32(tlv->val); break; case INTEL_TLV_FW_ID:
snprintf(version->fw_id, sizeof(version->fw_id), "%s", tlv->val); break; default: /* Ignore rest of information */ break;
} /* consume the current tlv and move to next*/
skb_pull(skb, tlv->len + sizeof(*tlv));
}
staticint regmap_ibt_write(void *context, constvoid *data, size_t count)
{ /* data contains register+value, since we only support 32bit addr, * minimum data size is 4 bytes.
*/ if (WARN_ONCE(count < 4, "Invalid register access")) return -EINVAL;
/* Config is the same for all register regions */ staticconststruct regmap_config regmap_ibt_cfg = {
.name = "btintel_regmap",
.reg_bits = 32,
.val_bits = 32,
};
staticint btintel_sfi_rsa_header_secure_send(struct hci_dev *hdev, conststruct firmware *fw)
{ int err;
/* Start the firmware download transaction with the Init fragment * represented by the 128 bytes of CSS header.
*/
err = btintel_secure_send(hdev, 0x00, 128, fw->data); if (err < 0) {
bt_dev_err(hdev, "Failed to send firmware header (%d)", err); goto done;
}
/* Send the 256 bytes of public key information from the firmware * as the PKey fragment.
*/
err = btintel_secure_send(hdev, 0x03, 256, fw->data + 128); if (err < 0) {
bt_dev_err(hdev, "Failed to send firmware pkey (%d)", err); goto done;
}
/* Send the 256 bytes of signature information from the firmware * as the Sign fragment.
*/
err = btintel_secure_send(hdev, 0x02, 256, fw->data + 388); if (err < 0) {
bt_dev_err(hdev, "Failed to send firmware signature (%d)", err); goto done;
}
done: return err;
}
staticint btintel_sfi_ecdsa_header_secure_send(struct hci_dev *hdev, conststruct firmware *fw)
{ int err;
/* Start the firmware download transaction with the Init fragment * represented by the 128 bytes of CSS header.
*/
err = btintel_secure_send(hdev, 0x00, 128, fw->data + 644); if (err < 0) {
bt_dev_err(hdev, "Failed to send firmware header (%d)", err); return err;
}
/* Send the 96 bytes of public key information from the firmware * as the PKey fragment.
*/
err = btintel_secure_send(hdev, 0x03, 96, fw->data + 644 + 128); if (err < 0) {
bt_dev_err(hdev, "Failed to send firmware pkey (%d)", err); return err;
}
/* Send the 96 bytes of signature information from the firmware * as the Sign fragment
*/
err = btintel_secure_send(hdev, 0x02, 96, fw->data + 644 + 224); if (err < 0) {
bt_dev_err(hdev, "Failed to send firmware signature (%d)",
err); return err;
} return 0;
}
/* The parameter length of the secure send command requires * a 4 byte alignment. It happens so that the firmware file * contains proper Intel_NOP commands to align the fragments * as needed. * * Send set of commands with 4 byte alignment from the * firmware data buffer as a single Data fragment.
*/ if (!(frag_len % 4)) {
err = btintel_secure_send(hdev, 0x01, frag_len, fw_ptr); if (err < 0) {
bt_dev_err(hdev, "Failed to send firmware data (%d)",
err); goto done;
}
/* Each SKU has a different reset parameter to use in the * HCI_Intel_Reset command and it is embedded in the firmware * data. So, instead of using static value per SKU, check * the firmware data and save it for later use.
*/ if (le16_to_cpu(cmd->opcode) == CMD_WRITE_BOOT_PARAMS) { struct cmd_write_boot_params *params;
int btintel_download_firmware(struct hci_dev *hdev, struct intel_version *ver, conststruct firmware *fw,
u32 *boot_param)
{ int err;
/* SfP and WsP don't seem to update the firmware version on file * so version checking is currently not possible.
*/ switch (ver->hw_variant) { case 0x0b: /* SfP */ case 0x0c: /* WsP */ /* Skip version checking */ break; default:
/* Skip download if firmware has the same version */ if (btintel_firmware_version(hdev, ver->fw_build_num,
ver->fw_build_ww, ver->fw_build_yy,
fw, boot_param)) {
bt_dev_info(hdev, "Firmware already loaded"); /* Return -EALREADY to indicate that the firmware has * already been loaded.
*/ 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;
/* Skip download if firmware has the same version */ if (btintel_firmware_version(hdev, ver->min_fw_build_nn,
ver->min_fw_build_cw,
ver->min_fw_build_yy,
fw, boot_param)) {
bt_dev_info(hdev, "Firmware already loaded"); /* Return -EALREADY to indicate that firmware has * already been loaded.
*/ return -EALREADY;
}
/* The firmware variant determines if the device is in bootloader * mode or is running operational firmware. The value 0x01 identifies * the bootloader and the value 0x03 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 == BTINTEL_IMG_OP) 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. * * iBT hardware variants 0x17, 0x18 onwards support both RSA and ECDSA * secure boot engine. As a result, the corresponding sfi file will * have RSA header of 644, ECDSA header of 320 bytes followed by * Command Buffer. * * CSS Header byte positions 0x08 to 0x0B represent the CSS Header * version: RSA(0x00010000) , ECDSA (0x00020000)
*/
css_header_ver = get_unaligned_le32(fw->data + CSS_HEADER_OFFSET); if (css_header_ver != 0x00010000) {
bt_dev_err(hdev, "Invalid CSS Header version"); return -EINVAL;
}
if (hw_variant <= 0x14) { if (sbe_type != 0x00) {
bt_dev_err(hdev, "Invalid SBE type for hardware variant (%d)",
hw_variant); return -EINVAL;
}
err = btintel_sfi_rsa_header_secure_send(hdev, fw); if (err) return err;
err = btintel_download_firmware_payload(hdev, fw, RSA_HEADER_LEN); if (err) return err;
} elseif (hw_variant >= 0x17) { /* Check if CSS header for ECDSA follows the RSA header */ if (fw->data[ECDSA_OFFSET] != 0x06) return -EINVAL;
/* Check if the CSS Header version is ECDSA(0x00020000) */
css_header_ver = get_unaligned_le32(fw->data + ECDSA_OFFSET + CSS_HEADER_OFFSET); if (css_header_ver != 0x00020000) {
bt_dev_err(hdev, "Invalid CSS Header version"); return -EINVAL;
}
if (sbe_type == 0x00) {
err = btintel_sfi_rsa_header_secure_send(hdev, fw); if (err) return err;
/* PCIe transport uses shared hardware reset mechanism for recovery * which gets triggered in pcie *setup* function on error.
*/ if (hdev->bus == HCI_PCI) return;
/* Send Intel Reset command. This will result in * re-enumeration of BT controller. * * Intel Reset parameter description: * reset_type : 0x00 (Soft reset), * 0x01 (Hard reset) * patch_enable : 0x00 (Do not enable), * 0x01 (Enable) * ddc_reload : 0x00 (Do not reload), * 0x01 (Reload) * boot_option: 0x00 (Current image), * 0x01 (Specified boot address) * boot_param: Boot address *
*/
skb = __hci_cmd_sync(hdev, BTINTEL_HCI_OP_RESET, sizeof(params),
¶ms, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) {
bt_dev_err(hdev, "FW download error recovery failed (%ld)",
PTR_ERR(skb)); return;
}
bt_dev_info(hdev, "Intel reset sent to retry FW download");
kfree_skb(skb);
/* Current Intel BT controllers(ThP/JfP) hold the USB reset * lines for 2ms when it receives Intel Reset in bootloader mode. * Whereas, the upcoming Intel BT controllers will hold USB reset * for 150ms. To keep the delay generic, 150ms is chosen here.
*/
msleep(150);
}
/* Intel controller supports two pages, each page is of 128-bit * feature bit mask. And each bit defines specific feature support
*/
skb = __hci_cmd_sync(hdev, 0xfca6, sizeof(page_no), &page_no,
HCI_INIT_TIMEOUT); if (IS_ERR(skb)) {
bt_dev_err(hdev, "Reading supported features failed (%ld)",
PTR_ERR(skb)); return PTR_ERR(skb);
}
if (skb->len != (sizeof(features->page1) + 3)) {
bt_dev_err(hdev, "Supported features event size mismatch");
kfree_skb(skb); return -EILSEQ;
}
int btintel_set_quality_report(struct hci_dev *hdev, bool enable)
{ struct intel_debug_features features; int err;
bt_dev_dbg(hdev, "enable %d", enable);
/* Read the Intel supported features and if new exception formats * supported, need to load the additional DDC config to enable.
*/
err = btintel_read_debug_features(hdev, &features); if (err) return err;
/* Set or reset the debug features. */ if (enable)
err = btintel_set_debug_features(hdev, &features); else
err = btintel_reset_debug_features(hdev, &features);
ret = request_firmware(&fw, fwname, &hdev->dev); if (ret < 0) { if (ret == -EINVAL) {
bt_dev_err(hdev, "Intel firmware file request failed (%d)",
ret); return NULL;
}
bt_dev_err(hdev, "failed to open Intel firmware file: %s (%d)",
fwname, ret);
/* If the correct firmware patch file is not found, use the * default firmware patch file instead
*/
snprintf(fwname, sizeof(fwname), "intel/ibt-hw-%x.%x.bseq",
ver->hw_platform, ver->hw_variant); if (request_firmware(&fw, fwname, &hdev->dev) < 0) {
bt_dev_err(hdev, "failed to open default fw file: %s",
fwname); return NULL;
}
}
bt_dev_info(hdev, "Intel Bluetooth firmware file: %s", fwname);
/* The first byte indicates the types of the patch command or event. * 0x01 means HCI command and 0x02 is HCI event. If the first bytes * in the current firmware buffer doesn't start with 0x01 or * the size of remain buffer is smaller than HCI command header, * the firmware file is corrupted and it should stop the patching * process.
*/ if (remain > HCI_COMMAND_HDR_SIZE && *fw_ptr[0] != 0x01) {
bt_dev_err(hdev, "Intel fw corrupted: invalid cmd read"); return -EINVAL;
}
(*fw_ptr)++;
remain--;
/* Ensure that the remain firmware data is long enough than the length * of command parameter. If not, the firmware file is corrupted.
*/ if (remain < cmd->plen) {
bt_dev_err(hdev, "Intel fw corrupted: invalid cmd len"); return -EFAULT;
}
/* If there is a command that loads a patch in the firmware * file, then enable the patch upon success, otherwise just * disable the manufacturer mode, for example patch activation * is not required when the default firmware patch file is used * because there are no patch data to load.
*/ if (*disable_patch && le16_to_cpu(cmd->opcode) == 0xfc8e)
*disable_patch = 0;
/* This reads the expected events when the above command is sent to the * device. Some vendor commands expects more than one events, for * example command status event followed by vendor specific event. * For this case, it only keeps the last expected event. so the command * can be sent with __hci_cmd_sync_ev() which returns the sk_buff of * last expected event.
*/ while (remain > HCI_EVENT_HDR_SIZE && *fw_ptr[0] == 0x02) {
(*fw_ptr)++;
remain--;
/* Every HCI commands in the firmware file has its correspond event. * If event is not found or remain is smaller than zero, the firmware * file is corrupted.
*/ if (!evt || !evt_param || remain < 0) {
bt_dev_err(hdev, "Intel fw corrupted: invalid evt read"); return -EFAULT;
}
/* It ensures that the returned event matches the event data read from * the firmware file. At fist, it checks the length and then * the contents of the event.
*/ if (skb->len != evt->plen) {
bt_dev_err(hdev, "mismatch event length (opcode 0x%4.4x)",
le16_to_cpu(cmd->opcode));
kfree_skb(skb); return -EFAULT;
}
/* fw_patch_num indicates the version of patch the device currently * have. If there is no patch data in the device, it is always 0x00. * So, if it is other than 0x00, no need to patch the device again.
*/ if (ver->fw_patch_num) {
bt_dev_info(hdev, "Intel device is already patched. patch num: %02x",
ver->fw_patch_num); goto complete;
}
/* Opens the firmware patch file based on the firmware version read * from the controller. If it fails to open the matching firmware * patch file, it tries to open the default firmware patch file. * If no patch file is found, allow the device to operate without * a patch.
*/
fw = btintel_legacy_rom_get_fw(hdev, ver); if (!fw) goto complete;
fw_ptr = fw->data;
/* Enable the manufacturer mode of the controller. * Only while this mode is enabled, the driver can download the * firmware patch data and configuration parameters.
*/
err = btintel_enter_mfg(hdev); if (err) {
release_firmware(fw); return err;
}
disable_patch = 1;
/* The firmware data file consists of list of Intel specific HCI * commands and its expected events. The first byte indicates the * type of the message, either HCI command or HCI event. * * It reads the command and its expected event from the firmware file, * and send to the controller. Once __hci_cmd_sync_ev() returns, * the returned event is compared with the event read from the firmware * file and it will continue until all the messages are downloaded to * the controller. * * Once the firmware patching is completed successfully, * the manufacturer mode is disabled with reset and activating the * downloaded patch. * * If the firmware patching fails, the manufacturer mode is * disabled with reset and deactivating the patch. * * If the default patch file is used, no reset is done when disabling * the manufacturer.
*/ while (fw->size > fw_ptr - fw->data) { int ret;
ret = btintel_legacy_rom_patching(hdev, fw, &fw_ptr,
&disable_patch); if (ret < 0) goto exit_mfg_deactivate;
}
release_firmware(fw);
if (disable_patch) goto exit_mfg_disable;
/* Patching completed successfully and disable the manufacturer mode * with reset and activate the downloaded firmware patches.
*/
err = btintel_exit_mfg(hdev, true, true); if (err) return err;
/* Need build number for downloaded fw patches in * every power-on boot
*/
err = btintel_read_version(hdev, &new_ver); if (err) return err;
/* Patching failed. Disable the manufacturer mode with reset and * deactivate the downloaded firmware patches.
*/
err = btintel_exit_mfg(hdev, true, false); if (err) return err;
bt_dev_info(hdev, "Intel firmware patch completed and deactivated");
complete: /* Set the event mask for Intel specific vendor events. This enables * a few extra events that are useful during general operation.
*/
btintel_set_event_mask_mfg(hdev, false);
btintel_check_bdaddr(hdev);
return 0;
}
staticint btintel_download_wait(struct hci_dev *hdev, ktime_t calltime, int msec)
{
ktime_t delta, rettime; unsignedlonglong duration; int err;
btintel_set_flag(hdev, INTEL_FIRMWARE_LOADED);
bt_dev_info(hdev, "Waiting for firmware download to complete");
/* The bootloader will not indicate when the device is ready. This * is done by the operational firmware sending bootup notification. * * Booting into operational firmware should not take longer than * 5 second. However if that happens, then just fail the setup * since something went wrong.
*/
err = btintel_boot_wait(hdev, calltime, 5000); if (err == -ETIMEDOUT) {
btintel_reset_to_bootloader(hdev); goto exit_error;
}
if (hdev->bus == HCI_PCI) { /* In case of PCIe, after receiving bootup event, driver performs * D0 entry by writing 0 to sleep control register (check * btintel_pcie_recv_event()) * Firmware acks with alive interrupt indicating host is full ready to * perform BT operation. Lets wait here till INTEL_WAIT_FOR_D0 * bit is cleared.
*/
calltime = ktime_get();
err = btintel_boot_wait_d0(hdev, calltime, 2000);
}
/* 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");
hci_set_quirk(hdev, HCI_QUIRK_INVALID_BDADDR);
}
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;
}
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);
/* Set the default boot parameter to 0x0 and it is updated to * SKU specific boot parameter after reading Intel_Write_Boot_Params * command while downloading the firmware.
*/
boot_param = 0x00000000;
btintel_set_flag(hdev, INTEL_BOOTLOADER);
err = btintel_download_fw(hdev, ver, ¶ms, &boot_param); if (err) return err;
/* controller is already having an operational firmware */ if (ver->fw_variant == 0x23) goto finish;
err = btintel_boot(hdev, boot_param); if (err) return err;
if (err < 0) {
bt_dev_err(hdev, "Unsupported Intel firmware naming");
} else { /* Once the device is running in operational mode, it needs to * apply the device configuration (DDC) parameters. * * The device can work without DDC parameters, so even if it * fails to load the file, no need to fail the setup.
*/
btintel_load_ddc_config(hdev, ddcname);
}
hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT);
/* Read the Intel version information after loading the FW */
err = btintel_read_version(hdev, &new_ver); if (err) return err;
btintel_version_info(hdev, &new_ver);
finish: /* Set the event mask for Intel specific vendor events. This enables * a few extra events that are useful during general operation. It * does not enable any debugging related events. * * The device will function correctly without these events enabled * and thus no need to fail the setup.
*/
btintel_set_event_mask(hdev, false);
/* Only Blazar product supports downloading of intermediate loader * image
*/ if (INTEL_HW_VARIANT(ver->cnvi_bt) >= 0x1e) {
u8 zero[BTINTEL_FWID_MAXLEN];
if (ver->img_type == BTINTEL_IMG_BOOTLOADER) {
format = "intel/ibt-%04x-%04x-iml.%s";
snprintf(fw_name, len, format, cnvi, cnvr, suffix); return;
}
memset(zero, 0, sizeof(zero));
/* ibt-<cnvi_top type+cnvi_top step>-<cnvr_top type+cnvr_top step-fw_id> */ if (memcmp(ver->fw_id, zero, sizeof(zero))) {
format = "intel/ibt-%04x-%04x-%s.%s";
snprintf(fw_name, len, format, cnvi, cnvr,
ver->fw_id, suffix); return;
} /* If firmware id is not present, fallback to legacy naming * convention
*/
} /* Fallback to legacy naming convention for other controllers * ibt-<cnvi_top type+cnvi_top step>-<cnvr_top type+cnvr_top step>
*/
format = "intel/ibt-%04x-%04x.%s";
snprintf(fw_name, len, format, cnvi, cnvr, suffix);
}
/* 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 == BTINTEL_IMG_OP) {
btintel_clear_flag(hdev, INTEL_BOOTLOADER);
btintel_check_bdaddr(hdev);
} else { /* * Check for valid bd address in boot loader mode. Device * will be marked as unconfigured if empty bd address is * found.
*/ if (!bacmp(&ver->otp_bd_addr, BDADDR_ANY)) {
bt_dev_info(hdev, "No device address configured");
hci_set_quirk(hdev, HCI_QUIRK_INVALID_BDADDR);
}
}
if (ver->img_type == BTINTEL_IMG_OP) { /* Controller running OP image. In case of FW downgrade, * FWID TLV may not be present and driver may attempt to load * firmware image which doesn't exist. Lets compare the version * of IML image
*/ if (INTEL_HW_VARIANT(ver->cnvi_bt) >= 0x1e)
btintel_get_iml_tlv(ver, fwname, sizeof(fwname), "sfi"); else
btintel_get_fw_name_tlv(ver, fwname, sizeof(fwname), "sfi");
} else {
btintel_get_fw_name_tlv(ver, fwname, sizeof(fwname), "sfi");
}
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;
}
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_fw_tlv(hdev, ver, fw, boot_param,
INTEL_HW_VARIANT(ver->cnvi_bt),
ver->sbe_type); 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 * 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 = btintel_download_wait(hdev, calltime, 5000); if (err == -ETIMEDOUT)
btintel_reset_to_bootloader(hdev);
staticint btintel_get_data_path_id(struct hci_dev *hdev, __u8 *data_path_id)
{ /* Intel uses 1 as data path id for all the usecases */
*data_path_id = 1; return 0;
}
/* PPAG is not supported if CRF is HrP2, Jfp2, JfP1 */ switch (ver->cnvr_top & 0xFFF) { case 0x504: /* Hrp2 */ case 0x202: /* Jfp2 */ case 0x201: /* Jfp1 */
bt_dev_dbg(hdev, "PPAG not supported for Intel CNVr (0x%3x)",
ver->cnvr_top & 0xFFF); return;
}
handle = ACPI_HANDLE(GET_HCIDEV_DEV(hdev)); if (!handle) {
bt_dev_info(hdev, "No support for BT device in ACPI firmware"); return;
}
status = acpi_evaluate_object(handle, "PPAG", NULL, &buffer); if (ACPI_FAILURE(status)) { if (status == AE_NOT_FOUND) {
bt_dev_dbg(hdev, "PPAG-BT: ACPI entry not found"); return;
}
bt_dev_warn(hdev, "PPAG-BT: ACPI Failure: %s", acpi_format_exception(status)); return;
}
p = buffer.pointer; if (p->type != ACPI_TYPE_PACKAGE || p->package.count != 2) {
bt_dev_warn(hdev, "PPAG-BT: Invalid object type: %d or package count: %d",
p->type, p->package.count);
--> --------------------
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.