diff options
author | Loic Poulain <loic.poulain@intel.com> | 2015-07-01 06:20:26 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-07-23 11:10:49 -0400 |
commit | ca93cee5a56e5199622bea8bff24c0a96e70c8f1 (patch) | |
tree | 11333aa7c821d5896f300b04486d3dfc6f170e9e /drivers/bluetooth | |
parent | 3cf24cf8c3c06f9a6cacc8fc2cad94661b6096b6 (diff) |
Bluetooth: hci_uart: Add basic support for Intel Lightning Peak devices
The Intel Lightning Peak devices do not come with Bluetooth firmware
loaded and thus require a full download of the operational Bluetooth
firmware when the device is attached via the Bluetooth line discipline.
Lightning Peak devices start with a bootloader mode that only accepts
a very limited set of HCI commands. The supported commands are enough
to identify the hardware and select the right firmware to load.
Signed-off-by: Loic Poulain <loic.poulain@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/Kconfig | 1 | ||||
-rw-r--r-- | drivers/bluetooth/hci_intel.c | 604 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ldisc.c | 6 | ||||
-rw-r--r-- | drivers/bluetooth/hci_uart.h | 5 |
4 files changed, 616 insertions, 0 deletions
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 2e777071e1dc..79e8234b1aa5 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig | |||
@@ -132,6 +132,7 @@ config BT_HCIUART_3WIRE | |||
132 | config BT_HCIUART_INTEL | 132 | config BT_HCIUART_INTEL |
133 | bool "Intel protocol support" | 133 | bool "Intel protocol support" |
134 | depends on BT_HCIUART | 134 | depends on BT_HCIUART |
135 | select BT_HCIUART_H4 | ||
135 | select BT_INTEL | 136 | select BT_INTEL |
136 | help | 137 | help |
137 | The Intel protocol support enables Bluetooth HCI over serial | 138 | The Intel protocol support enables Bluetooth HCI over serial |
diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c index 5dd07bf05236..ade19aaeb5c5 100644 --- a/drivers/bluetooth/hci_intel.c +++ b/drivers/bluetooth/hci_intel.c | |||
@@ -24,8 +24,612 @@ | |||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
26 | #include <linux/skbuff.h> | 26 | #include <linux/skbuff.h> |
27 | #include <linux/firmware.h> | ||
28 | #include <linux/wait.h> | ||
27 | 29 | ||
28 | #include <net/bluetooth/bluetooth.h> | 30 | #include <net/bluetooth/bluetooth.h> |
29 | #include <net/bluetooth/hci_core.h> | 31 | #include <net/bluetooth/hci_core.h> |
30 | 32 | ||
31 | #include "hci_uart.h" | 33 | #include "hci_uart.h" |
34 | #include "btintel.h" | ||
35 | |||
36 | #define STATE_BOOTLOADER 0 | ||
37 | #define STATE_DOWNLOADING 1 | ||
38 | #define STATE_FIRMWARE_LOADED 2 | ||
39 | #define STATE_FIRMWARE_FAILED 3 | ||
40 | #define STATE_BOOTING 4 | ||
41 | |||
42 | struct intel_data { | ||
43 | struct sk_buff *rx_skb; | ||
44 | struct sk_buff_head txq; | ||
45 | unsigned long flags; | ||
46 | }; | ||
47 | |||
48 | static int intel_open(struct hci_uart *hu) | ||
49 | { | ||
50 | struct intel_data *intel; | ||
51 | |||
52 | BT_DBG("hu %p", hu); | ||
53 | |||
54 | intel = kzalloc(sizeof(*intel), GFP_KERNEL); | ||
55 | if (!intel) | ||
56 | return -ENOMEM; | ||
57 | |||
58 | skb_queue_head_init(&intel->txq); | ||
59 | |||
60 | hu->priv = intel; | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static int intel_close(struct hci_uart *hu) | ||
65 | { | ||
66 | struct intel_data *intel = hu->priv; | ||
67 | |||
68 | BT_DBG("hu %p", hu); | ||
69 | |||
70 | skb_queue_purge(&intel->txq); | ||
71 | kfree_skb(intel->rx_skb); | ||
72 | kfree(intel); | ||
73 | |||
74 | hu->priv = NULL; | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int intel_flush(struct hci_uart *hu) | ||
79 | { | ||
80 | struct intel_data *intel = hu->priv; | ||
81 | |||
82 | BT_DBG("hu %p", hu); | ||
83 | |||
84 | skb_queue_purge(&intel->txq); | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int inject_cmd_complete(struct hci_dev *hdev, __u16 opcode) | ||
90 | { | ||
91 | struct sk_buff *skb; | ||
92 | struct hci_event_hdr *hdr; | ||
93 | struct hci_ev_cmd_complete *evt; | ||
94 | |||
95 | skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*evt) + 1, GFP_ATOMIC); | ||
96 | if (!skb) | ||
97 | return -ENOMEM; | ||
98 | |||
99 | hdr = (struct hci_event_hdr *)skb_put(skb, sizeof(*hdr)); | ||
100 | hdr->evt = HCI_EV_CMD_COMPLETE; | ||
101 | hdr->plen = sizeof(*evt) + 1; | ||
102 | |||
103 | evt = (struct hci_ev_cmd_complete *)skb_put(skb, sizeof(*evt)); | ||
104 | evt->ncmd = 0x01; | ||
105 | evt->opcode = cpu_to_le16(opcode); | ||
106 | |||
107 | *skb_put(skb, 1) = 0x00; | ||
108 | |||
109 | bt_cb(skb)->pkt_type = HCI_EVENT_PKT; | ||
110 | |||
111 | return hci_recv_frame(hdev, skb); | ||
112 | } | ||
113 | |||
114 | static int intel_secure_send(struct hci_dev *hdev, u8 fragment_type, | ||
115 | u32 plen, const void *param) | ||
116 | { | ||
117 | while (plen > 0) { | ||
118 | struct sk_buff *skb; | ||
119 | u8 cmd_param[253], fragment_len = (plen > 252) ? 252 : plen; | ||
120 | |||
121 | cmd_param[0] = fragment_type; | ||
122 | memcpy(cmd_param + 1, param, fragment_len); | ||
123 | |||
124 | skb = __hci_cmd_sync(hdev, 0xfc09, fragment_len + 1, | ||
125 | cmd_param, HCI_INIT_TIMEOUT); | ||
126 | if (IS_ERR(skb)) | ||
127 | return PTR_ERR(skb); | ||
128 | |||
129 | kfree_skb(skb); | ||
130 | |||
131 | plen -= fragment_len; | ||
132 | param += fragment_len; | ||
133 | } | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static void intel_version_info(struct hci_dev *hdev, | ||
139 | struct intel_version *ver) | ||
140 | { | ||
141 | const char *variant; | ||
142 | |||
143 | switch (ver->fw_variant) { | ||
144 | case 0x06: | ||
145 | variant = "Bootloader"; | ||
146 | break; | ||
147 | case 0x23: | ||
148 | variant = "Firmware"; | ||
149 | break; | ||
150 | default: | ||
151 | return; | ||
152 | } | ||
153 | |||
154 | BT_INFO("%s: %s revision %u.%u build %u week %u %u", hdev->name, | ||
155 | variant, ver->fw_revision >> 4, ver->fw_revision & 0x0f, | ||
156 | ver->fw_build_num, ver->fw_build_ww, 2000 + ver->fw_build_yy); | ||
157 | } | ||
158 | |||
159 | static int intel_setup(struct hci_uart *hu) | ||
160 | { | ||
161 | static const u8 reset_param[] = { 0x00, 0x01, 0x00, 0x01, | ||
162 | 0x00, 0x08, 0x04, 0x00 }; | ||
163 | struct intel_data *intel = hu->priv; | ||
164 | struct hci_dev *hdev = hu->hdev; | ||
165 | struct sk_buff *skb; | ||
166 | struct intel_version *ver; | ||
167 | struct intel_boot_params *params; | ||
168 | const struct firmware *fw; | ||
169 | const u8 *fw_ptr; | ||
170 | char fwname[64]; | ||
171 | u32 frag_len; | ||
172 | ktime_t calltime, delta, rettime; | ||
173 | unsigned long long duration; | ||
174 | int err; | ||
175 | |||
176 | BT_DBG("%s", hdev->name); | ||
177 | |||
178 | calltime = ktime_get(); | ||
179 | |||
180 | set_bit(STATE_BOOTLOADER, &intel->flags); | ||
181 | |||
182 | /* Read the Intel version information to determine if the device | ||
183 | * is in bootloader mode or if it already has operational firmware | ||
184 | * loaded. | ||
185 | */ | ||
186 | skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT); | ||
187 | if (IS_ERR(skb)) { | ||
188 | BT_ERR("%s: Reading Intel version information failed (%ld)", | ||
189 | hdev->name, PTR_ERR(skb)); | ||
190 | return PTR_ERR(skb); | ||
191 | } | ||
192 | |||
193 | if (skb->len != sizeof(*ver)) { | ||
194 | BT_ERR("%s: Intel version event size mismatch", hdev->name); | ||
195 | kfree_skb(skb); | ||
196 | return -EILSEQ; | ||
197 | } | ||
198 | |||
199 | ver = (struct intel_version *)skb->data; | ||
200 | if (ver->status) { | ||
201 | BT_ERR("%s: Intel version command failure (%02x)", | ||
202 | hdev->name, ver->status); | ||
203 | err = -bt_to_errno(ver->status); | ||
204 | kfree_skb(skb); | ||
205 | return err; | ||
206 | } | ||
207 | |||
208 | /* The hardware platform number has a fixed value of 0x37 and | ||
209 | * for now only accept this single value. | ||
210 | */ | ||
211 | if (ver->hw_platform != 0x37) { | ||
212 | BT_ERR("%s: Unsupported Intel hardware platform (%u)", | ||
213 | hdev->name, ver->hw_platform); | ||
214 | kfree_skb(skb); | ||
215 | return -EINVAL; | ||
216 | } | ||
217 | |||
218 | /* At the moment only the hardware variant iBT 3.0 (LnP/SfP) is | ||
219 | * supported by this firmware loading method. This check has been | ||
220 | * put in place to ensure correct forward compatibility options | ||
221 | * when newer hardware variants come along. | ||
222 | */ | ||
223 | if (ver->hw_variant != 0x0b) { | ||
224 | BT_ERR("%s: Unsupported Intel hardware variant (%u)", | ||
225 | hdev->name, ver->hw_variant); | ||
226 | kfree_skb(skb); | ||
227 | return -EINVAL; | ||
228 | } | ||
229 | |||
230 | intel_version_info(hdev, ver); | ||
231 | |||
232 | /* The firmware variant determines if the device is in bootloader | ||
233 | * mode or is running operational firmware. The value 0x06 identifies | ||
234 | * the bootloader and the value 0x23 identifies the operational | ||
235 | * firmware. | ||
236 | * | ||
237 | * When the operational firmware is already present, then only | ||
238 | * the check for valid Bluetooth device address is needed. This | ||
239 | * determines if the device will be added as configured or | ||
240 | * unconfigured controller. | ||
241 | * | ||
242 | * It is not possible to use the Secure Boot Parameters in this | ||
243 | * case since that command is only available in bootloader mode. | ||
244 | */ | ||
245 | if (ver->fw_variant == 0x23) { | ||
246 | kfree_skb(skb); | ||
247 | clear_bit(STATE_BOOTLOADER, &intel->flags); | ||
248 | btintel_check_bdaddr(hdev); | ||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | /* If the device is not in bootloader mode, then the only possible | ||
253 | * choice is to return an error and abort the device initialization. | ||
254 | */ | ||
255 | if (ver->fw_variant != 0x06) { | ||
256 | BT_ERR("%s: Unsupported Intel firmware variant (%u)", | ||
257 | hdev->name, ver->fw_variant); | ||
258 | kfree_skb(skb); | ||
259 | return -ENODEV; | ||
260 | } | ||
261 | |||
262 | kfree_skb(skb); | ||
263 | |||
264 | /* Read the secure boot parameters to identify the operating | ||
265 | * details of the bootloader. | ||
266 | */ | ||
267 | skb = __hci_cmd_sync(hdev, 0xfc0d, 0, NULL, HCI_INIT_TIMEOUT); | ||
268 | if (IS_ERR(skb)) { | ||
269 | BT_ERR("%s: Reading Intel boot parameters failed (%ld)", | ||
270 | hdev->name, PTR_ERR(skb)); | ||
271 | return PTR_ERR(skb); | ||
272 | } | ||
273 | |||
274 | if (skb->len != sizeof(*params)) { | ||
275 | BT_ERR("%s: Intel boot parameters size mismatch", hdev->name); | ||
276 | kfree_skb(skb); | ||
277 | return -EILSEQ; | ||
278 | } | ||
279 | |||
280 | params = (struct intel_boot_params *)skb->data; | ||
281 | if (params->status) { | ||
282 | BT_ERR("%s: Intel boot parameters command failure (%02x)", | ||
283 | hdev->name, params->status); | ||
284 | err = -bt_to_errno(params->status); | ||
285 | kfree_skb(skb); | ||
286 | return err; | ||
287 | } | ||
288 | |||
289 | BT_INFO("%s: Device revision is %u", hdev->name, | ||
290 | le16_to_cpu(params->dev_revid)); | ||
291 | |||
292 | BT_INFO("%s: Secure boot is %s", hdev->name, | ||
293 | params->secure_boot ? "enabled" : "disabled"); | ||
294 | |||
295 | BT_INFO("%s: Minimum firmware build %u week %u %u", hdev->name, | ||
296 | params->min_fw_build_nn, params->min_fw_build_cw, | ||
297 | 2000 + params->min_fw_build_yy); | ||
298 | |||
299 | /* It is required that every single firmware fragment is acknowledged | ||
300 | * with a command complete event. If the boot parameters indicate | ||
301 | * that this bootloader does not send them, then abort the setup. | ||
302 | */ | ||
303 | if (params->limited_cce != 0x00) { | ||
304 | BT_ERR("%s: Unsupported Intel firmware loading method (%u)", | ||
305 | hdev->name, params->limited_cce); | ||
306 | kfree_skb(skb); | ||
307 | return -EINVAL; | ||
308 | } | ||
309 | |||
310 | /* If the OTP has no valid Bluetooth device address, then there will | ||
311 | * also be no valid address for the operational firmware. | ||
312 | */ | ||
313 | if (!bacmp(¶ms->otp_bdaddr, BDADDR_ANY)) { | ||
314 | BT_INFO("%s: No device address configured", hdev->name); | ||
315 | set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); | ||
316 | } | ||
317 | |||
318 | /* With this Intel bootloader only the hardware variant and device | ||
319 | * revision information are used to select the right firmware. | ||
320 | * | ||
321 | * Currently this bootloader support is limited to hardware variant | ||
322 | * iBT 3.0 (LnP/SfP) which is identified by the value 11 (0x0b). | ||
323 | */ | ||
324 | snprintf(fwname, sizeof(fwname), "intel/ibt-11-%u.sfi", | ||
325 | le16_to_cpu(params->dev_revid)); | ||
326 | |||
327 | err = request_firmware(&fw, fwname, &hdev->dev); | ||
328 | if (err < 0) { | ||
329 | BT_ERR("%s: Failed to load Intel firmware file (%d)", | ||
330 | hdev->name, err); | ||
331 | kfree_skb(skb); | ||
332 | return err; | ||
333 | } | ||
334 | |||
335 | BT_INFO("%s: Found device firmware: %s", hdev->name, fwname); | ||
336 | |||
337 | kfree_skb(skb); | ||
338 | |||
339 | if (fw->size < 644) { | ||
340 | BT_ERR("%s: Invalid size of firmware file (%zu)", | ||
341 | hdev->name, fw->size); | ||
342 | err = -EBADF; | ||
343 | goto done; | ||
344 | } | ||
345 | |||
346 | set_bit(STATE_DOWNLOADING, &intel->flags); | ||
347 | |||
348 | /* Start the firmware download transaction with the Init fragment | ||
349 | * represented by the 128 bytes of CSS header. | ||
350 | */ | ||
351 | err = intel_secure_send(hdev, 0x00, 128, fw->data); | ||
352 | if (err < 0) { | ||
353 | BT_ERR("%s: Failed to send firmware header (%d)", | ||
354 | hdev->name, err); | ||
355 | goto done; | ||
356 | } | ||
357 | |||
358 | /* Send the 256 bytes of public key information from the firmware | ||
359 | * as the PKey fragment. | ||
360 | */ | ||
361 | err = intel_secure_send(hdev, 0x03, 256, fw->data + 128); | ||
362 | if (err < 0) { | ||
363 | BT_ERR("%s: Failed to send firmware public key (%d)", | ||
364 | hdev->name, err); | ||
365 | goto done; | ||
366 | } | ||
367 | |||
368 | /* Send the 256 bytes of signature information from the firmware | ||
369 | * as the Sign fragment. | ||
370 | */ | ||
371 | err = intel_secure_send(hdev, 0x02, 256, fw->data + 388); | ||
372 | if (err < 0) { | ||
373 | BT_ERR("%s: Failed to send firmware signature (%d)", | ||
374 | hdev->name, err); | ||
375 | goto done; | ||
376 | } | ||
377 | |||
378 | fw_ptr = fw->data + 644; | ||
379 | frag_len = 0; | ||
380 | |||
381 | while (fw_ptr - fw->data < fw->size) { | ||
382 | struct hci_command_hdr *cmd = (void *)(fw_ptr + frag_len); | ||
383 | |||
384 | frag_len += sizeof(*cmd) + cmd->plen; | ||
385 | |||
386 | BT_DBG("%s: patching %td/%zu", hdev->name, | ||
387 | (fw_ptr - fw->data), fw->size); | ||
388 | |||
389 | /* The parameter length of the secure send command requires | ||
390 | * a 4 byte alignment. It happens so that the firmware file | ||
391 | * contains proper Intel_NOP commands to align the fragments | ||
392 | * as needed. | ||
393 | * | ||
394 | * Send set of commands with 4 byte alignment from the | ||
395 | * firmware data buffer as a single Data fragement. | ||
396 | */ | ||
397 | if (frag_len % 4) | ||
398 | continue; | ||
399 | |||
400 | /* Send each command from the firmware data buffer as | ||
401 | * a single Data fragment. | ||
402 | */ | ||
403 | err = intel_secure_send(hdev, 0x01, frag_len, fw_ptr); | ||
404 | if (err < 0) { | ||
405 | BT_ERR("%s: Failed to send firmware data (%d)", | ||
406 | hdev->name, err); | ||
407 | goto done; | ||
408 | } | ||
409 | |||
410 | fw_ptr += frag_len; | ||
411 | frag_len = 0; | ||
412 | } | ||
413 | |||
414 | set_bit(STATE_FIRMWARE_LOADED, &intel->flags); | ||
415 | |||
416 | BT_INFO("%s: Waiting for firmware download to complete", hdev->name); | ||
417 | |||
418 | /* Before switching the device into operational mode and with that | ||
419 | * booting the loaded firmware, wait for the bootloader notification | ||
420 | * that all fragments have been successfully received. | ||
421 | * | ||
422 | * When the event processing receives the notification, then the | ||
423 | * STATE_DOWNLOADING flag will be cleared. | ||
424 | * | ||
425 | * The firmware loading should not take longer than 5 seconds | ||
426 | * and thus just timeout if that happens and fail the setup | ||
427 | * of this device. | ||
428 | */ | ||
429 | err = wait_on_bit_timeout(&intel->flags, STATE_DOWNLOADING, | ||
430 | TASK_INTERRUPTIBLE, | ||
431 | msecs_to_jiffies(5000)); | ||
432 | if (err == 1) { | ||
433 | BT_ERR("%s: Firmware loading interrupted", hdev->name); | ||
434 | err = -EINTR; | ||
435 | goto done; | ||
436 | } | ||
437 | |||
438 | if (err) { | ||
439 | BT_ERR("%s: Firmware loading timeout", hdev->name); | ||
440 | err = -ETIMEDOUT; | ||
441 | goto done; | ||
442 | } | ||
443 | |||
444 | if (test_bit(STATE_FIRMWARE_FAILED, &intel->flags)) { | ||
445 | BT_ERR("%s: Firmware loading failed", hdev->name); | ||
446 | err = -ENOEXEC; | ||
447 | goto done; | ||
448 | } | ||
449 | |||
450 | rettime = ktime_get(); | ||
451 | delta = ktime_sub(rettime, calltime); | ||
452 | duration = (unsigned long long) ktime_to_ns(delta) >> 10; | ||
453 | |||
454 | BT_INFO("%s: Firmware loaded in %llu usecs", hdev->name, duration); | ||
455 | |||
456 | done: | ||
457 | release_firmware(fw); | ||
458 | |||
459 | if (err < 0) | ||
460 | return err; | ||
461 | |||
462 | calltime = ktime_get(); | ||
463 | |||
464 | set_bit(STATE_BOOTING, &intel->flags); | ||
465 | |||
466 | skb = __hci_cmd_sync(hdev, 0xfc01, sizeof(reset_param), reset_param, | ||
467 | HCI_INIT_TIMEOUT); | ||
468 | if (IS_ERR(skb)) | ||
469 | return PTR_ERR(skb); | ||
470 | |||
471 | kfree_skb(skb); | ||
472 | |||
473 | /* The bootloader will not indicate when the device is ready. This | ||
474 | * is done by the operational firmware sending bootup notification. | ||
475 | * | ||
476 | * Booting into operational firmware should not take longer than | ||
477 | * 1 second. However if that happens, then just fail the setup | ||
478 | * since something went wrong. | ||
479 | */ | ||
480 | BT_INFO("%s: Waiting for device to boot", hdev->name); | ||
481 | |||
482 | err = wait_on_bit_timeout(&intel->flags, STATE_BOOTING, | ||
483 | TASK_INTERRUPTIBLE, | ||
484 | msecs_to_jiffies(1000)); | ||
485 | |||
486 | if (err == 1) { | ||
487 | BT_ERR("%s: Device boot interrupted", hdev->name); | ||
488 | return -EINTR; | ||
489 | } | ||
490 | |||
491 | if (err) { | ||
492 | BT_ERR("%s: Device boot timeout", hdev->name); | ||
493 | return -ETIMEDOUT; | ||
494 | } | ||
495 | |||
496 | rettime = ktime_get(); | ||
497 | delta = ktime_sub(rettime, calltime); | ||
498 | duration = (unsigned long long) ktime_to_ns(delta) >> 10; | ||
499 | |||
500 | BT_INFO("%s: Device booted in %llu usecs", hdev->name, duration); | ||
501 | |||
502 | clear_bit(STATE_BOOTLOADER, &intel->flags); | ||
503 | |||
504 | return 0; | ||
505 | } | ||
506 | |||
507 | static int intel_recv_event(struct hci_dev *hdev, struct sk_buff *skb) | ||
508 | { | ||
509 | struct hci_uart *hu = hci_get_drvdata(hdev); | ||
510 | struct intel_data *intel = hu->priv; | ||
511 | struct hci_event_hdr *hdr; | ||
512 | |||
513 | if (!test_bit(STATE_BOOTLOADER, &intel->flags)) | ||
514 | goto recv; | ||
515 | |||
516 | hdr = (void *)skb->data; | ||
517 | |||
518 | /* When the firmware loading completes the device sends | ||
519 | * out a vendor specific event indicating the result of | ||
520 | * the firmware loading. | ||
521 | */ | ||
522 | if (skb->len == 7 && hdr->evt == 0xff && hdr->plen == 0x05 && | ||
523 | skb->data[2] == 0x06) { | ||
524 | if (skb->data[3] != 0x00) | ||
525 | set_bit(STATE_FIRMWARE_FAILED, &intel->flags); | ||
526 | |||
527 | if (test_and_clear_bit(STATE_DOWNLOADING, &intel->flags) && | ||
528 | test_bit(STATE_FIRMWARE_LOADED, &intel->flags)) { | ||
529 | smp_mb__after_atomic(); | ||
530 | wake_up_bit(&intel->flags, STATE_DOWNLOADING); | ||
531 | } | ||
532 | |||
533 | /* When switching to the operational firmware the device | ||
534 | * sends a vendor specific event indicating that the bootup | ||
535 | * completed. | ||
536 | */ | ||
537 | } else if (skb->len == 9 && hdr->evt == 0xff && hdr->plen == 0x07 && | ||
538 | skb->data[2] == 0x02) { | ||
539 | if (test_and_clear_bit(STATE_BOOTING, &intel->flags)) { | ||
540 | smp_mb__after_atomic(); | ||
541 | wake_up_bit(&intel->flags, STATE_BOOTING); | ||
542 | } | ||
543 | } | ||
544 | recv: | ||
545 | return hci_recv_frame(hdev, skb); | ||
546 | } | ||
547 | |||
548 | static const struct h4_recv_pkt intel_recv_pkts[] = { | ||
549 | { H4_RECV_ACL, .recv = hci_recv_frame }, | ||
550 | { H4_RECV_SCO, .recv = hci_recv_frame }, | ||
551 | { H4_RECV_EVENT, .recv = intel_recv_event }, | ||
552 | }; | ||
553 | |||
554 | static int intel_recv(struct hci_uart *hu, const void *data, int count) | ||
555 | { | ||
556 | struct intel_data *intel = hu->priv; | ||
557 | |||
558 | if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) | ||
559 | return -EUNATCH; | ||
560 | |||
561 | intel->rx_skb = h4_recv_buf(hu->hdev, intel->rx_skb, data, count, | ||
562 | intel_recv_pkts, | ||
563 | ARRAY_SIZE(intel_recv_pkts)); | ||
564 | if (IS_ERR(intel->rx_skb)) { | ||
565 | int err = PTR_ERR(intel->rx_skb); | ||
566 | BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err); | ||
567 | intel->rx_skb = NULL; | ||
568 | return err; | ||
569 | } | ||
570 | |||
571 | return count; | ||
572 | } | ||
573 | |||
574 | static int intel_enqueue(struct hci_uart *hu, struct sk_buff *skb) | ||
575 | { | ||
576 | struct intel_data *intel = hu->priv; | ||
577 | |||
578 | BT_DBG("hu %p skb %p", hu, skb); | ||
579 | |||
580 | skb_queue_tail(&intel->txq, skb); | ||
581 | |||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | static struct sk_buff *intel_dequeue(struct hci_uart *hu) | ||
586 | { | ||
587 | struct intel_data *intel = hu->priv; | ||
588 | struct sk_buff *skb; | ||
589 | |||
590 | skb = skb_dequeue(&intel->txq); | ||
591 | if (!skb) | ||
592 | return skb; | ||
593 | |||
594 | if (test_bit(STATE_BOOTLOADER, &intel->flags) && | ||
595 | (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT)) { | ||
596 | struct hci_command_hdr *cmd = (void *)skb->data; | ||
597 | __u16 opcode = le16_to_cpu(cmd->opcode); | ||
598 | |||
599 | /* When the 0xfc01 command is issued to boot into | ||
600 | * the operational firmware, it will actually not | ||
601 | * send a command complete event. To keep the flow | ||
602 | * control working inject that event here. | ||
603 | */ | ||
604 | if (opcode == 0xfc01) | ||
605 | inject_cmd_complete(hu->hdev, opcode); | ||
606 | } | ||
607 | |||
608 | /* Prepend skb with frame type */ | ||
609 | memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); | ||
610 | |||
611 | return skb; | ||
612 | } | ||
613 | |||
614 | static const struct hci_uart_proto intel_proto = { | ||
615 | .id = HCI_UART_INTEL, | ||
616 | .name = "Intel", | ||
617 | .init_speed = 115200, | ||
618 | .open = intel_open, | ||
619 | .close = intel_close, | ||
620 | .flush = intel_flush, | ||
621 | .setup = intel_setup, | ||
622 | .recv = intel_recv, | ||
623 | .enqueue = intel_enqueue, | ||
624 | .dequeue = intel_dequeue, | ||
625 | }; | ||
626 | |||
627 | int __init intel_init(void) | ||
628 | { | ||
629 | return hci_uart_register_proto(&intel_proto); | ||
630 | } | ||
631 | |||
632 | int __exit intel_deinit(void) | ||
633 | { | ||
634 | return hci_uart_unregister_proto(&intel_proto); | ||
635 | } | ||
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 177dd69fdd95..051f8213697d 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -804,6 +804,9 @@ static int __init hci_uart_init(void) | |||
804 | #ifdef CONFIG_BT_HCIUART_3WIRE | 804 | #ifdef CONFIG_BT_HCIUART_3WIRE |
805 | h5_init(); | 805 | h5_init(); |
806 | #endif | 806 | #endif |
807 | #ifdef CONFIG_BT_HCIUART_INTEL | ||
808 | intel_init(); | ||
809 | #endif | ||
807 | #ifdef CONFIG_BT_HCIUART_BCM | 810 | #ifdef CONFIG_BT_HCIUART_BCM |
808 | bcm_init(); | 811 | bcm_init(); |
809 | #endif | 812 | #endif |
@@ -830,6 +833,9 @@ static void __exit hci_uart_exit(void) | |||
830 | #ifdef CONFIG_BT_HCIUART_3WIRE | 833 | #ifdef CONFIG_BT_HCIUART_3WIRE |
831 | h5_deinit(); | 834 | h5_deinit(); |
832 | #endif | 835 | #endif |
836 | #ifdef CONFIG_BT_HCIUART_INTEL | ||
837 | intel_deinit(); | ||
838 | #endif | ||
833 | #ifdef CONFIG_BT_HCIUART_BCM | 839 | #ifdef CONFIG_BT_HCIUART_BCM |
834 | bcm_deinit(); | 840 | bcm_deinit(); |
835 | #endif | 841 | #endif |
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h index ce9c670956f5..496587a73a9d 100644 --- a/drivers/bluetooth/hci_uart.h +++ b/drivers/bluetooth/hci_uart.h | |||
@@ -167,6 +167,11 @@ int h5_init(void); | |||
167 | int h5_deinit(void); | 167 | int h5_deinit(void); |
168 | #endif | 168 | #endif |
169 | 169 | ||
170 | #ifdef CONFIG_BT_HCIUART_INTEL | ||
171 | int intel_init(void); | ||
172 | int intel_deinit(void); | ||
173 | #endif | ||
174 | |||
170 | #ifdef CONFIG_BT_HCIUART_BCM | 175 | #ifdef CONFIG_BT_HCIUART_BCM |
171 | int bcm_init(void); | 176 | int bcm_init(void); |
172 | int bcm_deinit(void); | 177 | int bcm_deinit(void); |