xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 5af2e235)
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 
hci_scan_req(struct hci_request * req,unsigned long opt)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 
hci_auth_req(struct hci_request * req,unsigned long opt)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 
hci_encrypt_req(struct hci_request * req,unsigned long opt)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 
hci_linkpol_req(struct hci_request * req,unsigned long opt)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. */
hci_dev_get(int index)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 
hci_discovery_active(struct hci_dev * hdev)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 
hci_discovery_set_state(struct hci_dev * hdev,int state)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 
hci_inquiry_cache_flush(struct hci_dev * hdev)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 
hci_inquiry_cache_lookup(struct hci_dev * hdev,bdaddr_t * bdaddr)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 
hci_inquiry_cache_lookup_unknown(struct hci_dev * hdev,bdaddr_t * bdaddr)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 
hci_inquiry_cache_lookup_resolve(struct hci_dev * hdev,bdaddr_t * bdaddr,int state)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 
hci_inquiry_cache_update_resolve(struct hci_dev * hdev,struct inquiry_entry * ie)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 
hci_inquiry_cache_update(struct hci_dev * hdev,struct inquiry_data * data,bool name_known)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 
inquiry_cache_dump(struct hci_dev * hdev,int num,__u8 * buf)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 
hci_inq_req(struct hci_request * req,unsigned long opt)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 
hci_inquiry(void __user * arg)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 
398d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
39956f87901SJohan Hedberg 		err = -EOPNOTSUPP;
40056f87901SJohan Hedberg 		goto done;
40156f87901SJohan Hedberg 	}
40256f87901SJohan Hedberg 
403f41a4b2bSPavel Skripkin 	/* Restrict maximum inquiry length to 60 seconds */
404f41a4b2bSPavel Skripkin 	if (ir.length > 60) {
405f41a4b2bSPavel Skripkin 		err = -EINVAL;
406f41a4b2bSPavel Skripkin 		goto done;
407f41a4b2bSPavel Skripkin 	}
408f41a4b2bSPavel Skripkin 
40909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4101da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
411a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
4121f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
4131da177e4SLinus Torvalds 		do_inquiry = 1;
4141da177e4SLinus Torvalds 	}
41509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4161da177e4SLinus Torvalds 
41704837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
41870f23020SAndrei Emeltchenko 
41970f23020SAndrei Emeltchenko 	if (do_inquiry) {
42001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
4214ebeee2dSJohan Hedberg 				   timeo, NULL);
42270f23020SAndrei Emeltchenko 		if (err < 0)
4231da177e4SLinus Torvalds 			goto done;
4243e13fa1eSAndre Guedes 
4253e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
4263e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
4273e13fa1eSAndre Guedes 		 */
42874316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
42928a758c8SPan Bian 				TASK_INTERRUPTIBLE)) {
43028a758c8SPan Bian 			err = -EINTR;
43128a758c8SPan Bian 			goto done;
43228a758c8SPan Bian 		}
43370f23020SAndrei Emeltchenko 	}
4341da177e4SLinus Torvalds 
4358fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
4368fc9ced3SGustavo Padovan 	 * 255 entries
4378fc9ced3SGustavo Padovan 	 */
4381da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
4391da177e4SLinus Torvalds 
4401da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
4411da177e4SLinus Torvalds 	 * copy it to the user space.
4421da177e4SLinus Torvalds 	 */
4436da2ec56SKees Cook 	buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL);
44470f23020SAndrei Emeltchenko 	if (!buf) {
4451da177e4SLinus Torvalds 		err = -ENOMEM;
4461da177e4SLinus Torvalds 		goto done;
4471da177e4SLinus Torvalds 	}
4481da177e4SLinus Torvalds 
44909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4501da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
45109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4521da177e4SLinus Torvalds 
4531da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
4541da177e4SLinus Torvalds 
4551da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
4561da177e4SLinus Torvalds 		ptr += sizeof(ir);
4571da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
4581da177e4SLinus Torvalds 				 ir.num_rsp))
4591da177e4SLinus Torvalds 			err = -EFAULT;
4601da177e4SLinus Torvalds 	} else
4611da177e4SLinus Torvalds 		err = -EFAULT;
4621da177e4SLinus Torvalds 
4631da177e4SLinus Torvalds 	kfree(buf);
4641da177e4SLinus Torvalds 
4651da177e4SLinus Torvalds done:
4661da177e4SLinus Torvalds 	hci_dev_put(hdev);
4671da177e4SLinus Torvalds 	return err;
4681da177e4SLinus Torvalds }
4691da177e4SLinus Torvalds 
hci_dev_do_open(struct hci_dev * hdev)470cf75ad8bSLuiz Augusto von Dentz static int hci_dev_do_open(struct hci_dev *hdev)
471cf75ad8bSLuiz Augusto von Dentz {
472cf75ad8bSLuiz Augusto von Dentz 	int ret = 0;
473cf75ad8bSLuiz Augusto von Dentz 
474cf75ad8bSLuiz Augusto von Dentz 	BT_DBG("%s %p", hdev->name, hdev);
475cf75ad8bSLuiz Augusto von Dentz 
476cf75ad8bSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
477cf75ad8bSLuiz Augusto von Dentz 
478cf75ad8bSLuiz Augusto von Dentz 	ret = hci_dev_open_sync(hdev);
479cf75ad8bSLuiz Augusto von Dentz 
480b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
4811da177e4SLinus Torvalds 	return ret;
4821da177e4SLinus Torvalds }
4831da177e4SLinus Torvalds 
484cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
485cbed0ca1SJohan Hedberg 
hci_dev_open(__u16 dev)486cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
487cbed0ca1SJohan Hedberg {
488cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
489cbed0ca1SJohan Hedberg 	int err;
490cbed0ca1SJohan Hedberg 
491cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
492cbed0ca1SJohan Hedberg 	if (!hdev)
493cbed0ca1SJohan Hedberg 		return -ENODEV;
494cbed0ca1SJohan Hedberg 
4954a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
496fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
497fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
498fee746b0SMarcel Holtmann 	 * possible.
499fee746b0SMarcel Holtmann 	 *
500fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
501fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
502fee746b0SMarcel Holtmann 	 * open the device.
503fee746b0SMarcel Holtmann 	 */
504d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
505d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
506fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
507fee746b0SMarcel Holtmann 		goto done;
508fee746b0SMarcel Holtmann 	}
509fee746b0SMarcel Holtmann 
510e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
511e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
512e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
513e1d08f40SJohan Hedberg 	 * completed.
514e1d08f40SJohan Hedberg 	 */
515a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
516e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
517e1d08f40SJohan Hedberg 
518a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
519a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
520a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
521a5c8f270SMarcel Holtmann 	 */
522e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
523e1d08f40SJohan Hedberg 
52412aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
525b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
52612aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
52712aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
52812aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
52912aa4f0aSMarcel Holtmann 	 */
530d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
531d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_MGMT))
532a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BONDABLE);
53312aa4f0aSMarcel Holtmann 
534cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
535cbed0ca1SJohan Hedberg 
536fee746b0SMarcel Holtmann done:
537cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
538cbed0ca1SJohan Hedberg 	return err;
539cbed0ca1SJohan Hedberg }
540cbed0ca1SJohan Hedberg 
hci_dev_do_close(struct hci_dev * hdev)541cf75ad8bSLuiz Augusto von Dentz int hci_dev_do_close(struct hci_dev *hdev)
542cf75ad8bSLuiz Augusto von Dentz {
543cf75ad8bSLuiz Augusto von Dentz 	int err;
544cf75ad8bSLuiz Augusto von Dentz 
545cf75ad8bSLuiz Augusto von Dentz 	BT_DBG("%s %p", hdev->name, hdev);
546cf75ad8bSLuiz Augusto von Dentz 
547cf75ad8bSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
548cf75ad8bSLuiz Augusto von Dentz 
549cf75ad8bSLuiz Augusto von Dentz 	err = hci_dev_close_sync(hdev);
550cf75ad8bSLuiz Augusto von Dentz 
551b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
5521da177e4SLinus Torvalds 
55361969ef8SKangmin Park 	return err;
5541da177e4SLinus Torvalds }
5551da177e4SLinus Torvalds 
hci_dev_close(__u16 dev)5561da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
5571da177e4SLinus Torvalds {
5581da177e4SLinus Torvalds 	struct hci_dev *hdev;
5591da177e4SLinus Torvalds 	int err;
5601da177e4SLinus Torvalds 
56170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
56270f23020SAndrei Emeltchenko 	if (!hdev)
5631da177e4SLinus Torvalds 		return -ENODEV;
5648ee56540SMarcel Holtmann 
565d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
5660736cfa8SMarcel Holtmann 		err = -EBUSY;
5670736cfa8SMarcel Holtmann 		goto done;
5680736cfa8SMarcel Holtmann 	}
5690736cfa8SMarcel Holtmann 
570e36bea6eSVasyl Vavrychuk 	cancel_work_sync(&hdev->power_on);
571a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
5728ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
5738ee56540SMarcel Holtmann 
5741da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
5758ee56540SMarcel Holtmann 
5760736cfa8SMarcel Holtmann done:
5771da177e4SLinus Torvalds 	hci_dev_put(hdev);
5781da177e4SLinus Torvalds 	return err;
5791da177e4SLinus Torvalds }
5801da177e4SLinus Torvalds 
hci_dev_do_reset(struct hci_dev * hdev)5815c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev)
5821da177e4SLinus Torvalds {
5835c912495SMarcel Holtmann 	int ret;
5841da177e4SLinus Torvalds 
5855c912495SMarcel Holtmann 	BT_DBG("%s %p", hdev->name, hdev);
5861da177e4SLinus Torvalds 
587b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
5881da177e4SLinus Torvalds 
5891da177e4SLinus Torvalds 	/* Drop queues */
5901da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
5911da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
5921da177e4SLinus Torvalds 
593877afadaSSchspa Shi 	/* Cancel these to avoid queueing non-chained pending work */
594877afadaSSchspa Shi 	hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
595deee93d1STetsuo Handa 	/* Wait for
596deee93d1STetsuo Handa 	 *
597deee93d1STetsuo Handa 	 *    if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
598deee93d1STetsuo Handa 	 *        queue_delayed_work(&hdev->{cmd,ncmd}_timer)
599deee93d1STetsuo Handa 	 *
600deee93d1STetsuo Handa 	 * inside RCU section to see the flag or complete scheduling.
601deee93d1STetsuo Handa 	 */
602deee93d1STetsuo Handa 	synchronize_rcu();
603deee93d1STetsuo Handa 	/* Explicitly cancel works in case scheduled after setting the flag. */
604877afadaSSchspa Shi 	cancel_delayed_work(&hdev->cmd_timer);
605877afadaSSchspa Shi 	cancel_delayed_work(&hdev->ncmd_timer);
606877afadaSSchspa Shi 
60776727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
60876727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
60976727c02SJohan Hedberg 	 */
61076727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
61176727c02SJohan Hedberg 
61209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6131f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
6141da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
61509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6161da177e4SLinus Torvalds 
6171da177e4SLinus Torvalds 	if (hdev->flush)
6181da177e4SLinus Torvalds 		hdev->flush(hdev);
6191da177e4SLinus Torvalds 
620877afadaSSchspa Shi 	hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
621877afadaSSchspa Shi 
6221da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
62326afbd82SLuiz Augusto von Dentz 	hdev->acl_cnt = 0;
62426afbd82SLuiz Augusto von Dentz 	hdev->sco_cnt = 0;
62526afbd82SLuiz Augusto von Dentz 	hdev->le_cnt = 0;
62626afbd82SLuiz Augusto von Dentz 	hdev->iso_cnt = 0;
6271da177e4SLinus Torvalds 
628d0b13706SLuiz Augusto von Dentz 	ret = hci_reset_sync(hdev);
6291da177e4SLinus Torvalds 
630b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
6311da177e4SLinus Torvalds 	return ret;
6321da177e4SLinus Torvalds }
6331da177e4SLinus Torvalds 
hci_dev_reset(__u16 dev)6345c912495SMarcel Holtmann int hci_dev_reset(__u16 dev)
6355c912495SMarcel Holtmann {
6365c912495SMarcel Holtmann 	struct hci_dev *hdev;
6375c912495SMarcel Holtmann 	int err;
6385c912495SMarcel Holtmann 
6395c912495SMarcel Holtmann 	hdev = hci_dev_get(dev);
6405c912495SMarcel Holtmann 	if (!hdev)
6415c912495SMarcel Holtmann 		return -ENODEV;
6425c912495SMarcel Holtmann 
6435c912495SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
6445c912495SMarcel Holtmann 		err = -ENETDOWN;
6455c912495SMarcel Holtmann 		goto done;
6465c912495SMarcel Holtmann 	}
6475c912495SMarcel Holtmann 
648d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6495c912495SMarcel Holtmann 		err = -EBUSY;
6505c912495SMarcel Holtmann 		goto done;
6515c912495SMarcel Holtmann 	}
6525c912495SMarcel Holtmann 
653d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
6545c912495SMarcel Holtmann 		err = -EOPNOTSUPP;
6555c912495SMarcel Holtmann 		goto done;
6565c912495SMarcel Holtmann 	}
6575c912495SMarcel Holtmann 
6585c912495SMarcel Holtmann 	err = hci_dev_do_reset(hdev);
6595c912495SMarcel Holtmann 
6605c912495SMarcel Holtmann done:
6615c912495SMarcel Holtmann 	hci_dev_put(hdev);
6625c912495SMarcel Holtmann 	return err;
6635c912495SMarcel Holtmann }
6645c912495SMarcel Holtmann 
hci_dev_reset_stat(__u16 dev)6651da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
6661da177e4SLinus Torvalds {
6671da177e4SLinus Torvalds 	struct hci_dev *hdev;
6681da177e4SLinus Torvalds 	int ret = 0;
6691da177e4SLinus Torvalds 
67070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
67170f23020SAndrei Emeltchenko 	if (!hdev)
6721da177e4SLinus Torvalds 		return -ENODEV;
6731da177e4SLinus Torvalds 
674d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6750736cfa8SMarcel Holtmann 		ret = -EBUSY;
6760736cfa8SMarcel Holtmann 		goto done;
6770736cfa8SMarcel Holtmann 	}
6780736cfa8SMarcel Holtmann 
679d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
680fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
681fee746b0SMarcel Holtmann 		goto done;
682fee746b0SMarcel Holtmann 	}
683fee746b0SMarcel Holtmann 
6841da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
6851da177e4SLinus Torvalds 
6860736cfa8SMarcel Holtmann done:
6871da177e4SLinus Torvalds 	hci_dev_put(hdev);
6881da177e4SLinus Torvalds 	return ret;
6891da177e4SLinus Torvalds }
6901da177e4SLinus Torvalds 
hci_update_passive_scan_state(struct hci_dev * hdev,u8 scan)6915bee2fd6SLuiz Augusto von Dentz static void hci_update_passive_scan_state(struct hci_dev *hdev, u8 scan)
692123abc08SJohan Hedberg {
693bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
694123abc08SJohan Hedberg 
695123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
696123abc08SJohan Hedberg 
697123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
698238be788SMarcel Holtmann 		conn_changed = !hci_dev_test_and_set_flag(hdev,
699238be788SMarcel Holtmann 							  HCI_CONNECTABLE);
700123abc08SJohan Hedberg 	else
701a69d8927SMarcel Holtmann 		conn_changed = hci_dev_test_and_clear_flag(hdev,
702a69d8927SMarcel Holtmann 							   HCI_CONNECTABLE);
703123abc08SJohan Hedberg 
704bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
705238be788SMarcel Holtmann 		discov_changed = !hci_dev_test_and_set_flag(hdev,
706238be788SMarcel Holtmann 							    HCI_DISCOVERABLE);
707bc6d2d04SJohan Hedberg 	} else {
708a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
709a69d8927SMarcel Holtmann 		discov_changed = hci_dev_test_and_clear_flag(hdev,
710a69d8927SMarcel Holtmann 							     HCI_DISCOVERABLE);
711bc6d2d04SJohan Hedberg 	}
712bc6d2d04SJohan Hedberg 
713d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
714123abc08SJohan Hedberg 		return;
715123abc08SJohan Hedberg 
716bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
717bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
718a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
719bc6d2d04SJohan Hedberg 
720d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
721651cd3d6SBrian Gix 			hci_update_adv_data(hdev, hdev->cur_adv_instance);
722bc6d2d04SJohan Hedberg 
723123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
724123abc08SJohan Hedberg 	}
725bc6d2d04SJohan Hedberg }
726123abc08SJohan Hedberg 
hci_dev_cmd(unsigned int cmd,void __user * arg)7271da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
7281da177e4SLinus Torvalds {
7291da177e4SLinus Torvalds 	struct hci_dev *hdev;
7301da177e4SLinus Torvalds 	struct hci_dev_req dr;
7311da177e4SLinus Torvalds 	int err = 0;
7321da177e4SLinus Torvalds 
7331da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
7341da177e4SLinus Torvalds 		return -EFAULT;
7351da177e4SLinus Torvalds 
73670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
73770f23020SAndrei Emeltchenko 	if (!hdev)
7381da177e4SLinus Torvalds 		return -ENODEV;
7391da177e4SLinus Torvalds 
740d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
7410736cfa8SMarcel Holtmann 		err = -EBUSY;
7420736cfa8SMarcel Holtmann 		goto done;
7430736cfa8SMarcel Holtmann 	}
7440736cfa8SMarcel Holtmann 
745d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
746fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
747fee746b0SMarcel Holtmann 		goto done;
748fee746b0SMarcel Holtmann 	}
749fee746b0SMarcel Holtmann 
750d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
75156f87901SJohan Hedberg 		err = -EOPNOTSUPP;
75256f87901SJohan Hedberg 		goto done;
75356f87901SJohan Hedberg 	}
75456f87901SJohan Hedberg 
7551da177e4SLinus Torvalds 	switch (cmd) {
7561da177e4SLinus Torvalds 	case HCISETAUTH:
75701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
7584ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
7591da177e4SLinus Torvalds 		break;
7601da177e4SLinus Torvalds 
7611da177e4SLinus Torvalds 	case HCISETENCRYPT:
7621da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
7631da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
7641da177e4SLinus Torvalds 			break;
7651da177e4SLinus Torvalds 		}
7661da177e4SLinus Torvalds 
7671da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
7681da177e4SLinus Torvalds 			/* Auth must be enabled first */
76901178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
7704ebeee2dSJohan Hedberg 					   HCI_INIT_TIMEOUT, NULL);
7711da177e4SLinus Torvalds 			if (err)
7721da177e4SLinus Torvalds 				break;
7731da177e4SLinus Torvalds 		}
7741da177e4SLinus Torvalds 
77501178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
7764ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
7771da177e4SLinus Torvalds 		break;
7781da177e4SLinus Torvalds 
7791da177e4SLinus Torvalds 	case HCISETSCAN:
78001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
7814ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
78291a668b0SJohan Hedberg 
783bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
784bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
78591a668b0SJohan Hedberg 		 */
786123abc08SJohan Hedberg 		if (!err)
7875bee2fd6SLuiz Augusto von Dentz 			hci_update_passive_scan_state(hdev, dr.dev_opt);
7881da177e4SLinus Torvalds 		break;
7891da177e4SLinus Torvalds 
7901da177e4SLinus Torvalds 	case HCISETLINKPOL:
79101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
7924ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
7931da177e4SLinus Torvalds 		break;
7941da177e4SLinus Torvalds 
7951da177e4SLinus Torvalds 	case HCISETLINKMODE:
796e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
797e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
798e4e8e37cSMarcel Holtmann 		break;
799e4e8e37cSMarcel Holtmann 
800e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
801b7c23df8SJaganath Kanakkassery 		if (hdev->pkt_type == (__u16) dr.dev_opt)
802b7c23df8SJaganath Kanakkassery 			break;
803b7c23df8SJaganath Kanakkassery 
804e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
805b7c23df8SJaganath Kanakkassery 		mgmt_phy_configuration_changed(hdev, NULL);
8061da177e4SLinus Torvalds 		break;
8071da177e4SLinus Torvalds 
8081da177e4SLinus Torvalds 	case HCISETACLMTU:
8091da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
8101da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
8111da177e4SLinus Torvalds 		break;
8121da177e4SLinus Torvalds 
8131da177e4SLinus Torvalds 	case HCISETSCOMTU:
8141da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
8151da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
8161da177e4SLinus Torvalds 		break;
8171da177e4SLinus Torvalds 
8181da177e4SLinus Torvalds 	default:
8191da177e4SLinus Torvalds 		err = -EINVAL;
8201da177e4SLinus Torvalds 		break;
8211da177e4SLinus Torvalds 	}
822e4e8e37cSMarcel Holtmann 
8230736cfa8SMarcel Holtmann done:
8241da177e4SLinus Torvalds 	hci_dev_put(hdev);
8251da177e4SLinus Torvalds 	return err;
8261da177e4SLinus Torvalds }
8271da177e4SLinus Torvalds 
hci_get_dev_list(void __user * arg)8281da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
8291da177e4SLinus Torvalds {
8308035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
8311da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
8321da177e4SLinus Torvalds 	struct hci_dev_req *dr;
8331da177e4SLinus Torvalds 	int n = 0, size, err;
8341da177e4SLinus Torvalds 	__u16 dev_num;
8351da177e4SLinus Torvalds 
8361da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
8371da177e4SLinus Torvalds 		return -EFAULT;
8381da177e4SLinus Torvalds 
8391da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
8401da177e4SLinus Torvalds 		return -EINVAL;
8411da177e4SLinus Torvalds 
8421da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
8431da177e4SLinus Torvalds 
84470f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
84570f23020SAndrei Emeltchenko 	if (!dl)
8461da177e4SLinus Torvalds 		return -ENOMEM;
8471da177e4SLinus Torvalds 
8481da177e4SLinus Torvalds 	dr = dl->dev_req;
8491da177e4SLinus Torvalds 
850f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
8518035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
8522e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
853c542a06cSJohan Hedberg 
8542e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
8552e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
8562e84d8dbSMarcel Holtmann 		 * device is actually down.
8572e84d8dbSMarcel Holtmann 		 */
858d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
8592e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
860c542a06cSJohan Hedberg 
8611da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
8622e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
863c542a06cSJohan Hedberg 
8641da177e4SLinus Torvalds 		if (++n >= dev_num)
8651da177e4SLinus Torvalds 			break;
8661da177e4SLinus Torvalds 	}
867f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
8681da177e4SLinus Torvalds 
8691da177e4SLinus Torvalds 	dl->dev_num = n;
8701da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
8711da177e4SLinus Torvalds 
8721da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
8731da177e4SLinus Torvalds 	kfree(dl);
8741da177e4SLinus Torvalds 
8751da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
8761da177e4SLinus Torvalds }
8771da177e4SLinus Torvalds 
hci_get_dev_info(void __user * arg)8781da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
8791da177e4SLinus Torvalds {
8801da177e4SLinus Torvalds 	struct hci_dev *hdev;
8811da177e4SLinus Torvalds 	struct hci_dev_info di;
8822e84d8dbSMarcel Holtmann 	unsigned long flags;
8831da177e4SLinus Torvalds 	int err = 0;
8841da177e4SLinus Torvalds 
8851da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
8861da177e4SLinus Torvalds 		return -EFAULT;
8871da177e4SLinus Torvalds 
88870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
88970f23020SAndrei Emeltchenko 	if (!hdev)
8901da177e4SLinus Torvalds 		return -ENODEV;
8911da177e4SLinus Torvalds 
8922e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
8932e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
8942e84d8dbSMarcel Holtmann 	 * device is actually down.
8952e84d8dbSMarcel Holtmann 	 */
896d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
8972e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
8982e84d8dbSMarcel Holtmann 	else
8992e84d8dbSMarcel Holtmann 		flags = hdev->flags;
900c542a06cSJohan Hedberg 
901a41c8efeSLuiz Augusto von Dentz 	strscpy(di.name, hdev->name, sizeof(di.name));
9021da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
9035af2e235SLuiz Augusto von Dentz 	di.type     = (hdev->bus & 0x0f);
9042e84d8dbSMarcel Holtmann 	di.flags    = flags;
9051da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
906572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
9071da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
9081da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
9091da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
9101da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
911572c7f84SJohan Hedberg 	} else {
912572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
913572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
914572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
915572c7f84SJohan Hedberg 		di.sco_pkts = 0;
916572c7f84SJohan Hedberg 	}
9171da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
9181da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
9191da177e4SLinus Torvalds 
9201da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
9211da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
9221da177e4SLinus Torvalds 
9231da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
9241da177e4SLinus Torvalds 		err = -EFAULT;
9251da177e4SLinus Torvalds 
9261da177e4SLinus Torvalds 	hci_dev_put(hdev);
9271da177e4SLinus Torvalds 
9281da177e4SLinus Torvalds 	return err;
9291da177e4SLinus Torvalds }
9301da177e4SLinus Torvalds 
9311da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
9321da177e4SLinus Torvalds 
hci_rfkill_set_block(void * data,bool blocked)933611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
934611b30f7SMarcel Holtmann {
935611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
936611b30f7SMarcel Holtmann 
937611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
938611b30f7SMarcel Holtmann 
939d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
9400736cfa8SMarcel Holtmann 		return -EBUSY;
9410736cfa8SMarcel Holtmann 
9425e130367SJohan Hedberg 	if (blocked) {
943a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
944d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
945d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG))
946611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
9475e130367SJohan Hedberg 	} else {
948a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_RFKILLED);
9495e130367SJohan Hedberg 	}
950611b30f7SMarcel Holtmann 
951611b30f7SMarcel Holtmann 	return 0;
952611b30f7SMarcel Holtmann }
953611b30f7SMarcel Holtmann 
954611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
955611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
956611b30f7SMarcel Holtmann };
957611b30f7SMarcel Holtmann 
hci_power_on(struct work_struct * work)958ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
959ab81cbf9SJohan Hedberg {
960ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
96196570ffcSJohan Hedberg 	int err;
962ab81cbf9SJohan Hedberg 
963ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
964ab81cbf9SJohan Hedberg 
9652ff13894SJohan Hedberg 	if (test_bit(HCI_UP, &hdev->flags) &&
9662ff13894SJohan Hedberg 	    hci_dev_test_flag(hdev, HCI_MGMT) &&
9672ff13894SJohan Hedberg 	    hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
968d82142a8SWei-Ning Huang 		cancel_delayed_work(&hdev->power_off);
969cf75ad8bSLuiz Augusto von Dentz 		err = hci_powered_update_sync(hdev);
9702ff13894SJohan Hedberg 		mgmt_power_on(hdev, err);
9712ff13894SJohan Hedberg 		return;
9722ff13894SJohan Hedberg 	}
9732ff13894SJohan Hedberg 
974cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
97596570ffcSJohan Hedberg 	if (err < 0) {
9763ad67582SJaganath Kanakkassery 		hci_dev_lock(hdev);
97796570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
9783ad67582SJaganath Kanakkassery 		hci_dev_unlock(hdev);
979ab81cbf9SJohan Hedberg 		return;
98096570ffcSJohan Hedberg 	}
981ab81cbf9SJohan Hedberg 
982a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
983a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
984a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
985a5c8f270SMarcel Holtmann 	 */
986d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
987d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
9885af2e235SLuiz Augusto von Dentz 	    (!bacmp(&hdev->bdaddr, BDADDR_ANY) &&
989a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
990a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
991bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
992d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
99319202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
99419202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
995bf543036SJohan Hedberg 	}
996ab81cbf9SJohan Hedberg 
997a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
9984a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
9994a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
10004a964404SMarcel Holtmann 		 */
1001d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
10024a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
10030602a8adSMarcel Holtmann 
10040602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
10050602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
10060602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
10070602a8adSMarcel Holtmann 		 *
10080602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
10090602a8adSMarcel Holtmann 		 * and no event will be send.
10100602a8adSMarcel Holtmann 		 */
1011744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1012a69d8927SMarcel Holtmann 	} else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
10135ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
10145ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
10155ea234d3SMarcel Holtmann 		 */
1016d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
10175ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
10185ea234d3SMarcel Holtmann 
1019d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
1020d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
1021d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
1022d603b76bSMarcel Holtmann 		 */
1023d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
1024ab81cbf9SJohan Hedberg 	}
1025ab81cbf9SJohan Hedberg }
1026ab81cbf9SJohan Hedberg 
hci_power_off(struct work_struct * work)1027ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1028ab81cbf9SJohan Hedberg {
10293243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
10303243553fSJohan Hedberg 					    power_off.work);
1031ab81cbf9SJohan Hedberg 
1032ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1033ab81cbf9SJohan Hedberg 
10348ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1035ab81cbf9SJohan Hedberg }
1036ab81cbf9SJohan Hedberg 
hci_error_reset(struct work_struct * work)1037c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work)
1038c7741d16SMarcel Holtmann {
1039c7741d16SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
1040c7741d16SMarcel Holtmann 
10412ab9a19dSYing Hsu 	hci_dev_hold(hdev);
1042c7741d16SMarcel Holtmann 	BT_DBG("%s", hdev->name);
1043c7741d16SMarcel Holtmann 
1044c7741d16SMarcel Holtmann 	if (hdev->hw_error)
1045c7741d16SMarcel Holtmann 		hdev->hw_error(hdev, hdev->hw_error_code);
1046c7741d16SMarcel Holtmann 	else
10472064ee33SMarcel Holtmann 		bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code);
1048c7741d16SMarcel Holtmann 
10492ab9a19dSYing Hsu 	if (!hci_dev_do_close(hdev))
1050c7741d16SMarcel Holtmann 		hci_dev_do_open(hdev);
10512ab9a19dSYing Hsu 
10522ab9a19dSYing Hsu 	hci_dev_put(hdev);
1053c7741d16SMarcel Holtmann }
1054c7741d16SMarcel Holtmann 
hci_uuids_clear(struct hci_dev * hdev)105535f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
10562aeb9a1aSJohan Hedberg {
10574821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
10582aeb9a1aSJohan Hedberg 
10594821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
10604821002cSJohan Hedberg 		list_del(&uuid->list);
10612aeb9a1aSJohan Hedberg 		kfree(uuid);
10622aeb9a1aSJohan Hedberg 	}
10632aeb9a1aSJohan Hedberg }
10642aeb9a1aSJohan Hedberg 
hci_link_keys_clear(struct hci_dev * hdev)106535f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
106655ed8ca1SJohan Hedberg {
10673673952cSMin Li 	struct link_key *key, *tmp;
106855ed8ca1SJohan Hedberg 
10693673952cSMin Li 	list_for_each_entry_safe(key, tmp, &hdev->link_keys, list) {
10700378b597SJohan Hedberg 		list_del_rcu(&key->list);
10710378b597SJohan Hedberg 		kfree_rcu(key, rcu);
107255ed8ca1SJohan Hedberg 	}
107355ed8ca1SJohan Hedberg }
107455ed8ca1SJohan Hedberg 
hci_smp_ltks_clear(struct hci_dev * hdev)107535f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
1076b899efafSVinicius Costa Gomes {
10773673952cSMin Li 	struct smp_ltk *k, *tmp;
1078b899efafSVinicius Costa Gomes 
10793673952cSMin Li 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1080970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
1081970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
1082b899efafSVinicius Costa Gomes 	}
1083b899efafSVinicius Costa Gomes }
1084b899efafSVinicius Costa Gomes 
hci_smp_irks_clear(struct hci_dev * hdev)1085970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
1086970c4e46SJohan Hedberg {
10873673952cSMin Li 	struct smp_irk *k, *tmp;
1088970c4e46SJohan Hedberg 
10893673952cSMin Li 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
1090adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
1091adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
1092970c4e46SJohan Hedberg 	}
1093970c4e46SJohan Hedberg }
1094970c4e46SJohan Hedberg 
hci_blocked_keys_clear(struct hci_dev * hdev)1095600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev)
1096600a8749SAlain Michaud {
10973673952cSMin Li 	struct blocked_key *b, *tmp;
1098600a8749SAlain Michaud 
10993673952cSMin Li 	list_for_each_entry_safe(b, tmp, &hdev->blocked_keys, list) {
1100600a8749SAlain Michaud 		list_del_rcu(&b->list);
1101600a8749SAlain Michaud 		kfree_rcu(b, rcu);
1102600a8749SAlain Michaud 	}
1103600a8749SAlain Michaud }
1104600a8749SAlain Michaud 
hci_is_blocked_key(struct hci_dev * hdev,u8 type,u8 val[16])1105600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16])
1106600a8749SAlain Michaud {
1107600a8749SAlain Michaud 	bool blocked = false;
1108600a8749SAlain Michaud 	struct blocked_key *b;
1109600a8749SAlain Michaud 
1110600a8749SAlain Michaud 	rcu_read_lock();
11110c2ac7d4SMadhuparna Bhowmik 	list_for_each_entry_rcu(b, &hdev->blocked_keys, list) {
1112600a8749SAlain Michaud 		if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) {
1113600a8749SAlain Michaud 			blocked = true;
1114600a8749SAlain Michaud 			break;
1115600a8749SAlain Michaud 		}
1116600a8749SAlain Michaud 	}
1117600a8749SAlain Michaud 
1118600a8749SAlain Michaud 	rcu_read_unlock();
1119600a8749SAlain Michaud 	return blocked;
1120600a8749SAlain Michaud }
1121600a8749SAlain Michaud 
hci_find_link_key(struct hci_dev * hdev,bdaddr_t * bdaddr)112255ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
112355ed8ca1SJohan Hedberg {
112455ed8ca1SJohan Hedberg 	struct link_key *k;
112555ed8ca1SJohan Hedberg 
11260378b597SJohan Hedberg 	rcu_read_lock();
11270378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
11280378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
11290378b597SJohan Hedberg 			rcu_read_unlock();
1130600a8749SAlain Michaud 
1131600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev,
1132600a8749SAlain Michaud 					       HCI_BLOCKED_KEY_TYPE_LINKKEY,
1133600a8749SAlain Michaud 					       k->val)) {
1134600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
1135600a8749SAlain Michaud 							"Link key blocked for %pMR",
1136600a8749SAlain Michaud 							&k->bdaddr);
1137600a8749SAlain Michaud 				return NULL;
1138600a8749SAlain Michaud 			}
1139600a8749SAlain Michaud 
114055ed8ca1SJohan Hedberg 			return k;
11410378b597SJohan Hedberg 		}
11420378b597SJohan Hedberg 	}
11430378b597SJohan Hedberg 	rcu_read_unlock();
114455ed8ca1SJohan Hedberg 
114555ed8ca1SJohan Hedberg 	return NULL;
114655ed8ca1SJohan Hedberg }
114755ed8ca1SJohan Hedberg 
hci_persistent_key(struct hci_dev * hdev,struct hci_conn * conn,u8 key_type,u8 old_key_type)1148745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1149d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1150d25e28abSJohan Hedberg {
1151d25e28abSJohan Hedberg 	/* Legacy key */
1152d25e28abSJohan Hedberg 	if (key_type < 0x03)
1153745c0ce3SVishal Agarwal 		return true;
1154d25e28abSJohan Hedberg 
1155d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1156d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1157745c0ce3SVishal Agarwal 		return false;
1158d25e28abSJohan Hedberg 
1159d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1160d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1161745c0ce3SVishal Agarwal 		return false;
1162d25e28abSJohan Hedberg 
1163d25e28abSJohan Hedberg 	/* Security mode 3 case */
1164d25e28abSJohan Hedberg 	if (!conn)
1165745c0ce3SVishal Agarwal 		return true;
1166d25e28abSJohan Hedberg 
1167e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
1168e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
1169e3befab9SJohan Hedberg 		return true;
1170e3befab9SJohan Hedberg 
1171d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1172d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1173745c0ce3SVishal Agarwal 		return true;
1174d25e28abSJohan Hedberg 
1175d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1176d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1177745c0ce3SVishal Agarwal 		return true;
1178d25e28abSJohan Hedberg 
1179d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1180d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1181745c0ce3SVishal Agarwal 		return true;
1182d25e28abSJohan Hedberg 
1183d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1184d25e28abSJohan Hedberg 	 * persistently */
1185745c0ce3SVishal Agarwal 	return false;
1186d25e28abSJohan Hedberg }
1187d25e28abSJohan Hedberg 
ltk_role(u8 type)1188e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
118998a0b845SJohan Hedberg {
1190e804d25dSJohan Hedberg 	if (type == SMP_LTK)
1191e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
119298a0b845SJohan Hedberg 
1193e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
119498a0b845SJohan Hedberg }
119598a0b845SJohan Hedberg 
hci_find_ltk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type,u8 role)1196f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
1197e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
119875d262c2SVinicius Costa Gomes {
1199c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
120075d262c2SVinicius Costa Gomes 
1201970d0f1bSJohan Hedberg 	rcu_read_lock();
1202970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
12035378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
12045378bc56SJohan Hedberg 			continue;
12055378bc56SJohan Hedberg 
1206923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
1207970d0f1bSJohan Hedberg 			rcu_read_unlock();
1208600a8749SAlain Michaud 
1209600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK,
1210600a8749SAlain Michaud 					       k->val)) {
1211600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
1212600a8749SAlain Michaud 							"LTK blocked for %pMR",
1213600a8749SAlain Michaud 							&k->bdaddr);
1214600a8749SAlain Michaud 				return NULL;
1215600a8749SAlain Michaud 			}
1216600a8749SAlain Michaud 
121775d262c2SVinicius Costa Gomes 			return k;
1218970d0f1bSJohan Hedberg 		}
1219970d0f1bSJohan Hedberg 	}
1220970d0f1bSJohan Hedberg 	rcu_read_unlock();
122175d262c2SVinicius Costa Gomes 
122275d262c2SVinicius Costa Gomes 	return NULL;
122375d262c2SVinicius Costa Gomes }
122475d262c2SVinicius Costa Gomes 
hci_find_irk_by_rpa(struct hci_dev * hdev,bdaddr_t * rpa)1225970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
1226970c4e46SJohan Hedberg {
1227600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
1228970c4e46SJohan Hedberg 	struct smp_irk *irk;
1229970c4e46SJohan Hedberg 
1230adae20cbSJohan Hedberg 	rcu_read_lock();
1231adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1232adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
1233600a8749SAlain Michaud 			irk_to_return = irk;
1234600a8749SAlain Michaud 			goto done;
1235970c4e46SJohan Hedberg 		}
1236adae20cbSJohan Hedberg 	}
1237970c4e46SJohan Hedberg 
1238adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1239defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
1240970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
1241600a8749SAlain Michaud 			irk_to_return = irk;
1242600a8749SAlain Michaud 			goto done;
1243970c4e46SJohan Hedberg 		}
1244970c4e46SJohan Hedberg 	}
1245600a8749SAlain Michaud 
1246600a8749SAlain Michaud done:
1247600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
1248600a8749SAlain Michaud 						irk_to_return->val)) {
1249600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
1250600a8749SAlain Michaud 					&irk_to_return->bdaddr);
1251600a8749SAlain Michaud 		irk_to_return = NULL;
1252600a8749SAlain Michaud 	}
1253600a8749SAlain Michaud 
1254adae20cbSJohan Hedberg 	rcu_read_unlock();
1255970c4e46SJohan Hedberg 
1256600a8749SAlain Michaud 	return irk_to_return;
1257970c4e46SJohan Hedberg }
1258970c4e46SJohan Hedberg 
hci_find_irk_by_addr(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type)1259970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1260970c4e46SJohan Hedberg 				     u8 addr_type)
1261970c4e46SJohan Hedberg {
1262600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
1263970c4e46SJohan Hedberg 	struct smp_irk *irk;
1264970c4e46SJohan Hedberg 
12656cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
12666cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
12676cfc9988SJohan Hedberg 		return NULL;
12686cfc9988SJohan Hedberg 
1269adae20cbSJohan Hedberg 	rcu_read_lock();
1270adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1271970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
1272adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
1273600a8749SAlain Michaud 			irk_to_return = irk;
1274600a8749SAlain Michaud 			goto done;
1275970c4e46SJohan Hedberg 		}
1276adae20cbSJohan Hedberg 	}
1277600a8749SAlain Michaud 
1278600a8749SAlain Michaud done:
1279600a8749SAlain Michaud 
1280600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
1281600a8749SAlain Michaud 						irk_to_return->val)) {
1282600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
1283600a8749SAlain Michaud 					&irk_to_return->bdaddr);
1284600a8749SAlain Michaud 		irk_to_return = NULL;
1285600a8749SAlain Michaud 	}
1286600a8749SAlain Michaud 
1287adae20cbSJohan Hedberg 	rcu_read_unlock();
1288970c4e46SJohan Hedberg 
1289600a8749SAlain Michaud 	return irk_to_return;
1290970c4e46SJohan Hedberg }
1291970c4e46SJohan Hedberg 
hci_add_link_key(struct hci_dev * hdev,struct hci_conn * conn,bdaddr_t * bdaddr,u8 * val,u8 type,u8 pin_len,bool * persistent)1292567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
12937652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
12947652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
129555ed8ca1SJohan Hedberg {
129655ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1297745c0ce3SVishal Agarwal 	u8 old_key_type;
129855ed8ca1SJohan Hedberg 
129955ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
130055ed8ca1SJohan Hedberg 	if (old_key) {
130155ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
130255ed8ca1SJohan Hedberg 		key = old_key;
130355ed8ca1SJohan Hedberg 	} else {
130412adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
13050a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
130655ed8ca1SJohan Hedberg 		if (!key)
1307567fa2aaSJohan Hedberg 			return NULL;
13080378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
130955ed8ca1SJohan Hedberg 	}
131055ed8ca1SJohan Hedberg 
13116ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
131255ed8ca1SJohan Hedberg 
1313d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1314d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1315d25e28abSJohan Hedberg 	 * previous key */
1316d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1317a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1318d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1319655fe6ecSJohan Hedberg 		if (conn)
1320655fe6ecSJohan Hedberg 			conn->key_type = type;
1321655fe6ecSJohan Hedberg 	}
1322d25e28abSJohan Hedberg 
132355ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
13249b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
132555ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
132655ed8ca1SJohan Hedberg 
1327b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
132855ed8ca1SJohan Hedberg 		key->type = old_key_type;
13294748fed2SJohan Hedberg 	else
13304748fed2SJohan Hedberg 		key->type = type;
13314748fed2SJohan Hedberg 
13327652ff6aSJohan Hedberg 	if (persistent)
13337652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
13347652ff6aSJohan Hedberg 						 old_key_type);
13354df378a1SJohan Hedberg 
1336567fa2aaSJohan Hedberg 	return key;
133755ed8ca1SJohan Hedberg }
133855ed8ca1SJohan Hedberg 
hci_add_ltk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type,u8 type,u8 authenticated,u8 tk[16],u8 enc_size,__le16 ediv,__le64 rand)1339ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
134035d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
1341fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
134275d262c2SVinicius Costa Gomes {
1343c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
1344e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
134575d262c2SVinicius Costa Gomes 
1346f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
1347c9839a11SVinicius Costa Gomes 	if (old_key)
134875d262c2SVinicius Costa Gomes 		key = old_key;
1349c9839a11SVinicius Costa Gomes 	else {
13500a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
135175d262c2SVinicius Costa Gomes 		if (!key)
1352ca9142b8SJohan Hedberg 			return NULL;
1353970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
135475d262c2SVinicius Costa Gomes 	}
135575d262c2SVinicius Costa Gomes 
135675d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1357c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1358c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1359c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1360c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1361fe39c7b2SMarcel Holtmann 	key->rand = rand;
1362c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1363c9839a11SVinicius Costa Gomes 	key->type = type;
136475d262c2SVinicius Costa Gomes 
1365ca9142b8SJohan Hedberg 	return key;
136675d262c2SVinicius Costa Gomes }
136775d262c2SVinicius Costa Gomes 
hci_add_irk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type,u8 val[16],bdaddr_t * rpa)1368ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
1369ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
1370970c4e46SJohan Hedberg {
1371970c4e46SJohan Hedberg 	struct smp_irk *irk;
1372970c4e46SJohan Hedberg 
1373970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
1374970c4e46SJohan Hedberg 	if (!irk) {
1375970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
1376970c4e46SJohan Hedberg 		if (!irk)
1377ca9142b8SJohan Hedberg 			return NULL;
1378970c4e46SJohan Hedberg 
1379970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
1380970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
1381970c4e46SJohan Hedberg 
1382adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
1383970c4e46SJohan Hedberg 	}
1384970c4e46SJohan Hedberg 
1385970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
1386970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
1387970c4e46SJohan Hedberg 
1388ca9142b8SJohan Hedberg 	return irk;
1389970c4e46SJohan Hedberg }
1390970c4e46SJohan Hedberg 
hci_remove_link_key(struct hci_dev * hdev,bdaddr_t * bdaddr)139155ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
139255ed8ca1SJohan Hedberg {
139355ed8ca1SJohan Hedberg 	struct link_key *key;
139455ed8ca1SJohan Hedberg 
139555ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
139655ed8ca1SJohan Hedberg 	if (!key)
139755ed8ca1SJohan Hedberg 		return -ENOENT;
139855ed8ca1SJohan Hedberg 
13996ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
140055ed8ca1SJohan Hedberg 
14010378b597SJohan Hedberg 	list_del_rcu(&key->list);
14020378b597SJohan Hedberg 	kfree_rcu(key, rcu);
140355ed8ca1SJohan Hedberg 
140455ed8ca1SJohan Hedberg 	return 0;
140555ed8ca1SJohan Hedberg }
140655ed8ca1SJohan Hedberg 
hci_remove_ltk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 bdaddr_type)1407e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
1408b899efafSVinicius Costa Gomes {
1409c5d2b6faSLuiz Augusto von Dentz 	struct smp_ltk *k, *tmp;
1410c51ffa0bSJohan Hedberg 	int removed = 0;
1411b899efafSVinicius Costa Gomes 
1412c5d2b6faSLuiz Augusto von Dentz 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1413e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
1414b899efafSVinicius Costa Gomes 			continue;
1415b899efafSVinicius Costa Gomes 
14166ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1417b899efafSVinicius Costa Gomes 
1418970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
1419970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
1420c51ffa0bSJohan Hedberg 		removed++;
1421b899efafSVinicius Costa Gomes 	}
1422b899efafSVinicius Costa Gomes 
1423c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
1424b899efafSVinicius Costa Gomes }
1425b899efafSVinicius Costa Gomes 
hci_remove_irk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type)1426a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
1427a7ec7338SJohan Hedberg {
1428c5d2b6faSLuiz Augusto von Dentz 	struct smp_irk *k, *tmp;
1429a7ec7338SJohan Hedberg 
1430c5d2b6faSLuiz Augusto von Dentz 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
1431a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
1432a7ec7338SJohan Hedberg 			continue;
1433a7ec7338SJohan Hedberg 
1434a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1435a7ec7338SJohan Hedberg 
1436adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
1437adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
1438a7ec7338SJohan Hedberg 	}
1439a7ec7338SJohan Hedberg }
1440a7ec7338SJohan Hedberg 
hci_bdaddr_is_paired(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 type)144155e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
144255e76b38SJohan Hedberg {
144355e76b38SJohan Hedberg 	struct smp_ltk *k;
14444ba9faf3SJohan Hedberg 	struct smp_irk *irk;
144555e76b38SJohan Hedberg 	u8 addr_type;
144655e76b38SJohan Hedberg 
144755e76b38SJohan Hedberg 	if (type == BDADDR_BREDR) {
144855e76b38SJohan Hedberg 		if (hci_find_link_key(hdev, bdaddr))
144955e76b38SJohan Hedberg 			return true;
145055e76b38SJohan Hedberg 		return false;
145155e76b38SJohan Hedberg 	}
145255e76b38SJohan Hedberg 
145355e76b38SJohan Hedberg 	/* Convert to HCI addr type which struct smp_ltk uses */
145455e76b38SJohan Hedberg 	if (type == BDADDR_LE_PUBLIC)
145555e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_PUBLIC;
145655e76b38SJohan Hedberg 	else
145755e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_RANDOM;
145855e76b38SJohan Hedberg 
14594ba9faf3SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, addr_type);
14604ba9faf3SJohan Hedberg 	if (irk) {
14614ba9faf3SJohan Hedberg 		bdaddr = &irk->bdaddr;
14624ba9faf3SJohan Hedberg 		addr_type = irk->addr_type;
14634ba9faf3SJohan Hedberg 	}
14644ba9faf3SJohan Hedberg 
146555e76b38SJohan Hedberg 	rcu_read_lock();
146655e76b38SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
146787c8b28dSJohan Hedberg 		if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) {
146887c8b28dSJohan Hedberg 			rcu_read_unlock();
146955e76b38SJohan Hedberg 			return true;
147055e76b38SJohan Hedberg 		}
147187c8b28dSJohan Hedberg 	}
147255e76b38SJohan Hedberg 	rcu_read_unlock();
147355e76b38SJohan Hedberg 
147455e76b38SJohan Hedberg 	return false;
147555e76b38SJohan Hedberg }
147655e76b38SJohan Hedberg 
14776bd32326SVille Tervo /* HCI command timer function */
hci_cmd_timeout(struct work_struct * work)147865cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
14796bd32326SVille Tervo {
148065cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
148165cc2b49SMarcel Holtmann 					    cmd_timer.work);
14826bd32326SVille Tervo 
14832af7aa66SLuiz Augusto von Dentz 	if (hdev->req_skb) {
14842af7aa66SLuiz Augusto von Dentz 		u16 opcode = hci_skb_opcode(hdev->req_skb);
1485bda4f23aSAndrei Emeltchenko 
14862064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode);
14870ce1229cSLuiz Augusto von Dentz 
14880ce1229cSLuiz Augusto von Dentz 		hci_cmd_sync_cancel_sync(hdev, ETIMEDOUT);
1489bda4f23aSAndrei Emeltchenko 	} else {
14902064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command tx timeout");
1491bda4f23aSAndrei Emeltchenko 	}
1492bda4f23aSAndrei Emeltchenko 
1493e2bef384SRajat Jain 	if (hdev->cmd_timeout)
1494e2bef384SRajat Jain 		hdev->cmd_timeout(hdev);
1495e2bef384SRajat Jain 
14966bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1497c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
14986bd32326SVille Tervo }
14996bd32326SVille Tervo 
1500de75cd0dSManish Mandlik /* HCI ncmd timer function */
hci_ncmd_timeout(struct work_struct * work)1501de75cd0dSManish Mandlik static void hci_ncmd_timeout(struct work_struct *work)
1502de75cd0dSManish Mandlik {
1503de75cd0dSManish Mandlik 	struct hci_dev *hdev = container_of(work, struct hci_dev,
1504de75cd0dSManish Mandlik 					    ncmd_timer.work);
1505de75cd0dSManish Mandlik 
1506de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Controller not accepting commands anymore: ncmd = 0");
1507de75cd0dSManish Mandlik 
1508de75cd0dSManish Mandlik 	/* During HCI_INIT phase no events can be injected if the ncmd timer
1509de75cd0dSManish Mandlik 	 * triggers since the procedure has its own timeout handling.
1510de75cd0dSManish Mandlik 	 */
1511de75cd0dSManish Mandlik 	if (test_bit(HCI_INIT, &hdev->flags))
1512de75cd0dSManish Mandlik 		return;
1513de75cd0dSManish Mandlik 
1514de75cd0dSManish Mandlik 	/* This is an irrecoverable state, inject hardware error event */
1515de75cd0dSManish Mandlik 	hci_reset_dev(hdev);
1516de75cd0dSManish Mandlik }
1517de75cd0dSManish Mandlik 
hci_find_remote_oob_data(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 bdaddr_type)15182763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
15196928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
15202763eda6SSzymon Janc {
15212763eda6SSzymon Janc 	struct oob_data *data;
15222763eda6SSzymon Janc 
15236928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
15246928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
15256928a924SJohan Hedberg 			continue;
15266928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
15276928a924SJohan Hedberg 			continue;
15282763eda6SSzymon Janc 		return data;
15296928a924SJohan Hedberg 	}
15302763eda6SSzymon Janc 
15312763eda6SSzymon Janc 	return NULL;
15322763eda6SSzymon Janc }
15332763eda6SSzymon Janc 
hci_remove_remote_oob_data(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 bdaddr_type)15346928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
15356928a924SJohan Hedberg 			       u8 bdaddr_type)
15362763eda6SSzymon Janc {
15372763eda6SSzymon Janc 	struct oob_data *data;
15382763eda6SSzymon Janc 
15396928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
15402763eda6SSzymon Janc 	if (!data)
15412763eda6SSzymon Janc 		return -ENOENT;
15422763eda6SSzymon Janc 
15436928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
15442763eda6SSzymon Janc 
15452763eda6SSzymon Janc 	list_del(&data->list);
15462763eda6SSzymon Janc 	kfree(data);
15472763eda6SSzymon Janc 
15482763eda6SSzymon Janc 	return 0;
15492763eda6SSzymon Janc }
15502763eda6SSzymon Janc 
hci_remote_oob_data_clear(struct hci_dev * hdev)155135f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
15522763eda6SSzymon Janc {
15532763eda6SSzymon Janc 	struct oob_data *data, *n;
15542763eda6SSzymon Janc 
15552763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
15562763eda6SSzymon Janc 		list_del(&data->list);
15572763eda6SSzymon Janc 		kfree(data);
15582763eda6SSzymon Janc 	}
15592763eda6SSzymon Janc }
15602763eda6SSzymon Janc 
hci_add_remote_oob_data(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 bdaddr_type,u8 * hash192,u8 * rand192,u8 * hash256,u8 * rand256)15610798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
15626928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
156338da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
15640798872eSMarcel Holtmann {
15650798872eSMarcel Holtmann 	struct oob_data *data;
15660798872eSMarcel Holtmann 
15676928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
15680798872eSMarcel Holtmann 	if (!data) {
15690a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
15700798872eSMarcel Holtmann 		if (!data)
15710798872eSMarcel Holtmann 			return -ENOMEM;
15720798872eSMarcel Holtmann 
15730798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
15746928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
15750798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
15760798872eSMarcel Holtmann 	}
15770798872eSMarcel Holtmann 
157881328d5cSJohan Hedberg 	if (hash192 && rand192) {
15790798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
158038da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
1581f7697b16SMarcel Holtmann 		if (hash256 && rand256)
1582f7697b16SMarcel Holtmann 			data->present = 0x03;
158381328d5cSJohan Hedberg 	} else {
158481328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
158581328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
1586f7697b16SMarcel Holtmann 		if (hash256 && rand256)
1587f7697b16SMarcel Holtmann 			data->present = 0x02;
1588f7697b16SMarcel Holtmann 		else
1589f7697b16SMarcel Holtmann 			data->present = 0x00;
159081328d5cSJohan Hedberg 	}
15910798872eSMarcel Holtmann 
159281328d5cSJohan Hedberg 	if (hash256 && rand256) {
15930798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
159438da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
159581328d5cSJohan Hedberg 	} else {
159681328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
159781328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
1598f7697b16SMarcel Holtmann 		if (hash192 && rand192)
1599f7697b16SMarcel Holtmann 			data->present = 0x01;
160081328d5cSJohan Hedberg 	}
16010798872eSMarcel Holtmann 
16026ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
16032763eda6SSzymon Janc 
16042763eda6SSzymon Janc 	return 0;
16052763eda6SSzymon Janc }
16062763eda6SSzymon Janc 
1607d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
hci_find_adv_instance(struct hci_dev * hdev,u8 instance)1608d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance)
1609d2609b34SFlorian Grandel {
1610d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
1611d2609b34SFlorian Grandel 
1612d2609b34SFlorian Grandel 	list_for_each_entry(adv_instance, &hdev->adv_instances, list) {
1613d2609b34SFlorian Grandel 		if (adv_instance->instance == instance)
1614d2609b34SFlorian Grandel 			return adv_instance;
1615d2609b34SFlorian Grandel 	}
1616d2609b34SFlorian Grandel 
1617d2609b34SFlorian Grandel 	return NULL;
1618d2609b34SFlorian Grandel }
1619d2609b34SFlorian Grandel 
1620d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
hci_get_next_instance(struct hci_dev * hdev,u8 instance)162174b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance)
162274b93e9fSPrasanna Karthik {
1623d2609b34SFlorian Grandel 	struct adv_info *cur_instance;
1624d2609b34SFlorian Grandel 
1625d2609b34SFlorian Grandel 	cur_instance = hci_find_adv_instance(hdev, instance);
1626d2609b34SFlorian Grandel 	if (!cur_instance)
1627d2609b34SFlorian Grandel 		return NULL;
1628d2609b34SFlorian Grandel 
1629d2609b34SFlorian Grandel 	if (cur_instance == list_last_entry(&hdev->adv_instances,
1630d2609b34SFlorian Grandel 					    struct adv_info, list))
1631d2609b34SFlorian Grandel 		return list_first_entry(&hdev->adv_instances,
1632d2609b34SFlorian Grandel 						 struct adv_info, list);
1633d2609b34SFlorian Grandel 	else
1634d2609b34SFlorian Grandel 		return list_next_entry(cur_instance, list);
1635d2609b34SFlorian Grandel }
1636d2609b34SFlorian Grandel 
1637d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
hci_remove_adv_instance(struct hci_dev * hdev,u8 instance)1638d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance)
1639d2609b34SFlorian Grandel {
1640d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
1641d2609b34SFlorian Grandel 
1642d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
1643d2609b34SFlorian Grandel 	if (!adv_instance)
1644d2609b34SFlorian Grandel 		return -ENOENT;
1645d2609b34SFlorian Grandel 
1646d2609b34SFlorian Grandel 	BT_DBG("%s removing %dMR", hdev->name, instance);
1647d2609b34SFlorian Grandel 
1648cab054abSJohan Hedberg 	if (hdev->cur_adv_instance == instance) {
1649cab054abSJohan Hedberg 		if (hdev->adv_instance_timeout) {
16505d900e46SFlorian Grandel 			cancel_delayed_work(&hdev->adv_instance_expire);
16515d900e46SFlorian Grandel 			hdev->adv_instance_timeout = 0;
16525d900e46SFlorian Grandel 		}
1653cab054abSJohan Hedberg 		hdev->cur_adv_instance = 0x00;
1654cab054abSJohan Hedberg 	}
16555d900e46SFlorian Grandel 
1656a73c046aSJaganath Kanakkassery 	cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1657a73c046aSJaganath Kanakkassery 
1658d2609b34SFlorian Grandel 	list_del(&adv_instance->list);
1659d2609b34SFlorian Grandel 	kfree(adv_instance);
1660d2609b34SFlorian Grandel 
1661d2609b34SFlorian Grandel 	hdev->adv_instance_cnt--;
1662d2609b34SFlorian Grandel 
1663d2609b34SFlorian Grandel 	return 0;
1664d2609b34SFlorian Grandel }
1665d2609b34SFlorian Grandel 
hci_adv_instances_set_rpa_expired(struct hci_dev * hdev,bool rpa_expired)1666a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired)
1667a73c046aSJaganath Kanakkassery {
1668a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance, *n;
1669a73c046aSJaganath Kanakkassery 
1670a73c046aSJaganath Kanakkassery 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list)
1671a73c046aSJaganath Kanakkassery 		adv_instance->rpa_expired = rpa_expired;
1672a73c046aSJaganath Kanakkassery }
1673a73c046aSJaganath Kanakkassery 
1674d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
hci_adv_instances_clear(struct hci_dev * hdev)1675d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev)
1676d2609b34SFlorian Grandel {
1677d2609b34SFlorian Grandel 	struct adv_info *adv_instance, *n;
1678d2609b34SFlorian Grandel 
16795d900e46SFlorian Grandel 	if (hdev->adv_instance_timeout) {
16805d900e46SFlorian Grandel 		cancel_delayed_work(&hdev->adv_instance_expire);
16815d900e46SFlorian Grandel 		hdev->adv_instance_timeout = 0;
16825d900e46SFlorian Grandel 	}
16835d900e46SFlorian Grandel 
1684d2609b34SFlorian Grandel 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
1685a73c046aSJaganath Kanakkassery 		cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1686d2609b34SFlorian Grandel 		list_del(&adv_instance->list);
1687d2609b34SFlorian Grandel 		kfree(adv_instance);
1688d2609b34SFlorian Grandel 	}
1689d2609b34SFlorian Grandel 
1690d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
1691cab054abSJohan Hedberg 	hdev->cur_adv_instance = 0x00;
1692d2609b34SFlorian Grandel }
1693d2609b34SFlorian Grandel 
adv_instance_rpa_expired(struct work_struct * work)1694a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work)
1695a73c046aSJaganath Kanakkassery {
1696a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance = container_of(work, struct adv_info,
1697a73c046aSJaganath Kanakkassery 						     rpa_expired_cb.work);
1698a73c046aSJaganath Kanakkassery 
1699a73c046aSJaganath Kanakkassery 	BT_DBG("");
1700a73c046aSJaganath Kanakkassery 
1701a73c046aSJaganath Kanakkassery 	adv_instance->rpa_expired = true;
1702a73c046aSJaganath Kanakkassery }
1703a73c046aSJaganath Kanakkassery 
1704d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
hci_add_adv_instance(struct hci_dev * hdev,u8 instance,u32 flags,u16 adv_data_len,u8 * adv_data,u16 scan_rsp_len,u8 * scan_rsp_data,u16 timeout,u16 duration,s8 tx_power,u32 min_interval,u32 max_interval,u8 mesh_handle)1705eca0ae4aSLuiz Augusto von Dentz struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
1706eca0ae4aSLuiz Augusto von Dentz 				      u32 flags, u16 adv_data_len, u8 *adv_data,
1707d2609b34SFlorian Grandel 				      u16 scan_rsp_len, u8 *scan_rsp_data,
17089bf9f4b6SDaniel Winkler 				      u16 timeout, u16 duration, s8 tx_power,
1709b338d917SBrian Gix 				      u32 min_interval, u32 max_interval,
1710b338d917SBrian Gix 				      u8 mesh_handle)
1711d2609b34SFlorian Grandel {
1712eca0ae4aSLuiz Augusto von Dentz 	struct adv_info *adv;
1713d2609b34SFlorian Grandel 
1714eca0ae4aSLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
1715eca0ae4aSLuiz Augusto von Dentz 	if (adv) {
1716eca0ae4aSLuiz Augusto von Dentz 		memset(adv->adv_data, 0, sizeof(adv->adv_data));
1717eca0ae4aSLuiz Augusto von Dentz 		memset(adv->scan_rsp_data, 0, sizeof(adv->scan_rsp_data));
1718eca0ae4aSLuiz Augusto von Dentz 		memset(adv->per_adv_data, 0, sizeof(adv->per_adv_data));
1719d2609b34SFlorian Grandel 	} else {
17201d0fac2cSLuiz Augusto von Dentz 		if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets ||
1721b338d917SBrian Gix 		    instance < 1 || instance > hdev->le_num_of_adv_sets + 1)
1722eca0ae4aSLuiz Augusto von Dentz 			return ERR_PTR(-EOVERFLOW);
1723d2609b34SFlorian Grandel 
1724eca0ae4aSLuiz Augusto von Dentz 		adv = kzalloc(sizeof(*adv), GFP_KERNEL);
1725eca0ae4aSLuiz Augusto von Dentz 		if (!adv)
1726eca0ae4aSLuiz Augusto von Dentz 			return ERR_PTR(-ENOMEM);
1727d2609b34SFlorian Grandel 
1728eca0ae4aSLuiz Augusto von Dentz 		adv->pending = true;
1729eca0ae4aSLuiz Augusto von Dentz 		adv->instance = instance;
1730eca0ae4aSLuiz Augusto von Dentz 		list_add(&adv->list, &hdev->adv_instances);
1731d2609b34SFlorian Grandel 		hdev->adv_instance_cnt++;
1732d2609b34SFlorian Grandel 	}
1733d2609b34SFlorian Grandel 
1734eca0ae4aSLuiz Augusto von Dentz 	adv->flags = flags;
1735eca0ae4aSLuiz Augusto von Dentz 	adv->min_interval = min_interval;
1736eca0ae4aSLuiz Augusto von Dentz 	adv->max_interval = max_interval;
1737eca0ae4aSLuiz Augusto von Dentz 	adv->tx_power = tx_power;
1738b338d917SBrian Gix 	/* Defining a mesh_handle changes the timing units to ms,
1739b338d917SBrian Gix 	 * rather than seconds, and ties the instance to the requested
1740b338d917SBrian Gix 	 * mesh_tx queue.
1741b338d917SBrian Gix 	 */
1742b338d917SBrian Gix 	adv->mesh = mesh_handle;
1743d2609b34SFlorian Grandel 
174434a718bcSLuiz Augusto von Dentz 	hci_set_adv_instance_data(hdev, instance, adv_data_len, adv_data,
174534a718bcSLuiz Augusto von Dentz 				  scan_rsp_len, scan_rsp_data);
1746d2609b34SFlorian Grandel 
1747eca0ae4aSLuiz Augusto von Dentz 	adv->timeout = timeout;
1748eca0ae4aSLuiz Augusto von Dentz 	adv->remaining_time = timeout;
1749d2609b34SFlorian Grandel 
1750d2609b34SFlorian Grandel 	if (duration == 0)
1751eca0ae4aSLuiz Augusto von Dentz 		adv->duration = hdev->def_multi_adv_rotation_duration;
1752d2609b34SFlorian Grandel 	else
1753eca0ae4aSLuiz Augusto von Dentz 		adv->duration = duration;
1754d2609b34SFlorian Grandel 
1755eca0ae4aSLuiz Augusto von Dentz 	INIT_DELAYED_WORK(&adv->rpa_expired_cb, adv_instance_rpa_expired);
1756a73c046aSJaganath Kanakkassery 
1757d2609b34SFlorian Grandel 	BT_DBG("%s for %dMR", hdev->name, instance);
1758d2609b34SFlorian Grandel 
1759eca0ae4aSLuiz Augusto von Dentz 	return adv;
1760eca0ae4aSLuiz Augusto von Dentz }
1761eca0ae4aSLuiz Augusto von Dentz 
1762eca0ae4aSLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */
hci_add_per_instance(struct hci_dev * hdev,u8 instance,u32 flags,u8 data_len,u8 * data,u32 min_interval,u32 max_interval)1763eca0ae4aSLuiz Augusto von Dentz struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance,
1764eca0ae4aSLuiz Augusto von Dentz 				      u32 flags, u8 data_len, u8 *data,
1765eca0ae4aSLuiz Augusto von Dentz 				      u32 min_interval, u32 max_interval)
1766eca0ae4aSLuiz Augusto von Dentz {
1767eca0ae4aSLuiz Augusto von Dentz 	struct adv_info *adv;
1768eca0ae4aSLuiz Augusto von Dentz 
1769eca0ae4aSLuiz Augusto von Dentz 	adv = hci_add_adv_instance(hdev, instance, flags, 0, NULL, 0, NULL,
1770eca0ae4aSLuiz Augusto von Dentz 				   0, 0, HCI_ADV_TX_POWER_NO_PREFERENCE,
1771b338d917SBrian Gix 				   min_interval, max_interval, 0);
1772eca0ae4aSLuiz Augusto von Dentz 	if (IS_ERR(adv))
1773eca0ae4aSLuiz Augusto von Dentz 		return adv;
1774eca0ae4aSLuiz Augusto von Dentz 
1775eca0ae4aSLuiz Augusto von Dentz 	adv->periodic = true;
1776eca0ae4aSLuiz Augusto von Dentz 	adv->per_adv_data_len = data_len;
1777eca0ae4aSLuiz Augusto von Dentz 
1778eca0ae4aSLuiz Augusto von Dentz 	if (data)
1779eca0ae4aSLuiz Augusto von Dentz 		memcpy(adv->per_adv_data, data, data_len);
1780eca0ae4aSLuiz Augusto von Dentz 
1781eca0ae4aSLuiz Augusto von Dentz 	return adv;
1782d2609b34SFlorian Grandel }
1783d2609b34SFlorian Grandel 
1784e5e1e7fdSMiao-chen Chou /* This function requires the caller holds hdev->lock */
hci_set_adv_instance_data(struct hci_dev * hdev,u8 instance,u16 adv_data_len,u8 * adv_data,u16 scan_rsp_len,u8 * scan_rsp_data)178531aab5c2SDaniel Winkler int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance,
178631aab5c2SDaniel Winkler 			      u16 adv_data_len, u8 *adv_data,
178731aab5c2SDaniel Winkler 			      u16 scan_rsp_len, u8 *scan_rsp_data)
178831aab5c2SDaniel Winkler {
178934a718bcSLuiz Augusto von Dentz 	struct adv_info *adv;
179031aab5c2SDaniel Winkler 
179134a718bcSLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
179231aab5c2SDaniel Winkler 
179331aab5c2SDaniel Winkler 	/* If advertisement doesn't exist, we can't modify its data */
179434a718bcSLuiz Augusto von Dentz 	if (!adv)
179531aab5c2SDaniel Winkler 		return -ENOENT;
179631aab5c2SDaniel Winkler 
179734a718bcSLuiz Augusto von Dentz 	if (adv_data_len && ADV_DATA_CMP(adv, adv_data, adv_data_len)) {
179834a718bcSLuiz Augusto von Dentz 		memset(adv->adv_data, 0, sizeof(adv->adv_data));
179934a718bcSLuiz Augusto von Dentz 		memcpy(adv->adv_data, adv_data, adv_data_len);
180034a718bcSLuiz Augusto von Dentz 		adv->adv_data_len = adv_data_len;
180134a718bcSLuiz Augusto von Dentz 		adv->adv_data_changed = true;
180231aab5c2SDaniel Winkler 	}
180331aab5c2SDaniel Winkler 
180434a718bcSLuiz Augusto von Dentz 	if (scan_rsp_len && SCAN_RSP_CMP(adv, scan_rsp_data, scan_rsp_len)) {
180534a718bcSLuiz Augusto von Dentz 		memset(adv->scan_rsp_data, 0, sizeof(adv->scan_rsp_data));
180634a718bcSLuiz Augusto von Dentz 		memcpy(adv->scan_rsp_data, scan_rsp_data, scan_rsp_len);
180734a718bcSLuiz Augusto von Dentz 		adv->scan_rsp_len = scan_rsp_len;
180834a718bcSLuiz Augusto von Dentz 		adv->scan_rsp_changed = true;
180931aab5c2SDaniel Winkler 	}
181031aab5c2SDaniel Winkler 
181134a718bcSLuiz Augusto von Dentz 	/* Mark as changed if there are flags which would affect it */
181234a718bcSLuiz Augusto von Dentz 	if (((adv->flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance) ||
181334a718bcSLuiz Augusto von Dentz 	    adv->flags & MGMT_ADV_FLAG_LOCAL_NAME)
181434a718bcSLuiz Augusto von Dentz 		adv->scan_rsp_changed = true;
181534a718bcSLuiz Augusto von Dentz 
181631aab5c2SDaniel Winkler 	return 0;
181731aab5c2SDaniel Winkler }
181831aab5c2SDaniel Winkler 
181931aab5c2SDaniel Winkler /* This function requires the caller holds hdev->lock */
hci_adv_instance_flags(struct hci_dev * hdev,u8 instance)182001ce70b0SLuiz Augusto von Dentz u32 hci_adv_instance_flags(struct hci_dev *hdev, u8 instance)
182101ce70b0SLuiz Augusto von Dentz {
182201ce70b0SLuiz Augusto von Dentz 	u32 flags;
182301ce70b0SLuiz Augusto von Dentz 	struct adv_info *adv;
182401ce70b0SLuiz Augusto von Dentz 
182501ce70b0SLuiz Augusto von Dentz 	if (instance == 0x00) {
182601ce70b0SLuiz Augusto von Dentz 		/* Instance 0 always manages the "Tx Power" and "Flags"
182701ce70b0SLuiz Augusto von Dentz 		 * fields
182801ce70b0SLuiz Augusto von Dentz 		 */
182901ce70b0SLuiz Augusto von Dentz 		flags = MGMT_ADV_FLAG_TX_POWER | MGMT_ADV_FLAG_MANAGED_FLAGS;
183001ce70b0SLuiz Augusto von Dentz 
183101ce70b0SLuiz Augusto von Dentz 		/* For instance 0, the HCI_ADVERTISING_CONNECTABLE setting
183201ce70b0SLuiz Augusto von Dentz 		 * corresponds to the "connectable" instance flag.
183301ce70b0SLuiz Augusto von Dentz 		 */
183401ce70b0SLuiz Augusto von Dentz 		if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE))
183501ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_CONNECTABLE;
183601ce70b0SLuiz Augusto von Dentz 
183701ce70b0SLuiz Augusto von Dentz 		if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
183801ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
183901ce70b0SLuiz Augusto von Dentz 		else if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
184001ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_DISCOV;
184101ce70b0SLuiz Augusto von Dentz 
184201ce70b0SLuiz Augusto von Dentz 		return flags;
184301ce70b0SLuiz Augusto von Dentz 	}
184401ce70b0SLuiz Augusto von Dentz 
184501ce70b0SLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
184601ce70b0SLuiz Augusto von Dentz 
184701ce70b0SLuiz Augusto von Dentz 	/* Return 0 when we got an invalid instance identifier. */
184801ce70b0SLuiz Augusto von Dentz 	if (!adv)
184901ce70b0SLuiz Augusto von Dentz 		return 0;
185001ce70b0SLuiz Augusto von Dentz 
185101ce70b0SLuiz Augusto von Dentz 	return adv->flags;
185201ce70b0SLuiz Augusto von Dentz }
185301ce70b0SLuiz Augusto von Dentz 
hci_adv_instance_is_scannable(struct hci_dev * hdev,u8 instance)185401ce70b0SLuiz Augusto von Dentz bool hci_adv_instance_is_scannable(struct hci_dev *hdev, u8 instance)
185501ce70b0SLuiz Augusto von Dentz {
185601ce70b0SLuiz Augusto von Dentz 	struct adv_info *adv;
185701ce70b0SLuiz Augusto von Dentz 
185801ce70b0SLuiz Augusto von Dentz 	/* Instance 0x00 always set local name */
185901ce70b0SLuiz Augusto von Dentz 	if (instance == 0x00)
186001ce70b0SLuiz Augusto von Dentz 		return true;
186101ce70b0SLuiz Augusto von Dentz 
186201ce70b0SLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
186301ce70b0SLuiz Augusto von Dentz 	if (!adv)
186401ce70b0SLuiz Augusto von Dentz 		return false;
186501ce70b0SLuiz Augusto von Dentz 
186601ce70b0SLuiz Augusto von Dentz 	if (adv->flags & MGMT_ADV_FLAG_APPEARANCE ||
186701ce70b0SLuiz Augusto von Dentz 	    adv->flags & MGMT_ADV_FLAG_LOCAL_NAME)
186801ce70b0SLuiz Augusto von Dentz 		return true;
186901ce70b0SLuiz Augusto von Dentz 
187001ce70b0SLuiz Augusto von Dentz 	return adv->scan_rsp_len ? true : false;
187101ce70b0SLuiz Augusto von Dentz }
187201ce70b0SLuiz Augusto von Dentz 
187301ce70b0SLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */
hci_adv_monitors_clear(struct hci_dev * hdev)1874e5e1e7fdSMiao-chen Chou void hci_adv_monitors_clear(struct hci_dev *hdev)
1875e5e1e7fdSMiao-chen Chou {
1876b139553dSMiao-chen Chou 	struct adv_monitor *monitor;
1877b139553dSMiao-chen Chou 	int handle;
1878b139553dSMiao-chen Chou 
1879b139553dSMiao-chen Chou 	idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle)
188066bd095aSArchie Pusaka 		hci_free_adv_monitor(hdev, monitor);
1881b139553dSMiao-chen Chou 
1882e5e1e7fdSMiao-chen Chou 	idr_destroy(&hdev->adv_monitors_idr);
1883e5e1e7fdSMiao-chen Chou }
1884e5e1e7fdSMiao-chen Chou 
188566bd095aSArchie Pusaka /* Frees the monitor structure and do some bookkeepings.
188666bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
188766bd095aSArchie Pusaka  */
hci_free_adv_monitor(struct hci_dev * hdev,struct adv_monitor * monitor)188866bd095aSArchie Pusaka void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
1889b139553dSMiao-chen Chou {
1890b139553dSMiao-chen Chou 	struct adv_pattern *pattern;
1891b139553dSMiao-chen Chou 	struct adv_pattern *tmp;
1892b139553dSMiao-chen Chou 
1893b139553dSMiao-chen Chou 	if (!monitor)
1894b139553dSMiao-chen Chou 		return;
1895b139553dSMiao-chen Chou 
189666bd095aSArchie Pusaka 	list_for_each_entry_safe(pattern, tmp, &monitor->patterns, list) {
189766bd095aSArchie Pusaka 		list_del(&pattern->list);
1898b139553dSMiao-chen Chou 		kfree(pattern);
189966bd095aSArchie Pusaka 	}
190066bd095aSArchie Pusaka 
190166bd095aSArchie Pusaka 	if (monitor->handle)
190266bd095aSArchie Pusaka 		idr_remove(&hdev->adv_monitors_idr, monitor->handle);
190366bd095aSArchie Pusaka 
190466bd095aSArchie Pusaka 	if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) {
190566bd095aSArchie Pusaka 		hdev->adv_monitors_cnt--;
190666bd095aSArchie Pusaka 		mgmt_adv_monitor_removed(hdev, monitor->handle);
190766bd095aSArchie Pusaka 	}
1908b139553dSMiao-chen Chou 
1909b139553dSMiao-chen Chou 	kfree(monitor);
1910b139553dSMiao-chen Chou }
1911b139553dSMiao-chen Chou 
1912a2a4dedfSArchie Pusaka /* Assigns handle to a monitor, and if offloading is supported and power is on,
1913a2a4dedfSArchie Pusaka  * also attempts to forward the request to the controller.
1914b747a836SManish Mandlik  * This function requires the caller holds hci_req_sync_lock.
1915a2a4dedfSArchie Pusaka  */
hci_add_adv_monitor(struct hci_dev * hdev,struct adv_monitor * monitor)1916b747a836SManish Mandlik int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
1917b139553dSMiao-chen Chou {
1918b139553dSMiao-chen Chou 	int min, max, handle;
1919b747a836SManish Mandlik 	int status = 0;
1920b139553dSMiao-chen Chou 
1921b747a836SManish Mandlik 	if (!monitor)
1922b747a836SManish Mandlik 		return -EINVAL;
1923a2a4dedfSArchie Pusaka 
1924b747a836SManish Mandlik 	hci_dev_lock(hdev);
1925b139553dSMiao-chen Chou 
1926b139553dSMiao-chen Chou 	min = HCI_MIN_ADV_MONITOR_HANDLE;
1927b139553dSMiao-chen Chou 	max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES;
1928b139553dSMiao-chen Chou 	handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max,
1929b139553dSMiao-chen Chou 			   GFP_KERNEL);
1930b747a836SManish Mandlik 
1931b747a836SManish Mandlik 	hci_dev_unlock(hdev);
1932b747a836SManish Mandlik 
1933b747a836SManish Mandlik 	if (handle < 0)
1934b747a836SManish Mandlik 		return handle;
1935b139553dSMiao-chen Chou 
1936b139553dSMiao-chen Chou 	monitor->handle = handle;
19378208f5a9SMiao-chen Chou 
1938a2a4dedfSArchie Pusaka 	if (!hdev_is_powered(hdev))
1939b747a836SManish Mandlik 		return status;
19408208f5a9SMiao-chen Chou 
1941a2a4dedfSArchie Pusaka 	switch (hci_get_adv_monitor_offload_ext(hdev)) {
1942a2a4dedfSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_NONE:
19436f55eea1SDouglas Anderson 		bt_dev_dbg(hdev, "add monitor %d status %d",
1944b747a836SManish Mandlik 			   monitor->handle, status);
1945a2a4dedfSArchie Pusaka 		/* Message was not forwarded to controller - not an error */
1946b747a836SManish Mandlik 		break;
1947b747a836SManish Mandlik 
1948a2a4dedfSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_MSFT:
1949b747a836SManish Mandlik 		status = msft_add_monitor_pattern(hdev, monitor);
19506f55eea1SDouglas Anderson 		bt_dev_dbg(hdev, "add monitor %d msft status %d",
1951a2bcd2b6SManish Mandlik 			   handle, status);
1952a2a4dedfSArchie Pusaka 		break;
1953a2a4dedfSArchie Pusaka 	}
1954a2a4dedfSArchie Pusaka 
1955b747a836SManish Mandlik 	return status;
1956b139553dSMiao-chen Chou }
1957b139553dSMiao-chen Chou 
195866bd095aSArchie Pusaka /* Attempts to tell the controller and free the monitor. If somehow the
195966bd095aSArchie Pusaka  * controller doesn't have a corresponding handle, remove anyway.
19607cf5c297SManish Mandlik  * This function requires the caller holds hci_req_sync_lock.
196166bd095aSArchie Pusaka  */
hci_remove_adv_monitor(struct hci_dev * hdev,struct adv_monitor * monitor)19627cf5c297SManish Mandlik static int hci_remove_adv_monitor(struct hci_dev *hdev,
19637cf5c297SManish Mandlik 				  struct adv_monitor *monitor)
1964bd2fbc6cSMiao-chen Chou {
19657cf5c297SManish Mandlik 	int status = 0;
1966de6dfcefSDouglas Anderson 	int handle;
1967bd2fbc6cSMiao-chen Chou 
196866bd095aSArchie Pusaka 	switch (hci_get_adv_monitor_offload_ext(hdev)) {
196966bd095aSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */
19706f55eea1SDouglas Anderson 		bt_dev_dbg(hdev, "remove monitor %d status %d",
19717cf5c297SManish Mandlik 			   monitor->handle, status);
197266bd095aSArchie Pusaka 		goto free_monitor;
19737cf5c297SManish Mandlik 
197466bd095aSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_MSFT:
1975de6dfcefSDouglas Anderson 		handle = monitor->handle;
19767cf5c297SManish Mandlik 		status = msft_remove_monitor(hdev, monitor);
19776f55eea1SDouglas Anderson 		bt_dev_dbg(hdev, "remove monitor %d msft status %d",
19786f55eea1SDouglas Anderson 			   handle, status);
197966bd095aSArchie Pusaka 		break;
1980bd2fbc6cSMiao-chen Chou 	}
1981bd2fbc6cSMiao-chen Chou 
198266bd095aSArchie Pusaka 	/* In case no matching handle registered, just free the monitor */
19837cf5c297SManish Mandlik 	if (status == -ENOENT)
198466bd095aSArchie Pusaka 		goto free_monitor;
1985bd2fbc6cSMiao-chen Chou 
19867cf5c297SManish Mandlik 	return status;
1987bd2fbc6cSMiao-chen Chou 
198866bd095aSArchie Pusaka free_monitor:
19897cf5c297SManish Mandlik 	if (status == -ENOENT)
199066bd095aSArchie Pusaka 		bt_dev_warn(hdev, "Removing monitor with no matching handle %d",
199166bd095aSArchie Pusaka 			    monitor->handle);
199266bd095aSArchie Pusaka 	hci_free_adv_monitor(hdev, monitor);
199366bd095aSArchie Pusaka 
19947cf5c297SManish Mandlik 	return status;
1995bd2fbc6cSMiao-chen Chou }
1996bd2fbc6cSMiao-chen Chou 
19977cf5c297SManish Mandlik /* This function requires the caller holds hci_req_sync_lock */
hci_remove_single_adv_monitor(struct hci_dev * hdev,u16 handle)19987cf5c297SManish Mandlik int hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle)
199966bd095aSArchie Pusaka {
200066bd095aSArchie Pusaka 	struct adv_monitor *monitor = idr_find(&hdev->adv_monitors_idr, handle);
200166bd095aSArchie Pusaka 
20027cf5c297SManish Mandlik 	if (!monitor)
20037cf5c297SManish Mandlik 		return -EINVAL;
20047cf5c297SManish Mandlik 
20057cf5c297SManish Mandlik 	return hci_remove_adv_monitor(hdev, monitor);
200666bd095aSArchie Pusaka }
200766bd095aSArchie Pusaka 
20087cf5c297SManish Mandlik /* This function requires the caller holds hci_req_sync_lock */
hci_remove_all_adv_monitor(struct hci_dev * hdev)20097cf5c297SManish Mandlik int hci_remove_all_adv_monitor(struct hci_dev *hdev)
201066bd095aSArchie Pusaka {
201166bd095aSArchie Pusaka 	struct adv_monitor *monitor;
201266bd095aSArchie Pusaka 	int idr_next_id = 0;
20137cf5c297SManish Mandlik 	int status = 0;
201466bd095aSArchie Pusaka 
20157cf5c297SManish Mandlik 	while (1) {
201666bd095aSArchie Pusaka 		monitor = idr_get_next(&hdev->adv_monitors_idr, &idr_next_id);
201766bd095aSArchie Pusaka 		if (!monitor)
201866bd095aSArchie Pusaka 			break;
201966bd095aSArchie Pusaka 
20207cf5c297SManish Mandlik 		status = hci_remove_adv_monitor(hdev, monitor);
20217cf5c297SManish Mandlik 		if (status)
20227cf5c297SManish Mandlik 			return status;
202366bd095aSArchie Pusaka 
20247cf5c297SManish Mandlik 		idr_next_id++;
202566bd095aSArchie Pusaka 	}
202666bd095aSArchie Pusaka 
20277cf5c297SManish Mandlik 	return status;
2028bd2fbc6cSMiao-chen Chou }
2029bd2fbc6cSMiao-chen Chou 
20308208f5a9SMiao-chen Chou /* This function requires the caller holds hdev->lock */
hci_is_adv_monitoring(struct hci_dev * hdev)20318208f5a9SMiao-chen Chou bool hci_is_adv_monitoring(struct hci_dev *hdev)
20328208f5a9SMiao-chen Chou {
20338208f5a9SMiao-chen Chou 	return !idr_is_empty(&hdev->adv_monitors_idr);
20348208f5a9SMiao-chen Chou }
20358208f5a9SMiao-chen Chou 
hci_get_adv_monitor_offload_ext(struct hci_dev * hdev)2036a2a4dedfSArchie Pusaka int hci_get_adv_monitor_offload_ext(struct hci_dev *hdev)
2037a2a4dedfSArchie Pusaka {
2038a2a4dedfSArchie Pusaka 	if (msft_monitor_supported(hdev))
2039a2a4dedfSArchie Pusaka 		return HCI_ADV_MONITOR_EXT_MSFT;
2040a2a4dedfSArchie Pusaka 
2041a2a4dedfSArchie Pusaka 	return HCI_ADV_MONITOR_EXT_NONE;
2042a2a4dedfSArchie Pusaka }
2043a2a4dedfSArchie Pusaka 
hci_bdaddr_list_lookup(struct list_head * bdaddr_list,bdaddr_t * bdaddr,u8 type)2044dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
2045b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
2046b2a66aadSAntti Julku {
2047b2a66aadSAntti Julku 	struct bdaddr_list *b;
2048b2a66aadSAntti Julku 
2049dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
2050b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2051b2a66aadSAntti Julku 			return b;
2052b9ee0a78SMarcel Holtmann 	}
2053b2a66aadSAntti Julku 
2054b2a66aadSAntti Julku 	return NULL;
2055b2a66aadSAntti Julku }
2056b2a66aadSAntti Julku 
hci_bdaddr_list_lookup_with_irk(struct list_head * bdaddr_list,bdaddr_t * bdaddr,u8 type)2057b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
2058b950aa88SAnkit Navik 				struct list_head *bdaddr_list, bdaddr_t *bdaddr,
2059b950aa88SAnkit Navik 				u8 type)
2060b950aa88SAnkit Navik {
2061b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *b;
2062b950aa88SAnkit Navik 
2063b950aa88SAnkit Navik 	list_for_each_entry(b, bdaddr_list, list) {
2064b950aa88SAnkit Navik 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2065b950aa88SAnkit Navik 			return b;
2066b950aa88SAnkit Navik 	}
2067b950aa88SAnkit Navik 
2068b950aa88SAnkit Navik 	return NULL;
2069b950aa88SAnkit Navik }
2070b950aa88SAnkit Navik 
20718baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *
hci_bdaddr_list_lookup_with_flags(struct list_head * bdaddr_list,bdaddr_t * bdaddr,u8 type)20728baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list,
20738baaa403SAbhishek Pandit-Subedi 				  bdaddr_t *bdaddr, u8 type)
20748baaa403SAbhishek Pandit-Subedi {
20758baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *b;
20768baaa403SAbhishek Pandit-Subedi 
20778baaa403SAbhishek Pandit-Subedi 	list_for_each_entry(b, bdaddr_list, list) {
20788baaa403SAbhishek Pandit-Subedi 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
20798baaa403SAbhishek Pandit-Subedi 			return b;
20808baaa403SAbhishek Pandit-Subedi 	}
20818baaa403SAbhishek Pandit-Subedi 
20828baaa403SAbhishek Pandit-Subedi 	return NULL;
20838baaa403SAbhishek Pandit-Subedi }
20848baaa403SAbhishek Pandit-Subedi 
hci_bdaddr_list_clear(struct list_head * bdaddr_list)2085dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
2086b2a66aadSAntti Julku {
20877eb7404fSGeliang Tang 	struct bdaddr_list *b, *n;
2088b2a66aadSAntti Julku 
20897eb7404fSGeliang Tang 	list_for_each_entry_safe(b, n, bdaddr_list, list) {
20907eb7404fSGeliang Tang 		list_del(&b->list);
2091b2a66aadSAntti Julku 		kfree(b);
2092b2a66aadSAntti Julku 	}
2093b2a66aadSAntti Julku }
2094b2a66aadSAntti Julku 
hci_bdaddr_list_add(struct list_head * list,bdaddr_t * bdaddr,u8 type)2095dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2096b2a66aadSAntti Julku {
2097b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2098b2a66aadSAntti Julku 
2099b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
2100b2a66aadSAntti Julku 		return -EBADF;
2101b2a66aadSAntti Julku 
2102dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
21035e762444SAntti Julku 		return -EEXIST;
2104b2a66aadSAntti Julku 
210527f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
21065e762444SAntti Julku 	if (!entry)
21075e762444SAntti Julku 		return -ENOMEM;
2108b2a66aadSAntti Julku 
2109b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2110b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
2111b2a66aadSAntti Julku 
2112dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
2113b2a66aadSAntti Julku 
21142a8357f2SJohan Hedberg 	return 0;
2115b2a66aadSAntti Julku }
2116b2a66aadSAntti Julku 
hci_bdaddr_list_add_with_irk(struct list_head * list,bdaddr_t * bdaddr,u8 type,u8 * peer_irk,u8 * local_irk)2117b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2118b950aa88SAnkit Navik 					u8 type, u8 *peer_irk, u8 *local_irk)
2119b950aa88SAnkit Navik {
2120b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
2121b950aa88SAnkit Navik 
2122b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY))
2123b950aa88SAnkit Navik 		return -EBADF;
2124b950aa88SAnkit Navik 
2125b950aa88SAnkit Navik 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
2126b950aa88SAnkit Navik 		return -EEXIST;
2127b950aa88SAnkit Navik 
2128b950aa88SAnkit Navik 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
2129b950aa88SAnkit Navik 	if (!entry)
2130b950aa88SAnkit Navik 		return -ENOMEM;
2131b950aa88SAnkit Navik 
2132b950aa88SAnkit Navik 	bacpy(&entry->bdaddr, bdaddr);
2133b950aa88SAnkit Navik 	entry->bdaddr_type = type;
2134b950aa88SAnkit Navik 
2135b950aa88SAnkit Navik 	if (peer_irk)
2136b950aa88SAnkit Navik 		memcpy(entry->peer_irk, peer_irk, 16);
2137b950aa88SAnkit Navik 
2138b950aa88SAnkit Navik 	if (local_irk)
2139b950aa88SAnkit Navik 		memcpy(entry->local_irk, local_irk, 16);
2140b950aa88SAnkit Navik 
2141b950aa88SAnkit Navik 	list_add(&entry->list, list);
2142b950aa88SAnkit Navik 
2143b950aa88SAnkit Navik 	return 0;
2144b950aa88SAnkit Navik }
2145b950aa88SAnkit Navik 
hci_bdaddr_list_add_with_flags(struct list_head * list,bdaddr_t * bdaddr,u8 type,u32 flags)21468baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
21478baaa403SAbhishek Pandit-Subedi 				   u8 type, u32 flags)
21488baaa403SAbhishek Pandit-Subedi {
21498baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
21508baaa403SAbhishek Pandit-Subedi 
21518baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY))
21528baaa403SAbhishek Pandit-Subedi 		return -EBADF;
21538baaa403SAbhishek Pandit-Subedi 
21548baaa403SAbhishek Pandit-Subedi 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
21558baaa403SAbhishek Pandit-Subedi 		return -EEXIST;
21568baaa403SAbhishek Pandit-Subedi 
21578baaa403SAbhishek Pandit-Subedi 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
21588baaa403SAbhishek Pandit-Subedi 	if (!entry)
21598baaa403SAbhishek Pandit-Subedi 		return -ENOMEM;
21608baaa403SAbhishek Pandit-Subedi 
21618baaa403SAbhishek Pandit-Subedi 	bacpy(&entry->bdaddr, bdaddr);
21628baaa403SAbhishek Pandit-Subedi 	entry->bdaddr_type = type;
2163e1cff700SLinus Torvalds 	entry->flags = flags;
21648baaa403SAbhishek Pandit-Subedi 
21658baaa403SAbhishek Pandit-Subedi 	list_add(&entry->list, list);
21668baaa403SAbhishek Pandit-Subedi 
21678baaa403SAbhishek Pandit-Subedi 	return 0;
21688baaa403SAbhishek Pandit-Subedi }
21698baaa403SAbhishek Pandit-Subedi 
hci_bdaddr_list_del(struct list_head * list,bdaddr_t * bdaddr,u8 type)2170dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2171b2a66aadSAntti Julku {
2172b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2173b2a66aadSAntti Julku 
217435f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2175dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
217635f7498aSJohan Hedberg 		return 0;
217735f7498aSJohan Hedberg 	}
2178b2a66aadSAntti Julku 
2179dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
2180d2ab0ac1SMarcel Holtmann 	if (!entry)
2181d2ab0ac1SMarcel Holtmann 		return -ENOENT;
2182d2ab0ac1SMarcel Holtmann 
2183d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
2184d2ab0ac1SMarcel Holtmann 	kfree(entry);
2185d2ab0ac1SMarcel Holtmann 
2186d2ab0ac1SMarcel Holtmann 	return 0;
2187d2ab0ac1SMarcel Holtmann }
2188d2ab0ac1SMarcel Holtmann 
hci_bdaddr_list_del_with_irk(struct list_head * list,bdaddr_t * bdaddr,u8 type)2189b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2190b950aa88SAnkit Navik 							u8 type)
2191b950aa88SAnkit Navik {
2192b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
2193b950aa88SAnkit Navik 
2194b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2195b950aa88SAnkit Navik 		hci_bdaddr_list_clear(list);
2196b950aa88SAnkit Navik 		return 0;
2197b950aa88SAnkit Navik 	}
2198b950aa88SAnkit Navik 
2199b950aa88SAnkit Navik 	entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type);
2200b950aa88SAnkit Navik 	if (!entry)
2201b950aa88SAnkit Navik 		return -ENOENT;
2202b950aa88SAnkit Navik 
2203b950aa88SAnkit Navik 	list_del(&entry->list);
2204b950aa88SAnkit Navik 	kfree(entry);
2205b950aa88SAnkit Navik 
2206b950aa88SAnkit Navik 	return 0;
2207b950aa88SAnkit Navik }
2208b950aa88SAnkit Navik 
hci_bdaddr_list_del_with_flags(struct list_head * list,bdaddr_t * bdaddr,u8 type)22098baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
22108baaa403SAbhishek Pandit-Subedi 				   u8 type)
22118baaa403SAbhishek Pandit-Subedi {
22128baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
22138baaa403SAbhishek Pandit-Subedi 
22148baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY)) {
22158baaa403SAbhishek Pandit-Subedi 		hci_bdaddr_list_clear(list);
22168baaa403SAbhishek Pandit-Subedi 		return 0;
22178baaa403SAbhishek Pandit-Subedi 	}
22188baaa403SAbhishek Pandit-Subedi 
22198baaa403SAbhishek Pandit-Subedi 	entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type);
22208baaa403SAbhishek Pandit-Subedi 	if (!entry)
22218baaa403SAbhishek Pandit-Subedi 		return -ENOENT;
22228baaa403SAbhishek Pandit-Subedi 
22238baaa403SAbhishek Pandit-Subedi 	list_del(&entry->list);
22248baaa403SAbhishek Pandit-Subedi 	kfree(entry);
22258baaa403SAbhishek Pandit-Subedi 
22268baaa403SAbhishek Pandit-Subedi 	return 0;
22278baaa403SAbhishek Pandit-Subedi }
22288baaa403SAbhishek Pandit-Subedi 
222915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
hci_conn_params_lookup(struct hci_dev * hdev,bdaddr_t * addr,u8 addr_type)223015819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
223115819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
223215819a70SAndre Guedes {
223315819a70SAndre Guedes 	struct hci_conn_params *params;
223415819a70SAndre Guedes 
223515819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
223615819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
223715819a70SAndre Guedes 		    params->addr_type == addr_type) {
223815819a70SAndre Guedes 			return params;
223915819a70SAndre Guedes 		}
224015819a70SAndre Guedes 	}
224115819a70SAndre Guedes 
224215819a70SAndre Guedes 	return NULL;
224315819a70SAndre Guedes }
224415819a70SAndre Guedes 
2245195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock or rcu_read_lock */
hci_pend_le_action_lookup(struct list_head * list,bdaddr_t * addr,u8 addr_type)2246501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
22474b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
2248a9b0a04cSAndre Guedes {
2249912b42efSJohan Hedberg 	struct hci_conn_params *param;
2250a9b0a04cSAndre Guedes 
2251195ef75eSPauli Virtanen 	rcu_read_lock();
2252195ef75eSPauli Virtanen 
2253195ef75eSPauli Virtanen 	list_for_each_entry_rcu(param, list, action) {
2254912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
2255195ef75eSPauli Virtanen 		    param->addr_type == addr_type) {
2256195ef75eSPauli Virtanen 			rcu_read_unlock();
2257912b42efSJohan Hedberg 			return param;
22584b10966fSMarcel Holtmann 		}
2259195ef75eSPauli Virtanen 	}
2260195ef75eSPauli Virtanen 
2261195ef75eSPauli Virtanen 	rcu_read_unlock();
22624b10966fSMarcel Holtmann 
22634b10966fSMarcel Holtmann 	return NULL;
2264a9b0a04cSAndre Guedes }
2265a9b0a04cSAndre Guedes 
226615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
hci_pend_le_list_del_init(struct hci_conn_params * param)2267195ef75eSPauli Virtanen void hci_pend_le_list_del_init(struct hci_conn_params *param)
2268195ef75eSPauli Virtanen {
2269195ef75eSPauli Virtanen 	if (list_empty(&param->action))
2270195ef75eSPauli Virtanen 		return;
2271195ef75eSPauli Virtanen 
2272195ef75eSPauli Virtanen 	list_del_rcu(&param->action);
2273195ef75eSPauli Virtanen 	synchronize_rcu();
2274195ef75eSPauli Virtanen 	INIT_LIST_HEAD(&param->action);
2275195ef75eSPauli Virtanen }
2276195ef75eSPauli Virtanen 
2277195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock */
hci_pend_le_list_add(struct hci_conn_params * param,struct list_head * list)2278195ef75eSPauli Virtanen void hci_pend_le_list_add(struct hci_conn_params *param,
2279195ef75eSPauli Virtanen 			  struct list_head *list)
2280195ef75eSPauli Virtanen {
2281195ef75eSPauli Virtanen 	list_add_rcu(&param->action, list);
2282195ef75eSPauli Virtanen }
2283195ef75eSPauli Virtanen 
2284195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock */
hci_conn_params_add(struct hci_dev * hdev,bdaddr_t * addr,u8 addr_type)228551d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
228651d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
228715819a70SAndre Guedes {
228815819a70SAndre Guedes 	struct hci_conn_params *params;
228915819a70SAndre Guedes 
229015819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
2291cef952ceSAndre Guedes 	if (params)
229251d167c0SMarcel Holtmann 		return params;
229315819a70SAndre Guedes 
229415819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
229515819a70SAndre Guedes 	if (!params) {
22962064ee33SMarcel Holtmann 		bt_dev_err(hdev, "out of memory");
229751d167c0SMarcel Holtmann 		return NULL;
229815819a70SAndre Guedes 	}
229915819a70SAndre Guedes 
230015819a70SAndre Guedes 	bacpy(&params->addr, addr);
230115819a70SAndre Guedes 	params->addr_type = addr_type;
2302cef952ceSAndre Guedes 
2303cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
230493450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
2305cef952ceSAndre Guedes 
2306bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
2307bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
2308bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
2309bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
2310bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
2311bf5b3c8bSMarcel Holtmann 
2312bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
2313bf5b3c8bSMarcel Holtmann 
231451d167c0SMarcel Holtmann 	return params;
2315bf5b3c8bSMarcel Holtmann }
2316bf5b3c8bSMarcel Holtmann 
hci_conn_params_free(struct hci_conn_params * params)2317195ef75eSPauli Virtanen void hci_conn_params_free(struct hci_conn_params *params)
2318f6c63249SJohan Hedberg {
2319195ef75eSPauli Virtanen 	hci_pend_le_list_del_init(params);
2320195ef75eSPauli Virtanen 
2321f6c63249SJohan Hedberg 	if (params->conn) {
2322f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
2323f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
2324f6c63249SJohan Hedberg 	}
2325f6c63249SJohan Hedberg 
2326f6c63249SJohan Hedberg 	list_del(&params->list);
2327f6c63249SJohan Hedberg 	kfree(params);
2328f6c63249SJohan Hedberg }
2329f6c63249SJohan Hedberg 
233015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
hci_conn_params_del(struct hci_dev * hdev,bdaddr_t * addr,u8 addr_type)233115819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
233215819a70SAndre Guedes {
233315819a70SAndre Guedes 	struct hci_conn_params *params;
233415819a70SAndre Guedes 
233515819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
233615819a70SAndre Guedes 	if (!params)
233715819a70SAndre Guedes 		return;
233815819a70SAndre Guedes 
2339f6c63249SJohan Hedberg 	hci_conn_params_free(params);
234015819a70SAndre Guedes 
23415bee2fd6SLuiz Augusto von Dentz 	hci_update_passive_scan(hdev);
234295305baaSJohan Hedberg 
234315819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
234415819a70SAndre Guedes }
234515819a70SAndre Guedes 
234615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
hci_conn_params_clear_disabled(struct hci_dev * hdev)234755af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
234815819a70SAndre Guedes {
234915819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
235015819a70SAndre Guedes 
235115819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
235255af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
235355af49a8SJohan Hedberg 			continue;
2354f75113a2SJakub Pawlowski 
235591641b79SZheng Yongjun 		/* If trying to establish one time connection to disabled
2356f75113a2SJakub Pawlowski 		 * device, leave the params, but mark them as just once.
2357f75113a2SJakub Pawlowski 		 */
2358f75113a2SJakub Pawlowski 		if (params->explicit_connect) {
2359f75113a2SJakub Pawlowski 			params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
2360f75113a2SJakub Pawlowski 			continue;
2361f75113a2SJakub Pawlowski 		}
2362f75113a2SJakub Pawlowski 
2363195ef75eSPauli Virtanen 		hci_conn_params_free(params);
236415819a70SAndre Guedes 	}
236515819a70SAndre Guedes 
236655af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
236755af49a8SJohan Hedberg }
236855af49a8SJohan Hedberg 
236955af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
hci_conn_params_clear_all(struct hci_dev * hdev)2370030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev)
237115819a70SAndre Guedes {
237215819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
237315819a70SAndre Guedes 
2374f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
2375f6c63249SJohan Hedberg 		hci_conn_params_free(params);
237615819a70SAndre Guedes 
237715819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
237815819a70SAndre Guedes }
237915819a70SAndre Guedes 
2380a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
2381a1f4c318SJohan Hedberg  *
2382a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
2383a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
2384a1f4c318SJohan Hedberg  * the static random address.
2385a1f4c318SJohan Hedberg  *
2386a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
2387a1f4c318SJohan Hedberg  * public address to use the static random address instead.
238850b5b952SMarcel Holtmann  *
238950b5b952SMarcel Holtmann  * In case BR/EDR has been disabled on a dual-mode controller and
239050b5b952SMarcel Holtmann  * userspace has configured a static address, then that address
239150b5b952SMarcel Holtmann  * becomes the identity address instead of the public BR/EDR address.
2392a1f4c318SJohan Hedberg  */
hci_copy_identity_address(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 * bdaddr_type)2393a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
2394a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
2395a1f4c318SJohan Hedberg {
2396b7cb93e5SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
239750b5b952SMarcel Holtmann 	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
2398d7a5a11dSMarcel Holtmann 	    (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
239950b5b952SMarcel Holtmann 	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
2400a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
2401a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
2402a1f4c318SJohan Hedberg 	} else {
2403a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
2404a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
2405a1f4c318SJohan Hedberg 	}
2406a1f4c318SJohan Hedberg }
2407a1f4c318SJohan Hedberg 
hci_clear_wake_reason(struct hci_dev * hdev)24082f20216cSAbhishek Pandit-Subedi static void hci_clear_wake_reason(struct hci_dev *hdev)
24092f20216cSAbhishek Pandit-Subedi {
24102f20216cSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
24112f20216cSAbhishek Pandit-Subedi 
24122f20216cSAbhishek Pandit-Subedi 	hdev->wake_reason = 0;
24132f20216cSAbhishek Pandit-Subedi 	bacpy(&hdev->wake_addr, BDADDR_ANY);
24142f20216cSAbhishek Pandit-Subedi 	hdev->wake_addr_type = 0;
24152f20216cSAbhishek Pandit-Subedi 
24162f20216cSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
24172f20216cSAbhishek Pandit-Subedi }
24182f20216cSAbhishek Pandit-Subedi 
hci_suspend_notifier(struct notifier_block * nb,unsigned long action,void * data)24199952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
24209952d90eSAbhishek Pandit-Subedi 				void *data)
24219952d90eSAbhishek Pandit-Subedi {
24229952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
24239952d90eSAbhishek Pandit-Subedi 		container_of(nb, struct hci_dev, suspend_notifier);
24249952d90eSAbhishek Pandit-Subedi 	int ret = 0;
24259952d90eSAbhishek Pandit-Subedi 
24264b8af331SAbhishek Pandit-Subedi 	/* Userspace has full control of this device. Do nothing. */
24274b8af331SAbhishek Pandit-Subedi 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
24284b8af331SAbhishek Pandit-Subedi 		return NOTIFY_DONE;
24294b8af331SAbhishek Pandit-Subedi 
2430573ebae1SYing Hsu 	/* To avoid a potential race with hci_unregister_dev. */
2431573ebae1SYing Hsu 	hci_dev_hold(hdev);
2432573ebae1SYing Hsu 
2433e1b77d68SLuiz Augusto von Dentz 	if (action == PM_SUSPEND_PREPARE)
2434e1b77d68SLuiz Augusto von Dentz 		ret = hci_suspend_dev(hdev);
2435e1b77d68SLuiz Augusto von Dentz 	else if (action == PM_POST_SUSPEND)
2436e1b77d68SLuiz Augusto von Dentz 		ret = hci_resume_dev(hdev);
24379952d90eSAbhishek Pandit-Subedi 
2438a9ec8423SAbhishek Pandit-Subedi 	if (ret)
2439a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
2440a9ec8423SAbhishek Pandit-Subedi 			   action, ret);
2441a9ec8423SAbhishek Pandit-Subedi 
2442573ebae1SYing Hsu 	hci_dev_put(hdev);
244324b06572SMax Chou 	return NOTIFY_DONE;
24449952d90eSAbhishek Pandit-Subedi }
24458731840aSAbhishek Pandit-Subedi 
24469be0dab7SDavid Herrmann /* Alloc HCI device */
hci_alloc_dev_priv(int sizeof_priv)24476ec56613STedd Ho-Jeong An struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
24489be0dab7SDavid Herrmann {
24499be0dab7SDavid Herrmann 	struct hci_dev *hdev;
24506ec56613STedd Ho-Jeong An 	unsigned int alloc_size;
24519be0dab7SDavid Herrmann 
24526ec56613STedd Ho-Jeong An 	alloc_size = sizeof(*hdev);
24536ec56613STedd Ho-Jeong An 	if (sizeof_priv) {
24546ec56613STedd Ho-Jeong An 		/* Fixme: May need ALIGN-ment? */
24556ec56613STedd Ho-Jeong An 		alloc_size += sizeof_priv;
24566ec56613STedd Ho-Jeong An 	}
24576ec56613STedd Ho-Jeong An 
24586ec56613STedd Ho-Jeong An 	hdev = kzalloc(alloc_size, GFP_KERNEL);
24599be0dab7SDavid Herrmann 	if (!hdev)
24609be0dab7SDavid Herrmann 		return NULL;
24619be0dab7SDavid Herrmann 
2462b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2463b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
2464b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
2465b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
2466b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
246796c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
2468bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2469bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2470d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
2471d2609b34SFlorian Grandel 	hdev->cur_adv_instance = 0x00;
24725d900e46SFlorian Grandel 	hdev->adv_instance_timeout = 0;
2473b1b813d4SDavid Herrmann 
2474c4f1f408SHoward Chung 	hdev->advmon_allowlist_duration = 300;
2475c4f1f408SHoward Chung 	hdev->advmon_no_filter_duration = 500;
247680af16a3SHoward Chung 	hdev->enable_advmon_interleave_scan = 0x00;	/* Default to disable */
2477c4f1f408SHoward Chung 
2478b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
2479b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
2480b1b813d4SDavid Herrmann 
24813f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
2482628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
2483628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
2484bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
2485bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
248610873f99SAlain Michaud 	hdev->le_scan_int_suspend = 0x0400;
248710873f99SAlain Michaud 	hdev->le_scan_window_suspend = 0x0012;
248810873f99SAlain Michaud 	hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT;
248910873f99SAlain Michaud 	hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN;
2490ba29d036SMarcel Holtmann 	hdev->le_scan_int_adv_monitor = 0x0060;
2491ba29d036SMarcel Holtmann 	hdev->le_scan_window_adv_monitor = 0x0030;
249210873f99SAlain Michaud 	hdev->le_scan_int_connect = 0x0060;
249310873f99SAlain Michaud 	hdev->le_scan_window_connect = 0x0060;
2494b48c3b59SJonas Holmberg 	hdev->le_conn_min_interval = 0x0018;
2495b48c3b59SJonas Holmberg 	hdev->le_conn_max_interval = 0x0028;
249604fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
249704fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
2498a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = 0x001b;
2499a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = 0x0148;
2500a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = 0x001b;
2501a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = 0x0148;
2502a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = 0x001b;
2503a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = 0x0148;
250430d65e08SMatias Karhumaa 	hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE;
250530d65e08SMatias Karhumaa 	hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE;
25066decb5b4SJaganath Kanakkassery 	hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
25076decb5b4SJaganath Kanakkassery 	hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
25081d0fac2cSLuiz Augusto von Dentz 	hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES;
250910873f99SAlain Michaud 	hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION;
251049b020c1SAlain Michaud 	hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT;
25117c395ea5SDaniel Winkler 	hdev->min_le_tx_power = HCI_TX_POWER_INVALID;
25127c395ea5SDaniel Winkler 	hdev->max_le_tx_power = HCI_TX_POWER_INVALID;
2513bef64738SMarcel Holtmann 
2514d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
2515b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
251631ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
251731ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
2518302975cbSSpoorthi Ravishankar Koppad 	hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT;
251958a96fc3SMarcel Holtmann 	hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE;
2520d6bfd59cSJohan Hedberg 
252110873f99SAlain Michaud 	/* default 1.28 sec page scan */
252210873f99SAlain Michaud 	hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD;
252310873f99SAlain Michaud 	hdev->def_page_scan_int = 0x0800;
252410873f99SAlain Michaud 	hdev->def_page_scan_window = 0x0012;
252510873f99SAlain Michaud 
2526b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
2527b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
2528b1b813d4SDavid Herrmann 
252984cb0143SZiyang Xuan 	ida_init(&hdev->unset_handle_ida);
253084cb0143SZiyang Xuan 
2531b338d917SBrian Gix 	INIT_LIST_HEAD(&hdev->mesh_pending);
2532b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
25333d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->reject_list);
25343d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->accept_list);
2535b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
2536b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
2537b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
2538970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
2539b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
25403d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->le_accept_list);
2541cfdb0c2dSAnkit Navik 	INIT_LIST_HEAD(&hdev->le_resolv_list);
254215819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
254377a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
254466f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
25456b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
2546d2609b34SFlorian Grandel 	INIT_LIST_HEAD(&hdev->adv_instances);
2547600a8749SAlain Michaud 	INIT_LIST_HEAD(&hdev->blocked_keys);
25483368aa35SManish Mandlik 	INIT_LIST_HEAD(&hdev->monitored_devices);
2549b1b813d4SDavid Herrmann 
25508961987fSKiran K 	INIT_LIST_HEAD(&hdev->local_codecs);
2551b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2552b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2553b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2554b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2555c7741d16SMarcel Holtmann 	INIT_WORK(&hdev->error_reset, hci_error_reset);
2556b1b813d4SDavid Herrmann 
25576a98e383SMarcel Holtmann 	hci_cmd_sync_init(hdev);
25586a98e383SMarcel Holtmann 
2559b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2560b1b813d4SDavid Herrmann 
2561b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2562b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2563b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2564b1b813d4SDavid Herrmann 
2565b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2566b1b813d4SDavid Herrmann 
256765cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
2568de75cd0dSManish Mandlik 	INIT_DELAYED_WORK(&hdev->ncmd_timer, hci_ncmd_timeout);
2569b1b813d4SDavid Herrmann 
25709695ef87SAbhishek Pandit-Subedi 	hci_devcd_setup(hdev);
25715fc16cc4SJohan Hedberg 	hci_request_setup(hdev);
25725fc16cc4SJohan Hedberg 
2573b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2574b1b813d4SDavid Herrmann 	discovery_init(hdev);
25759be0dab7SDavid Herrmann 
25769be0dab7SDavid Herrmann 	return hdev;
25779be0dab7SDavid Herrmann }
25786ec56613STedd Ho-Jeong An EXPORT_SYMBOL(hci_alloc_dev_priv);
25799be0dab7SDavid Herrmann 
25809be0dab7SDavid Herrmann /* Free HCI device */
hci_free_dev(struct hci_dev * hdev)25819be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
25829be0dab7SDavid Herrmann {
25839be0dab7SDavid Herrmann 	/* will free via device release */
25849be0dab7SDavid Herrmann 	put_device(&hdev->dev);
25859be0dab7SDavid Herrmann }
25869be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
25879be0dab7SDavid Herrmann 
25881da177e4SLinus Torvalds /* Register HCI device */
hci_register_dev(struct hci_dev * hdev)25891da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
25901da177e4SLinus Torvalds {
2591b1b813d4SDavid Herrmann 	int id, error;
25921da177e4SLinus Torvalds 
259374292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
25941da177e4SLinus Torvalds 		return -EINVAL;
25951da177e4SLinus Torvalds 
25960a8af30aSChristophe JAILLET 	id = ida_alloc_max(&hci_index_ida, HCI_MAX_ID - 1, GFP_KERNEL);
25973df92b31SSasha Levin 	if (id < 0)
25983df92b31SSasha Levin 		return id;
25993df92b31SSasha Levin 
2600dcda1657SLuiz Augusto von Dentz 	error = dev_set_name(&hdev->dev, "hci%u", id);
2601dcda1657SLuiz Augusto von Dentz 	if (error)
2602dcda1657SLuiz Augusto von Dentz 		return error;
2603dcda1657SLuiz Augusto von Dentz 
2604dcda1657SLuiz Augusto von Dentz 	hdev->name = dev_name(&hdev->dev);
26051da177e4SLinus Torvalds 	hdev->id = id;
26062d8b3a11SAndrei Emeltchenko 
26072d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
26082d8b3a11SAndrei Emeltchenko 
260929e2dd0dSTejun Heo 	hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name);
261033ca954dSDavid Herrmann 	if (!hdev->workqueue) {
261133ca954dSDavid Herrmann 		error = -ENOMEM;
261233ca954dSDavid Herrmann 		goto err;
261333ca954dSDavid Herrmann 	}
2614f48fd9c8SMarcel Holtmann 
261529e2dd0dSTejun Heo 	hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI,
261629e2dd0dSTejun Heo 						      hdev->name);
26176ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
26186ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
26196ead1bbcSJohan Hedberg 		error = -ENOMEM;
26206ead1bbcSJohan Hedberg 		goto err;
26216ead1bbcSJohan Hedberg 	}
26226ead1bbcSJohan Hedberg 
26230153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
26240153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
26250153e2ecSMarcel Holtmann 
2626bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
262733ca954dSDavid Herrmann 	if (error < 0)
262854506918SJohan Hedberg 		goto err_wqueue;
26291da177e4SLinus Torvalds 
26306d5d2ee6SHeiner Kallweit 	hci_leds_init(hdev);
26316d5d2ee6SHeiner Kallweit 
2632611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2633a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2634a8c5fb1aSGustavo Padovan 				    hdev);
2635611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2636611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
2637611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
2638611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
2639611b30f7SMarcel Holtmann 		}
2640611b30f7SMarcel Holtmann 	}
2641611b30f7SMarcel Holtmann 
26425e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
2643a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
26445e130367SJohan Hedberg 
2645a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_SETUP);
2646a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_AUTO_OFF);
2647ce2be9acSAndrei Emeltchenko 
264856f87901SJohan Hedberg 	/* Assume BR/EDR support until proven otherwise (such as
264956f87901SJohan Hedberg 	 * through reading supported features during init.
265056f87901SJohan Hedberg 	 */
2651a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
2652ce2be9acSAndrei Emeltchenko 
2653fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
2654fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
2655fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
2656fcee3377SGustavo Padovan 
26574a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
26584a964404SMarcel Holtmann 	 * and should not be included in normal operation.
2659fee746b0SMarcel Holtmann 	 */
2660fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
2661a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
2662fee746b0SMarcel Holtmann 
2663fe92ee64SLuiz Augusto von Dentz 	/* Mark Remote Wakeup connection flag as supported if driver has wakeup
2664fe92ee64SLuiz Augusto von Dentz 	 * callback.
2665fe92ee64SLuiz Augusto von Dentz 	 */
2666fe92ee64SLuiz Augusto von Dentz 	if (hdev->wakeup)
2667e1cff700SLinus Torvalds 		hdev->conn_flags |= HCI_CONN_FLAG_REMOTE_WAKEUP;
2668fe92ee64SLuiz Augusto von Dentz 
266905fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_REG);
2670dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
26711da177e4SLinus Torvalds 
267291117864SDan Carpenter 	error = hci_register_suspend_notifier(hdev);
267391117864SDan Carpenter 	if (error)
26740d75da38SYang Yingliang 		BT_WARN("register suspend notifier failed error:%d\n", error);
26759952d90eSAbhishek Pandit-Subedi 
267619202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2677fbe96d6fSMarcel Holtmann 
2678e5e1e7fdSMiao-chen Chou 	idr_init(&hdev->adv_monitors_idr);
26795031ffccSMiao-chen Chou 	msft_register(hdev);
2680e5e1e7fdSMiao-chen Chou 
26811da177e4SLinus Torvalds 	return id;
2682f48fd9c8SMarcel Holtmann 
268333ca954dSDavid Herrmann err_wqueue:
26845a4bb6a8SWei Yongjun 	debugfs_remove_recursive(hdev->debugfs);
268533ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
26866ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
268733ca954dSDavid Herrmann err:
26880a8af30aSChristophe JAILLET 	ida_free(&hci_index_ida, hdev->id);
2689f48fd9c8SMarcel Holtmann 
269033ca954dSDavid Herrmann 	return error;
26911da177e4SLinus Torvalds }
26921da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
26931da177e4SLinus Torvalds 
26941da177e4SLinus Torvalds /* Unregister HCI device */
hci_unregister_dev(struct hci_dev * hdev)269559735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
26961da177e4SLinus Torvalds {
2697c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
26981da177e4SLinus Torvalds 
26991857c199SZhengping Jiang 	mutex_lock(&hdev->unregister_lock);
2700a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_UNREGISTER);
27011857c199SZhengping Jiang 	mutex_unlock(&hdev->unregister_lock);
270294324962SJohan Hovold 
2703f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
27041da177e4SLinus Torvalds 	list_del(&hdev->list);
2705f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
27061da177e4SLinus Torvalds 
2707e36bea6eSVasyl Vavrychuk 	cancel_work_sync(&hdev->power_on);
2708e36bea6eSVasyl Vavrychuk 
27096a98e383SMarcel Holtmann 	hci_cmd_sync_clear(hdev);
27106a98e383SMarcel Holtmann 
2711359ee4f8SAbhishek Pandit-Subedi 	hci_unregister_suspend_notifier(hdev);
27124e8c36c3SAbhishek Pandit-Subedi 
27134e8c36c3SAbhishek Pandit-Subedi 	hci_dev_do_close(hdev);
27149952d90eSAbhishek Pandit-Subedi 
2715ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2716d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_SETUP) &&
2717d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
271809fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2719744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
272009fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
272156e5cb86SJohan Hedberg 	}
2722ab81cbf9SJohan Hedberg 
27232e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
27242e58ef3eSJohan Hedberg 	 * pending list */
27252e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
27262e58ef3eSJohan Hedberg 
272705fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_UNREG);
27281da177e4SLinus Torvalds 
2729611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2730611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2731611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2732611b30f7SMarcel Holtmann 	}
2733611b30f7SMarcel Holtmann 
2734bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
2735e61fbee7SDavid S. Miller 	/* Actual cleanup is deferred until hci_release_dev(). */
2736e0448092STetsuo Handa 	hci_dev_put(hdev);
2737e0448092STetsuo Handa }
2738e0448092STetsuo Handa EXPORT_SYMBOL(hci_unregister_dev);
2739147e2d59SDave Young 
274058ce6d5bSTetsuo Handa /* Release HCI device */
hci_release_dev(struct hci_dev * hdev)274158ce6d5bSTetsuo Handa void hci_release_dev(struct hci_dev *hdev)
2742e0448092STetsuo Handa {
27430153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
27445177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
27455177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
27460153e2ecSMarcel Holtmann 
2747f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
27486ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2749f48fd9c8SMarcel Holtmann 
275009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
27513d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->reject_list);
27523d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->accept_list);
27532aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
275455ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2755b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
2756970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
27572763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
2758d2609b34SFlorian Grandel 	hci_adv_instances_clear(hdev);
2759e5e1e7fdSMiao-chen Chou 	hci_adv_monitors_clear(hdev);
27603d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
2761cfdb0c2dSAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
2762373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
276322078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
2764600a8749SAlain Michaud 	hci_blocked_keys_clear(hdev);
2765b938790eSLuiz Augusto von Dentz 	hci_codec_list_clear(&hdev->local_codecs);
2766a85a60e6SSungwoo Kim 	msft_release(hdev);
276709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2768e2e0cacbSJohan Hedberg 
276984cb0143SZiyang Xuan 	ida_destroy(&hdev->unset_handle_ida);
27700a8af30aSChristophe JAILLET 	ida_free(&hci_index_ida, hdev->id);
2771dd3b1dc3SLuiz Augusto von Dentz 	kfree_skb(hdev->sent_cmd);
27722af7aa66SLuiz Augusto von Dentz 	kfree_skb(hdev->req_skb);
2773dfe6d5c3SLuiz Augusto von Dentz 	kfree_skb(hdev->recv_event);
277458ce6d5bSTetsuo Handa 	kfree(hdev);
27751da177e4SLinus Torvalds }
277658ce6d5bSTetsuo Handa EXPORT_SYMBOL(hci_release_dev);
27771da177e4SLinus Torvalds 
hci_register_suspend_notifier(struct hci_dev * hdev)2778359ee4f8SAbhishek Pandit-Subedi int hci_register_suspend_notifier(struct hci_dev *hdev)
2779359ee4f8SAbhishek Pandit-Subedi {
2780359ee4f8SAbhishek Pandit-Subedi 	int ret = 0;
2781359ee4f8SAbhishek Pandit-Subedi 
2782b5ca3387SLuiz Augusto von Dentz 	if (!hdev->suspend_notifier.notifier_call &&
2783b5ca3387SLuiz Augusto von Dentz 	    !test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
2784359ee4f8SAbhishek Pandit-Subedi 		hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
2785359ee4f8SAbhishek Pandit-Subedi 		ret = register_pm_notifier(&hdev->suspend_notifier);
2786359ee4f8SAbhishek Pandit-Subedi 	}
2787359ee4f8SAbhishek Pandit-Subedi 
2788359ee4f8SAbhishek Pandit-Subedi 	return ret;
2789359ee4f8SAbhishek Pandit-Subedi }
2790359ee4f8SAbhishek Pandit-Subedi 
hci_unregister_suspend_notifier(struct hci_dev * hdev)2791359ee4f8SAbhishek Pandit-Subedi int hci_unregister_suspend_notifier(struct hci_dev *hdev)
2792359ee4f8SAbhishek Pandit-Subedi {
2793359ee4f8SAbhishek Pandit-Subedi 	int ret = 0;
2794359ee4f8SAbhishek Pandit-Subedi 
2795b5ca3387SLuiz Augusto von Dentz 	if (hdev->suspend_notifier.notifier_call) {
2796359ee4f8SAbhishek Pandit-Subedi 		ret = unregister_pm_notifier(&hdev->suspend_notifier);
2797b5ca3387SLuiz Augusto von Dentz 		if (!ret)
2798b5ca3387SLuiz Augusto von Dentz 			hdev->suspend_notifier.notifier_call = NULL;
2799b5ca3387SLuiz Augusto von Dentz 	}
2800359ee4f8SAbhishek Pandit-Subedi 
2801359ee4f8SAbhishek Pandit-Subedi 	return ret;
2802359ee4f8SAbhishek Pandit-Subedi }
2803359ee4f8SAbhishek Pandit-Subedi 
28040ce1229cSLuiz Augusto von Dentz /* Cancel ongoing command synchronously:
28050ce1229cSLuiz Augusto von Dentz  *
28060ce1229cSLuiz Augusto von Dentz  * - Cancel command timer
28070ce1229cSLuiz Augusto von Dentz  * - Reset command counter
28080ce1229cSLuiz Augusto von Dentz  * - Cancel command request
28090ce1229cSLuiz Augusto von Dentz  */
hci_cancel_cmd_sync(struct hci_dev * hdev,int err)28100ce1229cSLuiz Augusto von Dentz static void hci_cancel_cmd_sync(struct hci_dev *hdev, int err)
28110ce1229cSLuiz Augusto von Dentz {
28120ce1229cSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "err 0x%2.2x", err);
28130ce1229cSLuiz Augusto von Dentz 
28140ce1229cSLuiz Augusto von Dentz 	cancel_delayed_work_sync(&hdev->cmd_timer);
28150ce1229cSLuiz Augusto von Dentz 	cancel_delayed_work_sync(&hdev->ncmd_timer);
28160ce1229cSLuiz Augusto von Dentz 	atomic_set(&hdev->cmd_cnt, 1);
28170ce1229cSLuiz Augusto von Dentz 
28189ae3954dSLuiz Augusto von Dentz 	hci_cmd_sync_cancel_sync(hdev, err);
28190ce1229cSLuiz Augusto von Dentz }
28200ce1229cSLuiz Augusto von Dentz 
28211da177e4SLinus Torvalds /* Suspend HCI device */
hci_suspend_dev(struct hci_dev * hdev)28221da177e4SLinus Torvalds int hci_suspend_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 	/* Suspend 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 
2833182ee45dSLuiz Augusto von Dentz 	/* If powering down don't attempt to suspend */
2834182ee45dSLuiz Augusto von Dentz 	if (mgmt_powering_down(hdev))
2835182ee45dSLuiz Augusto von Dentz 		return 0;
2836e1b77d68SLuiz Augusto von Dentz 
2837f4198635SArchie Pusaka 	/* Cancel potentially blocking sync operation before suspend */
28389ae3954dSLuiz Augusto von Dentz 	hci_cancel_cmd_sync(hdev, EHOSTDOWN);
2839f4198635SArchie Pusaka 
2840182ee45dSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
2841182ee45dSLuiz Augusto von Dentz 	ret = hci_suspend_sync(hdev);
2842182ee45dSLuiz Augusto von Dentz 	hci_req_sync_unlock(hdev);
28434539ca67SLuiz Augusto von Dentz 
2844e1b77d68SLuiz Augusto von Dentz 	hci_clear_wake_reason(hdev);
2845182ee45dSLuiz Augusto von Dentz 	mgmt_suspending(hdev, hdev->suspend_state);
2846e1b77d68SLuiz Augusto von Dentz 
2847e1b77d68SLuiz Augusto von Dentz 	hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
2848e1b77d68SLuiz Augusto von Dentz 	return ret;
28491da177e4SLinus Torvalds }
28501da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
28511da177e4SLinus Torvalds 
28521da177e4SLinus Torvalds /* Resume HCI device */
hci_resume_dev(struct hci_dev * hdev)28531da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
28541da177e4SLinus Torvalds {
2855e1b77d68SLuiz Augusto von Dentz 	int ret;
2856e1b77d68SLuiz Augusto von Dentz 
2857e1b77d68SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
2858e1b77d68SLuiz Augusto von Dentz 
2859e1b77d68SLuiz Augusto von Dentz 	/* Resume should only act on when powered. */
2860e1b77d68SLuiz Augusto von Dentz 	if (!hdev_is_powered(hdev) ||
2861e1b77d68SLuiz Augusto von Dentz 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
28621da177e4SLinus Torvalds 		return 0;
2863e1b77d68SLuiz Augusto von Dentz 
2864e1b77d68SLuiz Augusto von Dentz 	/* If powering down don't attempt to resume */
2865e1b77d68SLuiz Augusto von Dentz 	if (mgmt_powering_down(hdev))
2866e1b77d68SLuiz Augusto von Dentz 		return 0;
2867e1b77d68SLuiz Augusto von Dentz 
2868182ee45dSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
2869182ee45dSLuiz Augusto von Dentz 	ret = hci_resume_sync(hdev);
2870182ee45dSLuiz Augusto von Dentz 	hci_req_sync_unlock(hdev);
2871e1b77d68SLuiz Augusto von Dentz 
2872e1b77d68SLuiz Augusto von Dentz 	mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr,
2873e1b77d68SLuiz Augusto von Dentz 		      hdev->wake_addr_type);
2874e1b77d68SLuiz Augusto von Dentz 
2875e1b77d68SLuiz Augusto von Dentz 	hci_sock_dev_event(hdev, HCI_DEV_RESUME);
2876e1b77d68SLuiz Augusto von Dentz 	return ret;
28771da177e4SLinus Torvalds }
28781da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
28791da177e4SLinus Torvalds 
288075e0569fSMarcel Holtmann /* Reset HCI device */
hci_reset_dev(struct hci_dev * hdev)288175e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
288275e0569fSMarcel Holtmann {
28831e4b6e91SColin Ian King 	static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
288475e0569fSMarcel Holtmann 	struct sk_buff *skb;
288575e0569fSMarcel Holtmann 
288675e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
288775e0569fSMarcel Holtmann 	if (!skb)
288875e0569fSMarcel Holtmann 		return -ENOMEM;
288975e0569fSMarcel Holtmann 
2890d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
289159ae1d12SJohannes Berg 	skb_put_data(skb, hw_err, 3);
289275e0569fSMarcel Holtmann 
2893de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Injecting HCI hardware error event");
2894de75cd0dSManish Mandlik 
289575e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
289675e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
289775e0569fSMarcel Holtmann }
289875e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
289975e0569fSMarcel Holtmann 
290076bca880SMarcel Holtmann /* Receive frame from HCI drivers */
hci_recv_frame(struct hci_dev * hdev,struct sk_buff * skb)2901e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
290276bca880SMarcel Holtmann {
290376bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
290476bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
290576bca880SMarcel Holtmann 		kfree_skb(skb);
290676bca880SMarcel Holtmann 		return -ENXIO;
290776bca880SMarcel Holtmann 	}
290876bca880SMarcel Holtmann 
2909876e7810SLuiz Augusto von Dentz 	switch (hci_skb_pkt_type(skb)) {
2910876e7810SLuiz Augusto von Dentz 	case HCI_EVENT_PKT:
2911876e7810SLuiz Augusto von Dentz 		break;
2912876e7810SLuiz Augusto von Dentz 	case HCI_ACLDATA_PKT:
2913876e7810SLuiz Augusto von Dentz 		/* Detect if ISO packet has been sent as ACL */
2914876e7810SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, ISO_LINK)) {
2915876e7810SLuiz Augusto von Dentz 			__u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle);
2916876e7810SLuiz Augusto von Dentz 			__u8 type;
2917876e7810SLuiz Augusto von Dentz 
2918876e7810SLuiz Augusto von Dentz 			type = hci_conn_lookup_type(hdev, hci_handle(handle));
2919876e7810SLuiz Augusto von Dentz 			if (type == ISO_LINK)
2920876e7810SLuiz Augusto von Dentz 				hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
2921876e7810SLuiz Augusto von Dentz 		}
2922876e7810SLuiz Augusto von Dentz 		break;
2923876e7810SLuiz Augusto von Dentz 	case HCI_SCODATA_PKT:
2924876e7810SLuiz Augusto von Dentz 		break;
2925876e7810SLuiz Augusto von Dentz 	case HCI_ISODATA_PKT:
2926876e7810SLuiz Augusto von Dentz 		break;
2927876e7810SLuiz Augusto von Dentz 	default:
2928fe806dceSMarcel Holtmann 		kfree_skb(skb);
2929fe806dceSMarcel Holtmann 		return -EINVAL;
2930fe806dceSMarcel Holtmann 	}
2931fe806dceSMarcel Holtmann 
2932d82603c6SJorrit Schippers 	/* Incoming skb */
293376bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
293476bca880SMarcel Holtmann 
293576bca880SMarcel Holtmann 	/* Time stamp */
293676bca880SMarcel Holtmann 	__net_timestamp(skb);
293776bca880SMarcel Holtmann 
293876bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2939b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2940c78ae283SMarcel Holtmann 
294176bca880SMarcel Holtmann 	return 0;
294276bca880SMarcel Holtmann }
294376bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
294476bca880SMarcel Holtmann 
2945e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */
hci_recv_diag(struct hci_dev * hdev,struct sk_buff * skb)2946e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
2947e875ff84SMarcel Holtmann {
2948581d6fd6SMarcel Holtmann 	/* Mark as diagnostic packet */
2949d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_DIAG_PKT;
2950581d6fd6SMarcel Holtmann 
2951e875ff84SMarcel Holtmann 	/* Time stamp */
2952e875ff84SMarcel Holtmann 	__net_timestamp(skb);
2953e875ff84SMarcel Holtmann 
2954581d6fd6SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2955581d6fd6SMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2956e875ff84SMarcel Holtmann 
2957e875ff84SMarcel Holtmann 	return 0;
2958e875ff84SMarcel Holtmann }
2959e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag);
2960e875ff84SMarcel Holtmann 
hci_set_hw_info(struct hci_dev * hdev,const char * fmt,...)29615177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...)
29625177a838SMarcel Holtmann {
29635177a838SMarcel Holtmann 	va_list vargs;
29645177a838SMarcel Holtmann 
29655177a838SMarcel Holtmann 	va_start(vargs, fmt);
29665177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
29675177a838SMarcel Holtmann 	hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
29685177a838SMarcel Holtmann 	va_end(vargs);
29695177a838SMarcel Holtmann }
29705177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info);
29715177a838SMarcel Holtmann 
hci_set_fw_info(struct hci_dev * hdev,const char * fmt,...)29725177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...)
29735177a838SMarcel Holtmann {
29745177a838SMarcel Holtmann 	va_list vargs;
29755177a838SMarcel Holtmann 
29765177a838SMarcel Holtmann 	va_start(vargs, fmt);
29775177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
29785177a838SMarcel Holtmann 	hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
29795177a838SMarcel Holtmann 	va_end(vargs);
29805177a838SMarcel Holtmann }
29815177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info);
29825177a838SMarcel Holtmann 
29831da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
29841da177e4SLinus Torvalds 
hci_register_cb(struct hci_cb * cb)29851da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
29861da177e4SLinus Torvalds {
29871da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
29881da177e4SLinus Torvalds 
2989fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
299000629e0fSJohan Hedberg 	list_add_tail(&cb->list, &hci_cb_list);
2991fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
29921da177e4SLinus Torvalds 
29931da177e4SLinus Torvalds 	return 0;
29941da177e4SLinus Torvalds }
29951da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
29961da177e4SLinus Torvalds 
hci_unregister_cb(struct hci_cb * cb)29971da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
29981da177e4SLinus Torvalds {
29991da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
30001da177e4SLinus Torvalds 
3001fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
30021da177e4SLinus Torvalds 	list_del(&cb->list);
3003fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
30041da177e4SLinus Torvalds 
30051da177e4SLinus Torvalds 	return 0;
30061da177e4SLinus Torvalds }
30071da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
30081da177e4SLinus Torvalds 
hci_send_frame(struct hci_dev * hdev,struct sk_buff * skb)30092250abadSBenjamin Berg static int hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
30101da177e4SLinus Torvalds {
3011cdc52faaSMarcel Holtmann 	int err;
3012cdc52faaSMarcel Holtmann 
3013d79f34e3SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb),
3014d79f34e3SMarcel Holtmann 	       skb->len);
30151da177e4SLinus Torvalds 
30161da177e4SLinus Torvalds 	/* Time stamp */
3017a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
30181da177e4SLinus Torvalds 
3019cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
3020cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
3021cd82e61cSMarcel Holtmann 
3022cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
3023cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
3024470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
30251da177e4SLinus Torvalds 	}
30261da177e4SLinus Torvalds 
30271da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
30281da177e4SLinus Torvalds 	skb_orphan(skb);
30291da177e4SLinus Torvalds 
303073d0d3c8SMarcel Holtmann 	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
303173d0d3c8SMarcel Holtmann 		kfree_skb(skb);
30322250abadSBenjamin Berg 		return -EINVAL;
303373d0d3c8SMarcel Holtmann 	}
303473d0d3c8SMarcel Holtmann 
3035cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
3036cdc52faaSMarcel Holtmann 	if (err < 0) {
30372064ee33SMarcel Holtmann 		bt_dev_err(hdev, "sending frame failed (%d)", err);
3038cdc52faaSMarcel Holtmann 		kfree_skb(skb);
30392250abadSBenjamin Berg 		return err;
3040cdc52faaSMarcel Holtmann 	}
30412250abadSBenjamin Berg 
30422250abadSBenjamin Berg 	return 0;
30431da177e4SLinus Torvalds }
30441da177e4SLinus Torvalds 
30451ca3a9d0SJohan Hedberg /* Send HCI command */
hci_send_cmd(struct hci_dev * hdev,__u16 opcode,__u32 plen,const void * param)304607dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
304707dc93ddSJohan Hedberg 		 const void *param)
30481ca3a9d0SJohan Hedberg {
30491ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
30501ca3a9d0SJohan Hedberg 
30511ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
30521ca3a9d0SJohan Hedberg 
30531ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
30541ca3a9d0SJohan Hedberg 	if (!skb) {
30552064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no memory for command");
30561ca3a9d0SJohan Hedberg 		return -ENOMEM;
30571ca3a9d0SJohan Hedberg 	}
30581ca3a9d0SJohan Hedberg 
305949c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
306011714b3dSJohan Hedberg 	 * single-command requests.
306111714b3dSJohan Hedberg 	 */
306244d27137SJohan Hedberg 	bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
306311714b3dSJohan Hedberg 
30641da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
3065c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
30661da177e4SLinus Torvalds 
30671da177e4SLinus Torvalds 	return 0;
30681da177e4SLinus Torvalds }
30691da177e4SLinus Torvalds 
__hci_cmd_send(struct hci_dev * hdev,u16 opcode,u32 plen,const void * param)3070d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
3071d6ee6ad7SLoic Poulain 		   const void *param)
3072d6ee6ad7SLoic Poulain {
3073d6ee6ad7SLoic Poulain 	struct sk_buff *skb;
3074d6ee6ad7SLoic Poulain 
3075d6ee6ad7SLoic Poulain 	if (hci_opcode_ogf(opcode) != 0x3f) {
3076d6ee6ad7SLoic Poulain 		/* A controller receiving a command shall respond with either
3077d6ee6ad7SLoic Poulain 		 * a Command Status Event or a Command Complete Event.
3078d6ee6ad7SLoic Poulain 		 * Therefore, all standard HCI commands must be sent via the
3079d6ee6ad7SLoic Poulain 		 * standard API, using hci_send_cmd or hci_cmd_sync helpers.
3080d6ee6ad7SLoic Poulain 		 * Some vendors do not comply with this rule for vendor-specific
3081d6ee6ad7SLoic Poulain 		 * commands and do not return any event. We want to support
3082d6ee6ad7SLoic Poulain 		 * unresponded commands for such cases only.
3083d6ee6ad7SLoic Poulain 		 */
3084d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "unresponded command not supported");
3085d6ee6ad7SLoic Poulain 		return -EINVAL;
3086d6ee6ad7SLoic Poulain 	}
3087d6ee6ad7SLoic Poulain 
3088d6ee6ad7SLoic Poulain 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
3089d6ee6ad7SLoic Poulain 	if (!skb) {
3090d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)",
3091d6ee6ad7SLoic Poulain 			   opcode);
3092d6ee6ad7SLoic Poulain 		return -ENOMEM;
3093d6ee6ad7SLoic Poulain 	}
3094d6ee6ad7SLoic Poulain 
3095d6ee6ad7SLoic Poulain 	hci_send_frame(hdev, skb);
3096d6ee6ad7SLoic Poulain 
3097d6ee6ad7SLoic Poulain 	return 0;
3098d6ee6ad7SLoic Poulain }
3099d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send);
3100d6ee6ad7SLoic Poulain 
31011da177e4SLinus Torvalds /* Get data from the previously sent command */
hci_cmd_data(struct sk_buff * skb,__u16 opcode)31022af7aa66SLuiz Augusto von Dentz static void *hci_cmd_data(struct sk_buff *skb, __u16 opcode)
31031da177e4SLinus Torvalds {
31041da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
31051da177e4SLinus Torvalds 
31062af7aa66SLuiz Augusto von Dentz 	if (!skb || skb->len < HCI_COMMAND_HDR_SIZE)
31071da177e4SLinus Torvalds 		return NULL;
31081da177e4SLinus Torvalds 
31092af7aa66SLuiz Augusto von Dentz 	hdr = (void *)skb->data;
31101da177e4SLinus Torvalds 
3111a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
31121da177e4SLinus Torvalds 		return NULL;
31131da177e4SLinus Torvalds 
31142af7aa66SLuiz Augusto von Dentz 	return skb->data + HCI_COMMAND_HDR_SIZE;
31152af7aa66SLuiz Augusto von Dentz }
31161da177e4SLinus Torvalds 
31172af7aa66SLuiz Augusto von Dentz /* Get data from the previously sent command */
hci_sent_cmd_data(struct hci_dev * hdev,__u16 opcode)31182af7aa66SLuiz Augusto von Dentz void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
31192af7aa66SLuiz Augusto von Dentz {
31202af7aa66SLuiz Augusto von Dentz 	void *data;
31212af7aa66SLuiz Augusto von Dentz 
31222af7aa66SLuiz Augusto von Dentz 	/* Check if opcode matches last sent command */
31232af7aa66SLuiz Augusto von Dentz 	data = hci_cmd_data(hdev->sent_cmd, opcode);
31242af7aa66SLuiz Augusto von Dentz 	if (!data)
31252af7aa66SLuiz Augusto von Dentz 		/* Check if opcode matches last request */
31262af7aa66SLuiz Augusto von Dentz 		data = hci_cmd_data(hdev->req_skb, opcode);
31272af7aa66SLuiz Augusto von Dentz 
31282af7aa66SLuiz Augusto von Dentz 	return data;
31291da177e4SLinus Torvalds }
31301da177e4SLinus Torvalds 
3131dfe6d5c3SLuiz Augusto von Dentz /* Get data from last received event */
hci_recv_event_data(struct hci_dev * hdev,__u8 event)3132dfe6d5c3SLuiz Augusto von Dentz void *hci_recv_event_data(struct hci_dev *hdev, __u8 event)
3133dfe6d5c3SLuiz Augusto von Dentz {
3134dfe6d5c3SLuiz Augusto von Dentz 	struct hci_event_hdr *hdr;
3135dfe6d5c3SLuiz Augusto von Dentz 	int offset;
3136dfe6d5c3SLuiz Augusto von Dentz 
3137dfe6d5c3SLuiz Augusto von Dentz 	if (!hdev->recv_event)
3138dfe6d5c3SLuiz Augusto von Dentz 		return NULL;
3139dfe6d5c3SLuiz Augusto von Dentz 
3140dfe6d5c3SLuiz Augusto von Dentz 	hdr = (void *)hdev->recv_event->data;
3141dfe6d5c3SLuiz Augusto von Dentz 	offset = sizeof(*hdr);
3142dfe6d5c3SLuiz Augusto von Dentz 
3143dfe6d5c3SLuiz Augusto von Dentz 	if (hdr->evt != event) {
3144dfe6d5c3SLuiz Augusto von Dentz 		/* In case of LE metaevent check the subevent match */
3145dfe6d5c3SLuiz Augusto von Dentz 		if (hdr->evt == HCI_EV_LE_META) {
3146dfe6d5c3SLuiz Augusto von Dentz 			struct hci_ev_le_meta *ev;
3147dfe6d5c3SLuiz Augusto von Dentz 
3148dfe6d5c3SLuiz Augusto von Dentz 			ev = (void *)hdev->recv_event->data + offset;
3149dfe6d5c3SLuiz Augusto von Dentz 			offset += sizeof(*ev);
3150dfe6d5c3SLuiz Augusto von Dentz 			if (ev->subevent == event)
3151dfe6d5c3SLuiz Augusto von Dentz 				goto found;
3152dfe6d5c3SLuiz Augusto von Dentz 		}
3153dfe6d5c3SLuiz Augusto von Dentz 		return NULL;
3154dfe6d5c3SLuiz Augusto von Dentz 	}
3155dfe6d5c3SLuiz Augusto von Dentz 
3156dfe6d5c3SLuiz Augusto von Dentz found:
3157dfe6d5c3SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "event 0x%2.2x", event);
3158dfe6d5c3SLuiz Augusto von Dentz 
3159dfe6d5c3SLuiz Augusto von Dentz 	return hdev->recv_event->data + offset;
3160dfe6d5c3SLuiz Augusto von Dentz }
3161dfe6d5c3SLuiz Augusto von Dentz 
31621da177e4SLinus Torvalds /* Send ACL data */
hci_add_acl_hdr(struct sk_buff * skb,__u16 handle,__u16 flags)31631da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
31641da177e4SLinus Torvalds {
31651da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
31661da177e4SLinus Torvalds 	int len = skb->len;
31671da177e4SLinus Torvalds 
3168badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3169badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
31709c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
3171aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3172aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
31731da177e4SLinus Torvalds }
31741da177e4SLinus Torvalds 
hci_queue_acl(struct hci_chan * chan,struct sk_buff_head * queue,struct sk_buff * skb,__u16 flags)3175ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
317673d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
31771da177e4SLinus Torvalds {
3178ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
31791da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
31801da177e4SLinus Torvalds 	struct sk_buff *list;
31811da177e4SLinus Torvalds 
3182087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3183087bfd99SGustavo Padovan 	skb->data_len = 0;
3184087bfd99SGustavo Padovan 
3185d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3186204a6e54SAndrei Emeltchenko 
3187087bfd99SGustavo Padovan 	hci_add_acl_hdr(skb, conn->handle, flags);
3188087bfd99SGustavo Padovan 
318970f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
319070f23020SAndrei Emeltchenko 	if (!list) {
31911da177e4SLinus Torvalds 		/* Non fragmented */
31921da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
31931da177e4SLinus Torvalds 
319473d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
31951da177e4SLinus Torvalds 	} else {
31961da177e4SLinus Torvalds 		/* Fragmented */
31971da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
31981da177e4SLinus Torvalds 
31991da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
32001da177e4SLinus Torvalds 
32019cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
32029cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
32039cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
32049cfd5a23SJukka Rissanen 		 * deadlocks.
32059cfd5a23SJukka Rissanen 		 */
32069cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
32071da177e4SLinus Torvalds 
320873d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3209e702112fSAndrei Emeltchenko 
3210e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3211e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
32121da177e4SLinus Torvalds 		do {
32131da177e4SLinus Torvalds 			skb = list; list = list->next;
32141da177e4SLinus Torvalds 
3215d79f34e3SMarcel Holtmann 			hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3216e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
32171da177e4SLinus Torvalds 
32181da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
32191da177e4SLinus Torvalds 
322073d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
32211da177e4SLinus Torvalds 		} while (list);
32221da177e4SLinus Torvalds 
32239cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
32241da177e4SLinus Torvalds 	}
322573d80debSLuiz Augusto von Dentz }
322673d80debSLuiz Augusto von Dentz 
hci_send_acl(struct hci_chan * chan,struct sk_buff * skb,__u16 flags)322773d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
322873d80debSLuiz Augusto von Dentz {
3229ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
323073d80debSLuiz Augusto von Dentz 
3231f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
323273d80debSLuiz Augusto von Dentz 
3233ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
32341da177e4SLinus Torvalds 
32353eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
32361da177e4SLinus Torvalds }
32371da177e4SLinus Torvalds 
32381da177e4SLinus Torvalds /* Send SCO data */
hci_send_sco(struct hci_conn * conn,struct sk_buff * skb)32390d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
32401da177e4SLinus Torvalds {
32411da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
32421da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
32431da177e4SLinus Torvalds 
32441da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
32451da177e4SLinus Torvalds 
3246aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
32471da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
32481da177e4SLinus Torvalds 
3249badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3250badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
32519c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
32521da177e4SLinus Torvalds 
3253d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
3254c78ae283SMarcel Holtmann 
32551da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
32563eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
32571da177e4SLinus Torvalds }
32581da177e4SLinus Torvalds 
325926afbd82SLuiz Augusto von Dentz /* Send ISO data */
hci_add_iso_hdr(struct sk_buff * skb,__u16 handle,__u8 flags)326026afbd82SLuiz Augusto von Dentz static void hci_add_iso_hdr(struct sk_buff *skb, __u16 handle, __u8 flags)
326126afbd82SLuiz Augusto von Dentz {
326226afbd82SLuiz Augusto von Dentz 	struct hci_iso_hdr *hdr;
326326afbd82SLuiz Augusto von Dentz 	int len = skb->len;
326426afbd82SLuiz Augusto von Dentz 
326526afbd82SLuiz Augusto von Dentz 	skb_push(skb, HCI_ISO_HDR_SIZE);
326626afbd82SLuiz Augusto von Dentz 	skb_reset_transport_header(skb);
326726afbd82SLuiz Augusto von Dentz 	hdr = (struct hci_iso_hdr *)skb_transport_header(skb);
326826afbd82SLuiz Augusto von Dentz 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
326926afbd82SLuiz Augusto von Dentz 	hdr->dlen   = cpu_to_le16(len);
327026afbd82SLuiz Augusto von Dentz }
327126afbd82SLuiz Augusto von Dentz 
hci_queue_iso(struct hci_conn * conn,struct sk_buff_head * queue,struct sk_buff * skb)327226afbd82SLuiz Augusto von Dentz static void hci_queue_iso(struct hci_conn *conn, struct sk_buff_head *queue,
327326afbd82SLuiz Augusto von Dentz 			  struct sk_buff *skb)
327426afbd82SLuiz Augusto von Dentz {
327526afbd82SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
327626afbd82SLuiz Augusto von Dentz 	struct sk_buff *list;
327726afbd82SLuiz Augusto von Dentz 	__u16 flags;
327826afbd82SLuiz Augusto von Dentz 
327926afbd82SLuiz Augusto von Dentz 	skb->len = skb_headlen(skb);
328026afbd82SLuiz Augusto von Dentz 	skb->data_len = 0;
328126afbd82SLuiz Augusto von Dentz 
328226afbd82SLuiz Augusto von Dentz 	hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
328326afbd82SLuiz Augusto von Dentz 
328426afbd82SLuiz Augusto von Dentz 	list = skb_shinfo(skb)->frag_list;
328526afbd82SLuiz Augusto von Dentz 
328626afbd82SLuiz Augusto von Dentz 	flags = hci_iso_flags_pack(list ? ISO_START : ISO_SINGLE, 0x00);
328726afbd82SLuiz Augusto von Dentz 	hci_add_iso_hdr(skb, conn->handle, flags);
328826afbd82SLuiz Augusto von Dentz 
328926afbd82SLuiz Augusto von Dentz 	if (!list) {
329026afbd82SLuiz Augusto von Dentz 		/* Non fragmented */
329126afbd82SLuiz Augusto von Dentz 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
329226afbd82SLuiz Augusto von Dentz 
329326afbd82SLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
329426afbd82SLuiz Augusto von Dentz 	} else {
329526afbd82SLuiz Augusto von Dentz 		/* Fragmented */
329626afbd82SLuiz Augusto von Dentz 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
329726afbd82SLuiz Augusto von Dentz 
329826afbd82SLuiz Augusto von Dentz 		skb_shinfo(skb)->frag_list = NULL;
329926afbd82SLuiz Augusto von Dentz 
330026afbd82SLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
330126afbd82SLuiz Augusto von Dentz 
330226afbd82SLuiz Augusto von Dentz 		do {
330326afbd82SLuiz Augusto von Dentz 			skb = list; list = list->next;
330426afbd82SLuiz Augusto von Dentz 
330526afbd82SLuiz Augusto von Dentz 			hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
330626afbd82SLuiz Augusto von Dentz 			flags = hci_iso_flags_pack(list ? ISO_CONT : ISO_END,
330726afbd82SLuiz Augusto von Dentz 						   0x00);
330826afbd82SLuiz Augusto von Dentz 			hci_add_iso_hdr(skb, conn->handle, flags);
330926afbd82SLuiz Augusto von Dentz 
331026afbd82SLuiz Augusto von Dentz 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
331126afbd82SLuiz Augusto von Dentz 
331226afbd82SLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
331326afbd82SLuiz Augusto von Dentz 		} while (list);
331426afbd82SLuiz Augusto von Dentz 	}
331526afbd82SLuiz Augusto von Dentz }
331626afbd82SLuiz Augusto von Dentz 
hci_send_iso(struct hci_conn * conn,struct sk_buff * skb)331726afbd82SLuiz Augusto von Dentz void hci_send_iso(struct hci_conn *conn, struct sk_buff *skb)
331826afbd82SLuiz Augusto von Dentz {
331926afbd82SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
332026afbd82SLuiz Augusto von Dentz 
332126afbd82SLuiz Augusto von Dentz 	BT_DBG("%s len %d", hdev->name, skb->len);
332226afbd82SLuiz Augusto von Dentz 
332326afbd82SLuiz Augusto von Dentz 	hci_queue_iso(conn, &conn->data_q, skb);
332426afbd82SLuiz Augusto von Dentz 
332526afbd82SLuiz Augusto von Dentz 	queue_work(hdev->workqueue, &hdev->tx_work);
332626afbd82SLuiz Augusto von Dentz }
332726afbd82SLuiz Augusto von Dentz 
33281da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
33291da177e4SLinus Torvalds 
33301da177e4SLinus Torvalds /* HCI Connection scheduler */
hci_quote_sent(struct hci_conn * conn,int num,int * quote)333126afbd82SLuiz Augusto von Dentz static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote)
333226afbd82SLuiz Augusto von Dentz {
333326afbd82SLuiz Augusto von Dentz 	struct hci_dev *hdev;
333426afbd82SLuiz Augusto von Dentz 	int cnt, q;
333526afbd82SLuiz Augusto von Dentz 
333626afbd82SLuiz Augusto von Dentz 	if (!conn) {
333726afbd82SLuiz Augusto von Dentz 		*quote = 0;
333826afbd82SLuiz Augusto von Dentz 		return;
333926afbd82SLuiz Augusto von Dentz 	}
334026afbd82SLuiz Augusto von Dentz 
334126afbd82SLuiz Augusto von Dentz 	hdev = conn->hdev;
334226afbd82SLuiz Augusto von Dentz 
334326afbd82SLuiz Augusto von Dentz 	switch (conn->type) {
334426afbd82SLuiz Augusto von Dentz 	case ACL_LINK:
334526afbd82SLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
334626afbd82SLuiz Augusto von Dentz 		break;
334726afbd82SLuiz Augusto von Dentz 	case SCO_LINK:
334826afbd82SLuiz Augusto von Dentz 	case ESCO_LINK:
334926afbd82SLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
335026afbd82SLuiz Augusto von Dentz 		break;
335126afbd82SLuiz Augusto von Dentz 	case LE_LINK:
335226afbd82SLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
335326afbd82SLuiz Augusto von Dentz 		break;
335426afbd82SLuiz Augusto von Dentz 	case ISO_LINK:
335526afbd82SLuiz Augusto von Dentz 		cnt = hdev->iso_mtu ? hdev->iso_cnt :
335626afbd82SLuiz Augusto von Dentz 			hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
335726afbd82SLuiz Augusto von Dentz 		break;
335826afbd82SLuiz Augusto von Dentz 	default:
335926afbd82SLuiz Augusto von Dentz 		cnt = 0;
336026afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev, "unknown link type %d", conn->type);
336126afbd82SLuiz Augusto von Dentz 	}
336226afbd82SLuiz Augusto von Dentz 
336326afbd82SLuiz Augusto von Dentz 	q = cnt / num;
336426afbd82SLuiz Augusto von Dentz 	*quote = q ? q : 1;
336526afbd82SLuiz Augusto von Dentz }
336626afbd82SLuiz Augusto von Dentz 
hci_low_sent(struct hci_dev * hdev,__u8 type,int * quote)33676039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3368a8c5fb1aSGustavo Padovan 				     int *quote)
33691da177e4SLinus Torvalds {
33701da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
33718035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
3372abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
33731da177e4SLinus Torvalds 
33741da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
33751da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
3376bf4c6325SGustavo F. Padovan 
3377bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3378bf4c6325SGustavo F. Padovan 
3379bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3380769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
33811da177e4SLinus Torvalds 			continue;
3382769be974SMarcel Holtmann 
3383769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3384769be974SMarcel Holtmann 			continue;
3385769be974SMarcel Holtmann 
33861da177e4SLinus Torvalds 		num++;
33871da177e4SLinus Torvalds 
33881da177e4SLinus Torvalds 		if (c->sent < min) {
33891da177e4SLinus Torvalds 			min  = c->sent;
33901da177e4SLinus Torvalds 			conn = c;
33911da177e4SLinus Torvalds 		}
339252087a79SLuiz Augusto von Dentz 
339352087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
339452087a79SLuiz Augusto von Dentz 			break;
33951da177e4SLinus Torvalds 	}
33961da177e4SLinus Torvalds 
3397bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3398bf4c6325SGustavo F. Padovan 
339926afbd82SLuiz Augusto von Dentz 	hci_quote_sent(conn, num, quote);
34001da177e4SLinus Torvalds 
34011da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
34021da177e4SLinus Torvalds 	return conn;
34031da177e4SLinus Torvalds }
34041da177e4SLinus Torvalds 
hci_link_tx_to(struct hci_dev * hdev,__u8 type)34056039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
34061da177e4SLinus Torvalds {
34071da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
34081da177e4SLinus Torvalds 	struct hci_conn *c;
34091da177e4SLinus Torvalds 
34102064ee33SMarcel Holtmann 	bt_dev_err(hdev, "link tx timeout");
34111da177e4SLinus Torvalds 
3412bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3413bf4c6325SGustavo F. Padovan 
34141da177e4SLinus Torvalds 	/* Kill stalled connections */
3415bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3416bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
34172064ee33SMarcel Holtmann 			bt_dev_err(hdev, "killing stalled connection %pMR",
34182064ee33SMarcel Holtmann 				   &c->dst);
3419c7eaf80bSYing Hsu 			/* hci_disconnect might sleep, so, we have to release
3420c7eaf80bSYing Hsu 			 * the RCU read lock before calling it.
3421c7eaf80bSYing Hsu 			 */
3422c7eaf80bSYing Hsu 			rcu_read_unlock();
3423bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
3424c7eaf80bSYing Hsu 			rcu_read_lock();
34251da177e4SLinus Torvalds 		}
34261da177e4SLinus Torvalds 	}
3427bf4c6325SGustavo F. Padovan 
3428bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
34291da177e4SLinus Torvalds }
34301da177e4SLinus Torvalds 
hci_chan_sent(struct hci_dev * hdev,__u8 type,int * quote)34316039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
343273d80debSLuiz Augusto von Dentz 				      int *quote)
343373d80debSLuiz Augusto von Dentz {
343473d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
343573d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3436abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
343773d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
343826afbd82SLuiz Augusto von Dentz 	int conn_num = 0;
343973d80debSLuiz Augusto von Dentz 
344073d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
344173d80debSLuiz Augusto von Dentz 
3442bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3443bf4c6325SGustavo F. Padovan 
3444bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
344573d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
344673d80debSLuiz Augusto von Dentz 
344773d80debSLuiz Augusto von Dentz 		if (conn->type != type)
344873d80debSLuiz Augusto von Dentz 			continue;
344973d80debSLuiz Augusto von Dentz 
345073d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
345173d80debSLuiz Augusto von Dentz 			continue;
345273d80debSLuiz Augusto von Dentz 
345373d80debSLuiz Augusto von Dentz 		conn_num++;
345473d80debSLuiz Augusto von Dentz 
34558192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
345673d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
345773d80debSLuiz Augusto von Dentz 
345873d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
345973d80debSLuiz Augusto von Dentz 				continue;
346073d80debSLuiz Augusto von Dentz 
346173d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
346273d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
346373d80debSLuiz Augusto von Dentz 				continue;
346473d80debSLuiz Augusto von Dentz 
346573d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
346673d80debSLuiz Augusto von Dentz 				num = 0;
346773d80debSLuiz Augusto von Dentz 				min = ~0;
346873d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
346973d80debSLuiz Augusto von Dentz 			}
347073d80debSLuiz Augusto von Dentz 
347173d80debSLuiz Augusto von Dentz 			num++;
347273d80debSLuiz Augusto von Dentz 
347373d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
347473d80debSLuiz Augusto von Dentz 				min  = conn->sent;
347573d80debSLuiz Augusto von Dentz 				chan = tmp;
347673d80debSLuiz Augusto von Dentz 			}
347773d80debSLuiz Augusto von Dentz 		}
347873d80debSLuiz Augusto von Dentz 
347973d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
348073d80debSLuiz Augusto von Dentz 			break;
348173d80debSLuiz Augusto von Dentz 	}
348273d80debSLuiz Augusto von Dentz 
3483bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3484bf4c6325SGustavo F. Padovan 
348573d80debSLuiz Augusto von Dentz 	if (!chan)
348673d80debSLuiz Augusto von Dentz 		return NULL;
348773d80debSLuiz Augusto von Dentz 
348826afbd82SLuiz Augusto von Dentz 	hci_quote_sent(chan->conn, num, quote);
348973d80debSLuiz Augusto von Dentz 
349073d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
349173d80debSLuiz Augusto von Dentz 	return chan;
349273d80debSLuiz Augusto von Dentz }
349373d80debSLuiz Augusto von Dentz 
hci_prio_recalculate(struct hci_dev * hdev,__u8 type)349402b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
349502b20f0bSLuiz Augusto von Dentz {
349602b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
349702b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
349802b20f0bSLuiz Augusto von Dentz 	int num = 0;
349902b20f0bSLuiz Augusto von Dentz 
350002b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
350102b20f0bSLuiz Augusto von Dentz 
3502bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3503bf4c6325SGustavo F. Padovan 
3504bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
350502b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
350602b20f0bSLuiz Augusto von Dentz 
350702b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
350802b20f0bSLuiz Augusto von Dentz 			continue;
350902b20f0bSLuiz Augusto von Dentz 
351002b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
351102b20f0bSLuiz Augusto von Dentz 			continue;
351202b20f0bSLuiz Augusto von Dentz 
351302b20f0bSLuiz Augusto von Dentz 		num++;
351402b20f0bSLuiz Augusto von Dentz 
35158192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
351602b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
351702b20f0bSLuiz Augusto von Dentz 
351802b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
351902b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
352002b20f0bSLuiz Augusto von Dentz 				continue;
352102b20f0bSLuiz Augusto von Dentz 			}
352202b20f0bSLuiz Augusto von Dentz 
352302b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
352402b20f0bSLuiz Augusto von Dentz 				continue;
352502b20f0bSLuiz Augusto von Dentz 
352602b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
352702b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
352802b20f0bSLuiz Augusto von Dentz 				continue;
352902b20f0bSLuiz Augusto von Dentz 
353002b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
353102b20f0bSLuiz Augusto von Dentz 
353202b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
353302b20f0bSLuiz Augusto von Dentz 			       skb->priority);
353402b20f0bSLuiz Augusto von Dentz 		}
353502b20f0bSLuiz Augusto von Dentz 
353602b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
353702b20f0bSLuiz Augusto von Dentz 			break;
353802b20f0bSLuiz Augusto von Dentz 	}
3539bf4c6325SGustavo F. Padovan 
3540bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3541bf4c6325SGustavo F. Padovan 
354202b20f0bSLuiz Augusto von Dentz }
354302b20f0bSLuiz Augusto von Dentz 
__check_timeout(struct hci_dev * hdev,unsigned int cnt,u8 type)3544116523c8SLuiz Augusto von Dentz static void __check_timeout(struct hci_dev *hdev, unsigned int cnt, u8 type)
35451da177e4SLinus Torvalds {
3546116523c8SLuiz Augusto von Dentz 	unsigned long last_tx;
3547116523c8SLuiz Augusto von Dentz 
3548116523c8SLuiz Augusto von Dentz 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
3549116523c8SLuiz Augusto von Dentz 		return;
3550116523c8SLuiz Augusto von Dentz 
3551116523c8SLuiz Augusto von Dentz 	switch (type) {
3552116523c8SLuiz Augusto von Dentz 	case LE_LINK:
3553116523c8SLuiz Augusto von Dentz 		last_tx = hdev->le_last_tx;
3554116523c8SLuiz Augusto von Dentz 		break;
3555116523c8SLuiz Augusto von Dentz 	default:
3556116523c8SLuiz Augusto von Dentz 		last_tx = hdev->acl_last_tx;
3557116523c8SLuiz Augusto von Dentz 		break;
35581da177e4SLinus Torvalds 	}
3559116523c8SLuiz Augusto von Dentz 
3560116523c8SLuiz Augusto von Dentz 	/* tx timeout must be longer than maximum link supervision timeout
3561116523c8SLuiz Augusto von Dentz 	 * (40.9 seconds)
3562116523c8SLuiz Augusto von Dentz 	 */
3563116523c8SLuiz Augusto von Dentz 	if (!cnt && time_after(jiffies, last_tx + HCI_ACL_TX_TIMEOUT))
3564116523c8SLuiz Augusto von Dentz 		hci_link_tx_to(hdev, type);
356563d2bc1bSAndrei Emeltchenko }
35661da177e4SLinus Torvalds 
35677fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */
hci_sched_sco(struct hci_dev * hdev)35687fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev)
35697fedd3bbSAbhishek Pandit-Subedi {
35707fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
35717fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
35727fedd3bbSAbhishek Pandit-Subedi 	int quote;
35737fedd3bbSAbhishek Pandit-Subedi 
35747fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
35757fedd3bbSAbhishek Pandit-Subedi 
35767fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, SCO_LINK))
35777fedd3bbSAbhishek Pandit-Subedi 		return;
35787fedd3bbSAbhishek Pandit-Subedi 
35797fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
35807fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
35817fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
35827fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
35837fedd3bbSAbhishek Pandit-Subedi 
35847fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
35857fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
35867fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
35877fedd3bbSAbhishek Pandit-Subedi 		}
35887fedd3bbSAbhishek Pandit-Subedi 	}
35897fedd3bbSAbhishek Pandit-Subedi }
35907fedd3bbSAbhishek Pandit-Subedi 
hci_sched_esco(struct hci_dev * hdev)35917fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev)
35927fedd3bbSAbhishek Pandit-Subedi {
35937fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
35947fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
35957fedd3bbSAbhishek Pandit-Subedi 	int quote;
35967fedd3bbSAbhishek Pandit-Subedi 
35977fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
35987fedd3bbSAbhishek Pandit-Subedi 
35997fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, ESCO_LINK))
36007fedd3bbSAbhishek Pandit-Subedi 		return;
36017fedd3bbSAbhishek Pandit-Subedi 
36027fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
36037fedd3bbSAbhishek Pandit-Subedi 						     &quote))) {
36047fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
36057fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
36067fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
36077fedd3bbSAbhishek Pandit-Subedi 
36087fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
36097fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
36107fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
36117fedd3bbSAbhishek Pandit-Subedi 		}
36127fedd3bbSAbhishek Pandit-Subedi 	}
36137fedd3bbSAbhishek Pandit-Subedi }
36147fedd3bbSAbhishek Pandit-Subedi 
hci_sched_acl_pkt(struct hci_dev * hdev)36156039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
361663d2bc1bSAndrei Emeltchenko {
361763d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
361863d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
361963d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
362063d2bc1bSAndrei Emeltchenko 	int quote;
362163d2bc1bSAndrei Emeltchenko 
3622116523c8SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt, ACL_LINK);
362304837f64SMarcel Holtmann 
362473d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
362573d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3626ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3627ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
362873d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
362973d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
363073d80debSLuiz Augusto von Dentz 
3631ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3632ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3633ec1cce24SLuiz Augusto von Dentz 				break;
3634ec1cce24SLuiz Augusto von Dentz 
3635ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3636ec1cce24SLuiz Augusto von Dentz 
363773d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
363873d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
363904837f64SMarcel Holtmann 
364057d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
36411da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
36421da177e4SLinus Torvalds 
36431da177e4SLinus Torvalds 			hdev->acl_cnt--;
364473d80debSLuiz Augusto von Dentz 			chan->sent++;
364573d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
36467fedd3bbSAbhishek Pandit-Subedi 
36477fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
36487fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
36497fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
36501da177e4SLinus Torvalds 		}
36511da177e4SLinus Torvalds 	}
365202b20f0bSLuiz Augusto von Dentz 
365302b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
365402b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
36551da177e4SLinus Torvalds }
36561da177e4SLinus Torvalds 
hci_sched_acl(struct hci_dev * hdev)36576039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3658b71d385aSAndrei Emeltchenko {
3659b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3660b71d385aSAndrei Emeltchenko 
3661bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
36625af2e235SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ACL_LINK))
3663bd1eb66bSAndrei Emeltchenko 		return;
3664bd1eb66bSAndrei Emeltchenko 
3665b71d385aSAndrei Emeltchenko 	hci_sched_acl_pkt(hdev);
3666b71d385aSAndrei Emeltchenko }
3667b71d385aSAndrei Emeltchenko 
hci_sched_le(struct hci_dev * hdev)36686039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
36696ed58ec5SVille Tervo {
367073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
36716ed58ec5SVille Tervo 	struct sk_buff *skb;
367202b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
36736ed58ec5SVille Tervo 
36746ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
36756ed58ec5SVille Tervo 
367652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
367752087a79SLuiz Augusto von Dentz 		return;
367852087a79SLuiz Augusto von Dentz 
36796ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
36801b1d29e5SLuiz Augusto von Dentz 
3681116523c8SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt, LE_LINK);
36821b1d29e5SLuiz Augusto von Dentz 
368302b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
368473d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3685ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3686ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
368773d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
368873d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
36896ed58ec5SVille Tervo 
3690ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3691ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3692ec1cce24SLuiz Augusto von Dentz 				break;
3693ec1cce24SLuiz Augusto von Dentz 
3694ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3695ec1cce24SLuiz Augusto von Dentz 
369657d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
36976ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
36986ed58ec5SVille Tervo 
36996ed58ec5SVille Tervo 			cnt--;
370073d80debSLuiz Augusto von Dentz 			chan->sent++;
370173d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
37027fedd3bbSAbhishek Pandit-Subedi 
37037fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
37047fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
37057fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
37066ed58ec5SVille Tervo 		}
37076ed58ec5SVille Tervo 	}
370873d80debSLuiz Augusto von Dentz 
37096ed58ec5SVille Tervo 	if (hdev->le_pkts)
37106ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
37116ed58ec5SVille Tervo 	else
37126ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
371302b20f0bSLuiz Augusto von Dentz 
371402b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
371502b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
37166ed58ec5SVille Tervo }
37176ed58ec5SVille Tervo 
371826afbd82SLuiz Augusto von Dentz /* Schedule CIS */
hci_sched_iso(struct hci_dev * hdev)371926afbd82SLuiz Augusto von Dentz static void hci_sched_iso(struct hci_dev *hdev)
372026afbd82SLuiz Augusto von Dentz {
372126afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
372226afbd82SLuiz Augusto von Dentz 	struct sk_buff *skb;
372326afbd82SLuiz Augusto von Dentz 	int quote, *cnt;
372426afbd82SLuiz Augusto von Dentz 
372526afbd82SLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
372626afbd82SLuiz Augusto von Dentz 
372726afbd82SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ISO_LINK))
372826afbd82SLuiz Augusto von Dentz 		return;
372926afbd82SLuiz Augusto von Dentz 
373026afbd82SLuiz Augusto von Dentz 	cnt = hdev->iso_pkts ? &hdev->iso_cnt :
373126afbd82SLuiz Augusto von Dentz 		hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt;
373226afbd82SLuiz Augusto von Dentz 	while (*cnt && (conn = hci_low_sent(hdev, ISO_LINK, &quote))) {
373326afbd82SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
373426afbd82SLuiz Augusto von Dentz 			BT_DBG("skb %p len %d", skb, skb->len);
373526afbd82SLuiz Augusto von Dentz 			hci_send_frame(hdev, skb);
373626afbd82SLuiz Augusto von Dentz 
373726afbd82SLuiz Augusto von Dentz 			conn->sent++;
373826afbd82SLuiz Augusto von Dentz 			if (conn->sent == ~0)
373926afbd82SLuiz Augusto von Dentz 				conn->sent = 0;
374026afbd82SLuiz Augusto von Dentz 			(*cnt)--;
374126afbd82SLuiz Augusto von Dentz 		}
374226afbd82SLuiz Augusto von Dentz 	}
374326afbd82SLuiz Augusto von Dentz }
374426afbd82SLuiz Augusto von Dentz 
hci_tx_work(struct work_struct * work)37453eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
37461da177e4SLinus Torvalds {
37473eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
37481da177e4SLinus Torvalds 	struct sk_buff *skb;
37491da177e4SLinus Torvalds 
375026afbd82SLuiz Augusto von Dentz 	BT_DBG("%s acl %d sco %d le %d iso %d", hdev->name, hdev->acl_cnt,
375126afbd82SLuiz Augusto von Dentz 	       hdev->sco_cnt, hdev->le_cnt, hdev->iso_cnt);
37521da177e4SLinus Torvalds 
3753d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
37541da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
37551da177e4SLinus Torvalds 		hci_sched_sco(hdev);
3756b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
375726afbd82SLuiz Augusto von Dentz 		hci_sched_iso(hdev);
37587fedd3bbSAbhishek Pandit-Subedi 		hci_sched_acl(hdev);
37596ed58ec5SVille Tervo 		hci_sched_le(hdev);
376052de599eSMarcel Holtmann 	}
37616ed58ec5SVille Tervo 
37621da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
37631da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
376457d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
37651da177e4SLinus Torvalds }
37661da177e4SLinus Torvalds 
376725985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
37681da177e4SLinus Torvalds 
37691da177e4SLinus Torvalds /* ACL data packet */
hci_acldata_packet(struct hci_dev * hdev,struct sk_buff * skb)37706039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
37711da177e4SLinus Torvalds {
37721da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
37731da177e4SLinus Torvalds 	struct hci_conn *conn;
37741da177e4SLinus Torvalds 	__u16 handle, flags;
37751da177e4SLinus Torvalds 
37761da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
37771da177e4SLinus Torvalds 
37781da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
37791da177e4SLinus Torvalds 	flags  = hci_flags(handle);
37801da177e4SLinus Torvalds 	handle = hci_handle(handle);
37811da177e4SLinus Torvalds 
3782f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3783a8c5fb1aSGustavo Padovan 	       handle, flags);
37841da177e4SLinus Torvalds 
37851da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
37861da177e4SLinus Torvalds 
37871da177e4SLinus Torvalds 	hci_dev_lock(hdev);
37881da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
37891da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
37901da177e4SLinus Torvalds 
37911da177e4SLinus Torvalds 	if (conn) {
379265983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
379304837f64SMarcel Holtmann 
37941da177e4SLinus Torvalds 		/* Send to upper protocol */
3795686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
37961da177e4SLinus Torvalds 		return;
37971da177e4SLinus Torvalds 	} else {
37982064ee33SMarcel Holtmann 		bt_dev_err(hdev, "ACL packet for unknown connection handle %d",
37992064ee33SMarcel Holtmann 			   handle);
38001da177e4SLinus Torvalds 	}
38011da177e4SLinus Torvalds 
38021da177e4SLinus Torvalds 	kfree_skb(skb);
38031da177e4SLinus Torvalds }
38041da177e4SLinus Torvalds 
38051da177e4SLinus Torvalds /* SCO data packet */
hci_scodata_packet(struct hci_dev * hdev,struct sk_buff * skb)38066039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
38071da177e4SLinus Torvalds {
38081da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
38091da177e4SLinus Torvalds 	struct hci_conn *conn;
3810debdedf2SMarcel Holtmann 	__u16 handle, flags;
38111da177e4SLinus Torvalds 
38121da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
38131da177e4SLinus Torvalds 
38141da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
3815debdedf2SMarcel Holtmann 	flags  = hci_flags(handle);
3816debdedf2SMarcel Holtmann 	handle = hci_handle(handle);
38171da177e4SLinus Torvalds 
3818debdedf2SMarcel Holtmann 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3819debdedf2SMarcel Holtmann 	       handle, flags);
38201da177e4SLinus Torvalds 
38211da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
38221da177e4SLinus Torvalds 
38231da177e4SLinus Torvalds 	hci_dev_lock(hdev);
38241da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
38251da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
38261da177e4SLinus Torvalds 
38271da177e4SLinus Torvalds 	if (conn) {
38281da177e4SLinus Torvalds 		/* Send to upper protocol */
38293f19ffb2SLuiz Augusto von Dentz 		hci_skb_pkt_status(skb) = flags & 0x03;
3830686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
38311da177e4SLinus Torvalds 		return;
38321da177e4SLinus Torvalds 	} else {
38332d4b37b6SLuiz Augusto von Dentz 		bt_dev_err_ratelimited(hdev, "SCO packet for unknown connection handle %d",
38342064ee33SMarcel Holtmann 				       handle);
38351da177e4SLinus Torvalds 	}
38361da177e4SLinus Torvalds 
38371da177e4SLinus Torvalds 	kfree_skb(skb);
38381da177e4SLinus Torvalds }
38391da177e4SLinus Torvalds 
hci_isodata_packet(struct hci_dev * hdev,struct sk_buff * skb)384026afbd82SLuiz Augusto von Dentz static void hci_isodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
384126afbd82SLuiz Augusto von Dentz {
384226afbd82SLuiz Augusto von Dentz 	struct hci_iso_hdr *hdr;
384326afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
384426afbd82SLuiz Augusto von Dentz 	__u16 handle, flags;
384526afbd82SLuiz Augusto von Dentz 
384626afbd82SLuiz Augusto von Dentz 	hdr = skb_pull_data(skb, sizeof(*hdr));
384726afbd82SLuiz Augusto von Dentz 	if (!hdr) {
384826afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev, "ISO packet too small");
384926afbd82SLuiz Augusto von Dentz 		goto drop;
385026afbd82SLuiz Augusto von Dentz 	}
385126afbd82SLuiz Augusto von Dentz 
385226afbd82SLuiz Augusto von Dentz 	handle = __le16_to_cpu(hdr->handle);
385326afbd82SLuiz Augusto von Dentz 	flags  = hci_flags(handle);
385426afbd82SLuiz Augusto von Dentz 	handle = hci_handle(handle);
385526afbd82SLuiz Augusto von Dentz 
385626afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "len %d handle 0x%4.4x flags 0x%4.4x", skb->len,
385726afbd82SLuiz Augusto von Dentz 		   handle, flags);
385826afbd82SLuiz Augusto von Dentz 
385926afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
386026afbd82SLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_handle(hdev, handle);
386126afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
386226afbd82SLuiz Augusto von Dentz 
386326afbd82SLuiz Augusto von Dentz 	if (!conn) {
386426afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev, "ISO packet for unknown connection handle %d",
386526afbd82SLuiz Augusto von Dentz 			   handle);
3866ccf74f23SLuiz Augusto von Dentz 		goto drop;
386726afbd82SLuiz Augusto von Dentz 	}
386826afbd82SLuiz Augusto von Dentz 
3869ccf74f23SLuiz Augusto von Dentz 	/* Send to upper protocol */
3870ccf74f23SLuiz Augusto von Dentz 	iso_recv(conn, skb, flags);
3871ccf74f23SLuiz Augusto von Dentz 	return;
3872ccf74f23SLuiz Augusto von Dentz 
387326afbd82SLuiz Augusto von Dentz drop:
387426afbd82SLuiz Augusto von Dentz 	kfree_skb(skb);
387526afbd82SLuiz Augusto von Dentz }
387626afbd82SLuiz Augusto von Dentz 
hci_req_is_complete(struct hci_dev * hdev)38779238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
38789238f36aSJohan Hedberg {
38799238f36aSJohan Hedberg 	struct sk_buff *skb;
38809238f36aSJohan Hedberg 
38819238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
38829238f36aSJohan Hedberg 	if (!skb)
38839238f36aSJohan Hedberg 		return true;
38849238f36aSJohan Hedberg 
388544d27137SJohan Hedberg 	return (bt_cb(skb)->hci.req_flags & HCI_REQ_START);
38869238f36aSJohan Hedberg }
38879238f36aSJohan Hedberg 
hci_resend_last(struct hci_dev * hdev)388842c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
388942c6b129SJohan Hedberg {
389042c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
389142c6b129SJohan Hedberg 	struct sk_buff *skb;
389242c6b129SJohan Hedberg 	u16 opcode;
389342c6b129SJohan Hedberg 
389442c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
389542c6b129SJohan Hedberg 		return;
389642c6b129SJohan Hedberg 
389742c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
389842c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
389942c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
390042c6b129SJohan Hedberg 		return;
390142c6b129SJohan Hedberg 
390242c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
390342c6b129SJohan Hedberg 	if (!skb)
390442c6b129SJohan Hedberg 		return;
390542c6b129SJohan Hedberg 
390642c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
390742c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
390842c6b129SJohan Hedberg }
390942c6b129SJohan Hedberg 
hci_req_cmd_complete(struct hci_dev * hdev,u16 opcode,u8 status,hci_req_complete_t * req_complete,hci_req_complete_skb_t * req_complete_skb)3910e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
3911e6214487SJohan Hedberg 			  hci_req_complete_t *req_complete,
3912e6214487SJohan Hedberg 			  hci_req_complete_skb_t *req_complete_skb)
39139238f36aSJohan Hedberg {
39149238f36aSJohan Hedberg 	struct sk_buff *skb;
39159238f36aSJohan Hedberg 	unsigned long flags;
39169238f36aSJohan Hedberg 
39179238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
39189238f36aSJohan Hedberg 
391942c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
392042c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
39219238f36aSJohan Hedberg 	 */
392242c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
392342c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
392442c6b129SJohan Hedberg 		 * reset complete event during init and any pending
392542c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
392642c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
392742c6b129SJohan Hedberg 		 * command.
392842c6b129SJohan Hedberg 		 */
392942c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
393042c6b129SJohan Hedberg 			hci_resend_last(hdev);
393142c6b129SJohan Hedberg 
39329238f36aSJohan Hedberg 		return;
393342c6b129SJohan Hedberg 	}
39349238f36aSJohan Hedberg 
3935f80c5dadSJoão Paulo Rechi Vita 	/* If we reach this point this event matches the last command sent */
3936f80c5dadSJoão Paulo Rechi Vita 	hci_dev_clear_flag(hdev, HCI_CMD_PENDING);
3937f80c5dadSJoão Paulo Rechi Vita 
39389238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
39399238f36aSJohan Hedberg 	 * this request the request is not yet complete.
39409238f36aSJohan Hedberg 	 */
39419238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
39429238f36aSJohan Hedberg 		return;
39439238f36aSJohan Hedberg 
39442af7aa66SLuiz Augusto von Dentz 	skb = hdev->req_skb;
39452af7aa66SLuiz Augusto von Dentz 
39469238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
39472af7aa66SLuiz Augusto von Dentz 	 * callback would be found in hdev->req_skb instead of the
39489238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
39499238f36aSJohan Hedberg 	 */
39502af7aa66SLuiz Augusto von Dentz 	if (skb && bt_cb(skb)->hci.req_flags & HCI_REQ_SKB) {
39512af7aa66SLuiz Augusto von Dentz 		*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
3952e6214487SJohan Hedberg 		return;
39539238f36aSJohan Hedberg 	}
3954e6214487SJohan Hedberg 
39552af7aa66SLuiz Augusto von Dentz 	if (skb && bt_cb(skb)->hci.req_complete) {
39562af7aa66SLuiz Augusto von Dentz 		*req_complete = bt_cb(skb)->hci.req_complete;
3957e6214487SJohan Hedberg 		return;
395853e21fbcSJohan Hedberg 	}
39599238f36aSJohan Hedberg 
39609238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
39619238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
39629238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
396344d27137SJohan Hedberg 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) {
39649238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
39659238f36aSJohan Hedberg 			break;
39669238f36aSJohan Hedberg 		}
39679238f36aSJohan Hedberg 
39683bd7594eSDouglas Anderson 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB)
3969242c0ebdSMarcel Holtmann 			*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
39703bd7594eSDouglas Anderson 		else
39713bd7594eSDouglas Anderson 			*req_complete = bt_cb(skb)->hci.req_complete;
397239c1eb6fSYang Yingliang 		dev_kfree_skb_irq(skb);
39739238f36aSJohan Hedberg 	}
39749238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
39759238f36aSJohan Hedberg }
39769238f36aSJohan Hedberg 
hci_rx_work(struct work_struct * work)3977b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
39781da177e4SLinus Torvalds {
3979b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
39801da177e4SLinus Torvalds 	struct sk_buff *skb;
39811da177e4SLinus Torvalds 
39821da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
39831da177e4SLinus Torvalds 
39849f30de9eSTamas Koczka 	/* The kcov_remote functions used for collecting packet parsing
39859f30de9eSTamas Koczka 	 * coverage information from this background thread and associate
39869f30de9eSTamas Koczka 	 * the coverage with the syscall's thread which originally injected
39879f30de9eSTamas Koczka 	 * the packet. This helps fuzzing the kernel.
39889f30de9eSTamas Koczka 	 */
39899f30de9eSTamas Koczka 	for (; (skb = skb_dequeue(&hdev->rx_q)); kcov_remote_stop()) {
39909f30de9eSTamas Koczka 		kcov_remote_start_common(skb_get_kcov_handle(skb));
39919f30de9eSTamas Koczka 
3992cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
3993cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
3994cd82e61cSMarcel Holtmann 
39951da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
39961da177e4SLinus Torvalds 			/* Send copy to the sockets */
3997470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
39981da177e4SLinus Torvalds 		}
39991da177e4SLinus Torvalds 
4000eb8c101eSMattijs Korpershoek 		/* If the device has been opened in HCI_USER_CHANNEL,
4001eb8c101eSMattijs Korpershoek 		 * the userspace has exclusive access to device.
4002eb8c101eSMattijs Korpershoek 		 * When device is HCI_INIT, we still need to process
4003eb8c101eSMattijs Korpershoek 		 * the data packets to the driver in order
4004eb8c101eSMattijs Korpershoek 		 * to complete its setup().
4005eb8c101eSMattijs Korpershoek 		 */
4006eb8c101eSMattijs Korpershoek 		if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
4007eb8c101eSMattijs Korpershoek 		    !test_bit(HCI_INIT, &hdev->flags)) {
40081da177e4SLinus Torvalds 			kfree_skb(skb);
40091da177e4SLinus Torvalds 			continue;
40101da177e4SLinus Torvalds 		}
40111da177e4SLinus Torvalds 
40121da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
40131da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
4014d79f34e3SMarcel Holtmann 			switch (hci_skb_pkt_type(skb)) {
40151da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
40161da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
4017cc974003SMarcel Holtmann 			case HCI_ISODATA_PKT:
40181da177e4SLinus Torvalds 				kfree_skb(skb);
40191da177e4SLinus Torvalds 				continue;
40203ff50b79SStephen Hemminger 			}
40211da177e4SLinus Torvalds 		}
40221da177e4SLinus Torvalds 
40231da177e4SLinus Torvalds 		/* Process frame */
4024d79f34e3SMarcel Holtmann 		switch (hci_skb_pkt_type(skb)) {
40251da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
4026b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
40271da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
40281da177e4SLinus Torvalds 			break;
40291da177e4SLinus Torvalds 
40301da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
40311da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
40321da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
40331da177e4SLinus Torvalds 			break;
40341da177e4SLinus Torvalds 
40351da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
40361da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
40371da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
40381da177e4SLinus Torvalds 			break;
40391da177e4SLinus Torvalds 
404026afbd82SLuiz Augusto von Dentz 		case HCI_ISODATA_PKT:
404126afbd82SLuiz Augusto von Dentz 			BT_DBG("%s ISO data packet", hdev->name);
404226afbd82SLuiz Augusto von Dentz 			hci_isodata_packet(hdev, skb);
404326afbd82SLuiz Augusto von Dentz 			break;
404426afbd82SLuiz Augusto von Dentz 
40451da177e4SLinus Torvalds 		default:
40461da177e4SLinus Torvalds 			kfree_skb(skb);
40471da177e4SLinus Torvalds 			break;
40481da177e4SLinus Torvalds 		}
40491da177e4SLinus Torvalds 	}
40501da177e4SLinus Torvalds }
40511da177e4SLinus Torvalds 
hci_send_cmd_sync(struct hci_dev * hdev,struct sk_buff * skb)40520ce1229cSLuiz Augusto von Dentz static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
40530ce1229cSLuiz Augusto von Dentz {
40540ce1229cSLuiz Augusto von Dentz 	int err;
40550ce1229cSLuiz Augusto von Dentz 
40560ce1229cSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "skb %p", skb);
40570ce1229cSLuiz Augusto von Dentz 
40580ce1229cSLuiz Augusto von Dentz 	kfree_skb(hdev->sent_cmd);
40590ce1229cSLuiz Augusto von Dentz 
40600ce1229cSLuiz Augusto von Dentz 	hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
40610ce1229cSLuiz Augusto von Dentz 	if (!hdev->sent_cmd) {
40620ce1229cSLuiz Augusto von Dentz 		skb_queue_head(&hdev->cmd_q, skb);
40630ce1229cSLuiz Augusto von Dentz 		queue_work(hdev->workqueue, &hdev->cmd_work);
40640ce1229cSLuiz Augusto von Dentz 		return;
40650ce1229cSLuiz Augusto von Dentz 	}
40660ce1229cSLuiz Augusto von Dentz 
40670ce1229cSLuiz Augusto von Dentz 	err = hci_send_frame(hdev, skb);
40680ce1229cSLuiz Augusto von Dentz 	if (err < 0) {
40699ae3954dSLuiz Augusto von Dentz 		hci_cmd_sync_cancel_sync(hdev, -err);
40700ce1229cSLuiz Augusto von Dentz 		return;
40710ce1229cSLuiz Augusto von Dentz 	}
40720ce1229cSLuiz Augusto von Dentz 
40732af7aa66SLuiz Augusto von Dentz 	if (hci_req_status_pend(hdev) &&
40742af7aa66SLuiz Augusto von Dentz 	    !hci_dev_test_and_set_flag(hdev, HCI_CMD_PENDING)) {
40752af7aa66SLuiz Augusto von Dentz 		kfree_skb(hdev->req_skb);
4076a2354605SPauli Virtanen 		hdev->req_skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
40772af7aa66SLuiz Augusto von Dentz 	}
40780ce1229cSLuiz Augusto von Dentz 
40790ce1229cSLuiz Augusto von Dentz 	atomic_dec(&hdev->cmd_cnt);
40800ce1229cSLuiz Augusto von Dentz }
40810ce1229cSLuiz Augusto von Dentz 
hci_cmd_work(struct work_struct * work)4082c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
40831da177e4SLinus Torvalds {
4084c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
40851da177e4SLinus Torvalds 	struct sk_buff *skb;
40861da177e4SLinus Torvalds 
40872104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
40882104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
40891da177e4SLinus Torvalds 
40901da177e4SLinus Torvalds 	/* Send queued commands */
40915a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
40925a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
40935a08ecceSAndrei Emeltchenko 		if (!skb)
40945a08ecceSAndrei Emeltchenko 			return;
40955a08ecceSAndrei Emeltchenko 
40960ce1229cSLuiz Augusto von Dentz 		hci_send_cmd_sync(hdev, skb);
40972250abadSBenjamin Berg 
4098deee93d1STetsuo Handa 		rcu_read_lock();
4099877afadaSSchspa Shi 		if (test_bit(HCI_RESET, &hdev->flags) ||
4100877afadaSSchspa Shi 		    hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
410165cc2b49SMarcel Holtmann 			cancel_delayed_work(&hdev->cmd_timer);
41027bdb8a5cSSzymon Janc 		else
4103deee93d1STetsuo Handa 			queue_delayed_work(hdev->workqueue, &hdev->cmd_timer,
410465cc2b49SMarcel Holtmann 					   HCI_CMD_TIMEOUT);
4105deee93d1STetsuo Handa 		rcu_read_unlock();
41061da177e4SLinus Torvalds 	}
41071da177e4SLinus Torvalds }
4108