summaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/btusb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/btusb.c')
-rw-r--r--drivers/bluetooth/btusb.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 70c06e6d7346..e97d036cde70 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1932,6 +1932,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
struct intel_boot_params *params;
const struct firmware *fw;
const u8 *fw_ptr;
+ u32 frag_len;
char fwname[64];
ktime_t calltime, delta, rettime;
unsigned long long duration;
@@ -2124,24 +2125,33 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
}
fw_ptr = fw->data + 644;
+ frag_len = 0;
while (fw_ptr - fw->data < fw->size) {
- struct hci_command_hdr *cmd = (void *)fw_ptr;
- u8 cmd_len;
+ struct hci_command_hdr *cmd = (void *)(fw_ptr + frag_len);
- cmd_len = sizeof(*cmd) + cmd->plen;
+ frag_len += sizeof(*cmd) + cmd->plen;
- /* Send each command from the firmware data buffer as
- * a single Data fragment.
+ /* The paramter 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 fragement.
*/
- err = btusb_intel_secure_send(hdev, 0x01, cmd_len, fw_ptr);
- if (err < 0) {
- BT_ERR("%s: Failed to send firmware data (%d)",
- hdev->name, err);
- goto done;
- }
+ if (!(frag_len % 4)) {
+ err = btusb_intel_secure_send(hdev, 0x01, frag_len,
+ fw_ptr);
+ if (err < 0) {
+ BT_ERR("%s: Failed to send firmware data (%d)",
+ hdev->name, err);
+ goto done;
+ }
- fw_ptr += cmd_len;
+ fw_ptr += frag_len;
+ frag_len = 0;
+ }
}
set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);