xref: /openbmc/linux/net/bluetooth/hci_core.c (revision f4198635)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
4590051deSGustavo F. Padovan    Copyright (C) 2011 ProFUSION Embedded Systems
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds    published by the Free Software Foundation;
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds /* Bluetooth HCI core. */
271da177e4SLinus Torvalds 
288c520a59SGustavo Padovan #include <linux/export.h>
29611b30f7SMarcel Holtmann #include <linux/rfkill.h>
30baf27f6eSMarcel Holtmann #include <linux/debugfs.h>
3199780a7bSJohan Hedberg #include <linux/crypto.h>
329f30de9eSTamas Koczka #include <linux/kcov.h>
337a0e5b15SMatthias Kaehlcke #include <linux/property.h>
349952d90eSAbhishek Pandit-Subedi #include <linux/suspend.h>
359952d90eSAbhishek Pandit-Subedi #include <linux/wait.h>
3647219839SMarcel Holtmann #include <asm/unaligned.h>
371da177e4SLinus Torvalds 
381da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
391da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
404bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h>
41af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h>
421da177e4SLinus Torvalds 
430857dd3bSJohan Hedberg #include "hci_request.h"
4460c5f5fbSMarcel Holtmann #include "hci_debugfs.h"
45970c4e46SJohan Hedberg #include "smp.h"
466d5d2ee6SHeiner Kallweit #include "leds.h"
47145373cbSMiao-chen Chou #include "msft.h"
48f67743f9SMarcel Holtmann #include "aosp.h"
498961987fSKiran K #include "hci_codec.h"
50970c4e46SJohan Hedberg 
51b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
52c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
533eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
541da177e4SLinus Torvalds 
551da177e4SLinus Torvalds /* HCI device list */
561da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
571da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds /* HCI callback list */
601da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
61fba7ecf0SJohan Hedberg DEFINE_MUTEX(hci_cb_list_lock);
621da177e4SLinus Torvalds 
633df92b31SSasha Levin /* HCI ID Numbering */
643df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
653df92b31SSasha Levin 
66a1d01db1SJohan Hedberg static int hci_scan_req(struct hci_request *req, unsigned long opt)
671da177e4SLinus Torvalds {
681da177e4SLinus Torvalds 	__u8 scan = opt;
691da177e4SLinus Torvalds 
7042c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
711da177e4SLinus Torvalds 
721da177e4SLinus Torvalds 	/* Inquiry and Page scans */
7342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
74a1d01db1SJohan Hedberg 	return 0;
751da177e4SLinus Torvalds }
761da177e4SLinus Torvalds 
77a1d01db1SJohan Hedberg static int hci_auth_req(struct hci_request *req, unsigned long opt)
781da177e4SLinus Torvalds {
791da177e4SLinus Torvalds 	__u8 auth = opt;
801da177e4SLinus Torvalds 
8142c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds 	/* Authentication */
8442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
85a1d01db1SJohan Hedberg 	return 0;
861da177e4SLinus Torvalds }
871da177e4SLinus Torvalds 
88a1d01db1SJohan Hedberg static int hci_encrypt_req(struct hci_request *req, unsigned long opt)
891da177e4SLinus Torvalds {
901da177e4SLinus Torvalds 	__u8 encrypt = opt;
911da177e4SLinus Torvalds 
9242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
931da177e4SLinus Torvalds 
94e4e8e37cSMarcel Holtmann 	/* Encryption */
9542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
96a1d01db1SJohan Hedberg 	return 0;
971da177e4SLinus Torvalds }
981da177e4SLinus Torvalds 
99a1d01db1SJohan Hedberg static int hci_linkpol_req(struct hci_request *req, unsigned long opt)
100e4e8e37cSMarcel Holtmann {
101e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
102e4e8e37cSMarcel Holtmann 
10342c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
104e4e8e37cSMarcel Holtmann 
105e4e8e37cSMarcel Holtmann 	/* Default link policy */
10642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
107a1d01db1SJohan Hedberg 	return 0;
108e4e8e37cSMarcel Holtmann }
109e4e8e37cSMarcel Holtmann 
1101da177e4SLinus Torvalds /* Get HCI device by index.
1111da177e4SLinus Torvalds  * Device is held on return. */
1121da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
1131da177e4SLinus Torvalds {
1148035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
1151da177e4SLinus Torvalds 
1161da177e4SLinus Torvalds 	BT_DBG("%d", index);
1171da177e4SLinus Torvalds 
1181da177e4SLinus Torvalds 	if (index < 0)
1191da177e4SLinus Torvalds 		return NULL;
1201da177e4SLinus Torvalds 
1211da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
1228035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
1231da177e4SLinus Torvalds 		if (d->id == index) {
1241da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
1251da177e4SLinus Torvalds 			break;
1261da177e4SLinus Torvalds 		}
1271da177e4SLinus Torvalds 	}
1281da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
1291da177e4SLinus Torvalds 	return hdev;
1301da177e4SLinus Torvalds }
1311da177e4SLinus Torvalds 
1321da177e4SLinus Torvalds /* ---- Inquiry support ---- */
133ff9ef578SJohan Hedberg 
13430dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
13530dc78e1SJohan Hedberg {
13630dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
13730dc78e1SJohan Hedberg 
1386fbe195dSAndre Guedes 	switch (discov->state) {
139343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1406fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
14130dc78e1SJohan Hedberg 		return true;
14230dc78e1SJohan Hedberg 
1436fbe195dSAndre Guedes 	default:
14430dc78e1SJohan Hedberg 		return false;
14530dc78e1SJohan Hedberg 	}
1466fbe195dSAndre Guedes }
14730dc78e1SJohan Hedberg 
148ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
149ff9ef578SJohan Hedberg {
150bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
151bb3e0a33SJohan Hedberg 
152ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
153ff9ef578SJohan Hedberg 
154bb3e0a33SJohan Hedberg 	if (old_state == state)
155ff9ef578SJohan Hedberg 		return;
156ff9ef578SJohan Hedberg 
157bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
158bb3e0a33SJohan Hedberg 
159ff9ef578SJohan Hedberg 	switch (state) {
160ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
1615bee2fd6SLuiz Augusto von Dentz 		hci_update_passive_scan(hdev);
162c54c3860SAndre Guedes 
163bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
164ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
165ff9ef578SJohan Hedberg 		break;
166ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
167ff9ef578SJohan Hedberg 		break;
168343f935bSAndre Guedes 	case DISCOVERY_FINDING:
169ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
170ff9ef578SJohan Hedberg 		break;
17130dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
17230dc78e1SJohan Hedberg 		break;
173ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
174ff9ef578SJohan Hedberg 		break;
175ff9ef578SJohan Hedberg 	}
176ff9ef578SJohan Hedberg }
177ff9ef578SJohan Hedberg 
1781f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
1791da177e4SLinus Torvalds {
18030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
181b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
1821da177e4SLinus Torvalds 
183561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
184561aafbcSJohan Hedberg 		list_del(&p->all);
185b57c1a56SJohan Hedberg 		kfree(p);
1861da177e4SLinus Torvalds 	}
187561aafbcSJohan Hedberg 
188561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
189561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
1901da177e4SLinus Torvalds }
1911da177e4SLinus Torvalds 
192a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
193a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
1941da177e4SLinus Torvalds {
19530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1961da177e4SLinus Torvalds 	struct inquiry_entry *e;
1971da177e4SLinus Torvalds 
1986ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1991da177e4SLinus Torvalds 
200561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
2011da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
2021da177e4SLinus Torvalds 			return e;
2031da177e4SLinus Torvalds 	}
2041da177e4SLinus Torvalds 
205b57c1a56SJohan Hedberg 	return NULL;
206b57c1a56SJohan Hedberg }
207b57c1a56SJohan Hedberg 
208561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
209561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
210561aafbcSJohan Hedberg {
21130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
212561aafbcSJohan Hedberg 	struct inquiry_entry *e;
213561aafbcSJohan Hedberg 
2146ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
215561aafbcSJohan Hedberg 
216561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
217561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
218561aafbcSJohan Hedberg 			return e;
219561aafbcSJohan Hedberg 	}
220561aafbcSJohan Hedberg 
221561aafbcSJohan Hedberg 	return NULL;
222561aafbcSJohan Hedberg }
223561aafbcSJohan Hedberg 
22430dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
22530dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
22630dc78e1SJohan Hedberg 						       int state)
22730dc78e1SJohan Hedberg {
22830dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
22930dc78e1SJohan Hedberg 	struct inquiry_entry *e;
23030dc78e1SJohan Hedberg 
2316ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
23230dc78e1SJohan Hedberg 
23330dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
23430dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
23530dc78e1SJohan Hedberg 			return e;
23630dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
23730dc78e1SJohan Hedberg 			return e;
23830dc78e1SJohan Hedberg 	}
23930dc78e1SJohan Hedberg 
24030dc78e1SJohan Hedberg 	return NULL;
24130dc78e1SJohan Hedberg }
24230dc78e1SJohan Hedberg 
243a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
244a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
245a3d4e20aSJohan Hedberg {
246a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
247a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
248a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
249a3d4e20aSJohan Hedberg 
250a3d4e20aSJohan Hedberg 	list_del(&ie->list);
251a3d4e20aSJohan Hedberg 
252a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
253a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
254a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
255a3d4e20aSJohan Hedberg 			break;
256a3d4e20aSJohan Hedberg 		pos = &p->list;
257a3d4e20aSJohan Hedberg 	}
258a3d4e20aSJohan Hedberg 
259a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
260a3d4e20aSJohan Hedberg }
261a3d4e20aSJohan Hedberg 
262af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
263af58925cSMarcel Holtmann 			     bool name_known)
2641da177e4SLinus Torvalds {
26530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
26670f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
267af58925cSMarcel Holtmann 	u32 flags = 0;
2681da177e4SLinus Torvalds 
2696ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
2701da177e4SLinus Torvalds 
2716928a924SJohan Hedberg 	hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
2722b2fec4dSSzymon Janc 
273af58925cSMarcel Holtmann 	if (!data->ssp_mode)
274af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
275388fc8faSJohan Hedberg 
27670f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
277a3d4e20aSJohan Hedberg 	if (ie) {
278af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
279af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
280388fc8faSJohan Hedberg 
281a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
282a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
283a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
284a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
285a3d4e20aSJohan Hedberg 		}
286a3d4e20aSJohan Hedberg 
287561aafbcSJohan Hedberg 		goto update;
288a3d4e20aSJohan Hedberg 	}
289561aafbcSJohan Hedberg 
2901da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
29127f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
292af58925cSMarcel Holtmann 	if (!ie) {
293af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
294af58925cSMarcel Holtmann 		goto done;
295af58925cSMarcel Holtmann 	}
29670f23020SAndrei Emeltchenko 
297561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
298561aafbcSJohan Hedberg 
299561aafbcSJohan Hedberg 	if (name_known) {
300561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
301561aafbcSJohan Hedberg 	} else {
302561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
303561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
304561aafbcSJohan Hedberg 	}
305561aafbcSJohan Hedberg 
306561aafbcSJohan Hedberg update:
307561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
308561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
309561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
310561aafbcSJohan Hedberg 		list_del(&ie->list);
3111da177e4SLinus Torvalds 	}
3121da177e4SLinus Torvalds 
31370f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
31470f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
3151da177e4SLinus Torvalds 	cache->timestamp = jiffies;
3163175405bSJohan Hedberg 
3173175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
318af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
3193175405bSJohan Hedberg 
320af58925cSMarcel Holtmann done:
321af58925cSMarcel Holtmann 	return flags;
3221da177e4SLinus Torvalds }
3231da177e4SLinus Torvalds 
3241da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
3251da177e4SLinus Torvalds {
32630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
3271da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
3281da177e4SLinus Torvalds 	struct inquiry_entry *e;
3291da177e4SLinus Torvalds 	int copied = 0;
3301da177e4SLinus Torvalds 
331561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
3321da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
333b57c1a56SJohan Hedberg 
334b57c1a56SJohan Hedberg 		if (copied >= num)
335b57c1a56SJohan Hedberg 			break;
336b57c1a56SJohan Hedberg 
3371da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
3381da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
3391da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
3401da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
3411da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
3421da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
343b57c1a56SJohan Hedberg 
3441da177e4SLinus Torvalds 		info++;
345b57c1a56SJohan Hedberg 		copied++;
3461da177e4SLinus Torvalds 	}
3471da177e4SLinus Torvalds 
3481da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
3491da177e4SLinus Torvalds 	return copied;
3501da177e4SLinus Torvalds }
3511da177e4SLinus Torvalds 
352a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt)
3531da177e4SLinus Torvalds {
3541da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
35542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
3561da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
3571da177e4SLinus Torvalds 
3581da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
3591da177e4SLinus Torvalds 
3601da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
361a1d01db1SJohan Hedberg 		return 0;
3621da177e4SLinus Torvalds 
3631da177e4SLinus Torvalds 	/* Start Inquiry */
3641da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
3651da177e4SLinus Torvalds 	cp.length  = ir->length;
3661da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
36742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
368a1d01db1SJohan Hedberg 
369a1d01db1SJohan Hedberg 	return 0;
3701da177e4SLinus Torvalds }
3711da177e4SLinus Torvalds 
3721da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
3731da177e4SLinus Torvalds {
3741da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
3751da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
3761da177e4SLinus Torvalds 	struct hci_dev *hdev;
3771da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
3781da177e4SLinus Torvalds 	long timeo;
3791da177e4SLinus Torvalds 	__u8 *buf;
3801da177e4SLinus Torvalds 
3811da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
3821da177e4SLinus Torvalds 		return -EFAULT;
3831da177e4SLinus Torvalds 
3845a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
3855a08ecceSAndrei Emeltchenko 	if (!hdev)
3861da177e4SLinus Torvalds 		return -ENODEV;
3871da177e4SLinus Torvalds 
388d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
3890736cfa8SMarcel Holtmann 		err = -EBUSY;
3900736cfa8SMarcel Holtmann 		goto done;
3910736cfa8SMarcel Holtmann 	}
3920736cfa8SMarcel Holtmann 
393d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
394fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
395fee746b0SMarcel Holtmann 		goto done;
396fee746b0SMarcel Holtmann 	}
397fee746b0SMarcel Holtmann 
398ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY) {
3995b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
4005b69bef5SMarcel Holtmann 		goto done;
4015b69bef5SMarcel Holtmann 	}
4025b69bef5SMarcel Holtmann 
403d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
40456f87901SJohan Hedberg 		err = -EOPNOTSUPP;
40556f87901SJohan Hedberg 		goto done;
40656f87901SJohan Hedberg 	}
40756f87901SJohan Hedberg 
408f41a4b2bSPavel Skripkin 	/* Restrict maximum inquiry length to 60 seconds */
409f41a4b2bSPavel Skripkin 	if (ir.length > 60) {
410f41a4b2bSPavel Skripkin 		err = -EINVAL;
411f41a4b2bSPavel Skripkin 		goto done;
412f41a4b2bSPavel Skripkin 	}
413f41a4b2bSPavel Skripkin 
41409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4151da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
416a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
4171f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
4181da177e4SLinus Torvalds 		do_inquiry = 1;
4191da177e4SLinus Torvalds 	}
42009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4211da177e4SLinus Torvalds 
42204837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
42370f23020SAndrei Emeltchenko 
42470f23020SAndrei Emeltchenko 	if (do_inquiry) {
42501178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
4264ebeee2dSJohan Hedberg 				   timeo, NULL);
42770f23020SAndrei Emeltchenko 		if (err < 0)
4281da177e4SLinus Torvalds 			goto done;
4293e13fa1eSAndre Guedes 
4303e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
4313e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
4323e13fa1eSAndre Guedes 		 */
43374316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
43428a758c8SPan Bian 				TASK_INTERRUPTIBLE)) {
43528a758c8SPan Bian 			err = -EINTR;
43628a758c8SPan Bian 			goto done;
43728a758c8SPan Bian 		}
43870f23020SAndrei Emeltchenko 	}
4391da177e4SLinus Torvalds 
4408fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
4418fc9ced3SGustavo Padovan 	 * 255 entries
4428fc9ced3SGustavo Padovan 	 */
4431da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
4441da177e4SLinus Torvalds 
4451da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
4461da177e4SLinus Torvalds 	 * copy it to the user space.
4471da177e4SLinus Torvalds 	 */
4486da2ec56SKees Cook 	buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL);
44970f23020SAndrei Emeltchenko 	if (!buf) {
4501da177e4SLinus Torvalds 		err = -ENOMEM;
4511da177e4SLinus Torvalds 		goto done;
4521da177e4SLinus Torvalds 	}
4531da177e4SLinus Torvalds 
45409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4551da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
45609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4571da177e4SLinus Torvalds 
4581da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
4591da177e4SLinus Torvalds 
4601da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
4611da177e4SLinus Torvalds 		ptr += sizeof(ir);
4621da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
4631da177e4SLinus Torvalds 				 ir.num_rsp))
4641da177e4SLinus Torvalds 			err = -EFAULT;
4651da177e4SLinus Torvalds 	} else
4661da177e4SLinus Torvalds 		err = -EFAULT;
4671da177e4SLinus Torvalds 
4681da177e4SLinus Torvalds 	kfree(buf);
4691da177e4SLinus Torvalds 
4701da177e4SLinus Torvalds done:
4711da177e4SLinus Torvalds 	hci_dev_put(hdev);
4721da177e4SLinus Torvalds 	return err;
4731da177e4SLinus Torvalds }
4741da177e4SLinus Torvalds 
475cf75ad8bSLuiz Augusto von Dentz static int hci_dev_do_open(struct hci_dev *hdev)
476cf75ad8bSLuiz Augusto von Dentz {
477cf75ad8bSLuiz Augusto von Dentz 	int ret = 0;
478cf75ad8bSLuiz Augusto von Dentz 
479cf75ad8bSLuiz Augusto von Dentz 	BT_DBG("%s %p", hdev->name, hdev);
480cf75ad8bSLuiz Augusto von Dentz 
481cf75ad8bSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
482cf75ad8bSLuiz Augusto von Dentz 
483cf75ad8bSLuiz Augusto von Dentz 	ret = hci_dev_open_sync(hdev);
484cf75ad8bSLuiz Augusto von Dentz 
485b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
4861da177e4SLinus Torvalds 	return ret;
4871da177e4SLinus Torvalds }
4881da177e4SLinus Torvalds 
489cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
490cbed0ca1SJohan Hedberg 
491cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
492cbed0ca1SJohan Hedberg {
493cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
494cbed0ca1SJohan Hedberg 	int err;
495cbed0ca1SJohan Hedberg 
496cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
497cbed0ca1SJohan Hedberg 	if (!hdev)
498cbed0ca1SJohan Hedberg 		return -ENODEV;
499cbed0ca1SJohan Hedberg 
5004a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
501fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
502fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
503fee746b0SMarcel Holtmann 	 * possible.
504fee746b0SMarcel Holtmann 	 *
505fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
506fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
507fee746b0SMarcel Holtmann 	 * open the device.
508fee746b0SMarcel Holtmann 	 */
509d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
510d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
511fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
512fee746b0SMarcel Holtmann 		goto done;
513fee746b0SMarcel Holtmann 	}
514fee746b0SMarcel Holtmann 
515e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
516e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
517e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
518e1d08f40SJohan Hedberg 	 * completed.
519e1d08f40SJohan Hedberg 	 */
520a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
521e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
522e1d08f40SJohan Hedberg 
523a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
524a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
525a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
526a5c8f270SMarcel Holtmann 	 */
527e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
528e1d08f40SJohan Hedberg 
52912aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
530b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
53112aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
53212aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
53312aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
53412aa4f0aSMarcel Holtmann 	 */
535d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
536d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_MGMT))
537a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BONDABLE);
53812aa4f0aSMarcel Holtmann 
539cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
540cbed0ca1SJohan Hedberg 
541fee746b0SMarcel Holtmann done:
542cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
543cbed0ca1SJohan Hedberg 	return err;
544cbed0ca1SJohan Hedberg }
545cbed0ca1SJohan Hedberg 
546cf75ad8bSLuiz Augusto von Dentz int hci_dev_do_close(struct hci_dev *hdev)
547cf75ad8bSLuiz Augusto von Dentz {
548cf75ad8bSLuiz Augusto von Dentz 	int err;
549cf75ad8bSLuiz Augusto von Dentz 
550cf75ad8bSLuiz Augusto von Dentz 	BT_DBG("%s %p", hdev->name, hdev);
551cf75ad8bSLuiz Augusto von Dentz 
552cf75ad8bSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
553cf75ad8bSLuiz Augusto von Dentz 
554cf75ad8bSLuiz Augusto von Dentz 	err = hci_dev_close_sync(hdev);
555cf75ad8bSLuiz Augusto von Dentz 
556b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
5571da177e4SLinus Torvalds 
55861969ef8SKangmin Park 	return err;
5591da177e4SLinus Torvalds }
5601da177e4SLinus Torvalds 
5611da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
5621da177e4SLinus Torvalds {
5631da177e4SLinus Torvalds 	struct hci_dev *hdev;
5641da177e4SLinus Torvalds 	int err;
5651da177e4SLinus Torvalds 
56670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
56770f23020SAndrei Emeltchenko 	if (!hdev)
5681da177e4SLinus Torvalds 		return -ENODEV;
5698ee56540SMarcel Holtmann 
570d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
5710736cfa8SMarcel Holtmann 		err = -EBUSY;
5720736cfa8SMarcel Holtmann 		goto done;
5730736cfa8SMarcel Holtmann 	}
5740736cfa8SMarcel Holtmann 
575e36bea6eSVasyl Vavrychuk 	cancel_work_sync(&hdev->power_on);
576a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
5778ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
5788ee56540SMarcel Holtmann 
5791da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
5808ee56540SMarcel Holtmann 
5810736cfa8SMarcel Holtmann done:
5821da177e4SLinus Torvalds 	hci_dev_put(hdev);
5831da177e4SLinus Torvalds 	return err;
5841da177e4SLinus Torvalds }
5851da177e4SLinus Torvalds 
5865c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev)
5871da177e4SLinus Torvalds {
5885c912495SMarcel Holtmann 	int ret;
5891da177e4SLinus Torvalds 
5905c912495SMarcel Holtmann 	BT_DBG("%s %p", hdev->name, hdev);
5911da177e4SLinus Torvalds 
592b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
5931da177e4SLinus Torvalds 
5941da177e4SLinus Torvalds 	/* Drop queues */
5951da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
5961da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
5971da177e4SLinus Torvalds 
598877afadaSSchspa Shi 	/* Cancel these to avoid queueing non-chained pending work */
599877afadaSSchspa Shi 	hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
600deee93d1STetsuo Handa 	/* Wait for
601deee93d1STetsuo Handa 	 *
602deee93d1STetsuo Handa 	 *    if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
603deee93d1STetsuo Handa 	 *        queue_delayed_work(&hdev->{cmd,ncmd}_timer)
604deee93d1STetsuo Handa 	 *
605deee93d1STetsuo Handa 	 * inside RCU section to see the flag or complete scheduling.
606deee93d1STetsuo Handa 	 */
607deee93d1STetsuo Handa 	synchronize_rcu();
608deee93d1STetsuo Handa 	/* Explicitly cancel works in case scheduled after setting the flag. */
609877afadaSSchspa Shi 	cancel_delayed_work(&hdev->cmd_timer);
610877afadaSSchspa Shi 	cancel_delayed_work(&hdev->ncmd_timer);
611877afadaSSchspa Shi 
61276727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
61376727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
61476727c02SJohan Hedberg 	 */
61576727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
61676727c02SJohan Hedberg 
61709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6181f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
6191da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
62009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6211da177e4SLinus Torvalds 
6221da177e4SLinus Torvalds 	if (hdev->flush)
6231da177e4SLinus Torvalds 		hdev->flush(hdev);
6241da177e4SLinus Torvalds 
625877afadaSSchspa Shi 	hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
626877afadaSSchspa Shi 
6271da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
62826afbd82SLuiz Augusto von Dentz 	hdev->acl_cnt = 0;
62926afbd82SLuiz Augusto von Dentz 	hdev->sco_cnt = 0;
63026afbd82SLuiz Augusto von Dentz 	hdev->le_cnt = 0;
63126afbd82SLuiz Augusto von Dentz 	hdev->iso_cnt = 0;
6321da177e4SLinus Torvalds 
633d0b13706SLuiz Augusto von Dentz 	ret = hci_reset_sync(hdev);
6341da177e4SLinus Torvalds 
635b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
6361da177e4SLinus Torvalds 	return ret;
6371da177e4SLinus Torvalds }
6381da177e4SLinus Torvalds 
6395c912495SMarcel Holtmann int hci_dev_reset(__u16 dev)
6405c912495SMarcel Holtmann {
6415c912495SMarcel Holtmann 	struct hci_dev *hdev;
6425c912495SMarcel Holtmann 	int err;
6435c912495SMarcel Holtmann 
6445c912495SMarcel Holtmann 	hdev = hci_dev_get(dev);
6455c912495SMarcel Holtmann 	if (!hdev)
6465c912495SMarcel Holtmann 		return -ENODEV;
6475c912495SMarcel Holtmann 
6485c912495SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
6495c912495SMarcel Holtmann 		err = -ENETDOWN;
6505c912495SMarcel Holtmann 		goto done;
6515c912495SMarcel Holtmann 	}
6525c912495SMarcel Holtmann 
653d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6545c912495SMarcel Holtmann 		err = -EBUSY;
6555c912495SMarcel Holtmann 		goto done;
6565c912495SMarcel Holtmann 	}
6575c912495SMarcel Holtmann 
658d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
6595c912495SMarcel Holtmann 		err = -EOPNOTSUPP;
6605c912495SMarcel Holtmann 		goto done;
6615c912495SMarcel Holtmann 	}
6625c912495SMarcel Holtmann 
6635c912495SMarcel Holtmann 	err = hci_dev_do_reset(hdev);
6645c912495SMarcel Holtmann 
6655c912495SMarcel Holtmann done:
6665c912495SMarcel Holtmann 	hci_dev_put(hdev);
6675c912495SMarcel Holtmann 	return err;
6685c912495SMarcel Holtmann }
6695c912495SMarcel Holtmann 
6701da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
6711da177e4SLinus Torvalds {
6721da177e4SLinus Torvalds 	struct hci_dev *hdev;
6731da177e4SLinus Torvalds 	int ret = 0;
6741da177e4SLinus Torvalds 
67570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
67670f23020SAndrei Emeltchenko 	if (!hdev)
6771da177e4SLinus Torvalds 		return -ENODEV;
6781da177e4SLinus Torvalds 
679d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6800736cfa8SMarcel Holtmann 		ret = -EBUSY;
6810736cfa8SMarcel Holtmann 		goto done;
6820736cfa8SMarcel Holtmann 	}
6830736cfa8SMarcel Holtmann 
684d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
685fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
686fee746b0SMarcel Holtmann 		goto done;
687fee746b0SMarcel Holtmann 	}
688fee746b0SMarcel Holtmann 
6891da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
6901da177e4SLinus Torvalds 
6910736cfa8SMarcel Holtmann done:
6921da177e4SLinus Torvalds 	hci_dev_put(hdev);
6931da177e4SLinus Torvalds 	return ret;
6941da177e4SLinus Torvalds }
6951da177e4SLinus Torvalds 
6965bee2fd6SLuiz Augusto von Dentz static void hci_update_passive_scan_state(struct hci_dev *hdev, u8 scan)
697123abc08SJohan Hedberg {
698bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
699123abc08SJohan Hedberg 
700123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
701123abc08SJohan Hedberg 
702123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
703238be788SMarcel Holtmann 		conn_changed = !hci_dev_test_and_set_flag(hdev,
704238be788SMarcel Holtmann 							  HCI_CONNECTABLE);
705123abc08SJohan Hedberg 	else
706a69d8927SMarcel Holtmann 		conn_changed = hci_dev_test_and_clear_flag(hdev,
707a69d8927SMarcel Holtmann 							   HCI_CONNECTABLE);
708123abc08SJohan Hedberg 
709bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
710238be788SMarcel Holtmann 		discov_changed = !hci_dev_test_and_set_flag(hdev,
711238be788SMarcel Holtmann 							    HCI_DISCOVERABLE);
712bc6d2d04SJohan Hedberg 	} else {
713a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
714a69d8927SMarcel Holtmann 		discov_changed = hci_dev_test_and_clear_flag(hdev,
715a69d8927SMarcel Holtmann 							     HCI_DISCOVERABLE);
716bc6d2d04SJohan Hedberg 	}
717bc6d2d04SJohan Hedberg 
718d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
719123abc08SJohan Hedberg 		return;
720123abc08SJohan Hedberg 
721bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
722bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
723a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
724bc6d2d04SJohan Hedberg 
725d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
726651cd3d6SBrian Gix 			hci_update_adv_data(hdev, hdev->cur_adv_instance);
727bc6d2d04SJohan Hedberg 
728123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
729123abc08SJohan Hedberg 	}
730bc6d2d04SJohan Hedberg }
731123abc08SJohan Hedberg 
7321da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
7331da177e4SLinus Torvalds {
7341da177e4SLinus Torvalds 	struct hci_dev *hdev;
7351da177e4SLinus Torvalds 	struct hci_dev_req dr;
7361da177e4SLinus Torvalds 	int err = 0;
7371da177e4SLinus Torvalds 
7381da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
7391da177e4SLinus Torvalds 		return -EFAULT;
7401da177e4SLinus Torvalds 
74170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
74270f23020SAndrei Emeltchenko 	if (!hdev)
7431da177e4SLinus Torvalds 		return -ENODEV;
7441da177e4SLinus Torvalds 
745d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
7460736cfa8SMarcel Holtmann 		err = -EBUSY;
7470736cfa8SMarcel Holtmann 		goto done;
7480736cfa8SMarcel Holtmann 	}
7490736cfa8SMarcel Holtmann 
750d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
751fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
752fee746b0SMarcel Holtmann 		goto done;
753fee746b0SMarcel Holtmann 	}
754fee746b0SMarcel Holtmann 
755ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY) {
7565b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
7575b69bef5SMarcel Holtmann 		goto done;
7585b69bef5SMarcel Holtmann 	}
7595b69bef5SMarcel Holtmann 
760d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
76156f87901SJohan Hedberg 		err = -EOPNOTSUPP;
76256f87901SJohan Hedberg 		goto done;
76356f87901SJohan Hedberg 	}
76456f87901SJohan Hedberg 
7651da177e4SLinus Torvalds 	switch (cmd) {
7661da177e4SLinus Torvalds 	case HCISETAUTH:
76701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
7684ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
7691da177e4SLinus Torvalds 		break;
7701da177e4SLinus Torvalds 
7711da177e4SLinus Torvalds 	case HCISETENCRYPT:
7721da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
7731da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
7741da177e4SLinus Torvalds 			break;
7751da177e4SLinus Torvalds 		}
7761da177e4SLinus Torvalds 
7771da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
7781da177e4SLinus Torvalds 			/* Auth must be enabled first */
77901178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
7804ebeee2dSJohan Hedberg 					   HCI_INIT_TIMEOUT, NULL);
7811da177e4SLinus Torvalds 			if (err)
7821da177e4SLinus Torvalds 				break;
7831da177e4SLinus Torvalds 		}
7841da177e4SLinus Torvalds 
78501178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
7864ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
7871da177e4SLinus Torvalds 		break;
7881da177e4SLinus Torvalds 
7891da177e4SLinus Torvalds 	case HCISETSCAN:
79001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
7914ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
79291a668b0SJohan Hedberg 
793bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
794bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
79591a668b0SJohan Hedberg 		 */
796123abc08SJohan Hedberg 		if (!err)
7975bee2fd6SLuiz Augusto von Dentz 			hci_update_passive_scan_state(hdev, dr.dev_opt);
7981da177e4SLinus Torvalds 		break;
7991da177e4SLinus Torvalds 
8001da177e4SLinus Torvalds 	case HCISETLINKPOL:
80101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
8024ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
8031da177e4SLinus Torvalds 		break;
8041da177e4SLinus Torvalds 
8051da177e4SLinus Torvalds 	case HCISETLINKMODE:
806e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
807e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
808e4e8e37cSMarcel Holtmann 		break;
809e4e8e37cSMarcel Holtmann 
810e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
811b7c23df8SJaganath Kanakkassery 		if (hdev->pkt_type == (__u16) dr.dev_opt)
812b7c23df8SJaganath Kanakkassery 			break;
813b7c23df8SJaganath Kanakkassery 
814e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
815b7c23df8SJaganath Kanakkassery 		mgmt_phy_configuration_changed(hdev, NULL);
8161da177e4SLinus Torvalds 		break;
8171da177e4SLinus Torvalds 
8181da177e4SLinus Torvalds 	case HCISETACLMTU:
8191da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
8201da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
8211da177e4SLinus Torvalds 		break;
8221da177e4SLinus Torvalds 
8231da177e4SLinus Torvalds 	case HCISETSCOMTU:
8241da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
8251da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
8261da177e4SLinus Torvalds 		break;
8271da177e4SLinus Torvalds 
8281da177e4SLinus Torvalds 	default:
8291da177e4SLinus Torvalds 		err = -EINVAL;
8301da177e4SLinus Torvalds 		break;
8311da177e4SLinus Torvalds 	}
832e4e8e37cSMarcel Holtmann 
8330736cfa8SMarcel Holtmann done:
8341da177e4SLinus Torvalds 	hci_dev_put(hdev);
8351da177e4SLinus Torvalds 	return err;
8361da177e4SLinus Torvalds }
8371da177e4SLinus Torvalds 
8381da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
8391da177e4SLinus Torvalds {
8408035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
8411da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
8421da177e4SLinus Torvalds 	struct hci_dev_req *dr;
8431da177e4SLinus Torvalds 	int n = 0, size, err;
8441da177e4SLinus Torvalds 	__u16 dev_num;
8451da177e4SLinus Torvalds 
8461da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
8471da177e4SLinus Torvalds 		return -EFAULT;
8481da177e4SLinus Torvalds 
8491da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
8501da177e4SLinus Torvalds 		return -EINVAL;
8511da177e4SLinus Torvalds 
8521da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
8531da177e4SLinus Torvalds 
85470f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
85570f23020SAndrei Emeltchenko 	if (!dl)
8561da177e4SLinus Torvalds 		return -ENOMEM;
8571da177e4SLinus Torvalds 
8581da177e4SLinus Torvalds 	dr = dl->dev_req;
8591da177e4SLinus Torvalds 
860f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
8618035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
8622e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
863c542a06cSJohan Hedberg 
8642e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
8652e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
8662e84d8dbSMarcel Holtmann 		 * device is actually down.
8672e84d8dbSMarcel Holtmann 		 */
868d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
8692e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
870c542a06cSJohan Hedberg 
8711da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
8722e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
873c542a06cSJohan Hedberg 
8741da177e4SLinus Torvalds 		if (++n >= dev_num)
8751da177e4SLinus Torvalds 			break;
8761da177e4SLinus Torvalds 	}
877f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
8781da177e4SLinus Torvalds 
8791da177e4SLinus Torvalds 	dl->dev_num = n;
8801da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
8811da177e4SLinus Torvalds 
8821da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
8831da177e4SLinus Torvalds 	kfree(dl);
8841da177e4SLinus Torvalds 
8851da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
8861da177e4SLinus Torvalds }
8871da177e4SLinus Torvalds 
8881da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
8891da177e4SLinus Torvalds {
8901da177e4SLinus Torvalds 	struct hci_dev *hdev;
8911da177e4SLinus Torvalds 	struct hci_dev_info di;
8922e84d8dbSMarcel Holtmann 	unsigned long flags;
8931da177e4SLinus Torvalds 	int err = 0;
8941da177e4SLinus Torvalds 
8951da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
8961da177e4SLinus Torvalds 		return -EFAULT;
8971da177e4SLinus Torvalds 
89870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
89970f23020SAndrei Emeltchenko 	if (!hdev)
9001da177e4SLinus Torvalds 		return -ENODEV;
9011da177e4SLinus Torvalds 
9022e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
9032e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
9042e84d8dbSMarcel Holtmann 	 * device is actually down.
9052e84d8dbSMarcel Holtmann 	 */
906d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
9072e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
9082e84d8dbSMarcel Holtmann 	else
9092e84d8dbSMarcel Holtmann 		flags = hdev->flags;
910c542a06cSJohan Hedberg 
9111da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
9121da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
91360f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
9142e84d8dbSMarcel Holtmann 	di.flags    = flags;
9151da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
916572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
9171da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
9181da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
9191da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
9201da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
921572c7f84SJohan Hedberg 	} else {
922572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
923572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
924572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
925572c7f84SJohan Hedberg 		di.sco_pkts = 0;
926572c7f84SJohan Hedberg 	}
9271da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
9281da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
9291da177e4SLinus Torvalds 
9301da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
9311da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
9321da177e4SLinus Torvalds 
9331da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
9341da177e4SLinus Torvalds 		err = -EFAULT;
9351da177e4SLinus Torvalds 
9361da177e4SLinus Torvalds 	hci_dev_put(hdev);
9371da177e4SLinus Torvalds 
9381da177e4SLinus Torvalds 	return err;
9391da177e4SLinus Torvalds }
9401da177e4SLinus Torvalds 
9411da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
9421da177e4SLinus Torvalds 
943611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
944611b30f7SMarcel Holtmann {
945611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
946611b30f7SMarcel Holtmann 
947611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
948611b30f7SMarcel Holtmann 
949d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
9500736cfa8SMarcel Holtmann 		return -EBUSY;
9510736cfa8SMarcel Holtmann 
9525e130367SJohan Hedberg 	if (blocked) {
953a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
954d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
955d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG))
956611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
9575e130367SJohan Hedberg 	} else {
958a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_RFKILLED);
9595e130367SJohan Hedberg 	}
960611b30f7SMarcel Holtmann 
961611b30f7SMarcel Holtmann 	return 0;
962611b30f7SMarcel Holtmann }
963611b30f7SMarcel Holtmann 
964611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
965611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
966611b30f7SMarcel Holtmann };
967611b30f7SMarcel Holtmann 
968ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
969ab81cbf9SJohan Hedberg {
970ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
97196570ffcSJohan Hedberg 	int err;
972ab81cbf9SJohan Hedberg 
973ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
974ab81cbf9SJohan Hedberg 
9752ff13894SJohan Hedberg 	if (test_bit(HCI_UP, &hdev->flags) &&
9762ff13894SJohan Hedberg 	    hci_dev_test_flag(hdev, HCI_MGMT) &&
9772ff13894SJohan Hedberg 	    hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
978d82142a8SWei-Ning Huang 		cancel_delayed_work(&hdev->power_off);
979cf75ad8bSLuiz Augusto von Dentz 		err = hci_powered_update_sync(hdev);
9802ff13894SJohan Hedberg 		mgmt_power_on(hdev, err);
9812ff13894SJohan Hedberg 		return;
9822ff13894SJohan Hedberg 	}
9832ff13894SJohan Hedberg 
984cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
98596570ffcSJohan Hedberg 	if (err < 0) {
9863ad67582SJaganath Kanakkassery 		hci_dev_lock(hdev);
98796570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
9883ad67582SJaganath Kanakkassery 		hci_dev_unlock(hdev);
989ab81cbf9SJohan Hedberg 		return;
99096570ffcSJohan Hedberg 	}
991ab81cbf9SJohan Hedberg 
992a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
993a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
994a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
995a5c8f270SMarcel Holtmann 	 */
996d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
997d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
998ca8bee5dSMarcel Holtmann 	    (hdev->dev_type == HCI_PRIMARY &&
999a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1000a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
1001a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
1002bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
1003d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
100419202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
100519202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
1006bf543036SJohan Hedberg 	}
1007ab81cbf9SJohan Hedberg 
1008a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
10094a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
10104a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
10114a964404SMarcel Holtmann 		 */
1012d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
10134a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
10140602a8adSMarcel Holtmann 
10150602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
10160602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
10170602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
10180602a8adSMarcel Holtmann 		 *
10190602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
10200602a8adSMarcel Holtmann 		 * and no event will be send.
10210602a8adSMarcel Holtmann 		 */
1022744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1023a69d8927SMarcel Holtmann 	} else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
10245ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
10255ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
10265ea234d3SMarcel Holtmann 		 */
1027d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
10285ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
10295ea234d3SMarcel Holtmann 
1030d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
1031d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
1032d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
1033d603b76bSMarcel Holtmann 		 */
1034d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
1035ab81cbf9SJohan Hedberg 	}
1036ab81cbf9SJohan Hedberg }
1037ab81cbf9SJohan Hedberg 
1038ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1039ab81cbf9SJohan Hedberg {
10403243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
10413243553fSJohan Hedberg 					    power_off.work);
1042ab81cbf9SJohan Hedberg 
1043ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1044ab81cbf9SJohan Hedberg 
10458ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1046ab81cbf9SJohan Hedberg }
1047ab81cbf9SJohan Hedberg 
1048c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work)
1049c7741d16SMarcel Holtmann {
1050c7741d16SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
1051c7741d16SMarcel Holtmann 
1052c7741d16SMarcel Holtmann 	BT_DBG("%s", hdev->name);
1053c7741d16SMarcel Holtmann 
1054c7741d16SMarcel Holtmann 	if (hdev->hw_error)
1055c7741d16SMarcel Holtmann 		hdev->hw_error(hdev, hdev->hw_error_code);
1056c7741d16SMarcel Holtmann 	else
10572064ee33SMarcel Holtmann 		bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code);
1058c7741d16SMarcel Holtmann 
1059c7741d16SMarcel Holtmann 	if (hci_dev_do_close(hdev))
1060c7741d16SMarcel Holtmann 		return;
1061c7741d16SMarcel Holtmann 
1062c7741d16SMarcel Holtmann 	hci_dev_do_open(hdev);
1063c7741d16SMarcel Holtmann }
1064c7741d16SMarcel Holtmann 
106535f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
10662aeb9a1aSJohan Hedberg {
10674821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
10682aeb9a1aSJohan Hedberg 
10694821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
10704821002cSJohan Hedberg 		list_del(&uuid->list);
10712aeb9a1aSJohan Hedberg 		kfree(uuid);
10722aeb9a1aSJohan Hedberg 	}
10732aeb9a1aSJohan Hedberg }
10742aeb9a1aSJohan Hedberg 
107535f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
107655ed8ca1SJohan Hedberg {
107755ed8ca1SJohan Hedberg 	struct link_key *key;
107855ed8ca1SJohan Hedberg 
1079d7d41682SMadhuparna Bhowmik 	list_for_each_entry(key, &hdev->link_keys, list) {
10800378b597SJohan Hedberg 		list_del_rcu(&key->list);
10810378b597SJohan Hedberg 		kfree_rcu(key, rcu);
108255ed8ca1SJohan Hedberg 	}
108355ed8ca1SJohan Hedberg }
108455ed8ca1SJohan Hedberg 
108535f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
1086b899efafSVinicius Costa Gomes {
1087970d0f1bSJohan Hedberg 	struct smp_ltk *k;
1088b899efafSVinicius Costa Gomes 
1089d7d41682SMadhuparna Bhowmik 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1090970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
1091970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
1092b899efafSVinicius Costa Gomes 	}
1093b899efafSVinicius Costa Gomes }
1094b899efafSVinicius Costa Gomes 
1095970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
1096970c4e46SJohan Hedberg {
1097adae20cbSJohan Hedberg 	struct smp_irk *k;
1098970c4e46SJohan Hedberg 
1099d7d41682SMadhuparna Bhowmik 	list_for_each_entry(k, &hdev->identity_resolving_keys, list) {
1100adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
1101adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
1102970c4e46SJohan Hedberg 	}
1103970c4e46SJohan Hedberg }
1104970c4e46SJohan Hedberg 
1105600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev)
1106600a8749SAlain Michaud {
1107600a8749SAlain Michaud 	struct blocked_key *b;
1108600a8749SAlain Michaud 
1109d7d41682SMadhuparna Bhowmik 	list_for_each_entry(b, &hdev->blocked_keys, list) {
1110600a8749SAlain Michaud 		list_del_rcu(&b->list);
1111600a8749SAlain Michaud 		kfree_rcu(b, rcu);
1112600a8749SAlain Michaud 	}
1113600a8749SAlain Michaud }
1114600a8749SAlain Michaud 
1115600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16])
1116600a8749SAlain Michaud {
1117600a8749SAlain Michaud 	bool blocked = false;
1118600a8749SAlain Michaud 	struct blocked_key *b;
1119600a8749SAlain Michaud 
1120600a8749SAlain Michaud 	rcu_read_lock();
11210c2ac7d4SMadhuparna Bhowmik 	list_for_each_entry_rcu(b, &hdev->blocked_keys, list) {
1122600a8749SAlain Michaud 		if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) {
1123600a8749SAlain Michaud 			blocked = true;
1124600a8749SAlain Michaud 			break;
1125600a8749SAlain Michaud 		}
1126600a8749SAlain Michaud 	}
1127600a8749SAlain Michaud 
1128600a8749SAlain Michaud 	rcu_read_unlock();
1129600a8749SAlain Michaud 	return blocked;
1130600a8749SAlain Michaud }
1131600a8749SAlain Michaud 
113255ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
113355ed8ca1SJohan Hedberg {
113455ed8ca1SJohan Hedberg 	struct link_key *k;
113555ed8ca1SJohan Hedberg 
11360378b597SJohan Hedberg 	rcu_read_lock();
11370378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
11380378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
11390378b597SJohan Hedberg 			rcu_read_unlock();
1140600a8749SAlain Michaud 
1141600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev,
1142600a8749SAlain Michaud 					       HCI_BLOCKED_KEY_TYPE_LINKKEY,
1143600a8749SAlain Michaud 					       k->val)) {
1144600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
1145600a8749SAlain Michaud 							"Link key blocked for %pMR",
1146600a8749SAlain Michaud 							&k->bdaddr);
1147600a8749SAlain Michaud 				return NULL;
1148600a8749SAlain Michaud 			}
1149600a8749SAlain Michaud 
115055ed8ca1SJohan Hedberg 			return k;
11510378b597SJohan Hedberg 		}
11520378b597SJohan Hedberg 	}
11530378b597SJohan Hedberg 	rcu_read_unlock();
115455ed8ca1SJohan Hedberg 
115555ed8ca1SJohan Hedberg 	return NULL;
115655ed8ca1SJohan Hedberg }
115755ed8ca1SJohan Hedberg 
1158745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1159d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1160d25e28abSJohan Hedberg {
1161d25e28abSJohan Hedberg 	/* Legacy key */
1162d25e28abSJohan Hedberg 	if (key_type < 0x03)
1163745c0ce3SVishal Agarwal 		return true;
1164d25e28abSJohan Hedberg 
1165d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1166d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1167745c0ce3SVishal Agarwal 		return false;
1168d25e28abSJohan Hedberg 
1169d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1170d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1171745c0ce3SVishal Agarwal 		return false;
1172d25e28abSJohan Hedberg 
1173d25e28abSJohan Hedberg 	/* Security mode 3 case */
1174d25e28abSJohan Hedberg 	if (!conn)
1175745c0ce3SVishal Agarwal 		return true;
1176d25e28abSJohan Hedberg 
1177e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
1178e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
1179e3befab9SJohan Hedberg 		return true;
1180e3befab9SJohan Hedberg 
1181d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1182d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1183745c0ce3SVishal Agarwal 		return true;
1184d25e28abSJohan Hedberg 
1185d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1186d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1187745c0ce3SVishal Agarwal 		return true;
1188d25e28abSJohan Hedberg 
1189d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1190d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1191745c0ce3SVishal Agarwal 		return true;
1192d25e28abSJohan Hedberg 
1193d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1194d25e28abSJohan Hedberg 	 * persistently */
1195745c0ce3SVishal Agarwal 	return false;
1196d25e28abSJohan Hedberg }
1197d25e28abSJohan Hedberg 
1198e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
119998a0b845SJohan Hedberg {
1200e804d25dSJohan Hedberg 	if (type == SMP_LTK)
1201e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
120298a0b845SJohan Hedberg 
1203e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
120498a0b845SJohan Hedberg }
120598a0b845SJohan Hedberg 
1206f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
1207e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
120875d262c2SVinicius Costa Gomes {
1209c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
121075d262c2SVinicius Costa Gomes 
1211970d0f1bSJohan Hedberg 	rcu_read_lock();
1212970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
12135378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
12145378bc56SJohan Hedberg 			continue;
12155378bc56SJohan Hedberg 
1216923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
1217970d0f1bSJohan Hedberg 			rcu_read_unlock();
1218600a8749SAlain Michaud 
1219600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK,
1220600a8749SAlain Michaud 					       k->val)) {
1221600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
1222600a8749SAlain Michaud 							"LTK blocked for %pMR",
1223600a8749SAlain Michaud 							&k->bdaddr);
1224600a8749SAlain Michaud 				return NULL;
1225600a8749SAlain Michaud 			}
1226600a8749SAlain Michaud 
122775d262c2SVinicius Costa Gomes 			return k;
1228970d0f1bSJohan Hedberg 		}
1229970d0f1bSJohan Hedberg 	}
1230970d0f1bSJohan Hedberg 	rcu_read_unlock();
123175d262c2SVinicius Costa Gomes 
123275d262c2SVinicius Costa Gomes 	return NULL;
123375d262c2SVinicius Costa Gomes }
123475d262c2SVinicius Costa Gomes 
1235970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
1236970c4e46SJohan Hedberg {
1237600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
1238970c4e46SJohan Hedberg 	struct smp_irk *irk;
1239970c4e46SJohan Hedberg 
1240adae20cbSJohan Hedberg 	rcu_read_lock();
1241adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1242adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
1243600a8749SAlain Michaud 			irk_to_return = irk;
1244600a8749SAlain Michaud 			goto done;
1245970c4e46SJohan Hedberg 		}
1246adae20cbSJohan Hedberg 	}
1247970c4e46SJohan Hedberg 
1248adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1249defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
1250970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
1251600a8749SAlain Michaud 			irk_to_return = irk;
1252600a8749SAlain Michaud 			goto done;
1253970c4e46SJohan Hedberg 		}
1254970c4e46SJohan Hedberg 	}
1255600a8749SAlain Michaud 
1256600a8749SAlain Michaud done:
1257600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
1258600a8749SAlain Michaud 						irk_to_return->val)) {
1259600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
1260600a8749SAlain Michaud 					&irk_to_return->bdaddr);
1261600a8749SAlain Michaud 		irk_to_return = NULL;
1262600a8749SAlain Michaud 	}
1263600a8749SAlain Michaud 
1264adae20cbSJohan Hedberg 	rcu_read_unlock();
1265970c4e46SJohan Hedberg 
1266600a8749SAlain Michaud 	return irk_to_return;
1267970c4e46SJohan Hedberg }
1268970c4e46SJohan Hedberg 
1269970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1270970c4e46SJohan Hedberg 				     u8 addr_type)
1271970c4e46SJohan Hedberg {
1272600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
1273970c4e46SJohan Hedberg 	struct smp_irk *irk;
1274970c4e46SJohan Hedberg 
12756cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
12766cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
12776cfc9988SJohan Hedberg 		return NULL;
12786cfc9988SJohan Hedberg 
1279adae20cbSJohan Hedberg 	rcu_read_lock();
1280adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1281970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
1282adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
1283600a8749SAlain Michaud 			irk_to_return = irk;
1284600a8749SAlain Michaud 			goto done;
1285970c4e46SJohan Hedberg 		}
1286adae20cbSJohan Hedberg 	}
1287600a8749SAlain Michaud 
1288600a8749SAlain Michaud done:
1289600a8749SAlain Michaud 
1290600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
1291600a8749SAlain Michaud 						irk_to_return->val)) {
1292600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
1293600a8749SAlain Michaud 					&irk_to_return->bdaddr);
1294600a8749SAlain Michaud 		irk_to_return = NULL;
1295600a8749SAlain Michaud 	}
1296600a8749SAlain Michaud 
1297adae20cbSJohan Hedberg 	rcu_read_unlock();
1298970c4e46SJohan Hedberg 
1299600a8749SAlain Michaud 	return irk_to_return;
1300970c4e46SJohan Hedberg }
1301970c4e46SJohan Hedberg 
1302567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
13037652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
13047652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
130555ed8ca1SJohan Hedberg {
130655ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1307745c0ce3SVishal Agarwal 	u8 old_key_type;
130855ed8ca1SJohan Hedberg 
130955ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
131055ed8ca1SJohan Hedberg 	if (old_key) {
131155ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
131255ed8ca1SJohan Hedberg 		key = old_key;
131355ed8ca1SJohan Hedberg 	} else {
131412adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
13150a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
131655ed8ca1SJohan Hedberg 		if (!key)
1317567fa2aaSJohan Hedberg 			return NULL;
13180378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
131955ed8ca1SJohan Hedberg 	}
132055ed8ca1SJohan Hedberg 
13216ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
132255ed8ca1SJohan Hedberg 
1323d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1324d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1325d25e28abSJohan Hedberg 	 * previous key */
1326d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1327a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1328d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1329655fe6ecSJohan Hedberg 		if (conn)
1330655fe6ecSJohan Hedberg 			conn->key_type = type;
1331655fe6ecSJohan Hedberg 	}
1332d25e28abSJohan Hedberg 
133355ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
13349b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
133555ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
133655ed8ca1SJohan Hedberg 
1337b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
133855ed8ca1SJohan Hedberg 		key->type = old_key_type;
13394748fed2SJohan Hedberg 	else
13404748fed2SJohan Hedberg 		key->type = type;
13414748fed2SJohan Hedberg 
13427652ff6aSJohan Hedberg 	if (persistent)
13437652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
13447652ff6aSJohan Hedberg 						 old_key_type);
13454df378a1SJohan Hedberg 
1346567fa2aaSJohan Hedberg 	return key;
134755ed8ca1SJohan Hedberg }
134855ed8ca1SJohan Hedberg 
1349ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
135035d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
1351fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
135275d262c2SVinicius Costa Gomes {
1353c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
1354e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
135575d262c2SVinicius Costa Gomes 
1356f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
1357c9839a11SVinicius Costa Gomes 	if (old_key)
135875d262c2SVinicius Costa Gomes 		key = old_key;
1359c9839a11SVinicius Costa Gomes 	else {
13600a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
136175d262c2SVinicius Costa Gomes 		if (!key)
1362ca9142b8SJohan Hedberg 			return NULL;
1363970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
136475d262c2SVinicius Costa Gomes 	}
136575d262c2SVinicius Costa Gomes 
136675d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1367c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1368c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1369c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1370c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1371fe39c7b2SMarcel Holtmann 	key->rand = rand;
1372c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1373c9839a11SVinicius Costa Gomes 	key->type = type;
137475d262c2SVinicius Costa Gomes 
1375ca9142b8SJohan Hedberg 	return key;
137675d262c2SVinicius Costa Gomes }
137775d262c2SVinicius Costa Gomes 
1378ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
1379ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
1380970c4e46SJohan Hedberg {
1381970c4e46SJohan Hedberg 	struct smp_irk *irk;
1382970c4e46SJohan Hedberg 
1383970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
1384970c4e46SJohan Hedberg 	if (!irk) {
1385970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
1386970c4e46SJohan Hedberg 		if (!irk)
1387ca9142b8SJohan Hedberg 			return NULL;
1388970c4e46SJohan Hedberg 
1389970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
1390970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
1391970c4e46SJohan Hedberg 
1392adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
1393970c4e46SJohan Hedberg 	}
1394970c4e46SJohan Hedberg 
1395970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
1396970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
1397970c4e46SJohan Hedberg 
1398ca9142b8SJohan Hedberg 	return irk;
1399970c4e46SJohan Hedberg }
1400970c4e46SJohan Hedberg 
140155ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
140255ed8ca1SJohan Hedberg {
140355ed8ca1SJohan Hedberg 	struct link_key *key;
140455ed8ca1SJohan Hedberg 
140555ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
140655ed8ca1SJohan Hedberg 	if (!key)
140755ed8ca1SJohan Hedberg 		return -ENOENT;
140855ed8ca1SJohan Hedberg 
14096ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
141055ed8ca1SJohan Hedberg 
14110378b597SJohan Hedberg 	list_del_rcu(&key->list);
14120378b597SJohan Hedberg 	kfree_rcu(key, rcu);
141355ed8ca1SJohan Hedberg 
141455ed8ca1SJohan Hedberg 	return 0;
141555ed8ca1SJohan Hedberg }
141655ed8ca1SJohan Hedberg 
1417e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
1418b899efafSVinicius Costa Gomes {
1419970d0f1bSJohan Hedberg 	struct smp_ltk *k;
1420c51ffa0bSJohan Hedberg 	int removed = 0;
1421b899efafSVinicius Costa Gomes 
1422970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
1423e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
1424b899efafSVinicius Costa Gomes 			continue;
1425b899efafSVinicius Costa Gomes 
14266ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1427b899efafSVinicius Costa Gomes 
1428970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
1429970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
1430c51ffa0bSJohan Hedberg 		removed++;
1431b899efafSVinicius Costa Gomes 	}
1432b899efafSVinicius Costa Gomes 
1433c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
1434b899efafSVinicius Costa Gomes }
1435b899efafSVinicius Costa Gomes 
1436a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
1437a7ec7338SJohan Hedberg {
1438adae20cbSJohan Hedberg 	struct smp_irk *k;
1439a7ec7338SJohan Hedberg 
1440adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
1441a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
1442a7ec7338SJohan Hedberg 			continue;
1443a7ec7338SJohan Hedberg 
1444a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1445a7ec7338SJohan Hedberg 
1446adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
1447adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
1448a7ec7338SJohan Hedberg 	}
1449a7ec7338SJohan Hedberg }
1450a7ec7338SJohan Hedberg 
145155e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
145255e76b38SJohan Hedberg {
145355e76b38SJohan Hedberg 	struct smp_ltk *k;
14544ba9faf3SJohan Hedberg 	struct smp_irk *irk;
145555e76b38SJohan Hedberg 	u8 addr_type;
145655e76b38SJohan Hedberg 
145755e76b38SJohan Hedberg 	if (type == BDADDR_BREDR) {
145855e76b38SJohan Hedberg 		if (hci_find_link_key(hdev, bdaddr))
145955e76b38SJohan Hedberg 			return true;
146055e76b38SJohan Hedberg 		return false;
146155e76b38SJohan Hedberg 	}
146255e76b38SJohan Hedberg 
146355e76b38SJohan Hedberg 	/* Convert to HCI addr type which struct smp_ltk uses */
146455e76b38SJohan Hedberg 	if (type == BDADDR_LE_PUBLIC)
146555e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_PUBLIC;
146655e76b38SJohan Hedberg 	else
146755e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_RANDOM;
146855e76b38SJohan Hedberg 
14694ba9faf3SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, addr_type);
14704ba9faf3SJohan Hedberg 	if (irk) {
14714ba9faf3SJohan Hedberg 		bdaddr = &irk->bdaddr;
14724ba9faf3SJohan Hedberg 		addr_type = irk->addr_type;
14734ba9faf3SJohan Hedberg 	}
14744ba9faf3SJohan Hedberg 
147555e76b38SJohan Hedberg 	rcu_read_lock();
147655e76b38SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
147787c8b28dSJohan Hedberg 		if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) {
147887c8b28dSJohan Hedberg 			rcu_read_unlock();
147955e76b38SJohan Hedberg 			return true;
148055e76b38SJohan Hedberg 		}
148187c8b28dSJohan Hedberg 	}
148255e76b38SJohan Hedberg 	rcu_read_unlock();
148355e76b38SJohan Hedberg 
148455e76b38SJohan Hedberg 	return false;
148555e76b38SJohan Hedberg }
148655e76b38SJohan Hedberg 
14876bd32326SVille Tervo /* HCI command timer function */
148865cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
14896bd32326SVille Tervo {
149065cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
149165cc2b49SMarcel Holtmann 					    cmd_timer.work);
14926bd32326SVille Tervo 
1493bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
1494bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
1495bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
1496bda4f23aSAndrei Emeltchenko 
14972064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode);
1498bda4f23aSAndrei Emeltchenko 	} else {
14992064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command tx timeout");
1500bda4f23aSAndrei Emeltchenko 	}
1501bda4f23aSAndrei Emeltchenko 
1502e2bef384SRajat Jain 	if (hdev->cmd_timeout)
1503e2bef384SRajat Jain 		hdev->cmd_timeout(hdev);
1504e2bef384SRajat Jain 
15056bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1506c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
15076bd32326SVille Tervo }
15086bd32326SVille Tervo 
1509de75cd0dSManish Mandlik /* HCI ncmd timer function */
1510de75cd0dSManish Mandlik static void hci_ncmd_timeout(struct work_struct *work)
1511de75cd0dSManish Mandlik {
1512de75cd0dSManish Mandlik 	struct hci_dev *hdev = container_of(work, struct hci_dev,
1513de75cd0dSManish Mandlik 					    ncmd_timer.work);
1514de75cd0dSManish Mandlik 
1515de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Controller not accepting commands anymore: ncmd = 0");
1516de75cd0dSManish Mandlik 
1517de75cd0dSManish Mandlik 	/* During HCI_INIT phase no events can be injected if the ncmd timer
1518de75cd0dSManish Mandlik 	 * triggers since the procedure has its own timeout handling.
1519de75cd0dSManish Mandlik 	 */
1520de75cd0dSManish Mandlik 	if (test_bit(HCI_INIT, &hdev->flags))
1521de75cd0dSManish Mandlik 		return;
1522de75cd0dSManish Mandlik 
1523de75cd0dSManish Mandlik 	/* This is an irrecoverable state, inject hardware error event */
1524de75cd0dSManish Mandlik 	hci_reset_dev(hdev);
1525de75cd0dSManish Mandlik }
1526de75cd0dSManish Mandlik 
15272763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
15286928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
15292763eda6SSzymon Janc {
15302763eda6SSzymon Janc 	struct oob_data *data;
15312763eda6SSzymon Janc 
15326928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
15336928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
15346928a924SJohan Hedberg 			continue;
15356928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
15366928a924SJohan Hedberg 			continue;
15372763eda6SSzymon Janc 		return data;
15386928a924SJohan Hedberg 	}
15392763eda6SSzymon Janc 
15402763eda6SSzymon Janc 	return NULL;
15412763eda6SSzymon Janc }
15422763eda6SSzymon Janc 
15436928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
15446928a924SJohan Hedberg 			       u8 bdaddr_type)
15452763eda6SSzymon Janc {
15462763eda6SSzymon Janc 	struct oob_data *data;
15472763eda6SSzymon Janc 
15486928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
15492763eda6SSzymon Janc 	if (!data)
15502763eda6SSzymon Janc 		return -ENOENT;
15512763eda6SSzymon Janc 
15526928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
15532763eda6SSzymon Janc 
15542763eda6SSzymon Janc 	list_del(&data->list);
15552763eda6SSzymon Janc 	kfree(data);
15562763eda6SSzymon Janc 
15572763eda6SSzymon Janc 	return 0;
15582763eda6SSzymon Janc }
15592763eda6SSzymon Janc 
156035f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
15612763eda6SSzymon Janc {
15622763eda6SSzymon Janc 	struct oob_data *data, *n;
15632763eda6SSzymon Janc 
15642763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
15652763eda6SSzymon Janc 		list_del(&data->list);
15662763eda6SSzymon Janc 		kfree(data);
15672763eda6SSzymon Janc 	}
15682763eda6SSzymon Janc }
15692763eda6SSzymon Janc 
15700798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
15716928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
157238da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
15730798872eSMarcel Holtmann {
15740798872eSMarcel Holtmann 	struct oob_data *data;
15750798872eSMarcel Holtmann 
15766928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
15770798872eSMarcel Holtmann 	if (!data) {
15780a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
15790798872eSMarcel Holtmann 		if (!data)
15800798872eSMarcel Holtmann 			return -ENOMEM;
15810798872eSMarcel Holtmann 
15820798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
15836928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
15840798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
15850798872eSMarcel Holtmann 	}
15860798872eSMarcel Holtmann 
158781328d5cSJohan Hedberg 	if (hash192 && rand192) {
15880798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
158938da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
1590f7697b16SMarcel Holtmann 		if (hash256 && rand256)
1591f7697b16SMarcel Holtmann 			data->present = 0x03;
159281328d5cSJohan Hedberg 	} else {
159381328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
159481328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
1595f7697b16SMarcel Holtmann 		if (hash256 && rand256)
1596f7697b16SMarcel Holtmann 			data->present = 0x02;
1597f7697b16SMarcel Holtmann 		else
1598f7697b16SMarcel Holtmann 			data->present = 0x00;
159981328d5cSJohan Hedberg 	}
16000798872eSMarcel Holtmann 
160181328d5cSJohan Hedberg 	if (hash256 && rand256) {
16020798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
160338da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
160481328d5cSJohan Hedberg 	} else {
160581328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
160681328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
1607f7697b16SMarcel Holtmann 		if (hash192 && rand192)
1608f7697b16SMarcel Holtmann 			data->present = 0x01;
160981328d5cSJohan Hedberg 	}
16100798872eSMarcel Holtmann 
16116ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
16122763eda6SSzymon Janc 
16132763eda6SSzymon Janc 	return 0;
16142763eda6SSzymon Janc }
16152763eda6SSzymon Janc 
1616d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1617d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance)
1618d2609b34SFlorian Grandel {
1619d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
1620d2609b34SFlorian Grandel 
1621d2609b34SFlorian Grandel 	list_for_each_entry(adv_instance, &hdev->adv_instances, list) {
1622d2609b34SFlorian Grandel 		if (adv_instance->instance == instance)
1623d2609b34SFlorian Grandel 			return adv_instance;
1624d2609b34SFlorian Grandel 	}
1625d2609b34SFlorian Grandel 
1626d2609b34SFlorian Grandel 	return NULL;
1627d2609b34SFlorian Grandel }
1628d2609b34SFlorian Grandel 
1629d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
163074b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance)
163174b93e9fSPrasanna Karthik {
1632d2609b34SFlorian Grandel 	struct adv_info *cur_instance;
1633d2609b34SFlorian Grandel 
1634d2609b34SFlorian Grandel 	cur_instance = hci_find_adv_instance(hdev, instance);
1635d2609b34SFlorian Grandel 	if (!cur_instance)
1636d2609b34SFlorian Grandel 		return NULL;
1637d2609b34SFlorian Grandel 
1638d2609b34SFlorian Grandel 	if (cur_instance == list_last_entry(&hdev->adv_instances,
1639d2609b34SFlorian Grandel 					    struct adv_info, list))
1640d2609b34SFlorian Grandel 		return list_first_entry(&hdev->adv_instances,
1641d2609b34SFlorian Grandel 						 struct adv_info, list);
1642d2609b34SFlorian Grandel 	else
1643d2609b34SFlorian Grandel 		return list_next_entry(cur_instance, list);
1644d2609b34SFlorian Grandel }
1645d2609b34SFlorian Grandel 
1646d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1647d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance)
1648d2609b34SFlorian Grandel {
1649d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
1650d2609b34SFlorian Grandel 
1651d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
1652d2609b34SFlorian Grandel 	if (!adv_instance)
1653d2609b34SFlorian Grandel 		return -ENOENT;
1654d2609b34SFlorian Grandel 
1655d2609b34SFlorian Grandel 	BT_DBG("%s removing %dMR", hdev->name, instance);
1656d2609b34SFlorian Grandel 
1657cab054abSJohan Hedberg 	if (hdev->cur_adv_instance == instance) {
1658cab054abSJohan Hedberg 		if (hdev->adv_instance_timeout) {
16595d900e46SFlorian Grandel 			cancel_delayed_work(&hdev->adv_instance_expire);
16605d900e46SFlorian Grandel 			hdev->adv_instance_timeout = 0;
16615d900e46SFlorian Grandel 		}
1662cab054abSJohan Hedberg 		hdev->cur_adv_instance = 0x00;
1663cab054abSJohan Hedberg 	}
16645d900e46SFlorian Grandel 
1665a73c046aSJaganath Kanakkassery 	cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1666a73c046aSJaganath Kanakkassery 
1667d2609b34SFlorian Grandel 	list_del(&adv_instance->list);
1668d2609b34SFlorian Grandel 	kfree(adv_instance);
1669d2609b34SFlorian Grandel 
1670d2609b34SFlorian Grandel 	hdev->adv_instance_cnt--;
1671d2609b34SFlorian Grandel 
1672d2609b34SFlorian Grandel 	return 0;
1673d2609b34SFlorian Grandel }
1674d2609b34SFlorian Grandel 
1675a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired)
1676a73c046aSJaganath Kanakkassery {
1677a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance, *n;
1678a73c046aSJaganath Kanakkassery 
1679a73c046aSJaganath Kanakkassery 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list)
1680a73c046aSJaganath Kanakkassery 		adv_instance->rpa_expired = rpa_expired;
1681a73c046aSJaganath Kanakkassery }
1682a73c046aSJaganath Kanakkassery 
1683d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1684d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev)
1685d2609b34SFlorian Grandel {
1686d2609b34SFlorian Grandel 	struct adv_info *adv_instance, *n;
1687d2609b34SFlorian Grandel 
16885d900e46SFlorian Grandel 	if (hdev->adv_instance_timeout) {
16895d900e46SFlorian Grandel 		cancel_delayed_work(&hdev->adv_instance_expire);
16905d900e46SFlorian Grandel 		hdev->adv_instance_timeout = 0;
16915d900e46SFlorian Grandel 	}
16925d900e46SFlorian Grandel 
1693d2609b34SFlorian Grandel 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
1694a73c046aSJaganath Kanakkassery 		cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1695d2609b34SFlorian Grandel 		list_del(&adv_instance->list);
1696d2609b34SFlorian Grandel 		kfree(adv_instance);
1697d2609b34SFlorian Grandel 	}
1698d2609b34SFlorian Grandel 
1699d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
1700cab054abSJohan Hedberg 	hdev->cur_adv_instance = 0x00;
1701d2609b34SFlorian Grandel }
1702d2609b34SFlorian Grandel 
1703a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work)
1704a73c046aSJaganath Kanakkassery {
1705a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance = container_of(work, struct adv_info,
1706a73c046aSJaganath Kanakkassery 						     rpa_expired_cb.work);
1707a73c046aSJaganath Kanakkassery 
1708a73c046aSJaganath Kanakkassery 	BT_DBG("");
1709a73c046aSJaganath Kanakkassery 
1710a73c046aSJaganath Kanakkassery 	adv_instance->rpa_expired = true;
1711a73c046aSJaganath Kanakkassery }
1712a73c046aSJaganath Kanakkassery 
1713d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1714eca0ae4aSLuiz Augusto von Dentz struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
1715eca0ae4aSLuiz Augusto von Dentz 				      u32 flags, u16 adv_data_len, u8 *adv_data,
1716d2609b34SFlorian Grandel 				      u16 scan_rsp_len, u8 *scan_rsp_data,
17179bf9f4b6SDaniel Winkler 				      u16 timeout, u16 duration, s8 tx_power,
1718b338d917SBrian Gix 				      u32 min_interval, u32 max_interval,
1719b338d917SBrian Gix 				      u8 mesh_handle)
1720d2609b34SFlorian Grandel {
1721eca0ae4aSLuiz Augusto von Dentz 	struct adv_info *adv;
1722d2609b34SFlorian Grandel 
1723eca0ae4aSLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
1724eca0ae4aSLuiz Augusto von Dentz 	if (adv) {
1725eca0ae4aSLuiz Augusto von Dentz 		memset(adv->adv_data, 0, sizeof(adv->adv_data));
1726eca0ae4aSLuiz Augusto von Dentz 		memset(adv->scan_rsp_data, 0, sizeof(adv->scan_rsp_data));
1727eca0ae4aSLuiz Augusto von Dentz 		memset(adv->per_adv_data, 0, sizeof(adv->per_adv_data));
1728d2609b34SFlorian Grandel 	} else {
17291d0fac2cSLuiz Augusto von Dentz 		if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets ||
1730b338d917SBrian Gix 		    instance < 1 || instance > hdev->le_num_of_adv_sets + 1)
1731eca0ae4aSLuiz Augusto von Dentz 			return ERR_PTR(-EOVERFLOW);
1732d2609b34SFlorian Grandel 
1733eca0ae4aSLuiz Augusto von Dentz 		adv = kzalloc(sizeof(*adv), GFP_KERNEL);
1734eca0ae4aSLuiz Augusto von Dentz 		if (!adv)
1735eca0ae4aSLuiz Augusto von Dentz 			return ERR_PTR(-ENOMEM);
1736d2609b34SFlorian Grandel 
1737eca0ae4aSLuiz Augusto von Dentz 		adv->pending = true;
1738eca0ae4aSLuiz Augusto von Dentz 		adv->instance = instance;
1739eca0ae4aSLuiz Augusto von Dentz 		list_add(&adv->list, &hdev->adv_instances);
1740d2609b34SFlorian Grandel 		hdev->adv_instance_cnt++;
1741d2609b34SFlorian Grandel 	}
1742d2609b34SFlorian Grandel 
1743eca0ae4aSLuiz Augusto von Dentz 	adv->flags = flags;
1744eca0ae4aSLuiz Augusto von Dentz 	adv->min_interval = min_interval;
1745eca0ae4aSLuiz Augusto von Dentz 	adv->max_interval = max_interval;
1746eca0ae4aSLuiz Augusto von Dentz 	adv->tx_power = tx_power;
1747b338d917SBrian Gix 	/* Defining a mesh_handle changes the timing units to ms,
1748b338d917SBrian Gix 	 * rather than seconds, and ties the instance to the requested
1749b338d917SBrian Gix 	 * mesh_tx queue.
1750b338d917SBrian Gix 	 */
1751b338d917SBrian Gix 	adv->mesh = mesh_handle;
1752d2609b34SFlorian Grandel 
175334a718bcSLuiz Augusto von Dentz 	hci_set_adv_instance_data(hdev, instance, adv_data_len, adv_data,
175434a718bcSLuiz Augusto von Dentz 				  scan_rsp_len, scan_rsp_data);
1755d2609b34SFlorian Grandel 
1756eca0ae4aSLuiz Augusto von Dentz 	adv->timeout = timeout;
1757eca0ae4aSLuiz Augusto von Dentz 	adv->remaining_time = timeout;
1758d2609b34SFlorian Grandel 
1759d2609b34SFlorian Grandel 	if (duration == 0)
1760eca0ae4aSLuiz Augusto von Dentz 		adv->duration = hdev->def_multi_adv_rotation_duration;
1761d2609b34SFlorian Grandel 	else
1762eca0ae4aSLuiz Augusto von Dentz 		adv->duration = duration;
1763d2609b34SFlorian Grandel 
1764eca0ae4aSLuiz Augusto von Dentz 	INIT_DELAYED_WORK(&adv->rpa_expired_cb, adv_instance_rpa_expired);
1765a73c046aSJaganath Kanakkassery 
1766d2609b34SFlorian Grandel 	BT_DBG("%s for %dMR", hdev->name, instance);
1767d2609b34SFlorian Grandel 
1768eca0ae4aSLuiz Augusto von Dentz 	return adv;
1769eca0ae4aSLuiz Augusto von Dentz }
1770eca0ae4aSLuiz Augusto von Dentz 
1771eca0ae4aSLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */
1772eca0ae4aSLuiz Augusto von Dentz struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance,
1773eca0ae4aSLuiz Augusto von Dentz 				      u32 flags, u8 data_len, u8 *data,
1774eca0ae4aSLuiz Augusto von Dentz 				      u32 min_interval, u32 max_interval)
1775eca0ae4aSLuiz Augusto von Dentz {
1776eca0ae4aSLuiz Augusto von Dentz 	struct adv_info *adv;
1777eca0ae4aSLuiz Augusto von Dentz 
1778eca0ae4aSLuiz Augusto von Dentz 	adv = hci_add_adv_instance(hdev, instance, flags, 0, NULL, 0, NULL,
1779eca0ae4aSLuiz Augusto von Dentz 				   0, 0, HCI_ADV_TX_POWER_NO_PREFERENCE,
1780b338d917SBrian Gix 				   min_interval, max_interval, 0);
1781eca0ae4aSLuiz Augusto von Dentz 	if (IS_ERR(adv))
1782eca0ae4aSLuiz Augusto von Dentz 		return adv;
1783eca0ae4aSLuiz Augusto von Dentz 
1784eca0ae4aSLuiz Augusto von Dentz 	adv->periodic = true;
1785eca0ae4aSLuiz Augusto von Dentz 	adv->per_adv_data_len = data_len;
1786eca0ae4aSLuiz Augusto von Dentz 
1787eca0ae4aSLuiz Augusto von Dentz 	if (data)
1788eca0ae4aSLuiz Augusto von Dentz 		memcpy(adv->per_adv_data, data, data_len);
1789eca0ae4aSLuiz Augusto von Dentz 
1790eca0ae4aSLuiz Augusto von Dentz 	return adv;
1791d2609b34SFlorian Grandel }
1792d2609b34SFlorian Grandel 
1793e5e1e7fdSMiao-chen Chou /* This function requires the caller holds hdev->lock */
179431aab5c2SDaniel Winkler int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance,
179531aab5c2SDaniel Winkler 			      u16 adv_data_len, u8 *adv_data,
179631aab5c2SDaniel Winkler 			      u16 scan_rsp_len, u8 *scan_rsp_data)
179731aab5c2SDaniel Winkler {
179834a718bcSLuiz Augusto von Dentz 	struct adv_info *adv;
179931aab5c2SDaniel Winkler 
180034a718bcSLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
180131aab5c2SDaniel Winkler 
180231aab5c2SDaniel Winkler 	/* If advertisement doesn't exist, we can't modify its data */
180334a718bcSLuiz Augusto von Dentz 	if (!adv)
180431aab5c2SDaniel Winkler 		return -ENOENT;
180531aab5c2SDaniel Winkler 
180634a718bcSLuiz Augusto von Dentz 	if (adv_data_len && ADV_DATA_CMP(adv, adv_data, adv_data_len)) {
180734a718bcSLuiz Augusto von Dentz 		memset(adv->adv_data, 0, sizeof(adv->adv_data));
180834a718bcSLuiz Augusto von Dentz 		memcpy(adv->adv_data, adv_data, adv_data_len);
180934a718bcSLuiz Augusto von Dentz 		adv->adv_data_len = adv_data_len;
181034a718bcSLuiz Augusto von Dentz 		adv->adv_data_changed = true;
181131aab5c2SDaniel Winkler 	}
181231aab5c2SDaniel Winkler 
181334a718bcSLuiz Augusto von Dentz 	if (scan_rsp_len && SCAN_RSP_CMP(adv, scan_rsp_data, scan_rsp_len)) {
181434a718bcSLuiz Augusto von Dentz 		memset(adv->scan_rsp_data, 0, sizeof(adv->scan_rsp_data));
181534a718bcSLuiz Augusto von Dentz 		memcpy(adv->scan_rsp_data, scan_rsp_data, scan_rsp_len);
181634a718bcSLuiz Augusto von Dentz 		adv->scan_rsp_len = scan_rsp_len;
181734a718bcSLuiz Augusto von Dentz 		adv->scan_rsp_changed = true;
181831aab5c2SDaniel Winkler 	}
181931aab5c2SDaniel Winkler 
182034a718bcSLuiz Augusto von Dentz 	/* Mark as changed if there are flags which would affect it */
182134a718bcSLuiz Augusto von Dentz 	if (((adv->flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance) ||
182234a718bcSLuiz Augusto von Dentz 	    adv->flags & MGMT_ADV_FLAG_LOCAL_NAME)
182334a718bcSLuiz Augusto von Dentz 		adv->scan_rsp_changed = true;
182434a718bcSLuiz Augusto von Dentz 
182531aab5c2SDaniel Winkler 	return 0;
182631aab5c2SDaniel Winkler }
182731aab5c2SDaniel Winkler 
182831aab5c2SDaniel Winkler /* This function requires the caller holds hdev->lock */
182901ce70b0SLuiz Augusto von Dentz u32 hci_adv_instance_flags(struct hci_dev *hdev, u8 instance)
183001ce70b0SLuiz Augusto von Dentz {
183101ce70b0SLuiz Augusto von Dentz 	u32 flags;
183201ce70b0SLuiz Augusto von Dentz 	struct adv_info *adv;
183301ce70b0SLuiz Augusto von Dentz 
183401ce70b0SLuiz Augusto von Dentz 	if (instance == 0x00) {
183501ce70b0SLuiz Augusto von Dentz 		/* Instance 0 always manages the "Tx Power" and "Flags"
183601ce70b0SLuiz Augusto von Dentz 		 * fields
183701ce70b0SLuiz Augusto von Dentz 		 */
183801ce70b0SLuiz Augusto von Dentz 		flags = MGMT_ADV_FLAG_TX_POWER | MGMT_ADV_FLAG_MANAGED_FLAGS;
183901ce70b0SLuiz Augusto von Dentz 
184001ce70b0SLuiz Augusto von Dentz 		/* For instance 0, the HCI_ADVERTISING_CONNECTABLE setting
184101ce70b0SLuiz Augusto von Dentz 		 * corresponds to the "connectable" instance flag.
184201ce70b0SLuiz Augusto von Dentz 		 */
184301ce70b0SLuiz Augusto von Dentz 		if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE))
184401ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_CONNECTABLE;
184501ce70b0SLuiz Augusto von Dentz 
184601ce70b0SLuiz Augusto von Dentz 		if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
184701ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
184801ce70b0SLuiz Augusto von Dentz 		else if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
184901ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_DISCOV;
185001ce70b0SLuiz Augusto von Dentz 
185101ce70b0SLuiz Augusto von Dentz 		return flags;
185201ce70b0SLuiz Augusto von Dentz 	}
185301ce70b0SLuiz Augusto von Dentz 
185401ce70b0SLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
185501ce70b0SLuiz Augusto von Dentz 
185601ce70b0SLuiz Augusto von Dentz 	/* Return 0 when we got an invalid instance identifier. */
185701ce70b0SLuiz Augusto von Dentz 	if (!adv)
185801ce70b0SLuiz Augusto von Dentz 		return 0;
185901ce70b0SLuiz Augusto von Dentz 
186001ce70b0SLuiz Augusto von Dentz 	return adv->flags;
186101ce70b0SLuiz Augusto von Dentz }
186201ce70b0SLuiz Augusto von Dentz 
186301ce70b0SLuiz Augusto von Dentz bool hci_adv_instance_is_scannable(struct hci_dev *hdev, u8 instance)
186401ce70b0SLuiz Augusto von Dentz {
186501ce70b0SLuiz Augusto von Dentz 	struct adv_info *adv;
186601ce70b0SLuiz Augusto von Dentz 
186701ce70b0SLuiz Augusto von Dentz 	/* Instance 0x00 always set local name */
186801ce70b0SLuiz Augusto von Dentz 	if (instance == 0x00)
186901ce70b0SLuiz Augusto von Dentz 		return true;
187001ce70b0SLuiz Augusto von Dentz 
187101ce70b0SLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
187201ce70b0SLuiz Augusto von Dentz 	if (!adv)
187301ce70b0SLuiz Augusto von Dentz 		return false;
187401ce70b0SLuiz Augusto von Dentz 
187501ce70b0SLuiz Augusto von Dentz 	if (adv->flags & MGMT_ADV_FLAG_APPEARANCE ||
187601ce70b0SLuiz Augusto von Dentz 	    adv->flags & MGMT_ADV_FLAG_LOCAL_NAME)
187701ce70b0SLuiz Augusto von Dentz 		return true;
187801ce70b0SLuiz Augusto von Dentz 
187901ce70b0SLuiz Augusto von Dentz 	return adv->scan_rsp_len ? true : false;
188001ce70b0SLuiz Augusto von Dentz }
188101ce70b0SLuiz Augusto von Dentz 
188201ce70b0SLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */
1883e5e1e7fdSMiao-chen Chou void hci_adv_monitors_clear(struct hci_dev *hdev)
1884e5e1e7fdSMiao-chen Chou {
1885b139553dSMiao-chen Chou 	struct adv_monitor *monitor;
1886b139553dSMiao-chen Chou 	int handle;
1887b139553dSMiao-chen Chou 
1888b139553dSMiao-chen Chou 	idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle)
188966bd095aSArchie Pusaka 		hci_free_adv_monitor(hdev, monitor);
1890b139553dSMiao-chen Chou 
1891e5e1e7fdSMiao-chen Chou 	idr_destroy(&hdev->adv_monitors_idr);
1892e5e1e7fdSMiao-chen Chou }
1893e5e1e7fdSMiao-chen Chou 
189466bd095aSArchie Pusaka /* Frees the monitor structure and do some bookkeepings.
189566bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
189666bd095aSArchie Pusaka  */
189766bd095aSArchie Pusaka void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
1898b139553dSMiao-chen Chou {
1899b139553dSMiao-chen Chou 	struct adv_pattern *pattern;
1900b139553dSMiao-chen Chou 	struct adv_pattern *tmp;
1901b139553dSMiao-chen Chou 
1902b139553dSMiao-chen Chou 	if (!monitor)
1903b139553dSMiao-chen Chou 		return;
1904b139553dSMiao-chen Chou 
190566bd095aSArchie Pusaka 	list_for_each_entry_safe(pattern, tmp, &monitor->patterns, list) {
190666bd095aSArchie Pusaka 		list_del(&pattern->list);
1907b139553dSMiao-chen Chou 		kfree(pattern);
190866bd095aSArchie Pusaka 	}
190966bd095aSArchie Pusaka 
191066bd095aSArchie Pusaka 	if (monitor->handle)
191166bd095aSArchie Pusaka 		idr_remove(&hdev->adv_monitors_idr, monitor->handle);
191266bd095aSArchie Pusaka 
191366bd095aSArchie Pusaka 	if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) {
191466bd095aSArchie Pusaka 		hdev->adv_monitors_cnt--;
191566bd095aSArchie Pusaka 		mgmt_adv_monitor_removed(hdev, monitor->handle);
191666bd095aSArchie Pusaka 	}
1917b139553dSMiao-chen Chou 
1918b139553dSMiao-chen Chou 	kfree(monitor);
1919b139553dSMiao-chen Chou }
1920b139553dSMiao-chen Chou 
1921a2a4dedfSArchie Pusaka /* Assigns handle to a monitor, and if offloading is supported and power is on,
1922a2a4dedfSArchie Pusaka  * also attempts to forward the request to the controller.
1923b747a836SManish Mandlik  * This function requires the caller holds hci_req_sync_lock.
1924a2a4dedfSArchie Pusaka  */
1925b747a836SManish Mandlik int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
1926b139553dSMiao-chen Chou {
1927b139553dSMiao-chen Chou 	int min, max, handle;
1928b747a836SManish Mandlik 	int status = 0;
1929b139553dSMiao-chen Chou 
1930b747a836SManish Mandlik 	if (!monitor)
1931b747a836SManish Mandlik 		return -EINVAL;
1932a2a4dedfSArchie Pusaka 
1933b747a836SManish Mandlik 	hci_dev_lock(hdev);
1934b139553dSMiao-chen Chou 
1935b139553dSMiao-chen Chou 	min = HCI_MIN_ADV_MONITOR_HANDLE;
1936b139553dSMiao-chen Chou 	max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES;
1937b139553dSMiao-chen Chou 	handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max,
1938b139553dSMiao-chen Chou 			   GFP_KERNEL);
1939b747a836SManish Mandlik 
1940b747a836SManish Mandlik 	hci_dev_unlock(hdev);
1941b747a836SManish Mandlik 
1942b747a836SManish Mandlik 	if (handle < 0)
1943b747a836SManish Mandlik 		return handle;
1944b139553dSMiao-chen Chou 
1945b139553dSMiao-chen Chou 	monitor->handle = handle;
19468208f5a9SMiao-chen Chou 
1947a2a4dedfSArchie Pusaka 	if (!hdev_is_powered(hdev))
1948b747a836SManish Mandlik 		return status;
19498208f5a9SMiao-chen Chou 
1950a2a4dedfSArchie Pusaka 	switch (hci_get_adv_monitor_offload_ext(hdev)) {
1951a2a4dedfSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_NONE:
1952b747a836SManish Mandlik 		bt_dev_dbg(hdev, "%s add monitor %d status %d", hdev->name,
1953b747a836SManish Mandlik 			   monitor->handle, status);
1954a2a4dedfSArchie Pusaka 		/* Message was not forwarded to controller - not an error */
1955b747a836SManish Mandlik 		break;
1956b747a836SManish Mandlik 
1957a2a4dedfSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_MSFT:
1958b747a836SManish Mandlik 		status = msft_add_monitor_pattern(hdev, monitor);
1959b747a836SManish Mandlik 		bt_dev_dbg(hdev, "%s add monitor %d msft status %d", hdev->name,
1960b747a836SManish Mandlik 			   monitor->handle, status);
1961a2a4dedfSArchie Pusaka 		break;
1962a2a4dedfSArchie Pusaka 	}
1963a2a4dedfSArchie Pusaka 
1964b747a836SManish Mandlik 	return status;
1965b139553dSMiao-chen Chou }
1966b139553dSMiao-chen Chou 
196766bd095aSArchie Pusaka /* Attempts to tell the controller and free the monitor. If somehow the
196866bd095aSArchie Pusaka  * controller doesn't have a corresponding handle, remove anyway.
19697cf5c297SManish Mandlik  * This function requires the caller holds hci_req_sync_lock.
197066bd095aSArchie Pusaka  */
19717cf5c297SManish Mandlik static int hci_remove_adv_monitor(struct hci_dev *hdev,
19727cf5c297SManish Mandlik 				  struct adv_monitor *monitor)
1973bd2fbc6cSMiao-chen Chou {
19747cf5c297SManish Mandlik 	int status = 0;
1975bd2fbc6cSMiao-chen Chou 
197666bd095aSArchie Pusaka 	switch (hci_get_adv_monitor_offload_ext(hdev)) {
197766bd095aSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */
19787cf5c297SManish Mandlik 		bt_dev_dbg(hdev, "%s remove monitor %d status %d", hdev->name,
19797cf5c297SManish Mandlik 			   monitor->handle, status);
198066bd095aSArchie Pusaka 		goto free_monitor;
19817cf5c297SManish Mandlik 
198266bd095aSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_MSFT:
19837cf5c297SManish Mandlik 		status = msft_remove_monitor(hdev, monitor);
19847cf5c297SManish Mandlik 		bt_dev_dbg(hdev, "%s remove monitor %d msft status %d",
19857cf5c297SManish Mandlik 			   hdev->name, monitor->handle, status);
198666bd095aSArchie Pusaka 		break;
1987bd2fbc6cSMiao-chen Chou 	}
1988bd2fbc6cSMiao-chen Chou 
198966bd095aSArchie Pusaka 	/* In case no matching handle registered, just free the monitor */
19907cf5c297SManish Mandlik 	if (status == -ENOENT)
199166bd095aSArchie Pusaka 		goto free_monitor;
1992bd2fbc6cSMiao-chen Chou 
19937cf5c297SManish Mandlik 	return status;
1994bd2fbc6cSMiao-chen Chou 
199566bd095aSArchie Pusaka free_monitor:
19967cf5c297SManish Mandlik 	if (status == -ENOENT)
199766bd095aSArchie Pusaka 		bt_dev_warn(hdev, "Removing monitor with no matching handle %d",
199866bd095aSArchie Pusaka 			    monitor->handle);
199966bd095aSArchie Pusaka 	hci_free_adv_monitor(hdev, monitor);
200066bd095aSArchie Pusaka 
20017cf5c297SManish Mandlik 	return status;
2002bd2fbc6cSMiao-chen Chou }
2003bd2fbc6cSMiao-chen Chou 
20047cf5c297SManish Mandlik /* This function requires the caller holds hci_req_sync_lock */
20057cf5c297SManish Mandlik int hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle)
200666bd095aSArchie Pusaka {
200766bd095aSArchie Pusaka 	struct adv_monitor *monitor = idr_find(&hdev->adv_monitors_idr, handle);
200866bd095aSArchie Pusaka 
20097cf5c297SManish Mandlik 	if (!monitor)
20107cf5c297SManish Mandlik 		return -EINVAL;
20117cf5c297SManish Mandlik 
20127cf5c297SManish Mandlik 	return hci_remove_adv_monitor(hdev, monitor);
201366bd095aSArchie Pusaka }
201466bd095aSArchie Pusaka 
20157cf5c297SManish Mandlik /* This function requires the caller holds hci_req_sync_lock */
20167cf5c297SManish Mandlik int hci_remove_all_adv_monitor(struct hci_dev *hdev)
201766bd095aSArchie Pusaka {
201866bd095aSArchie Pusaka 	struct adv_monitor *monitor;
201966bd095aSArchie Pusaka 	int idr_next_id = 0;
20207cf5c297SManish Mandlik 	int status = 0;
202166bd095aSArchie Pusaka 
20227cf5c297SManish Mandlik 	while (1) {
202366bd095aSArchie Pusaka 		monitor = idr_get_next(&hdev->adv_monitors_idr, &idr_next_id);
202466bd095aSArchie Pusaka 		if (!monitor)
202566bd095aSArchie Pusaka 			break;
202666bd095aSArchie Pusaka 
20277cf5c297SManish Mandlik 		status = hci_remove_adv_monitor(hdev, monitor);
20287cf5c297SManish Mandlik 		if (status)
20297cf5c297SManish Mandlik 			return status;
203066bd095aSArchie Pusaka 
20317cf5c297SManish Mandlik 		idr_next_id++;
203266bd095aSArchie Pusaka 	}
203366bd095aSArchie Pusaka 
20347cf5c297SManish Mandlik 	return status;
2035bd2fbc6cSMiao-chen Chou }
2036bd2fbc6cSMiao-chen Chou 
20378208f5a9SMiao-chen Chou /* This function requires the caller holds hdev->lock */
20388208f5a9SMiao-chen Chou bool hci_is_adv_monitoring(struct hci_dev *hdev)
20398208f5a9SMiao-chen Chou {
20408208f5a9SMiao-chen Chou 	return !idr_is_empty(&hdev->adv_monitors_idr);
20418208f5a9SMiao-chen Chou }
20428208f5a9SMiao-chen Chou 
2043a2a4dedfSArchie Pusaka int hci_get_adv_monitor_offload_ext(struct hci_dev *hdev)
2044a2a4dedfSArchie Pusaka {
2045a2a4dedfSArchie Pusaka 	if (msft_monitor_supported(hdev))
2046a2a4dedfSArchie Pusaka 		return HCI_ADV_MONITOR_EXT_MSFT;
2047a2a4dedfSArchie Pusaka 
2048a2a4dedfSArchie Pusaka 	return HCI_ADV_MONITOR_EXT_NONE;
2049a2a4dedfSArchie Pusaka }
2050a2a4dedfSArchie Pusaka 
2051dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
2052b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
2053b2a66aadSAntti Julku {
2054b2a66aadSAntti Julku 	struct bdaddr_list *b;
2055b2a66aadSAntti Julku 
2056dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
2057b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2058b2a66aadSAntti Julku 			return b;
2059b9ee0a78SMarcel Holtmann 	}
2060b2a66aadSAntti Julku 
2061b2a66aadSAntti Julku 	return NULL;
2062b2a66aadSAntti Julku }
2063b2a66aadSAntti Julku 
2064b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
2065b950aa88SAnkit Navik 				struct list_head *bdaddr_list, bdaddr_t *bdaddr,
2066b950aa88SAnkit Navik 				u8 type)
2067b950aa88SAnkit Navik {
2068b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *b;
2069b950aa88SAnkit Navik 
2070b950aa88SAnkit Navik 	list_for_each_entry(b, bdaddr_list, list) {
2071b950aa88SAnkit Navik 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2072b950aa88SAnkit Navik 			return b;
2073b950aa88SAnkit Navik 	}
2074b950aa88SAnkit Navik 
2075b950aa88SAnkit Navik 	return NULL;
2076b950aa88SAnkit Navik }
2077b950aa88SAnkit Navik 
20788baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *
20798baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list,
20808baaa403SAbhishek Pandit-Subedi 				  bdaddr_t *bdaddr, u8 type)
20818baaa403SAbhishek Pandit-Subedi {
20828baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *b;
20838baaa403SAbhishek Pandit-Subedi 
20848baaa403SAbhishek Pandit-Subedi 	list_for_each_entry(b, bdaddr_list, list) {
20858baaa403SAbhishek Pandit-Subedi 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
20868baaa403SAbhishek Pandit-Subedi 			return b;
20878baaa403SAbhishek Pandit-Subedi 	}
20888baaa403SAbhishek Pandit-Subedi 
20898baaa403SAbhishek Pandit-Subedi 	return NULL;
20908baaa403SAbhishek Pandit-Subedi }
20918baaa403SAbhishek Pandit-Subedi 
2092dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
2093b2a66aadSAntti Julku {
20947eb7404fSGeliang Tang 	struct bdaddr_list *b, *n;
2095b2a66aadSAntti Julku 
20967eb7404fSGeliang Tang 	list_for_each_entry_safe(b, n, bdaddr_list, list) {
20977eb7404fSGeliang Tang 		list_del(&b->list);
2098b2a66aadSAntti Julku 		kfree(b);
2099b2a66aadSAntti Julku 	}
2100b2a66aadSAntti Julku }
2101b2a66aadSAntti Julku 
2102dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2103b2a66aadSAntti Julku {
2104b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2105b2a66aadSAntti Julku 
2106b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
2107b2a66aadSAntti Julku 		return -EBADF;
2108b2a66aadSAntti Julku 
2109dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
21105e762444SAntti Julku 		return -EEXIST;
2111b2a66aadSAntti Julku 
211227f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
21135e762444SAntti Julku 	if (!entry)
21145e762444SAntti Julku 		return -ENOMEM;
2115b2a66aadSAntti Julku 
2116b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2117b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
2118b2a66aadSAntti Julku 
2119dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
2120b2a66aadSAntti Julku 
21212a8357f2SJohan Hedberg 	return 0;
2122b2a66aadSAntti Julku }
2123b2a66aadSAntti Julku 
2124b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2125b950aa88SAnkit Navik 					u8 type, u8 *peer_irk, u8 *local_irk)
2126b950aa88SAnkit Navik {
2127b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
2128b950aa88SAnkit Navik 
2129b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY))
2130b950aa88SAnkit Navik 		return -EBADF;
2131b950aa88SAnkit Navik 
2132b950aa88SAnkit Navik 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
2133b950aa88SAnkit Navik 		return -EEXIST;
2134b950aa88SAnkit Navik 
2135b950aa88SAnkit Navik 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
2136b950aa88SAnkit Navik 	if (!entry)
2137b950aa88SAnkit Navik 		return -ENOMEM;
2138b950aa88SAnkit Navik 
2139b950aa88SAnkit Navik 	bacpy(&entry->bdaddr, bdaddr);
2140b950aa88SAnkit Navik 	entry->bdaddr_type = type;
2141b950aa88SAnkit Navik 
2142b950aa88SAnkit Navik 	if (peer_irk)
2143b950aa88SAnkit Navik 		memcpy(entry->peer_irk, peer_irk, 16);
2144b950aa88SAnkit Navik 
2145b950aa88SAnkit Navik 	if (local_irk)
2146b950aa88SAnkit Navik 		memcpy(entry->local_irk, local_irk, 16);
2147b950aa88SAnkit Navik 
2148b950aa88SAnkit Navik 	list_add(&entry->list, list);
2149b950aa88SAnkit Navik 
2150b950aa88SAnkit Navik 	return 0;
2151b950aa88SAnkit Navik }
2152b950aa88SAnkit Navik 
21538baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
21548baaa403SAbhishek Pandit-Subedi 				   u8 type, u32 flags)
21558baaa403SAbhishek Pandit-Subedi {
21568baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
21578baaa403SAbhishek Pandit-Subedi 
21588baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY))
21598baaa403SAbhishek Pandit-Subedi 		return -EBADF;
21608baaa403SAbhishek Pandit-Subedi 
21618baaa403SAbhishek Pandit-Subedi 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
21628baaa403SAbhishek Pandit-Subedi 		return -EEXIST;
21638baaa403SAbhishek Pandit-Subedi 
21648baaa403SAbhishek Pandit-Subedi 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
21658baaa403SAbhishek Pandit-Subedi 	if (!entry)
21668baaa403SAbhishek Pandit-Subedi 		return -ENOMEM;
21678baaa403SAbhishek Pandit-Subedi 
21688baaa403SAbhishek Pandit-Subedi 	bacpy(&entry->bdaddr, bdaddr);
21698baaa403SAbhishek Pandit-Subedi 	entry->bdaddr_type = type;
2170e1cff700SLinus Torvalds 	entry->flags = flags;
21718baaa403SAbhishek Pandit-Subedi 
21728baaa403SAbhishek Pandit-Subedi 	list_add(&entry->list, list);
21738baaa403SAbhishek Pandit-Subedi 
21748baaa403SAbhishek Pandit-Subedi 	return 0;
21758baaa403SAbhishek Pandit-Subedi }
21768baaa403SAbhishek Pandit-Subedi 
2177dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2178b2a66aadSAntti Julku {
2179b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2180b2a66aadSAntti Julku 
218135f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2182dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
218335f7498aSJohan Hedberg 		return 0;
218435f7498aSJohan Hedberg 	}
2185b2a66aadSAntti Julku 
2186dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
2187d2ab0ac1SMarcel Holtmann 	if (!entry)
2188d2ab0ac1SMarcel Holtmann 		return -ENOENT;
2189d2ab0ac1SMarcel Holtmann 
2190d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
2191d2ab0ac1SMarcel Holtmann 	kfree(entry);
2192d2ab0ac1SMarcel Holtmann 
2193d2ab0ac1SMarcel Holtmann 	return 0;
2194d2ab0ac1SMarcel Holtmann }
2195d2ab0ac1SMarcel Holtmann 
2196b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2197b950aa88SAnkit Navik 							u8 type)
2198b950aa88SAnkit Navik {
2199b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
2200b950aa88SAnkit Navik 
2201b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2202b950aa88SAnkit Navik 		hci_bdaddr_list_clear(list);
2203b950aa88SAnkit Navik 		return 0;
2204b950aa88SAnkit Navik 	}
2205b950aa88SAnkit Navik 
2206b950aa88SAnkit Navik 	entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type);
2207b950aa88SAnkit Navik 	if (!entry)
2208b950aa88SAnkit Navik 		return -ENOENT;
2209b950aa88SAnkit Navik 
2210b950aa88SAnkit Navik 	list_del(&entry->list);
2211b950aa88SAnkit Navik 	kfree(entry);
2212b950aa88SAnkit Navik 
2213b950aa88SAnkit Navik 	return 0;
2214b950aa88SAnkit Navik }
2215b950aa88SAnkit Navik 
22168baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
22178baaa403SAbhishek Pandit-Subedi 				   u8 type)
22188baaa403SAbhishek Pandit-Subedi {
22198baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
22208baaa403SAbhishek Pandit-Subedi 
22218baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY)) {
22228baaa403SAbhishek Pandit-Subedi 		hci_bdaddr_list_clear(list);
22238baaa403SAbhishek Pandit-Subedi 		return 0;
22248baaa403SAbhishek Pandit-Subedi 	}
22258baaa403SAbhishek Pandit-Subedi 
22268baaa403SAbhishek Pandit-Subedi 	entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type);
22278baaa403SAbhishek Pandit-Subedi 	if (!entry)
22288baaa403SAbhishek Pandit-Subedi 		return -ENOENT;
22298baaa403SAbhishek Pandit-Subedi 
22308baaa403SAbhishek Pandit-Subedi 	list_del(&entry->list);
22318baaa403SAbhishek Pandit-Subedi 	kfree(entry);
22328baaa403SAbhishek Pandit-Subedi 
22338baaa403SAbhishek Pandit-Subedi 	return 0;
22348baaa403SAbhishek Pandit-Subedi }
22358baaa403SAbhishek Pandit-Subedi 
223615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
223715819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
223815819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
223915819a70SAndre Guedes {
224015819a70SAndre Guedes 	struct hci_conn_params *params;
224115819a70SAndre Guedes 
224215819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
224315819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
224415819a70SAndre Guedes 		    params->addr_type == addr_type) {
224515819a70SAndre Guedes 			return params;
224615819a70SAndre Guedes 		}
224715819a70SAndre Guedes 	}
224815819a70SAndre Guedes 
224915819a70SAndre Guedes 	return NULL;
225015819a70SAndre Guedes }
225115819a70SAndre Guedes 
225215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
2253501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
22544b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
225515819a70SAndre Guedes {
2256912b42efSJohan Hedberg 	struct hci_conn_params *param;
225715819a70SAndre Guedes 
2258501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
2259912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
2260912b42efSJohan Hedberg 		    param->addr_type == addr_type)
2261912b42efSJohan Hedberg 			return param;
22624b10966fSMarcel Holtmann 	}
22634b10966fSMarcel Holtmann 
22644b10966fSMarcel Holtmann 	return NULL;
226515819a70SAndre Guedes }
226615819a70SAndre Guedes 
226715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
226851d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
226951d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
227015819a70SAndre Guedes {
227115819a70SAndre Guedes 	struct hci_conn_params *params;
227215819a70SAndre Guedes 
227315819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
2274cef952ceSAndre Guedes 	if (params)
227551d167c0SMarcel Holtmann 		return params;
227615819a70SAndre Guedes 
227715819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
227815819a70SAndre Guedes 	if (!params) {
22792064ee33SMarcel Holtmann 		bt_dev_err(hdev, "out of memory");
228051d167c0SMarcel Holtmann 		return NULL;
228115819a70SAndre Guedes 	}
228215819a70SAndre Guedes 
228315819a70SAndre Guedes 	bacpy(&params->addr, addr);
228415819a70SAndre Guedes 	params->addr_type = addr_type;
2285cef952ceSAndre Guedes 
2286cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
228793450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
2288cef952ceSAndre Guedes 
2289bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
2290bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
2291bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
2292bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
2293bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
2294bf5b3c8bSMarcel Holtmann 
2295bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
2296bf5b3c8bSMarcel Holtmann 
229751d167c0SMarcel Holtmann 	return params;
2298bf5b3c8bSMarcel Holtmann }
2299bf5b3c8bSMarcel Holtmann 
2300f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params)
2301f6c63249SJohan Hedberg {
2302f6c63249SJohan Hedberg 	if (params->conn) {
2303f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
2304f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
2305f6c63249SJohan Hedberg 	}
2306f6c63249SJohan Hedberg 
2307f6c63249SJohan Hedberg 	list_del(&params->action);
2308f6c63249SJohan Hedberg 	list_del(&params->list);
2309f6c63249SJohan Hedberg 	kfree(params);
2310f6c63249SJohan Hedberg }
2311f6c63249SJohan Hedberg 
231215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
231315819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
231415819a70SAndre Guedes {
231515819a70SAndre Guedes 	struct hci_conn_params *params;
231615819a70SAndre Guedes 
231715819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
231815819a70SAndre Guedes 	if (!params)
231915819a70SAndre Guedes 		return;
232015819a70SAndre Guedes 
2321f6c63249SJohan Hedberg 	hci_conn_params_free(params);
232215819a70SAndre Guedes 
23235bee2fd6SLuiz Augusto von Dentz 	hci_update_passive_scan(hdev);
232495305baaSJohan Hedberg 
232515819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
232615819a70SAndre Guedes }
232715819a70SAndre Guedes 
232815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
232955af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
233015819a70SAndre Guedes {
233115819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
233215819a70SAndre Guedes 
233315819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
233455af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
233555af49a8SJohan Hedberg 			continue;
2336f75113a2SJakub Pawlowski 
233791641b79SZheng Yongjun 		/* If trying to establish one time connection to disabled
2338f75113a2SJakub Pawlowski 		 * device, leave the params, but mark them as just once.
2339f75113a2SJakub Pawlowski 		 */
2340f75113a2SJakub Pawlowski 		if (params->explicit_connect) {
2341f75113a2SJakub Pawlowski 			params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
2342f75113a2SJakub Pawlowski 			continue;
2343f75113a2SJakub Pawlowski 		}
2344f75113a2SJakub Pawlowski 
234515819a70SAndre Guedes 		list_del(&params->list);
234615819a70SAndre Guedes 		kfree(params);
234715819a70SAndre Guedes 	}
234815819a70SAndre Guedes 
234955af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
235055af49a8SJohan Hedberg }
235155af49a8SJohan Hedberg 
235255af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
2353030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev)
235415819a70SAndre Guedes {
235515819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
235615819a70SAndre Guedes 
2357f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
2358f6c63249SJohan Hedberg 		hci_conn_params_free(params);
235915819a70SAndre Guedes 
236015819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
236115819a70SAndre Guedes }
236215819a70SAndre Guedes 
2363a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
2364a1f4c318SJohan Hedberg  *
2365a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
2366a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
2367a1f4c318SJohan Hedberg  * the static random address.
2368a1f4c318SJohan Hedberg  *
2369a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
2370a1f4c318SJohan Hedberg  * public address to use the static random address instead.
237150b5b952SMarcel Holtmann  *
237250b5b952SMarcel Holtmann  * In case BR/EDR has been disabled on a dual-mode controller and
237350b5b952SMarcel Holtmann  * userspace has configured a static address, then that address
237450b5b952SMarcel Holtmann  * becomes the identity address instead of the public BR/EDR address.
2375a1f4c318SJohan Hedberg  */
2376a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
2377a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
2378a1f4c318SJohan Hedberg {
2379b7cb93e5SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
238050b5b952SMarcel Holtmann 	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
2381d7a5a11dSMarcel Holtmann 	    (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
238250b5b952SMarcel Holtmann 	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
2383a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
2384a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
2385a1f4c318SJohan Hedberg 	} else {
2386a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
2387a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
2388a1f4c318SJohan Hedberg 	}
2389a1f4c318SJohan Hedberg }
2390a1f4c318SJohan Hedberg 
23912f20216cSAbhishek Pandit-Subedi static void hci_clear_wake_reason(struct hci_dev *hdev)
23922f20216cSAbhishek Pandit-Subedi {
23932f20216cSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
23942f20216cSAbhishek Pandit-Subedi 
23952f20216cSAbhishek Pandit-Subedi 	hdev->wake_reason = 0;
23962f20216cSAbhishek Pandit-Subedi 	bacpy(&hdev->wake_addr, BDADDR_ANY);
23972f20216cSAbhishek Pandit-Subedi 	hdev->wake_addr_type = 0;
23982f20216cSAbhishek Pandit-Subedi 
23992f20216cSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
24002f20216cSAbhishek Pandit-Subedi }
24012f20216cSAbhishek Pandit-Subedi 
24029952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
24039952d90eSAbhishek Pandit-Subedi 				void *data)
24049952d90eSAbhishek Pandit-Subedi {
24059952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
24069952d90eSAbhishek Pandit-Subedi 		container_of(nb, struct hci_dev, suspend_notifier);
24079952d90eSAbhishek Pandit-Subedi 	int ret = 0;
24089952d90eSAbhishek Pandit-Subedi 
24094b8af331SAbhishek Pandit-Subedi 	/* Userspace has full control of this device. Do nothing. */
24104b8af331SAbhishek Pandit-Subedi 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
24114b8af331SAbhishek Pandit-Subedi 		return NOTIFY_DONE;
24124b8af331SAbhishek Pandit-Subedi 
2413e1b77d68SLuiz Augusto von Dentz 	if (action == PM_SUSPEND_PREPARE)
2414e1b77d68SLuiz Augusto von Dentz 		ret = hci_suspend_dev(hdev);
2415e1b77d68SLuiz Augusto von Dentz 	else if (action == PM_POST_SUSPEND)
2416e1b77d68SLuiz Augusto von Dentz 		ret = hci_resume_dev(hdev);
24179952d90eSAbhishek Pandit-Subedi 
2418a9ec8423SAbhishek Pandit-Subedi 	if (ret)
2419a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
2420a9ec8423SAbhishek Pandit-Subedi 			   action, ret);
2421a9ec8423SAbhishek Pandit-Subedi 
242224b06572SMax Chou 	return NOTIFY_DONE;
24239952d90eSAbhishek Pandit-Subedi }
24248731840aSAbhishek Pandit-Subedi 
24259be0dab7SDavid Herrmann /* Alloc HCI device */
24266ec56613STedd Ho-Jeong An struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
24279be0dab7SDavid Herrmann {
24289be0dab7SDavid Herrmann 	struct hci_dev *hdev;
24296ec56613STedd Ho-Jeong An 	unsigned int alloc_size;
24309be0dab7SDavid Herrmann 
24316ec56613STedd Ho-Jeong An 	alloc_size = sizeof(*hdev);
24326ec56613STedd Ho-Jeong An 	if (sizeof_priv) {
24336ec56613STedd Ho-Jeong An 		/* Fixme: May need ALIGN-ment? */
24346ec56613STedd Ho-Jeong An 		alloc_size += sizeof_priv;
24356ec56613STedd Ho-Jeong An 	}
24366ec56613STedd Ho-Jeong An 
24376ec56613STedd Ho-Jeong An 	hdev = kzalloc(alloc_size, GFP_KERNEL);
24389be0dab7SDavid Herrmann 	if (!hdev)
24399be0dab7SDavid Herrmann 		return NULL;
24409be0dab7SDavid Herrmann 
2441b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2442b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
2443b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
2444b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
2445b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
244696c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
2447bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2448bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2449d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
2450d2609b34SFlorian Grandel 	hdev->cur_adv_instance = 0x00;
24515d900e46SFlorian Grandel 	hdev->adv_instance_timeout = 0;
2452b1b813d4SDavid Herrmann 
2453c4f1f408SHoward Chung 	hdev->advmon_allowlist_duration = 300;
2454c4f1f408SHoward Chung 	hdev->advmon_no_filter_duration = 500;
245580af16a3SHoward Chung 	hdev->enable_advmon_interleave_scan = 0x00;	/* Default to disable */
2456c4f1f408SHoward Chung 
2457b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
2458b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
2459b1b813d4SDavid Herrmann 
24603f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
2461628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
2462628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
2463bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
2464bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
246510873f99SAlain Michaud 	hdev->le_scan_int_suspend = 0x0400;
246610873f99SAlain Michaud 	hdev->le_scan_window_suspend = 0x0012;
246710873f99SAlain Michaud 	hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT;
246810873f99SAlain Michaud 	hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN;
2469ba29d036SMarcel Holtmann 	hdev->le_scan_int_adv_monitor = 0x0060;
2470ba29d036SMarcel Holtmann 	hdev->le_scan_window_adv_monitor = 0x0030;
247110873f99SAlain Michaud 	hdev->le_scan_int_connect = 0x0060;
247210873f99SAlain Michaud 	hdev->le_scan_window_connect = 0x0060;
2473b48c3b59SJonas Holmberg 	hdev->le_conn_min_interval = 0x0018;
2474b48c3b59SJonas Holmberg 	hdev->le_conn_max_interval = 0x0028;
247504fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
247604fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
2477a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = 0x001b;
2478a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = 0x0148;
2479a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = 0x001b;
2480a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = 0x0148;
2481a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = 0x001b;
2482a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = 0x0148;
248330d65e08SMatias Karhumaa 	hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE;
248430d65e08SMatias Karhumaa 	hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE;
24856decb5b4SJaganath Kanakkassery 	hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
24866decb5b4SJaganath Kanakkassery 	hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
24871d0fac2cSLuiz Augusto von Dentz 	hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES;
248810873f99SAlain Michaud 	hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION;
248949b020c1SAlain Michaud 	hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT;
24907c395ea5SDaniel Winkler 	hdev->min_le_tx_power = HCI_TX_POWER_INVALID;
24917c395ea5SDaniel Winkler 	hdev->max_le_tx_power = HCI_TX_POWER_INVALID;
2492bef64738SMarcel Holtmann 
2493d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
2494b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
249531ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
249631ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
2497302975cbSSpoorthi Ravishankar Koppad 	hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT;
249858a96fc3SMarcel Holtmann 	hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE;
2499d6bfd59cSJohan Hedberg 
250010873f99SAlain Michaud 	/* default 1.28 sec page scan */
250110873f99SAlain Michaud 	hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD;
250210873f99SAlain Michaud 	hdev->def_page_scan_int = 0x0800;
250310873f99SAlain Michaud 	hdev->def_page_scan_window = 0x0012;
250410873f99SAlain Michaud 
2505b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
2506b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
2507b1b813d4SDavid Herrmann 
2508b338d917SBrian Gix 	INIT_LIST_HEAD(&hdev->mesh_pending);
2509b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
25103d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->reject_list);
25113d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->accept_list);
2512b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
2513b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
2514b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
2515970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
2516b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
25173d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->le_accept_list);
2518cfdb0c2dSAnkit Navik 	INIT_LIST_HEAD(&hdev->le_resolv_list);
251915819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
252077a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
252166f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
25226b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
2523d2609b34SFlorian Grandel 	INIT_LIST_HEAD(&hdev->adv_instances);
2524600a8749SAlain Michaud 	INIT_LIST_HEAD(&hdev->blocked_keys);
25253368aa35SManish Mandlik 	INIT_LIST_HEAD(&hdev->monitored_devices);
2526b1b813d4SDavid Herrmann 
25278961987fSKiran K 	INIT_LIST_HEAD(&hdev->local_codecs);
2528b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2529b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2530b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2531b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2532c7741d16SMarcel Holtmann 	INIT_WORK(&hdev->error_reset, hci_error_reset);
2533b1b813d4SDavid Herrmann 
25346a98e383SMarcel Holtmann 	hci_cmd_sync_init(hdev);
25356a98e383SMarcel Holtmann 
2536b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2537b1b813d4SDavid Herrmann 
2538b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2539b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2540b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2541b1b813d4SDavid Herrmann 
2542b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2543b1b813d4SDavid Herrmann 
254465cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
2545de75cd0dSManish Mandlik 	INIT_DELAYED_WORK(&hdev->ncmd_timer, hci_ncmd_timeout);
2546b1b813d4SDavid Herrmann 
25479695ef87SAbhishek Pandit-Subedi 	hci_devcd_setup(hdev);
25485fc16cc4SJohan Hedberg 	hci_request_setup(hdev);
25495fc16cc4SJohan Hedberg 
2550b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2551b1b813d4SDavid Herrmann 	discovery_init(hdev);
25529be0dab7SDavid Herrmann 
25539be0dab7SDavid Herrmann 	return hdev;
25549be0dab7SDavid Herrmann }
25556ec56613STedd Ho-Jeong An EXPORT_SYMBOL(hci_alloc_dev_priv);
25569be0dab7SDavid Herrmann 
25579be0dab7SDavid Herrmann /* Free HCI device */
25589be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
25599be0dab7SDavid Herrmann {
25609be0dab7SDavid Herrmann 	/* will free via device release */
25619be0dab7SDavid Herrmann 	put_device(&hdev->dev);
25629be0dab7SDavid Herrmann }
25639be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
25649be0dab7SDavid Herrmann 
25651da177e4SLinus Torvalds /* Register HCI device */
25661da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
25671da177e4SLinus Torvalds {
2568b1b813d4SDavid Herrmann 	int id, error;
25691da177e4SLinus Torvalds 
257074292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
25711da177e4SLinus Torvalds 		return -EINVAL;
25721da177e4SLinus Torvalds 
257308add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
257408add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
257508add513SMat Martineau 	 */
25763df92b31SSasha Levin 	switch (hdev->dev_type) {
2577ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
2578103a2f32SItay Iellin 		id = ida_simple_get(&hci_index_ida, 0, HCI_MAX_ID, GFP_KERNEL);
25791da177e4SLinus Torvalds 		break;
25803df92b31SSasha Levin 	case HCI_AMP:
2581103a2f32SItay Iellin 		id = ida_simple_get(&hci_index_ida, 1, HCI_MAX_ID, GFP_KERNEL);
25823df92b31SSasha Levin 		break;
25833df92b31SSasha Levin 	default:
25843df92b31SSasha Levin 		return -EINVAL;
25851da177e4SLinus Torvalds 	}
25861da177e4SLinus Torvalds 
25873df92b31SSasha Levin 	if (id < 0)
25883df92b31SSasha Levin 		return id;
25893df92b31SSasha Levin 
2590103a2f32SItay Iellin 	snprintf(hdev->name, sizeof(hdev->name), "hci%d", id);
25911da177e4SLinus Torvalds 	hdev->id = id;
25922d8b3a11SAndrei Emeltchenko 
25932d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
25942d8b3a11SAndrei Emeltchenko 
259529e2dd0dSTejun Heo 	hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name);
259633ca954dSDavid Herrmann 	if (!hdev->workqueue) {
259733ca954dSDavid Herrmann 		error = -ENOMEM;
259833ca954dSDavid Herrmann 		goto err;
259933ca954dSDavid Herrmann 	}
2600f48fd9c8SMarcel Holtmann 
260129e2dd0dSTejun Heo 	hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI,
260229e2dd0dSTejun Heo 						      hdev->name);
26036ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
26046ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
26056ead1bbcSJohan Hedberg 		error = -ENOMEM;
26066ead1bbcSJohan Hedberg 		goto err;
26076ead1bbcSJohan Hedberg 	}
26086ead1bbcSJohan Hedberg 
26090153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
26100153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
26110153e2ecSMarcel Holtmann 
2612bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
2613bdc3e0f1SMarcel Holtmann 
2614bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
261533ca954dSDavid Herrmann 	if (error < 0)
261654506918SJohan Hedberg 		goto err_wqueue;
26171da177e4SLinus Torvalds 
26186d5d2ee6SHeiner Kallweit 	hci_leds_init(hdev);
26196d5d2ee6SHeiner Kallweit 
2620611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2621a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2622a8c5fb1aSGustavo Padovan 				    hdev);
2623611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2624611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
2625611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
2626611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
2627611b30f7SMarcel Holtmann 		}
2628611b30f7SMarcel Holtmann 	}
2629611b30f7SMarcel Holtmann 
26305e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
2631a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
26325e130367SJohan Hedberg 
2633a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_SETUP);
2634a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_AUTO_OFF);
2635ce2be9acSAndrei Emeltchenko 
2636ca8bee5dSMarcel Holtmann 	if (hdev->dev_type == HCI_PRIMARY) {
263756f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
263856f87901SJohan Hedberg 		 * through reading supported features during init.
263956f87901SJohan Hedberg 		 */
2640a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
264156f87901SJohan Hedberg 	}
2642ce2be9acSAndrei Emeltchenko 
2643fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
2644fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
2645fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
2646fcee3377SGustavo Padovan 
26474a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
26484a964404SMarcel Holtmann 	 * and should not be included in normal operation.
2649fee746b0SMarcel Holtmann 	 */
2650fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
2651a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
2652fee746b0SMarcel Holtmann 
2653fe92ee64SLuiz Augusto von Dentz 	/* Mark Remote Wakeup connection flag as supported if driver has wakeup
2654fe92ee64SLuiz Augusto von Dentz 	 * callback.
2655fe92ee64SLuiz Augusto von Dentz 	 */
2656fe92ee64SLuiz Augusto von Dentz 	if (hdev->wakeup)
2657e1cff700SLinus Torvalds 		hdev->conn_flags |= HCI_CONN_FLAG_REMOTE_WAKEUP;
2658fe92ee64SLuiz Augusto von Dentz 
265905fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_REG);
2660dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
26611da177e4SLinus Torvalds 
266291117864SDan Carpenter 	error = hci_register_suspend_notifier(hdev);
266391117864SDan Carpenter 	if (error)
26640d75da38SYang Yingliang 		BT_WARN("register suspend notifier failed error:%d\n", error);
26659952d90eSAbhishek Pandit-Subedi 
266619202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2667fbe96d6fSMarcel Holtmann 
2668e5e1e7fdSMiao-chen Chou 	idr_init(&hdev->adv_monitors_idr);
26695031ffccSMiao-chen Chou 	msft_register(hdev);
2670e5e1e7fdSMiao-chen Chou 
26711da177e4SLinus Torvalds 	return id;
2672f48fd9c8SMarcel Holtmann 
267333ca954dSDavid Herrmann err_wqueue:
26745a4bb6a8SWei Yongjun 	debugfs_remove_recursive(hdev->debugfs);
267533ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
26766ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
267733ca954dSDavid Herrmann err:
26783df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
2679f48fd9c8SMarcel Holtmann 
268033ca954dSDavid Herrmann 	return error;
26811da177e4SLinus Torvalds }
26821da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
26831da177e4SLinus Torvalds 
26841da177e4SLinus Torvalds /* Unregister HCI device */
268559735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
26861da177e4SLinus Torvalds {
2687c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
26881da177e4SLinus Torvalds 
2689a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_UNREGISTER);
269094324962SJohan Hovold 
2691f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
26921da177e4SLinus Torvalds 	list_del(&hdev->list);
2693f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
26941da177e4SLinus Torvalds 
2695e36bea6eSVasyl Vavrychuk 	cancel_work_sync(&hdev->power_on);
2696e36bea6eSVasyl Vavrychuk 
26976a98e383SMarcel Holtmann 	hci_cmd_sync_clear(hdev);
26986a98e383SMarcel Holtmann 
2699359ee4f8SAbhishek Pandit-Subedi 	hci_unregister_suspend_notifier(hdev);
27004e8c36c3SAbhishek Pandit-Subedi 
27015031ffccSMiao-chen Chou 	msft_unregister(hdev);
27025031ffccSMiao-chen Chou 
27034e8c36c3SAbhishek Pandit-Subedi 	hci_dev_do_close(hdev);
27049952d90eSAbhishek Pandit-Subedi 
2705ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2706d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_SETUP) &&
2707d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
270809fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2709744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
271009fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
271156e5cb86SJohan Hedberg 	}
2712ab81cbf9SJohan Hedberg 
27132e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
27142e58ef3eSJohan Hedberg 	 * pending list */
27152e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
27162e58ef3eSJohan Hedberg 
271705fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_UNREG);
27181da177e4SLinus Torvalds 
2719611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2720611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2721611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2722611b30f7SMarcel Holtmann 	}
2723611b30f7SMarcel Holtmann 
2724bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
2725e61fbee7SDavid S. Miller 	/* Actual cleanup is deferred until hci_release_dev(). */
2726e0448092STetsuo Handa 	hci_dev_put(hdev);
2727e0448092STetsuo Handa }
2728e0448092STetsuo Handa EXPORT_SYMBOL(hci_unregister_dev);
2729147e2d59SDave Young 
273058ce6d5bSTetsuo Handa /* Release HCI device */
273158ce6d5bSTetsuo Handa void hci_release_dev(struct hci_dev *hdev)
2732e0448092STetsuo Handa {
27330153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
27345177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
27355177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
27360153e2ecSMarcel Holtmann 
2737f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
27386ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2739f48fd9c8SMarcel Holtmann 
274009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
27413d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->reject_list);
27423d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->accept_list);
27432aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
274455ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2745b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
2746970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
27472763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
2748d2609b34SFlorian Grandel 	hci_adv_instances_clear(hdev);
2749e5e1e7fdSMiao-chen Chou 	hci_adv_monitors_clear(hdev);
27503d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
2751cfdb0c2dSAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
2752373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
275322078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
2754600a8749SAlain Michaud 	hci_blocked_keys_clear(hdev);
275509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2756e2e0cacbSJohan Hedberg 
2757e0448092STetsuo Handa 	ida_simple_remove(&hci_index_ida, hdev->id);
2758dd3b1dc3SLuiz Augusto von Dentz 	kfree_skb(hdev->sent_cmd);
2759dfe6d5c3SLuiz Augusto von Dentz 	kfree_skb(hdev->recv_event);
276058ce6d5bSTetsuo Handa 	kfree(hdev);
27611da177e4SLinus Torvalds }
276258ce6d5bSTetsuo Handa EXPORT_SYMBOL(hci_release_dev);
27631da177e4SLinus Torvalds 
2764359ee4f8SAbhishek Pandit-Subedi int hci_register_suspend_notifier(struct hci_dev *hdev)
2765359ee4f8SAbhishek Pandit-Subedi {
2766359ee4f8SAbhishek Pandit-Subedi 	int ret = 0;
2767359ee4f8SAbhishek Pandit-Subedi 
2768b5ca3387SLuiz Augusto von Dentz 	if (!hdev->suspend_notifier.notifier_call &&
2769b5ca3387SLuiz Augusto von Dentz 	    !test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
2770359ee4f8SAbhishek Pandit-Subedi 		hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
2771359ee4f8SAbhishek Pandit-Subedi 		ret = register_pm_notifier(&hdev->suspend_notifier);
2772359ee4f8SAbhishek Pandit-Subedi 	}
2773359ee4f8SAbhishek Pandit-Subedi 
2774359ee4f8SAbhishek Pandit-Subedi 	return ret;
2775359ee4f8SAbhishek Pandit-Subedi }
2776359ee4f8SAbhishek Pandit-Subedi 
2777359ee4f8SAbhishek Pandit-Subedi int hci_unregister_suspend_notifier(struct hci_dev *hdev)
2778359ee4f8SAbhishek Pandit-Subedi {
2779359ee4f8SAbhishek Pandit-Subedi 	int ret = 0;
2780359ee4f8SAbhishek Pandit-Subedi 
2781b5ca3387SLuiz Augusto von Dentz 	if (hdev->suspend_notifier.notifier_call) {
2782359ee4f8SAbhishek Pandit-Subedi 		ret = unregister_pm_notifier(&hdev->suspend_notifier);
2783b5ca3387SLuiz Augusto von Dentz 		if (!ret)
2784b5ca3387SLuiz Augusto von Dentz 			hdev->suspend_notifier.notifier_call = NULL;
2785b5ca3387SLuiz Augusto von Dentz 	}
2786359ee4f8SAbhishek Pandit-Subedi 
2787359ee4f8SAbhishek Pandit-Subedi 	return ret;
2788359ee4f8SAbhishek Pandit-Subedi }
2789359ee4f8SAbhishek Pandit-Subedi 
27901da177e4SLinus Torvalds /* Suspend HCI device */
27911da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
27921da177e4SLinus Torvalds {
2793e1b77d68SLuiz Augusto von Dentz 	int ret;
2794e1b77d68SLuiz Augusto von Dentz 
2795e1b77d68SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
2796e1b77d68SLuiz Augusto von Dentz 
2797e1b77d68SLuiz Augusto von Dentz 	/* Suspend should only act on when powered. */
2798e1b77d68SLuiz Augusto von Dentz 	if (!hdev_is_powered(hdev) ||
2799e1b77d68SLuiz Augusto von Dentz 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
28001da177e4SLinus Torvalds 		return 0;
2801e1b77d68SLuiz Augusto von Dentz 
2802182ee45dSLuiz Augusto von Dentz 	/* If powering down don't attempt to suspend */
2803182ee45dSLuiz Augusto von Dentz 	if (mgmt_powering_down(hdev))
2804182ee45dSLuiz Augusto von Dentz 		return 0;
2805e1b77d68SLuiz Augusto von Dentz 
2806*f4198635SArchie Pusaka 	/* Cancel potentially blocking sync operation before suspend */
2807*f4198635SArchie Pusaka 	__hci_cmd_sync_cancel(hdev, -EHOSTDOWN);
2808*f4198635SArchie Pusaka 
2809182ee45dSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
2810182ee45dSLuiz Augusto von Dentz 	ret = hci_suspend_sync(hdev);
2811182ee45dSLuiz Augusto von Dentz 	hci_req_sync_unlock(hdev);
28124539ca67SLuiz Augusto von Dentz 
2813e1b77d68SLuiz Augusto von Dentz 	hci_clear_wake_reason(hdev);
2814182ee45dSLuiz Augusto von Dentz 	mgmt_suspending(hdev, hdev->suspend_state);
2815e1b77d68SLuiz Augusto von Dentz 
2816e1b77d68SLuiz Augusto von Dentz 	hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
2817e1b77d68SLuiz Augusto von Dentz 	return ret;
28181da177e4SLinus Torvalds }
28191da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
28201da177e4SLinus Torvalds 
28211da177e4SLinus Torvalds /* Resume HCI device */
28221da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
28231da177e4SLinus Torvalds {
2824e1b77d68SLuiz Augusto von Dentz 	int ret;
2825e1b77d68SLuiz Augusto von Dentz 
2826e1b77d68SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
2827e1b77d68SLuiz Augusto von Dentz 
2828e1b77d68SLuiz Augusto von Dentz 	/* Resume should only act on when powered. */
2829e1b77d68SLuiz Augusto von Dentz 	if (!hdev_is_powered(hdev) ||
2830e1b77d68SLuiz Augusto von Dentz 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
28311da177e4SLinus Torvalds 		return 0;
2832e1b77d68SLuiz Augusto von Dentz 
2833e1b77d68SLuiz Augusto von Dentz 	/* If powering down don't attempt to resume */
2834e1b77d68SLuiz Augusto von Dentz 	if (mgmt_powering_down(hdev))
2835e1b77d68SLuiz Augusto von Dentz 		return 0;
2836e1b77d68SLuiz Augusto von Dentz 
2837182ee45dSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
2838182ee45dSLuiz Augusto von Dentz 	ret = hci_resume_sync(hdev);
2839182ee45dSLuiz Augusto von Dentz 	hci_req_sync_unlock(hdev);
2840e1b77d68SLuiz Augusto von Dentz 
2841e1b77d68SLuiz Augusto von Dentz 	mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr,
2842e1b77d68SLuiz Augusto von Dentz 		      hdev->wake_addr_type);
2843e1b77d68SLuiz Augusto von Dentz 
2844e1b77d68SLuiz Augusto von Dentz 	hci_sock_dev_event(hdev, HCI_DEV_RESUME);
2845e1b77d68SLuiz Augusto von Dentz 	return ret;
28461da177e4SLinus Torvalds }
28471da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
28481da177e4SLinus Torvalds 
284975e0569fSMarcel Holtmann /* Reset HCI device */
285075e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
285175e0569fSMarcel Holtmann {
28521e4b6e91SColin Ian King 	static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
285375e0569fSMarcel Holtmann 	struct sk_buff *skb;
285475e0569fSMarcel Holtmann 
285575e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
285675e0569fSMarcel Holtmann 	if (!skb)
285775e0569fSMarcel Holtmann 		return -ENOMEM;
285875e0569fSMarcel Holtmann 
2859d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
286059ae1d12SJohannes Berg 	skb_put_data(skb, hw_err, 3);
286175e0569fSMarcel Holtmann 
2862de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Injecting HCI hardware error event");
2863de75cd0dSManish Mandlik 
286475e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
286575e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
286675e0569fSMarcel Holtmann }
286775e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
286875e0569fSMarcel Holtmann 
286976bca880SMarcel Holtmann /* Receive frame from HCI drivers */
2870e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
287176bca880SMarcel Holtmann {
287276bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
287376bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
287476bca880SMarcel Holtmann 		kfree_skb(skb);
287576bca880SMarcel Holtmann 		return -ENXIO;
287676bca880SMarcel Holtmann 	}
287776bca880SMarcel Holtmann 
2878876e7810SLuiz Augusto von Dentz 	switch (hci_skb_pkt_type(skb)) {
2879876e7810SLuiz Augusto von Dentz 	case HCI_EVENT_PKT:
2880876e7810SLuiz Augusto von Dentz 		break;
2881876e7810SLuiz Augusto von Dentz 	case HCI_ACLDATA_PKT:
2882876e7810SLuiz Augusto von Dentz 		/* Detect if ISO packet has been sent as ACL */
2883876e7810SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, ISO_LINK)) {
2884876e7810SLuiz Augusto von Dentz 			__u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle);
2885876e7810SLuiz Augusto von Dentz 			__u8 type;
2886876e7810SLuiz Augusto von Dentz 
2887876e7810SLuiz Augusto von Dentz 			type = hci_conn_lookup_type(hdev, hci_handle(handle));
2888876e7810SLuiz Augusto von Dentz 			if (type == ISO_LINK)
2889876e7810SLuiz Augusto von Dentz 				hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
2890876e7810SLuiz Augusto von Dentz 		}
2891876e7810SLuiz Augusto von Dentz 		break;
2892876e7810SLuiz Augusto von Dentz 	case HCI_SCODATA_PKT:
2893876e7810SLuiz Augusto von Dentz 		break;
2894876e7810SLuiz Augusto von Dentz 	case HCI_ISODATA_PKT:
2895876e7810SLuiz Augusto von Dentz 		break;
2896876e7810SLuiz Augusto von Dentz 	default:
2897fe806dceSMarcel Holtmann 		kfree_skb(skb);
2898fe806dceSMarcel Holtmann 		return -EINVAL;
2899fe806dceSMarcel Holtmann 	}
2900fe806dceSMarcel Holtmann 
2901d82603c6SJorrit Schippers 	/* Incoming skb */
290276bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
290376bca880SMarcel Holtmann 
290476bca880SMarcel Holtmann 	/* Time stamp */
290576bca880SMarcel Holtmann 	__net_timestamp(skb);
290676bca880SMarcel Holtmann 
290776bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2908b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2909c78ae283SMarcel Holtmann 
291076bca880SMarcel Holtmann 	return 0;
291176bca880SMarcel Holtmann }
291276bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
291376bca880SMarcel Holtmann 
2914e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */
2915e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
2916e875ff84SMarcel Holtmann {
2917581d6fd6SMarcel Holtmann 	/* Mark as diagnostic packet */
2918d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_DIAG_PKT;
2919581d6fd6SMarcel Holtmann 
2920e875ff84SMarcel Holtmann 	/* Time stamp */
2921e875ff84SMarcel Holtmann 	__net_timestamp(skb);
2922e875ff84SMarcel Holtmann 
2923581d6fd6SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2924581d6fd6SMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2925e875ff84SMarcel Holtmann 
2926e875ff84SMarcel Holtmann 	return 0;
2927e875ff84SMarcel Holtmann }
2928e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag);
2929e875ff84SMarcel Holtmann 
29305177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...)
29315177a838SMarcel Holtmann {
29325177a838SMarcel Holtmann 	va_list vargs;
29335177a838SMarcel Holtmann 
29345177a838SMarcel Holtmann 	va_start(vargs, fmt);
29355177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
29365177a838SMarcel Holtmann 	hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
29375177a838SMarcel Holtmann 	va_end(vargs);
29385177a838SMarcel Holtmann }
29395177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info);
29405177a838SMarcel Holtmann 
29415177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...)
29425177a838SMarcel Holtmann {
29435177a838SMarcel Holtmann 	va_list vargs;
29445177a838SMarcel Holtmann 
29455177a838SMarcel Holtmann 	va_start(vargs, fmt);
29465177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
29475177a838SMarcel Holtmann 	hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
29485177a838SMarcel Holtmann 	va_end(vargs);
29495177a838SMarcel Holtmann }
29505177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info);
29515177a838SMarcel Holtmann 
29521da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
29531da177e4SLinus Torvalds 
29541da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
29551da177e4SLinus Torvalds {
29561da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
29571da177e4SLinus Torvalds 
2958fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
295900629e0fSJohan Hedberg 	list_add_tail(&cb->list, &hci_cb_list);
2960fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
29611da177e4SLinus Torvalds 
29621da177e4SLinus Torvalds 	return 0;
29631da177e4SLinus Torvalds }
29641da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
29651da177e4SLinus Torvalds 
29661da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
29671da177e4SLinus Torvalds {
29681da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
29691da177e4SLinus Torvalds 
2970fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
29711da177e4SLinus Torvalds 	list_del(&cb->list);
2972fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
29731da177e4SLinus Torvalds 
29741da177e4SLinus Torvalds 	return 0;
29751da177e4SLinus Torvalds }
29761da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
29771da177e4SLinus Torvalds 
29782250abadSBenjamin Berg static int hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
29791da177e4SLinus Torvalds {
2980cdc52faaSMarcel Holtmann 	int err;
2981cdc52faaSMarcel Holtmann 
2982d79f34e3SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb),
2983d79f34e3SMarcel Holtmann 	       skb->len);
29841da177e4SLinus Torvalds 
29851da177e4SLinus Torvalds 	/* Time stamp */
2986a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
29871da177e4SLinus Torvalds 
2988cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2989cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2990cd82e61cSMarcel Holtmann 
2991cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2992cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2993470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
29941da177e4SLinus Torvalds 	}
29951da177e4SLinus Torvalds 
29961da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
29971da177e4SLinus Torvalds 	skb_orphan(skb);
29981da177e4SLinus Torvalds 
299973d0d3c8SMarcel Holtmann 	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
300073d0d3c8SMarcel Holtmann 		kfree_skb(skb);
30012250abadSBenjamin Berg 		return -EINVAL;
300273d0d3c8SMarcel Holtmann 	}
300373d0d3c8SMarcel Holtmann 
3004cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
3005cdc52faaSMarcel Holtmann 	if (err < 0) {
30062064ee33SMarcel Holtmann 		bt_dev_err(hdev, "sending frame failed (%d)", err);
3007cdc52faaSMarcel Holtmann 		kfree_skb(skb);
30082250abadSBenjamin Berg 		return err;
3009cdc52faaSMarcel Holtmann 	}
30102250abadSBenjamin Berg 
30112250abadSBenjamin Berg 	return 0;
30121da177e4SLinus Torvalds }
30131da177e4SLinus Torvalds 
30141ca3a9d0SJohan Hedberg /* Send HCI command */
301507dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
301607dc93ddSJohan Hedberg 		 const void *param)
30171ca3a9d0SJohan Hedberg {
30181ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
30191ca3a9d0SJohan Hedberg 
30201ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
30211ca3a9d0SJohan Hedberg 
30221ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
30231ca3a9d0SJohan Hedberg 	if (!skb) {
30242064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no memory for command");
30251ca3a9d0SJohan Hedberg 		return -ENOMEM;
30261ca3a9d0SJohan Hedberg 	}
30271ca3a9d0SJohan Hedberg 
302849c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
302911714b3dSJohan Hedberg 	 * single-command requests.
303011714b3dSJohan Hedberg 	 */
303144d27137SJohan Hedberg 	bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
303211714b3dSJohan Hedberg 
30331da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
3034c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
30351da177e4SLinus Torvalds 
30361da177e4SLinus Torvalds 	return 0;
30371da177e4SLinus Torvalds }
30381da177e4SLinus Torvalds 
3039d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
3040d6ee6ad7SLoic Poulain 		   const void *param)
3041d6ee6ad7SLoic Poulain {
3042d6ee6ad7SLoic Poulain 	struct sk_buff *skb;
3043d6ee6ad7SLoic Poulain 
3044d6ee6ad7SLoic Poulain 	if (hci_opcode_ogf(opcode) != 0x3f) {
3045d6ee6ad7SLoic Poulain 		/* A controller receiving a command shall respond with either
3046d6ee6ad7SLoic Poulain 		 * a Command Status Event or a Command Complete Event.
3047d6ee6ad7SLoic Poulain 		 * Therefore, all standard HCI commands must be sent via the
3048d6ee6ad7SLoic Poulain 		 * standard API, using hci_send_cmd or hci_cmd_sync helpers.
3049d6ee6ad7SLoic Poulain 		 * Some vendors do not comply with this rule for vendor-specific
3050d6ee6ad7SLoic Poulain 		 * commands and do not return any event. We want to support
3051d6ee6ad7SLoic Poulain 		 * unresponded commands for such cases only.
3052d6ee6ad7SLoic Poulain 		 */
3053d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "unresponded command not supported");
3054d6ee6ad7SLoic Poulain 		return -EINVAL;
3055d6ee6ad7SLoic Poulain 	}
3056d6ee6ad7SLoic Poulain 
3057d6ee6ad7SLoic Poulain 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
3058d6ee6ad7SLoic Poulain 	if (!skb) {
3059d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)",
3060d6ee6ad7SLoic Poulain 			   opcode);
3061d6ee6ad7SLoic Poulain 		return -ENOMEM;
3062d6ee6ad7SLoic Poulain 	}
3063d6ee6ad7SLoic Poulain 
3064d6ee6ad7SLoic Poulain 	hci_send_frame(hdev, skb);
3065d6ee6ad7SLoic Poulain 
3066d6ee6ad7SLoic Poulain 	return 0;
3067d6ee6ad7SLoic Poulain }
3068d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send);
3069d6ee6ad7SLoic Poulain 
30701da177e4SLinus Torvalds /* Get data from the previously sent command */
3071a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
30721da177e4SLinus Torvalds {
30731da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
30741da177e4SLinus Torvalds 
30751da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
30761da177e4SLinus Torvalds 		return NULL;
30771da177e4SLinus Torvalds 
30781da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
30791da177e4SLinus Torvalds 
3080a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
30811da177e4SLinus Torvalds 		return NULL;
30821da177e4SLinus Torvalds 
3083f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
30841da177e4SLinus Torvalds 
30851da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
30861da177e4SLinus Torvalds }
30871da177e4SLinus Torvalds 
3088dfe6d5c3SLuiz Augusto von Dentz /* Get data from last received event */
3089dfe6d5c3SLuiz Augusto von Dentz void *hci_recv_event_data(struct hci_dev *hdev, __u8 event)
3090dfe6d5c3SLuiz Augusto von Dentz {
3091dfe6d5c3SLuiz Augusto von Dentz 	struct hci_event_hdr *hdr;
3092dfe6d5c3SLuiz Augusto von Dentz 	int offset;
3093dfe6d5c3SLuiz Augusto von Dentz 
3094dfe6d5c3SLuiz Augusto von Dentz 	if (!hdev->recv_event)
3095dfe6d5c3SLuiz Augusto von Dentz 		return NULL;
3096dfe6d5c3SLuiz Augusto von Dentz 
3097dfe6d5c3SLuiz Augusto von Dentz 	hdr = (void *)hdev->recv_event->data;
3098dfe6d5c3SLuiz Augusto von Dentz 	offset = sizeof(*hdr);
3099dfe6d5c3SLuiz Augusto von Dentz 
3100dfe6d5c3SLuiz Augusto von Dentz 	if (hdr->evt != event) {
3101dfe6d5c3SLuiz Augusto von Dentz 		/* In case of LE metaevent check the subevent match */
3102dfe6d5c3SLuiz Augusto von Dentz 		if (hdr->evt == HCI_EV_LE_META) {
3103dfe6d5c3SLuiz Augusto von Dentz 			struct hci_ev_le_meta *ev;
3104dfe6d5c3SLuiz Augusto von Dentz 
3105dfe6d5c3SLuiz Augusto von Dentz 			ev = (void *)hdev->recv_event->data + offset;
3106dfe6d5c3SLuiz Augusto von Dentz 			offset += sizeof(*ev);
3107dfe6d5c3SLuiz Augusto von Dentz 			if (ev->subevent == event)
3108dfe6d5c3SLuiz Augusto von Dentz 				goto found;
3109dfe6d5c3SLuiz Augusto von Dentz 		}
3110dfe6d5c3SLuiz Augusto von Dentz 		return NULL;
3111dfe6d5c3SLuiz Augusto von Dentz 	}
3112dfe6d5c3SLuiz Augusto von Dentz 
3113dfe6d5c3SLuiz Augusto von Dentz found:
3114dfe6d5c3SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "event 0x%2.2x", event);
3115dfe6d5c3SLuiz Augusto von Dentz 
3116dfe6d5c3SLuiz Augusto von Dentz 	return hdev->recv_event->data + offset;
3117dfe6d5c3SLuiz Augusto von Dentz }
3118dfe6d5c3SLuiz Augusto von Dentz 
31191da177e4SLinus Torvalds /* Send ACL data */
31201da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
31211da177e4SLinus Torvalds {
31221da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
31231da177e4SLinus Torvalds 	int len = skb->len;
31241da177e4SLinus Torvalds 
3125badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3126badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
31279c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
3128aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3129aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
31301da177e4SLinus Torvalds }
31311da177e4SLinus Torvalds 
3132ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
313373d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
31341da177e4SLinus Torvalds {
3135ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
31361da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
31371da177e4SLinus Torvalds 	struct sk_buff *list;
31381da177e4SLinus Torvalds 
3139087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3140087bfd99SGustavo Padovan 	skb->data_len = 0;
3141087bfd99SGustavo Padovan 
3142d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3143204a6e54SAndrei Emeltchenko 
3144204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
3145ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
3146087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
3147204a6e54SAndrei Emeltchenko 		break;
3148204a6e54SAndrei Emeltchenko 	case HCI_AMP:
3149204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
3150204a6e54SAndrei Emeltchenko 		break;
3151204a6e54SAndrei Emeltchenko 	default:
31522064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type);
3153204a6e54SAndrei Emeltchenko 		return;
3154204a6e54SAndrei Emeltchenko 	}
3155087bfd99SGustavo Padovan 
315670f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
315770f23020SAndrei Emeltchenko 	if (!list) {
31581da177e4SLinus Torvalds 		/* Non fragmented */
31591da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
31601da177e4SLinus Torvalds 
316173d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
31621da177e4SLinus Torvalds 	} else {
31631da177e4SLinus Torvalds 		/* Fragmented */
31641da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
31651da177e4SLinus Torvalds 
31661da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
31671da177e4SLinus Torvalds 
31689cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
31699cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
31709cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
31719cfd5a23SJukka Rissanen 		 * deadlocks.
31729cfd5a23SJukka Rissanen 		 */
31739cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
31741da177e4SLinus Torvalds 
317573d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3176e702112fSAndrei Emeltchenko 
3177e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3178e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
31791da177e4SLinus Torvalds 		do {
31801da177e4SLinus Torvalds 			skb = list; list = list->next;
31811da177e4SLinus Torvalds 
3182d79f34e3SMarcel Holtmann 			hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3183e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
31841da177e4SLinus Torvalds 
31851da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
31861da177e4SLinus Torvalds 
318773d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
31881da177e4SLinus Torvalds 		} while (list);
31891da177e4SLinus Torvalds 
31909cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
31911da177e4SLinus Torvalds 	}
319273d80debSLuiz Augusto von Dentz }
319373d80debSLuiz Augusto von Dentz 
319473d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
319573d80debSLuiz Augusto von Dentz {
3196ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
319773d80debSLuiz Augusto von Dentz 
3198f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
319973d80debSLuiz Augusto von Dentz 
3200ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
32011da177e4SLinus Torvalds 
32023eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
32031da177e4SLinus Torvalds }
32041da177e4SLinus Torvalds 
32051da177e4SLinus Torvalds /* Send SCO data */
32060d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
32071da177e4SLinus Torvalds {
32081da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
32091da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
32101da177e4SLinus Torvalds 
32111da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
32121da177e4SLinus Torvalds 
3213aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
32141da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
32151da177e4SLinus Torvalds 
3216badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3217badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
32189c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
32191da177e4SLinus Torvalds 
3220d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
3221c78ae283SMarcel Holtmann 
32221da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
32233eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
32241da177e4SLinus Torvalds }
32251da177e4SLinus Torvalds 
322626afbd82SLuiz Augusto von Dentz /* Send ISO data */
322726afbd82SLuiz Augusto von Dentz static void hci_add_iso_hdr(struct sk_buff *skb, __u16 handle, __u8 flags)
322826afbd82SLuiz Augusto von Dentz {
322926afbd82SLuiz Augusto von Dentz 	struct hci_iso_hdr *hdr;
323026afbd82SLuiz Augusto von Dentz 	int len = skb->len;
323126afbd82SLuiz Augusto von Dentz 
323226afbd82SLuiz Augusto von Dentz 	skb_push(skb, HCI_ISO_HDR_SIZE);
323326afbd82SLuiz Augusto von Dentz 	skb_reset_transport_header(skb);
323426afbd82SLuiz Augusto von Dentz 	hdr = (struct hci_iso_hdr *)skb_transport_header(skb);
323526afbd82SLuiz Augusto von Dentz 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
323626afbd82SLuiz Augusto von Dentz 	hdr->dlen   = cpu_to_le16(len);
323726afbd82SLuiz Augusto von Dentz }
323826afbd82SLuiz Augusto von Dentz 
323926afbd82SLuiz Augusto von Dentz static void hci_queue_iso(struct hci_conn *conn, struct sk_buff_head *queue,
324026afbd82SLuiz Augusto von Dentz 			  struct sk_buff *skb)
324126afbd82SLuiz Augusto von Dentz {
324226afbd82SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
324326afbd82SLuiz Augusto von Dentz 	struct sk_buff *list;
324426afbd82SLuiz Augusto von Dentz 	__u16 flags;
324526afbd82SLuiz Augusto von Dentz 
324626afbd82SLuiz Augusto von Dentz 	skb->len = skb_headlen(skb);
324726afbd82SLuiz Augusto von Dentz 	skb->data_len = 0;
324826afbd82SLuiz Augusto von Dentz 
324926afbd82SLuiz Augusto von Dentz 	hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
325026afbd82SLuiz Augusto von Dentz 
325126afbd82SLuiz Augusto von Dentz 	list = skb_shinfo(skb)->frag_list;
325226afbd82SLuiz Augusto von Dentz 
325326afbd82SLuiz Augusto von Dentz 	flags = hci_iso_flags_pack(list ? ISO_START : ISO_SINGLE, 0x00);
325426afbd82SLuiz Augusto von Dentz 	hci_add_iso_hdr(skb, conn->handle, flags);
325526afbd82SLuiz Augusto von Dentz 
325626afbd82SLuiz Augusto von Dentz 	if (!list) {
325726afbd82SLuiz Augusto von Dentz 		/* Non fragmented */
325826afbd82SLuiz Augusto von Dentz 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
325926afbd82SLuiz Augusto von Dentz 
326026afbd82SLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
326126afbd82SLuiz Augusto von Dentz 	} else {
326226afbd82SLuiz Augusto von Dentz 		/* Fragmented */
326326afbd82SLuiz Augusto von Dentz 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
326426afbd82SLuiz Augusto von Dentz 
326526afbd82SLuiz Augusto von Dentz 		skb_shinfo(skb)->frag_list = NULL;
326626afbd82SLuiz Augusto von Dentz 
326726afbd82SLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
326826afbd82SLuiz Augusto von Dentz 
326926afbd82SLuiz Augusto von Dentz 		do {
327026afbd82SLuiz Augusto von Dentz 			skb = list; list = list->next;
327126afbd82SLuiz Augusto von Dentz 
327226afbd82SLuiz Augusto von Dentz 			hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
327326afbd82SLuiz Augusto von Dentz 			flags = hci_iso_flags_pack(list ? ISO_CONT : ISO_END,
327426afbd82SLuiz Augusto von Dentz 						   0x00);
327526afbd82SLuiz Augusto von Dentz 			hci_add_iso_hdr(skb, conn->handle, flags);
327626afbd82SLuiz Augusto von Dentz 
327726afbd82SLuiz Augusto von Dentz 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
327826afbd82SLuiz Augusto von Dentz 
327926afbd82SLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
328026afbd82SLuiz Augusto von Dentz 		} while (list);
328126afbd82SLuiz Augusto von Dentz 	}
328226afbd82SLuiz Augusto von Dentz }
328326afbd82SLuiz Augusto von Dentz 
328426afbd82SLuiz Augusto von Dentz void hci_send_iso(struct hci_conn *conn, struct sk_buff *skb)
328526afbd82SLuiz Augusto von Dentz {
328626afbd82SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
328726afbd82SLuiz Augusto von Dentz 
328826afbd82SLuiz Augusto von Dentz 	BT_DBG("%s len %d", hdev->name, skb->len);
328926afbd82SLuiz Augusto von Dentz 
329026afbd82SLuiz Augusto von Dentz 	hci_queue_iso(conn, &conn->data_q, skb);
329126afbd82SLuiz Augusto von Dentz 
329226afbd82SLuiz Augusto von Dentz 	queue_work(hdev->workqueue, &hdev->tx_work);
329326afbd82SLuiz Augusto von Dentz }
329426afbd82SLuiz Augusto von Dentz 
32951da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
32961da177e4SLinus Torvalds 
32971da177e4SLinus Torvalds /* HCI Connection scheduler */
329826afbd82SLuiz Augusto von Dentz static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote)
329926afbd82SLuiz Augusto von Dentz {
330026afbd82SLuiz Augusto von Dentz 	struct hci_dev *hdev;
330126afbd82SLuiz Augusto von Dentz 	int cnt, q;
330226afbd82SLuiz Augusto von Dentz 
330326afbd82SLuiz Augusto von Dentz 	if (!conn) {
330426afbd82SLuiz Augusto von Dentz 		*quote = 0;
330526afbd82SLuiz Augusto von Dentz 		return;
330626afbd82SLuiz Augusto von Dentz 	}
330726afbd82SLuiz Augusto von Dentz 
330826afbd82SLuiz Augusto von Dentz 	hdev = conn->hdev;
330926afbd82SLuiz Augusto von Dentz 
331026afbd82SLuiz Augusto von Dentz 	switch (conn->type) {
331126afbd82SLuiz Augusto von Dentz 	case ACL_LINK:
331226afbd82SLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
331326afbd82SLuiz Augusto von Dentz 		break;
331426afbd82SLuiz Augusto von Dentz 	case AMP_LINK:
331526afbd82SLuiz Augusto von Dentz 		cnt = hdev->block_cnt;
331626afbd82SLuiz Augusto von Dentz 		break;
331726afbd82SLuiz Augusto von Dentz 	case SCO_LINK:
331826afbd82SLuiz Augusto von Dentz 	case ESCO_LINK:
331926afbd82SLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
332026afbd82SLuiz Augusto von Dentz 		break;
332126afbd82SLuiz Augusto von Dentz 	case LE_LINK:
332226afbd82SLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
332326afbd82SLuiz Augusto von Dentz 		break;
332426afbd82SLuiz Augusto von Dentz 	case ISO_LINK:
332526afbd82SLuiz Augusto von Dentz 		cnt = hdev->iso_mtu ? hdev->iso_cnt :
332626afbd82SLuiz Augusto von Dentz 			hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
332726afbd82SLuiz Augusto von Dentz 		break;
332826afbd82SLuiz Augusto von Dentz 	default:
332926afbd82SLuiz Augusto von Dentz 		cnt = 0;
333026afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev, "unknown link type %d", conn->type);
333126afbd82SLuiz Augusto von Dentz 	}
333226afbd82SLuiz Augusto von Dentz 
333326afbd82SLuiz Augusto von Dentz 	q = cnt / num;
333426afbd82SLuiz Augusto von Dentz 	*quote = q ? q : 1;
333526afbd82SLuiz Augusto von Dentz }
333626afbd82SLuiz Augusto von Dentz 
33376039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3338a8c5fb1aSGustavo Padovan 				     int *quote)
33391da177e4SLinus Torvalds {
33401da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
33418035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
3342abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
33431da177e4SLinus Torvalds 
33441da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
33451da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
3346bf4c6325SGustavo F. Padovan 
3347bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3348bf4c6325SGustavo F. Padovan 
3349bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3350769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
33511da177e4SLinus Torvalds 			continue;
3352769be974SMarcel Holtmann 
3353769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3354769be974SMarcel Holtmann 			continue;
3355769be974SMarcel Holtmann 
33561da177e4SLinus Torvalds 		num++;
33571da177e4SLinus Torvalds 
33581da177e4SLinus Torvalds 		if (c->sent < min) {
33591da177e4SLinus Torvalds 			min  = c->sent;
33601da177e4SLinus Torvalds 			conn = c;
33611da177e4SLinus Torvalds 		}
336252087a79SLuiz Augusto von Dentz 
336352087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
336452087a79SLuiz Augusto von Dentz 			break;
33651da177e4SLinus Torvalds 	}
33661da177e4SLinus Torvalds 
3367bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3368bf4c6325SGustavo F. Padovan 
336926afbd82SLuiz Augusto von Dentz 	hci_quote_sent(conn, num, quote);
33701da177e4SLinus Torvalds 
33711da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
33721da177e4SLinus Torvalds 	return conn;
33731da177e4SLinus Torvalds }
33741da177e4SLinus Torvalds 
33756039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
33761da177e4SLinus Torvalds {
33771da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
33781da177e4SLinus Torvalds 	struct hci_conn *c;
33791da177e4SLinus Torvalds 
33802064ee33SMarcel Holtmann 	bt_dev_err(hdev, "link tx timeout");
33811da177e4SLinus Torvalds 
3382bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3383bf4c6325SGustavo F. Padovan 
33841da177e4SLinus Torvalds 	/* Kill stalled connections */
3385bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3386bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
33872064ee33SMarcel Holtmann 			bt_dev_err(hdev, "killing stalled connection %pMR",
33882064ee33SMarcel Holtmann 				   &c->dst);
3389bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
33901da177e4SLinus Torvalds 		}
33911da177e4SLinus Torvalds 	}
3392bf4c6325SGustavo F. Padovan 
3393bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
33941da177e4SLinus Torvalds }
33951da177e4SLinus Torvalds 
33966039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
339773d80debSLuiz Augusto von Dentz 				      int *quote)
339873d80debSLuiz Augusto von Dentz {
339973d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
340073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3401abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
340273d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
340326afbd82SLuiz Augusto von Dentz 	int conn_num = 0;
340473d80debSLuiz Augusto von Dentz 
340573d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
340673d80debSLuiz Augusto von Dentz 
3407bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3408bf4c6325SGustavo F. Padovan 
3409bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
341073d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
341173d80debSLuiz Augusto von Dentz 
341273d80debSLuiz Augusto von Dentz 		if (conn->type != type)
341373d80debSLuiz Augusto von Dentz 			continue;
341473d80debSLuiz Augusto von Dentz 
341573d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
341673d80debSLuiz Augusto von Dentz 			continue;
341773d80debSLuiz Augusto von Dentz 
341873d80debSLuiz Augusto von Dentz 		conn_num++;
341973d80debSLuiz Augusto von Dentz 
34208192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
342173d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
342273d80debSLuiz Augusto von Dentz 
342373d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
342473d80debSLuiz Augusto von Dentz 				continue;
342573d80debSLuiz Augusto von Dentz 
342673d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
342773d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
342873d80debSLuiz Augusto von Dentz 				continue;
342973d80debSLuiz Augusto von Dentz 
343073d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
343173d80debSLuiz Augusto von Dentz 				num = 0;
343273d80debSLuiz Augusto von Dentz 				min = ~0;
343373d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
343473d80debSLuiz Augusto von Dentz 			}
343573d80debSLuiz Augusto von Dentz 
343673d80debSLuiz Augusto von Dentz 			num++;
343773d80debSLuiz Augusto von Dentz 
343873d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
343973d80debSLuiz Augusto von Dentz 				min  = conn->sent;
344073d80debSLuiz Augusto von Dentz 				chan = tmp;
344173d80debSLuiz Augusto von Dentz 			}
344273d80debSLuiz Augusto von Dentz 		}
344373d80debSLuiz Augusto von Dentz 
344473d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
344573d80debSLuiz Augusto von Dentz 			break;
344673d80debSLuiz Augusto von Dentz 	}
344773d80debSLuiz Augusto von Dentz 
3448bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3449bf4c6325SGustavo F. Padovan 
345073d80debSLuiz Augusto von Dentz 	if (!chan)
345173d80debSLuiz Augusto von Dentz 		return NULL;
345273d80debSLuiz Augusto von Dentz 
345326afbd82SLuiz Augusto von Dentz 	hci_quote_sent(chan->conn, num, quote);
345473d80debSLuiz Augusto von Dentz 
345573d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
345673d80debSLuiz Augusto von Dentz 	return chan;
345773d80debSLuiz Augusto von Dentz }
345873d80debSLuiz Augusto von Dentz 
345902b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
346002b20f0bSLuiz Augusto von Dentz {
346102b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
346202b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
346302b20f0bSLuiz Augusto von Dentz 	int num = 0;
346402b20f0bSLuiz Augusto von Dentz 
346502b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
346602b20f0bSLuiz Augusto von Dentz 
3467bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3468bf4c6325SGustavo F. Padovan 
3469bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
347002b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
347102b20f0bSLuiz Augusto von Dentz 
347202b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
347302b20f0bSLuiz Augusto von Dentz 			continue;
347402b20f0bSLuiz Augusto von Dentz 
347502b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
347602b20f0bSLuiz Augusto von Dentz 			continue;
347702b20f0bSLuiz Augusto von Dentz 
347802b20f0bSLuiz Augusto von Dentz 		num++;
347902b20f0bSLuiz Augusto von Dentz 
34808192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
348102b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
348202b20f0bSLuiz Augusto von Dentz 
348302b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
348402b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
348502b20f0bSLuiz Augusto von Dentz 				continue;
348602b20f0bSLuiz Augusto von Dentz 			}
348702b20f0bSLuiz Augusto von Dentz 
348802b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
348902b20f0bSLuiz Augusto von Dentz 				continue;
349002b20f0bSLuiz Augusto von Dentz 
349102b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
349202b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
349302b20f0bSLuiz Augusto von Dentz 				continue;
349402b20f0bSLuiz Augusto von Dentz 
349502b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
349602b20f0bSLuiz Augusto von Dentz 
349702b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
349802b20f0bSLuiz Augusto von Dentz 			       skb->priority);
349902b20f0bSLuiz Augusto von Dentz 		}
350002b20f0bSLuiz Augusto von Dentz 
350102b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
350202b20f0bSLuiz Augusto von Dentz 			break;
350302b20f0bSLuiz Augusto von Dentz 	}
3504bf4c6325SGustavo F. Padovan 
3505bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3506bf4c6325SGustavo F. Padovan 
350702b20f0bSLuiz Augusto von Dentz }
350802b20f0bSLuiz Augusto von Dentz 
3509b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3510b71d385aSAndrei Emeltchenko {
3511b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3512b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3513b71d385aSAndrei Emeltchenko }
3514b71d385aSAndrei Emeltchenko 
3515116523c8SLuiz Augusto von Dentz static void __check_timeout(struct hci_dev *hdev, unsigned int cnt, u8 type)
35161da177e4SLinus Torvalds {
3517116523c8SLuiz Augusto von Dentz 	unsigned long last_tx;
3518116523c8SLuiz Augusto von Dentz 
3519116523c8SLuiz Augusto von Dentz 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
3520116523c8SLuiz Augusto von Dentz 		return;
3521116523c8SLuiz Augusto von Dentz 
3522116523c8SLuiz Augusto von Dentz 	switch (type) {
3523116523c8SLuiz Augusto von Dentz 	case LE_LINK:
3524116523c8SLuiz Augusto von Dentz 		last_tx = hdev->le_last_tx;
3525116523c8SLuiz Augusto von Dentz 		break;
3526116523c8SLuiz Augusto von Dentz 	default:
3527116523c8SLuiz Augusto von Dentz 		last_tx = hdev->acl_last_tx;
3528116523c8SLuiz Augusto von Dentz 		break;
35291da177e4SLinus Torvalds 	}
3530116523c8SLuiz Augusto von Dentz 
3531116523c8SLuiz Augusto von Dentz 	/* tx timeout must be longer than maximum link supervision timeout
3532116523c8SLuiz Augusto von Dentz 	 * (40.9 seconds)
3533116523c8SLuiz Augusto von Dentz 	 */
3534116523c8SLuiz Augusto von Dentz 	if (!cnt && time_after(jiffies, last_tx + HCI_ACL_TX_TIMEOUT))
3535116523c8SLuiz Augusto von Dentz 		hci_link_tx_to(hdev, type);
353663d2bc1bSAndrei Emeltchenko }
35371da177e4SLinus Torvalds 
35387fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */
35397fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev)
35407fedd3bbSAbhishek Pandit-Subedi {
35417fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
35427fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
35437fedd3bbSAbhishek Pandit-Subedi 	int quote;
35447fedd3bbSAbhishek Pandit-Subedi 
35457fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
35467fedd3bbSAbhishek Pandit-Subedi 
35477fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, SCO_LINK))
35487fedd3bbSAbhishek Pandit-Subedi 		return;
35497fedd3bbSAbhishek Pandit-Subedi 
35507fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
35517fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
35527fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
35537fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
35547fedd3bbSAbhishek Pandit-Subedi 
35557fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
35567fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
35577fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
35587fedd3bbSAbhishek Pandit-Subedi 		}
35597fedd3bbSAbhishek Pandit-Subedi 	}
35607fedd3bbSAbhishek Pandit-Subedi }
35617fedd3bbSAbhishek Pandit-Subedi 
35627fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev)
35637fedd3bbSAbhishek Pandit-Subedi {
35647fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
35657fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
35667fedd3bbSAbhishek Pandit-Subedi 	int quote;
35677fedd3bbSAbhishek Pandit-Subedi 
35687fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
35697fedd3bbSAbhishek Pandit-Subedi 
35707fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, ESCO_LINK))
35717fedd3bbSAbhishek Pandit-Subedi 		return;
35727fedd3bbSAbhishek Pandit-Subedi 
35737fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
35747fedd3bbSAbhishek Pandit-Subedi 						     &quote))) {
35757fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
35767fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
35777fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
35787fedd3bbSAbhishek Pandit-Subedi 
35797fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
35807fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
35817fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
35827fedd3bbSAbhishek Pandit-Subedi 		}
35837fedd3bbSAbhishek Pandit-Subedi 	}
35847fedd3bbSAbhishek Pandit-Subedi }
35857fedd3bbSAbhishek Pandit-Subedi 
35866039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
358763d2bc1bSAndrei Emeltchenko {
358863d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
358963d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
359063d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
359163d2bc1bSAndrei Emeltchenko 	int quote;
359263d2bc1bSAndrei Emeltchenko 
3593116523c8SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt, ACL_LINK);
359404837f64SMarcel Holtmann 
359573d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
359673d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3597ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3598ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
359973d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
360073d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
360173d80debSLuiz Augusto von Dentz 
3602ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3603ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3604ec1cce24SLuiz Augusto von Dentz 				break;
3605ec1cce24SLuiz Augusto von Dentz 
3606ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3607ec1cce24SLuiz Augusto von Dentz 
360873d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
360973d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
361004837f64SMarcel Holtmann 
361157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
36121da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
36131da177e4SLinus Torvalds 
36141da177e4SLinus Torvalds 			hdev->acl_cnt--;
361573d80debSLuiz Augusto von Dentz 			chan->sent++;
361673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
36177fedd3bbSAbhishek Pandit-Subedi 
36187fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
36197fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
36207fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
36211da177e4SLinus Torvalds 		}
36221da177e4SLinus Torvalds 	}
362302b20f0bSLuiz Augusto von Dentz 
362402b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
362502b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
36261da177e4SLinus Torvalds }
36271da177e4SLinus Torvalds 
36286039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3629b71d385aSAndrei Emeltchenko {
363063d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3631b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3632b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3633b71d385aSAndrei Emeltchenko 	int quote;
3634bd1eb66bSAndrei Emeltchenko 	u8 type;
3635b71d385aSAndrei Emeltchenko 
3636bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3637bd1eb66bSAndrei Emeltchenko 
3638bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3639bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3640bd1eb66bSAndrei Emeltchenko 	else
3641bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3642bd1eb66bSAndrei Emeltchenko 
3643116523c8SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt, type);
3644116523c8SLuiz Augusto von Dentz 
3645b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3646bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3647b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3648b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3649b71d385aSAndrei Emeltchenko 			int blocks;
3650b71d385aSAndrei Emeltchenko 
3651b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3652b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3653b71d385aSAndrei Emeltchenko 
3654b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3655b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3656b71d385aSAndrei Emeltchenko 				break;
3657b71d385aSAndrei Emeltchenko 
3658b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3659b71d385aSAndrei Emeltchenko 
3660b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3661b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3662b71d385aSAndrei Emeltchenko 				return;
3663b71d385aSAndrei Emeltchenko 
3664b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3665b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3666b71d385aSAndrei Emeltchenko 
366757d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3668b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3669b71d385aSAndrei Emeltchenko 
3670b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3671b71d385aSAndrei Emeltchenko 			quote -= blocks;
3672b71d385aSAndrei Emeltchenko 
3673b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3674b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3675b71d385aSAndrei Emeltchenko 		}
3676b71d385aSAndrei Emeltchenko 	}
3677b71d385aSAndrei Emeltchenko 
3678b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3679bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3680b71d385aSAndrei Emeltchenko }
3681b71d385aSAndrei Emeltchenko 
36826039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3683b71d385aSAndrei Emeltchenko {
3684b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3685b71d385aSAndrei Emeltchenko 
3686bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3687ca8bee5dSMarcel Holtmann 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY)
3688bd1eb66bSAndrei Emeltchenko 		return;
3689bd1eb66bSAndrei Emeltchenko 
3690bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3691bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3692b71d385aSAndrei Emeltchenko 		return;
3693b71d385aSAndrei Emeltchenko 
3694b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3695b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3696b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3697b71d385aSAndrei Emeltchenko 		break;
3698b71d385aSAndrei Emeltchenko 
3699b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3700b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3701b71d385aSAndrei Emeltchenko 		break;
3702b71d385aSAndrei Emeltchenko 	}
3703b71d385aSAndrei Emeltchenko }
3704b71d385aSAndrei Emeltchenko 
37056039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
37066ed58ec5SVille Tervo {
370773d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
37086ed58ec5SVille Tervo 	struct sk_buff *skb;
370902b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
37106ed58ec5SVille Tervo 
37116ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
37126ed58ec5SVille Tervo 
371352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
371452087a79SLuiz Augusto von Dentz 		return;
371552087a79SLuiz Augusto von Dentz 
37166ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
37171b1d29e5SLuiz Augusto von Dentz 
3718116523c8SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt, LE_LINK);
37191b1d29e5SLuiz Augusto von Dentz 
372002b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
372173d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3722ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3723ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
372473d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
372573d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
37266ed58ec5SVille Tervo 
3727ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3728ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3729ec1cce24SLuiz Augusto von Dentz 				break;
3730ec1cce24SLuiz Augusto von Dentz 
3731ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3732ec1cce24SLuiz Augusto von Dentz 
373357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
37346ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
37356ed58ec5SVille Tervo 
37366ed58ec5SVille Tervo 			cnt--;
373773d80debSLuiz Augusto von Dentz 			chan->sent++;
373873d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
37397fedd3bbSAbhishek Pandit-Subedi 
37407fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
37417fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
37427fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
37436ed58ec5SVille Tervo 		}
37446ed58ec5SVille Tervo 	}
374573d80debSLuiz Augusto von Dentz 
37466ed58ec5SVille Tervo 	if (hdev->le_pkts)
37476ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
37486ed58ec5SVille Tervo 	else
37496ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
375002b20f0bSLuiz Augusto von Dentz 
375102b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
375202b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
37536ed58ec5SVille Tervo }
37546ed58ec5SVille Tervo 
375526afbd82SLuiz Augusto von Dentz /* Schedule CIS */
375626afbd82SLuiz Augusto von Dentz static void hci_sched_iso(struct hci_dev *hdev)
375726afbd82SLuiz Augusto von Dentz {
375826afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
375926afbd82SLuiz Augusto von Dentz 	struct sk_buff *skb;
376026afbd82SLuiz Augusto von Dentz 	int quote, *cnt;
376126afbd82SLuiz Augusto von Dentz 
376226afbd82SLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
376326afbd82SLuiz Augusto von Dentz 
376426afbd82SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ISO_LINK))
376526afbd82SLuiz Augusto von Dentz 		return;
376626afbd82SLuiz Augusto von Dentz 
376726afbd82SLuiz Augusto von Dentz 	cnt = hdev->iso_pkts ? &hdev->iso_cnt :
376826afbd82SLuiz Augusto von Dentz 		hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt;
376926afbd82SLuiz Augusto von Dentz 	while (*cnt && (conn = hci_low_sent(hdev, ISO_LINK, &quote))) {
377026afbd82SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
377126afbd82SLuiz Augusto von Dentz 			BT_DBG("skb %p len %d", skb, skb->len);
377226afbd82SLuiz Augusto von Dentz 			hci_send_frame(hdev, skb);
377326afbd82SLuiz Augusto von Dentz 
377426afbd82SLuiz Augusto von Dentz 			conn->sent++;
377526afbd82SLuiz Augusto von Dentz 			if (conn->sent == ~0)
377626afbd82SLuiz Augusto von Dentz 				conn->sent = 0;
377726afbd82SLuiz Augusto von Dentz 			(*cnt)--;
377826afbd82SLuiz Augusto von Dentz 		}
377926afbd82SLuiz Augusto von Dentz 	}
378026afbd82SLuiz Augusto von Dentz }
378126afbd82SLuiz Augusto von Dentz 
37823eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
37831da177e4SLinus Torvalds {
37843eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
37851da177e4SLinus Torvalds 	struct sk_buff *skb;
37861da177e4SLinus Torvalds 
378726afbd82SLuiz Augusto von Dentz 	BT_DBG("%s acl %d sco %d le %d iso %d", hdev->name, hdev->acl_cnt,
378826afbd82SLuiz Augusto von Dentz 	       hdev->sco_cnt, hdev->le_cnt, hdev->iso_cnt);
37891da177e4SLinus Torvalds 
3790d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
37911da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
37921da177e4SLinus Torvalds 		hci_sched_sco(hdev);
3793b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
379426afbd82SLuiz Augusto von Dentz 		hci_sched_iso(hdev);
37957fedd3bbSAbhishek Pandit-Subedi 		hci_sched_acl(hdev);
37966ed58ec5SVille Tervo 		hci_sched_le(hdev);
379752de599eSMarcel Holtmann 	}
37986ed58ec5SVille Tervo 
37991da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
38001da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
380157d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
38021da177e4SLinus Torvalds }
38031da177e4SLinus Torvalds 
380425985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
38051da177e4SLinus Torvalds 
38061da177e4SLinus Torvalds /* ACL data packet */
38076039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
38081da177e4SLinus Torvalds {
38091da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
38101da177e4SLinus Torvalds 	struct hci_conn *conn;
38111da177e4SLinus Torvalds 	__u16 handle, flags;
38121da177e4SLinus Torvalds 
38131da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
38141da177e4SLinus Torvalds 
38151da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
38161da177e4SLinus Torvalds 	flags  = hci_flags(handle);
38171da177e4SLinus Torvalds 	handle = hci_handle(handle);
38181da177e4SLinus Torvalds 
3819f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3820a8c5fb1aSGustavo Padovan 	       handle, flags);
38211da177e4SLinus Torvalds 
38221da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
38231da177e4SLinus Torvalds 
38241da177e4SLinus Torvalds 	hci_dev_lock(hdev);
38251da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
38261da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
38271da177e4SLinus Torvalds 
38281da177e4SLinus Torvalds 	if (conn) {
382965983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
383004837f64SMarcel Holtmann 
38311da177e4SLinus Torvalds 		/* Send to upper protocol */
3832686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
38331da177e4SLinus Torvalds 		return;
38341da177e4SLinus Torvalds 	} else {
38352064ee33SMarcel Holtmann 		bt_dev_err(hdev, "ACL packet for unknown connection handle %d",
38362064ee33SMarcel Holtmann 			   handle);
38371da177e4SLinus Torvalds 	}
38381da177e4SLinus Torvalds 
38391da177e4SLinus Torvalds 	kfree_skb(skb);
38401da177e4SLinus Torvalds }
38411da177e4SLinus Torvalds 
38421da177e4SLinus Torvalds /* SCO data packet */
38436039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
38441da177e4SLinus Torvalds {
38451da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
38461da177e4SLinus Torvalds 	struct hci_conn *conn;
3847debdedf2SMarcel Holtmann 	__u16 handle, flags;
38481da177e4SLinus Torvalds 
38491da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
38501da177e4SLinus Torvalds 
38511da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
3852debdedf2SMarcel Holtmann 	flags  = hci_flags(handle);
3853debdedf2SMarcel Holtmann 	handle = hci_handle(handle);
38541da177e4SLinus Torvalds 
3855debdedf2SMarcel Holtmann 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3856debdedf2SMarcel Holtmann 	       handle, flags);
38571da177e4SLinus Torvalds 
38581da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
38591da177e4SLinus Torvalds 
38601da177e4SLinus Torvalds 	hci_dev_lock(hdev);
38611da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
38621da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
38631da177e4SLinus Torvalds 
38641da177e4SLinus Torvalds 	if (conn) {
38651da177e4SLinus Torvalds 		/* Send to upper protocol */
386600398e1dSAlain Michaud 		bt_cb(skb)->sco.pkt_status = flags & 0x03;
3867686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
38681da177e4SLinus Torvalds 		return;
38691da177e4SLinus Torvalds 	} else {
38702d4b37b6SLuiz Augusto von Dentz 		bt_dev_err_ratelimited(hdev, "SCO packet for unknown connection handle %d",
38712064ee33SMarcel Holtmann 				       handle);
38721da177e4SLinus Torvalds 	}
38731da177e4SLinus Torvalds 
38741da177e4SLinus Torvalds 	kfree_skb(skb);
38751da177e4SLinus Torvalds }
38761da177e4SLinus Torvalds 
387726afbd82SLuiz Augusto von Dentz static void hci_isodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
387826afbd82SLuiz Augusto von Dentz {
387926afbd82SLuiz Augusto von Dentz 	struct hci_iso_hdr *hdr;
388026afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
388126afbd82SLuiz Augusto von Dentz 	__u16 handle, flags;
388226afbd82SLuiz Augusto von Dentz 
388326afbd82SLuiz Augusto von Dentz 	hdr = skb_pull_data(skb, sizeof(*hdr));
388426afbd82SLuiz Augusto von Dentz 	if (!hdr) {
388526afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev, "ISO packet too small");
388626afbd82SLuiz Augusto von Dentz 		goto drop;
388726afbd82SLuiz Augusto von Dentz 	}
388826afbd82SLuiz Augusto von Dentz 
388926afbd82SLuiz Augusto von Dentz 	handle = __le16_to_cpu(hdr->handle);
389026afbd82SLuiz Augusto von Dentz 	flags  = hci_flags(handle);
389126afbd82SLuiz Augusto von Dentz 	handle = hci_handle(handle);
389226afbd82SLuiz Augusto von Dentz 
389326afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "len %d handle 0x%4.4x flags 0x%4.4x", skb->len,
389426afbd82SLuiz Augusto von Dentz 		   handle, flags);
389526afbd82SLuiz Augusto von Dentz 
389626afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
389726afbd82SLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_handle(hdev, handle);
389826afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
389926afbd82SLuiz Augusto von Dentz 
390026afbd82SLuiz Augusto von Dentz 	if (!conn) {
390126afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev, "ISO packet for unknown connection handle %d",
390226afbd82SLuiz Augusto von Dentz 			   handle);
3903ccf74f23SLuiz Augusto von Dentz 		goto drop;
390426afbd82SLuiz Augusto von Dentz 	}
390526afbd82SLuiz Augusto von Dentz 
3906ccf74f23SLuiz Augusto von Dentz 	/* Send to upper protocol */
3907ccf74f23SLuiz Augusto von Dentz 	iso_recv(conn, skb, flags);
3908ccf74f23SLuiz Augusto von Dentz 	return;
3909ccf74f23SLuiz Augusto von Dentz 
391026afbd82SLuiz Augusto von Dentz drop:
391126afbd82SLuiz Augusto von Dentz 	kfree_skb(skb);
391226afbd82SLuiz Augusto von Dentz }
391326afbd82SLuiz Augusto von Dentz 
39149238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
39159238f36aSJohan Hedberg {
39169238f36aSJohan Hedberg 	struct sk_buff *skb;
39179238f36aSJohan Hedberg 
39189238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
39199238f36aSJohan Hedberg 	if (!skb)
39209238f36aSJohan Hedberg 		return true;
39219238f36aSJohan Hedberg 
392244d27137SJohan Hedberg 	return (bt_cb(skb)->hci.req_flags & HCI_REQ_START);
39239238f36aSJohan Hedberg }
39249238f36aSJohan Hedberg 
392542c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
392642c6b129SJohan Hedberg {
392742c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
392842c6b129SJohan Hedberg 	struct sk_buff *skb;
392942c6b129SJohan Hedberg 	u16 opcode;
393042c6b129SJohan Hedberg 
393142c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
393242c6b129SJohan Hedberg 		return;
393342c6b129SJohan Hedberg 
393442c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
393542c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
393642c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
393742c6b129SJohan Hedberg 		return;
393842c6b129SJohan Hedberg 
393942c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
394042c6b129SJohan Hedberg 	if (!skb)
394142c6b129SJohan Hedberg 		return;
394242c6b129SJohan Hedberg 
394342c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
394442c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
394542c6b129SJohan Hedberg }
394642c6b129SJohan Hedberg 
3947e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
3948e6214487SJohan Hedberg 			  hci_req_complete_t *req_complete,
3949e6214487SJohan Hedberg 			  hci_req_complete_skb_t *req_complete_skb)
39509238f36aSJohan Hedberg {
39519238f36aSJohan Hedberg 	struct sk_buff *skb;
39529238f36aSJohan Hedberg 	unsigned long flags;
39539238f36aSJohan Hedberg 
39549238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
39559238f36aSJohan Hedberg 
395642c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
395742c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
39589238f36aSJohan Hedberg 	 */
395942c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
396042c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
396142c6b129SJohan Hedberg 		 * reset complete event during init and any pending
396242c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
396342c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
396442c6b129SJohan Hedberg 		 * command.
396542c6b129SJohan Hedberg 		 */
396642c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
396742c6b129SJohan Hedberg 			hci_resend_last(hdev);
396842c6b129SJohan Hedberg 
39699238f36aSJohan Hedberg 		return;
397042c6b129SJohan Hedberg 	}
39719238f36aSJohan Hedberg 
3972f80c5dadSJoão Paulo Rechi Vita 	/* If we reach this point this event matches the last command sent */
3973f80c5dadSJoão Paulo Rechi Vita 	hci_dev_clear_flag(hdev, HCI_CMD_PENDING);
3974f80c5dadSJoão Paulo Rechi Vita 
39759238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
39769238f36aSJohan Hedberg 	 * this request the request is not yet complete.
39779238f36aSJohan Hedberg 	 */
39789238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
39799238f36aSJohan Hedberg 		return;
39809238f36aSJohan Hedberg 
39819238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
39829238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
39839238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
39849238f36aSJohan Hedberg 	 */
398544d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) {
398644d27137SJohan Hedberg 		*req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb;
3987e6214487SJohan Hedberg 		return;
39889238f36aSJohan Hedberg 	}
3989e6214487SJohan Hedberg 
399044d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_complete) {
399144d27137SJohan Hedberg 		*req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete;
3992e6214487SJohan Hedberg 		return;
399353e21fbcSJohan Hedberg 	}
39949238f36aSJohan Hedberg 
39959238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
39969238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
39979238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
399844d27137SJohan Hedberg 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) {
39999238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
40009238f36aSJohan Hedberg 			break;
40019238f36aSJohan Hedberg 		}
40029238f36aSJohan Hedberg 
40033bd7594eSDouglas Anderson 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB)
4004242c0ebdSMarcel Holtmann 			*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
40053bd7594eSDouglas Anderson 		else
40063bd7594eSDouglas Anderson 			*req_complete = bt_cb(skb)->hci.req_complete;
400739c1eb6fSYang Yingliang 		dev_kfree_skb_irq(skb);
40089238f36aSJohan Hedberg 	}
40099238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
40109238f36aSJohan Hedberg }
40119238f36aSJohan Hedberg 
4012b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
40131da177e4SLinus Torvalds {
4014b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
40151da177e4SLinus Torvalds 	struct sk_buff *skb;
40161da177e4SLinus Torvalds 
40171da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
40181da177e4SLinus Torvalds 
40199f30de9eSTamas Koczka 	/* The kcov_remote functions used for collecting packet parsing
40209f30de9eSTamas Koczka 	 * coverage information from this background thread and associate
40219f30de9eSTamas Koczka 	 * the coverage with the syscall's thread which originally injected
40229f30de9eSTamas Koczka 	 * the packet. This helps fuzzing the kernel.
40239f30de9eSTamas Koczka 	 */
40249f30de9eSTamas Koczka 	for (; (skb = skb_dequeue(&hdev->rx_q)); kcov_remote_stop()) {
40259f30de9eSTamas Koczka 		kcov_remote_start_common(skb_get_kcov_handle(skb));
40269f30de9eSTamas Koczka 
4027cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
4028cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
4029cd82e61cSMarcel Holtmann 
40301da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
40311da177e4SLinus Torvalds 			/* Send copy to the sockets */
4032470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
40331da177e4SLinus Torvalds 		}
40341da177e4SLinus Torvalds 
4035eb8c101eSMattijs Korpershoek 		/* If the device has been opened in HCI_USER_CHANNEL,
4036eb8c101eSMattijs Korpershoek 		 * the userspace has exclusive access to device.
4037eb8c101eSMattijs Korpershoek 		 * When device is HCI_INIT, we still need to process
4038eb8c101eSMattijs Korpershoek 		 * the data packets to the driver in order
4039eb8c101eSMattijs Korpershoek 		 * to complete its setup().
4040eb8c101eSMattijs Korpershoek 		 */
4041eb8c101eSMattijs Korpershoek 		if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
4042eb8c101eSMattijs Korpershoek 		    !test_bit(HCI_INIT, &hdev->flags)) {
40431da177e4SLinus Torvalds 			kfree_skb(skb);
40441da177e4SLinus Torvalds 			continue;
40451da177e4SLinus Torvalds 		}
40461da177e4SLinus Torvalds 
40471da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
40481da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
4049d79f34e3SMarcel Holtmann 			switch (hci_skb_pkt_type(skb)) {
40501da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
40511da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
4052cc974003SMarcel Holtmann 			case HCI_ISODATA_PKT:
40531da177e4SLinus Torvalds 				kfree_skb(skb);
40541da177e4SLinus Torvalds 				continue;
40553ff50b79SStephen Hemminger 			}
40561da177e4SLinus Torvalds 		}
40571da177e4SLinus Torvalds 
40581da177e4SLinus Torvalds 		/* Process frame */
4059d79f34e3SMarcel Holtmann 		switch (hci_skb_pkt_type(skb)) {
40601da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
4061b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
40621da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
40631da177e4SLinus Torvalds 			break;
40641da177e4SLinus Torvalds 
40651da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
40661da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
40671da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
40681da177e4SLinus Torvalds 			break;
40691da177e4SLinus Torvalds 
40701da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
40711da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
40721da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
40731da177e4SLinus Torvalds 			break;
40741da177e4SLinus Torvalds 
407526afbd82SLuiz Augusto von Dentz 		case HCI_ISODATA_PKT:
407626afbd82SLuiz Augusto von Dentz 			BT_DBG("%s ISO data packet", hdev->name);
407726afbd82SLuiz Augusto von Dentz 			hci_isodata_packet(hdev, skb);
407826afbd82SLuiz Augusto von Dentz 			break;
407926afbd82SLuiz Augusto von Dentz 
40801da177e4SLinus Torvalds 		default:
40811da177e4SLinus Torvalds 			kfree_skb(skb);
40821da177e4SLinus Torvalds 			break;
40831da177e4SLinus Torvalds 		}
40841da177e4SLinus Torvalds 	}
40851da177e4SLinus Torvalds }
40861da177e4SLinus Torvalds 
4087c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
40881da177e4SLinus Torvalds {
4089c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
40901da177e4SLinus Torvalds 	struct sk_buff *skb;
40911da177e4SLinus Torvalds 
40922104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
40932104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
40941da177e4SLinus Torvalds 
40951da177e4SLinus Torvalds 	/* Send queued commands */
40965a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
40975a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
40985a08ecceSAndrei Emeltchenko 		if (!skb)
40995a08ecceSAndrei Emeltchenko 			return;
41005a08ecceSAndrei Emeltchenko 
41011da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
41021da177e4SLinus Torvalds 
4103a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
410470f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
41052250abadSBenjamin Berg 			int res;
4106f80c5dadSJoão Paulo Rechi Vita 			if (hci_req_status_pend(hdev))
4107f80c5dadSJoão Paulo Rechi Vita 				hci_dev_set_flag(hdev, HCI_CMD_PENDING);
41081da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
41092250abadSBenjamin Berg 
41102250abadSBenjamin Berg 			res = hci_send_frame(hdev, skb);
41112250abadSBenjamin Berg 			if (res < 0)
4112744451c1SBenjamin Berg 				__hci_cmd_sync_cancel(hdev, -res);
41132250abadSBenjamin Berg 
4114deee93d1STetsuo Handa 			rcu_read_lock();
4115877afadaSSchspa Shi 			if (test_bit(HCI_RESET, &hdev->flags) ||
4116877afadaSSchspa Shi 			    hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
411765cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
41187bdb8a5cSSzymon Janc 			else
4119deee93d1STetsuo Handa 				queue_delayed_work(hdev->workqueue, &hdev->cmd_timer,
412065cc2b49SMarcel Holtmann 						   HCI_CMD_TIMEOUT);
4121deee93d1STetsuo Handa 			rcu_read_unlock();
41221da177e4SLinus Torvalds 		} else {
41231da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
4124c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
41251da177e4SLinus Torvalds 		}
41261da177e4SLinus Torvalds 	}
41271da177e4SLinus Torvalds }
4128