diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2013-03-05 13:37:43 -0500 |
---|---|---|
committer | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2013-03-08 08:40:25 -0500 |
commit | 2177bab507d2715ae3b745f47056eacd38b79fa7 (patch) | |
tree | c247ec5fb757caadc79999c36d71564aa507b8ad /net/bluetooth | |
parent | 53cce22dc795e73fb48205e3f584f63f4c71c90c (diff) |
Bluetooth: Split HCI init sequence into three stages
Having conditional command sending during a request has always been
problematic and caused hacks like the hdev->init_last_cmd variable. This
patch removes these conditionals and instead splits the init sequence
into three stages, each with its own __hci_req_sync() call.
This also paves the way to the upcoming asynchronous request support
swhich will also benefit by having a simpler implementation if it
doesn't need to cater for requests that change on the fly.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_core.c | 274 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 255 |
2 files changed, 274 insertions, 255 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 9369e010c90e..6ab38fecf1fe 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -193,6 +193,9 @@ static void bredr_init(struct hci_dev *hdev) | |||
193 | 193 | ||
194 | /* Read Local Version */ | 194 | /* Read Local Version */ |
195 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); | 195 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); |
196 | |||
197 | /* Read BD Address */ | ||
198 | hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL); | ||
196 | } | 199 | } |
197 | 200 | ||
198 | static void amp_init(struct hci_dev *hdev) | 201 | static void amp_init(struct hci_dev *hdev) |
@@ -209,7 +212,7 @@ static void amp_init(struct hci_dev *hdev) | |||
209 | hci_send_cmd(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); | 212 | hci_send_cmd(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL); |
210 | } | 213 | } |
211 | 214 | ||
212 | static void hci_init_req(struct hci_dev *hdev, unsigned long opt) | 215 | static void hci_init1_req(struct hci_dev *hdev, unsigned long opt) |
213 | { | 216 | { |
214 | struct sk_buff *skb; | 217 | struct sk_buff *skb; |
215 | 218 | ||
@@ -246,6 +249,273 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) | |||
246 | } | 249 | } |
247 | } | 250 | } |
248 | 251 | ||
252 | static void bredr_setup(struct hci_dev *hdev) | ||
253 | { | ||
254 | struct hci_cp_delete_stored_link_key cp; | ||
255 | __le16 param; | ||
256 | __u8 flt_type; | ||
257 | |||
258 | /* Read Buffer Size (ACL mtu, max pkt, etc.) */ | ||
259 | hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL); | ||
260 | |||
261 | /* Read Class of Device */ | ||
262 | hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); | ||
263 | |||
264 | /* Read Local Name */ | ||
265 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL); | ||
266 | |||
267 | /* Read Voice Setting */ | ||
268 | hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL); | ||
269 | |||
270 | /* Clear Event Filters */ | ||
271 | flt_type = HCI_FLT_CLEAR_ALL; | ||
272 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); | ||
273 | |||
274 | /* Connection accept timeout ~20 secs */ | ||
275 | param = __constant_cpu_to_le16(0x7d00); | ||
276 | hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); | ||
277 | |||
278 | bacpy(&cp.bdaddr, BDADDR_ANY); | ||
279 | cp.delete_all = 0x01; | ||
280 | hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); | ||
281 | } | ||
282 | |||
283 | static void le_setup(struct hci_dev *hdev) | ||
284 | { | ||
285 | /* Read LE Buffer Size */ | ||
286 | hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); | ||
287 | |||
288 | /* Read LE Local Supported Features */ | ||
289 | hci_send_cmd(hdev, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); | ||
290 | |||
291 | /* Read LE Advertising Channel TX Power */ | ||
292 | hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); | ||
293 | |||
294 | /* Read LE White List Size */ | ||
295 | hci_send_cmd(hdev, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); | ||
296 | |||
297 | /* Read LE Supported States */ | ||
298 | hci_send_cmd(hdev, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); | ||
299 | } | ||
300 | |||
301 | static u8 hci_get_inquiry_mode(struct hci_dev *hdev) | ||
302 | { | ||
303 | if (lmp_ext_inq_capable(hdev)) | ||
304 | return 0x02; | ||
305 | |||
306 | if (lmp_inq_rssi_capable(hdev)) | ||
307 | return 0x01; | ||
308 | |||
309 | if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && | ||
310 | hdev->lmp_subver == 0x0757) | ||
311 | return 0x01; | ||
312 | |||
313 | if (hdev->manufacturer == 15) { | ||
314 | if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) | ||
315 | return 0x01; | ||
316 | if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) | ||
317 | return 0x01; | ||
318 | if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) | ||
319 | return 0x01; | ||
320 | } | ||
321 | |||
322 | if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && | ||
323 | hdev->lmp_subver == 0x1805) | ||
324 | return 0x01; | ||
325 | |||
326 | return 0x00; | ||
327 | } | ||
328 | |||
329 | static void hci_setup_inquiry_mode(struct hci_dev *hdev) | ||
330 | { | ||
331 | u8 mode; | ||
332 | |||
333 | mode = hci_get_inquiry_mode(hdev); | ||
334 | |||
335 | hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); | ||
336 | } | ||
337 | |||
338 | static void hci_setup_event_mask(struct hci_dev *hdev) | ||
339 | { | ||
340 | /* The second byte is 0xff instead of 0x9f (two reserved bits | ||
341 | * disabled) since a Broadcom 1.2 dongle doesn't respond to the | ||
342 | * command otherwise. | ||
343 | */ | ||
344 | u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; | ||
345 | |||
346 | /* CSR 1.1 dongles does not accept any bitfield so don't try to set | ||
347 | * any event mask for pre 1.2 devices. | ||
348 | */ | ||
349 | if (hdev->hci_ver < BLUETOOTH_VER_1_2) | ||
350 | return; | ||
351 | |||
352 | if (lmp_bredr_capable(hdev)) { | ||
353 | events[4] |= 0x01; /* Flow Specification Complete */ | ||
354 | events[4] |= 0x02; /* Inquiry Result with RSSI */ | ||
355 | events[4] |= 0x04; /* Read Remote Extended Features Complete */ | ||
356 | events[5] |= 0x08; /* Synchronous Connection Complete */ | ||
357 | events[5] |= 0x10; /* Synchronous Connection Changed */ | ||
358 | } | ||
359 | |||
360 | if (lmp_inq_rssi_capable(hdev)) | ||
361 | events[4] |= 0x02; /* Inquiry Result with RSSI */ | ||
362 | |||
363 | if (lmp_sniffsubr_capable(hdev)) | ||
364 | events[5] |= 0x20; /* Sniff Subrating */ | ||
365 | |||
366 | if (lmp_pause_enc_capable(hdev)) | ||
367 | events[5] |= 0x80; /* Encryption Key Refresh Complete */ | ||
368 | |||
369 | if (lmp_ext_inq_capable(hdev)) | ||
370 | events[5] |= 0x40; /* Extended Inquiry Result */ | ||
371 | |||
372 | if (lmp_no_flush_capable(hdev)) | ||
373 | events[7] |= 0x01; /* Enhanced Flush Complete */ | ||
374 | |||
375 | if (lmp_lsto_capable(hdev)) | ||
376 | events[6] |= 0x80; /* Link Supervision Timeout Changed */ | ||
377 | |||
378 | if (lmp_ssp_capable(hdev)) { | ||
379 | events[6] |= 0x01; /* IO Capability Request */ | ||
380 | events[6] |= 0x02; /* IO Capability Response */ | ||
381 | events[6] |= 0x04; /* User Confirmation Request */ | ||
382 | events[6] |= 0x08; /* User Passkey Request */ | ||
383 | events[6] |= 0x10; /* Remote OOB Data Request */ | ||
384 | events[6] |= 0x20; /* Simple Pairing Complete */ | ||
385 | events[7] |= 0x04; /* User Passkey Notification */ | ||
386 | events[7] |= 0x08; /* Keypress Notification */ | ||
387 | events[7] |= 0x10; /* Remote Host Supported | ||
388 | * Features Notification | ||
389 | */ | ||
390 | } | ||
391 | |||
392 | if (lmp_le_capable(hdev)) | ||
393 | events[7] |= 0x20; /* LE Meta-Event */ | ||
394 | |||
395 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); | ||
396 | |||
397 | if (lmp_le_capable(hdev)) { | ||
398 | memset(events, 0, sizeof(events)); | ||
399 | events[0] = 0x1f; | ||
400 | hci_send_cmd(hdev, HCI_OP_LE_SET_EVENT_MASK, | ||
401 | sizeof(events), events); | ||
402 | } | ||
403 | } | ||
404 | |||
405 | static void hci_init2_req(struct hci_dev *hdev, unsigned long opt) | ||
406 | { | ||
407 | if (lmp_bredr_capable(hdev)) | ||
408 | bredr_setup(hdev); | ||
409 | |||
410 | if (lmp_le_capable(hdev)) | ||
411 | le_setup(hdev); | ||
412 | |||
413 | hci_setup_event_mask(hdev); | ||
414 | |||
415 | if (hdev->hci_ver > BLUETOOTH_VER_1_1) | ||
416 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); | ||
417 | |||
418 | if (lmp_ssp_capable(hdev)) { | ||
419 | if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { | ||
420 | u8 mode = 0x01; | ||
421 | hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, | ||
422 | sizeof(mode), &mode); | ||
423 | } else { | ||
424 | struct hci_cp_write_eir cp; | ||
425 | |||
426 | memset(hdev->eir, 0, sizeof(hdev->eir)); | ||
427 | memset(&cp, 0, sizeof(cp)); | ||
428 | |||
429 | hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp); | ||
430 | } | ||
431 | } | ||
432 | |||
433 | if (lmp_inq_rssi_capable(hdev)) | ||
434 | hci_setup_inquiry_mode(hdev); | ||
435 | |||
436 | if (lmp_inq_tx_pwr_capable(hdev)) | ||
437 | hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); | ||
438 | |||
439 | if (lmp_ext_feat_capable(hdev)) { | ||
440 | struct hci_cp_read_local_ext_features cp; | ||
441 | |||
442 | cp.page = 0x01; | ||
443 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), | ||
444 | &cp); | ||
445 | } | ||
446 | |||
447 | if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { | ||
448 | u8 enable = 1; | ||
449 | hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), | ||
450 | &enable); | ||
451 | } | ||
452 | } | ||
453 | |||
454 | static void hci_setup_link_policy(struct hci_dev *hdev) | ||
455 | { | ||
456 | struct hci_cp_write_def_link_policy cp; | ||
457 | u16 link_policy = 0; | ||
458 | |||
459 | if (lmp_rswitch_capable(hdev)) | ||
460 | link_policy |= HCI_LP_RSWITCH; | ||
461 | if (lmp_hold_capable(hdev)) | ||
462 | link_policy |= HCI_LP_HOLD; | ||
463 | if (lmp_sniff_capable(hdev)) | ||
464 | link_policy |= HCI_LP_SNIFF; | ||
465 | if (lmp_park_capable(hdev)) | ||
466 | link_policy |= HCI_LP_PARK; | ||
467 | |||
468 | cp.policy = cpu_to_le16(link_policy); | ||
469 | hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); | ||
470 | } | ||
471 | |||
472 | static void hci_set_le_support(struct hci_dev *hdev) | ||
473 | { | ||
474 | struct hci_cp_write_le_host_supported cp; | ||
475 | |||
476 | memset(&cp, 0, sizeof(cp)); | ||
477 | |||
478 | if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { | ||
479 | cp.le = 0x01; | ||
480 | cp.simul = lmp_le_br_capable(hdev); | ||
481 | } | ||
482 | |||
483 | if (cp.le != lmp_host_le_capable(hdev)) | ||
484 | hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), | ||
485 | &cp); | ||
486 | } | ||
487 | |||
488 | static void hci_init3_req(struct hci_dev *hdev, unsigned long opt) | ||
489 | { | ||
490 | if (hdev->commands[5] & 0x10) | ||
491 | hci_setup_link_policy(hdev); | ||
492 | |||
493 | if (lmp_le_capable(hdev)) | ||
494 | hci_set_le_support(hdev); | ||
495 | } | ||
496 | |||
497 | static int __hci_init(struct hci_dev *hdev) | ||
498 | { | ||
499 | int err; | ||
500 | |||
501 | err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT); | ||
502 | if (err < 0) | ||
503 | return err; | ||
504 | |||
505 | /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode | ||
506 | * BR/EDR/LE type controllers. AMP controllers only need the | ||
507 | * first stage init. | ||
508 | */ | ||
509 | if (hdev->dev_type != HCI_BREDR) | ||
510 | return 0; | ||
511 | |||
512 | err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT); | ||
513 | if (err < 0) | ||
514 | return err; | ||
515 | |||
516 | return __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); | ||
517 | } | ||
518 | |||
249 | static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) | 519 | static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) |
250 | { | 520 | { |
251 | __u8 scan = opt; | 521 | __u8 scan = opt; |
@@ -746,7 +1016,7 @@ int hci_dev_open(__u16 dev) | |||
746 | set_bit(HCI_INIT, &hdev->flags); | 1016 | set_bit(HCI_INIT, &hdev->flags); |
747 | hdev->init_last_cmd = 0; | 1017 | hdev->init_last_cmd = 0; |
748 | 1018 | ||
749 | ret = __hci_req_sync(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT); | 1019 | ret = __hci_init(hdev); |
750 | 1020 | ||
751 | clear_bit(HCI_INIT, &hdev->flags); | 1021 | clear_bit(HCI_INIT, &hdev->flags); |
752 | } | 1022 | } |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 5892e54835a1..14e872aa0d2c 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -472,211 +472,6 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) | |||
472 | } | 472 | } |
473 | } | 473 | } |
474 | 474 | ||
475 | static u8 hci_get_inquiry_mode(struct hci_dev *hdev) | ||
476 | { | ||
477 | if (lmp_ext_inq_capable(hdev)) | ||
478 | return 2; | ||
479 | |||
480 | if (lmp_inq_rssi_capable(hdev)) | ||
481 | return 1; | ||
482 | |||
483 | if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && | ||
484 | hdev->lmp_subver == 0x0757) | ||
485 | return 1; | ||
486 | |||
487 | if (hdev->manufacturer == 15) { | ||
488 | if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) | ||
489 | return 1; | ||
490 | if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) | ||
491 | return 1; | ||
492 | if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) | ||
493 | return 1; | ||
494 | } | ||
495 | |||
496 | if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && | ||
497 | hdev->lmp_subver == 0x1805) | ||
498 | return 1; | ||
499 | |||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | static void hci_setup_inquiry_mode(struct hci_dev *hdev) | ||
504 | { | ||
505 | u8 mode; | ||
506 | |||
507 | mode = hci_get_inquiry_mode(hdev); | ||
508 | |||
509 | hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); | ||
510 | } | ||
511 | |||
512 | static void hci_setup_event_mask(struct hci_dev *hdev) | ||
513 | { | ||
514 | /* The second byte is 0xff instead of 0x9f (two reserved bits | ||
515 | * disabled) since a Broadcom 1.2 dongle doesn't respond to the | ||
516 | * command otherwise */ | ||
517 | u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; | ||
518 | |||
519 | /* CSR 1.1 dongles does not accept any bitfield so don't try to set | ||
520 | * any event mask for pre 1.2 devices */ | ||
521 | if (hdev->hci_ver < BLUETOOTH_VER_1_2) | ||
522 | return; | ||
523 | |||
524 | if (lmp_bredr_capable(hdev)) { | ||
525 | events[4] |= 0x01; /* Flow Specification Complete */ | ||
526 | events[4] |= 0x02; /* Inquiry Result with RSSI */ | ||
527 | events[4] |= 0x04; /* Read Remote Extended Features Complete */ | ||
528 | events[5] |= 0x08; /* Synchronous Connection Complete */ | ||
529 | events[5] |= 0x10; /* Synchronous Connection Changed */ | ||
530 | } | ||
531 | |||
532 | if (lmp_inq_rssi_capable(hdev)) | ||
533 | events[4] |= 0x02; /* Inquiry Result with RSSI */ | ||
534 | |||
535 | if (lmp_sniffsubr_capable(hdev)) | ||
536 | events[5] |= 0x20; /* Sniff Subrating */ | ||
537 | |||
538 | if (lmp_pause_enc_capable(hdev)) | ||
539 | events[5] |= 0x80; /* Encryption Key Refresh Complete */ | ||
540 | |||
541 | if (lmp_ext_inq_capable(hdev)) | ||
542 | events[5] |= 0x40; /* Extended Inquiry Result */ | ||
543 | |||
544 | if (lmp_no_flush_capable(hdev)) | ||
545 | events[7] |= 0x01; /* Enhanced Flush Complete */ | ||
546 | |||
547 | if (lmp_lsto_capable(hdev)) | ||
548 | events[6] |= 0x80; /* Link Supervision Timeout Changed */ | ||
549 | |||
550 | if (lmp_ssp_capable(hdev)) { | ||
551 | events[6] |= 0x01; /* IO Capability Request */ | ||
552 | events[6] |= 0x02; /* IO Capability Response */ | ||
553 | events[6] |= 0x04; /* User Confirmation Request */ | ||
554 | events[6] |= 0x08; /* User Passkey Request */ | ||
555 | events[6] |= 0x10; /* Remote OOB Data Request */ | ||
556 | events[6] |= 0x20; /* Simple Pairing Complete */ | ||
557 | events[7] |= 0x04; /* User Passkey Notification */ | ||
558 | events[7] |= 0x08; /* Keypress Notification */ | ||
559 | events[7] |= 0x10; /* Remote Host Supported | ||
560 | * Features Notification */ | ||
561 | } | ||
562 | |||
563 | if (lmp_le_capable(hdev)) | ||
564 | events[7] |= 0x20; /* LE Meta-Event */ | ||
565 | |||
566 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); | ||
567 | |||
568 | if (lmp_le_capable(hdev)) { | ||
569 | memset(events, 0, sizeof(events)); | ||
570 | events[0] = 0x1f; | ||
571 | hci_send_cmd(hdev, HCI_OP_LE_SET_EVENT_MASK, | ||
572 | sizeof(events), events); | ||
573 | } | ||
574 | } | ||
575 | |||
576 | static void bredr_setup(struct hci_dev *hdev) | ||
577 | { | ||
578 | struct hci_cp_delete_stored_link_key cp; | ||
579 | __le16 param; | ||
580 | __u8 flt_type; | ||
581 | |||
582 | /* Read Buffer Size (ACL mtu, max pkt, etc.) */ | ||
583 | hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL); | ||
584 | |||
585 | /* Read Class of Device */ | ||
586 | hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); | ||
587 | |||
588 | /* Read Local Name */ | ||
589 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL); | ||
590 | |||
591 | /* Read Voice Setting */ | ||
592 | hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL); | ||
593 | |||
594 | /* Clear Event Filters */ | ||
595 | flt_type = HCI_FLT_CLEAR_ALL; | ||
596 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); | ||
597 | |||
598 | /* Connection accept timeout ~20 secs */ | ||
599 | param = __constant_cpu_to_le16(0x7d00); | ||
600 | hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); | ||
601 | |||
602 | bacpy(&cp.bdaddr, BDADDR_ANY); | ||
603 | cp.delete_all = 1; | ||
604 | hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); | ||
605 | } | ||
606 | |||
607 | static void le_setup(struct hci_dev *hdev) | ||
608 | { | ||
609 | /* Read LE Buffer Size */ | ||
610 | hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); | ||
611 | |||
612 | /* Read LE Local Supported Features */ | ||
613 | hci_send_cmd(hdev, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL); | ||
614 | |||
615 | /* Read LE Advertising Channel TX Power */ | ||
616 | hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); | ||
617 | |||
618 | /* Read LE White List Size */ | ||
619 | hci_send_cmd(hdev, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL); | ||
620 | |||
621 | /* Read LE Supported States */ | ||
622 | hci_send_cmd(hdev, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); | ||
623 | } | ||
624 | |||
625 | static void hci_setup(struct hci_dev *hdev) | ||
626 | { | ||
627 | if (hdev->dev_type != HCI_BREDR) | ||
628 | return; | ||
629 | |||
630 | /* Read BD Address */ | ||
631 | hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL); | ||
632 | |||
633 | if (lmp_bredr_capable(hdev)) | ||
634 | bredr_setup(hdev); | ||
635 | |||
636 | if (lmp_le_capable(hdev)) | ||
637 | le_setup(hdev); | ||
638 | |||
639 | hci_setup_event_mask(hdev); | ||
640 | |||
641 | if (hdev->hci_ver > BLUETOOTH_VER_1_1) | ||
642 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); | ||
643 | |||
644 | if (lmp_ssp_capable(hdev)) { | ||
645 | if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { | ||
646 | u8 mode = 0x01; | ||
647 | hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, | ||
648 | sizeof(mode), &mode); | ||
649 | } else { | ||
650 | struct hci_cp_write_eir cp; | ||
651 | |||
652 | memset(hdev->eir, 0, sizeof(hdev->eir)); | ||
653 | memset(&cp, 0, sizeof(cp)); | ||
654 | |||
655 | hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp); | ||
656 | } | ||
657 | } | ||
658 | |||
659 | if (lmp_inq_rssi_capable(hdev)) | ||
660 | hci_setup_inquiry_mode(hdev); | ||
661 | |||
662 | if (lmp_inq_tx_pwr_capable(hdev)) | ||
663 | hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); | ||
664 | |||
665 | if (lmp_ext_feat_capable(hdev)) { | ||
666 | struct hci_cp_read_local_ext_features cp; | ||
667 | |||
668 | cp.page = 0x01; | ||
669 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), | ||
670 | &cp); | ||
671 | } | ||
672 | |||
673 | if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { | ||
674 | u8 enable = 1; | ||
675 | hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), | ||
676 | &enable); | ||
677 | } | ||
678 | } | ||
679 | |||
680 | static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) | 475 | static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) |
681 | { | 476 | { |
682 | struct hci_rp_read_local_version *rp = (void *) skb->data; | 477 | struct hci_rp_read_local_version *rp = (void *) skb->data; |
@@ -695,31 +490,10 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) | |||
695 | BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name, | 490 | BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name, |
696 | hdev->manufacturer, hdev->hci_ver, hdev->hci_rev); | 491 | hdev->manufacturer, hdev->hci_ver, hdev->hci_rev); |
697 | 492 | ||
698 | if (test_bit(HCI_INIT, &hdev->flags)) | ||
699 | hci_setup(hdev); | ||
700 | |||
701 | done: | 493 | done: |
702 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status); | 494 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status); |
703 | } | 495 | } |
704 | 496 | ||
705 | static void hci_setup_link_policy(struct hci_dev *hdev) | ||
706 | { | ||
707 | struct hci_cp_write_def_link_policy cp; | ||
708 | u16 link_policy = 0; | ||
709 | |||
710 | if (lmp_rswitch_capable(hdev)) | ||
711 | link_policy |= HCI_LP_RSWITCH; | ||
712 | if (lmp_hold_capable(hdev)) | ||
713 | link_policy |= HCI_LP_HOLD; | ||
714 | if (lmp_sniff_capable(hdev)) | ||
715 | link_policy |= HCI_LP_SNIFF; | ||
716 | if (lmp_park_capable(hdev)) | ||
717 | link_policy |= HCI_LP_PARK; | ||
718 | |||
719 | cp.policy = cpu_to_le16(link_policy); | ||
720 | hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); | ||
721 | } | ||
722 | |||
723 | static void hci_cc_read_local_commands(struct hci_dev *hdev, | 497 | static void hci_cc_read_local_commands(struct hci_dev *hdev, |
724 | struct sk_buff *skb) | 498 | struct sk_buff *skb) |
725 | { | 499 | { |
@@ -727,15 +501,9 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev, | |||
727 | 501 | ||
728 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); | 502 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
729 | 503 | ||
730 | if (rp->status) | 504 | if (!rp->status) |
731 | goto done; | 505 | memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); |
732 | |||
733 | memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); | ||
734 | |||
735 | if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10)) | ||
736 | hci_setup_link_policy(hdev); | ||
737 | 506 | ||
738 | done: | ||
739 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status); | 507 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status); |
740 | } | 508 | } |
741 | 509 | ||
@@ -795,22 +563,6 @@ static void hci_cc_read_local_features(struct hci_dev *hdev, | |||
795 | hdev->features[6], hdev->features[7]); | 563 | hdev->features[6], hdev->features[7]); |
796 | } | 564 | } |
797 | 565 | ||
798 | static void hci_set_le_support(struct hci_dev *hdev) | ||
799 | { | ||
800 | struct hci_cp_write_le_host_supported cp; | ||
801 | |||
802 | memset(&cp, 0, sizeof(cp)); | ||
803 | |||
804 | if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { | ||
805 | cp.le = 1; | ||
806 | cp.simul = lmp_le_br_capable(hdev); | ||
807 | } | ||
808 | |||
809 | if (cp.le != lmp_host_le_capable(hdev)) | ||
810 | hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), | ||
811 | &cp); | ||
812 | } | ||
813 | |||
814 | static void hci_cc_read_local_ext_features(struct hci_dev *hdev, | 566 | static void hci_cc_read_local_ext_features(struct hci_dev *hdev, |
815 | struct sk_buff *skb) | 567 | struct sk_buff *skb) |
816 | { | 568 | { |
@@ -830,9 +582,6 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev, | |||
830 | break; | 582 | break; |
831 | } | 583 | } |
832 | 584 | ||
833 | if (test_bit(HCI_INIT, &hdev->flags) && lmp_le_capable(hdev)) | ||
834 | hci_set_le_support(hdev); | ||
835 | |||
836 | done: | 585 | done: |
837 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status); | 586 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status); |
838 | } | 587 | } |