#include "smp.h"
#include "hci_request.h"
+#include "msft.h"
#define HCI_REQ_DONE 0
#define HCI_REQ_PEND 1
clear_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks);
wake_up(&hdev->suspend_wait_q);
}
+
+ if (test_bit(SUSPEND_SET_ADV_FILTER, hdev->suspend_tasks)) {
+ clear_bit(SUSPEND_SET_ADV_FILTER, hdev->suspend_tasks);
+ wake_up(&hdev->suspend_wait_q);
+ }
+}
+
+static void hci_req_add_set_adv_filter_enable(struct hci_request *req,
+ bool enable)
+{
+ struct hci_dev *hdev = req->hdev;
+
+ switch (hci_get_adv_monitor_offload_ext(hdev)) {
+ case HCI_ADV_MONITOR_EXT_MSFT:
+ msft_req_add_set_filter_enable(req, enable);
+ break;
+ default:
+ return;
+ }
+
+ /* No need to block when enabling since it's on resume path */
+ if (hdev->suspended && !enable)
+ set_bit(SUSPEND_SET_ADV_FILTER, hdev->suspend_tasks);
}
/* Call with hci_dev_lock */
hci_req_add_le_scan_disable(&req, false);
}
+ /* Disable advertisement filters */
+ hci_req_add_set_adv_filter_enable(&req, false);
+
/* Mark task needing completion */
set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks);
hci_req_clear_event_filter(&req);
/* Reset passive/background scanning to normal */
__hci_update_background_scan(&req);
+ /* Enable all of the advertisement filters */
+ hci_req_add_set_adv_filter_enable(&req, true);
/* Unpause directed advertising */
hdev->advertising_paused = false;
return err;
}
-int msft_set_filter_enable(struct hci_dev *hdev, bool enable)
+void msft_req_add_set_filter_enable(struct hci_request *req, bool enable)
{
+ struct hci_dev *hdev = req->hdev;
struct msft_cp_le_set_advertisement_filter_enable cp;
+
+ cp.sub_opcode = MSFT_OP_LE_SET_ADVERTISEMENT_FILTER_ENABLE;
+ cp.enable = enable;
+
+ hci_req_add(req, hdev->msft_opcode, sizeof(cp), &cp);
+}
+
+int msft_set_filter_enable(struct hci_dev *hdev, bool enable)
+{
struct hci_request req;
struct msft_data *msft = hdev->msft_data;
int err;
if (!msft)
return -EOPNOTSUPP;
- cp.sub_opcode = MSFT_OP_LE_SET_ADVERTISEMENT_FILTER_ENABLE;
- cp.enable = enable;
-
hci_req_init(&req, hdev);
- hci_req_add(&req, hdev->msft_opcode, sizeof(cp), &cp);
+ msft_req_add_set_filter_enable(&req, enable);
err = hci_req_run_skb(&req, msft_le_set_advertisement_filter_enable_cb);
return err;
int msft_add_monitor_pattern(struct hci_dev *hdev, struct adv_monitor *monitor);
int msft_remove_monitor(struct hci_dev *hdev, struct adv_monitor *monitor,
u16 handle);
+void msft_req_add_set_filter_enable(struct hci_request *req, bool enable);
int msft_set_filter_enable(struct hci_dev *hdev, bool enable);
#else
return -EOPNOTSUPP;
}
+static inline void msft_req_add_set_filter_enable(struct hci_request *req,
+ bool enable) {}
static inline int msft_set_filter_enable(struct hci_dev *hdev, bool enable)
{
return -EOPNOTSUPP;