diff options
Diffstat (limited to 'drivers/bluetooth/btintel.c')
-rw-r--r-- | drivers/bluetooth/btintel.c | 88 |
1 files changed, 71 insertions, 17 deletions
diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index 6ba7f5d1b837..0c855c3ee1c1 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -245,7 +245,7 @@ static int btintel_set_diag_combined(struct hci_dev *hdev, bool enable) return ret; } -static void btintel_hw_error(struct hci_dev *hdev, u8 code) +void btintel_hw_error(struct hci_dev *hdev, u8 code) { struct sk_buff *skb; u8 type = 0x00; @@ -277,6 +277,7 @@ static void btintel_hw_error(struct hci_dev *hdev, u8 code) kfree_skb(skb); } +EXPORT_SYMBOL_GPL(btintel_hw_error); int btintel_version_info(struct hci_dev *hdev, struct intel_version *ver) { @@ -455,8 +456,8 @@ int btintel_read_version(struct hci_dev *hdev, struct intel_version *ver) } EXPORT_SYMBOL_GPL(btintel_read_version); -static int btintel_version_info_tlv(struct hci_dev *hdev, - struct intel_version_tlv *version) +int btintel_version_info_tlv(struct hci_dev *hdev, + struct intel_version_tlv *version) { const char *variant; @@ -481,6 +482,7 @@ static int btintel_version_info_tlv(struct hci_dev *hdev, case 0x19: /* Slr-F */ case 0x1b: /* Mgr */ case 0x1c: /* Gale Peak (GaP) */ + case 0x1e: /* BlazarI (Bzr) */ break; default: bt_dev_err(hdev, "Unsupported Intel hardware variant (0x%x)", @@ -489,7 +491,7 @@ static int btintel_version_info_tlv(struct hci_dev *hdev, } switch (version->img_type) { - case 0x01: + 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 @@ -521,7 +523,10 @@ static int btintel_version_info_tlv(struct hci_dev *hdev, version->min_fw_build_nn, version->min_fw_build_cw, 2000 + version->min_fw_build_yy); break; - case 0x03: + case BTINTEL_IMG_IML: + variant = "Intermediate loader"; + break; + case BTINTEL_IMG_OP: variant = "Firmware"; break; default: @@ -535,15 +540,16 @@ static int btintel_version_info_tlv(struct hci_dev *hdev, bt_dev_info(hdev, "%s timestamp %u.%u buildtype %u build %u", variant, 2000 + (version->timestamp >> 8), version->timestamp & 0xff, version->build_type, version->build_num); - if (version->img_type == 0x03) + if (version->img_type == BTINTEL_IMG_OP) bt_dev_info(hdev, "Firmware SHA1: 0x%8.8x", version->git_sha1); return 0; } +EXPORT_SYMBOL_GPL(btintel_version_info_tlv); -static int btintel_parse_version_tlv(struct hci_dev *hdev, - struct intel_version_tlv *version, - struct sk_buff *skb) +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); @@ -645,6 +651,7 @@ static int btintel_parse_version_tlv(struct hci_dev *hdev, return 0; } +EXPORT_SYMBOL_GPL(btintel_parse_version_tlv); static int btintel_read_version_tlv(struct hci_dev *hdev, struct intel_version_tlv *version) @@ -1172,7 +1179,7 @@ static int btintel_download_fw_tlv(struct hci_dev *hdev, * 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) + if (ver->img_type == BTINTEL_IMG_OP) return -EINVAL; /* iBT hardware variants 0x0b, 0x0c, 0x11, 0x12, 0x13, 0x14 support @@ -2194,10 +2201,26 @@ static void btintel_get_fw_name_tlv(const struct intel_version_tlv *ver, char *fw_name, size_t len, const char *suffix) { + const char *format; /* The firmware file name for new generation controllers will be * ibt-<cnvi_top type+cnvi_top step>-<cnvr_top type+cnvr_top step> */ - snprintf(fw_name, len, "intel/ibt-%04x-%04x.%s", + switch (ver->cnvi_top & 0xfff) { + /* Only Blazar product supports downloading of intermediate loader + * image + */ + case BTINTEL_CNVI_BLAZARI: + if (ver->img_type == BTINTEL_IMG_BOOTLOADER) + format = "intel/ibt-%04x-%04x-iml.%s"; + else + format = "intel/ibt-%04x-%04x.%s"; + break; + default: + format = "intel/ibt-%04x-%04x.%s"; + break; + } + + snprintf(fw_name, len, format, INTEL_CNVX_TOP_PACK_SWAB(INTEL_CNVX_TOP_TYPE(ver->cnvi_top), INTEL_CNVX_TOP_STEP(ver->cnvi_top)), INTEL_CNVX_TOP_PACK_SWAB(INTEL_CNVX_TOP_TYPE(ver->cnvr_top), @@ -2230,7 +2253,7 @@ static int btintel_prepare_fw_download_tlv(struct hci_dev *hdev, * 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) { + if (ver->img_type == BTINTEL_IMG_OP) { btintel_clear_flag(hdev, INTEL_BOOTLOADER); btintel_check_bdaddr(hdev); } else { @@ -2577,8 +2600,8 @@ static void btintel_set_dsm_reset_method(struct hci_dev *hdev, data->acpi_reset_method = btintel_acpi_reset_method; } -static int btintel_bootloader_setup_tlv(struct hci_dev *hdev, - struct intel_version_tlv *ver) +int btintel_bootloader_setup_tlv(struct hci_dev *hdev, + struct intel_version_tlv *ver) { u32 boot_param; char ddcname[64]; @@ -2600,13 +2623,30 @@ static int btintel_bootloader_setup_tlv(struct hci_dev *hdev, return err; /* check if controller is already having an operational firmware */ - if (ver->img_type == 0x03) + if (ver->img_type == BTINTEL_IMG_OP) goto finish; err = btintel_boot(hdev, boot_param); if (err) return err; + err = btintel_read_version_tlv(hdev, ver); + if (err) + return err; + + /* If image type returned is BTINTEL_IMG_IML, then controller supports + * intermediae loader image + */ + if (ver->img_type == BTINTEL_IMG_IML) { + err = btintel_prepare_fw_download_tlv(hdev, ver, &boot_param); + if (err) + return err; + + err = btintel_boot(hdev, boot_param); + if (err) + return err; + } + btintel_clear_flag(hdev, INTEL_BOOTLOADER); btintel_get_fw_name_tlv(ver, ddcname, sizeof(ddcname), "ddc"); @@ -2645,8 +2685,9 @@ finish: return 0; } +EXPORT_SYMBOL_GPL(btintel_bootloader_setup_tlv); -static void btintel_set_msft_opcode(struct hci_dev *hdev, u8 hw_variant) +void btintel_set_msft_opcode(struct hci_dev *hdev, u8 hw_variant) { switch (hw_variant) { /* Legacy bootloader devices that supports MSFT Extension */ @@ -2662,6 +2703,7 @@ static void btintel_set_msft_opcode(struct hci_dev *hdev, u8 hw_variant) case 0x19: case 0x1b: case 0x1c: + case 0x1e: hci_set_msft_opcode(hdev, 0xFC1E); break; default: @@ -2669,6 +2711,7 @@ static void btintel_set_msft_opcode(struct hci_dev *hdev, u8 hw_variant) break; } } +EXPORT_SYMBOL_GPL(btintel_set_msft_opcode); static void btintel_print_fseq_info(struct hci_dev *hdev) { @@ -2920,6 +2963,11 @@ static int btintel_setup_combined(struct hci_dev *hdev) err = -EINVAL; } + hci_set_hw_info(hdev, + "INTEL platform=%u variant=%u revision=%u", + ver.hw_platform, ver.hw_variant, + ver.hw_revision); + goto exit_error; } @@ -2996,6 +3044,7 @@ static int btintel_setup_combined(struct hci_dev *hdev) case 0x19: case 0x1b: case 0x1c: + case 0x1e: /* Display version information of TLV type */ btintel_version_info_tlv(hdev, &ver_tlv); @@ -3024,13 +3073,17 @@ static int btintel_setup_combined(struct hci_dev *hdev) break; } + hci_set_hw_info(hdev, "INTEL platform=%u variant=%u", + INTEL_HW_PLATFORM(ver_tlv.cnvi_bt), + INTEL_HW_VARIANT(ver_tlv.cnvi_bt)); + exit_error: kfree_skb(skb); return err; } -static int btintel_shutdown_combined(struct hci_dev *hdev) +int btintel_shutdown_combined(struct hci_dev *hdev) { struct sk_buff *skb; int ret; @@ -3064,6 +3117,7 @@ static int btintel_shutdown_combined(struct hci_dev *hdev) return 0; } +EXPORT_SYMBOL_GPL(btintel_shutdown_combined); int btintel_configure_setup(struct hci_dev *hdev, const char *driver_name) { |