aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2015-06-07 03:47:08 -0400
committerJohan Hedberg <johan.hedberg@intel.com>2015-06-09 03:41:49 -0400
commite66890a96abbb746e1229c3067471be36dc49b34 (patch)
tree3fca106502e3f4f0e9887b7393e7d46c1329a567 /drivers/bluetooth
parent8b76ce34c43a569f981623485c1b6c700594678e (diff)
Bluetooth: btusb: Fix secure send command length alignment on Intel 8260
This patch fixes the command length alignment issue for Intel Bluetooth 8260. The length of parameters in the firmware downloading command must be multiplication of 4. If not, the command must append Intel_NOP command with extra parameters, zeros, at the end, and the firmware file is already included Intel_NOP command for alignment. This patch checks the next command and if the next command is Intel_NOP command, it reads the Intel_NOP command and send them together. For example, if the data from the firmware file looks like this: 8E FC 03 11 22 33 02 FC 03 00 00 00 Previously, btusb sends two commands: 09 FC 06 8E FC 03 11 22 33 09 FC 06 02 FC 03 00 00 00 This won't work because the length of parameters are 6 which violates the 4 byte alignment. This patch will append them together and send as one command: 09 FC 0C 8E FC 03 11 22 33 02 FC 03 00 00 00 Based on previous work from Tedd Ho-Jeong An <tedd.an@intel.com> Reported-by: Tedd Ho-Jeong An <tedd.an@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Tested-by: Tedd Ho-Jeong An <tedd.an@intel.com> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers/bluetooth')
-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)
1932 struct intel_boot_params *params; 1932 struct intel_boot_params *params;
1933 const struct firmware *fw; 1933 const struct firmware *fw;
1934 const u8 *fw_ptr; 1934 const u8 *fw_ptr;
1935 u32 frag_len;
1935 char fwname[64]; 1936 char fwname[64];
1936 ktime_t calltime, delta, rettime; 1937 ktime_t calltime, delta, rettime;
1937 unsigned long long duration; 1938 unsigned long long duration;
@@ -2124,24 +2125,33 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
2124 } 2125 }
2125 2126
2126 fw_ptr = fw->data + 644; 2127 fw_ptr = fw->data + 644;
2128 frag_len = 0;
2127 2129
2128 while (fw_ptr - fw->data < fw->size) { 2130 while (fw_ptr - fw->data < fw->size) {
2129 struct hci_command_hdr *cmd = (void *)fw_ptr; 2131 struct hci_command_hdr *cmd = (void *)(fw_ptr + frag_len);
2130 u8 cmd_len;
2131 2132
2132 cmd_len = sizeof(*cmd) + cmd->plen; 2133 frag_len += sizeof(*cmd) + cmd->plen;
2133 2134
2134 /* Send each command from the firmware data buffer as 2135 /* The paramter length of the secure send command requires
2135 * a single Data fragment. 2136 * a 4 byte alignment. It happens so that the firmware file
2137 * contains proper Intel_NOP commands to align the fragments
2138 * as needed.
2139 *
2140 * Send set of commands with 4 byte alignment from the
2141 * firmware data buffer as a single Data fragement.
2136 */ 2142 */
2137 err = btusb_intel_secure_send(hdev, 0x01, cmd_len, fw_ptr); 2143 if (!(frag_len % 4)) {
2138 if (err < 0) { 2144 err = btusb_intel_secure_send(hdev, 0x01, frag_len,
2139 BT_ERR("%s: Failed to send firmware data (%d)", 2145 fw_ptr);
2140 hdev->name, err); 2146 if (err < 0) {
2141 goto done; 2147 BT_ERR("%s: Failed to send firmware data (%d)",
2142 } 2148 hdev->name, err);
2149 goto done;
2150 }
2143 2151
2144 fw_ptr += cmd_len; 2152 fw_ptr += frag_len;
2153 frag_len = 0;
2154 }
2145 } 2155 }
2146 2156
2147 set_bit(BTUSB_FIRMWARE_LOADED, &data->flags); 2157 set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);