// SPDX-License-Identifier: GPL-2.0
/*
 * BlueZ - Bluetooth protocol stack for Linux
 *
 * Copyright (C) 2021 Intel Corporation
 * Copyright 2023 NXP
 */

#include <linux/property.h>

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/mgmt.h>

#include "hci_request.h"
#include "hci_codec.h"
#include "hci_debugfs.h"
#include "smp.h"
#include "eir.h"
#include "msft.h"
#include "aosp.h"
#include "leds.h"

static void hci_cmd_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode,
				  struct sk_buff *skb)
{
	bt_dev_dbg(hdev, "result 0x%2.2x", result);

	if (hdev->req_status != HCI_REQ_PEND)
		return;

	hdev->req_result = result;
	hdev->req_status = HCI_REQ_DONE;

	/* Free the request command so it is not used as response */
	kfree_skb(hdev->req_skb);
	hdev->req_skb = NULL;

	if (skb) {
		struct sock *sk = hci_skb_sk(skb);

		/* Drop sk reference if set */
		if (sk)
			sock_put(sk);

		hdev->req_rsp = skb_get(skb);
	}

	wake_up_interruptible(&hdev->req_wait_q);
}

static struct sk_buff *hci_cmd_sync_alloc(struct hci_dev *hdev, u16 opcode,
					  u32 plen, const void *param,
					  struct sock *sk)
{
	int len = HCI_COMMAND_HDR_SIZE + plen;
	struct hci_command_hdr *hdr;
	struct sk_buff *skb;

	skb = bt_skb_alloc(len, GFP_ATOMIC);
	if (!skb)
		return NULL;

	hdr = skb_put(skb, HCI_COMMAND_HDR_SIZE);
	hdr->opcode = cpu_to_le16(opcode);
	hdr->plen   = plen;

	if (plen)
		skb_put_data(skb, param, plen);

	bt_dev_dbg(hdev, "skb len %d", skb->len);

	hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
	hci_skb_opcode(skb) = opcode;

	/* Grab a reference if command needs to be associated with a sock (e.g.
	 * likely mgmt socket that initiated the command).
	 */
	if (sk) {
		hci_skb_sk(skb) = sk;
		sock_hold(sk);
	}

	return skb;
}

static void hci_cmd_sync_add(struct hci_request *req, u16 opcode, u32 plen,
			     const void *param, u8 event, struct sock *sk)
{
	struct hci_dev *hdev = req->hdev;
	struct sk_buff *skb;

	bt_dev_dbg(hdev, "opcode 0x%4.4x plen %d", opcode, plen);

	/* If an error occurred during request building, there is no point in
	 * queueing the HCI command. We can simply return.
	 */
	if (req->err)
		return;

	skb = hci_cmd_sync_alloc(hdev, opcode, plen, param, sk);
	if (!skb) {
		bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)",
			   opcode);
		req->err = -ENOMEM;
		return;
	}

	if (skb_queue_empty(&req->cmd_q))
		bt_cb(skb)->hci.req_flags |= HCI_REQ_START;

	hci_skb_event(skb) = event;

	skb_queue_tail(&req->cmd_q, skb);
}

static int hci_cmd_sync_run(struct hci_request *req)
{
	struct hci_dev *hdev = req->hdev;
	struct sk_buff *skb;
	unsigned long flags;

	bt_dev_dbg(hdev, "length %u", skb_queue_len(&req->cmd_q));

	/* If an error occurred during request building, remove all HCI
	 * commands queued on the HCI request queue.
	 */
	if (req->err) {
		skb_queue_purge(&req->cmd_q);
		return req->err;
	}

	/* Do not allow empty requests */
	if (skb_queue_empty(&req->cmd_q))
		return -ENODATA;

	skb = skb_peek_tail(&req->cmd_q);
	bt_cb(skb)->hci.req_complete_skb = hci_cmd_sync_complete;
	bt_cb(skb)->hci.req_flags |= HCI_REQ_SKB;

	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);

	queue_work(hdev->workqueue, &hdev->cmd_work);

	return 0;
}

/* This function requires the caller holds hdev->req_lock. */
struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
				  const void *param, u8 event, u32 timeout,
				  struct sock *sk)
{
	struct hci_request req;
	struct sk_buff *skb;
	int err = 0;

	bt_dev_dbg(hdev, "Opcode 0x%4.4x", opcode);

	hci_req_init(&req, hdev);

	hci_cmd_sync_add(&req, opcode, plen, param, event, sk);

	hdev->req_status = HCI_REQ_PEND;

	err = hci_cmd_sync_run(&req);
	if (err < 0)
		return ERR_PTR(err);

	err = wait_event_interruptible_timeout(hdev->req_wait_q,
					       hdev->req_status != HCI_REQ_PEND,
					       timeout);

	if (err == -ERESTARTSYS)
		return ERR_PTR(-EINTR);

	switch (hdev->req_status) {
	case HCI_REQ_DONE:
		err = -bt_to_errno(hdev->req_result);
		break;

	case HCI_REQ_CANCELED:
		err = -hdev->req_result;
		break;

	default:
		err = -ETIMEDOUT;
		break;
	}

	hdev->req_status = 0;
	hdev->req_result = 0;
	skb = hdev->req_rsp;
	hdev->req_rsp = NULL;

	bt_dev_dbg(hdev, "end: err %d", err);

	if (err < 0) {
		kfree_skb(skb);
		return ERR_PTR(err);
	}

	return skb;
}
EXPORT_SYMBOL(__hci_cmd_sync_sk);

/* This function requires the caller holds hdev->req_lock. */
struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
			       const void *param, u32 timeout)
{
	return __hci_cmd_sync_sk(hdev, opcode, plen, param, 0, timeout, NULL);
}
EXPORT_SYMBOL(__hci_cmd_sync);

/* Send HCI command and wait for command complete event */
struct sk_buff *hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
			     const void *param, u32 timeout)
{
	struct sk_buff *skb;

	if (!test_bit(HCI_UP, &hdev->flags))
		return ERR_PTR(-ENETDOWN);

	bt_dev_dbg(hdev, "opcode 0x%4.4x plen %d", opcode, plen);

	hci_req_sync_lock(hdev);
	skb = __hci_cmd_sync(hdev, opcode, plen, param, timeout);
	hci_req_sync_unlock(hdev);

	return skb;
}
EXPORT_SYMBOL(hci_cmd_sync);

/* This function requires the caller holds hdev->req_lock. */
struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
				  const void *param, u8 event, u32 timeout)
{
	return __hci_cmd_sync_sk(hdev, opcode, plen, param, event, timeout,
				 NULL);
}
EXPORT_SYMBOL(__hci_cmd_sync_ev);

/* This function requires the caller holds hdev->req_lock. */
int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
			     const void *param, u8 event, u32 timeout,
			     struct sock *sk)
{
	struct sk_buff *skb;
	u8 status;

	skb = __hci_cmd_sync_sk(hdev, opcode, plen, param, event, timeout, sk);
	if (IS_ERR(skb)) {
		if (!event)
			bt_dev_err(hdev, "Opcode 0x%4.4x failed: %ld", opcode,
				   PTR_ERR(skb));
		return PTR_ERR(skb);
	}

	/* If command return a status event skb will be set to NULL as there are
	 * no parameters, in case of failure IS_ERR(skb) would have be set to
	 * the actual error would be found with PTR_ERR(skb).
	 */
	if (!skb)
		return 0;

	status = skb->data[0];

	kfree_skb(skb);

	return status;
}
EXPORT_SYMBOL(__hci_cmd_sync_status_sk);

int __hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen,
			  const void *param, u32 timeout)
{
	return __hci_cmd_sync_status_sk(hdev, opcode, plen, param, 0, timeout,
					NULL);
}
EXPORT_SYMBOL(__hci_cmd_sync_status);

static void hci_cmd_sync_work(struct work_struct *work)
{
	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_sync_work);

	bt_dev_dbg(hdev, "");

	/* Dequeue all entries and run them */
	while (1) {
		struct hci_cmd_sync_work_entry *entry;

		mutex_lock(&hdev->cmd_sync_work_lock);
		entry = list_first_entry_or_null(&hdev->cmd_sync_work_list,
						 struct hci_cmd_sync_work_entry,
						 list);
		if (entry)
			list_del(&entry->list);
		mutex_unlock(&hdev->cmd_sync_work_lock);

		if (!entry)
			break;

		bt_dev_dbg(hdev, "entry %p", entry);

		if (entry->func) {
			int err;

			hci_req_sync_lock(hdev);
			err = entry->func(hdev, entry->data);
			if (entry->destroy)
				entry->destroy(hdev, entry->data, err);
			hci_req_sync_unlock(hdev);
		}

		kfree(entry);
	}
}

static void hci_cmd_sync_cancel_work(struct work_struct *work)
{
	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_sync_cancel_work);

	cancel_delayed_work_sync(&hdev->cmd_timer);
	cancel_delayed_work_sync(&hdev->ncmd_timer);
	atomic_set(&hdev->cmd_cnt, 1);

	wake_up_interruptible(&hdev->req_wait_q);
}

static int hci_scan_disable_sync(struct hci_dev *hdev);
static int scan_disable_sync(struct hci_dev *hdev, void *data)
{
	return hci_scan_disable_sync(hdev);
}

static int hci_inquiry_sync(struct hci_dev *hdev, u8 length);
static int interleaved_inquiry_sync(struct hci_dev *hdev, void *data)
{
	return hci_inquiry_sync(hdev, DISCOV_INTERLEAVED_INQUIRY_LEN);
}

static void le_scan_disable(struct work_struct *work)
{
	struct hci_dev *hdev = container_of(work, struct hci_dev,
					    le_scan_disable.work);
	int status;

	bt_dev_dbg(hdev, "");
	hci_dev_lock(hdev);

	if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
		goto _return;

	status = hci_cmd_sync_queue(hdev, scan_disable_sync, NULL, NULL);
	if (status) {
		bt_dev_err(hdev, "failed to disable LE scan: %d", status);
		goto _return;
	}

	hdev->discovery.scan_start = 0;

	/* If we were running LE only scan, change discovery state. If
	 * we were running both LE and BR/EDR inquiry simultaneously,
	 * and BR/EDR inquiry is already finished, stop discovery,
	 * otherwise BR/EDR inquiry will stop discovery when finished.
	 * If we will resolve remote device name, do not change
	 * discovery state.
	 */

	if (hdev->discovery.type == DISCOV_TYPE_LE)
		goto discov_stopped;

	if (hdev->discovery.type != DISCOV_TYPE_INTERLEAVED)
		goto _return;

	if (test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) {
		if (!test_bit(HCI_INQUIRY, &hdev->flags) &&
		    hdev->discovery.state != DISCOVERY_RESOLVING)
			goto discov_stopped;

		goto _return;
	}

	status = hci_cmd_sync_queue(hdev, interleaved_inquiry_sync, NULL, NULL);
	if (status) {
		bt_dev_err(hdev, "inquiry failed: status %d", status);
		goto discov_stopped;
	}

	goto _return;

discov_stopped:
	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);

_return:
	hci_dev_unlock(hdev);
}

static int hci_le_set_scan_enable_sync(struct hci_dev *hdev, u8 val,
				       u8 filter_dup);

static int reenable_adv_sync(struct hci_dev *hdev, void *data)
{
	bt_dev_dbg(hdev, "");

	if (!hci_dev_test_flag(hdev, HCI_ADVERTISING) &&
	    list_empty(&hdev->adv_instances))
		return 0;

	if (hdev->cur_adv_instance) {
		return hci_schedule_adv_instance_sync(hdev,
						      hdev->cur_adv_instance,
						      true);
	} else {
		if (ext_adv_capable(hdev)) {
			hci_start_ext_adv_sync(hdev, 0x00);
		} else {
			hci_update_adv_data_sync(hdev, 0x00);
			hci_update_scan_rsp_data_sync(hdev, 0x00);
			hci_enable_advertising_sync(hdev);
		}
	}

	return 0;
}

static void reenable_adv(struct work_struct *work)
{
	struct hci_dev *hdev = container_of(work, struct hci_dev,
					    reenable_adv_work);
	int status;

	bt_dev_dbg(hdev, "");

	hci_dev_lock(hdev);

	status = hci_cmd_sync_queue(hdev, reenable_adv_sync, NULL, NULL);
	if (status)
		bt_dev_err(hdev, "failed to reenable ADV: %d", status);

	hci_dev_unlock(hdev);
}

static void cancel_adv_timeout(struct hci_dev *hdev)
{
	if (hdev->adv_instance_timeout) {
		hdev->adv_instance_timeout = 0;
		cancel_delayed_work(&hdev->adv_instance_expire);
	}
}

/* For a single instance:
 * - force == true: The instance will be removed even when its remaining
 *   lifetime is not zero.
 * - force == false: the instance will be deactivated but kept stored unless
 *   the remaining lifetime is zero.
 *
 * For instance == 0x00:
 * - force == true: All instances will be removed regardless of their timeout
 *   setting.
 * - force == false: Only instances that have a timeout will be removed.
 */
int hci_clear_adv_instance_sync(struct hci_dev *hdev, struct sock *sk,
				u8 instance, bool force)
{
	struct adv_info *adv_instance, *n, *next_instance = NULL;
	int err;
	u8 rem_inst;

	/* Cancel any timeout concerning the removed instance(s). */
	if (!instance || hdev->cur_adv_instance == instance)
		cancel_adv_timeout(hdev);

	/* Get the next instance to advertise BEFORE we remove
	 * the current one. This can be the same instance again
	 * if there is only one instance.
	 */
	if (instance && hdev->cur_adv_instance == instance)
		next_instance = hci_get_next_instance(hdev, instance);

	if (instance == 0x00) {
		list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances,
					 list) {
			if (!(force || adv_instance->timeout))
				continue;

			rem_inst = adv_instance->instance;
			err = hci_remove_adv_instance(hdev, rem_inst);
			if (!err)
				mgmt_advertising_removed(sk, hdev, rem_inst);
		}
	} else {
		adv_instance = hci_find_adv_instance(hdev, instance);

		if (force || (adv_instance && adv_instance->timeout &&
			      !adv_instance->remaining_time)) {
			/* Don't advertise a removed instance. */
			if (next_instance &&
			    next_instance->instance == instance)
				next_instance = NULL;

			err = hci_remove_adv_instance(hdev, instance);
			if (!err)
				mgmt_advertising_removed(sk, hdev, instance);
		}
	}

	if (!hdev_is_powered(hdev) || hci_dev_test_flag(hdev, HCI_ADVERTISING))
		return 0;

	if (next_instance && !ext_adv_capable(hdev))
		return hci_schedule_adv_instance_sync(hdev,
						      next_instance->instance,
						      false);

	return 0;
}

static int adv_timeout_expire_sync(struct hci_dev *hdev, void *data)
{
	u8 instance = *(u8 *)data;

	kfree(data);

	hci_clear_adv_instance_sync(hdev, NULL, instance, false);

	if (list_empty(&hdev->adv_instances))
		return hci_disable_advertising_sync(hdev);

	return 0;
}

static void adv_timeout_expire(struct work_struct *work)
{
	u8 *inst_ptr;
	struct hci_dev *hdev = container_of(work, struct hci_dev,
					    adv_instance_expire.work);

	bt_dev_dbg(hdev, "");

	hci_dev_lock(hdev);

	hdev->adv_instance_timeout = 0;

	if (hdev->cur_adv_instance == 0x00)
		goto unlock;

	inst_ptr = kmalloc(1, GFP_KERNEL);
	if (!inst_ptr)
		goto unlock;

	*inst_ptr = hdev->cur_adv_instance;
	hci_cmd_sync_queue(hdev, adv_timeout_expire_sync, inst_ptr, NULL);

unlock:
	hci_dev_unlock(hdev);
}

void hci_cmd_sync_init(struct hci_dev *hdev)
{
	INIT_WORK(&hdev->cmd_sync_work, hci_cmd_sync_work);
	INIT_LIST_HEAD(&hdev->cmd_sync_work_list);
	mutex_init(&hdev->cmd_sync_work_lock);
	mutex_init(&hdev->unregister_lock);

	INIT_WORK(&hdev->cmd_sync_cancel_work, hci_cmd_sync_cancel_work);
	INIT_WORK(&hdev->reenable_adv_work, reenable_adv);
	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable);
	INIT_DELAYED_WORK(&hdev->adv_instance_expire, adv_timeout_expire);
}

static void _hci_cmd_sync_cancel_entry(struct hci_dev *hdev,
				       struct hci_cmd_sync_work_entry *entry,
				       int err)
{
	if (entry->destroy)
		entry->destroy(hdev, entry->data, err);

	list_del(&entry->list);
	kfree(entry);
}

void hci_cmd_sync_clear(struct hci_dev *hdev)
{
	struct hci_cmd_sync_work_entry *entry, *tmp;

	cancel_work_sync(&hdev->cmd_sync_work);
	cancel_work_sync(&hdev->reenable_adv_work);

	mutex_lock(&hdev->cmd_sync_work_lock);
	list_for_each_entry_safe(entry, tmp, &hdev->cmd_sync_work_list, list)
		_hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
	mutex_unlock(&hdev->cmd_sync_work_lock);
}

void hci_cmd_sync_cancel(struct hci_dev *hdev, int err)
{
	bt_dev_dbg(hdev, "err 0x%2.2x", err);

	if (hdev->req_status == HCI_REQ_PEND) {
		hdev->req_result = err;
		hdev->req_status = HCI_REQ_CANCELED;

		queue_work(hdev->workqueue, &hdev->cmd_sync_cancel_work);
	}
}
EXPORT_SYMBOL(hci_cmd_sync_cancel);

/* Cancel ongoing command request synchronously:
 *
 * - Set result and mark status to HCI_REQ_CANCELED
 * - Wakeup command sync thread
 */
void hci_cmd_sync_cancel_sync(struct hci_dev *hdev, int err)
{
	bt_dev_dbg(hdev, "err 0x%2.2x", err);

	if (hdev->req_status == HCI_REQ_PEND) {
		/* req_result is __u32 so error must be positive to be properly
		 * propagated.
		 */
		hdev->req_result = err < 0 ? -err : err;
		hdev->req_status = HCI_REQ_CANCELED;

		wake_up_interruptible(&hdev->req_wait_q);
	}
}
EXPORT_SYMBOL(hci_cmd_sync_cancel_sync);

/* Submit HCI command to be run in as cmd_sync_work:
 *
 * - hdev must _not_ be unregistered
 */
int hci_cmd_sync_submit(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
			void *data, hci_cmd_sync_work_destroy_t destroy)
{
	struct hci_cmd_sync_work_entry *entry;
	int err = 0;

	mutex_lock(&hdev->unregister_lock);
	if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
		err = -ENODEV;
		goto unlock;
	}

	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
	if (!entry) {
		err = -ENOMEM;
		goto unlock;
	}
	entry->func = func;
	entry->data = data;
	entry->destroy = destroy;

	mutex_lock(&hdev->cmd_sync_work_lock);
	list_add_tail(&entry->list, &hdev->cmd_sync_work_list);
	mutex_unlock(&hdev->cmd_sync_work_lock);

	queue_work(hdev->req_workqueue, &hdev->cmd_sync_work);

unlock:
	mutex_unlock(&hdev->unregister_lock);
	return err;
}
EXPORT_SYMBOL(hci_cmd_sync_submit);

/* Queue HCI command:
 *
 * - hdev must be running
 */
int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
		       void *data, hci_cmd_sync_work_destroy_t destroy)
{
	/* Only queue command if hdev is running which means it had been opened
	 * and is either on init phase or is already up.
	 */
	if (!test_bit(HCI_RUNNING, &hdev->flags))
		return -ENETDOWN;

	return hci_cmd_sync_submit(hdev, func, data, destroy);
}
EXPORT_SYMBOL(hci_cmd_sync_queue);

static struct hci_cmd_sync_work_entry *
_hci_cmd_sync_lookup_entry(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
			   void *data, hci_cmd_sync_work_destroy_t destroy)
{
	struct hci_cmd_sync_work_entry *entry, *tmp;

	list_for_each_entry_safe(entry, tmp, &hdev->cmd_sync_work_list, list) {
		if (func && entry->func != func)
			continue;

		if (data && entry->data != data)
			continue;

		if (destroy && entry->destroy != destroy)
			continue;

		return entry;
	}

	return NULL;
}

/* Queue HCI command entry once:
 *
 * - Lookup if an entry already exist and only if it doesn't creates a new entry
 *   and queue it.
 */
int hci_cmd_sync_queue_once(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
			    void *data, hci_cmd_sync_work_destroy_t destroy)
{
	if (hci_cmd_sync_lookup_entry(hdev, func, data, destroy))
		return 0;

	return hci_cmd_sync_queue(hdev, func, data, destroy);
}
EXPORT_SYMBOL(hci_cmd_sync_queue_once);

/* Lookup HCI command entry:
 *
 * - Return first entry that matches by function callback or data or
 *   destroy callback.
 */
struct hci_cmd_sync_work_entry *
hci_cmd_sync_lookup_entry(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
			  void *data, hci_cmd_sync_work_destroy_t destroy)
{
	struct hci_cmd_sync_work_entry *entry;

	mutex_lock(&hdev->cmd_sync_work_lock);
	entry = _hci_cmd_sync_lookup_entry(hdev, func, data, destroy);
	mutex_unlock(&hdev->cmd_sync_work_lock);

	return entry;
}
EXPORT_SYMBOL(hci_cmd_sync_lookup_entry);

/* Cancel HCI command entry */
void hci_cmd_sync_cancel_entry(struct hci_dev *hdev,
			       struct hci_cmd_sync_work_entry *entry)
{
	mutex_lock(&hdev->cmd_sync_work_lock);
	_hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
	mutex_unlock(&hdev->cmd_sync_work_lock);
}
EXPORT_SYMBOL(hci_cmd_sync_cancel_entry);

/* Dequeue one HCI command entry:
 *
 * - Lookup and cancel first entry that matches.
 */
bool hci_cmd_sync_dequeue_once(struct hci_dev *hdev,
			       hci_cmd_sync_work_func_t func,
			       void *data, hci_cmd_sync_work_destroy_t destroy)
{
	struct hci_cmd_sync_work_entry *entry;

	entry = hci_cmd_sync_lookup_entry(hdev, func, data, destroy);
	if (!entry)
		return false;

	hci_cmd_sync_cancel_entry(hdev, entry);

	return true;
}
EXPORT_SYMBOL(hci_cmd_sync_dequeue_once);

/* Dequeue HCI command entry:
 *
 * - Lookup and cancel any entry that matches by function callback or data or
 *   destroy callback.
 */
bool hci_cmd_sync_dequeue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
			  void *data, hci_cmd_sync_work_destroy_t destroy)
{
	struct hci_cmd_sync_work_entry *entry;
	bool ret = false;

	mutex_lock(&hdev->cmd_sync_work_lock);
	while ((entry = _hci_cmd_sync_lookup_entry(hdev, func, data,
						   destroy))) {
		_hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
		ret = true;
	}
	mutex_unlock(&hdev->cmd_sync_work_lock);

	return ret;
}
EXPORT_SYMBOL(hci_cmd_sync_dequeue);

int hci_update_eir_sync(struct hci_dev *hdev)
{
	struct hci_cp_write_eir cp;

	bt_dev_dbg(hdev, "");

	if (!hdev_is_powered(hdev))
		return 0;

	if (!lmp_ext_inq_capable(hdev))
		return 0;

	if (!hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
		return 0;

	if (hci_dev_test_flag(hdev, HCI_SERVICE_CACHE))
		return 0;

	memset(&cp, 0, sizeof(cp));

	eir_create(hdev, cp.data);

	if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0)
		return 0;

	memcpy(hdev->eir, cp.data, sizeof(cp.data));

	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp,
				     HCI_CMD_TIMEOUT);
}

static u8 get_service_classes(struct hci_dev *hdev)
{
	struct bt_uuid *uuid;
	u8 val = 0;

	list_for_each_entry(uuid, &hdev->uuids, list)
		val |= uuid->svc_hint;

	return val;
}

int hci_update_class_sync(struct hci_dev *hdev)
{
	u8 cod[3];

	bt_dev_dbg(hdev, "");

	if (!hdev_is_powered(hdev))
		return 0;

	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
		return 0;

	if (hci_dev_test_flag(hdev, HCI_SERVICE_CACHE))
		return 0;

	cod[0] = hdev->minor_class;
	cod[1] = hdev->major_class;
	cod[2] = get_service_classes(hdev);

	if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
		cod[1] |= 0x20;

	if (memcmp(cod, hdev->dev_class, 3) == 0)
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_CLASS_OF_DEV,
				     sizeof(cod), cod, HCI_CMD_TIMEOUT);
}

static bool is_advertising_allowed(struct hci_dev *hdev, bool connectable)
{
	/* If there is no connection we are OK to advertise. */
	if (hci_conn_num(hdev, LE_LINK) == 0)
		return true;

	/* Check le_states if there is any connection in peripheral role. */
	if (hdev->conn_hash.le_num_peripheral > 0) {
		/* Peripheral connection state and non connectable mode
		 * bit 20.
		 */
		if (!connectable && !(hdev->le_states[2] & 0x10))
			return false;

		/* Peripheral connection state and connectable mode bit 38
		 * and scannable bit 21.
		 */
		if (connectable && (!(hdev->le_states[4] & 0x40) ||
				    !(hdev->le_states[2] & 0x20)))
			return false;
	}

	/* Check le_states if there is any connection in central role. */
	if (hci_conn_num(hdev, LE_LINK) != hdev->conn_hash.le_num_peripheral) {
		/* Central connection state and non connectable mode bit 18. */
		if (!connectable && !(hdev->le_states[2] & 0x02))
			return false;

		/* Central connection state and connectable mode bit 35 and
		 * scannable 19.
		 */
		if (connectable && (!(hdev->le_states[4] & 0x08) ||
				    !(hdev->le_states[2] & 0x08)))
			return false;
	}

	return true;
}

static bool adv_use_rpa(struct hci_dev *hdev, uint32_t flags)
{
	/* If privacy is not enabled don't use RPA */
	if (!hci_dev_test_flag(hdev, HCI_PRIVACY))
		return false;

	/* If basic privacy mode is enabled use RPA */
	if (!hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY))
		return true;

	/* If limited privacy mode is enabled don't use RPA if we're
	 * both discoverable and bondable.
	 */
	if ((flags & MGMT_ADV_FLAG_DISCOV) &&
	    hci_dev_test_flag(hdev, HCI_BONDABLE))
		return false;

	/* We're neither bondable nor discoverable in the limited
	 * privacy mode, therefore use RPA.
	 */
	return true;
}

static int hci_set_random_addr_sync(struct hci_dev *hdev, bdaddr_t *rpa)
{
	/* If we're advertising or initiating an LE connection we can't
	 * go ahead and change the random address at this time. This is
	 * because the eventual initiator address used for the
	 * subsequently created connection will be undefined (some
	 * controllers use the new address and others the one we had
	 * when the operation started).
	 *
	 * In this kind of scenario skip the update and let the random
	 * address be updated at the next cycle.
	 */
	if (hci_dev_test_flag(hdev, HCI_LE_ADV) ||
	    hci_lookup_le_connect(hdev)) {
		bt_dev_dbg(hdev, "Deferring random address update");
		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
		return 0;
	}

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_RANDOM_ADDR,
				     6, rpa, HCI_CMD_TIMEOUT);
}

int hci_update_random_address_sync(struct hci_dev *hdev, bool require_privacy,
				   bool rpa, u8 *own_addr_type)
{
	int err;

	/* If privacy is enabled use a resolvable private address. If
	 * current RPA has expired or there is something else than
	 * the current RPA in use, then generate a new one.
	 */
	if (rpa) {
		/* If Controller supports LL Privacy use own address type is
		 * 0x03
		 */
		if (use_ll_privacy(hdev))
			*own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED;
		else
			*own_addr_type = ADDR_LE_DEV_RANDOM;

		/* Check if RPA is valid */
		if (rpa_valid(hdev))
			return 0;

		err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
		if (err < 0) {
			bt_dev_err(hdev, "failed to generate new RPA");
			return err;
		}

		err = hci_set_random_addr_sync(hdev, &hdev->rpa);
		if (err)
			return err;

		return 0;
	}

	/* In case of required privacy without resolvable private address,
	 * use an non-resolvable private address. This is useful for active
	 * scanning and non-connectable advertising.
	 */
	if (require_privacy) {
		bdaddr_t nrpa;

		while (true) {
			/* The non-resolvable private address is generated
			 * from random six bytes with the two most significant
			 * bits cleared.
			 */
			get_random_bytes(&nrpa, 6);
			nrpa.b[5] &= 0x3f;

			/* The non-resolvable private address shall not be
			 * equal to the public address.
			 */
			if (bacmp(&hdev->bdaddr, &nrpa))
				break;
		}

		*own_addr_type = ADDR_LE_DEV_RANDOM;

		return hci_set_random_addr_sync(hdev, &nrpa);
	}

	/* If forcing static address is in use or there is no public
	 * address use the static address as random address (but skip
	 * the HCI command if the current random address is already the
	 * static one.
	 *
	 * In case BR/EDR has been disabled on a dual-mode controller
	 * and a static address has been configured, then use that
	 * address instead of the public BR/EDR address.
	 */
	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
	    (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
		*own_addr_type = ADDR_LE_DEV_RANDOM;
		if (bacmp(&hdev->static_addr, &hdev->random_addr))
			return hci_set_random_addr_sync(hdev,
							&hdev->static_addr);
		return 0;
	}

	/* Neither privacy nor static address is being used so use a
	 * public address.
	 */
	*own_addr_type = ADDR_LE_DEV_PUBLIC;

	return 0;
}

static int hci_disable_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
{
	struct hci_cp_le_set_ext_adv_enable *cp;
	struct hci_cp_ext_adv_set *set;
	u8 data[sizeof(*cp) + sizeof(*set) * 1];
	u8 size;

	/* If request specifies an instance that doesn't exist, fail */
	if (instance > 0) {
		struct adv_info *adv;

		adv = hci_find_adv_instance(hdev, instance);
		if (!adv)
			return -EINVAL;

		/* If not enabled there is nothing to do */
		if (!adv->enabled)
			return 0;
	}

	memset(data, 0, sizeof(data));

	cp = (void *)data;
	set = (void *)cp->data;

	/* Instance 0x00 indicates all advertising instances will be disabled */
	cp->num_of_sets = !!instance;
	cp->enable = 0x00;

	set->handle = instance;

	size = sizeof(*cp) + sizeof(*set) * cp->num_of_sets;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE,
				     size, data, HCI_CMD_TIMEOUT);
}

static int hci_set_adv_set_random_addr_sync(struct hci_dev *hdev, u8 instance,
					    bdaddr_t *random_addr)
{
	struct hci_cp_le_set_adv_set_rand_addr cp;
	int err;

	if (!instance) {
		/* Instance 0x00 doesn't have an adv_info, instead it uses
		 * hdev->random_addr to track its address so whenever it needs
		 * to be updated this also set the random address since
		 * hdev->random_addr is shared with scan state machine.
		 */
		err = hci_set_random_addr_sync(hdev, random_addr);
		if (err)
			return err;
	}

	memset(&cp, 0, sizeof(cp));

	cp.handle = instance;
	bacpy(&cp.bdaddr, random_addr);

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
{
	struct hci_cp_le_set_ext_adv_params cp;
	bool connectable;
	u32 flags;
	bdaddr_t random_addr;
	u8 own_addr_type;
	int err;
	struct adv_info *adv;
	bool secondary_adv;

	if (instance > 0) {
		adv = hci_find_adv_instance(hdev, instance);
		if (!adv)
			return -EINVAL;
	} else {
		adv = NULL;
	}

	/* Updating parameters of an active instance will return a
	 * Command Disallowed error, so we must first disable the
	 * instance if it is active.
	 */
	if (adv && !adv->pending) {
		err = hci_disable_ext_adv_instance_sync(hdev, instance);
		if (err)
			return err;
	}

	flags = hci_adv_instance_flags(hdev, instance);

	/* If the "connectable" instance flag was not set, then choose between
	 * ADV_IND and ADV_NONCONN_IND based on the global connectable setting.
	 */
	connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE) ||
		      mgmt_get_connectable(hdev);

	if (!is_advertising_allowed(hdev, connectable))
		return -EPERM;

	/* Set require_privacy to true only when non-connectable
	 * advertising is used. In that case it is fine to use a
	 * non-resolvable private address.
	 */
	err = hci_get_random_address(hdev, !connectable,
				     adv_use_rpa(hdev, flags), adv,
				     &own_addr_type, &random_addr);
	if (err < 0)
		return err;

	memset(&cp, 0, sizeof(cp));

	if (adv) {
		hci_cpu_to_le24(adv->min_interval, cp.min_interval);
		hci_cpu_to_le24(adv->max_interval, cp.max_interval);
		cp.tx_power = adv->tx_power;
	} else {
		hci_cpu_to_le24(hdev->le_adv_min_interval, cp.min_interval);
		hci_cpu_to_le24(hdev->le_adv_max_interval, cp.max_interval);
		cp.tx_power = HCI_ADV_TX_POWER_NO_PREFERENCE;
	}

	secondary_adv = (flags & MGMT_ADV_FLAG_SEC_MASK);

	if (connectable) {
		if (secondary_adv)
			cp.evt_properties = cpu_to_le16(LE_EXT_ADV_CONN_IND);
		else
			cp.evt_properties = cpu_to_le16(LE_LEGACY_ADV_IND);
	} else if (hci_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
			cp.evt_properties = cpu_to_le16(LE_LEGACY_ADV_SCAN_IND);
	} else {
		if (secondary_adv)
			cp.evt_properties = cpu_to_le16(LE_EXT_ADV_NON_CONN_IND);
		else
			cp.evt_properties = cpu_to_le16(LE_LEGACY_NONCONN_IND);
	}

	/* If Own_Address_Type equals 0x02 or 0x03, the Peer_Address parameter
	 * contains the peer’s Identity Address and the Peer_Address_Type
	 * parameter contains the peer’s Identity Type (i.e., 0x00 or 0x01).
	 * These parameters are used to locate the corresponding local IRK in
	 * the resolving list; this IRK is used to generate their own address
	 * used in the advertisement.
	 */
	if (own_addr_type == ADDR_LE_DEV_RANDOM_RESOLVED)
		hci_copy_identity_address(hdev, &cp.peer_addr,
					  &cp.peer_addr_type);

	cp.own_addr_type = own_addr_type;
	cp.channel_map = hdev->le_adv_channel_map;
	cp.handle = instance;

	if (flags & MGMT_ADV_FLAG_SEC_2M) {
		cp.primary_phy = HCI_ADV_PHY_1M;
		cp.secondary_phy = HCI_ADV_PHY_2M;
	} else if (flags & MGMT_ADV_FLAG_SEC_CODED) {
		cp.primary_phy = HCI_ADV_PHY_CODED;
		cp.secondary_phy = HCI_ADV_PHY_CODED;
	} else {
		/* In all other cases use 1M */
		cp.primary_phy = HCI_ADV_PHY_1M;
		cp.secondary_phy = HCI_ADV_PHY_1M;
	}

	err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS,
				    sizeof(cp), &cp, HCI_CMD_TIMEOUT);
	if (err)
		return err;

	if ((own_addr_type == ADDR_LE_DEV_RANDOM ||
	     own_addr_type == ADDR_LE_DEV_RANDOM_RESOLVED) &&
	    bacmp(&random_addr, BDADDR_ANY)) {
		/* Check if random address need to be updated */
		if (adv) {
			if (!bacmp(&random_addr, &adv->random_addr))
				return 0;
		} else {
			if (!bacmp(&random_addr, &hdev->random_addr))
				return 0;
		}

		return hci_set_adv_set_random_addr_sync(hdev, instance,
							&random_addr);
	}

	return 0;
}

static int hci_set_ext_scan_rsp_data_sync(struct hci_dev *hdev, u8 instance)
{
	struct {
		struct hci_cp_le_set_ext_scan_rsp_data cp;
		u8 data[HCI_MAX_EXT_AD_LENGTH];
	} pdu;
	u8 len;
	struct adv_info *adv = NULL;
	int err;

	memset(&pdu, 0, sizeof(pdu));

	if (instance) {
		adv = hci_find_adv_instance(hdev, instance);
		if (!adv || !adv->scan_rsp_changed)
			return 0;
	}

	len = eir_create_scan_rsp(hdev, instance, pdu.data);

	pdu.cp.handle = instance;
	pdu.cp.length = len;
	pdu.cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
	pdu.cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;

	err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_SCAN_RSP_DATA,
				    sizeof(pdu.cp) + len, &pdu.cp,
				    HCI_CMD_TIMEOUT);
	if (err)
		return err;

	if (adv) {
		adv->scan_rsp_changed = false;
	} else {
		memcpy(hdev->scan_rsp_data, pdu.data, len);
		hdev->scan_rsp_data_len = len;
	}

	return 0;
}

static int __hci_set_scan_rsp_data_sync(struct hci_dev *hdev, u8 instance)
{
	struct hci_cp_le_set_scan_rsp_data cp;
	u8 len;

	memset(&cp, 0, sizeof(cp));

	len = eir_create_scan_rsp(hdev, instance, cp.data);

	if (hdev->scan_rsp_data_len == len &&
	    !memcmp(cp.data, hdev->scan_rsp_data, len))
		return 0;

	memcpy(hdev->scan_rsp_data, cp.data, sizeof(cp.data));
	hdev->scan_rsp_data_len = len;

	cp.length = len;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_SCAN_RSP_DATA,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

int hci_update_scan_rsp_data_sync(struct hci_dev *hdev, u8 instance)
{
	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
		return 0;

	if (ext_adv_capable(hdev))
		return hci_set_ext_scan_rsp_data_sync(hdev, instance);

	return __hci_set_scan_rsp_data_sync(hdev, instance);
}

int hci_enable_ext_advertising_sync(struct hci_dev *hdev, u8 instance)
{
	struct hci_cp_le_set_ext_adv_enable *cp;
	struct hci_cp_ext_adv_set *set;
	u8 data[sizeof(*cp) + sizeof(*set) * 1];
	struct adv_info *adv;

	if (instance > 0) {
		adv = hci_find_adv_instance(hdev, instance);
		if (!adv)
			return -EINVAL;
		/* If already enabled there is nothing to do */
		if (adv->enabled)
			return 0;
	} else {
		adv = NULL;
	}

	cp = (void *)data;
	set = (void *)cp->data;

	memset(cp, 0, sizeof(*cp));

	cp->enable = 0x01;
	cp->num_of_sets = 0x01;

	memset(set, 0, sizeof(*set));

	set->handle = instance;

	/* Set duration per instance since controller is responsible for
	 * scheduling it.
	 */
	if (adv && adv->timeout) {
		u16 duration = adv->timeout * MSEC_PER_SEC;

		/* Time = N * 10 ms */
		set->duration = cpu_to_le16(duration / 10);
	}

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE,
				     sizeof(*cp) +
				     sizeof(*set) * cp->num_of_sets,
				     data, HCI_CMD_TIMEOUT);
}

int hci_start_ext_adv_sync(struct hci_dev *hdev, u8 instance)
{
	int err;

	err = hci_setup_ext_adv_instance_sync(hdev, instance);
	if (err)
		return err;

	err = hci_set_ext_scan_rsp_data_sync(hdev, instance);
	if (err)
		return err;

	return hci_enable_ext_advertising_sync(hdev, instance);
}

int hci_disable_per_advertising_sync(struct hci_dev *hdev, u8 instance)
{
	struct hci_cp_le_set_per_adv_enable cp;
	struct adv_info *adv = NULL;

	/* If periodic advertising already disabled there is nothing to do. */
	adv = hci_find_adv_instance(hdev, instance);
	if (!adv || !adv->periodic || !adv->enabled)
		return 0;

	memset(&cp, 0, sizeof(cp));

	cp.enable = 0x00;
	cp.handle = instance;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_PER_ADV_ENABLE,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_set_per_adv_params_sync(struct hci_dev *hdev, u8 instance,
				       u16 min_interval, u16 max_interval)
{
	struct hci_cp_le_set_per_adv_params cp;

	memset(&cp, 0, sizeof(cp));

	if (!min_interval)
		min_interval = DISCOV_LE_PER_ADV_INT_MIN;

	if (!max_interval)
		max_interval = DISCOV_LE_PER_ADV_INT_MAX;

	cp.handle = instance;
	cp.min_interval = cpu_to_le16(min_interval);
	cp.max_interval = cpu_to_le16(max_interval);
	cp.periodic_properties = 0x0000;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_PER_ADV_PARAMS,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_set_per_adv_data_sync(struct hci_dev *hdev, u8 instance)
{
	struct {
		struct hci_cp_le_set_per_adv_data cp;
		u8 data[HCI_MAX_PER_AD_LENGTH];
	} pdu;
	u8 len;

	memset(&pdu, 0, sizeof(pdu));

	if (instance) {
		struct adv_info *adv = hci_find_adv_instance(hdev, instance);

		if (!adv || !adv->periodic)
			return 0;
	}

	len = eir_create_per_adv_data(hdev, instance, pdu.data);

	pdu.cp.length = len;
	pdu.cp.handle = instance;
	pdu.cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_PER_ADV_DATA,
				     sizeof(pdu.cp) + len, &pdu,
				     HCI_CMD_TIMEOUT);
}

static int hci_enable_per_advertising_sync(struct hci_dev *hdev, u8 instance)
{
	struct hci_cp_le_set_per_adv_enable cp;
	struct adv_info *adv = NULL;

	/* If periodic advertising already enabled there is nothing to do. */
	adv = hci_find_adv_instance(hdev, instance);
	if (adv && adv->periodic && adv->enabled)
		return 0;

	memset(&cp, 0, sizeof(cp));

	cp.enable = 0x01;
	cp.handle = instance;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_PER_ADV_ENABLE,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

/* Checks if periodic advertising data contains a Basic Announcement and if it
 * does generates a Broadcast ID and add Broadcast Announcement.
 */
static int hci_adv_bcast_annoucement(struct hci_dev *hdev, struct adv_info *adv)
{
	u8 bid[3];
	u8 ad[4 + 3];

	/* Skip if NULL adv as instance 0x00 is used for general purpose
	 * advertising so it cannot used for the likes of Broadcast Announcement
	 * as it can be overwritten at any point.
	 */
	if (!adv)
		return 0;

	/* Check if PA data doesn't contains a Basic Audio Announcement then
	 * there is nothing to do.
	 */
	if (!eir_get_service_data(adv->per_adv_data, adv->per_adv_data_len,
				  0x1851, NULL))
		return 0;

	/* Check if advertising data already has a Broadcast Announcement since
	 * the process may want to control the Broadcast ID directly and in that
	 * case the kernel shall no interfere.
	 */
	if (eir_get_service_data(adv->adv_data, adv->adv_data_len, 0x1852,
				 NULL))
		return 0;

	/* Generate Broadcast ID */
	get_random_bytes(bid, sizeof(bid));
	eir_append_service_data(ad, 0, 0x1852, bid, sizeof(bid));
	hci_set_adv_instance_data(hdev, adv->instance, sizeof(ad), ad, 0, NULL);

	return hci_update_adv_data_sync(hdev, adv->instance);
}

int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 data_len,
			   u8 *data, u32 flags, u16 min_interval,
			   u16 max_interval, u16 sync_interval)
{
	struct adv_info *adv = NULL;
	int err;
	bool added = false;

	hci_disable_per_advertising_sync(hdev, instance);

	if (instance) {
		adv = hci_find_adv_instance(hdev, instance);
		/* Create an instance if that could not be found */
		if (!adv) {
			adv = hci_add_per_instance(hdev, instance, flags,
						   data_len, data,
						   sync_interval,
						   sync_interval);
			if (IS_ERR(adv))
				return PTR_ERR(adv);
			adv->pending = false;
			added = true;
		}
	}

	/* Start advertising */
	err = hci_start_ext_adv_sync(hdev, instance);
	if (err < 0)
		goto fail;

	err = hci_adv_bcast_annoucement(hdev, adv);
	if (err < 0)
		goto fail;

	err = hci_set_per_adv_params_sync(hdev, instance, min_interval,
					  max_interval);
	if (err < 0)
		goto fail;

	err = hci_set_per_adv_data_sync(hdev, instance);
	if (err < 0)
		goto fail;

	err = hci_enable_per_advertising_sync(hdev, instance);
	if (err < 0)
		goto fail;

	return 0;

fail:
	if (added)
		hci_remove_adv_instance(hdev, instance);

	return err;
}

static int hci_start_adv_sync(struct hci_dev *hdev, u8 instance)
{
	int err;

	if (ext_adv_capable(hdev))
		return hci_start_ext_adv_sync(hdev, instance);

	err = hci_update_adv_data_sync(hdev, instance);
	if (err)
		return err;

	err = hci_update_scan_rsp_data_sync(hdev, instance);
	if (err)
		return err;

	return hci_enable_advertising_sync(hdev);
}

int hci_enable_advertising_sync(struct hci_dev *hdev)
{
	struct adv_info *adv_instance;
	struct hci_cp_le_set_adv_param cp;
	u8 own_addr_type, enable = 0x01;
	bool connectable;
	u16 adv_min_interval, adv_max_interval;
	u32 flags;
	u8 status;

	if (ext_adv_capable(hdev))
		return hci_enable_ext_advertising_sync(hdev,
						       hdev->cur_adv_instance);

	flags = hci_adv_instance_flags(hdev, hdev->cur_adv_instance);
	adv_instance = hci_find_adv_instance(hdev, hdev->cur_adv_instance);

	/* If the "connectable" instance flag was not set, then choose between
	 * ADV_IND and ADV_NONCONN_IND based on the global connectable setting.
	 */
	connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE) ||
		      mgmt_get_connectable(hdev);

	if (!is_advertising_allowed(hdev, connectable))
		return -EINVAL;

	status = hci_disable_advertising_sync(hdev);
	if (status)
		return status;

	/* Clear the HCI_LE_ADV bit temporarily so that the
	 * hci_update_random_address knows that it's safe to go ahead
	 * and write a new random address. The flag will be set back on
	 * as soon as the SET_ADV_ENABLE HCI command completes.
	 */
	hci_dev_clear_flag(hdev, HCI_LE_ADV);

	/* Set require_privacy to true only when non-connectable
	 * advertising is used. In that case it is fine to use a
	 * non-resolvable private address.
	 */
	status = hci_update_random_address_sync(hdev, !connectable,
						adv_use_rpa(hdev, flags),
						&own_addr_type);
	if (status)
		return status;

	memset(&cp, 0, sizeof(cp));

	if (adv_instance) {
		adv_min_interval = adv_instance->min_interval;
		adv_max_interval = adv_instance->max_interval;
	} else {
		adv_min_interval = hdev->le_adv_min_interval;
		adv_max_interval = hdev->le_adv_max_interval;
	}

	if (connectable) {
		cp.type = LE_ADV_IND;
	} else {
		if (hci_adv_instance_is_scannable(hdev, hdev->cur_adv_instance))
			cp.type = LE_ADV_SCAN_IND;
		else
			cp.type = LE_ADV_NONCONN_IND;

		if (!hci_dev_test_flag(hdev, HCI_DISCOVERABLE) ||
		    hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE)) {
			adv_min_interval = DISCOV_LE_FAST_ADV_INT_MIN;
			adv_max_interval = DISCOV_LE_FAST_ADV_INT_MAX;
		}
	}

	cp.min_interval = cpu_to_le16(adv_min_interval);
	cp.max_interval = cpu_to_le16(adv_max_interval);
	cp.own_address_type = own_addr_type;
	cp.channel_map = hdev->le_adv_channel_map;

	status = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_PARAM,
				       sizeof(cp), &cp, HCI_CMD_TIMEOUT);
	if (status)
		return status;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_ENABLE,
				     sizeof(enable), &enable, HCI_CMD_TIMEOUT);
}

static int enable_advertising_sync(struct hci_dev *hdev, void *data)
{
	return hci_enable_advertising_sync(hdev);
}

int hci_enable_advertising(struct hci_dev *hdev)
{
	if (!hci_dev_test_flag(hdev, HCI_ADVERTISING) &&
	    list_empty(&hdev->adv_instances))
		return 0;

	return hci_cmd_sync_queue(hdev, enable_advertising_sync, NULL, NULL);
}

int hci_remove_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance,
				     struct sock *sk)
{
	int err;

	if (!ext_adv_capable(hdev))
		return 0;

	err = hci_disable_ext_adv_instance_sync(hdev, instance);
	if (err)
		return err;

	/* If request specifies an instance that doesn't exist, fail */
	if (instance > 0 && !hci_find_adv_instance(hdev, instance))
		return -EINVAL;

	return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_REMOVE_ADV_SET,
					sizeof(instance), &instance, 0,
					HCI_CMD_TIMEOUT, sk);
}

static int remove_ext_adv_sync(struct hci_dev *hdev, void *data)
{
	struct adv_info *adv = data;
	u8 instance = 0;

	if (adv)
		instance = adv->instance;

	return hci_remove_ext_adv_instance_sync(hdev, instance, NULL);
}

int hci_remove_ext_adv_instance(struct hci_dev *hdev, u8 instance)
{
	struct adv_info *adv = NULL;

	if (instance) {
		adv = hci_find_adv_instance(hdev, instance);
		if (!adv)
			return -EINVAL;
	}

	return hci_cmd_sync_queue(hdev, remove_ext_adv_sync, adv, NULL);
}

int hci_le_terminate_big_sync(struct hci_dev *hdev, u8 handle, u8 reason)
{
	struct hci_cp_le_term_big cp;

	memset(&cp, 0, sizeof(cp));
	cp.handle = handle;
	cp.reason = reason;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_TERM_BIG,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_set_ext_adv_data_sync(struct hci_dev *hdev, u8 instance)
{
	struct {
		struct hci_cp_le_set_ext_adv_data cp;
		u8 data[HCI_MAX_EXT_AD_LENGTH];
	} pdu;
	u8 len;
	struct adv_info *adv = NULL;
	int err;

	memset(&pdu, 0, sizeof(pdu));

	if (instance) {
		adv = hci_find_adv_instance(hdev, instance);
		if (!adv || !adv->adv_data_changed)
			return 0;
	}

	len = eir_create_adv_data(hdev, instance, pdu.data);

	pdu.cp.length = len;
	pdu.cp.handle = instance;
	pdu.cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
	pdu.cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;

	err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_DATA,
				    sizeof(pdu.cp) + len, &pdu.cp,
				    HCI_CMD_TIMEOUT);
	if (err)
		return err;

	/* Update data if the command succeed */
	if (adv) {
		adv->adv_data_changed = false;
	} else {
		memcpy(hdev->adv_data, pdu.data, len);
		hdev->adv_data_len = len;
	}

	return 0;
}

static int hci_set_adv_data_sync(struct hci_dev *hdev, u8 instance)
{
	struct hci_cp_le_set_adv_data cp;
	u8 len;

	memset(&cp, 0, sizeof(cp));

	len = eir_create_adv_data(hdev, instance, cp.data);

	/* There's nothing to do if the data hasn't changed */
	if (hdev->adv_data_len == len &&
	    memcmp(cp.data, hdev->adv_data, len) == 0)
		return 0;

	memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
	hdev->adv_data_len = len;

	cp.length = len;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_DATA,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

int hci_update_adv_data_sync(struct hci_dev *hdev, u8 instance)
{
	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
		return 0;

	if (ext_adv_capable(hdev))
		return hci_set_ext_adv_data_sync(hdev, instance);

	return hci_set_adv_data_sync(hdev, instance);
}

int hci_schedule_adv_instance_sync(struct hci_dev *hdev, u8 instance,
				   bool force)
{
	struct adv_info *adv = NULL;
	u16 timeout;

	if (hci_dev_test_flag(hdev, HCI_ADVERTISING) && !ext_adv_capable(hdev))
		return -EPERM;

	if (hdev->adv_instance_timeout)
		return -EBUSY;

	adv = hci_find_adv_instance(hdev, instance);
	if (!adv)
		return -ENOENT;

	/* A zero timeout means unlimited advertising. As long as there is
	 * only one instance, duration should be ignored. We still set a timeout
	 * in case further instances are being added later on.
	 *
	 * If the remaining lifetime of the instance is more than the duration
	 * then the timeout corresponds to the duration, otherwise it will be
	 * reduced to the remaining instance lifetime.
	 */
	if (adv->timeout == 0 || adv->duration <= adv->remaining_time)
		timeout = adv->duration;
	else
		timeout = adv->remaining_time;

	/* The remaining time is being reduced unless the instance is being
	 * advertised without time limit.
	 */
	if (adv->timeout)
		adv->remaining_time = adv->remaining_time - timeout;

	/* Only use work for scheduling instances with legacy advertising */
	if (!ext_adv_capable(hdev)) {
		hdev->adv_instance_timeout = timeout;
		queue_delayed_work(hdev->req_workqueue,
				   &hdev->adv_instance_expire,
				   msecs_to_jiffies(timeout * 1000));
	}

	/* If we're just re-scheduling the same instance again then do not
	 * execute any HCI commands. This happens when a single instance is
	 * being advertised.
	 */
	if (!force && hdev->cur_adv_instance == instance &&
	    hci_dev_test_flag(hdev, HCI_LE_ADV))
		return 0;

	hdev->cur_adv_instance = instance;

	return hci_start_adv_sync(hdev, instance);
}

static int hci_clear_adv_sets_sync(struct hci_dev *hdev, struct sock *sk)
{
	int err;

	if (!ext_adv_capable(hdev))
		return 0;

	/* Disable instance 0x00 to disable all instances */
	err = hci_disable_ext_adv_instance_sync(hdev, 0x00);
	if (err)
		return err;

	return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_CLEAR_ADV_SETS,
					0, NULL, 0, HCI_CMD_TIMEOUT, sk);
}

static int hci_clear_adv_sync(struct hci_dev *hdev, struct sock *sk, bool force)
{
	struct adv_info *adv, *n;
	int err = 0;

	if (ext_adv_capable(hdev))
		/* Remove all existing sets */
		err = hci_clear_adv_sets_sync(hdev, sk);
	if (ext_adv_capable(hdev))
		return err;

	/* This is safe as long as there is no command send while the lock is
	 * held.
	 */
	hci_dev_lock(hdev);

	/* Cleanup non-ext instances */
	list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) {
		u8 instance = adv->instance;
		int err;

		if (!(force || adv->timeout))
			continue;

		err = hci_remove_adv_instance(hdev, instance);
		if (!err)
			mgmt_advertising_removed(sk, hdev, instance);
	}

	hci_dev_unlock(hdev);

	return 0;
}

static int hci_remove_adv_sync(struct hci_dev *hdev, u8 instance,
			       struct sock *sk)
{
	int err = 0;

	/* If we use extended advertising, instance has to be removed first. */
	if (ext_adv_capable(hdev))
		err = hci_remove_ext_adv_instance_sync(hdev, instance, sk);
	if (ext_adv_capable(hdev))
		return err;

	/* This is safe as long as there is no command send while the lock is
	 * held.
	 */
	hci_dev_lock(hdev);

	err = hci_remove_adv_instance(hdev, instance);
	if (!err)
		mgmt_advertising_removed(sk, hdev, instance);

	hci_dev_unlock(hdev);

	return err;
}

/* For a single instance:
 * - force == true: The instance will be removed even when its remaining
 *   lifetime is not zero.
 * - force == false: the instance will be deactivated but kept stored unless
 *   the remaining lifetime is zero.
 *
 * For instance == 0x00:
 * - force == true: All instances will be removed regardless of their timeout
 *   setting.
 * - force == false: Only instances that have a timeout will be removed.
 */
int hci_remove_advertising_sync(struct hci_dev *hdev, struct sock *sk,
				u8 instance, bool force)
{
	struct adv_info *next = NULL;
	int err;

	/* Cancel any timeout concerning the removed instance(s). */
	if (!instance || hdev->cur_adv_instance == instance)
		cancel_adv_timeout(hdev);

	/* Get the next instance to advertise BEFORE we remove
	 * the current one. This can be the same instance again
	 * if there is only one instance.
	 */
	if (hdev->cur_adv_instance == instance)
		next = hci_get_next_instance(hdev, instance);

	if (!instance) {
		err = hci_clear_adv_sync(hdev, sk, force);
		if (err)
			return err;
	} else {
		struct adv_info *adv = hci_find_adv_instance(hdev, instance);

		if (force || (adv && adv->timeout && !adv->remaining_time)) {
			/* Don't advertise a removed instance. */
			if (next && next->instance == instance)
				next = NULL;

			err = hci_remove_adv_sync(hdev, instance, sk);
			if (err)
				return err;
		}
	}

	if (!hdev_is_powered(hdev) || hci_dev_test_flag(hdev, HCI_ADVERTISING))
		return 0;

	if (next && !ext_adv_capable(hdev))
		hci_schedule_adv_instance_sync(hdev, next->instance, false);

	return 0;
}

int hci_read_rssi_sync(struct hci_dev *hdev, __le16 handle)
{
	struct hci_cp_read_rssi cp;

	cp.handle = handle;
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_RSSI,
					sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

int hci_read_clock_sync(struct hci_dev *hdev, struct hci_cp_read_clock *cp)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_CLOCK,
					sizeof(*cp), cp, HCI_CMD_TIMEOUT);
}

int hci_read_tx_power_sync(struct hci_dev *hdev, __le16 handle, u8 type)
{
	struct hci_cp_read_tx_power cp;

	cp.handle = handle;
	cp.type = type;
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_TX_POWER,
					sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

int hci_disable_advertising_sync(struct hci_dev *hdev)
{
	u8 enable = 0x00;
	int err = 0;

	/* If controller is not advertising we are done. */
	if (!hci_dev_test_flag(hdev, HCI_LE_ADV))
		return 0;

	if (ext_adv_capable(hdev))
		err = hci_disable_ext_adv_instance_sync(hdev, 0x00);
	if (ext_adv_capable(hdev))
		return err;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_ENABLE,
				     sizeof(enable), &enable, HCI_CMD_TIMEOUT);
}

static int hci_le_set_ext_scan_enable_sync(struct hci_dev *hdev, u8 val,
					   u8 filter_dup)
{
	struct hci_cp_le_set_ext_scan_enable cp;

	memset(&cp, 0, sizeof(cp));
	cp.enable = val;

	if (hci_dev_test_flag(hdev, HCI_MESH))
		cp.filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
	else
		cp.filter_dup = filter_dup;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_SCAN_ENABLE,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_le_set_scan_enable_sync(struct hci_dev *hdev, u8 val,
				       u8 filter_dup)
{
	struct hci_cp_le_set_scan_enable cp;

	if (use_ext_scan(hdev))
		return hci_le_set_ext_scan_enable_sync(hdev, val, filter_dup);

	memset(&cp, 0, sizeof(cp));
	cp.enable = val;

	if (val && hci_dev_test_flag(hdev, HCI_MESH))
		cp.filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
	else
		cp.filter_dup = filter_dup;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_SCAN_ENABLE,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_le_set_addr_resolution_enable_sync(struct hci_dev *hdev, u8 val)
{
	if (!use_ll_privacy(hdev))
		return 0;

	/* If controller is not/already resolving we are done. */
	if (val == hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE,
				     sizeof(val), &val, HCI_CMD_TIMEOUT);
}

static int hci_scan_disable_sync(struct hci_dev *hdev)
{
	int err;

	/* If controller is not scanning we are done. */
	if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
		return 0;

	if (hdev->scanning_paused) {
		bt_dev_dbg(hdev, "Scanning is paused for suspend");
		return 0;
	}

	err = hci_le_set_scan_enable_sync(hdev, LE_SCAN_DISABLE, 0x00);
	if (err) {
		bt_dev_err(hdev, "Unable to disable scanning: %d", err);
		return err;
	}

	return err;
}

static bool scan_use_rpa(struct hci_dev *hdev)
{
	return hci_dev_test_flag(hdev, HCI_PRIVACY);
}

static void hci_start_interleave_scan(struct hci_dev *hdev)
{
	hdev->interleave_scan_state = INTERLEAVE_SCAN_NO_FILTER;
	queue_delayed_work(hdev->req_workqueue,
			   &hdev->interleave_scan, 0);
}

static bool is_interleave_scanning(struct hci_dev *hdev)
{
	return hdev->interleave_scan_state != INTERLEAVE_SCAN_NONE;
}

static void cancel_interleave_scan(struct hci_dev *hdev)
{
	bt_dev_dbg(hdev, "cancelling interleave scan");

	cancel_delayed_work_sync(&hdev->interleave_scan);

	hdev->interleave_scan_state = INTERLEAVE_SCAN_NONE;
}

/* Return true if interleave_scan wasn't started until exiting this function,
 * otherwise, return false
 */
static bool hci_update_interleaved_scan_sync(struct hci_dev *hdev)
{
	/* Do interleaved scan only if all of the following are true:
	 * - There is at least one ADV monitor
	 * - At least one pending LE connection or one device to be scanned for
	 * - Monitor offloading is not supported
	 * If so, we should alternate between allowlist scan and one without
	 * any filters to save power.
	 */
	bool use_interleaving = hci_is_adv_monitoring(hdev) &&
				!(list_empty(&hdev->pend_le_conns) &&
				  list_empty(&hdev->pend_le_reports)) &&
				hci_get_adv_monitor_offload_ext(hdev) ==
				    HCI_ADV_MONITOR_EXT_NONE;
	bool is_interleaving = is_interleave_scanning(hdev);

	if (use_interleaving && !is_interleaving) {
		hci_start_interleave_scan(hdev);
		bt_dev_dbg(hdev, "starting interleave scan");
		return true;
	}

	if (!use_interleaving && is_interleaving)
		cancel_interleave_scan(hdev);

	return false;
}

/* Removes connection to resolve list if needed.*/
static int hci_le_del_resolve_list_sync(struct hci_dev *hdev,
					bdaddr_t *bdaddr, u8 bdaddr_type)
{
	struct hci_cp_le_del_from_resolv_list cp;
	struct bdaddr_list_with_irk *entry;

	if (!use_ll_privacy(hdev))
		return 0;

	/* Check if the IRK has been programmed */
	entry = hci_bdaddr_list_lookup_with_irk(&hdev->le_resolv_list, bdaddr,
						bdaddr_type);
	if (!entry)
		return 0;

	cp.bdaddr_type = bdaddr_type;
	bacpy(&cp.bdaddr, bdaddr);

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_DEL_FROM_RESOLV_LIST,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_le_del_accept_list_sync(struct hci_dev *hdev,
				       bdaddr_t *bdaddr, u8 bdaddr_type)
{
	struct hci_cp_le_del_from_accept_list cp;
	int err;

	/* Check if device is on accept list before removing it */
	if (!hci_bdaddr_list_lookup(&hdev->le_accept_list, bdaddr, bdaddr_type))
		return 0;

	cp.bdaddr_type = bdaddr_type;
	bacpy(&cp.bdaddr, bdaddr);

	/* Ignore errors when removing from resolving list as that is likely
	 * that the device was never added.
	 */
	hci_le_del_resolve_list_sync(hdev, &cp.bdaddr, cp.bdaddr_type);

	err = __hci_cmd_sync_status(hdev, HCI_OP_LE_DEL_FROM_ACCEPT_LIST,
				    sizeof(cp), &cp, HCI_CMD_TIMEOUT);
	if (err) {
		bt_dev_err(hdev, "Unable to remove from allow list: %d", err);
		return err;
	}

	bt_dev_dbg(hdev, "Remove %pMR (0x%x) from allow list", &cp.bdaddr,
		   cp.bdaddr_type);

	return 0;
}

struct conn_params {
	bdaddr_t addr;
	u8 addr_type;
	hci_conn_flags_t flags;
	u8 privacy_mode;
};

/* Adds connection to resolve list if needed.
 * Setting params to NULL programs local hdev->irk
 */
static int hci_le_add_resolve_list_sync(struct hci_dev *hdev,
					struct conn_params *params)
{
	struct hci_cp_le_add_to_resolv_list cp;
	struct smp_irk *irk;
	struct bdaddr_list_with_irk *entry;
	struct hci_conn_params *p;

	if (!use_ll_privacy(hdev))
		return 0;

	/* Attempt to program local identity address, type and irk if params is
	 * NULL.
	 */
	if (!params) {
		if (!hci_dev_test_flag(hdev, HCI_PRIVACY))
			return 0;

		hci_copy_identity_address(hdev, &cp.bdaddr, &cp.bdaddr_type);
		memcpy(cp.peer_irk, hdev->irk, 16);
		goto done;
	}

	irk = hci_find_irk_by_addr(hdev, &params->addr, params->addr_type);
	if (!irk)
		return 0;

	/* Check if the IK has _not_ been programmed yet. */
	entry = hci_bdaddr_list_lookup_with_irk(&hdev->le_resolv_list,
						&params->addr,
						params->addr_type);
	if (entry)
		return 0;

	cp.bdaddr_type = params->addr_type;
	bacpy(&cp.bdaddr, &params->addr);
	memcpy(cp.peer_irk, irk->val, 16);

	/* Default privacy mode is always Network */
	params->privacy_mode = HCI_NETWORK_PRIVACY;

	rcu_read_lock();
	p = hci_pend_le_action_lookup(&hdev->pend_le_conns,
				      &params->addr, params->addr_type);
	if (!p)
		p = hci_pend_le_action_lookup(&hdev->pend_le_reports,
					      &params->addr, params->addr_type);
	if (p)
		WRITE_ONCE(p->privacy_mode, HCI_NETWORK_PRIVACY);
	rcu_read_unlock();

done:
	if (hci_dev_test_flag(hdev, HCI_PRIVACY))
		memcpy(cp.local_irk, hdev->irk, 16);
	else
		memset(cp.local_irk, 0, 16);

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_ADD_TO_RESOLV_LIST,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

/* Set Device Privacy Mode. */
static int hci_le_set_privacy_mode_sync(struct hci_dev *hdev,
					struct conn_params *params)
{
	struct hci_cp_le_set_privacy_mode cp;
	struct smp_irk *irk;

	/* If device privacy mode has already been set there is nothing to do */
	if (params->privacy_mode == HCI_DEVICE_PRIVACY)
		return 0;

	/* Check if HCI_CONN_FLAG_DEVICE_PRIVACY has been set as it also
	 * indicates that LL Privacy has been enabled and
	 * HCI_OP_LE_SET_PRIVACY_MODE is supported.
	 */
	if (!(params->flags & HCI_CONN_FLAG_DEVICE_PRIVACY))
		return 0;

	irk = hci_find_irk_by_addr(hdev, &params->addr, params->addr_type);
	if (!irk)
		return 0;

	memset(&cp, 0, sizeof(cp));
	cp.bdaddr_type = irk->addr_type;
	bacpy(&cp.bdaddr, &irk->bdaddr);
	cp.mode = HCI_DEVICE_PRIVACY;

	/* Note: params->privacy_mode is not updated since it is a copy */

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_PRIVACY_MODE,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

/* Adds connection to allow list if needed, if the device uses RPA (has IRK)
 * this attempts to program the device in the resolving list as well and
 * properly set the privacy mode.
 */
static int hci_le_add_accept_list_sync(struct hci_dev *hdev,
				       struct conn_params *params,
				       u8 *num_entries)
{
	struct hci_cp_le_add_to_accept_list cp;
	int err;

	/* During suspend, only wakeable devices can be in acceptlist */
	if (hdev->suspended &&
	    !(params->flags & HCI_CONN_FLAG_REMOTE_WAKEUP)) {
		hci_le_del_accept_list_sync(hdev, &params->addr,
					    params->addr_type);
		return 0;
	}

	/* Select filter policy to accept all advertising */
	if (*num_entries >= hdev->le_accept_list_size)
		return -ENOSPC;

	/* Accept list can not be used with RPAs */
	if (!use_ll_privacy(hdev) &&
	    hci_find_irk_by_addr(hdev, &params->addr, params->addr_type))
		return -EINVAL;

	/* Attempt to program the device in the resolving list first to avoid
	 * having to rollback in case it fails since the resolving list is
	 * dynamic it can probably be smaller than the accept list.
	 */
	err = hci_le_add_resolve_list_sync(hdev, params);
	if (err) {
		bt_dev_err(hdev, "Unable to add to resolve list: %d", err);
		return err;
	}

	/* Set Privacy Mode */
	err = hci_le_set_privacy_mode_sync(hdev, params);
	if (err) {
		bt_dev_err(hdev, "Unable to set privacy mode: %d", err);
		return err;
	}

	/* Check if already in accept list */
	if (hci_bdaddr_list_lookup(&hdev->le_accept_list, &params->addr,
				   params->addr_type))
		return 0;

	*num_entries += 1;
	cp.bdaddr_type = params->addr_type;
	bacpy(&cp.bdaddr, &params->addr);

	err = __hci_cmd_sync_status(hdev, HCI_OP_LE_ADD_TO_ACCEPT_LIST,
				    sizeof(cp), &cp, HCI_CMD_TIMEOUT);
	if (err) {
		bt_dev_err(hdev, "Unable to add to allow list: %d", err);
		/* Rollback the device from the resolving list */
		hci_le_del_resolve_list_sync(hdev, &cp.bdaddr, cp.bdaddr_type);
		return err;
	}

	bt_dev_dbg(hdev, "Add %pMR (0x%x) to allow list", &cp.bdaddr,
		   cp.bdaddr_type);

	return 0;
}

/* This function disables/pause all advertising instances */
static int hci_pause_advertising_sync(struct hci_dev *hdev)
{
	int err;
	int old_state;

	/* If already been paused there is nothing to do. */
	if (hdev->advertising_paused)
		return 0;

	bt_dev_dbg(hdev, "Pausing directed advertising");

	/* Stop directed advertising */
	old_state = hci_dev_test_flag(hdev, HCI_ADVERTISING);
	if (old_state) {
		/* When discoverable timeout triggers, then just make sure
		 * the limited discoverable flag is cleared. Even in the case
		 * of a timeout triggered from general discoverable, it is
		 * safe to unconditionally clear the flag.
		 */
		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
		hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
		hdev->discov_timeout = 0;
	}

	bt_dev_dbg(hdev, "Pausing advertising instances");

	/* Call to disable any advertisements active on the controller.
	 * This will succeed even if no advertisements are configured.
	 */
	err = hci_disable_advertising_sync(hdev);
	if (err)
		return err;

	/* If we are using software rotation, pause the loop */
	if (!ext_adv_capable(hdev))
		cancel_adv_timeout(hdev);

	hdev->advertising_paused = true;
	hdev->advertising_old_state = old_state;

	return 0;
}

/* This function enables all user advertising instances */
static int hci_resume_advertising_sync(struct hci_dev *hdev)
{
	struct adv_info *adv, *tmp;
	int err;

	/* If advertising has not been paused there is nothing  to do. */
	if (!hdev->advertising_paused)
		return 0;

	/* Resume directed advertising */
	hdev->advertising_paused = false;
	if (hdev->advertising_old_state) {
		hci_dev_set_flag(hdev, HCI_ADVERTISING);
		hdev->advertising_old_state = 0;
	}

	bt_dev_dbg(hdev, "Resuming advertising instances");

	if (ext_adv_capable(hdev)) {
		/* Call for each tracked instance to be re-enabled */
		list_for_each_entry_safe(adv, tmp, &hdev->adv_instances, list) {
			err = hci_enable_ext_advertising_sync(hdev,
							      adv->instance);
			if (!err)
				continue;

			/* If the instance cannot be resumed remove it */
			hci_remove_ext_adv_instance_sync(hdev, adv->instance,
							 NULL);
		}
	} else {
		/* Schedule for most recent instance to be restarted and begin
		 * the software rotation loop
		 */
		err = hci_schedule_adv_instance_sync(hdev,
						     hdev->cur_adv_instance,
						     true);
	}

	hdev->advertising_paused = false;

	return err;
}

static int hci_pause_addr_resolution(struct hci_dev *hdev)
{
	int err;

	if (!use_ll_privacy(hdev))
		return 0;

	if (!hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION))
		return 0;

	/* Cannot disable addr resolution if scanning is enabled or
	 * when initiating an LE connection.
	 */
	if (hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
	    hci_lookup_le_connect(hdev)) {
		bt_dev_err(hdev, "Command not allowed when scan/LE connect");
		return -EPERM;
	}

	/* Cannot disable addr resolution if advertising is enabled. */
	err = hci_pause_advertising_sync(hdev);
	if (err) {
		bt_dev_err(hdev, "Pause advertising failed: %d", err);
		return err;
	}

	err = hci_le_set_addr_resolution_enable_sync(hdev, 0x00);
	if (err)
		bt_dev_err(hdev, "Unable to disable Address Resolution: %d",
			   err);

	/* Return if address resolution is disabled and RPA is not used. */
	if (!err && scan_use_rpa(hdev))
		return 0;

	hci_resume_advertising_sync(hdev);
	return err;
}

struct sk_buff *hci_read_local_oob_data_sync(struct hci_dev *hdev,
					     bool extended, struct sock *sk)
{
	u16 opcode = extended ? HCI_OP_READ_LOCAL_OOB_EXT_DATA :
					HCI_OP_READ_LOCAL_OOB_DATA;

	return __hci_cmd_sync_sk(hdev, opcode, 0, NULL, 0, HCI_CMD_TIMEOUT, sk);
}

static struct conn_params *conn_params_copy(struct list_head *list, size_t *n)
{
	struct hci_conn_params *params;
	struct conn_params *p;
	size_t i;

	rcu_read_lock();

	i = 0;
	list_for_each_entry_rcu(params, list, action)
		++i;
	*n = i;

	rcu_read_unlock();

	p = kvcalloc(*n, sizeof(struct conn_params), GFP_KERNEL);
	if (!p)
		return NULL;

	rcu_read_lock();

	i = 0;
	list_for_each_entry_rcu(params, list, action) {
		/* Racing adds are handled in next scan update */
		if (i >= *n)
			break;

		/* No hdev->lock, but: addr, addr_type are immutable.
		 * privacy_mode is only written by us or in
		 * hci_cc_le_set_privacy_mode that we wait for.
		 * We should be idempotent so MGMT updating flags
		 * while we are processing is OK.
		 */
		bacpy(&p[i].addr, &params->addr);
		p[i].addr_type = params->addr_type;
		p[i].flags = READ_ONCE(params->flags);
		p[i].privacy_mode = READ_ONCE(params->privacy_mode);
		++i;
	}

	rcu_read_unlock();

	*n = i;
	return p;
}

/* Clear LE Accept List */
static int hci_le_clear_accept_list_sync(struct hci_dev *hdev)
{
	if (!(hdev->commands[26] & 0x80))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_CLEAR_ACCEPT_LIST, 0, NULL,
				     HCI_CMD_TIMEOUT);
}

/* Device must not be scanning when updating the accept list.
 *
 * Update is done using the following sequence:
 *
 * use_ll_privacy((Disable Advertising) -> Disable Resolving List) ->
 * Remove Devices From Accept List ->
 * (has IRK && use_ll_privacy(Remove Devices From Resolving List))->
 * Add Devices to Accept List ->
 * (has IRK && use_ll_privacy(Remove Devices From Resolving List)) ->
 * use_ll_privacy(Enable Resolving List -> (Enable Advertising)) ->
 * Enable Scanning
 *
 * In case of failure advertising shall be restored to its original state and
 * return would disable accept list since either accept or resolving list could
 * not be programmed.
 *
 */
static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
{
	struct conn_params *params;
	struct bdaddr_list *b, *t;
	u8 num_entries = 0;
	bool pend_conn, pend_report;
	u8 filter_policy;
	size_t i, n;
	int err;

	/* Pause advertising if resolving list can be used as controllers
	 * cannot accept resolving list modifications while advertising.
	 */
	if (use_ll_privacy(hdev)) {
		err = hci_pause_advertising_sync(hdev);
		if (err) {
			bt_dev_err(hdev, "pause advertising failed: %d", err);
			return 0x00;
		}
	}

	/* Disable address resolution while reprogramming accept list since
	 * devices that do have an IRK will be programmed in the resolving list
	 * when LL Privacy is enabled.
	 */
	err = hci_le_set_addr_resolution_enable_sync(hdev, 0x00);
	if (err) {
		bt_dev_err(hdev, "Unable to disable LL privacy: %d", err);
		goto done;
	}

	/* Force address filtering if PA Sync is in progress */
	if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) {
		struct hci_cp_le_pa_create_sync *sent;

		sent = hci_sent_cmd_data(hdev, HCI_OP_LE_PA_CREATE_SYNC);
		if (sent) {
			struct conn_params pa;

			memset(&pa, 0, sizeof(pa));

			bacpy(&pa.addr, &sent->addr);
			pa.addr_type = sent->addr_type;

			/* Clear first since there could be addresses left
			 * behind.
			 */
			hci_le_clear_accept_list_sync(hdev);

			num_entries = 1;
			err = hci_le_add_accept_list_sync(hdev, &pa,
							  &num_entries);
			goto done;
		}
	}

	/* Go through the current accept list programmed into the
	 * controller one by one and check if that address is connected or is
	 * still in the list of pending connections or list of devices to
	 * report. If not present in either list, then remove it from
	 * the controller.
	 */
	list_for_each_entry_safe(b, t, &hdev->le_accept_list, list) {
		if (hci_conn_hash_lookup_le(hdev, &b->bdaddr, b->bdaddr_type))
			continue;

		/* Pointers not dereferenced, no locks needed */
		pend_conn = hci_pend_le_action_lookup(&hdev->pend_le_conns,
						      &b->bdaddr,
						      b->bdaddr_type);
		pend_report = hci_pend_le_action_lookup(&hdev->pend_le_reports,
							&b->bdaddr,
							b->bdaddr_type);

		/* If the device is not likely to connect or report,
		 * remove it from the acceptlist.
		 */
		if (!pend_conn && !pend_report) {
			hci_le_del_accept_list_sync(hdev, &b->bdaddr,
						    b->bdaddr_type);
			continue;
		}

		num_entries++;
	}

	/* Since all no longer valid accept list entries have been
	 * removed, walk through the list of pending connections
	 * and ensure that any new device gets programmed into
	 * the controller.
	 *
	 * If the list of the devices is larger than the list of
	 * available accept list entries in the controller, then
	 * just abort and return filer policy value to not use the
	 * accept list.
	 *
	 * The list and params may be mutated while we wait for events,
	 * so make a copy and iterate it.
	 */

	params = conn_params_copy(&hdev->pend_le_conns, &n);
	if (!params) {
		err = -ENOMEM;
		goto done;
	}

	for (i = 0; i < n; ++i) {
		err = hci_le_add_accept_list_sync(hdev, &params[i],
						  &num_entries);
		if (err) {
			kvfree(params);
			goto done;
		}
	}

	kvfree(params);

	/* After adding all new pending connections, walk through
	 * the list of pending reports and also add these to the
	 * accept list if there is still space. Abort if space runs out.
	 */

	params = conn_params_copy(&hdev->pend_le_reports, &n);
	if (!params) {
		err = -ENOMEM;
		goto done;
	}

	for (i = 0; i < n; ++i) {
		err = hci_le_add_accept_list_sync(hdev, &params[i],
						  &num_entries);
		if (err) {
			kvfree(params);
			goto done;
		}
	}

	kvfree(params);

	/* Use the allowlist unless the following conditions are all true:
	 * - We are not currently suspending
	 * - There are 1 or more ADV monitors registered and it's not offloaded
	 * - Interleaved scanning is not currently using the allowlist
	 */
	if (!idr_is_empty(&hdev->adv_monitors_idr) && !hdev->suspended &&
	    hci_get_adv_monitor_offload_ext(hdev) == HCI_ADV_MONITOR_EXT_NONE &&
	    hdev->interleave_scan_state != INTERLEAVE_SCAN_ALLOWLIST)
		err = -EINVAL;

done:
	filter_policy = err ? 0x00 : 0x01;

	/* Enable address resolution when LL Privacy is enabled. */
	err = hci_le_set_addr_resolution_enable_sync(hdev, 0x01);
	if (err)
		bt_dev_err(hdev, "Unable to enable LL privacy: %d", err);

	/* Resume advertising if it was paused */
	if (use_ll_privacy(hdev))
		hci_resume_advertising_sync(hdev);

	/* Select filter policy to use accept list */
	return filter_policy;
}

static void hci_le_scan_phy_params(struct hci_cp_le_scan_phy_params *cp,
				   u8 type, u16 interval, u16 window)
{
	cp->type = type;
	cp->interval = cpu_to_le16(interval);
	cp->window = cpu_to_le16(window);
}

static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type,
					  u16 interval, u16 window,
					  u8 own_addr_type, u8 filter_policy)
{
	struct hci_cp_le_set_ext_scan_params *cp;
	struct hci_cp_le_scan_phy_params *phy;
	u8 data[sizeof(*cp) + sizeof(*phy) * 2];
	u8 num_phy = 0x00;

	cp = (void *)data;
	phy = (void *)cp->data;

	memset(data, 0, sizeof(data));

	cp->own_addr_type = own_addr_type;
	cp->filter_policy = filter_policy;

	/* Check if PA Sync is in progress then select the PHY based on the
	 * hci_conn.iso_qos.
	 */
	if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) {
		struct hci_cp_le_add_to_accept_list *sent;

		sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_ACCEPT_LIST);
		if (sent) {
			struct hci_conn *conn;

			conn = hci_conn_hash_lookup_ba(hdev, ISO_LINK,
						       &sent->bdaddr);
			if (conn) {
				struct bt_iso_qos *qos = &conn->iso_qos;

				if (qos->bcast.in.phy & BT_ISO_PHY_1M ||
				    qos->bcast.in.phy & BT_ISO_PHY_2M) {
					cp->scanning_phys |= LE_SCAN_PHY_1M;
					hci_le_scan_phy_params(phy, type,
							       interval,
							       window);
					num_phy++;
					phy++;
				}

				if (qos->bcast.in.phy & BT_ISO_PHY_CODED) {
					cp->scanning_phys |= LE_SCAN_PHY_CODED;
					hci_le_scan_phy_params(phy, type,
							       interval * 3,
							       window * 3);
					num_phy++;
					phy++;
				}

				if (num_phy)
					goto done;
			}
		}
	}

	if (scan_1m(hdev) || scan_2m(hdev)) {
		cp->scanning_phys |= LE_SCAN_PHY_1M;
		hci_le_scan_phy_params(phy, type, interval, window);
		num_phy++;
		phy++;
	}

	if (scan_coded(hdev)) {
		cp->scanning_phys |= LE_SCAN_PHY_CODED;
		hci_le_scan_phy_params(phy, type, interval * 3, window * 3);
		num_phy++;
		phy++;
	}

done:
	if (!num_phy)
		return -EINVAL;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_SCAN_PARAMS,
				     sizeof(*cp) + sizeof(*phy) * num_phy,
				     data, HCI_CMD_TIMEOUT);
}

static int hci_le_set_scan_param_sync(struct hci_dev *hdev, u8 type,
				      u16 interval, u16 window,
				      u8 own_addr_type, u8 filter_policy)
{
	struct hci_cp_le_set_scan_param cp;

	if (use_ext_scan(hdev))
		return hci_le_set_ext_scan_param_sync(hdev, type, interval,
						      window, own_addr_type,
						      filter_policy);

	memset(&cp, 0, sizeof(cp));
	cp.type = type;
	cp.interval = cpu_to_le16(interval);
	cp.window = cpu_to_le16(window);
	cp.own_address_type = own_addr_type;
	cp.filter_policy = filter_policy;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_SCAN_PARAM,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_start_scan_sync(struct hci_dev *hdev, u8 type, u16 interval,
			       u16 window, u8 own_addr_type, u8 filter_policy,
			       u8 filter_dup)
{
	int err;

	if (hdev->scanning_paused) {
		bt_dev_dbg(hdev, "Scanning is paused for suspend");
		return 0;
	}

	err = hci_le_set_scan_param_sync(hdev, type, interval, window,
					 own_addr_type, filter_policy);
	if (err)
		return err;

	return hci_le_set_scan_enable_sync(hdev, LE_SCAN_ENABLE, filter_dup);
}

static int hci_passive_scan_sync(struct hci_dev *hdev)
{
	u8 own_addr_type;
	u8 filter_policy;
	u16 window, interval;
	u8 filter_dups = LE_SCAN_FILTER_DUP_ENABLE;
	int err;

	if (hdev->scanning_paused) {
		bt_dev_dbg(hdev, "Scanning is paused for suspend");
		return 0;
	}

	err = hci_scan_disable_sync(hdev);
	if (err) {
		bt_dev_err(hdev, "disable scanning failed: %d", err);
		return err;
	}

	/* Set require_privacy to false since no SCAN_REQ are send
	 * during passive scanning. Not using an non-resolvable address
	 * here is important so that peer devices using direct
	 * advertising with our address will be correctly reported
	 * by the controller.
	 */
	if (hci_update_random_address_sync(hdev, false, scan_use_rpa(hdev),
					   &own_addr_type))
		return 0;

	if (hdev->enable_advmon_interleave_scan &&
	    hci_update_interleaved_scan_sync(hdev))
		return 0;

	bt_dev_dbg(hdev, "interleave state %d", hdev->interleave_scan_state);

	/* Adding or removing entries from the accept list must
	 * happen before enabling scanning. The controller does
	 * not allow accept list modification while scanning.
	 */
	filter_policy = hci_update_accept_list_sync(hdev);

	/* When the controller is using random resolvable addresses and
	 * with that having LE privacy enabled, then controllers with
	 * Extended Scanner Filter Policies support can now enable support
	 * for handling directed advertising.
	 *
	 * So instead of using filter polices 0x00 (no acceptlist)
	 * and 0x01 (acceptlist enabled) use the new filter policies
	 * 0x02 (no acceptlist) and 0x03 (acceptlist enabled).
	 */
	if (hci_dev_test_flag(hdev, HCI_PRIVACY) &&
	    (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY))
		filter_policy |= 0x02;

	if (hdev->suspended) {
		window = hdev->le_scan_window_suspend;
		interval = hdev->le_scan_int_suspend;
	} else if (hci_is_le_conn_scanning(hdev)) {
		window = hdev->le_scan_window_connect;
		interval = hdev->le_scan_int_connect;
	} else if (hci_is_adv_monitoring(hdev)) {
		window = hdev->le_scan_window_adv_monitor;
		interval = hdev->le_scan_int_adv_monitor;
	} else {
		window = hdev->le_scan_window;
		interval = hdev->le_scan_interval;
	}

	/* Disable all filtering for Mesh */
	if (hci_dev_test_flag(hdev, HCI_MESH)) {
		filter_policy = 0;
		filter_dups = LE_SCAN_FILTER_DUP_DISABLE;
	}

	bt_dev_dbg(hdev, "LE passive scan with acceptlist = %d", filter_policy);

	return hci_start_scan_sync(hdev, LE_SCAN_PASSIVE, interval, window,
				   own_addr_type, filter_policy, filter_dups);
}

/* This function controls the passive scanning based on hdev->pend_le_conns
 * list. If there are pending LE connection we start the background scanning,
 * otherwise we stop it in the following sequence:
 *
 * If there are devices to scan:
 *
 * Disable Scanning -> Update Accept List ->
 * use_ll_privacy((Disable Advertising) -> Disable Resolving List ->
 * Update Resolving List -> Enable Resolving List -> (Enable Advertising)) ->
 * Enable Scanning
 *
 * Otherwise:
 *
 * Disable Scanning
 */
int hci_update_passive_scan_sync(struct hci_dev *hdev)
{
	int err;

	if (!test_bit(HCI_UP, &hdev->flags) ||
	    test_bit(HCI_INIT, &hdev->flags) ||
	    hci_dev_test_flag(hdev, HCI_SETUP) ||
	    hci_dev_test_flag(hdev, HCI_CONFIG) ||
	    hci_dev_test_flag(hdev, HCI_AUTO_OFF) ||
	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
		return 0;

	/* No point in doing scanning if LE support hasn't been enabled */
	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
		return 0;

	/* If discovery is active don't interfere with it */
	if (hdev->discovery.state != DISCOVERY_STOPPED)
		return 0;

	/* Reset RSSI and UUID filters when starting background scanning
	 * since these filters are meant for service discovery only.
	 *
	 * The Start Discovery and Start Service Discovery operations
	 * ensure to set proper values for RSSI threshold and UUID
	 * filter list. So it is safe to just reset them here.
	 */
	hci_discovery_filter_clear(hdev);

	bt_dev_dbg(hdev, "ADV monitoring is %s",
		   hci_is_adv_monitoring(hdev) ? "on" : "off");

	if (!hci_dev_test_flag(hdev, HCI_MESH) &&
	    list_empty(&hdev->pend_le_conns) &&
	    list_empty(&hdev->pend_le_reports) &&
	    !hci_is_adv_monitoring(hdev) &&
	    !hci_dev_test_flag(hdev, HCI_PA_SYNC)) {
		/* If there is no pending LE connections or devices
		 * to be scanned for or no ADV monitors, we should stop the
		 * background scanning.
		 */

		bt_dev_dbg(hdev, "stopping background scanning");

		err = hci_scan_disable_sync(hdev);
		if (err)
			bt_dev_err(hdev, "stop background scanning failed: %d",
				   err);
	} else {
		/* If there is at least one pending LE connection, we should
		 * keep the background scan running.
		 */

		/* If controller is connecting, we should not start scanning
		 * since some controllers are not able to scan and connect at
		 * the same time.
		 */
		if (hci_lookup_le_connect(hdev))
			return 0;

		bt_dev_dbg(hdev, "start background scanning");

		err = hci_passive_scan_sync(hdev);
		if (err)
			bt_dev_err(hdev, "start background scanning failed: %d",
				   err);
	}

	return err;
}

static int update_scan_sync(struct hci_dev *hdev, void *data)
{
	return hci_update_scan_sync(hdev);
}

int hci_update_scan(struct hci_dev *hdev)
{
	return hci_cmd_sync_queue(hdev, update_scan_sync, NULL, NULL);
}

static int update_passive_scan_sync(struct hci_dev *hdev, void *data)
{
	return hci_update_passive_scan_sync(hdev);
}

int hci_update_passive_scan(struct hci_dev *hdev)
{
	/* Only queue if it would have any effect */
	if (!test_bit(HCI_UP, &hdev->flags) ||
	    test_bit(HCI_INIT, &hdev->flags) ||
	    hci_dev_test_flag(hdev, HCI_SETUP) ||
	    hci_dev_test_flag(hdev, HCI_CONFIG) ||
	    hci_dev_test_flag(hdev, HCI_AUTO_OFF) ||
	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
		return 0;

	return hci_cmd_sync_queue_once(hdev, update_passive_scan_sync, NULL,
				       NULL);
}

int hci_write_sc_support_sync(struct hci_dev *hdev, u8 val)
{
	int err;

	if (!bredr_sc_enabled(hdev) || lmp_host_sc_capable(hdev))
		return 0;

	err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_SC_SUPPORT,
				    sizeof(val), &val, HCI_CMD_TIMEOUT);

	if (!err) {
		if (val) {
			hdev->features[1][0] |= LMP_HOST_SC;
			hci_dev_set_flag(hdev, HCI_SC_ENABLED);
		} else {
			hdev->features[1][0] &= ~LMP_HOST_SC;
			hci_dev_clear_flag(hdev, HCI_SC_ENABLED);
		}
	}

	return err;
}

int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode)
{
	int err;

	if (!hci_dev_test_flag(hdev, HCI_SSP_ENABLED) ||
	    lmp_host_ssp_capable(hdev))
		return 0;

	if (!mode && hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
		__hci_cmd_sync_status(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE,
				      sizeof(mode), &mode, HCI_CMD_TIMEOUT);
	}

	err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_SSP_MODE,
				    sizeof(mode), &mode, HCI_CMD_TIMEOUT);
	if (err)
		return err;

	return hci_write_sc_support_sync(hdev, 0x01);
}

int hci_write_le_host_supported_sync(struct hci_dev *hdev, u8 le, u8 simul)
{
	struct hci_cp_write_le_host_supported cp;

	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED) ||
	    !lmp_bredr_capable(hdev))
		return 0;

	/* Check first if we already have the right host state
	 * (host features set)
	 */
	if (le == lmp_host_le_capable(hdev) &&
	    simul == lmp_host_le_br_capable(hdev))
		return 0;

	memset(&cp, 0, sizeof(cp));

	cp.le = le;
	cp.simul = simul;

	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_powered_update_adv_sync(struct hci_dev *hdev)
{
	struct adv_info *adv, *tmp;
	int err;

	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
		return 0;

	/* If RPA Resolution has not been enable yet it means the
	 * resolving list is empty and we should attempt to program the
	 * local IRK in order to support using own_addr_type
	 * ADDR_LE_DEV_RANDOM_RESOLVED (0x03).
	 */
	if (!hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION)) {
		hci_le_add_resolve_list_sync(hdev, NULL);
		hci_le_set_addr_resolution_enable_sync(hdev, 0x01);
	}

	/* Make sure the controller has a good default for
	 * advertising data. This also applies to the case
	 * where BR/EDR was toggled during the AUTO_OFF phase.
	 */
	if (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
	    list_empty(&hdev->adv_instances)) {
		if (ext_adv_capable(hdev)) {
			err = hci_setup_ext_adv_instance_sync(hdev, 0x00);
			if (!err)
				hci_update_scan_rsp_data_sync(hdev, 0x00);
		} else {
			err = hci_update_adv_data_sync(hdev, 0x00);
			if (!err)
				hci_update_scan_rsp_data_sync(hdev, 0x00);
		}

		if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
			hci_enable_advertising_sync(hdev);
	}

	/* Call for each tracked instance to be scheduled */
	list_for_each_entry_safe(adv, tmp, &hdev->adv_instances, list)
		hci_schedule_adv_instance_sync(hdev, adv->instance, true);

	return 0;
}

static int hci_write_auth_enable_sync(struct hci_dev *hdev)
{
	u8 link_sec;

	link_sec = hci_dev_test_flag(hdev, HCI_LINK_SECURITY);
	if (link_sec == test_bit(HCI_AUTH, &hdev->flags))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_AUTH_ENABLE,
				     sizeof(link_sec), &link_sec,
				     HCI_CMD_TIMEOUT);
}

int hci_write_fast_connectable_sync(struct hci_dev *hdev, bool enable)
{
	struct hci_cp_write_page_scan_activity cp;
	u8 type;
	int err = 0;

	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
		return 0;

	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
		return 0;

	memset(&cp, 0, sizeof(cp));

	if (enable) {
		type = PAGE_SCAN_TYPE_INTERLACED;

		/* 160 msec page scan interval */
		cp.interval = cpu_to_le16(0x0100);
	} else {
		type = hdev->def_page_scan_type;
		cp.interval = cpu_to_le16(hdev->def_page_scan_int);
	}

	cp.window = cpu_to_le16(hdev->def_page_scan_window);

	if (__cpu_to_le16(hdev->page_scan_interval) != cp.interval ||
	    __cpu_to_le16(hdev->page_scan_window) != cp.window) {
		err = __hci_cmd_sync_status(hdev,
					    HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
					    sizeof(cp), &cp, HCI_CMD_TIMEOUT);
		if (err)
			return err;
	}

	if (hdev->page_scan_type != type)
		err = __hci_cmd_sync_status(hdev,
					    HCI_OP_WRITE_PAGE_SCAN_TYPE,
					    sizeof(type), &type,
					    HCI_CMD_TIMEOUT);

	return err;
}

static bool disconnected_accept_list_entries(struct hci_dev *hdev)
{
	struct bdaddr_list *b;

	list_for_each_entry(b, &hdev->accept_list, list) {
		struct hci_conn *conn;

		conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &b->bdaddr);
		if (!conn)
			return true;

		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
			return true;
	}

	return false;
}

static int hci_write_scan_enable_sync(struct hci_dev *hdev, u8 val)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_SCAN_ENABLE,
					    sizeof(val), &val,
					    HCI_CMD_TIMEOUT);
}

int hci_update_scan_sync(struct hci_dev *hdev)
{
	u8 scan;

	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
		return 0;

	if (!hdev_is_powered(hdev))
		return 0;

	if (mgmt_powering_down(hdev))
		return 0;

	if (hdev->scanning_paused)
		return 0;

	if (hci_dev_test_flag(hdev, HCI_CONNECTABLE) ||
	    disconnected_accept_list_entries(hdev))
		scan = SCAN_PAGE;
	else
		scan = SCAN_DISABLED;

	if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
		scan |= SCAN_INQUIRY;

	if (test_bit(HCI_PSCAN, &hdev->flags) == !!(scan & SCAN_PAGE) &&
	    test_bit(HCI_ISCAN, &hdev->flags) == !!(scan & SCAN_INQUIRY))
		return 0;

	return hci_write_scan_enable_sync(hdev, scan);
}

int hci_update_name_sync(struct hci_dev *hdev)
{
	struct hci_cp_write_local_name cp;

	memset(&cp, 0, sizeof(cp));

	memcpy(cp.name, hdev->dev_name, sizeof(cp.name));

	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME,
					    sizeof(cp), &cp,
					    HCI_CMD_TIMEOUT);
}

/* This function perform powered update HCI command sequence after the HCI init
 * sequence which end up resetting all states, the sequence is as follows:
 *
 * HCI_SSP_ENABLED(Enable SSP)
 * HCI_LE_ENABLED(Enable LE)
 * HCI_LE_ENABLED(use_ll_privacy(Add local IRK to Resolving List) ->
 * Update adv data)
 * Enable Authentication
 * lmp_bredr_capable(Set Fast Connectable -> Set Scan Type -> Set Class ->
 * Set Name -> Set EIR)
 * HCI_FORCE_STATIC_ADDR | BDADDR_ANY && !HCI_BREDR_ENABLED (Set Static Address)
 */
int hci_powered_update_sync(struct hci_dev *hdev)
{
	int err;

	/* Register the available SMP channels (BR/EDR and LE) only when
	 * successfully powering on the controller. This late
	 * registration is required so that LE SMP can clearly decide if
	 * the public address or static address is used.
	 */
	smp_register(hdev);

	err = hci_write_ssp_mode_sync(hdev, 0x01);
	if (err)
		return err;

	err = hci_write_le_host_supported_sync(hdev, 0x01, 0x00);
	if (err)
		return err;

	err = hci_powered_update_adv_sync(hdev);
	if (err)
		return err;

	err = hci_write_auth_enable_sync(hdev);
	if (err)
		return err;

	if (lmp_bredr_capable(hdev)) {
		if (hci_dev_test_flag(hdev, HCI_FAST_CONNECTABLE))
			hci_write_fast_connectable_sync(hdev, true);
		else
			hci_write_fast_connectable_sync(hdev, false);
		hci_update_scan_sync(hdev);
		hci_update_class_sync(hdev);
		hci_update_name_sync(hdev);
		hci_update_eir_sync(hdev);
	}

	/* If forcing static address is in use or there is no public
	 * address use the static address as random address (but skip
	 * the HCI command if the current random address is already the
	 * static one.
	 *
	 * In case BR/EDR has been disabled on a dual-mode controller
	 * and a static address has been configured, then use that
	 * address instead of the public BR/EDR address.
	 */
	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
	    (!bacmp(&hdev->bdaddr, BDADDR_ANY) &&
	    !hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))) {
		if (bacmp(&hdev->static_addr, BDADDR_ANY))
			return hci_set_random_addr_sync(hdev,
							&hdev->static_addr);
	}

	return 0;
}

/**
 * hci_dev_get_bd_addr_from_property - Get the Bluetooth Device Address
 *				       (BD_ADDR) for a HCI device from
 *				       a firmware node property.
 * @hdev:	The HCI device
 *
 * Search the firmware node for 'local-bd-address'.
 *
 * All-zero BD addresses are rejected, because those could be properties
 * that exist in the firmware tables, but were not updated by the firmware. For
 * example, the DTS could define 'local-bd-address', with zero BD addresses.
 */
static void hci_dev_get_bd_addr_from_property(struct hci_dev *hdev)
{
	struct fwnode_handle *fwnode = dev_fwnode(hdev->dev.parent);
	bdaddr_t ba;
	int ret;

	ret = fwnode_property_read_u8_array(fwnode, "local-bd-address",
					    (u8 *)&ba, sizeof(ba));
	if (ret < 0 || !bacmp(&ba, BDADDR_ANY))
		return;

	if (test_bit(HCI_QUIRK_BDADDR_PROPERTY_BROKEN, &hdev->quirks))
		baswap(&hdev->public_addr, &ba);
	else
		bacpy(&hdev->public_addr, &ba);
}

struct hci_init_stage {
	int (*func)(struct hci_dev *hdev);
};

/* Run init stage NULL terminated function table */
static int hci_init_stage_sync(struct hci_dev *hdev,
			       const struct hci_init_stage *stage)
{
	size_t i;

	for (i = 0; stage[i].func; i++) {
		int err;

		err = stage[i].func(hdev);
		if (err)
			return err;
	}

	return 0;
}

/* Read Local Version */
static int hci_read_local_version_sync(struct hci_dev *hdev)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_LOCAL_VERSION,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Read BD Address */
static int hci_read_bd_addr_sync(struct hci_dev *hdev)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_BD_ADDR,
				     0, NULL, HCI_CMD_TIMEOUT);
}

#define HCI_INIT(_func) \
{ \
	.func = _func, \
}

static const struct hci_init_stage hci_init0[] = {
	/* HCI_OP_READ_LOCAL_VERSION */
	HCI_INIT(hci_read_local_version_sync),
	/* HCI_OP_READ_BD_ADDR */
	HCI_INIT(hci_read_bd_addr_sync),
	{}
};

int hci_reset_sync(struct hci_dev *hdev)
{
	int err;

	set_bit(HCI_RESET, &hdev->flags);

	err = __hci_cmd_sync_status(hdev, HCI_OP_RESET, 0, NULL,
				    HCI_CMD_TIMEOUT);
	if (err)
		return err;

	return 0;
}

static int hci_init0_sync(struct hci_dev *hdev)
{
	int err;

	bt_dev_dbg(hdev, "");

	/* Reset */
	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
		err = hci_reset_sync(hdev);
		if (err)
			return err;
	}

	return hci_init_stage_sync(hdev, hci_init0);
}

static int hci_unconf_init_sync(struct hci_dev *hdev)
{
	int err;

	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
		return 0;

	err = hci_init0_sync(hdev);
	if (err < 0)
		return err;

	if (hci_dev_test_flag(hdev, HCI_SETUP))
		hci_debugfs_create_basic(hdev);

	return 0;
}

/* Read Local Supported Features. */
static int hci_read_local_features_sync(struct hci_dev *hdev)
{
	 /* Not all AMP controllers support this command */
	if (hdev->dev_type == HCI_AMP && !(hdev->commands[14] & 0x20))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_READ_LOCAL_FEATURES,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* BR Controller init stage 1 command sequence */
static const struct hci_init_stage br_init1[] = {
	/* HCI_OP_READ_LOCAL_FEATURES */
	HCI_INIT(hci_read_local_features_sync),
	/* HCI_OP_READ_LOCAL_VERSION */
	HCI_INIT(hci_read_local_version_sync),
	/* HCI_OP_READ_BD_ADDR */
	HCI_INIT(hci_read_bd_addr_sync),
	{}
};

/* Read Local Commands */
static int hci_read_local_cmds_sync(struct hci_dev *hdev)
{
	/* All Bluetooth 1.2 and later controllers should support the
	 * HCI command for reading the local supported commands.
	 *
	 * Unfortunately some controllers indicate Bluetooth 1.2 support,
	 * but do not have support for this command. If that is the case,
	 * the driver can quirk the behavior and skip reading the local
	 * supported commands.
	 */
	if (hdev->hci_ver > BLUETOOTH_VER_1_1 &&
	    !test_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks))
		return __hci_cmd_sync_status(hdev, HCI_OP_READ_LOCAL_COMMANDS,
					     0, NULL, HCI_CMD_TIMEOUT);

	return 0;
}

/* Read Local AMP Info */
static int hci_read_local_amp_info_sync(struct hci_dev *hdev)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_LOCAL_AMP_INFO,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Read Data Blk size */
static int hci_read_data_block_size_sync(struct hci_dev *hdev)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_DATA_BLOCK_SIZE,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Read Flow Control Mode */
static int hci_read_flow_control_mode_sync(struct hci_dev *hdev)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_FLOW_CONTROL_MODE,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Read Location Data */
static int hci_read_location_data_sync(struct hci_dev *hdev)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_LOCATION_DATA,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* AMP Controller init stage 1 command sequence */
static const struct hci_init_stage amp_init1[] = {
	/* HCI_OP_READ_LOCAL_VERSION */
	HCI_INIT(hci_read_local_version_sync),
	/* HCI_OP_READ_LOCAL_COMMANDS */
	HCI_INIT(hci_read_local_cmds_sync),
	/* HCI_OP_READ_LOCAL_AMP_INFO */
	HCI_INIT(hci_read_local_amp_info_sync),
	/* HCI_OP_READ_DATA_BLOCK_SIZE */
	HCI_INIT(hci_read_data_block_size_sync),
	/* HCI_OP_READ_FLOW_CONTROL_MODE */
	HCI_INIT(hci_read_flow_control_mode_sync),
	/* HCI_OP_READ_LOCATION_DATA */
	HCI_INIT(hci_read_location_data_sync),
	{}
};

static int hci_init1_sync(struct hci_dev *hdev)
{
	int err;

	bt_dev_dbg(hdev, "");

	/* Reset */
	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
		err = hci_reset_sync(hdev);
		if (err)
			return err;
	}

	switch (hdev->dev_type) {
	case HCI_PRIMARY:
		hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
		return hci_init_stage_sync(hdev, br_init1);
	case HCI_AMP:
		hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
		return hci_init_stage_sync(hdev, amp_init1);
	default:
		bt_dev_err(hdev, "Unknown device type %d", hdev->dev_type);
		break;
	}

	return 0;
}

/* AMP Controller init stage 2 command sequence */
static const struct hci_init_stage amp_init2[] = {
	/* HCI_OP_READ_LOCAL_FEATURES */
	HCI_INIT(hci_read_local_features_sync),
	{}
};

/* Read Buffer Size (ACL mtu, max pkt, etc.) */
static int hci_read_buffer_size_sync(struct hci_dev *hdev)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_BUFFER_SIZE,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Read Class of Device */
static int hci_read_dev_class_sync(struct hci_dev *hdev)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_CLASS_OF_DEV,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Read Local Name */
static int hci_read_local_name_sync(struct hci_dev *hdev)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_LOCAL_NAME,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Read Voice Setting */
static int hci_read_voice_setting_sync(struct hci_dev *hdev)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_VOICE_SETTING,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Read Number of Supported IAC */
static int hci_read_num_supported_iac_sync(struct hci_dev *hdev)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_NUM_SUPPORTED_IAC,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Read Current IAC LAP */
static int hci_read_current_iac_lap_sync(struct hci_dev *hdev)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_READ_CURRENT_IAC_LAP,
				     0, NULL, HCI_CMD_TIMEOUT);
}

static int hci_set_event_filter_sync(struct hci_dev *hdev, u8 flt_type,
				     u8 cond_type, bdaddr_t *bdaddr,
				     u8 auto_accept)
{
	struct hci_cp_set_event_filter cp;

	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
		return 0;

	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
		return 0;

	memset(&cp, 0, sizeof(cp));
	cp.flt_type = flt_type;

	if (flt_type != HCI_FLT_CLEAR_ALL) {
		cp.cond_type = cond_type;
		bacpy(&cp.addr_conn_flt.bdaddr, bdaddr);
		cp.addr_conn_flt.auto_accept = auto_accept;
	}

	return __hci_cmd_sync_status(hdev, HCI_OP_SET_EVENT_FLT,
				     flt_type == HCI_FLT_CLEAR_ALL ?
				     sizeof(cp.flt_type) : sizeof(cp), &cp,
				     HCI_CMD_TIMEOUT);
}

static int hci_clear_event_filter_sync(struct hci_dev *hdev)
{
	if (!hci_dev_test_flag(hdev, HCI_EVENT_FILTER_CONFIGURED))
		return 0;

	/* In theory the state machine should not reach here unless
	 * a hci_set_event_filter_sync() call succeeds, but we do
	 * the check both for parity and as a future reminder.
	 */
	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
		return 0;

	return hci_set_event_filter_sync(hdev, HCI_FLT_CLEAR_ALL, 0x00,
					 BDADDR_ANY, 0x00);
}

/* Connection accept timeout ~20 secs */
static int hci_write_ca_timeout_sync(struct hci_dev *hdev)
{
	__le16 param = cpu_to_le16(0x7d00);

	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_CA_TIMEOUT,
				     sizeof(param), &param, HCI_CMD_TIMEOUT);
}

/* BR Controller init stage 2 command sequence */
static const struct hci_init_stage br_init2[] = {
	/* HCI_OP_READ_BUFFER_SIZE */
	HCI_INIT(hci_read_buffer_size_sync),
	/* HCI_OP_READ_CLASS_OF_DEV */
	HCI_INIT(hci_read_dev_class_sync),
	/* HCI_OP_READ_LOCAL_NAME */
	HCI_INIT(hci_read_local_name_sync),
	/* HCI_OP_READ_VOICE_SETTING */
	HCI_INIT(hci_read_voice_setting_sync),
	/* HCI_OP_READ_NUM_SUPPORTED_IAC */
	HCI_INIT(hci_read_num_supported_iac_sync),
	/* HCI_OP_READ_CURRENT_IAC_LAP */
	HCI_INIT(hci_read_current_iac_lap_sync),
	/* HCI_OP_SET_EVENT_FLT */
	HCI_INIT(hci_clear_event_filter_sync),
	/* HCI_OP_WRITE_CA_TIMEOUT */
	HCI_INIT(hci_write_ca_timeout_sync),
	{}
};

static int hci_write_ssp_mode_1_sync(struct hci_dev *hdev)
{
	u8 mode = 0x01;

	if (!lmp_ssp_capable(hdev) || !hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
		return 0;

	/* When SSP is available, then the host features page
	 * should also be available as well. However some
	 * controllers list the max_page as 0 as long as SSP
	 * has not been enabled. To achieve proper debugging
	 * output, force the minimum max_page to 1 at least.
	 */
	hdev->max_page = 0x01;

	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_SSP_MODE,
				     sizeof(mode), &mode, HCI_CMD_TIMEOUT);
}

static int hci_write_eir_sync(struct hci_dev *hdev)
{
	struct hci_cp_write_eir cp;

	if (!lmp_ssp_capable(hdev) || hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
		return 0;

	memset(hdev->eir, 0, sizeof(hdev->eir));
	memset(&cp, 0, sizeof(cp));

	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp,
				     HCI_CMD_TIMEOUT);
}

static int hci_write_inquiry_mode_sync(struct hci_dev *hdev)
{
	u8 mode;

	if (!lmp_inq_rssi_capable(hdev) &&
	    !test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks))
		return 0;

	/* If Extended Inquiry Result events are supported, then
	 * they are clearly preferred over Inquiry Result with RSSI
	 * events.
	 */
	mode = lmp_ext_inq_capable(hdev) ? 0x02 : 0x01;

	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_INQUIRY_MODE,
				     sizeof(mode), &mode, HCI_CMD_TIMEOUT);
}

static int hci_read_inq_rsp_tx_power_sync(struct hci_dev *hdev)
{
	if (!lmp_inq_tx_pwr_capable(hdev))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_READ_INQ_RSP_TX_POWER,
				     0, NULL, HCI_CMD_TIMEOUT);
}

static int hci_read_local_ext_features_sync(struct hci_dev *hdev, u8 page)
{
	struct hci_cp_read_local_ext_features cp;

	if (!lmp_ext_feat_capable(hdev))
		return 0;

	memset(&cp, 0, sizeof(cp));
	cp.page = page;

	return __hci_cmd_sync_status(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_read_local_ext_features_1_sync(struct hci_dev *hdev)
{
	return hci_read_local_ext_features_sync(hdev, 0x01);
}

/* HCI Controller init stage 2 command sequence */
static const struct hci_init_stage hci_init2[] = {
	/* HCI_OP_READ_LOCAL_COMMANDS */
	HCI_INIT(hci_read_local_cmds_sync),
	/* HCI_OP_WRITE_SSP_MODE */
	HCI_INIT(hci_write_ssp_mode_1_sync),
	/* HCI_OP_WRITE_EIR */
	HCI_INIT(hci_write_eir_sync),
	/* HCI_OP_WRITE_INQUIRY_MODE */
	HCI_INIT(hci_write_inquiry_mode_sync),
	/* HCI_OP_READ_INQ_RSP_TX_POWER */
	HCI_INIT(hci_read_inq_rsp_tx_power_sync),
	/* HCI_OP_READ_LOCAL_EXT_FEATURES */
	HCI_INIT(hci_read_local_ext_features_1_sync),
	/* HCI_OP_WRITE_AUTH_ENABLE */
	HCI_INIT(hci_write_auth_enable_sync),
	{}
};

/* Read LE Buffer Size */
static int hci_le_read_buffer_size_sync(struct hci_dev *hdev)
{
	/* Use Read LE Buffer Size V2 if supported */
	if (iso_capable(hdev) && hdev->commands[41] & 0x20)
		return __hci_cmd_sync_status(hdev,
					     HCI_OP_LE_READ_BUFFER_SIZE_V2,
					     0, NULL, HCI_CMD_TIMEOUT);

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_READ_BUFFER_SIZE,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Read LE Local Supported Features */
static int hci_le_read_local_features_sync(struct hci_dev *hdev)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_LE_READ_LOCAL_FEATURES,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Read LE Supported States */
static int hci_le_read_supported_states_sync(struct hci_dev *hdev)
{
	return __hci_cmd_sync_status(hdev, HCI_OP_LE_READ_SUPPORTED_STATES,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* LE Controller init stage 2 command sequence */
static const struct hci_init_stage le_init2[] = {
	/* HCI_OP_LE_READ_LOCAL_FEATURES */
	HCI_INIT(hci_le_read_local_features_sync),
	/* HCI_OP_LE_READ_BUFFER_SIZE */
	HCI_INIT(hci_le_read_buffer_size_sync),
	/* HCI_OP_LE_READ_SUPPORTED_STATES */
	HCI_INIT(hci_le_read_supported_states_sync),
	{}
};

static int hci_init2_sync(struct hci_dev *hdev)
{
	int err;

	bt_dev_dbg(hdev, "");

	if (hdev->dev_type == HCI_AMP)
		return hci_init_stage_sync(hdev, amp_init2);

	err = hci_init_stage_sync(hdev, hci_init2);
	if (err)
		return err;

	if (lmp_bredr_capable(hdev)) {
		err = hci_init_stage_sync(hdev, br_init2);
		if (err)
			return err;
	} else {
		hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED);
	}

	if (lmp_le_capable(hdev)) {
		err = hci_init_stage_sync(hdev, le_init2);
		if (err)
			return err;
		/* LE-only controllers have LE implicitly enabled */
		if (!lmp_bredr_capable(hdev))
			hci_dev_set_flag(hdev, HCI_LE_ENABLED);
	}

	return 0;
}

static int hci_set_event_mask_sync(struct hci_dev *hdev)
{
	/* The second byte is 0xff instead of 0x9f (two reserved bits
	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
	 * command otherwise.
	 */
	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };

	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
	 * any event mask for pre 1.2 devices.
	 */
	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
		return 0;

	if (lmp_bredr_capable(hdev)) {
		events[4] |= 0x01; /* Flow Specification Complete */

		/* Don't set Disconnect Complete and mode change when
		 * suspended as that would wakeup the host when disconnecting
		 * due to suspend.
		 */
		if (hdev->suspended) {
			events[0] &= 0xef;
			events[2] &= 0xf7;
		}
	} else {
		/* Use a different default for LE-only devices */
		memset(events, 0, sizeof(events));
		events[1] |= 0x20; /* Command Complete */
		events[1] |= 0x40; /* Command Status */
		events[1] |= 0x80; /* Hardware Error */

		/* If the controller supports the Disconnect command, enable
		 * the corresponding event. In addition enable packet flow
		 * control related events.
		 */
		if (hdev->commands[0] & 0x20) {
			/* Don't set Disconnect Complete when suspended as that
			 * would wakeup the host when disconnecting due to
			 * suspend.
			 */
			if (!hdev->suspended)
				events[0] |= 0x10; /* Disconnection Complete */
			events[2] |= 0x04; /* Number of Completed Packets */
			events[3] |= 0x02; /* Data Buffer Overflow */
		}

		/* If the controller supports the Read Remote Version
		 * Information command, enable the corresponding event.
		 */
		if (hdev->commands[2] & 0x80)
			events[1] |= 0x08; /* Read Remote Version Information
					    * Complete
					    */

		if (hdev->le_features[0] & HCI_LE_ENCRYPTION) {
			events[0] |= 0x80; /* Encryption Change */
			events[5] |= 0x80; /* Encryption Key Refresh Complete */
		}
	}

	if (lmp_inq_rssi_capable(hdev) ||
	    test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks))
		events[4] |= 0x02; /* Inquiry Result with RSSI */

	if (lmp_ext_feat_capable(hdev))
		events[4] |= 0x04; /* Read Remote Extended Features Complete */

	if (lmp_esco_capable(hdev)) {
		events[5] |= 0x08; /* Synchronous Connection Complete */
		events[5] |= 0x10; /* Synchronous Connection Changed */
	}

	if (lmp_sniffsubr_capable(hdev))
		events[5] |= 0x20; /* Sniff Subrating */

	if (lmp_pause_enc_capable(hdev))
		events[5] |= 0x80; /* Encryption Key Refresh Complete */

	if (lmp_ext_inq_capable(hdev))
		events[5] |= 0x40; /* Extended Inquiry Result */

	if (lmp_no_flush_capable(hdev))
		events[7] |= 0x01; /* Enhanced Flush Complete */

	if (lmp_lsto_capable(hdev))
		events[6] |= 0x80; /* Link Supervision Timeout Changed */

	if (lmp_ssp_capable(hdev)) {
		events[6] |= 0x01;	/* IO Capability Request */
		events[6] |= 0x02;	/* IO Capability Response */
		events[6] |= 0x04;	/* User Confirmation Request */
		events[6] |= 0x08;	/* User Passkey Request */
		events[6] |= 0x10;	/* Remote OOB Data Request */
		events[6] |= 0x20;	/* Simple Pairing Complete */
		events[7] |= 0x04;	/* User Passkey Notification */
		events[7] |= 0x08;	/* Keypress Notification */
		events[7] |= 0x10;	/* Remote Host Supported
					 * Features Notification
					 */
	}

	if (lmp_le_capable(hdev))
		events[7] |= 0x20;	/* LE Meta-Event */

	return __hci_cmd_sync_status(hdev, HCI_OP_SET_EVENT_MASK,
				     sizeof(events), events, HCI_CMD_TIMEOUT);
}

static int hci_read_stored_link_key_sync(struct hci_dev *hdev)
{
	struct hci_cp_read_stored_link_key cp;

	if (!(hdev->commands[6] & 0x20) ||
	    test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks))
		return 0;

	memset(&cp, 0, sizeof(cp));
	bacpy(&cp.bdaddr, BDADDR_ANY);
	cp.read_all = 0x01;

	return __hci_cmd_sync_status(hdev, HCI_OP_READ_STORED_LINK_KEY,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_setup_link_policy_sync(struct hci_dev *hdev)
{
	struct hci_cp_write_def_link_policy cp;
	u16 link_policy = 0;

	if (!(hdev->commands[5] & 0x10))
		return 0;

	memset(&cp, 0, sizeof(cp));

	if (lmp_rswitch_capable(hdev))
		link_policy |= HCI_LP_RSWITCH;
	if (lmp_hold_capable(hdev))
		link_policy |= HCI_LP_HOLD;
	if (lmp_sniff_capable(hdev))
		link_policy |= HCI_LP_SNIFF;
	if (lmp_park_capable(hdev))
		link_policy |= HCI_LP_PARK;

	cp.policy = cpu_to_le16(link_policy);

	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_read_page_scan_activity_sync(struct hci_dev *hdev)
{
	if (!(hdev->commands[8] & 0x01))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_READ_PAGE_SCAN_ACTIVITY,
				     0, NULL, HCI_CMD_TIMEOUT);
}

static int hci_read_def_err_data_reporting_sync(struct hci_dev *hdev)
{
	if (!(hdev->commands[18] & 0x04) ||
	    !(hdev->features[0][6] & LMP_ERR_DATA_REPORTING) ||
	    test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_READ_DEF_ERR_DATA_REPORTING,
				     0, NULL, HCI_CMD_TIMEOUT);
}

static int hci_read_page_scan_type_sync(struct hci_dev *hdev)
{
	/* Some older Broadcom based Bluetooth 1.2 controllers do not
	 * support the Read Page Scan Type command. Check support for
	 * this command in the bit mask of supported commands.
	 */
	if (!(hdev->commands[13] & 0x01))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_READ_PAGE_SCAN_TYPE,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Read features beyond page 1 if available */
static int hci_read_local_ext_features_all_sync(struct hci_dev *hdev)
{
	u8 page;
	int err;

	if (!lmp_ext_feat_capable(hdev))
		return 0;

	for (page = 2; page < HCI_MAX_PAGES && page <= hdev->max_page;
	     page++) {
		err = hci_read_local_ext_features_sync(hdev, page);
		if (err)
			return err;
	}

	return 0;
}

/* HCI Controller init stage 3 command sequence */
static const struct hci_init_stage hci_init3[] = {
	/* HCI_OP_SET_EVENT_MASK */
	HCI_INIT(hci_set_event_mask_sync),
	/* HCI_OP_READ_STORED_LINK_KEY */
	HCI_INIT(hci_read_stored_link_key_sync),
	/* HCI_OP_WRITE_DEF_LINK_POLICY */
	HCI_INIT(hci_setup_link_policy_sync),
	/* HCI_OP_READ_PAGE_SCAN_ACTIVITY */
	HCI_INIT(hci_read_page_scan_activity_sync),
	/* HCI_OP_READ_DEF_ERR_DATA_REPORTING */
	HCI_INIT(hci_read_def_err_data_reporting_sync),
	/* HCI_OP_READ_PAGE_SCAN_TYPE */
	HCI_INIT(hci_read_page_scan_type_sync),
	/* HCI_OP_READ_LOCAL_EXT_FEATURES */
	HCI_INIT(hci_read_local_ext_features_all_sync),
	{}
};

static int hci_le_set_event_mask_sync(struct hci_dev *hdev)
{
	u8 events[8];

	if (!lmp_le_capable(hdev))
		return 0;

	memset(events, 0, sizeof(events));

	if (hdev->le_features[0] & HCI_LE_ENCRYPTION)
		events[0] |= 0x10;	/* LE Long Term Key Request */

	/* If controller supports the Connection Parameters Request
	 * Link Layer Procedure, enable the corresponding event.
	 */
	if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC)
		/* LE Remote Connection Parameter Request */
		events[0] |= 0x20;

	/* If the controller supports the Data Length Extension
	 * feature, enable the corresponding event.
	 */
	if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT)
		events[0] |= 0x40;	/* LE Data Length Change */

	/* If the controller supports LL Privacy feature or LE Extended Adv,
	 * enable the corresponding event.
	 */
	if (use_enhanced_conn_complete(hdev))
		events[1] |= 0x02;	/* LE Enhanced Connection Complete */

	/* If the controller supports Extended Scanner Filter
	 * Policies, enable the corresponding event.
	 */
	if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY)
		events[1] |= 0x04;	/* LE Direct Advertising Report */

	/* If the controller supports Channel Selection Algorithm #2
	 * feature, enable the corresponding event.
	 */
	if (hdev->le_features[1] & HCI_LE_CHAN_SEL_ALG2)
		events[2] |= 0x08;	/* LE Channel Selection Algorithm */

	/* If the controller supports the LE Set Scan Enable command,
	 * enable the corresponding advertising report event.
	 */
	if (hdev->commands[26] & 0x08)
		events[0] |= 0x02;	/* LE Advertising Report */

	/* If the controller supports the LE Create Connection
	 * command, enable the corresponding event.
	 */
	if (hdev->commands[26] & 0x10)
		events[0] |= 0x01;	/* LE Connection Complete */

	/* If the controller supports the LE Connection Update
	 * command, enable the corresponding event.
	 */
	if (hdev->commands[27] & 0x04)
		events[0] |= 0x04;	/* LE Connection Update Complete */

	/* If the controller supports the LE Read Remote Used Features
	 * command, enable the corresponding event.
	 */
	if (hdev->commands[27] & 0x20)
		/* LE Read Remote Used Features Complete */
		events[0] |= 0x08;

	/* If the controller supports the LE Read Local P-256
	 * Public Key command, enable the corresponding event.
	 */
	if (hdev->commands[34] & 0x02)
		/* LE Read Local P-256 Public Key Complete */
		events[0] |= 0x80;

	/* If the controller supports the LE Generate DHKey
	 * command, enable the corresponding event.
	 */
	if (hdev->commands[34] & 0x04)
		events[1] |= 0x01;	/* LE Generate DHKey Complete */

	/* If the controller supports the LE Set Default PHY or
	 * LE Set PHY commands, enable the corresponding event.
	 */
	if (hdev->commands[35] & (0x20 | 0x40))
		events[1] |= 0x08;        /* LE PHY Update Complete */

	/* If the controller supports LE Set Extended Scan Parameters
	 * and LE Set Extended Scan Enable commands, enable the
	 * corresponding event.
	 */
	if (use_ext_scan(hdev))
		events[1] |= 0x10;	/* LE Extended Advertising Report */

	/* If the controller supports the LE Extended Advertising
	 * command, enable the corresponding event.
	 */
	if (ext_adv_capable(hdev))
		events[2] |= 0x02;	/* LE Advertising Set Terminated */

	if (cis_capable(hdev)) {
		events[3] |= 0x01;	/* LE CIS Established */
		if (cis_peripheral_capable(hdev))
			events[3] |= 0x02; /* LE CIS Request */
	}

	if (bis_capable(hdev)) {
		events[1] |= 0x20;	/* LE PA Report */
		events[1] |= 0x40;	/* LE PA Sync Established */
		events[3] |= 0x04;	/* LE Create BIG Complete */
		events[3] |= 0x08;	/* LE Terminate BIG Complete */
		events[3] |= 0x10;	/* LE BIG Sync Established */
		events[3] |= 0x20;	/* LE BIG Sync Loss */
		events[4] |= 0x02;	/* LE BIG Info Advertising Report */
	}

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EVENT_MASK,
				     sizeof(events), events, HCI_CMD_TIMEOUT);
}

/* Read LE Advertising Channel TX Power */
static int hci_le_read_adv_tx_power_sync(struct hci_dev *hdev)
{
	if ((hdev->commands[25] & 0x40) && !ext_adv_capable(hdev)) {
		/* HCI TS spec forbids mixing of legacy and extended
		 * advertising commands wherein READ_ADV_TX_POWER is
		 * also included. So do not call it if extended adv
		 * is supported otherwise controller will return
		 * COMMAND_DISALLOWED for extended commands.
		 */
		return __hci_cmd_sync_status(hdev,
					       HCI_OP_LE_READ_ADV_TX_POWER,
					       0, NULL, HCI_CMD_TIMEOUT);
	}

	return 0;
}

/* Read LE Min/Max Tx Power*/
static int hci_le_read_tx_power_sync(struct hci_dev *hdev)
{
	if (!(hdev->commands[38] & 0x80) ||
	    test_bit(HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER, &hdev->quirks))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_READ_TRANSMIT_POWER,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Read LE Accept List Size */
static int hci_le_read_accept_list_size_sync(struct hci_dev *hdev)
{
	if (!(hdev->commands[26] & 0x40))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_READ_ACCEPT_LIST_SIZE,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Read LE Resolving List Size */
static int hci_le_read_resolv_list_size_sync(struct hci_dev *hdev)
{
	if (!(hdev->commands[34] & 0x40))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_READ_RESOLV_LIST_SIZE,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Clear LE Resolving List */
static int hci_le_clear_resolv_list_sync(struct hci_dev *hdev)
{
	if (!(hdev->commands[34] & 0x20))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_CLEAR_RESOLV_LIST, 0, NULL,
				     HCI_CMD_TIMEOUT);
}

/* Set RPA timeout */
static int hci_le_set_rpa_timeout_sync(struct hci_dev *hdev)
{
	__le16 timeout = cpu_to_le16(hdev->rpa_timeout);

	if (!(hdev->commands[35] & 0x04) ||
	    test_bit(HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT, &hdev->quirks))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_RPA_TIMEOUT,
				     sizeof(timeout), &timeout,
				     HCI_CMD_TIMEOUT);
}

/* Read LE Maximum Data Length */
static int hci_le_read_max_data_len_sync(struct hci_dev *hdev)
{
	if (!(hdev->le_features[0] & HCI_LE_DATA_LEN_EXT))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL,
				     HCI_CMD_TIMEOUT);
}

/* Read LE Suggested Default Data Length */
static int hci_le_read_def_data_len_sync(struct hci_dev *hdev)
{
	if (!(hdev->le_features[0] & HCI_LE_DATA_LEN_EXT))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_READ_DEF_DATA_LEN, 0, NULL,
				     HCI_CMD_TIMEOUT);
}

/* Read LE Number of Supported Advertising Sets */
static int hci_le_read_num_support_adv_sets_sync(struct hci_dev *hdev)
{
	if (!ext_adv_capable(hdev))
		return 0;

	return __hci_cmd_sync_status(hdev,
				     HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Write LE Host Supported */
static int hci_set_le_support_sync(struct hci_dev *hdev)
{
	struct hci_cp_write_le_host_supported cp;

	/* LE-only devices do not support explicit enablement */
	if (!lmp_bredr_capable(hdev))
		return 0;

	memset(&cp, 0, sizeof(cp));

	if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
		cp.le = 0x01;
		cp.simul = 0x00;
	}

	if (cp.le == lmp_host_le_capable(hdev))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

/* LE Set Host Feature */
static int hci_le_set_host_feature_sync(struct hci_dev *hdev)
{
	struct hci_cp_le_set_host_feature cp;

	if (!cis_capable(hdev))
		return 0;

	memset(&cp, 0, sizeof(cp));

	/* Connected Isochronous Channels (Host Support) */
	cp.bit_number = 32;
	cp.bit_value = 1;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_HOST_FEATURE,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

/* LE Controller init stage 3 command sequence */
static const struct hci_init_stage le_init3[] = {
	/* HCI_OP_LE_SET_EVENT_MASK */
	HCI_INIT(hci_le_set_event_mask_sync),
	/* HCI_OP_LE_READ_ADV_TX_POWER */
	HCI_INIT(hci_le_read_adv_tx_power_sync),
	/* HCI_OP_LE_READ_TRANSMIT_POWER */
	HCI_INIT(hci_le_read_tx_power_sync),
	/* HCI_OP_LE_READ_ACCEPT_LIST_SIZE */
	HCI_INIT(hci_le_read_accept_list_size_sync),
	/* HCI_OP_LE_CLEAR_ACCEPT_LIST */
	HCI_INIT(hci_le_clear_accept_list_sync),
	/* HCI_OP_LE_READ_RESOLV_LIST_SIZE */
	HCI_INIT(hci_le_read_resolv_list_size_sync),
	/* HCI_OP_LE_CLEAR_RESOLV_LIST */
	HCI_INIT(hci_le_clear_resolv_list_sync),
	/* HCI_OP_LE_SET_RPA_TIMEOUT */
	HCI_INIT(hci_le_set_rpa_timeout_sync),
	/* HCI_OP_LE_READ_MAX_DATA_LEN */
	HCI_INIT(hci_le_read_max_data_len_sync),
	/* HCI_OP_LE_READ_DEF_DATA_LEN */
	HCI_INIT(hci_le_read_def_data_len_sync),
	/* HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS */
	HCI_INIT(hci_le_read_num_support_adv_sets_sync),
	/* HCI_OP_WRITE_LE_HOST_SUPPORTED */
	HCI_INIT(hci_set_le_support_sync),
	/* HCI_OP_LE_SET_HOST_FEATURE */
	HCI_INIT(hci_le_set_host_feature_sync),
	{}
};

static int hci_init3_sync(struct hci_dev *hdev)
{
	int err;

	bt_dev_dbg(hdev, "");

	err = hci_init_stage_sync(hdev, hci_init3);
	if (err)
		return err;

	if (lmp_le_capable(hdev))
		return hci_init_stage_sync(hdev, le_init3);

	return 0;
}

static int hci_delete_stored_link_key_sync(struct hci_dev *hdev)
{
	struct hci_cp_delete_stored_link_key cp;

	/* Some Broadcom based Bluetooth controllers do not support the
	 * Delete Stored Link Key command. They are clearly indicating its
	 * absence in the bit mask of supported commands.
	 *
	 * Check the supported commands and only if the command is marked
	 * as supported send it. If not supported assume that the controller
	 * does not have actual support for stored link keys which makes this
	 * command redundant anyway.
	 *
	 * Some controllers indicate that they support handling deleting
	 * stored link keys, but they don't. The quirk lets a driver
	 * just disable this command.
	 */
	if (!(hdev->commands[6] & 0x80) ||
	    test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks))
		return 0;

	memset(&cp, 0, sizeof(cp));
	bacpy(&cp.bdaddr, BDADDR_ANY);
	cp.delete_all = 0x01;

	return __hci_cmd_sync_status(hdev, HCI_OP_DELETE_STORED_LINK_KEY,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_set_event_mask_page_2_sync(struct hci_dev *hdev)
{
	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
	bool changed = false;

	/* Set event mask page 2 if the HCI command for it is supported */
	if (!(hdev->commands[22] & 0x04))
		return 0;

	/* If Connectionless Peripheral Broadcast central role is supported
	 * enable all necessary events for it.
	 */
	if (lmp_cpb_central_capable(hdev)) {
		events[1] |= 0x40;	/* Triggered Clock Capture */
		events[1] |= 0x80;	/* Synchronization Train Complete */
		events[2] |= 0x08;	/* Truncated Page Complete */
		events[2] |= 0x20;	/* CPB Channel Map Change */
		changed = true;
	}

	/* If Connectionless Peripheral Broadcast peripheral role is supported
	 * enable all necessary events for it.
	 */
	if (lmp_cpb_peripheral_capable(hdev)) {
		events[2] |= 0x01;	/* Synchronization Train Received */
		events[2] |= 0x02;	/* CPB Receive */
		events[2] |= 0x04;	/* CPB Timeout */
		events[2] |= 0x10;	/* Peripheral Page Response Timeout */
		changed = true;
	}

	/* Enable Authenticated Payload Timeout Expired event if supported */
	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING) {
		events[2] |= 0x80;
		changed = true;
	}

	/* Some Broadcom based controllers indicate support for Set Event
	 * Mask Page 2 command, but then actually do not support it. Since
	 * the default value is all bits set to zero, the command is only
	 * required if the event mask has to be changed. In case no change
	 * to the event mask is needed, skip this command.
	 */
	if (!changed)
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_SET_EVENT_MASK_PAGE_2,
				     sizeof(events), events, HCI_CMD_TIMEOUT);
}

/* Read local codec list if the HCI command is supported */
static int hci_read_local_codecs_sync(struct hci_dev *hdev)
{
	if (hdev->commands[45] & 0x04)
		hci_read_supported_codecs_v2(hdev);
	else if (hdev->commands[29] & 0x20)
		hci_read_supported_codecs(hdev);

	return 0;
}

/* Read local pairing options if the HCI command is supported */
static int hci_read_local_pairing_opts_sync(struct hci_dev *hdev)
{
	if (!(hdev->commands[41] & 0x08))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_READ_LOCAL_PAIRING_OPTS,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Get MWS transport configuration if the HCI command is supported */
static int hci_get_mws_transport_config_sync(struct hci_dev *hdev)
{
	if (!mws_transport_config_capable(hdev))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_GET_MWS_TRANSPORT_CONFIG,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Check for Synchronization Train support */
static int hci_read_sync_train_params_sync(struct hci_dev *hdev)
{
	if (!lmp_sync_train_capable(hdev))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_READ_SYNC_TRAIN_PARAMS,
				     0, NULL, HCI_CMD_TIMEOUT);
}

/* Enable Secure Connections if supported and configured */
static int hci_write_sc_support_1_sync(struct hci_dev *hdev)
{
	u8 support = 0x01;

	if (!hci_dev_test_flag(hdev, HCI_SSP_ENABLED) ||
	    !bredr_sc_enabled(hdev))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_SC_SUPPORT,
				     sizeof(support), &support,
				     HCI_CMD_TIMEOUT);
}

/* Set erroneous data reporting if supported to the wideband speech
 * setting value
 */
static int hci_set_err_data_report_sync(struct hci_dev *hdev)
{
	struct hci_cp_write_def_err_data_reporting cp;
	bool enabled = hci_dev_test_flag(hdev, HCI_WIDEBAND_SPEECH_ENABLED);

	if (!(hdev->commands[18] & 0x08) ||
	    !(hdev->features[0][6] & LMP_ERR_DATA_REPORTING) ||
	    test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks))
		return 0;

	if (enabled == hdev->err_data_reporting)
		return 0;

	memset(&cp, 0, sizeof(cp));
	cp.err_data_reporting = enabled ? ERR_DATA_REPORTING_ENABLED :
				ERR_DATA_REPORTING_DISABLED;

	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING,
				    sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static const struct hci_init_stage hci_init4[] = {
	 /* HCI_OP_DELETE_STORED_LINK_KEY */
	HCI_INIT(hci_delete_stored_link_key_sync),
	/* HCI_OP_SET_EVENT_MASK_PAGE_2 */
	HCI_INIT(hci_set_event_mask_page_2_sync),
	/* HCI_OP_READ_LOCAL_CODECS */
	HCI_INIT(hci_read_local_codecs_sync),
	 /* HCI_OP_READ_LOCAL_PAIRING_OPTS */
	HCI_INIT(hci_read_local_pairing_opts_sync),
	 /* HCI_OP_GET_MWS_TRANSPORT_CONFIG */
	HCI_INIT(hci_get_mws_transport_config_sync),
	 /* HCI_OP_READ_SYNC_TRAIN_PARAMS */
	HCI_INIT(hci_read_sync_train_params_sync),
	/* HCI_OP_WRITE_SC_SUPPORT */
	HCI_INIT(hci_write_sc_support_1_sync),
	/* HCI_OP_WRITE_DEF_ERR_DATA_REPORTING */
	HCI_INIT(hci_set_err_data_report_sync),
	{}
};

/* Set Suggested Default Data Length to maximum if supported */
static int hci_le_set_write_def_data_len_sync(struct hci_dev *hdev)
{
	struct hci_cp_le_write_def_data_len cp;

	if (!(hdev->le_features[0] & HCI_LE_DATA_LEN_EXT))
		return 0;

	memset(&cp, 0, sizeof(cp));
	cp.tx_len = cpu_to_le16(hdev->le_max_tx_len);
	cp.tx_time = cpu_to_le16(hdev->le_max_tx_time);

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

/* Set Default PHY parameters if command is supported, enables all supported
 * PHYs according to the LE Features bits.
 */
static int hci_le_set_default_phy_sync(struct hci_dev *hdev)
{
	struct hci_cp_le_set_default_phy cp;

	if (!(hdev->commands[35] & 0x20)) {
		/* If the command is not supported it means only 1M PHY is
		 * supported.
		 */
		hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
		hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
		return 0;
	}

	memset(&cp, 0, sizeof(cp));
	cp.all_phys = 0x00;
	cp.tx_phys = HCI_LE_SET_PHY_1M;
	cp.rx_phys = HCI_LE_SET_PHY_1M;

	/* Enables 2M PHY if supported */
	if (le_2m_capable(hdev)) {
		cp.tx_phys |= HCI_LE_SET_PHY_2M;
		cp.rx_phys |= HCI_LE_SET_PHY_2M;
	}

	/* Enables Coded PHY if supported */
	if (le_coded_capable(hdev)) {
		cp.tx_phys |= HCI_LE_SET_PHY_CODED;
		cp.rx_phys |= HCI_LE_SET_PHY_CODED;
	}

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_DEFAULT_PHY,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static const struct hci_init_stage le_init4[] = {
	/* HCI_OP_LE_WRITE_DEF_DATA_LEN */
	HCI_INIT(hci_le_set_write_def_data_len_sync),
	/* HCI_OP_LE_SET_DEFAULT_PHY */
	HCI_INIT(hci_le_set_default_phy_sync),
	{}
};

static int hci_init4_sync(struct hci_dev *hdev)
{
	int err;

	bt_dev_dbg(hdev, "");

	err = hci_init_stage_sync(hdev, hci_init4);
	if (err)
		return err;

	if (lmp_le_capable(hdev))
		return hci_init_stage_sync(hdev, le_init4);

	return 0;
}

static int hci_init_sync(struct hci_dev *hdev)
{
	int err;

	err = hci_init1_sync(hdev);
	if (err < 0)
		return err;

	if (hci_dev_test_flag(hdev, HCI_SETUP))
		hci_debugfs_create_basic(hdev);

	err = hci_init2_sync(hdev);
	if (err < 0)
		return err;

	/* HCI_PRIMARY covers both single-mode LE, BR/EDR and dual-mode
	 * BR/EDR/LE type controllers. AMP controllers only need the
	 * first two stages of init.
	 */
	if (hdev->dev_type != HCI_PRIMARY)
		return 0;

	err = hci_init3_sync(hdev);
	if (err < 0)
		return err;

	err = hci_init4_sync(hdev);
	if (err < 0)
		return err;

	/* This function is only called when the controller is actually in
	 * configured state. When the controller is marked as unconfigured,
	 * this initialization procedure is not run.
	 *
	 * It means that it is possible that a controller runs through its
	 * setup phase and then discovers missing settings. If that is the
	 * case, then this function will not be called. It then will only
	 * be called during the config phase.
	 *
	 * So only when in setup phase or config phase, create the debugfs
	 * entries and register the SMP channels.
	 */
	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
	    !hci_dev_test_flag(hdev, HCI_CONFIG))
		return 0;

	if (hci_dev_test_and_set_flag(hdev, HCI_DEBUGFS_CREATED))
		return 0;

	hci_debugfs_create_common(hdev);

	if (lmp_bredr_capable(hdev))
		hci_debugfs_create_bredr(hdev);

	if (lmp_le_capable(hdev))
		hci_debugfs_create_le(hdev);

	return 0;
}

#define HCI_QUIRK_BROKEN(_quirk, _desc) { HCI_QUIRK_BROKEN_##_quirk, _desc }

static const struct {
	unsigned long quirk;
	const char *desc;
} hci_broken_table[] = {
	HCI_QUIRK_BROKEN(LOCAL_COMMANDS,
			 "HCI Read Local Supported Commands not supported"),
	HCI_QUIRK_BROKEN(STORED_LINK_KEY,
			 "HCI Delete Stored Link Key command is advertised, "
			 "but not supported."),
	HCI_QUIRK_BROKEN(ERR_DATA_REPORTING,
			 "HCI Read Default Erroneous Data Reporting command is "
			 "advertised, but not supported."),
	HCI_QUIRK_BROKEN(READ_TRANSMIT_POWER,
			 "HCI Read Transmit Power Level command is advertised, "
			 "but not supported."),
	HCI_QUIRK_BROKEN(FILTER_CLEAR_ALL,
			 "HCI Set Event Filter command not supported."),
	HCI_QUIRK_BROKEN(ENHANCED_SETUP_SYNC_CONN,
			 "HCI Enhanced Setup Synchronous Connection command is "
			 "advertised, but not supported."),
	HCI_QUIRK_BROKEN(SET_RPA_TIMEOUT,
			 "HCI LE Set Random Private Address Timeout command is "
			 "advertised, but not supported."),
	HCI_QUIRK_BROKEN(LE_CODED,
			 "HCI LE Coded PHY feature bit is set, "
			 "but its usage is not supported.")
};

/* This function handles hdev setup stage:
 *
 * Calls hdev->setup
 * Setup address if HCI_QUIRK_USE_BDADDR_PROPERTY is set.
 */
static int hci_dev_setup_sync(struct hci_dev *hdev)
{
	int ret = 0;
	bool invalid_bdaddr;
	size_t i;

	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
	    !test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks))
		return 0;

	bt_dev_dbg(hdev, "");

	hci_sock_dev_event(hdev, HCI_DEV_SETUP);

	if (hdev->setup)
		ret = hdev->setup(hdev);

	for (i = 0; i < ARRAY_SIZE(hci_broken_table); i++) {
		if (test_bit(hci_broken_table[i].quirk, &hdev->quirks))
			bt_dev_warn(hdev, "%s", hci_broken_table[i].desc);
	}

	/* The transport driver can set the quirk to mark the
	 * BD_ADDR invalid before creating the HCI device or in
	 * its setup callback.
	 */
	invalid_bdaddr = test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) ||
			 test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
	if (!ret) {
		if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks) &&
		    !bacmp(&hdev->public_addr, BDADDR_ANY))
			hci_dev_get_bd_addr_from_property(hdev);

		if (invalid_bdaddr && bacmp(&hdev->public_addr, BDADDR_ANY) &&
		    hdev->set_bdaddr) {
			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
			if (!ret)
				invalid_bdaddr = false;
		}
	}

	/* The transport driver can set these quirks before
	 * creating the HCI device or in its setup callback.
	 *
	 * For the invalid BD_ADDR quirk it is possible that
	 * it becomes a valid address if the bootloader does
	 * provide it (see above).
	 *
	 * In case any of them is set, the controller has to
	 * start up as unconfigured.
	 */
	if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
	    invalid_bdaddr)
		hci_dev_set_flag(hdev, HCI_UNCONFIGURED);

	/* For an unconfigured controller it is required to
	 * read at least the version information provided by
	 * the Read Local Version Information command.
	 *
	 * If the set_bdaddr driver callback is provided, then
	 * also the original Bluetooth public device address
	 * will be read using the Read BD Address command.
	 */
	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
		return hci_unconf_init_sync(hdev);

	return ret;
}

/* This function handles hdev init stage:
 *
 * Calls hci_dev_setup_sync to perform setup stage
 * Calls hci_init_sync to perform HCI command init sequence
 */
static int hci_dev_init_sync(struct hci_dev *hdev)
{
	int ret;

	bt_dev_dbg(hdev, "");

	atomic_set(&hdev->cmd_cnt, 1);
	set_bit(HCI_INIT, &hdev->flags);

	ret = hci_dev_setup_sync(hdev);

	if (hci_dev_test_flag(hdev, HCI_CONFIG)) {
		/* If public address change is configured, ensure that
		 * the address gets programmed. If the driver does not
		 * support changing the public address, fail the power
		 * on procedure.
		 */
		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
		    hdev->set_bdaddr)
			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
		else
			ret = -EADDRNOTAVAIL;
	}

	if (!ret) {
		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
			ret = hci_init_sync(hdev);
			if (!ret && hdev->post_init)
				ret = hdev->post_init(hdev);
		}
	}

	/* If the HCI Reset command is clearing all diagnostic settings,
	 * then they need to be reprogrammed after the init procedure
	 * completed.
	 */
	if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
	    hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag)
		ret = hdev->set_diag(hdev, true);

	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
		msft_do_open(hdev);
		aosp_do_open(hdev);
	}

	clear_bit(HCI_INIT, &hdev->flags);

	return ret;
}

int hci_dev_open_sync(struct hci_dev *hdev)
{
	int ret;

	bt_dev_dbg(hdev, "");

	if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
		ret = -ENODEV;
		goto done;
	}

	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
		/* Check for rfkill but allow the HCI setup stage to
		 * proceed (which in itself doesn't cause any RF activity).
		 */
		if (hci_dev_test_flag(hdev, HCI_RFKILLED)) {
			ret = -ERFKILL;
			goto done;
		}

		/* Check for valid public address or a configured static
		 * random address, but let the HCI setup proceed to
		 * be able to determine if there is a public address
		 * or not.
		 *
		 * In case of user channel usage, it is not important
		 * if a public address or static random address is
		 * available.
		 *
		 * This check is only valid for BR/EDR controllers
		 * since AMP controllers do not have an address.
		 */
		if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
		    hdev->dev_type == HCI_PRIMARY &&
		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
			ret = -EADDRNOTAVAIL;
			goto done;
		}
	}

	if (test_bit(HCI_UP, &hdev->flags)) {
		ret = -EALREADY;
		goto done;
	}

	if (hdev->open(hdev)) {
		ret = -EIO;
		goto done;
	}

	hci_devcd_reset(hdev);

	set_bit(HCI_RUNNING, &hdev->flags);
	hci_sock_dev_event(hdev, HCI_DEV_OPEN);

	ret = hci_dev_init_sync(hdev);
	if (!ret) {
		hci_dev_hold(hdev);
		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
		hci_adv_instances_set_rpa_expired(hdev, true);
		set_bit(HCI_UP, &hdev->flags);
		hci_sock_dev_event(hdev, HCI_DEV_UP);
		hci_leds_update_powered(hdev, true);
		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
		    !hci_dev_test_flag(hdev, HCI_CONFIG) &&
		    !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
		    hci_dev_test_flag(hdev, HCI_MGMT) &&
		    hdev->dev_type == HCI_PRIMARY) {
			ret = hci_powered_update_sync(hdev);
			mgmt_power_on(hdev, ret);
		}
	} else {
		/* Init failed, cleanup */
		flush_work(&hdev->tx_work);

		/* Since hci_rx_work() is possible to awake new cmd_work
		 * it should be flushed first to avoid unexpected call of
		 * hci_cmd_work()
		 */
		flush_work(&hdev->rx_work);
		flush_work(&hdev->cmd_work);

		skb_queue_purge(&hdev->cmd_q);
		skb_queue_purge(&hdev->rx_q);

		if (hdev->flush)
			hdev->flush(hdev);

		if (hdev->sent_cmd) {
			cancel_delayed_work_sync(&hdev->cmd_timer);
			kfree_skb(hdev->sent_cmd);
			hdev->sent_cmd = NULL;
		}

		if (hdev->req_skb) {
			kfree_skb(hdev->req_skb);
			hdev->req_skb = NULL;
		}

		clear_bit(HCI_RUNNING, &hdev->flags);
		hci_sock_dev_event(hdev, HCI_DEV_CLOSE);

		hdev->close(hdev);
		hdev->flags &= BIT(HCI_RAW);
	}

done:
	return ret;
}

/* This function requires the caller holds hdev->lock */
static void hci_pend_le_actions_clear(struct hci_dev *hdev)
{
	struct hci_conn_params *p;

	list_for_each_entry(p, &hdev->le_conn_params, list) {
		hci_pend_le_list_del_init(p);
		if (p->conn) {
			hci_conn_drop(p->conn);
			hci_conn_put(p->conn);
			p->conn = NULL;
		}
	}

	BT_DBG("All LE pending actions cleared");
}

static int hci_dev_shutdown(struct hci_dev *hdev)
{
	int err = 0;
	/* Similar to how we first do setup and then set the exclusive access
	 * bit for userspace, we must first unset userchannel and then clean up.
	 * Otherwise, the kernel can't properly use the hci channel to clean up
	 * the controller (some shutdown routines require sending additional
	 * commands to the controller for example).
	 */
	bool was_userchannel =
		hci_dev_test_and_clear_flag(hdev, HCI_USER_CHANNEL);

	if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
	    test_bit(HCI_UP, &hdev->flags)) {
		/* Execute vendor specific shutdown routine */
		if (hdev->shutdown)
			err = hdev->shutdown(hdev);
	}

	if (was_userchannel)
		hci_dev_set_flag(hdev, HCI_USER_CHANNEL);

	return err;
}

int hci_dev_close_sync(struct hci_dev *hdev)
{
	bool auto_off;
	int err = 0;

	bt_dev_dbg(hdev, "");

	cancel_delayed_work(&hdev->power_off);
	cancel_delayed_work(&hdev->ncmd_timer);
	cancel_delayed_work(&hdev->le_scan_disable);

	hci_request_cancel_all(hdev);

	if (hdev->adv_instance_timeout) {
		cancel_delayed_work_sync(&hdev->adv_instance_expire);
		hdev->adv_instance_timeout = 0;
	}

	err = hci_dev_shutdown(hdev);

	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
		cancel_delayed_work_sync(&hdev->cmd_timer);
		return err;
	}

	hci_leds_update_powered(hdev, false);

	/* Flush RX and TX works */
	flush_work(&hdev->tx_work);
	flush_work(&hdev->rx_work);

	if (hdev->discov_timeout > 0) {
		hdev->discov_timeout = 0;
		hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
	}

	if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE))
		cancel_delayed_work(&hdev->service_cache);

	if (hci_dev_test_flag(hdev, HCI_MGMT)) {
		struct adv_info *adv_instance;

		cancel_delayed_work_sync(&hdev->rpa_expired);

		list_for_each_entry(adv_instance, &hdev->adv_instances, list)
			cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
	}

	/* Avoid potential lockdep warnings from the *_flush() calls by
	 * ensuring the workqueue is empty up front.
	 */
	drain_workqueue(hdev->workqueue);

	hci_dev_lock(hdev);

	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);

	auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF);

	if (!auto_off && hdev->dev_type == HCI_PRIMARY &&
	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
	    hci_dev_test_flag(hdev, HCI_MGMT))
		__mgmt_power_off(hdev);

	hci_inquiry_cache_flush(hdev);
	hci_pend_le_actions_clear(hdev);
	hci_conn_hash_flush(hdev);
	/* Prevent data races on hdev->smp_data or hdev->smp_bredr_data */
	smp_unregister(hdev);
	hci_dev_unlock(hdev);

	hci_sock_dev_event(hdev, HCI_DEV_DOWN);

	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
		aosp_do_close(hdev);
		msft_do_close(hdev);
	}

	if (hdev->flush)
		hdev->flush(hdev);

	/* Reset device */
	skb_queue_purge(&hdev->cmd_q);
	atomic_set(&hdev->cmd_cnt, 1);
	if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) &&
	    !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
		set_bit(HCI_INIT, &hdev->flags);
		hci_reset_sync(hdev);
		clear_bit(HCI_INIT, &hdev->flags);
	}

	/* flush cmd  work */
	flush_work(&hdev->cmd_work);

	/* Drop queues */
	skb_queue_purge(&hdev->rx_q);
	skb_queue_purge(&hdev->cmd_q);
	skb_queue_purge(&hdev->raw_q);

	/* Drop last sent command */
	if (hdev->sent_cmd) {
		cancel_delayed_work_sync(&hdev->cmd_timer);
		kfree_skb(hdev->sent_cmd);
		hdev->sent_cmd = NULL;
	}

	/* Drop last request */
	if (hdev->req_skb) {
		kfree_skb(hdev->req_skb);
		hdev->req_skb = NULL;
	}

	clear_bit(HCI_RUNNING, &hdev->flags);
	hci_sock_dev_event(hdev, HCI_DEV_CLOSE);

	/* After this point our queues are empty and no tasks are scheduled. */
	hdev->close(hdev);

	/* Clear flags */
	hdev->flags &= BIT(HCI_RAW);
	hci_dev_clear_volatile_flags(hdev);

	/* Controller radio is available but is currently powered down */
	hdev->amp_status = AMP_STATUS_POWERED_DOWN;

	memset(hdev->eir, 0, sizeof(hdev->eir));
	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
	bacpy(&hdev->random_addr, BDADDR_ANY);
	hci_codec_list_clear(&hdev->local_codecs);

	hci_dev_put(hdev);
	return err;
}

/* This function perform power on HCI command sequence as follows:
 *
 * If controller is already up (HCI_UP) performs hci_powered_update_sync
 * sequence otherwise run hci_dev_open_sync which will follow with
 * hci_powered_update_sync after the init sequence is completed.
 */
static int hci_power_on_sync(struct hci_dev *hdev)
{
	int err;

	if (test_bit(HCI_UP, &hdev->flags) &&
	    hci_dev_test_flag(hdev, HCI_MGMT) &&
	    hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
		cancel_delayed_work(&hdev->power_off);
		return hci_powered_update_sync(hdev);
	}

	err = hci_dev_open_sync(hdev);
	if (err < 0)
		return err;

	/* During the HCI setup phase, a few error conditions are
	 * ignored and they need to be checked now. If they are still
	 * valid, it is important to return the device back off.
	 */
	if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
	    hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
	    (hdev->dev_type == HCI_PRIMARY &&
	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
		hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
		hci_dev_close_sync(hdev);
	} else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
				   HCI_AUTO_OFF_TIMEOUT);
	}

	if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
		/* For unconfigured devices, set the HCI_RAW flag
		 * so that userspace can easily identify them.
		 */
		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
			set_bit(HCI_RAW, &hdev->flags);

		/* For fully configured devices, this will send
		 * the Index Added event. For unconfigured devices,
		 * it will send Unconfigued Index Added event.
		 *
		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
		 * and no event will be send.
		 */
		mgmt_index_added(hdev);
	} else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
		/* When the controller is now configured, then it
		 * is important to clear the HCI_RAW flag.
		 */
		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
			clear_bit(HCI_RAW, &hdev->flags);

		/* Powering on the controller with HCI_CONFIG set only
		 * happens with the transition from unconfigured to
		 * configured. This will send the Index Added event.
		 */
		mgmt_index_added(hdev);
	}

	return 0;
}

static int hci_remote_name_cancel_sync(struct hci_dev *hdev, bdaddr_t *addr)
{
	struct hci_cp_remote_name_req_cancel cp;

	memset(&cp, 0, sizeof(cp));
	bacpy(&cp.bdaddr, addr);

	return __hci_cmd_sync_status(hdev, HCI_OP_REMOTE_NAME_REQ_CANCEL,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

int hci_stop_discovery_sync(struct hci_dev *hdev)
{
	struct discovery_state *d = &hdev->discovery;
	struct inquiry_entry *e;
	int err;

	bt_dev_dbg(hdev, "state %u", hdev->discovery.state);

	if (d->state == DISCOVERY_FINDING || d->state == DISCOVERY_STOPPING) {
		if (test_bit(HCI_INQUIRY, &hdev->flags)) {
			err = __hci_cmd_sync_status(hdev, HCI_OP_INQUIRY_CANCEL,
						    0, NULL, HCI_CMD_TIMEOUT);
			if (err)
				return err;
		}

		if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
			cancel_delayed_work(&hdev->le_scan_disable);

			err = hci_scan_disable_sync(hdev);
			if (err)
				return err;
		}

	} else {
		err = hci_scan_disable_sync(hdev);
		if (err)
			return err;
	}

	/* Resume advertising if it was paused */
	if (use_ll_privacy(hdev))
		hci_resume_advertising_sync(hdev);

	/* No further actions needed for LE-only discovery */
	if (d->type == DISCOV_TYPE_LE)
		return 0;

	if (d->state == DISCOVERY_RESOLVING || d->state == DISCOVERY_STOPPING) {
		e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
						     NAME_PENDING);
		if (!e)
			return 0;

		return hci_remote_name_cancel_sync(hdev, &e->data.bdaddr);
	}

	return 0;
}

static int hci_disconnect_phy_link_sync(struct hci_dev *hdev, u16 handle,
					u8 reason)
{
	struct hci_cp_disconn_phy_link cp;

	memset(&cp, 0, sizeof(cp));
	cp.phy_handle = HCI_PHY_HANDLE(handle);
	cp.reason = reason;

	return __hci_cmd_sync_status(hdev, HCI_OP_DISCONN_PHY_LINK,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_disconnect_sync(struct hci_dev *hdev, struct hci_conn *conn,
			       u8 reason)
{
	struct hci_cp_disconnect cp;

	if (conn->type == AMP_LINK)
		return hci_disconnect_phy_link_sync(hdev, conn->handle, reason);

	if (test_bit(HCI_CONN_BIG_CREATED, &conn->flags)) {
		/* This is a BIS connection, hci_conn_del will
		 * do the necessary cleanup.
		 */
		hci_dev_lock(hdev);
		hci_conn_failed(conn, reason);
		hci_dev_unlock(hdev);

		return 0;
	}

	memset(&cp, 0, sizeof(cp));
	cp.handle = cpu_to_le16(conn->handle);
	cp.reason = reason;

	/* Wait for HCI_EV_DISCONN_COMPLETE, not HCI_EV_CMD_STATUS, when the
	 * reason is anything but HCI_ERROR_REMOTE_POWER_OFF. This reason is
	 * used when suspending or powering off, where we don't want to wait
	 * for the peer's response.
	 */
	if (reason != HCI_ERROR_REMOTE_POWER_OFF)
		return __hci_cmd_sync_status_sk(hdev, HCI_OP_DISCONNECT,
						sizeof(cp), &cp,
						HCI_EV_DISCONN_COMPLETE,
						HCI_CMD_TIMEOUT, NULL);

	return __hci_cmd_sync_status(hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp,
				     HCI_CMD_TIMEOUT);
}

static int hci_le_connect_cancel_sync(struct hci_dev *hdev,
				      struct hci_conn *conn, u8 reason)
{
	/* Return reason if scanning since the connection shall probably be
	 * cleanup directly.
	 */
	if (test_bit(HCI_CONN_SCANNING, &conn->flags))
		return reason;

	if (conn->role == HCI_ROLE_SLAVE ||
	    test_and_set_bit(HCI_CONN_CANCEL, &conn->flags))
		return 0;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_CREATE_CONN_CANCEL,
				     0, NULL, HCI_CMD_TIMEOUT);
}

static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn,
				   u8 reason)
{
	if (conn->type == LE_LINK)
		return hci_le_connect_cancel_sync(hdev, conn, reason);

	if (conn->type == ISO_LINK) {
		/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
		 * page 1857:
		 *
		 * If this command is issued for a CIS on the Central and the
		 * CIS is successfully terminated before being established,
		 * then an HCI_LE_CIS_Established event shall also be sent for
		 * this CIS with the Status Operation Cancelled by Host (0x44).
		 */
		if (test_bit(HCI_CONN_CREATE_CIS, &conn->flags))
			return hci_disconnect_sync(hdev, conn, reason);

		/* CIS with no Create CIS sent have nothing to cancel */
		if (bacmp(&conn->dst, BDADDR_ANY))
			return HCI_ERROR_LOCAL_HOST_TERM;

		/* There is no way to cancel a BIS without terminating the BIG
		 * which is done later on connection cleanup.
		 */
		return 0;
	}

	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
		return 0;

	/* Wait for HCI_EV_CONN_COMPLETE, not HCI_EV_CMD_STATUS, when the
	 * reason is anything but HCI_ERROR_REMOTE_POWER_OFF. This reason is
	 * used when suspending or powering off, where we don't want to wait
	 * for the peer's response.
	 */
	if (reason != HCI_ERROR_REMOTE_POWER_OFF)
		return __hci_cmd_sync_status_sk(hdev, HCI_OP_CREATE_CONN_CANCEL,
						6, &conn->dst,
						HCI_EV_CONN_COMPLETE,
						HCI_CMD_TIMEOUT, NULL);

	return __hci_cmd_sync_status(hdev, HCI_OP_CREATE_CONN_CANCEL,
				     6, &conn->dst, HCI_CMD_TIMEOUT);
}

static int hci_reject_sco_sync(struct hci_dev *hdev, struct hci_conn *conn,
			       u8 reason)
{
	struct hci_cp_reject_sync_conn_req cp;

	memset(&cp, 0, sizeof(cp));
	bacpy(&cp.bdaddr, &conn->dst);
	cp.reason = reason;

	/* SCO rejection has its own limited set of
	 * allowed error values (0x0D-0x0F).
	 */
	if (reason < 0x0d || reason > 0x0f)
		cp.reason = HCI_ERROR_REJ_LIMITED_RESOURCES;

	return __hci_cmd_sync_status(hdev, HCI_OP_REJECT_SYNC_CONN_REQ,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_le_reject_cis_sync(struct hci_dev *hdev, struct hci_conn *conn,
				  u8 reason)
{
	struct hci_cp_le_reject_cis cp;

	memset(&cp, 0, sizeof(cp));
	cp.handle = cpu_to_le16(conn->handle);
	cp.reason = reason;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_REJECT_CIS,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,
				u8 reason)
{
	struct hci_cp_reject_conn_req cp;

	if (conn->type == ISO_LINK)
		return hci_le_reject_cis_sync(hdev, conn, reason);

	if (conn->type == SCO_LINK || conn->type == ESCO_LINK)
		return hci_reject_sco_sync(hdev, conn, reason);

	memset(&cp, 0, sizeof(cp));
	bacpy(&cp.bdaddr, &conn->dst);
	cp.reason = reason;

	return __hci_cmd_sync_status(hdev, HCI_OP_REJECT_CONN_REQ,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
{
	int err = 0;
	u16 handle = conn->handle;
	bool disconnect = false;
	struct hci_conn *c;

	switch (conn->state) {
	case BT_CONNECTED:
	case BT_CONFIG:
		err = hci_disconnect_sync(hdev, conn, reason);
		break;
	case BT_CONNECT:
		err = hci_connect_cancel_sync(hdev, conn, reason);
		break;
	case BT_CONNECT2:
		err = hci_reject_conn_sync(hdev, conn, reason);
		break;
	case BT_OPEN:
	case BT_BOUND:
		break;
	default:
		disconnect = true;
		break;
	}

	hci_dev_lock(hdev);

	/* Check if the connection has been cleaned up concurrently */
	c = hci_conn_hash_lookup_handle(hdev, handle);
	if (!c || c != conn) {
		err = 0;
		goto unlock;
	}

	/* Cleanup hci_conn object if it cannot be cancelled as it
	 * likelly means the controller and host stack are out of sync
	 * or in case of LE it was still scanning so it can be cleanup
	 * safely.
	 */
	if (disconnect) {
		conn->state = BT_CLOSED;
		hci_disconn_cfm(conn, reason);
		hci_conn_del(conn);
	} else {
		hci_conn_failed(conn, reason);
	}

unlock:
	hci_dev_unlock(hdev);
	return err;
}

static int hci_disconnect_all_sync(struct hci_dev *hdev, u8 reason)
{
	struct list_head *head = &hdev->conn_hash.list;
	struct hci_conn *conn;

	rcu_read_lock();
	while ((conn = list_first_or_null_rcu(head, struct hci_conn, list))) {
		/* Make sure the connection is not freed while unlocking */
		conn = hci_conn_get(conn);
		rcu_read_unlock();
		/* Disregard possible errors since hci_conn_del shall have been
		 * called even in case of errors had occurred since it would
		 * then cause hci_conn_failed to be called which calls
		 * hci_conn_del internally.
		 */
		hci_abort_conn_sync(hdev, conn, reason);
		hci_conn_put(conn);
		rcu_read_lock();
	}
	rcu_read_unlock();

	return 0;
}

/* This function perform power off HCI command sequence as follows:
 *
 * Clear Advertising
 * Stop Discovery
 * Disconnect all connections
 * hci_dev_close_sync
 */
static int hci_power_off_sync(struct hci_dev *hdev)
{
	int err;

	/* If controller is already down there is nothing to do */
	if (!test_bit(HCI_UP, &hdev->flags))
		return 0;

	hci_dev_set_flag(hdev, HCI_POWERING_DOWN);

	if (test_bit(HCI_ISCAN, &hdev->flags) ||
	    test_bit(HCI_PSCAN, &hdev->flags)) {
		err = hci_write_scan_enable_sync(hdev, 0x00);
		if (err)
			goto out;
	}

	err = hci_clear_adv_sync(hdev, NULL, false);
	if (err)
		goto out;

	err = hci_stop_discovery_sync(hdev);
	if (err)
		goto out;

	/* Terminated due to Power Off */
	err = hci_disconnect_all_sync(hdev, HCI_ERROR_REMOTE_POWER_OFF);
	if (err)
		goto out;

	err = hci_dev_close_sync(hdev);

out:
	hci_dev_clear_flag(hdev, HCI_POWERING_DOWN);
	return err;
}

int hci_set_powered_sync(struct hci_dev *hdev, u8 val)
{
	if (val)
		return hci_power_on_sync(hdev);

	return hci_power_off_sync(hdev);
}

static int hci_write_iac_sync(struct hci_dev *hdev)
{
	struct hci_cp_write_current_iac_lap cp;

	if (!hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
		return 0;

	memset(&cp, 0, sizeof(cp));

	if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE)) {
		/* Limited discoverable mode */
		cp.num_iac = min_t(u8, hdev->num_iac, 2);
		cp.iac_lap[0] = 0x00;	/* LIAC */
		cp.iac_lap[1] = 0x8b;
		cp.iac_lap[2] = 0x9e;
		cp.iac_lap[3] = 0x33;	/* GIAC */
		cp.iac_lap[4] = 0x8b;
		cp.iac_lap[5] = 0x9e;
	} else {
		/* General discoverable mode */
		cp.num_iac = 1;
		cp.iac_lap[0] = 0x33;	/* GIAC */
		cp.iac_lap[1] = 0x8b;
		cp.iac_lap[2] = 0x9e;
	}

	return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_CURRENT_IAC_LAP,
				     (cp.num_iac * 3) + 1, &cp,
				     HCI_CMD_TIMEOUT);
}

int hci_update_discoverable_sync(struct hci_dev *hdev)
{
	int err = 0;

	if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
		err = hci_write_iac_sync(hdev);
		if (err)
			return err;

		err = hci_update_scan_sync(hdev);
		if (err)
			return err;

		err = hci_update_class_sync(hdev);
		if (err)
			return err;
	}

	/* Advertising instances don't use the global discoverable setting, so
	 * only update AD if advertising was enabled using Set Advertising.
	 */
	if (hci_dev_test_flag(hdev, HCI_ADVERTISING)) {
		err = hci_update_adv_data_sync(hdev, 0x00);
		if (err)
			return err;

		/* Discoverable mode affects the local advertising
		 * address in limited privacy mode.
		 */
		if (hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY)) {
			if (ext_adv_capable(hdev))
				err = hci_start_ext_adv_sync(hdev, 0x00);
			else
				err = hci_enable_advertising_sync(hdev);
		}
	}

	return err;
}

static int update_discoverable_sync(struct hci_dev *hdev, void *data)
{
	return hci_update_discoverable_sync(hdev);
}

int hci_update_discoverable(struct hci_dev *hdev)
{
	/* Only queue if it would have any effect */
	if (hdev_is_powered(hdev) &&
	    hci_dev_test_flag(hdev, HCI_ADVERTISING) &&
	    hci_dev_test_flag(hdev, HCI_DISCOVERABLE) &&
	    hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY))
		return hci_cmd_sync_queue(hdev, update_discoverable_sync, NULL,
					  NULL);

	return 0;
}

int hci_update_connectable_sync(struct hci_dev *hdev)
{
	int err;

	err = hci_update_scan_sync(hdev);
	if (err)
		return err;

	/* If BR/EDR is not enabled and we disable advertising as a
	 * by-product of disabling connectable, we need to update the
	 * advertising flags.
	 */
	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
		err = hci_update_adv_data_sync(hdev, hdev->cur_adv_instance);

	/* Update the advertising parameters if necessary */
	if (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
	    !list_empty(&hdev->adv_instances)) {
		if (ext_adv_capable(hdev))
			err = hci_start_ext_adv_sync(hdev,
						     hdev->cur_adv_instance);
		else
			err = hci_enable_advertising_sync(hdev);

		if (err)
			return err;
	}

	return hci_update_passive_scan_sync(hdev);
}

static int hci_inquiry_sync(struct hci_dev *hdev, u8 length)
{
	const u8 giac[3] = { 0x33, 0x8b, 0x9e };
	const u8 liac[3] = { 0x00, 0x8b, 0x9e };
	struct hci_cp_inquiry cp;

	bt_dev_dbg(hdev, "");

	if (test_bit(HCI_INQUIRY, &hdev->flags))
		return 0;

	hci_dev_lock(hdev);
	hci_inquiry_cache_flush(hdev);
	hci_dev_unlock(hdev);

	memset(&cp, 0, sizeof(cp));

	if (hdev->discovery.limited)
		memcpy(&cp.lap, liac, sizeof(cp.lap));
	else
		memcpy(&cp.lap, giac, sizeof(cp.lap));

	cp.length = length;

	return __hci_cmd_sync_status(hdev, HCI_OP_INQUIRY,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

static int hci_active_scan_sync(struct hci_dev *hdev, uint16_t interval)
{
	u8 own_addr_type;
	/* Accept list is not used for discovery */
	u8 filter_policy = 0x00;
	/* Default is to enable duplicates filter */
	u8 filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
	int err;

	bt_dev_dbg(hdev, "");

	/* If controller is scanning, it means the passive scanning is
	 * running. Thus, we should temporarily stop it in order to set the
	 * discovery scanning parameters.
	 */
	err = hci_scan_disable_sync(hdev);
	if (err) {
		bt_dev_err(hdev, "Unable to disable scanning: %d", err);
		return err;
	}

	cancel_interleave_scan(hdev);

	/* Pause address resolution for active scan and stop advertising if
	 * privacy is enabled.
	 */
	err = hci_pause_addr_resolution(hdev);
	if (err)
		goto failed;

	/* All active scans will be done with either a resolvable private
	 * address (when privacy feature has been enabled) or non-resolvable
	 * private address.
	 */
	err = hci_update_random_address_sync(hdev, true, scan_use_rpa(hdev),
					     &own_addr_type);
	if (err < 0)
		own_addr_type = ADDR_LE_DEV_PUBLIC;

	if (hci_is_adv_monitoring(hdev) ||
	    (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) &&
	    hdev->discovery.result_filtering)) {
		/* Duplicate filter should be disabled when some advertisement
		 * monitor is activated, otherwise AdvMon can only receive one
		 * advertisement for one peer(*) during active scanning, and
		 * might report loss to these peers.
		 *
		 * If controller does strict duplicate filtering and the
		 * discovery requires result filtering disables controller based
		 * filtering since that can cause reports that would match the
		 * host filter to not be reported.
		 */
		filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
	}

	err = hci_start_scan_sync(hdev, LE_SCAN_ACTIVE, interval,
				  hdev->le_scan_window_discovery,
				  own_addr_type, filter_policy, filter_dup);
	if (!err)
		return err;

failed:
	/* Resume advertising if it was paused */
	if (use_ll_privacy(hdev))
		hci_resume_advertising_sync(hdev);

	/* Resume passive scanning */
	hci_update_passive_scan_sync(hdev);
	return err;
}

static int hci_start_interleaved_discovery_sync(struct hci_dev *hdev)
{
	int err;

	bt_dev_dbg(hdev, "");

	err = hci_active_scan_sync(hdev, hdev->le_scan_int_discovery * 2);
	if (err)
		return err;

	return hci_inquiry_sync(hdev, DISCOV_BREDR_INQUIRY_LEN);
}

int hci_start_discovery_sync(struct hci_dev *hdev)
{
	unsigned long timeout;
	int err;

	bt_dev_dbg(hdev, "type %u", hdev->discovery.type);

	switch (hdev->discovery.type) {
	case DISCOV_TYPE_BREDR:
		return hci_inquiry_sync(hdev, DISCOV_BREDR_INQUIRY_LEN);
	case DISCOV_TYPE_INTERLEAVED:
		/* 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);
			/* During simultaneous discovery, we double LE scan
			 * interval. We must leave some time for the controller
			 * to do BR/EDR inquiry.
			 */
			err = hci_start_interleaved_discovery_sync(hdev);
			break;
		}

		timeout = msecs_to_jiffies(hdev->discov_interleaved_timeout);
		err = hci_active_scan_sync(hdev, hdev->le_scan_int_discovery);
		break;
	case DISCOV_TYPE_LE:
		timeout = msecs_to_jiffies(DISCOV_LE_TIMEOUT);
		err = hci_active_scan_sync(hdev, hdev->le_scan_int_discovery);
		break;
	default:
		return -EINVAL;
	}

	if (err)
		return err;

	bt_dev_dbg(hdev, "timeout %u ms", jiffies_to_msecs(timeout));

	queue_delayed_work(hdev->req_workqueue, &hdev->le_scan_disable,
			   timeout);
	return 0;
}

static void hci_suspend_monitor_sync(struct hci_dev *hdev)
{
	switch (hci_get_adv_monitor_offload_ext(hdev)) {
	case HCI_ADV_MONITOR_EXT_MSFT:
		msft_suspend_sync(hdev);
		break;
	default:
		return;
	}
}

/* This function disables discovery and mark it as paused */
static int hci_pause_discovery_sync(struct hci_dev *hdev)
{
	int old_state = hdev->discovery.state;
	int err;

	/* If discovery already stopped/stopping/paused there nothing to do */
	if (old_state == DISCOVERY_STOPPED || old_state == DISCOVERY_STOPPING ||
	    hdev->discovery_paused)
		return 0;

	hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
	err = hci_stop_discovery_sync(hdev);
	if (err)
		return err;

	hdev->discovery_paused = true;
	hdev->discovery_old_state = old_state;
	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);

	return 0;
}

static int hci_update_event_filter_sync(struct hci_dev *hdev)
{
	struct bdaddr_list_with_flags *b;
	u8 scan = SCAN_DISABLED;
	bool scanning = test_bit(HCI_PSCAN, &hdev->flags);
	int err;

	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
		return 0;

	/* Some fake CSR controllers lock up after setting this type of
	 * filter, so avoid sending the request altogether.
	 */
	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
		return 0;

	/* Always clear event filter when starting */
	hci_clear_event_filter_sync(hdev);

	list_for_each_entry(b, &hdev->accept_list, list) {
		if (!(b->flags & HCI_CONN_FLAG_REMOTE_WAKEUP))
			continue;

		bt_dev_dbg(hdev, "Adding event filters for %pMR", &b->bdaddr);

		err =  hci_set_event_filter_sync(hdev, HCI_FLT_CONN_SETUP,
						 HCI_CONN_SETUP_ALLOW_BDADDR,
						 &b->bdaddr,
						 HCI_CONN_SETUP_AUTO_ON);
		if (err)
			bt_dev_dbg(hdev, "Failed to set event filter for %pMR",
				   &b->bdaddr);
		else
			scan = SCAN_PAGE;
	}

	if (scan && !scanning)
		hci_write_scan_enable_sync(hdev, scan);
	else if (!scan && scanning)
		hci_write_scan_enable_sync(hdev, scan);

	return 0;
}

/* This function disables scan (BR and LE) and mark it as paused */
static int hci_pause_scan_sync(struct hci_dev *hdev)
{
	if (hdev->scanning_paused)
		return 0;

	/* Disable page scan if enabled */
	if (test_bit(HCI_PSCAN, &hdev->flags))
		hci_write_scan_enable_sync(hdev, SCAN_DISABLED);

	hci_scan_disable_sync(hdev);

	hdev->scanning_paused = true;

	return 0;
}

/* This function performs the HCI suspend procedures in the follow order:
 *
 * Pause discovery (active scanning/inquiry)
 * Pause Directed Advertising/Advertising
 * Pause Scanning (passive scanning in case discovery was not active)
 * Disconnect all connections
 * Set suspend_status to BT_SUSPEND_DISCONNECT if hdev cannot wakeup
 * otherwise:
 * Update event mask (only set events that are allowed to wake up the host)
 * Update event filter (with devices marked with HCI_CONN_FLAG_REMOTE_WAKEUP)
 * Update passive scanning (lower duty cycle)
 * Set suspend_status to BT_SUSPEND_CONFIGURE_WAKE
 */
int hci_suspend_sync(struct hci_dev *hdev)
{
	int err;

	/* If marked as suspended there nothing to do */
	if (hdev->suspended)
		return 0;

	/* Mark device as suspended */
	hdev->suspended = true;

	/* Pause discovery if not already stopped */
	hci_pause_discovery_sync(hdev);

	/* Pause other advertisements */
	hci_pause_advertising_sync(hdev);

	/* Suspend monitor filters */
	hci_suspend_monitor_sync(hdev);

	/* Prevent disconnects from causing scanning to be re-enabled */
	hci_pause_scan_sync(hdev);

	if (hci_conn_count(hdev)) {
		/* Soft disconnect everything (power off) */
		err = hci_disconnect_all_sync(hdev, HCI_ERROR_REMOTE_POWER_OFF);
		if (err) {
			/* Set state to BT_RUNNING so resume doesn't notify */
			hdev->suspend_state = BT_RUNNING;
			hci_resume_sync(hdev);
			return err;
		}

		/* Update event mask so only the allowed event can wakeup the
		 * host.
		 */
		hci_set_event_mask_sync(hdev);
	}

	/* Only configure accept list if disconnect succeeded and wake
	 * isn't being prevented.
	 */
	if (!hdev->wakeup || !hdev->wakeup(hdev)) {
		hdev->suspend_state = BT_SUSPEND_DISCONNECT;
		return 0;
	}

	/* Unpause to take care of updating scanning params */
	hdev->scanning_paused = false;

	/* Enable event filter for paired devices */
	hci_update_event_filter_sync(hdev);

	/* Update LE passive scan if enabled */
	hci_update_passive_scan_sync(hdev);

	/* Pause scan changes again. */
	hdev->scanning_paused = true;

	hdev->suspend_state = BT_SUSPEND_CONFIGURE_WAKE;

	return 0;
}

/* This function resumes discovery */
static int hci_resume_discovery_sync(struct hci_dev *hdev)
{
	int err;

	/* If discovery not paused there nothing to do */
	if (!hdev->discovery_paused)
		return 0;

	hdev->discovery_paused = false;

	hci_discovery_set_state(hdev, DISCOVERY_STARTING);

	err = hci_start_discovery_sync(hdev);

	hci_discovery_set_state(hdev, err ? DISCOVERY_STOPPED :
				DISCOVERY_FINDING);

	return err;
}

static void hci_resume_monitor_sync(struct hci_dev *hdev)
{
	switch (hci_get_adv_monitor_offload_ext(hdev)) {
	case HCI_ADV_MONITOR_EXT_MSFT:
		msft_resume_sync(hdev);
		break;
	default:
		return;
	}
}

/* This function resume scan and reset paused flag */
static int hci_resume_scan_sync(struct hci_dev *hdev)
{
	if (!hdev->scanning_paused)
		return 0;

	hdev->scanning_paused = false;

	hci_update_scan_sync(hdev);

	/* Reset passive scanning to normal */
	hci_update_passive_scan_sync(hdev);

	return 0;
}

/* This function performs the HCI suspend procedures in the follow order:
 *
 * Restore event mask
 * Clear event filter
 * Update passive scanning (normal duty cycle)
 * Resume Directed Advertising/Advertising
 * Resume discovery (active scanning/inquiry)
 */
int hci_resume_sync(struct hci_dev *hdev)
{
	/* If not marked as suspended there nothing to do */
	if (!hdev->suspended)
		return 0;

	hdev->suspended = false;

	/* Restore event mask */
	hci_set_event_mask_sync(hdev);

	/* Clear any event filters and restore scan state */
	hci_clear_event_filter_sync(hdev);

	/* Resume scanning */
	hci_resume_scan_sync(hdev);

	/* Resume monitor filters */
	hci_resume_monitor_sync(hdev);

	/* Resume other advertisements */
	hci_resume_advertising_sync(hdev);

	/* Resume discovery */
	hci_resume_discovery_sync(hdev);

	return 0;
}

static bool conn_use_rpa(struct hci_conn *conn)
{
	struct hci_dev *hdev = conn->hdev;

	return hci_dev_test_flag(hdev, HCI_PRIVACY);
}

static int hci_le_ext_directed_advertising_sync(struct hci_dev *hdev,
						struct hci_conn *conn)
{
	struct hci_cp_le_set_ext_adv_params cp;
	int err;
	bdaddr_t random_addr;
	u8 own_addr_type;

	err = hci_update_random_address_sync(hdev, false, conn_use_rpa(conn),
					     &own_addr_type);
	if (err)
		return err;

	/* Set require_privacy to false so that the remote device has a
	 * chance of identifying us.
	 */
	err = hci_get_random_address(hdev, false, conn_use_rpa(conn), NULL,
				     &own_addr_type, &random_addr);
	if (err)
		return err;

	memset(&cp, 0, sizeof(cp));

	cp.evt_properties = cpu_to_le16(LE_LEGACY_ADV_DIRECT_IND);
	cp.channel_map = hdev->le_adv_channel_map;
	cp.tx_power = HCI_TX_POWER_INVALID;
	cp.primary_phy = HCI_ADV_PHY_1M;
	cp.secondary_phy = HCI_ADV_PHY_1M;
	cp.handle = 0x00; /* Use instance 0 for directed adv */
	cp.own_addr_type = own_addr_type;
	cp.peer_addr_type = conn->dst_type;
	bacpy(&cp.peer_addr, &conn->dst);

	/* As per Core Spec 5.2 Vol 2, PART E, Sec 7.8.53, for
	 * advertising_event_property LE_LEGACY_ADV_DIRECT_IND
	 * does not supports advertising data when the advertising set already
	 * contains some, the controller shall return erroc code 'Invalid
	 * HCI Command Parameters(0x12).
	 * So it is required to remove adv set for handle 0x00. since we use
	 * instance 0 for directed adv.
	 */
	err = hci_remove_ext_adv_instance_sync(hdev, cp.handle, NULL);
	if (err)
		return err;

	err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS,
				    sizeof(cp), &cp, HCI_CMD_TIMEOUT);
	if (err)
		return err;

	/* Check if random address need to be updated */
	if (own_addr_type == ADDR_LE_DEV_RANDOM &&
	    bacmp(&random_addr, BDADDR_ANY) &&
	    bacmp(&random_addr, &hdev->random_addr)) {
		err = hci_set_adv_set_random_addr_sync(hdev, 0x00,
						       &random_addr);
		if (err)
			return err;
	}

	return hci_enable_ext_advertising_sync(hdev, 0x00);
}

static int hci_le_directed_advertising_sync(struct hci_dev *hdev,
					    struct hci_conn *conn)
{
	struct hci_cp_le_set_adv_param cp;
	u8 status;
	u8 own_addr_type;
	u8 enable;

	if (ext_adv_capable(hdev))
		return hci_le_ext_directed_advertising_sync(hdev, conn);

	/* Clear the HCI_LE_ADV bit temporarily so that the
	 * hci_update_random_address knows that it's safe to go ahead
	 * and write a new random address. The flag will be set back on
	 * as soon as the SET_ADV_ENABLE HCI command completes.
	 */
	hci_dev_clear_flag(hdev, HCI_LE_ADV);

	/* Set require_privacy to false so that the remote device has a
	 * chance of identifying us.
	 */
	status = hci_update_random_address_sync(hdev, false, conn_use_rpa(conn),
						&own_addr_type);
	if (status)
		return status;

	memset(&cp, 0, sizeof(cp));

	/* Some controllers might reject command if intervals are not
	 * within range for undirected advertising.
	 * BCM20702A0 is known to be affected by this.
	 */
	cp.min_interval = cpu_to_le16(0x0020);
	cp.max_interval = cpu_to_le16(0x0020);

	cp.type = LE_ADV_DIRECT_IND;
	cp.own_address_type = own_addr_type;
	cp.direct_addr_type = conn->dst_type;
	bacpy(&cp.direct_addr, &conn->dst);
	cp.channel_map = hdev->le_adv_channel_map;

	status = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_PARAM,
				       sizeof(cp), &cp, HCI_CMD_TIMEOUT);
	if (status)
		return status;

	enable = 0x01;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_ENABLE,
				     sizeof(enable), &enable, HCI_CMD_TIMEOUT);
}

static void set_ext_conn_params(struct hci_conn *conn,
				struct hci_cp_le_ext_conn_param *p)
{
	struct hci_dev *hdev = conn->hdev;

	memset(p, 0, sizeof(*p));

	p->scan_interval = cpu_to_le16(hdev->le_scan_int_connect);
	p->scan_window = cpu_to_le16(hdev->le_scan_window_connect);
	p->conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
	p->conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
	p->conn_latency = cpu_to_le16(conn->le_conn_latency);
	p->supervision_timeout = cpu_to_le16(conn->le_supv_timeout);
	p->min_ce_len = cpu_to_le16(0x0000);
	p->max_ce_len = cpu_to_le16(0x0000);
}

static int hci_le_ext_create_conn_sync(struct hci_dev *hdev,
				       struct hci_conn *conn, u8 own_addr_type)
{
	struct hci_cp_le_ext_create_conn *cp;
	struct hci_cp_le_ext_conn_param *p;
	u8 data[sizeof(*cp) + sizeof(*p) * 3];
	u32 plen;

	cp = (void *)data;
	p = (void *)cp->data;

	memset(cp, 0, sizeof(*cp));

	bacpy(&cp->peer_addr, &conn->dst);
	cp->peer_addr_type = conn->dst_type;
	cp->own_addr_type = own_addr_type;

	plen = sizeof(*cp);

	if (scan_1m(hdev)) {
		cp->phys |= LE_SCAN_PHY_1M;
		set_ext_conn_params(conn, p);

		p++;
		plen += sizeof(*p);
	}

	if (scan_2m(hdev)) {
		cp->phys |= LE_SCAN_PHY_2M;
		set_ext_conn_params(conn, p);

		p++;
		plen += sizeof(*p);
	}

	if (scan_coded(hdev)) {
		cp->phys |= LE_SCAN_PHY_CODED;
		set_ext_conn_params(conn, p);

		plen += sizeof(*p);
	}

	return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_EXT_CREATE_CONN,
					plen, data,
					HCI_EV_LE_ENHANCED_CONN_COMPLETE,
					conn->conn_timeout, NULL);
}

static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
{
	struct hci_cp_le_create_conn cp;
	struct hci_conn_params *params;
	u8 own_addr_type;
	int err;
	struct hci_conn *conn = data;

	if (!hci_conn_valid(hdev, conn))
		return -ECANCELED;

	bt_dev_dbg(hdev, "conn %p", conn);

	clear_bit(HCI_CONN_SCANNING, &conn->flags);
	conn->state = BT_CONNECT;

	/* If requested to connect as peripheral use directed advertising */
	if (conn->role == HCI_ROLE_SLAVE) {
		/* If we're active scanning and simultaneous roles is not
		 * enabled simply reject the attempt.
		 */
		if (hci_dev_test_flag(hdev, HCI_LE_SCAN) &&
		    hdev->le_scan_type == LE_SCAN_ACTIVE &&
		    !hci_dev_test_flag(hdev, HCI_LE_SIMULTANEOUS_ROLES)) {
			hci_conn_del(conn);
			return -EBUSY;
		}

		/* Pause advertising while doing directed advertising. */
		hci_pause_advertising_sync(hdev);

		err = hci_le_directed_advertising_sync(hdev, conn);
		goto done;
	}

	/* Disable advertising if simultaneous roles is not in use. */
	if (!hci_dev_test_flag(hdev, HCI_LE_SIMULTANEOUS_ROLES))
		hci_pause_advertising_sync(hdev);

	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
	if (params) {
		conn->le_conn_min_interval = params->conn_min_interval;
		conn->le_conn_max_interval = params->conn_max_interval;
		conn->le_conn_latency = params->conn_latency;
		conn->le_supv_timeout = params->supervision_timeout;
	} else {
		conn->le_conn_min_interval = hdev->le_conn_min_interval;
		conn->le_conn_max_interval = hdev->le_conn_max_interval;
		conn->le_conn_latency = hdev->le_conn_latency;
		conn->le_supv_timeout = hdev->le_supv_timeout;
	}

	/* If controller is scanning, we stop it since some controllers are
	 * not able to scan and connect at the same time. Also set the
	 * HCI_LE_SCAN_INTERRUPTED flag so that the command complete
	 * handler for scan disabling knows to set the correct discovery
	 * state.
	 */
	if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
		hci_scan_disable_sync(hdev);
		hci_dev_set_flag(hdev, HCI_LE_SCAN_INTERRUPTED);
	}

	/* Update random address, but set require_privacy to false so
	 * that we never connect with an non-resolvable address.
	 */
	err = hci_update_random_address_sync(hdev, false, conn_use_rpa(conn),
					     &own_addr_type);
	if (err)
		goto done;

	if (use_ext_conn(hdev)) {
		err = hci_le_ext_create_conn_sync(hdev, conn, own_addr_type);
		goto done;
	}

	memset(&cp, 0, sizeof(cp));

	cp.scan_interval = cpu_to_le16(hdev->le_scan_int_connect);
	cp.scan_window = cpu_to_le16(hdev->le_scan_window_connect);

	bacpy(&cp.peer_addr, &conn->dst);
	cp.peer_addr_type = conn->dst_type;
	cp.own_address_type = own_addr_type;
	cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
	cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
	cp.conn_latency = cpu_to_le16(conn->le_conn_latency);
	cp.supervision_timeout = cpu_to_le16(conn->le_supv_timeout);
	cp.min_ce_len = cpu_to_le16(0x0000);
	cp.max_ce_len = cpu_to_le16(0x0000);

	/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 2261:
	 *
	 * If this event is unmasked and the HCI_LE_Connection_Complete event
	 * is unmasked, only the HCI_LE_Enhanced_Connection_Complete event is
	 * sent when a new connection has been created.
	 */
	err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_CREATE_CONN,
				       sizeof(cp), &cp,
				       use_enhanced_conn_complete(hdev) ?
				       HCI_EV_LE_ENHANCED_CONN_COMPLETE :
				       HCI_EV_LE_CONN_COMPLETE,
				       conn->conn_timeout, NULL);

done:
	if (err == -ETIMEDOUT)
		hci_le_connect_cancel_sync(hdev, conn, 0x00);

	/* Re-enable advertising after the connection attempt is finished. */
	hci_resume_advertising_sync(hdev);
	return err;
}

int hci_le_create_cis_sync(struct hci_dev *hdev)
{
	struct {
		struct hci_cp_le_create_cis cp;
		struct hci_cis cis[0x1f];
	} cmd;
	struct hci_conn *conn;
	u8 cig = BT_ISO_QOS_CIG_UNSET;

	/* The spec allows only one pending LE Create CIS command at a time. If
	 * the command is pending now, don't do anything. We check for pending
	 * connections after each CIS Established event.
	 *
	 * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
	 * page 2566:
	 *
	 * If the Host issues this command before all the
	 * HCI_LE_CIS_Established events from the previous use of the
	 * command have been generated, the Controller shall return the
	 * error code Command Disallowed (0x0C).
	 *
	 * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
	 * page 2567:
	 *
	 * When the Controller receives the HCI_LE_Create_CIS command, the
	 * Controller sends the HCI_Command_Status event to the Host. An
	 * HCI_LE_CIS_Established event will be generated for each CIS when it
	 * is established or if it is disconnected or considered lost before
	 * being established; until all the events are generated, the command
	 * remains pending.
	 */

	memset(&cmd, 0, sizeof(cmd));

	hci_dev_lock(hdev);

	rcu_read_lock();

	/* Wait until previous Create CIS has completed */
	list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
		if (test_bit(HCI_CONN_CREATE_CIS, &conn->flags))
			goto done;
	}

	/* Find CIG with all CIS ready */
	list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
		struct hci_conn *link;

		if (hci_conn_check_create_cis(conn))
			continue;

		cig = conn->iso_qos.ucast.cig;

		list_for_each_entry_rcu(link, &hdev->conn_hash.list, list) {
			if (hci_conn_check_create_cis(link) > 0 &&
			    link->iso_qos.ucast.cig == cig &&
			    link->state != BT_CONNECTED) {
				cig = BT_ISO_QOS_CIG_UNSET;
				break;
			}
		}

		if (cig != BT_ISO_QOS_CIG_UNSET)
			break;
	}

	if (cig == BT_ISO_QOS_CIG_UNSET)
		goto done;

	list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
		struct hci_cis *cis = &cmd.cis[cmd.cp.num_cis];

		if (hci_conn_check_create_cis(conn) ||
		    conn->iso_qos.ucast.cig != cig)
			continue;

		set_bit(HCI_CONN_CREATE_CIS, &conn->flags);
		cis->acl_handle = cpu_to_le16(conn->parent->handle);
		cis->cis_handle = cpu_to_le16(conn->handle);
		cmd.cp.num_cis++;

		if (cmd.cp.num_cis >= ARRAY_SIZE(cmd.cis))
			break;
	}

done:
	rcu_read_unlock();

	hci_dev_unlock(hdev);

	if (!cmd.cp.num_cis)
		return 0;

	/* Wait for HCI_LE_CIS_Established */
	return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_CREATE_CIS,
					sizeof(cmd.cp) + sizeof(cmd.cis[0]) *
					cmd.cp.num_cis, &cmd,
					HCI_EVT_LE_CIS_ESTABLISHED,
					conn->conn_timeout, NULL);
}

int hci_le_remove_cig_sync(struct hci_dev *hdev, u8 handle)
{
	struct hci_cp_le_remove_cig cp;

	memset(&cp, 0, sizeof(cp));
	cp.cig_id = handle;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_REMOVE_CIG, sizeof(cp),
				     &cp, HCI_CMD_TIMEOUT);
}

int hci_le_big_terminate_sync(struct hci_dev *hdev, u8 handle)
{
	struct hci_cp_le_big_term_sync cp;

	memset(&cp, 0, sizeof(cp));
	cp.handle = handle;

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_BIG_TERM_SYNC,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

int hci_le_pa_terminate_sync(struct hci_dev *hdev, u16 handle)
{
	struct hci_cp_le_pa_term_sync cp;

	memset(&cp, 0, sizeof(cp));
	cp.handle = cpu_to_le16(handle);

	return __hci_cmd_sync_status(hdev, HCI_OP_LE_PA_TERM_SYNC,
				     sizeof(cp), &cp, HCI_CMD_TIMEOUT);
}

int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
			   bool use_rpa, struct adv_info *adv_instance,
			   u8 *own_addr_type, bdaddr_t *rand_addr)
{
	int err;

	bacpy(rand_addr, BDADDR_ANY);

	/* If privacy is enabled use a resolvable private address. If
	 * current RPA has expired then generate a new one.
	 */
	if (use_rpa) {
		/* If Controller supports LL Privacy use own address type is
		 * 0x03
		 */
		if (use_ll_privacy(hdev))
			*own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED;
		else
			*own_addr_type = ADDR_LE_DEV_RANDOM;

		if (adv_instance) {
			if (adv_rpa_valid(adv_instance))
				return 0;
		} else {
			if (rpa_valid(hdev))
				return 0;
		}

		err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
		if (err < 0) {
			bt_dev_err(hdev, "failed to generate new RPA");
			return err;
		}

		bacpy(rand_addr, &hdev->rpa);

		return 0;
	}

	/* In case of required privacy without resolvable private address,
	 * use an non-resolvable private address. This is useful for
	 * non-connectable advertising.
	 */
	if (require_privacy) {
		bdaddr_t nrpa;

		while (true) {
			/* The non-resolvable private address is generated
			 * from random six bytes with the two most significant
			 * bits cleared.
			 */
			get_random_bytes(&nrpa, 6);
			nrpa.b[5] &= 0x3f;

			/* The non-resolvable private address shall not be
			 * equal to the public address.
			 */
			if (bacmp(&hdev->bdaddr, &nrpa))
				break;
		}

		*own_addr_type = ADDR_LE_DEV_RANDOM;
		bacpy(rand_addr, &nrpa);

		return 0;
	}

	/* No privacy so use a public address. */
	*own_addr_type = ADDR_LE_DEV_PUBLIC;

	return 0;
}

static int _update_adv_data_sync(struct hci_dev *hdev, void *data)
{
	u8 instance = PTR_UINT(data);

	return hci_update_adv_data_sync(hdev, instance);
}

int hci_update_adv_data(struct hci_dev *hdev, u8 instance)
{
	return hci_cmd_sync_queue(hdev, _update_adv_data_sync,
				  UINT_PTR(instance), NULL);
}

static int hci_acl_create_conn_sync(struct hci_dev *hdev, void *data)
{
	struct hci_conn *conn = data;
	struct inquiry_entry *ie;
	struct hci_cp_create_conn cp;
	int err;

	if (!hci_conn_valid(hdev, conn))
		return -ECANCELED;

	/* Many controllers disallow HCI Create Connection while it is doing
	 * HCI Inquiry. So we cancel the Inquiry first before issuing HCI Create
	 * Connection. This may cause the MGMT discovering state to become false
	 * without user space's request but it is okay since the MGMT Discovery
	 * APIs do not promise that discovery should be done forever. Instead,
	 * the user space monitors the status of MGMT discovering and it may
	 * request for discovery again when this flag becomes false.
	 */
	if (test_bit(HCI_INQUIRY, &hdev->flags)) {
		err = __hci_cmd_sync_status(hdev, HCI_OP_INQUIRY_CANCEL, 0,
					    NULL, HCI_CMD_TIMEOUT);
		if (err)
			bt_dev_warn(hdev, "Failed to cancel inquiry %d", err);
	}

	conn->state = BT_CONNECT;
	conn->out = true;
	conn->role = HCI_ROLE_MASTER;

	conn->attempt++;

	conn->link_policy = hdev->link_policy;

	memset(&cp, 0, sizeof(cp));
	bacpy(&cp.bdaddr, &conn->dst);
	cp.pscan_rep_mode = 0x02;

	ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
	if (ie) {
		if (inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
			cp.pscan_rep_mode = ie->data.pscan_rep_mode;
			cp.pscan_mode     = ie->data.pscan_mode;
			cp.clock_offset   = ie->data.clock_offset |
					    cpu_to_le16(0x8000);
		}

		memcpy(conn->dev_class, ie->data.dev_class, 3);
	}

	cp.pkt_type = cpu_to_le16(conn->pkt_type);
	if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
		cp.role_switch = 0x01;
	else
		cp.role_switch = 0x00;

	return __hci_cmd_sync_status_sk(hdev, HCI_OP_CREATE_CONN,
					sizeof(cp), &cp,
					HCI_EV_CONN_COMPLETE,
					conn->conn_timeout, NULL);
}

int hci_connect_acl_sync(struct hci_dev *hdev, struct hci_conn *conn)
{
	return hci_cmd_sync_queue_once(hdev, hci_acl_create_conn_sync, conn,
				       NULL);
}

static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)
{
	struct hci_conn *conn = data;

	bt_dev_dbg(hdev, "err %d", err);

	if (err == -ECANCELED)
		return;

	hci_dev_lock(hdev);

	if (!hci_conn_valid(hdev, conn))
		goto done;

	if (!err) {
		hci_connect_le_scan_cleanup(conn, 0x00);
		goto done;
	}

	/* Check if connection is still pending */
	if (conn != hci_lookup_le_connect(hdev))
		goto done;

	/* Flush to make sure we send create conn cancel command if needed */
	flush_delayed_work(&conn->le_conn_timeout);
	hci_conn_failed(conn, bt_status(err));

done:
	hci_dev_unlock(hdev);
}

int hci_connect_le_sync(struct hci_dev *hdev, struct hci_conn *conn)
{
	return hci_cmd_sync_queue_once(hdev, hci_le_create_conn_sync, conn,
				       create_le_conn_complete);
}

int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn)
{
	if (conn->state != BT_OPEN)
		return -EINVAL;

	switch (conn->type) {
	case ACL_LINK:
		return !hci_cmd_sync_dequeue_once(hdev,
						  hci_acl_create_conn_sync,
						  conn, NULL);
	case LE_LINK:
		return !hci_cmd_sync_dequeue_once(hdev, hci_le_create_conn_sync,
						  conn, create_le_conn_complete);
	}

	return -ENOENT;
}
