Lines Matching +full:x +full:- +full:rp
1 // SPDX-License-Identifier: GPL-2.0-only
14 #define MSFT_RSSI_THRESHOLD_VALUE_MIN -127
116 struct msft_rp_read_supported_features *rp; in read_supported_features() local
121 skb = __hci_cmd_sync(hdev, hdev->msft_opcode, sizeof(cp), &cp, in read_supported_features()
125 skb = ERR_PTR(-EIO); in read_supported_features()
132 if (skb->len < sizeof(*rp)) { in read_supported_features()
137 rp = (struct msft_rp_read_supported_features *)skb->data; in read_supported_features()
139 if (rp->sub_opcode != MSFT_OP_READ_SUPPORTED_FEATURES) in read_supported_features()
142 if (rp->evt_prefix_len > 0) { in read_supported_features()
143 msft->evt_prefix = kmemdup(rp->evt_prefix, rp->evt_prefix_len, in read_supported_features()
145 if (!msft->evt_prefix) in read_supported_features()
149 msft->evt_prefix_len = rp->evt_prefix_len; in read_supported_features()
150 msft->features = __le64_to_cpu(rp->features); in read_supported_features()
152 if (msft->features & MSFT_FEATURE_MASK_CURVE_VALIDITY) in read_supported_features()
153 hdev->msft_curve_validity = true; in read_supported_features()
165 * This function requires the caller holds hdev->lock
171 struct msft_data *msft = hdev->msft_data; in msft_find_handle_data()
173 list_for_each_entry(entry, &msft->handle_map, list) { in msft_find_handle_data()
174 if (is_mgmt && entry->mgmt_handle == handle) in msft_find_handle_data()
176 if (!is_mgmt && entry->msft_handle == handle) in msft_find_handle_data()
183 /* This function requires the caller holds hdev->lock */
191 list_for_each_entry_safe(dev, tmp, &hdev->monitored_devices, list) { in msft_monitor_device_del()
196 if ((!mgmt_handle || dev->handle == mgmt_handle) && in msft_monitor_device_del()
197 (!bdaddr || (!bacmp(bdaddr, &dev->bdaddr) && in msft_monitor_device_del()
198 addr_type == dev->addr_type))) { in msft_monitor_device_del()
199 if (notify && dev->notified) { in msft_monitor_device_del()
200 mgmt_adv_monitor_device_lost(hdev, dev->handle, in msft_monitor_device_del()
201 &dev->bdaddr, in msft_monitor_device_del()
202 dev->addr_type); in msft_monitor_device_del()
205 list_del(&dev->list); in msft_monitor_device_del()
218 struct msft_rp_le_monitor_advertisement *rp; in msft_le_monitor_advertisement_cb() local
220 struct msft_data *msft = hdev->msft_data; in msft_le_monitor_advertisement_cb()
225 rp = (struct msft_rp_le_monitor_advertisement *)skb->data; in msft_le_monitor_advertisement_cb()
226 if (skb->len < sizeof(*rp)) { in msft_le_monitor_advertisement_cb()
231 status = rp->status; in msft_le_monitor_advertisement_cb()
241 handle_data->mgmt_handle = monitor->handle; in msft_le_monitor_advertisement_cb()
242 handle_data->msft_handle = rp->handle; in msft_le_monitor_advertisement_cb()
243 INIT_LIST_HEAD(&handle_data->list); in msft_le_monitor_advertisement_cb()
244 list_add(&handle_data->list, &msft->handle_map); in msft_le_monitor_advertisement_cb()
246 monitor->state = ADV_MONITOR_STATE_OFFLOADED; in msft_le_monitor_advertisement_cb()
262 struct msft_rp_le_cancel_monitor_advertisement *rp; in msft_le_cancel_monitor_advertisement_cb() local
264 struct msft_data *msft = hdev->msft_data; in msft_le_cancel_monitor_advertisement_cb()
267 rp = (struct msft_rp_le_cancel_monitor_advertisement *)skb->data; in msft_le_cancel_monitor_advertisement_cb()
268 if (skb->len < sizeof(*rp)) { in msft_le_cancel_monitor_advertisement_cb()
273 status = rp->status; in msft_le_cancel_monitor_advertisement_cb()
279 handle_data = msft_find_handle_data(hdev, monitor->handle, true); in msft_le_cancel_monitor_advertisement_cb()
282 if (monitor->state == ADV_MONITOR_STATE_OFFLOADED) in msft_le_cancel_monitor_advertisement_cb()
283 monitor->state = ADV_MONITOR_STATE_REGISTERED; in msft_le_cancel_monitor_advertisement_cb()
286 * suspend. It will be re-monitored on resume. in msft_le_cancel_monitor_advertisement_cb()
288 if (!msft->suspending) { in msft_le_cancel_monitor_advertisement_cb()
292 msft_monitor_device_del(hdev, handle_data->mgmt_handle, in msft_le_cancel_monitor_advertisement_cb()
296 list_del(&handle_data->list); in msft_le_cancel_monitor_advertisement_cb()
314 handle_data = msft_find_handle_data(hdev, monitor->handle, true); in msft_remove_monitor_sync()
318 return -ENOENT; in msft_remove_monitor_sync()
321 cp.handle = handle_data->msft_handle; in msft_remove_monitor_sync()
323 skb = __hci_cmd_sync(hdev, hdev->msft_opcode, sizeof(cp), &cp, in msft_remove_monitor_sync()
327 return -EIO; in msft_remove_monitor_sync()
331 return msft_le_cancel_monitor_advertisement_cb(hdev, hdev->msft_opcode, in msft_remove_monitor_sync()
338 struct msft_data *msft = hdev->msft_data; in msft_suspend_sync()
345 msft->suspending = true; in msft_suspend_sync()
348 monitor = idr_get_next(&hdev->adv_monitors_idr, &handle); in msft_suspend_sync()
358 msft->suspending = false; in msft_suspend_sync()
365 struct adv_rssi_thresholds *r = &monitor->rssi; in msft_monitor_rssi_valid()
367 if (r->high_threshold < MSFT_RSSI_THRESHOLD_VALUE_MIN || in msft_monitor_rssi_valid()
368 r->high_threshold > MSFT_RSSI_THRESHOLD_VALUE_MAX || in msft_monitor_rssi_valid()
369 r->low_threshold < MSFT_RSSI_THRESHOLD_VALUE_MIN || in msft_monitor_rssi_valid()
370 r->low_threshold > MSFT_RSSI_THRESHOLD_VALUE_MAX) in msft_monitor_rssi_valid()
376 if (r->high_threshold_timeout != 0) in msft_monitor_rssi_valid()
379 if (r->low_threshold_timeout > MSFT_RSSI_LOW_TIMEOUT_MAX) in msft_monitor_rssi_valid()
389 /* No additional check needed for pattern-based monitor */ in msft_monitor_pattern_valid()
405 return -EINVAL; in msft_add_monitor_sync()
407 list_for_each_entry(entry, &monitor->patterns, list) { in msft_add_monitor_sync()
409 total_size += sizeof(*pattern) + entry->length; in msft_add_monitor_sync()
414 return -ENOMEM; in msft_add_monitor_sync()
416 cp->sub_opcode = MSFT_OP_LE_MONITOR_ADVERTISEMENT; in msft_add_monitor_sync()
417 cp->rssi_high = monitor->rssi.high_threshold; in msft_add_monitor_sync()
418 cp->rssi_low = monitor->rssi.low_threshold; in msft_add_monitor_sync()
419 cp->rssi_low_interval = (u8)monitor->rssi.low_threshold_timeout; in msft_add_monitor_sync()
420 cp->rssi_sampling_period = monitor->rssi.sampling_period; in msft_add_monitor_sync()
422 cp->cond_type = MSFT_MONITOR_ADVERTISEMENT_TYPE_PATTERN; in msft_add_monitor_sync()
424 pattern_data = (void *)cp->data; in msft_add_monitor_sync()
425 pattern_data->count = pattern_count; in msft_add_monitor_sync()
427 list_for_each_entry(entry, &monitor->patterns, list) { in msft_add_monitor_sync()
428 pattern = (void *)(pattern_data->data + offset); in msft_add_monitor_sync()
430 pattern->length = entry->length + 2; in msft_add_monitor_sync()
431 pattern->data_type = entry->ad_type; in msft_add_monitor_sync()
432 pattern->start_byte = entry->offset; in msft_add_monitor_sync()
433 memcpy(pattern->pattern, entry->value, entry->length); in msft_add_monitor_sync()
434 offset += sizeof(*pattern) + entry->length; in msft_add_monitor_sync()
437 skb = __hci_cmd_sync(hdev, hdev->msft_opcode, total_size, cp, in msft_add_monitor_sync()
443 return -EIO; in msft_add_monitor_sync()
447 return msft_le_monitor_advertisement_cb(hdev, hdev->msft_opcode, in msft_add_monitor_sync()
455 struct msft_data *msft = hdev->msft_data; in reregister_monitor()
461 msft->resuming = true; in reregister_monitor()
464 monitor = idr_get_next(&hdev->adv_monitors_idr, &handle); in reregister_monitor()
474 msft->resuming = false; in reregister_monitor()
480 struct msft_data *msft = hdev->msft_data; in msft_resume_sync()
490 hdev->advmon_pend_notify = false; in msft_resume_sync()
503 struct msft_data *msft = hdev->msft_data; in msft_do_open()
505 if (hdev->msft_opcode == HCI_OP_NOP) in msft_do_open()
515 /* Reset existing MSFT data before re-reading */ in msft_do_open()
516 kfree(msft->evt_prefix); in msft_do_open()
517 msft->evt_prefix = NULL; in msft_do_open()
518 msft->evt_prefix_len = 0; in msft_do_open()
519 msft->features = 0; in msft_do_open()
522 hdev->msft_data = NULL; in msft_do_open()
528 msft->resuming = true; in msft_do_open()
531 * tell the controller to re-monitor. in msft_do_open()
539 struct msft_data *msft = hdev->msft_data; in msft_do_close()
551 list_for_each_entry_safe(handle_data, tmp, &msft->handle_map, list) { in msft_do_close()
552 monitor = idr_find(&hdev->adv_monitors_idr, in msft_do_close()
553 handle_data->mgmt_handle); in msft_do_close()
555 if (monitor && monitor->state == ADV_MONITOR_STATE_OFFLOADED) in msft_do_close()
556 monitor->state = ADV_MONITOR_STATE_REGISTERED; in msft_do_close()
558 list_del(&handle_data->list); in msft_do_close()
565 hdev->advmon_pend_notify = false; in msft_do_close()
583 INIT_LIST_HEAD(&msft->handle_map); in msft_register()
584 hdev->msft_data = msft; in msft_register()
589 struct msft_data *msft = hdev->msft_data; in msft_unregister()
596 hdev->msft_data = NULL; in msft_unregister()
598 kfree(msft->evt_prefix); in msft_unregister()
602 /* This function requires the caller holds hdev->lock */
615 bacpy(&dev->bdaddr, bdaddr); in msft_device_found()
616 dev->addr_type = addr_type; in msft_device_found()
617 dev->handle = mgmt_handle; in msft_device_found()
618 dev->notified = false; in msft_device_found()
620 INIT_LIST_HEAD(&dev->list); in msft_device_found()
621 list_add(&dev->list, &hdev->monitored_devices); in msft_device_found()
622 hdev->advmon_pend_notify = true; in msft_device_found()
625 /* This function requires the caller holds hdev->lock */
643 bt_dev_err(hdev, "Malformed MSFT vendor event: 0x%02x", ev); in msft_skb_pull()
648 /* This function requires the caller holds hdev->lock */
660 "MSFT vendor event 0x%02x: handle 0x%04x state %d addr %pMR", in msft_monitor_device_evt()
661 MSFT_EV_LE_MONITOR_DEVICE, ev->monitor_handle, in msft_monitor_device_evt()
662 ev->monitor_state, &ev->bdaddr); in msft_monitor_device_evt()
664 handle_data = msft_find_handle_data(hdev, ev->monitor_handle, false); in msft_monitor_device_evt()
668 switch (ev->addr_type) { in msft_monitor_device_evt()
679 "MSFT vendor event 0x%02x: unknown addr type 0x%02x", in msft_monitor_device_evt()
680 MSFT_EV_LE_MONITOR_DEVICE, ev->addr_type); in msft_monitor_device_evt()
684 if (ev->monitor_state) in msft_monitor_device_evt()
685 msft_device_found(hdev, &ev->bdaddr, addr_type, in msft_monitor_device_evt()
686 handle_data->mgmt_handle); in msft_monitor_device_evt()
688 msft_device_lost(hdev, &ev->bdaddr, addr_type, in msft_monitor_device_evt()
689 handle_data->mgmt_handle); in msft_monitor_device_evt()
694 struct msft_data *msft = hdev->msft_data; in msft_vendor_evt()
704 if (msft->evt_prefix_len > 0) { in msft_vendor_evt()
705 evt_prefix = msft_skb_pull(hdev, skb, 0, msft->evt_prefix_len); in msft_vendor_evt()
709 if (memcmp(evt_prefix, msft->evt_prefix, msft->evt_prefix_len)) in msft_vendor_evt()
716 if (skb->len < 1) in msft_vendor_evt()
731 bt_dev_dbg(hdev, "MSFT vendor event 0x%02x", *evt); in msft_vendor_evt()
740 struct msft_data *msft = hdev->msft_data; in msft_get_features()
742 return msft ? msft->features : 0; in msft_get_features()
750 struct msft_rp_le_set_advertisement_filter_enable *rp; in msft_le_set_advertisement_filter_enable_cb() local
751 struct msft_data *msft = hdev->msft_data; in msft_le_set_advertisement_filter_enable_cb()
753 rp = (struct msft_rp_le_set_advertisement_filter_enable *)skb->data; in msft_le_set_advertisement_filter_enable_cb()
754 if (skb->len < sizeof(*rp)) in msft_le_set_advertisement_filter_enable_cb()
769 cp = hci_sent_cmd_data(hdev, hdev->msft_opcode); in msft_le_set_advertisement_filter_enable_cb()
770 msft->filter_enabled = cp->enable; in msft_le_set_advertisement_filter_enable_cb()
774 cp->enable ? "on" : "off"); in msft_le_set_advertisement_filter_enable_cb()
782 struct msft_data *msft = hdev->msft_data; in msft_add_monitor_pattern()
785 return -EOPNOTSUPP; in msft_add_monitor_pattern()
787 if (msft->resuming || msft->suspending) in msft_add_monitor_pattern()
788 return -EBUSY; in msft_add_monitor_pattern()
796 struct msft_data *msft = hdev->msft_data; in msft_remove_monitor()
799 return -EOPNOTSUPP; in msft_remove_monitor()
801 if (msft->resuming || msft->suspending) in msft_remove_monitor()
802 return -EBUSY; in msft_remove_monitor()
809 struct hci_dev *hdev = req->hdev; in msft_req_add_set_filter_enable()
815 hci_req_add(req, hdev->msft_opcode, sizeof(cp), &cp); in msft_req_add_set_filter_enable()
821 struct msft_data *msft = hdev->msft_data; in msft_set_filter_enable()
825 return -EOPNOTSUPP; in msft_set_filter_enable()
836 return hdev->msft_curve_validity; in msft_curve_validity()