Merge tag 'docs-5.13-2' of git://git.lwn.net/linux
[linux-2.6-microblaze.git] / net / bluetooth / hci_request.c
index 805ce54..fa9125b 100644 (file)
@@ -851,6 +851,10 @@ static u8 update_white_list(struct hci_request *req)
         */
        bool allow_rpa = hdev->suspended;
 
+       if (use_ll_privacy(hdev) &&
+           hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY))
+               allow_rpa = true;
+
        /* Go through the current white list programmed into the
         * controller one by one and check if that address is still
         * in the list of pending connections or list of devices to
@@ -1135,14 +1139,14 @@ static void hci_req_clear_event_filter(struct hci_request *req)
 {
        struct hci_cp_set_event_filter f;
 
-       memset(&f, 0, sizeof(f));
-       f.flt_type = HCI_FLT_CLEAR_ALL;
-       hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &f);
+       if (!hci_dev_test_flag(req->hdev, HCI_BREDR_ENABLED))
+               return;
 
-       /* Update page scan state (since we may have modified it when setting
-        * the event filter).
-        */
-       __hci_req_update_scan(req);
+       if (hci_dev_test_flag(req->hdev, HCI_EVENT_FILTER_CONFIGURED)) {
+               memset(&f, 0, sizeof(f));
+               f.flt_type = HCI_FLT_CLEAR_ALL;
+               hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &f);
+       }
 }
 
 static void hci_req_set_event_filter(struct hci_request *req)
@@ -1151,6 +1155,10 @@ static void hci_req_set_event_filter(struct hci_request *req)
        struct hci_cp_set_event_filter f;
        struct hci_dev *hdev = req->hdev;
        u8 scan = SCAN_DISABLED;
+       bool scanning = test_bit(HCI_PSCAN, &hdev->flags);
+
+       if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
+               return;
 
        /* Always clear event filter when starting */
        hci_req_clear_event_filter(req);
@@ -1171,12 +1179,13 @@ static void hci_req_set_event_filter(struct hci_request *req)
                scan = SCAN_PAGE;
        }
 
-       if (scan)
+       if (scan && !scanning) {
                set_bit(SUSPEND_SCAN_ENABLE, hdev->suspend_tasks);
-       else
+               hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
+       } else if (!scan && scanning) {
                set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks);
-
-       hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
+               hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
+       }
 }
 
 static void cancel_adv_timeout(struct hci_dev *hdev)
@@ -1319,9 +1328,14 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next)
 
                hdev->advertising_paused = true;
                hdev->advertising_old_state = old_state;
-               /* Disable page scan */
-               page_scan = SCAN_DISABLED;
-               hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &page_scan);
+
+               /* Disable page scan if enabled */
+               if (test_bit(HCI_PSCAN, &hdev->flags)) {
+                       page_scan = SCAN_DISABLED;
+                       hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1,
+                                   &page_scan);
+                       set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks);
+               }
 
                /* Disable LE passive scan if enabled */
                if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
@@ -1332,9 +1346,6 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next)
                /* Disable advertisement filters */
                hci_req_add_set_adv_filter_enable(&req, false);
 
-               /* Mark task needing completion */
-               set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks);
-
                /* Prevent disconnects from causing scanning to be re-enabled */
                hdev->scanning_paused = true;
 
@@ -1368,7 +1379,10 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next)
                hdev->suspended = false;
                hdev->scanning_paused = false;
 
+               /* Clear any event filters and restore scan state */
                hci_req_clear_event_filter(&req);
+               __hci_req_update_scan(&req);
+
                /* Reset passive/background scanning to normal */
                __hci_update_background_scan(&req);
                /* Enable all of the advertisement filters */
@@ -1641,9 +1655,8 @@ static u8 create_default_scan_rsp_data(struct hci_dev *hdev, u8 *ptr)
 {
        u8 scan_rsp_len = 0;
 
-       if (hdev->appearance) {
+       if (hdev->appearance)
                scan_rsp_len = append_appearance(hdev, ptr, scan_rsp_len);
-       }
 
        return append_local_name(hdev, ptr, scan_rsp_len);
 }
@@ -1661,9 +1674,8 @@ static u8 create_instance_scan_rsp_data(struct hci_dev *hdev, u8 instance,
 
        instance_flags = adv_instance->flags;
 
-       if ((instance_flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance) {
+       if ((instance_flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance)
                scan_rsp_len = append_appearance(hdev, ptr, scan_rsp_len);
-       }
 
        memcpy(&ptr[scan_rsp_len], adv_instance->scan_rsp_data,
               adv_instance->scan_rsp_len);
@@ -2039,7 +2051,8 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
                /* If Controller supports LL Privacy use own address type is
                 * 0x03
                 */
-               if (use_ll_privacy(hdev))
+               if (use_ll_privacy(hdev) &&
+                   hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY))
                        *own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED;
                else
                        *own_addr_type = ADDR_LE_DEV_RANDOM;
@@ -2174,7 +2187,8 @@ int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance)
                        cp.evt_properties = cpu_to_le16(LE_EXT_ADV_CONN_IND);
                else
                        cp.evt_properties = cpu_to_le16(LE_LEGACY_ADV_IND);
-       } else if (adv_instance_is_scannable(hdev, instance)) {
+       } else if (adv_instance_is_scannable(hdev, instance) ||
+                  (flags & MGMT_ADV_PARAM_SCAN_RSP)) {
                if (secondary_adv)
                        cp.evt_properties = cpu_to_le16(LE_EXT_ADV_SCAN_IND);
                else
@@ -2512,7 +2526,8 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
                /* If Controller supports LL Privacy use own address type is
                 * 0x03
                 */
-               if (use_ll_privacy(hdev))
+               if (use_ll_privacy(hdev) &&
+                   hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY))
                        *own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED;
                else
                        *own_addr_type = ADDR_LE_DEV_RANDOM;
@@ -2945,6 +2960,9 @@ static int bredr_inquiry(struct hci_request *req, unsigned long opt)
        const u8 liac[3] = { 0x00, 0x8b, 0x9e };
        struct hci_cp_inquiry cp;
 
+       if (test_bit(HCI_INQUIRY, &req->hdev->flags))
+               return 0;
+
        bt_dev_dbg(req->hdev, "");
 
        hci_dev_lock(req->hdev);
@@ -3245,6 +3263,7 @@ bool hci_req_stop_discovery(struct hci_request *req)
 
                if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
                        cancel_delayed_work(&hdev->le_scan_disable);
+                       cancel_delayed_work(&hdev->le_scan_restart);
                        hci_req_add_le_scan_disable(req, false);
                }