aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorJakub Pawlowski <jpawlowski@google.com>2015-03-17 09:04:14 -0700
committerJohan Hedberg <johan.hedberg@intel.com>2015-03-17 18:31:00 +0200
commit07d2334ae747772fc4426077340aa3efe499f50b (patch)
treea6d218d89270d7713d418ce44034691f101142b5 /net/bluetooth/mgmt.c
parentBluetooth: Refactor BR/EDR inquiry and LE scan triggering. (diff)
downloadlinux-dev-07d2334ae747772fc4426077340aa3efe499f50b.tar.xz
linux-dev-07d2334ae747772fc4426077340aa3efe499f50b.zip
Bluetooth: Add simultaneous dual mode scan
When doing scan through mgmt api, some controllers can do both le and classic scan at same time. They can be distinguished by HCI_QUIRK_SIMULTANEOUS_DISCOVERY set. This patch enables them to use this feature when doing dual mode scan. Instead of doing le, then classic scan, both scans are run at once. Signed-off-by: Jakub Pawlowski <jpawlowski@google.com> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to '')
-rw-r--r--net/bluetooth/mgmt.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 5a4b9d5a224f..7bcdf61afe11 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1408,9 +1408,10 @@ static bool hci_stop_discovery(struct hci_request *req)
switch (hdev->discovery.state) {
case DISCOVERY_FINDING:
- if (test_bit(HCI_INQUIRY, &hdev->flags)) {
+ if (test_bit(HCI_INQUIRY, &hdev->flags))
hci_req_add(req, HCI_OP_INQUIRY_CANCEL, 0, NULL);
- } else {
+
+ if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
cancel_delayed_work(&hdev->le_scan_disable);
hci_req_add_le_scan_disable(req);
}
@@ -4019,6 +4020,22 @@ static bool trigger_discovery(struct hci_request *req, u8 *status)
break;
case DISCOV_TYPE_INTERLEAVED:
+ if (test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY,
+ &hdev->quirks)) {
+ /* During simultaneous discovery, we double LE scan
+ * interval. We must leave some time for the controller
+ * to do BR/EDR inquiry.
+ */
+ if (!trigger_le_scan(req, DISCOV_LE_SCAN_INT * 2,
+ status))
+ return false;
+
+ if (!trigger_bredr_inquiry(req, status))
+ return false;
+
+ return true;
+ }
+
if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
*status = MGMT_STATUS_NOT_SUPPORTED;
return false;
@@ -4072,7 +4089,18 @@ static void start_discovery_complete(struct hci_dev *hdev, u8 status,
timeout = msecs_to_jiffies(DISCOV_LE_TIMEOUT);
break;
case DISCOV_TYPE_INTERLEAVED:
- timeout = msecs_to_jiffies(hdev->discov_interleaved_timeout);
+ /* When running simultaneous discovery, the LE scanning time
+ * should occupy the whole discovery time sine BR/EDR inquiry
+ * and LE scanning are scheduled by the controller.
+ *
+ * For interleaving discovery in comparison, BR/EDR inquiry
+ * and LE scanning are done sequentially with separate
+ * timeouts.
+ */
+ if (test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
+ timeout = msecs_to_jiffies(DISCOV_LE_TIMEOUT);
+ else
+ timeout = msecs_to_jiffies(hdev->discov_interleaved_timeout);
break;
case DISCOV_TYPE_BREDR:
timeout = 0;