summaryrefslogtreecommitdiff
path: root/drivers/bluetooth/hci_intel.c
diff options
context:
space:
mode:
authorTedd Ho-Jeong An <tedd.an@linux.intel.com>2018-01-24 20:19:19 +0300
committerMarcel Holtmann <marcel@holtmann.org>2018-01-24 21:31:49 +0300
commit04d729b8a56304698c2eec6b93f2319b38851f6e (patch)
treecfeeadf77c9b2e83feeaa5ceda629555105c83dd /drivers/bluetooth/hci_intel.c
parente5889af62fce081dbd2e5d087683b9b7135bc731 (diff)
downloadlinux-04d729b8a56304698c2eec6b93f2319b38851f6e.tar.xz
Bluetooth: btintel: Use boot parameter from firmware file
Each RAM SKU has a different boot parameter which is used in HCI_Intel_Reset command after downloading the firmware. The boot parameter is embedded in the firmware data and to support multiple SKUs, driver reads the boot parameter while downloading the firmware instead of using static values per SKU. Signed-off-by: Tedd Ho-Jeong An <tedd.an@linux.intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth/hci_intel.c')
-rw-r--r--drivers/bluetooth/hci_intel.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c
index acac48d0c79c..6f02f65820a3 100644
--- a/drivers/bluetooth/hci_intel.c
+++ b/drivers/bluetooth/hci_intel.c
@@ -33,6 +33,7 @@
#include <linux/acpi.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
+#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -562,8 +563,11 @@ static int intel_setup(struct hci_uart *hu)
hu->hdev->set_diag = btintel_set_diag;
hu->hdev->set_bdaddr = btintel_set_bdaddr;
- /* Default boot parameter */
- boot_param = 0x00040800;
+ /* 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;
calltime = ktime_get();
@@ -824,6 +828,20 @@ static int intel_setup(struct hci_uart *hu)
while (fw_ptr - fw->data < fw->size) {
struct hci_command_hdr *cmd = (void *)(fw_ptr + frag_len);
+ /* 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 (cmd->opcode == 0xfc0e) {
+ /* The boot parameter is the first 32-bit value
+ * and rest of 3 octets are reserved.
+ */
+ boot_param = get_unaligned_le32(fw_ptr + sizeof(*cmd));
+
+ bt_dev_dbg(hdev, "boot_param=0x%x", boot_param);
+ }
+
frag_len += sizeof(*cmd) + cmd->plen;
bt_dev_dbg(hdev, "Patching %td/%zu", (fw_ptr - fw->data),