xref: /openbmc/linux/net/bluetooth/hci_core.c (revision a41c8efe)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
4590051deSGustavo F. Padovan    Copyright (C) 2011 ProFUSION Embedded Systems
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds    published by the Free Software Foundation;
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds /* Bluetooth HCI core. */
271da177e4SLinus Torvalds 
288c520a59SGustavo Padovan #include <linux/export.h>
29611b30f7SMarcel Holtmann #include <linux/rfkill.h>
30baf27f6eSMarcel Holtmann #include <linux/debugfs.h>
3199780a7bSJohan Hedberg #include <linux/crypto.h>
329f30de9eSTamas Koczka #include <linux/kcov.h>
337a0e5b15SMatthias Kaehlcke #include <linux/property.h>
349952d90eSAbhishek Pandit-Subedi #include <linux/suspend.h>
359952d90eSAbhishek Pandit-Subedi #include <linux/wait.h>
3647219839SMarcel Holtmann #include <asm/unaligned.h>
371da177e4SLinus Torvalds 
381da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
391da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
404bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h>
41af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h>
421da177e4SLinus Torvalds 
430857dd3bSJohan Hedberg #include "hci_request.h"
4460c5f5fbSMarcel Holtmann #include "hci_debugfs.h"
45970c4e46SJohan Hedberg #include "smp.h"
466d5d2ee6SHeiner Kallweit #include "leds.h"
47145373cbSMiao-chen Chou #include "msft.h"
48f67743f9SMarcel Holtmann #include "aosp.h"
498961987fSKiran K #include "hci_codec.h"
50970c4e46SJohan Hedberg 
51b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
52c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
533eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
541da177e4SLinus Torvalds 
551da177e4SLinus Torvalds /* HCI device list */
561da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
571da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds /* HCI callback list */
601da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
61fba7ecf0SJohan Hedberg DEFINE_MUTEX(hci_cb_list_lock);
621da177e4SLinus Torvalds 
633df92b31SSasha Levin /* HCI ID Numbering */
643df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
653df92b31SSasha Levin 
66a1d01db1SJohan Hedberg static int hci_scan_req(struct hci_request *req, unsigned long opt)
671da177e4SLinus Torvalds {
681da177e4SLinus Torvalds 	__u8 scan = opt;
691da177e4SLinus Torvalds 
7042c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
711da177e4SLinus Torvalds 
721da177e4SLinus Torvalds 	/* Inquiry and Page scans */
7342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
74a1d01db1SJohan Hedberg 	return 0;
751da177e4SLinus Torvalds }
761da177e4SLinus Torvalds 
77a1d01db1SJohan Hedberg static int hci_auth_req(struct hci_request *req, unsigned long opt)
781da177e4SLinus Torvalds {
791da177e4SLinus Torvalds 	__u8 auth = opt;
801da177e4SLinus Torvalds 
8142c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds 	/* Authentication */
8442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
85a1d01db1SJohan Hedberg 	return 0;
861da177e4SLinus Torvalds }
871da177e4SLinus Torvalds 
88a1d01db1SJohan Hedberg static int hci_encrypt_req(struct hci_request *req, unsigned long opt)
891da177e4SLinus Torvalds {
901da177e4SLinus Torvalds 	__u8 encrypt = opt;
911da177e4SLinus Torvalds 
9242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
931da177e4SLinus Torvalds 
94e4e8e37cSMarcel Holtmann 	/* Encryption */
9542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
96a1d01db1SJohan Hedberg 	return 0;
971da177e4SLinus Torvalds }
981da177e4SLinus Torvalds 
99a1d01db1SJohan Hedberg static int hci_linkpol_req(struct hci_request *req, unsigned long opt)
100e4e8e37cSMarcel Holtmann {
101e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
102e4e8e37cSMarcel Holtmann 
10342c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
104e4e8e37cSMarcel Holtmann 
105e4e8e37cSMarcel Holtmann 	/* Default link policy */
10642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
107a1d01db1SJohan Hedberg 	return 0;
108e4e8e37cSMarcel Holtmann }
109e4e8e37cSMarcel Holtmann 
1101da177e4SLinus Torvalds /* Get HCI device by index.
1111da177e4SLinus Torvalds  * Device is held on return. */
1121da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
1131da177e4SLinus Torvalds {
1148035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
1151da177e4SLinus Torvalds 
1161da177e4SLinus Torvalds 	BT_DBG("%d", index);
1171da177e4SLinus Torvalds 
1181da177e4SLinus Torvalds 	if (index < 0)
1191da177e4SLinus Torvalds 		return NULL;
1201da177e4SLinus Torvalds 
1211da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
1228035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
1231da177e4SLinus Torvalds 		if (d->id == index) {
1241da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
1251da177e4SLinus Torvalds 			break;
1261da177e4SLinus Torvalds 		}
1271da177e4SLinus Torvalds 	}
1281da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
1291da177e4SLinus Torvalds 	return hdev;
1301da177e4SLinus Torvalds }
1311da177e4SLinus Torvalds 
1321da177e4SLinus Torvalds /* ---- Inquiry support ---- */
133ff9ef578SJohan Hedberg 
13430dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
13530dc78e1SJohan Hedberg {
13630dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
13730dc78e1SJohan Hedberg 
1386fbe195dSAndre Guedes 	switch (discov->state) {
139343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1406fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
14130dc78e1SJohan Hedberg 		return true;
14230dc78e1SJohan Hedberg 
1436fbe195dSAndre Guedes 	default:
14430dc78e1SJohan Hedberg 		return false;
14530dc78e1SJohan Hedberg 	}
1466fbe195dSAndre Guedes }
14730dc78e1SJohan Hedberg 
148ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
149ff9ef578SJohan Hedberg {
150bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
151bb3e0a33SJohan Hedberg 
152ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
153ff9ef578SJohan Hedberg 
154bb3e0a33SJohan Hedberg 	if (old_state == state)
155ff9ef578SJohan Hedberg 		return;
156ff9ef578SJohan Hedberg 
157bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
158bb3e0a33SJohan Hedberg 
159ff9ef578SJohan Hedberg 	switch (state) {
160ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
1615bee2fd6SLuiz Augusto von Dentz 		hci_update_passive_scan(hdev);
162c54c3860SAndre Guedes 
163bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
164ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
165ff9ef578SJohan Hedberg 		break;
166ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
167ff9ef578SJohan Hedberg 		break;
168343f935bSAndre Guedes 	case DISCOVERY_FINDING:
169ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
170ff9ef578SJohan Hedberg 		break;
17130dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
17230dc78e1SJohan Hedberg 		break;
173ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
174ff9ef578SJohan Hedberg 		break;
175ff9ef578SJohan Hedberg 	}
176ff9ef578SJohan Hedberg }
177ff9ef578SJohan Hedberg 
1781f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
1791da177e4SLinus Torvalds {
18030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
181b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
1821da177e4SLinus Torvalds 
183561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
184561aafbcSJohan Hedberg 		list_del(&p->all);
185b57c1a56SJohan Hedberg 		kfree(p);
1861da177e4SLinus Torvalds 	}
187561aafbcSJohan Hedberg 
188561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
189561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
1901da177e4SLinus Torvalds }
1911da177e4SLinus Torvalds 
192a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
193a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
1941da177e4SLinus Torvalds {
19530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1961da177e4SLinus Torvalds 	struct inquiry_entry *e;
1971da177e4SLinus Torvalds 
1986ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1991da177e4SLinus Torvalds 
200561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
2011da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
2021da177e4SLinus Torvalds 			return e;
2031da177e4SLinus Torvalds 	}
2041da177e4SLinus Torvalds 
205b57c1a56SJohan Hedberg 	return NULL;
206b57c1a56SJohan Hedberg }
207b57c1a56SJohan Hedberg 
208561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
209561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
210561aafbcSJohan Hedberg {
21130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
212561aafbcSJohan Hedberg 	struct inquiry_entry *e;
213561aafbcSJohan Hedberg 
2146ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
215561aafbcSJohan Hedberg 
216561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
217561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
218561aafbcSJohan Hedberg 			return e;
219561aafbcSJohan Hedberg 	}
220561aafbcSJohan Hedberg 
221561aafbcSJohan Hedberg 	return NULL;
222561aafbcSJohan Hedberg }
223561aafbcSJohan Hedberg 
22430dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
22530dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
22630dc78e1SJohan Hedberg 						       int state)
22730dc78e1SJohan Hedberg {
22830dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
22930dc78e1SJohan Hedberg 	struct inquiry_entry *e;
23030dc78e1SJohan Hedberg 
2316ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
23230dc78e1SJohan Hedberg 
23330dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
23430dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
23530dc78e1SJohan Hedberg 			return e;
23630dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
23730dc78e1SJohan Hedberg 			return e;
23830dc78e1SJohan Hedberg 	}
23930dc78e1SJohan Hedberg 
24030dc78e1SJohan Hedberg 	return NULL;
24130dc78e1SJohan Hedberg }
24230dc78e1SJohan Hedberg 
243a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
244a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
245a3d4e20aSJohan Hedberg {
246a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
247a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
248a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
249a3d4e20aSJohan Hedberg 
250a3d4e20aSJohan Hedberg 	list_del(&ie->list);
251a3d4e20aSJohan Hedberg 
252a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
253a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
254a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
255a3d4e20aSJohan Hedberg 			break;
256a3d4e20aSJohan Hedberg 		pos = &p->list;
257a3d4e20aSJohan Hedberg 	}
258a3d4e20aSJohan Hedberg 
259a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
260a3d4e20aSJohan Hedberg }
261a3d4e20aSJohan Hedberg 
262af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
263af58925cSMarcel Holtmann 			     bool name_known)
2641da177e4SLinus Torvalds {
26530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
26670f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
267af58925cSMarcel Holtmann 	u32 flags = 0;
2681da177e4SLinus Torvalds 
2696ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
2701da177e4SLinus Torvalds 
2716928a924SJohan Hedberg 	hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
2722b2fec4dSSzymon Janc 
273af58925cSMarcel Holtmann 	if (!data->ssp_mode)
274af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
275388fc8faSJohan Hedberg 
27670f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
277a3d4e20aSJohan Hedberg 	if (ie) {
278af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
279af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
280388fc8faSJohan Hedberg 
281a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
282a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
283a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
284a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
285a3d4e20aSJohan Hedberg 		}
286a3d4e20aSJohan Hedberg 
287561aafbcSJohan Hedberg 		goto update;
288a3d4e20aSJohan Hedberg 	}
289561aafbcSJohan Hedberg 
2901da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
29127f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
292af58925cSMarcel Holtmann 	if (!ie) {
293af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
294af58925cSMarcel Holtmann 		goto done;
295af58925cSMarcel Holtmann 	}
29670f23020SAndrei Emeltchenko 
297561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
298561aafbcSJohan Hedberg 
299561aafbcSJohan Hedberg 	if (name_known) {
300561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
301561aafbcSJohan Hedberg 	} else {
302561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
303561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
304561aafbcSJohan Hedberg 	}
305561aafbcSJohan Hedberg 
306561aafbcSJohan Hedberg update:
307561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
308561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
309561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
310561aafbcSJohan Hedberg 		list_del(&ie->list);
3111da177e4SLinus Torvalds 	}
3121da177e4SLinus Torvalds 
31370f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
31470f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
3151da177e4SLinus Torvalds 	cache->timestamp = jiffies;
3163175405bSJohan Hedberg 
3173175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
318af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
3193175405bSJohan Hedberg 
320af58925cSMarcel Holtmann done:
321af58925cSMarcel Holtmann 	return flags;
3221da177e4SLinus Torvalds }
3231da177e4SLinus Torvalds 
3241da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
3251da177e4SLinus Torvalds {
32630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
3271da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
3281da177e4SLinus Torvalds 	struct inquiry_entry *e;
3291da177e4SLinus Torvalds 	int copied = 0;
3301da177e4SLinus Torvalds 
331561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
3321da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
333b57c1a56SJohan Hedberg 
334b57c1a56SJohan Hedberg 		if (copied >= num)
335b57c1a56SJohan Hedberg 			break;
336b57c1a56SJohan Hedberg 
3371da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
3381da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
3391da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
3401da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
3411da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
3421da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
343b57c1a56SJohan Hedberg 
3441da177e4SLinus Torvalds 		info++;
345b57c1a56SJohan Hedberg 		copied++;
3461da177e4SLinus Torvalds 	}
3471da177e4SLinus Torvalds 
3481da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
3491da177e4SLinus Torvalds 	return copied;
3501da177e4SLinus Torvalds }
3511da177e4SLinus Torvalds 
352a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt)
3531da177e4SLinus Torvalds {
3541da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
35542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
3561da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
3571da177e4SLinus Torvalds 
3581da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
3591da177e4SLinus Torvalds 
3601da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
361a1d01db1SJohan Hedberg 		return 0;
3621da177e4SLinus Torvalds 
3631da177e4SLinus Torvalds 	/* Start Inquiry */
3641da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
3651da177e4SLinus Torvalds 	cp.length  = ir->length;
3661da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
36742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
368a1d01db1SJohan Hedberg 
369a1d01db1SJohan Hedberg 	return 0;
3701da177e4SLinus Torvalds }
3711da177e4SLinus Torvalds 
3721da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
3731da177e4SLinus Torvalds {
3741da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
3751da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
3761da177e4SLinus Torvalds 	struct hci_dev *hdev;
3771da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
3781da177e4SLinus Torvalds 	long timeo;
3791da177e4SLinus Torvalds 	__u8 *buf;
3801da177e4SLinus Torvalds 
3811da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
3821da177e4SLinus Torvalds 		return -EFAULT;
3831da177e4SLinus Torvalds 
3845a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
3855a08ecceSAndrei Emeltchenko 	if (!hdev)
3861da177e4SLinus Torvalds 		return -ENODEV;
3871da177e4SLinus Torvalds 
388d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
3890736cfa8SMarcel Holtmann 		err = -EBUSY;
3900736cfa8SMarcel Holtmann 		goto done;
3910736cfa8SMarcel Holtmann 	}
3920736cfa8SMarcel Holtmann 
393d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
394fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
395fee746b0SMarcel Holtmann 		goto done;
396fee746b0SMarcel Holtmann 	}
397fee746b0SMarcel Holtmann 
398ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY) {
3995b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
4005b69bef5SMarcel Holtmann 		goto done;
4015b69bef5SMarcel Holtmann 	}
4025b69bef5SMarcel Holtmann 
403d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
40456f87901SJohan Hedberg 		err = -EOPNOTSUPP;
40556f87901SJohan Hedberg 		goto done;
40656f87901SJohan Hedberg 	}
40756f87901SJohan Hedberg 
408f41a4b2bSPavel Skripkin 	/* Restrict maximum inquiry length to 60 seconds */
409f41a4b2bSPavel Skripkin 	if (ir.length > 60) {
410f41a4b2bSPavel Skripkin 		err = -EINVAL;
411f41a4b2bSPavel Skripkin 		goto done;
412f41a4b2bSPavel Skripkin 	}
413f41a4b2bSPavel Skripkin 
41409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4151da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
416a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
4171f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
4181da177e4SLinus Torvalds 		do_inquiry = 1;
4191da177e4SLinus Torvalds 	}
42009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4211da177e4SLinus Torvalds 
42204837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
42370f23020SAndrei Emeltchenko 
42470f23020SAndrei Emeltchenko 	if (do_inquiry) {
42501178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
4264ebeee2dSJohan Hedberg 				   timeo, NULL);
42770f23020SAndrei Emeltchenko 		if (err < 0)
4281da177e4SLinus Torvalds 			goto done;
4293e13fa1eSAndre Guedes 
4303e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
4313e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
4323e13fa1eSAndre Guedes 		 */
43374316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
43428a758c8SPan Bian 				TASK_INTERRUPTIBLE)) {
43528a758c8SPan Bian 			err = -EINTR;
43628a758c8SPan Bian 			goto done;
43728a758c8SPan Bian 		}
43870f23020SAndrei Emeltchenko 	}
4391da177e4SLinus Torvalds 
4408fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
4418fc9ced3SGustavo Padovan 	 * 255 entries
4428fc9ced3SGustavo Padovan 	 */
4431da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
4441da177e4SLinus Torvalds 
4451da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
4461da177e4SLinus Torvalds 	 * copy it to the user space.
4471da177e4SLinus Torvalds 	 */
4486da2ec56SKees Cook 	buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL);
44970f23020SAndrei Emeltchenko 	if (!buf) {
4501da177e4SLinus Torvalds 		err = -ENOMEM;
4511da177e4SLinus Torvalds 		goto done;
4521da177e4SLinus Torvalds 	}
4531da177e4SLinus Torvalds 
45409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4551da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
45609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4571da177e4SLinus Torvalds 
4581da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
4591da177e4SLinus Torvalds 
4601da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
4611da177e4SLinus Torvalds 		ptr += sizeof(ir);
4621da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
4631da177e4SLinus Torvalds 				 ir.num_rsp))
4641da177e4SLinus Torvalds 			err = -EFAULT;
4651da177e4SLinus Torvalds 	} else
4661da177e4SLinus Torvalds 		err = -EFAULT;
4671da177e4SLinus Torvalds 
4681da177e4SLinus Torvalds 	kfree(buf);
4691da177e4SLinus Torvalds 
4701da177e4SLinus Torvalds done:
4711da177e4SLinus Torvalds 	hci_dev_put(hdev);
4721da177e4SLinus Torvalds 	return err;
4731da177e4SLinus Torvalds }
4741da177e4SLinus Torvalds 
475cf75ad8bSLuiz Augusto von Dentz static int hci_dev_do_open(struct hci_dev *hdev)
476cf75ad8bSLuiz Augusto von Dentz {
477cf75ad8bSLuiz Augusto von Dentz 	int ret = 0;
478cf75ad8bSLuiz Augusto von Dentz 
479cf75ad8bSLuiz Augusto von Dentz 	BT_DBG("%s %p", hdev->name, hdev);
480cf75ad8bSLuiz Augusto von Dentz 
481cf75ad8bSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
482cf75ad8bSLuiz Augusto von Dentz 
483cf75ad8bSLuiz Augusto von Dentz 	ret = hci_dev_open_sync(hdev);
484cf75ad8bSLuiz Augusto von Dentz 
485b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
4861da177e4SLinus Torvalds 	return ret;
4871da177e4SLinus Torvalds }
4881da177e4SLinus Torvalds 
489cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
490cbed0ca1SJohan Hedberg 
491cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
492cbed0ca1SJohan Hedberg {
493cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
494cbed0ca1SJohan Hedberg 	int err;
495cbed0ca1SJohan Hedberg 
496cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
497cbed0ca1SJohan Hedberg 	if (!hdev)
498cbed0ca1SJohan Hedberg 		return -ENODEV;
499cbed0ca1SJohan Hedberg 
5004a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
501fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
502fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
503fee746b0SMarcel Holtmann 	 * possible.
504fee746b0SMarcel Holtmann 	 *
505fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
506fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
507fee746b0SMarcel Holtmann 	 * open the device.
508fee746b0SMarcel Holtmann 	 */
509d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
510d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
511fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
512fee746b0SMarcel Holtmann 		goto done;
513fee746b0SMarcel Holtmann 	}
514fee746b0SMarcel Holtmann 
515e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
516e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
517e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
518e1d08f40SJohan Hedberg 	 * completed.
519e1d08f40SJohan Hedberg 	 */
520a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
521e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
522e1d08f40SJohan Hedberg 
523a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
524a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
525a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
526a5c8f270SMarcel Holtmann 	 */
527e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
528e1d08f40SJohan Hedberg 
52912aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
530b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
53112aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
53212aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
53312aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
53412aa4f0aSMarcel Holtmann 	 */
535d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
536d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_MGMT))
537a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BONDABLE);
53812aa4f0aSMarcel Holtmann 
539cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
540cbed0ca1SJohan Hedberg 
541fee746b0SMarcel Holtmann done:
542cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
543cbed0ca1SJohan Hedberg 	return err;
544cbed0ca1SJohan Hedberg }
545cbed0ca1SJohan Hedberg 
546cf75ad8bSLuiz Augusto von Dentz int hci_dev_do_close(struct hci_dev *hdev)
547cf75ad8bSLuiz Augusto von Dentz {
548cf75ad8bSLuiz Augusto von Dentz 	int err;
549cf75ad8bSLuiz Augusto von Dentz 
550cf75ad8bSLuiz Augusto von Dentz 	BT_DBG("%s %p", hdev->name, hdev);
551cf75ad8bSLuiz Augusto von Dentz 
552cf75ad8bSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
553cf75ad8bSLuiz Augusto von Dentz 
554cf75ad8bSLuiz Augusto von Dentz 	err = hci_dev_close_sync(hdev);
555cf75ad8bSLuiz Augusto von Dentz 
556b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
5571da177e4SLinus Torvalds 
55861969ef8SKangmin Park 	return err;
5591da177e4SLinus Torvalds }
5601da177e4SLinus Torvalds 
5611da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
5621da177e4SLinus Torvalds {
5631da177e4SLinus Torvalds 	struct hci_dev *hdev;
5641da177e4SLinus Torvalds 	int err;
5651da177e4SLinus Torvalds 
56670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
56770f23020SAndrei Emeltchenko 	if (!hdev)
5681da177e4SLinus Torvalds 		return -ENODEV;
5698ee56540SMarcel Holtmann 
570d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
5710736cfa8SMarcel Holtmann 		err = -EBUSY;
5720736cfa8SMarcel Holtmann 		goto done;
5730736cfa8SMarcel Holtmann 	}
5740736cfa8SMarcel Holtmann 
575e36bea6eSVasyl Vavrychuk 	cancel_work_sync(&hdev->power_on);
576a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
5778ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
5788ee56540SMarcel Holtmann 
5791da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
5808ee56540SMarcel Holtmann 
5810736cfa8SMarcel Holtmann done:
5821da177e4SLinus Torvalds 	hci_dev_put(hdev);
5831da177e4SLinus Torvalds 	return err;
5841da177e4SLinus Torvalds }
5851da177e4SLinus Torvalds 
5865c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev)
5871da177e4SLinus Torvalds {
5885c912495SMarcel Holtmann 	int ret;
5891da177e4SLinus Torvalds 
5905c912495SMarcel Holtmann 	BT_DBG("%s %p", hdev->name, hdev);
5911da177e4SLinus Torvalds 
592b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
5931da177e4SLinus Torvalds 
5941da177e4SLinus Torvalds 	/* Drop queues */
5951da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
5961da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
5971da177e4SLinus Torvalds 
598877afadaSSchspa Shi 	/* Cancel these to avoid queueing non-chained pending work */
599877afadaSSchspa Shi 	hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
600deee93d1STetsuo Handa 	/* Wait for
601deee93d1STetsuo Handa 	 *
602deee93d1STetsuo Handa 	 *    if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
603deee93d1STetsuo Handa 	 *        queue_delayed_work(&hdev->{cmd,ncmd}_timer)
604deee93d1STetsuo Handa 	 *
605deee93d1STetsuo Handa 	 * inside RCU section to see the flag or complete scheduling.
606deee93d1STetsuo Handa 	 */
607deee93d1STetsuo Handa 	synchronize_rcu();
608deee93d1STetsuo Handa 	/* Explicitly cancel works in case scheduled after setting the flag. */
609877afadaSSchspa Shi 	cancel_delayed_work(&hdev->cmd_timer);
610877afadaSSchspa Shi 	cancel_delayed_work(&hdev->ncmd_timer);
611877afadaSSchspa Shi 
61276727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
61376727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
61476727c02SJohan Hedberg 	 */
61576727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
61676727c02SJohan Hedberg 
61709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6181f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
6191da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
62009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6211da177e4SLinus Torvalds 
6221da177e4SLinus Torvalds 	if (hdev->flush)
6231da177e4SLinus Torvalds 		hdev->flush(hdev);
6241da177e4SLinus Torvalds 
625877afadaSSchspa Shi 	hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
626877afadaSSchspa Shi 
6271da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
62826afbd82SLuiz Augusto von Dentz 	hdev->acl_cnt = 0;
62926afbd82SLuiz Augusto von Dentz 	hdev->sco_cnt = 0;
63026afbd82SLuiz Augusto von Dentz 	hdev->le_cnt = 0;
63126afbd82SLuiz Augusto von Dentz 	hdev->iso_cnt = 0;
6321da177e4SLinus Torvalds 
633d0b13706SLuiz Augusto von Dentz 	ret = hci_reset_sync(hdev);
6341da177e4SLinus Torvalds 
635b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
6361da177e4SLinus Torvalds 	return ret;
6371da177e4SLinus Torvalds }
6381da177e4SLinus Torvalds 
6395c912495SMarcel Holtmann int hci_dev_reset(__u16 dev)
6405c912495SMarcel Holtmann {
6415c912495SMarcel Holtmann 	struct hci_dev *hdev;
6425c912495SMarcel Holtmann 	int err;
6435c912495SMarcel Holtmann 
6445c912495SMarcel Holtmann 	hdev = hci_dev_get(dev);
6455c912495SMarcel Holtmann 	if (!hdev)
6465c912495SMarcel Holtmann 		return -ENODEV;
6475c912495SMarcel Holtmann 
6485c912495SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
6495c912495SMarcel Holtmann 		err = -ENETDOWN;
6505c912495SMarcel Holtmann 		goto done;
6515c912495SMarcel Holtmann 	}
6525c912495SMarcel Holtmann 
653d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6545c912495SMarcel Holtmann 		err = -EBUSY;
6555c912495SMarcel Holtmann 		goto done;
6565c912495SMarcel Holtmann 	}
6575c912495SMarcel Holtmann 
658d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
6595c912495SMarcel Holtmann 		err = -EOPNOTSUPP;
6605c912495SMarcel Holtmann 		goto done;
6615c912495SMarcel Holtmann 	}
6625c912495SMarcel Holtmann 
6635c912495SMarcel Holtmann 	err = hci_dev_do_reset(hdev);
6645c912495SMarcel Holtmann 
6655c912495SMarcel Holtmann done:
6665c912495SMarcel Holtmann 	hci_dev_put(hdev);
6675c912495SMarcel Holtmann 	return err;
6685c912495SMarcel Holtmann }
6695c912495SMarcel Holtmann 
6701da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
6711da177e4SLinus Torvalds {
6721da177e4SLinus Torvalds 	struct hci_dev *hdev;
6731da177e4SLinus Torvalds 	int ret = 0;
6741da177e4SLinus Torvalds 
67570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
67670f23020SAndrei Emeltchenko 	if (!hdev)
6771da177e4SLinus Torvalds 		return -ENODEV;
6781da177e4SLinus Torvalds 
679d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6800736cfa8SMarcel Holtmann 		ret = -EBUSY;
6810736cfa8SMarcel Holtmann 		goto done;
6820736cfa8SMarcel Holtmann 	}
6830736cfa8SMarcel Holtmann 
684d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
685fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
686fee746b0SMarcel Holtmann 		goto done;
687fee746b0SMarcel Holtmann 	}
688fee746b0SMarcel Holtmann 
6891da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
6901da177e4SLinus Torvalds 
6910736cfa8SMarcel Holtmann done:
6921da177e4SLinus Torvalds 	hci_dev_put(hdev);
6931da177e4SLinus Torvalds 	return ret;
6941da177e4SLinus Torvalds }
6951da177e4SLinus Torvalds 
6965bee2fd6SLuiz Augusto von Dentz static void hci_update_passive_scan_state(struct hci_dev *hdev, u8 scan)
697123abc08SJohan Hedberg {
698bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
699123abc08SJohan Hedberg 
700123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
701123abc08SJohan Hedberg 
702123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
703238be788SMarcel Holtmann 		conn_changed = !hci_dev_test_and_set_flag(hdev,
704238be788SMarcel Holtmann 							  HCI_CONNECTABLE);
705123abc08SJohan Hedberg 	else
706a69d8927SMarcel Holtmann 		conn_changed = hci_dev_test_and_clear_flag(hdev,
707a69d8927SMarcel Holtmann 							   HCI_CONNECTABLE);
708123abc08SJohan Hedberg 
709bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
710238be788SMarcel Holtmann 		discov_changed = !hci_dev_test_and_set_flag(hdev,
711238be788SMarcel Holtmann 							    HCI_DISCOVERABLE);
712bc6d2d04SJohan Hedberg 	} else {
713a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
714a69d8927SMarcel Holtmann 		discov_changed = hci_dev_test_and_clear_flag(hdev,
715a69d8927SMarcel Holtmann 							     HCI_DISCOVERABLE);
716bc6d2d04SJohan Hedberg 	}
717bc6d2d04SJohan Hedberg 
718d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
719123abc08SJohan Hedberg 		return;
720123abc08SJohan Hedberg 
721bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
722bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
723a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
724bc6d2d04SJohan Hedberg 
725d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
726651cd3d6SBrian Gix 			hci_update_adv_data(hdev, hdev->cur_adv_instance);
727bc6d2d04SJohan Hedberg 
728123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
729123abc08SJohan Hedberg 	}
730bc6d2d04SJohan Hedberg }
731123abc08SJohan Hedberg 
7321da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
7331da177e4SLinus Torvalds {
7341da177e4SLinus Torvalds 	struct hci_dev *hdev;
7351da177e4SLinus Torvalds 	struct hci_dev_req dr;
7361da177e4SLinus Torvalds 	int err = 0;
7371da177e4SLinus Torvalds 
7381da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
7391da177e4SLinus Torvalds 		return -EFAULT;
7401da177e4SLinus Torvalds 
74170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
74270f23020SAndrei Emeltchenko 	if (!hdev)
7431da177e4SLinus Torvalds 		return -ENODEV;
7441da177e4SLinus Torvalds 
745d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
7460736cfa8SMarcel Holtmann 		err = -EBUSY;
7470736cfa8SMarcel Holtmann 		goto done;
7480736cfa8SMarcel Holtmann 	}
7490736cfa8SMarcel Holtmann 
750d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
751fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
752fee746b0SMarcel Holtmann 		goto done;
753fee746b0SMarcel Holtmann 	}
754fee746b0SMarcel Holtmann 
755ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY) {
7565b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
7575b69bef5SMarcel Holtmann 		goto done;
7585b69bef5SMarcel Holtmann 	}
7595b69bef5SMarcel Holtmann 
760d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
76156f87901SJohan Hedberg 		err = -EOPNOTSUPP;
76256f87901SJohan Hedberg 		goto done;
76356f87901SJohan Hedberg 	}
76456f87901SJohan Hedberg 
7651da177e4SLinus Torvalds 	switch (cmd) {
7661da177e4SLinus Torvalds 	case HCISETAUTH:
76701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
7684ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
7691da177e4SLinus Torvalds 		break;
7701da177e4SLinus Torvalds 
7711da177e4SLinus Torvalds 	case HCISETENCRYPT:
7721da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
7731da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
7741da177e4SLinus Torvalds 			break;
7751da177e4SLinus Torvalds 		}
7761da177e4SLinus Torvalds 
7771da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
7781da177e4SLinus Torvalds 			/* Auth must be enabled first */
77901178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
7804ebeee2dSJohan Hedberg 					   HCI_INIT_TIMEOUT, NULL);
7811da177e4SLinus Torvalds 			if (err)
7821da177e4SLinus Torvalds 				break;
7831da177e4SLinus Torvalds 		}
7841da177e4SLinus Torvalds 
78501178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
7864ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
7871da177e4SLinus Torvalds 		break;
7881da177e4SLinus Torvalds 
7891da177e4SLinus Torvalds 	case HCISETSCAN:
79001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
7914ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
79291a668b0SJohan Hedberg 
793bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
794bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
79591a668b0SJohan Hedberg 		 */
796123abc08SJohan Hedberg 		if (!err)
7975bee2fd6SLuiz Augusto von Dentz 			hci_update_passive_scan_state(hdev, dr.dev_opt);
7981da177e4SLinus Torvalds 		break;
7991da177e4SLinus Torvalds 
8001da177e4SLinus Torvalds 	case HCISETLINKPOL:
80101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
8024ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
8031da177e4SLinus Torvalds 		break;
8041da177e4SLinus Torvalds 
8051da177e4SLinus Torvalds 	case HCISETLINKMODE:
806e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
807e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
808e4e8e37cSMarcel Holtmann 		break;
809e4e8e37cSMarcel Holtmann 
810e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
811b7c23df8SJaganath Kanakkassery 		if (hdev->pkt_type == (__u16) dr.dev_opt)
812b7c23df8SJaganath Kanakkassery 			break;
813b7c23df8SJaganath Kanakkassery 
814e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
815b7c23df8SJaganath Kanakkassery 		mgmt_phy_configuration_changed(hdev, NULL);
8161da177e4SLinus Torvalds 		break;
8171da177e4SLinus Torvalds 
8181da177e4SLinus Torvalds 	case HCISETACLMTU:
8191da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
8201da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
8211da177e4SLinus Torvalds 		break;
8221da177e4SLinus Torvalds 
8231da177e4SLinus Torvalds 	case HCISETSCOMTU:
8241da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
8251da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
8261da177e4SLinus Torvalds 		break;
8271da177e4SLinus Torvalds 
8281da177e4SLinus Torvalds 	default:
8291da177e4SLinus Torvalds 		err = -EINVAL;
8301da177e4SLinus Torvalds 		break;
8311da177e4SLinus Torvalds 	}
832e4e8e37cSMarcel Holtmann 
8330736cfa8SMarcel Holtmann done:
8341da177e4SLinus Torvalds 	hci_dev_put(hdev);
8351da177e4SLinus Torvalds 	return err;
8361da177e4SLinus Torvalds }
8371da177e4SLinus Torvalds 
8381da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
8391da177e4SLinus Torvalds {
8408035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
8411da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
8421da177e4SLinus Torvalds 	struct hci_dev_req *dr;
8431da177e4SLinus Torvalds 	int n = 0, size, err;
8441da177e4SLinus Torvalds 	__u16 dev_num;
8451da177e4SLinus Torvalds 
8461da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
8471da177e4SLinus Torvalds 		return -EFAULT;
8481da177e4SLinus Torvalds 
8491da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
8501da177e4SLinus Torvalds 		return -EINVAL;
8511da177e4SLinus Torvalds 
8521da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
8531da177e4SLinus Torvalds 
85470f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
85570f23020SAndrei Emeltchenko 	if (!dl)
8561da177e4SLinus Torvalds 		return -ENOMEM;
8571da177e4SLinus Torvalds 
8581da177e4SLinus Torvalds 	dr = dl->dev_req;
8591da177e4SLinus Torvalds 
860f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
8618035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
8622e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
863c542a06cSJohan Hedberg 
8642e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
8652e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
8662e84d8dbSMarcel Holtmann 		 * device is actually down.
8672e84d8dbSMarcel Holtmann 		 */
868d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
8692e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
870c542a06cSJohan Hedberg 
8711da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
8722e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
873c542a06cSJohan Hedberg 
8741da177e4SLinus Torvalds 		if (++n >= dev_num)
8751da177e4SLinus Torvalds 			break;
8761da177e4SLinus Torvalds 	}
877f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
8781da177e4SLinus Torvalds 
8791da177e4SLinus Torvalds 	dl->dev_num = n;
8801da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
8811da177e4SLinus Torvalds 
8821da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
8831da177e4SLinus Torvalds 	kfree(dl);
8841da177e4SLinus Torvalds 
8851da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
8861da177e4SLinus Torvalds }
8871da177e4SLinus Torvalds 
8881da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
8891da177e4SLinus Torvalds {
8901da177e4SLinus Torvalds 	struct hci_dev *hdev;
8911da177e4SLinus Torvalds 	struct hci_dev_info di;
8922e84d8dbSMarcel Holtmann 	unsigned long flags;
8931da177e4SLinus Torvalds 	int err = 0;
8941da177e4SLinus Torvalds 
8951da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
8961da177e4SLinus Torvalds 		return -EFAULT;
8971da177e4SLinus Torvalds 
89870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
89970f23020SAndrei Emeltchenko 	if (!hdev)
9001da177e4SLinus Torvalds 		return -ENODEV;
9011da177e4SLinus Torvalds 
9022e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
9032e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
9042e84d8dbSMarcel Holtmann 	 * device is actually down.
9052e84d8dbSMarcel Holtmann 	 */
906d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
9072e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
9082e84d8dbSMarcel Holtmann 	else
9092e84d8dbSMarcel Holtmann 		flags = hdev->flags;
910c542a06cSJohan Hedberg 
911*a41c8efeSLuiz Augusto von Dentz 	strscpy(di.name, hdev->name, sizeof(di.name));
9121da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
91360f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
9142e84d8dbSMarcel Holtmann 	di.flags    = flags;
9151da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
916572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
9171da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
9181da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
9191da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
9201da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
921572c7f84SJohan Hedberg 	} else {
922572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
923572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
924572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
925572c7f84SJohan Hedberg 		di.sco_pkts = 0;
926572c7f84SJohan Hedberg 	}
9271da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
9281da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
9291da177e4SLinus Torvalds 
9301da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
9311da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
9321da177e4SLinus Torvalds 
9331da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
9341da177e4SLinus Torvalds 		err = -EFAULT;
9351da177e4SLinus Torvalds 
9361da177e4SLinus Torvalds 	hci_dev_put(hdev);
9371da177e4SLinus Torvalds 
9381da177e4SLinus Torvalds 	return err;
9391da177e4SLinus Torvalds }
9401da177e4SLinus Torvalds 
9411da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
9421da177e4SLinus Torvalds 
943611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
944611b30f7SMarcel Holtmann {
945611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
946611b30f7SMarcel Holtmann 
947611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
948611b30f7SMarcel Holtmann 
949d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
9500736cfa8SMarcel Holtmann 		return -EBUSY;
9510736cfa8SMarcel Holtmann 
9525e130367SJohan Hedberg 	if (blocked) {
953a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
954d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
955d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG))
956611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
9575e130367SJohan Hedberg 	} else {
958a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_RFKILLED);
9595e130367SJohan Hedberg 	}
960611b30f7SMarcel Holtmann 
961611b30f7SMarcel Holtmann 	return 0;
962611b30f7SMarcel Holtmann }
963611b30f7SMarcel Holtmann 
964611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
965611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
966611b30f7SMarcel Holtmann };
967611b30f7SMarcel Holtmann 
968ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
969ab81cbf9SJohan Hedberg {
970ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
97196570ffcSJohan Hedberg 	int err;
972ab81cbf9SJohan Hedberg 
973ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
974ab81cbf9SJohan Hedberg 
9752ff13894SJohan Hedberg 	if (test_bit(HCI_UP, &hdev->flags) &&
9762ff13894SJohan Hedberg 	    hci_dev_test_flag(hdev, HCI_MGMT) &&
9772ff13894SJohan Hedberg 	    hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
978d82142a8SWei-Ning Huang 		cancel_delayed_work(&hdev->power_off);
979cf75ad8bSLuiz Augusto von Dentz 		err = hci_powered_update_sync(hdev);
9802ff13894SJohan Hedberg 		mgmt_power_on(hdev, err);
9812ff13894SJohan Hedberg 		return;
9822ff13894SJohan Hedberg 	}
9832ff13894SJohan Hedberg 
984cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
98596570ffcSJohan Hedberg 	if (err < 0) {
9863ad67582SJaganath Kanakkassery 		hci_dev_lock(hdev);
98796570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
9883ad67582SJaganath Kanakkassery 		hci_dev_unlock(hdev);
989ab81cbf9SJohan Hedberg 		return;
99096570ffcSJohan Hedberg 	}
991ab81cbf9SJohan Hedberg 
992a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
993a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
994a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
995a5c8f270SMarcel Holtmann 	 */
996d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
997d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
998ca8bee5dSMarcel Holtmann 	    (hdev->dev_type == HCI_PRIMARY &&
999a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1000a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
1001a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
1002bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
1003d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
100419202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
100519202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
1006bf543036SJohan Hedberg 	}
1007ab81cbf9SJohan Hedberg 
1008a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
10094a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
10104a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
10114a964404SMarcel Holtmann 		 */
1012d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
10134a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
10140602a8adSMarcel Holtmann 
10150602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
10160602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
10170602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
10180602a8adSMarcel Holtmann 		 *
10190602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
10200602a8adSMarcel Holtmann 		 * and no event will be send.
10210602a8adSMarcel Holtmann 		 */
1022744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1023a69d8927SMarcel Holtmann 	} else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
10245ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
10255ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
10265ea234d3SMarcel Holtmann 		 */
1027d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
10285ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
10295ea234d3SMarcel Holtmann 
1030d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
1031d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
1032d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
1033d603b76bSMarcel Holtmann 		 */
1034d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
1035ab81cbf9SJohan Hedberg 	}
1036ab81cbf9SJohan Hedberg }
1037ab81cbf9SJohan Hedberg 
1038ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1039ab81cbf9SJohan Hedberg {
10403243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
10413243553fSJohan Hedberg 					    power_off.work);
1042ab81cbf9SJohan Hedberg 
1043ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1044ab81cbf9SJohan Hedberg 
10458ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1046ab81cbf9SJohan Hedberg }
1047ab81cbf9SJohan Hedberg 
1048c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work)
1049c7741d16SMarcel Holtmann {
1050c7741d16SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
1051c7741d16SMarcel Holtmann 
10522ab9a19dSYing Hsu 	hci_dev_hold(hdev);
1053c7741d16SMarcel Holtmann 	BT_DBG("%s", hdev->name);
1054c7741d16SMarcel Holtmann 
1055c7741d16SMarcel Holtmann 	if (hdev->hw_error)
1056c7741d16SMarcel Holtmann 		hdev->hw_error(hdev, hdev->hw_error_code);
1057c7741d16SMarcel Holtmann 	else
10582064ee33SMarcel Holtmann 		bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code);
1059c7741d16SMarcel Holtmann 
10602ab9a19dSYing Hsu 	if (!hci_dev_do_close(hdev))
1061c7741d16SMarcel Holtmann 		hci_dev_do_open(hdev);
10622ab9a19dSYing Hsu 
10632ab9a19dSYing Hsu 	hci_dev_put(hdev);
1064c7741d16SMarcel Holtmann }
1065c7741d16SMarcel Holtmann 
106635f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
10672aeb9a1aSJohan Hedberg {
10684821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
10692aeb9a1aSJohan Hedberg 
10704821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
10714821002cSJohan Hedberg 		list_del(&uuid->list);
10722aeb9a1aSJohan Hedberg 		kfree(uuid);
10732aeb9a1aSJohan Hedberg 	}
10742aeb9a1aSJohan Hedberg }
10752aeb9a1aSJohan Hedberg 
107635f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
107755ed8ca1SJohan Hedberg {
10783673952cSMin Li 	struct link_key *key, *tmp;
107955ed8ca1SJohan Hedberg 
10803673952cSMin Li 	list_for_each_entry_safe(key, tmp, &hdev->link_keys, list) {
10810378b597SJohan Hedberg 		list_del_rcu(&key->list);
10820378b597SJohan Hedberg 		kfree_rcu(key, rcu);
108355ed8ca1SJohan Hedberg 	}
108455ed8ca1SJohan Hedberg }
108555ed8ca1SJohan Hedberg 
108635f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
1087b899efafSVinicius Costa Gomes {
10883673952cSMin Li 	struct smp_ltk *k, *tmp;
1089b899efafSVinicius Costa Gomes 
10903673952cSMin Li 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1091970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
1092970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
1093b899efafSVinicius Costa Gomes 	}
1094b899efafSVinicius Costa Gomes }
1095b899efafSVinicius Costa Gomes 
1096970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
1097970c4e46SJohan Hedberg {
10983673952cSMin Li 	struct smp_irk *k, *tmp;
1099970c4e46SJohan Hedberg 
11003673952cSMin Li 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
1101adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
1102adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
1103970c4e46SJohan Hedberg 	}
1104970c4e46SJohan Hedberg }
1105970c4e46SJohan Hedberg 
1106600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev)
1107600a8749SAlain Michaud {
11083673952cSMin Li 	struct blocked_key *b, *tmp;
1109600a8749SAlain Michaud 
11103673952cSMin Li 	list_for_each_entry_safe(b, tmp, &hdev->blocked_keys, list) {
1111600a8749SAlain Michaud 		list_del_rcu(&b->list);
1112600a8749SAlain Michaud 		kfree_rcu(b, rcu);
1113600a8749SAlain Michaud 	}
1114600a8749SAlain Michaud }
1115600a8749SAlain Michaud 
1116600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16])
1117600a8749SAlain Michaud {
1118600a8749SAlain Michaud 	bool blocked = false;
1119600a8749SAlain Michaud 	struct blocked_key *b;
1120600a8749SAlain Michaud 
1121600a8749SAlain Michaud 	rcu_read_lock();
11220c2ac7d4SMadhuparna Bhowmik 	list_for_each_entry_rcu(b, &hdev->blocked_keys, list) {
1123600a8749SAlain Michaud 		if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) {
1124600a8749SAlain Michaud 			blocked = true;
1125600a8749SAlain Michaud 			break;
1126600a8749SAlain Michaud 		}
1127600a8749SAlain Michaud 	}
1128600a8749SAlain Michaud 
1129600a8749SAlain Michaud 	rcu_read_unlock();
1130600a8749SAlain Michaud 	return blocked;
1131600a8749SAlain Michaud }
1132600a8749SAlain Michaud 
113355ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
113455ed8ca1SJohan Hedberg {
113555ed8ca1SJohan Hedberg 	struct link_key *k;
113655ed8ca1SJohan Hedberg 
11370378b597SJohan Hedberg 	rcu_read_lock();
11380378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
11390378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
11400378b597SJohan Hedberg 			rcu_read_unlock();
1141600a8749SAlain Michaud 
1142600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev,
1143600a8749SAlain Michaud 					       HCI_BLOCKED_KEY_TYPE_LINKKEY,
1144600a8749SAlain Michaud 					       k->val)) {
1145600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
1146600a8749SAlain Michaud 							"Link key blocked for %pMR",
1147600a8749SAlain Michaud 							&k->bdaddr);
1148600a8749SAlain Michaud 				return NULL;
1149600a8749SAlain Michaud 			}
1150600a8749SAlain Michaud 
115155ed8ca1SJohan Hedberg 			return k;
11520378b597SJohan Hedberg 		}
11530378b597SJohan Hedberg 	}
11540378b597SJohan Hedberg 	rcu_read_unlock();
115555ed8ca1SJohan Hedberg 
115655ed8ca1SJohan Hedberg 	return NULL;
115755ed8ca1SJohan Hedberg }
115855ed8ca1SJohan Hedberg 
1159745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1160d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1161d25e28abSJohan Hedberg {
1162d25e28abSJohan Hedberg 	/* Legacy key */
1163d25e28abSJohan Hedberg 	if (key_type < 0x03)
1164745c0ce3SVishal Agarwal 		return true;
1165d25e28abSJohan Hedberg 
1166d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1167d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1168745c0ce3SVishal Agarwal 		return false;
1169d25e28abSJohan Hedberg 
1170d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1171d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1172745c0ce3SVishal Agarwal 		return false;
1173d25e28abSJohan Hedberg 
1174d25e28abSJohan Hedberg 	/* Security mode 3 case */
1175d25e28abSJohan Hedberg 	if (!conn)
1176745c0ce3SVishal Agarwal 		return true;
1177d25e28abSJohan Hedberg 
1178e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
1179e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
1180e3befab9SJohan Hedberg 		return true;
1181e3befab9SJohan Hedberg 
1182d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1183d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1184745c0ce3SVishal Agarwal 		return true;
1185d25e28abSJohan Hedberg 
1186d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1187d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1188745c0ce3SVishal Agarwal 		return true;
1189d25e28abSJohan Hedberg 
1190d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1191d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1192745c0ce3SVishal Agarwal 		return true;
1193d25e28abSJohan Hedberg 
1194d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1195d25e28abSJohan Hedberg 	 * persistently */
1196745c0ce3SVishal Agarwal 	return false;
1197d25e28abSJohan Hedberg }
1198d25e28abSJohan Hedberg 
1199e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
120098a0b845SJohan Hedberg {
1201e804d25dSJohan Hedberg 	if (type == SMP_LTK)
1202e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
120398a0b845SJohan Hedberg 
1204e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
120598a0b845SJohan Hedberg }
120698a0b845SJohan Hedberg 
1207f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
1208e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
120975d262c2SVinicius Costa Gomes {
1210c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
121175d262c2SVinicius Costa Gomes 
1212970d0f1bSJohan Hedberg 	rcu_read_lock();
1213970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
12145378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
12155378bc56SJohan Hedberg 			continue;
12165378bc56SJohan Hedberg 
1217923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
1218970d0f1bSJohan Hedberg 			rcu_read_unlock();
1219600a8749SAlain Michaud 
1220600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK,
1221600a8749SAlain Michaud 					       k->val)) {
1222600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
1223600a8749SAlain Michaud 							"LTK blocked for %pMR",
1224600a8749SAlain Michaud 							&k->bdaddr);
1225600a8749SAlain Michaud 				return NULL;
1226600a8749SAlain Michaud 			}
1227600a8749SAlain Michaud 
122875d262c2SVinicius Costa Gomes 			return k;
1229970d0f1bSJohan Hedberg 		}
1230970d0f1bSJohan Hedberg 	}
1231970d0f1bSJohan Hedberg 	rcu_read_unlock();
123275d262c2SVinicius Costa Gomes 
123375d262c2SVinicius Costa Gomes 	return NULL;
123475d262c2SVinicius Costa Gomes }
123575d262c2SVinicius Costa Gomes 
1236970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
1237970c4e46SJohan Hedberg {
1238600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
1239970c4e46SJohan Hedberg 	struct smp_irk *irk;
1240970c4e46SJohan Hedberg 
1241adae20cbSJohan Hedberg 	rcu_read_lock();
1242adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1243adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
1244600a8749SAlain Michaud 			irk_to_return = irk;
1245600a8749SAlain Michaud 			goto done;
1246970c4e46SJohan Hedberg 		}
1247adae20cbSJohan Hedberg 	}
1248970c4e46SJohan Hedberg 
1249adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1250defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
1251970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
1252600a8749SAlain Michaud 			irk_to_return = irk;
1253600a8749SAlain Michaud 			goto done;
1254970c4e46SJohan Hedberg 		}
1255970c4e46SJohan Hedberg 	}
1256600a8749SAlain Michaud 
1257600a8749SAlain Michaud done:
1258600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
1259600a8749SAlain Michaud 						irk_to_return->val)) {
1260600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
1261600a8749SAlain Michaud 					&irk_to_return->bdaddr);
1262600a8749SAlain Michaud 		irk_to_return = NULL;
1263600a8749SAlain Michaud 	}
1264600a8749SAlain Michaud 
1265adae20cbSJohan Hedberg 	rcu_read_unlock();
1266970c4e46SJohan Hedberg 
1267600a8749SAlain Michaud 	return irk_to_return;
1268970c4e46SJohan Hedberg }
1269970c4e46SJohan Hedberg 
1270970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1271970c4e46SJohan Hedberg 				     u8 addr_type)
1272970c4e46SJohan Hedberg {
1273600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
1274970c4e46SJohan Hedberg 	struct smp_irk *irk;
1275970c4e46SJohan Hedberg 
12766cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
12776cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
12786cfc9988SJohan Hedberg 		return NULL;
12796cfc9988SJohan Hedberg 
1280adae20cbSJohan Hedberg 	rcu_read_lock();
1281adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1282970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
1283adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
1284600a8749SAlain Michaud 			irk_to_return = irk;
1285600a8749SAlain Michaud 			goto done;
1286970c4e46SJohan Hedberg 		}
1287adae20cbSJohan Hedberg 	}
1288600a8749SAlain Michaud 
1289600a8749SAlain Michaud done:
1290600a8749SAlain Michaud 
1291600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
1292600a8749SAlain Michaud 						irk_to_return->val)) {
1293600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
1294600a8749SAlain Michaud 					&irk_to_return->bdaddr);
1295600a8749SAlain Michaud 		irk_to_return = NULL;
1296600a8749SAlain Michaud 	}
1297600a8749SAlain Michaud 
1298adae20cbSJohan Hedberg 	rcu_read_unlock();
1299970c4e46SJohan Hedberg 
1300600a8749SAlain Michaud 	return irk_to_return;
1301970c4e46SJohan Hedberg }
1302970c4e46SJohan Hedberg 
1303567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
13047652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
13057652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
130655ed8ca1SJohan Hedberg {
130755ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1308745c0ce3SVishal Agarwal 	u8 old_key_type;
130955ed8ca1SJohan Hedberg 
131055ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
131155ed8ca1SJohan Hedberg 	if (old_key) {
131255ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
131355ed8ca1SJohan Hedberg 		key = old_key;
131455ed8ca1SJohan Hedberg 	} else {
131512adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
13160a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
131755ed8ca1SJohan Hedberg 		if (!key)
1318567fa2aaSJohan Hedberg 			return NULL;
13190378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
132055ed8ca1SJohan Hedberg 	}
132155ed8ca1SJohan Hedberg 
13226ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
132355ed8ca1SJohan Hedberg 
1324d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1325d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1326d25e28abSJohan Hedberg 	 * previous key */
1327d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1328a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1329d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1330655fe6ecSJohan Hedberg 		if (conn)
1331655fe6ecSJohan Hedberg 			conn->key_type = type;
1332655fe6ecSJohan Hedberg 	}
1333d25e28abSJohan Hedberg 
133455ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
13359b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
133655ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
133755ed8ca1SJohan Hedberg 
1338b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
133955ed8ca1SJohan Hedberg 		key->type = old_key_type;
13404748fed2SJohan Hedberg 	else
13414748fed2SJohan Hedberg 		key->type = type;
13424748fed2SJohan Hedberg 
13437652ff6aSJohan Hedberg 	if (persistent)
13447652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
13457652ff6aSJohan Hedberg 						 old_key_type);
13464df378a1SJohan Hedberg 
1347567fa2aaSJohan Hedberg 	return key;
134855ed8ca1SJohan Hedberg }
134955ed8ca1SJohan Hedberg 
1350ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
135135d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
1352fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
135375d262c2SVinicius Costa Gomes {
1354c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
1355e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
135675d262c2SVinicius Costa Gomes 
1357f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
1358c9839a11SVinicius Costa Gomes 	if (old_key)
135975d262c2SVinicius Costa Gomes 		key = old_key;
1360c9839a11SVinicius Costa Gomes 	else {
13610a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
136275d262c2SVinicius Costa Gomes 		if (!key)
1363ca9142b8SJohan Hedberg 			return NULL;
1364970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
136575d262c2SVinicius Costa Gomes 	}
136675d262c2SVinicius Costa Gomes 
136775d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1368c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1369c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1370c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1371c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1372fe39c7b2SMarcel Holtmann 	key->rand = rand;
1373c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1374c9839a11SVinicius Costa Gomes 	key->type = type;
137575d262c2SVinicius Costa Gomes 
1376ca9142b8SJohan Hedberg 	return key;
137775d262c2SVinicius Costa Gomes }
137875d262c2SVinicius Costa Gomes 
1379ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
1380ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
1381970c4e46SJohan Hedberg {
1382970c4e46SJohan Hedberg 	struct smp_irk *irk;
1383970c4e46SJohan Hedberg 
1384970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
1385970c4e46SJohan Hedberg 	if (!irk) {
1386970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
1387970c4e46SJohan Hedberg 		if (!irk)
1388ca9142b8SJohan Hedberg 			return NULL;
1389970c4e46SJohan Hedberg 
1390970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
1391970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
1392970c4e46SJohan Hedberg 
1393adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
1394970c4e46SJohan Hedberg 	}
1395970c4e46SJohan Hedberg 
1396970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
1397970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
1398970c4e46SJohan Hedberg 
1399ca9142b8SJohan Hedberg 	return irk;
1400970c4e46SJohan Hedberg }
1401970c4e46SJohan Hedberg 
140255ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
140355ed8ca1SJohan Hedberg {
140455ed8ca1SJohan Hedberg 	struct link_key *key;
140555ed8ca1SJohan Hedberg 
140655ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
140755ed8ca1SJohan Hedberg 	if (!key)
140855ed8ca1SJohan Hedberg 		return -ENOENT;
140955ed8ca1SJohan Hedberg 
14106ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
141155ed8ca1SJohan Hedberg 
14120378b597SJohan Hedberg 	list_del_rcu(&key->list);
14130378b597SJohan Hedberg 	kfree_rcu(key, rcu);
141455ed8ca1SJohan Hedberg 
141555ed8ca1SJohan Hedberg 	return 0;
141655ed8ca1SJohan Hedberg }
141755ed8ca1SJohan Hedberg 
1418e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
1419b899efafSVinicius Costa Gomes {
1420c5d2b6faSLuiz Augusto von Dentz 	struct smp_ltk *k, *tmp;
1421c51ffa0bSJohan Hedberg 	int removed = 0;
1422b899efafSVinicius Costa Gomes 
1423c5d2b6faSLuiz Augusto von Dentz 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1424e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
1425b899efafSVinicius Costa Gomes 			continue;
1426b899efafSVinicius Costa Gomes 
14276ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1428b899efafSVinicius Costa Gomes 
1429970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
1430970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
1431c51ffa0bSJohan Hedberg 		removed++;
1432b899efafSVinicius Costa Gomes 	}
1433b899efafSVinicius Costa Gomes 
1434c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
1435b899efafSVinicius Costa Gomes }
1436b899efafSVinicius Costa Gomes 
1437a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
1438a7ec7338SJohan Hedberg {
1439c5d2b6faSLuiz Augusto von Dentz 	struct smp_irk *k, *tmp;
1440a7ec7338SJohan Hedberg 
1441c5d2b6faSLuiz Augusto von Dentz 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
1442a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
1443a7ec7338SJohan Hedberg 			continue;
1444a7ec7338SJohan Hedberg 
1445a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1446a7ec7338SJohan Hedberg 
1447adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
1448adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
1449a7ec7338SJohan Hedberg 	}
1450a7ec7338SJohan Hedberg }
1451a7ec7338SJohan Hedberg 
145255e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
145355e76b38SJohan Hedberg {
145455e76b38SJohan Hedberg 	struct smp_ltk *k;
14554ba9faf3SJohan Hedberg 	struct smp_irk *irk;
145655e76b38SJohan Hedberg 	u8 addr_type;
145755e76b38SJohan Hedberg 
145855e76b38SJohan Hedberg 	if (type == BDADDR_BREDR) {
145955e76b38SJohan Hedberg 		if (hci_find_link_key(hdev, bdaddr))
146055e76b38SJohan Hedberg 			return true;
146155e76b38SJohan Hedberg 		return false;
146255e76b38SJohan Hedberg 	}
146355e76b38SJohan Hedberg 
146455e76b38SJohan Hedberg 	/* Convert to HCI addr type which struct smp_ltk uses */
146555e76b38SJohan Hedberg 	if (type == BDADDR_LE_PUBLIC)
146655e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_PUBLIC;
146755e76b38SJohan Hedberg 	else
146855e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_RANDOM;
146955e76b38SJohan Hedberg 
14704ba9faf3SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, addr_type);
14714ba9faf3SJohan Hedberg 	if (irk) {
14724ba9faf3SJohan Hedberg 		bdaddr = &irk->bdaddr;
14734ba9faf3SJohan Hedberg 		addr_type = irk->addr_type;
14744ba9faf3SJohan Hedberg 	}
14754ba9faf3SJohan Hedberg 
147655e76b38SJohan Hedberg 	rcu_read_lock();
147755e76b38SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
147887c8b28dSJohan Hedberg 		if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) {
147987c8b28dSJohan Hedberg 			rcu_read_unlock();
148055e76b38SJohan Hedberg 			return true;
148155e76b38SJohan Hedberg 		}
148287c8b28dSJohan Hedberg 	}
148355e76b38SJohan Hedberg 	rcu_read_unlock();
148455e76b38SJohan Hedberg 
148555e76b38SJohan Hedberg 	return false;
148655e76b38SJohan Hedberg }
148755e76b38SJohan Hedberg 
14886bd32326SVille Tervo /* HCI command timer function */
148965cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
14906bd32326SVille Tervo {
149165cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
149265cc2b49SMarcel Holtmann 					    cmd_timer.work);
14936bd32326SVille Tervo 
14942af7aa66SLuiz Augusto von Dentz 	if (hdev->req_skb) {
14952af7aa66SLuiz Augusto von Dentz 		u16 opcode = hci_skb_opcode(hdev->req_skb);
1496bda4f23aSAndrei Emeltchenko 
14972064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode);
14980ce1229cSLuiz Augusto von Dentz 
14990ce1229cSLuiz Augusto von Dentz 		hci_cmd_sync_cancel_sync(hdev, ETIMEDOUT);
1500bda4f23aSAndrei Emeltchenko 	} else {
15012064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command tx timeout");
1502bda4f23aSAndrei Emeltchenko 	}
1503bda4f23aSAndrei Emeltchenko 
1504e2bef384SRajat Jain 	if (hdev->cmd_timeout)
1505e2bef384SRajat Jain 		hdev->cmd_timeout(hdev);
1506e2bef384SRajat Jain 
15076bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1508c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
15096bd32326SVille Tervo }
15106bd32326SVille Tervo 
1511de75cd0dSManish Mandlik /* HCI ncmd timer function */
1512de75cd0dSManish Mandlik static void hci_ncmd_timeout(struct work_struct *work)
1513de75cd0dSManish Mandlik {
1514de75cd0dSManish Mandlik 	struct hci_dev *hdev = container_of(work, struct hci_dev,
1515de75cd0dSManish Mandlik 					    ncmd_timer.work);
1516de75cd0dSManish Mandlik 
1517de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Controller not accepting commands anymore: ncmd = 0");
1518de75cd0dSManish Mandlik 
1519de75cd0dSManish Mandlik 	/* During HCI_INIT phase no events can be injected if the ncmd timer
1520de75cd0dSManish Mandlik 	 * triggers since the procedure has its own timeout handling.
1521de75cd0dSManish Mandlik 	 */
1522de75cd0dSManish Mandlik 	if (test_bit(HCI_INIT, &hdev->flags))
1523de75cd0dSManish Mandlik 		return;
1524de75cd0dSManish Mandlik 
1525de75cd0dSManish Mandlik 	/* This is an irrecoverable state, inject hardware error event */
1526de75cd0dSManish Mandlik 	hci_reset_dev(hdev);
1527de75cd0dSManish Mandlik }
1528de75cd0dSManish Mandlik 
15292763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
15306928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
15312763eda6SSzymon Janc {
15322763eda6SSzymon Janc 	struct oob_data *data;
15332763eda6SSzymon Janc 
15346928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
15356928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
15366928a924SJohan Hedberg 			continue;
15376928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
15386928a924SJohan Hedberg 			continue;
15392763eda6SSzymon Janc 		return data;
15406928a924SJohan Hedberg 	}
15412763eda6SSzymon Janc 
15422763eda6SSzymon Janc 	return NULL;
15432763eda6SSzymon Janc }
15442763eda6SSzymon Janc 
15456928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
15466928a924SJohan Hedberg 			       u8 bdaddr_type)
15472763eda6SSzymon Janc {
15482763eda6SSzymon Janc 	struct oob_data *data;
15492763eda6SSzymon Janc 
15506928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
15512763eda6SSzymon Janc 	if (!data)
15522763eda6SSzymon Janc 		return -ENOENT;
15532763eda6SSzymon Janc 
15546928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
15552763eda6SSzymon Janc 
15562763eda6SSzymon Janc 	list_del(&data->list);
15572763eda6SSzymon Janc 	kfree(data);
15582763eda6SSzymon Janc 
15592763eda6SSzymon Janc 	return 0;
15602763eda6SSzymon Janc }
15612763eda6SSzymon Janc 
156235f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
15632763eda6SSzymon Janc {
15642763eda6SSzymon Janc 	struct oob_data *data, *n;
15652763eda6SSzymon Janc 
15662763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
15672763eda6SSzymon Janc 		list_del(&data->list);
15682763eda6SSzymon Janc 		kfree(data);
15692763eda6SSzymon Janc 	}
15702763eda6SSzymon Janc }
15712763eda6SSzymon Janc 
15720798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
15736928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
157438da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
15750798872eSMarcel Holtmann {
15760798872eSMarcel Holtmann 	struct oob_data *data;
15770798872eSMarcel Holtmann 
15786928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
15790798872eSMarcel Holtmann 	if (!data) {
15800a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
15810798872eSMarcel Holtmann 		if (!data)
15820798872eSMarcel Holtmann 			return -ENOMEM;
15830798872eSMarcel Holtmann 
15840798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
15856928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
15860798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
15870798872eSMarcel Holtmann 	}
15880798872eSMarcel Holtmann 
158981328d5cSJohan Hedberg 	if (hash192 && rand192) {
15900798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
159138da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
1592f7697b16SMarcel Holtmann 		if (hash256 && rand256)
1593f7697b16SMarcel Holtmann 			data->present = 0x03;
159481328d5cSJohan Hedberg 	} else {
159581328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
159681328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
1597f7697b16SMarcel Holtmann 		if (hash256 && rand256)
1598f7697b16SMarcel Holtmann 			data->present = 0x02;
1599f7697b16SMarcel Holtmann 		else
1600f7697b16SMarcel Holtmann 			data->present = 0x00;
160181328d5cSJohan Hedberg 	}
16020798872eSMarcel Holtmann 
160381328d5cSJohan Hedberg 	if (hash256 && rand256) {
16040798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
160538da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
160681328d5cSJohan Hedberg 	} else {
160781328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
160881328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
1609f7697b16SMarcel Holtmann 		if (hash192 && rand192)
1610f7697b16SMarcel Holtmann 			data->present = 0x01;
161181328d5cSJohan Hedberg 	}
16120798872eSMarcel Holtmann 
16136ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
16142763eda6SSzymon Janc 
16152763eda6SSzymon Janc 	return 0;
16162763eda6SSzymon Janc }
16172763eda6SSzymon Janc 
1618d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1619d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance)
1620d2609b34SFlorian Grandel {
1621d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
1622d2609b34SFlorian Grandel 
1623d2609b34SFlorian Grandel 	list_for_each_entry(adv_instance, &hdev->adv_instances, list) {
1624d2609b34SFlorian Grandel 		if (adv_instance->instance == instance)
1625d2609b34SFlorian Grandel 			return adv_instance;
1626d2609b34SFlorian Grandel 	}
1627d2609b34SFlorian Grandel 
1628d2609b34SFlorian Grandel 	return NULL;
1629d2609b34SFlorian Grandel }
1630d2609b34SFlorian Grandel 
1631d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
163274b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance)
163374b93e9fSPrasanna Karthik {
1634d2609b34SFlorian Grandel 	struct adv_info *cur_instance;
1635d2609b34SFlorian Grandel 
1636d2609b34SFlorian Grandel 	cur_instance = hci_find_adv_instance(hdev, instance);
1637d2609b34SFlorian Grandel 	if (!cur_instance)
1638d2609b34SFlorian Grandel 		return NULL;
1639d2609b34SFlorian Grandel 
1640d2609b34SFlorian Grandel 	if (cur_instance == list_last_entry(&hdev->adv_instances,
1641d2609b34SFlorian Grandel 					    struct adv_info, list))
1642d2609b34SFlorian Grandel 		return list_first_entry(&hdev->adv_instances,
1643d2609b34SFlorian Grandel 						 struct adv_info, list);
1644d2609b34SFlorian Grandel 	else
1645d2609b34SFlorian Grandel 		return list_next_entry(cur_instance, list);
1646d2609b34SFlorian Grandel }
1647d2609b34SFlorian Grandel 
1648d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1649d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance)
1650d2609b34SFlorian Grandel {
1651d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
1652d2609b34SFlorian Grandel 
1653d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
1654d2609b34SFlorian Grandel 	if (!adv_instance)
1655d2609b34SFlorian Grandel 		return -ENOENT;
1656d2609b34SFlorian Grandel 
1657d2609b34SFlorian Grandel 	BT_DBG("%s removing %dMR", hdev->name, instance);
1658d2609b34SFlorian Grandel 
1659cab054abSJohan Hedberg 	if (hdev->cur_adv_instance == instance) {
1660cab054abSJohan Hedberg 		if (hdev->adv_instance_timeout) {
16615d900e46SFlorian Grandel 			cancel_delayed_work(&hdev->adv_instance_expire);
16625d900e46SFlorian Grandel 			hdev->adv_instance_timeout = 0;
16635d900e46SFlorian Grandel 		}
1664cab054abSJohan Hedberg 		hdev->cur_adv_instance = 0x00;
1665cab054abSJohan Hedberg 	}
16665d900e46SFlorian Grandel 
1667a73c046aSJaganath Kanakkassery 	cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1668a73c046aSJaganath Kanakkassery 
1669d2609b34SFlorian Grandel 	list_del(&adv_instance->list);
1670d2609b34SFlorian Grandel 	kfree(adv_instance);
1671d2609b34SFlorian Grandel 
1672d2609b34SFlorian Grandel 	hdev->adv_instance_cnt--;
1673d2609b34SFlorian Grandel 
1674d2609b34SFlorian Grandel 	return 0;
1675d2609b34SFlorian Grandel }
1676d2609b34SFlorian Grandel 
1677a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired)
1678a73c046aSJaganath Kanakkassery {
1679a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance, *n;
1680a73c046aSJaganath Kanakkassery 
1681a73c046aSJaganath Kanakkassery 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list)
1682a73c046aSJaganath Kanakkassery 		adv_instance->rpa_expired = rpa_expired;
1683a73c046aSJaganath Kanakkassery }
1684a73c046aSJaganath Kanakkassery 
1685d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1686d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev)
1687d2609b34SFlorian Grandel {
1688d2609b34SFlorian Grandel 	struct adv_info *adv_instance, *n;
1689d2609b34SFlorian Grandel 
16905d900e46SFlorian Grandel 	if (hdev->adv_instance_timeout) {
16915d900e46SFlorian Grandel 		cancel_delayed_work(&hdev->adv_instance_expire);
16925d900e46SFlorian Grandel 		hdev->adv_instance_timeout = 0;
16935d900e46SFlorian Grandel 	}
16945d900e46SFlorian Grandel 
1695d2609b34SFlorian Grandel 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
1696a73c046aSJaganath Kanakkassery 		cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1697d2609b34SFlorian Grandel 		list_del(&adv_instance->list);
1698d2609b34SFlorian Grandel 		kfree(adv_instance);
1699d2609b34SFlorian Grandel 	}
1700d2609b34SFlorian Grandel 
1701d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
1702cab054abSJohan Hedberg 	hdev->cur_adv_instance = 0x00;
1703d2609b34SFlorian Grandel }
1704d2609b34SFlorian Grandel 
1705a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work)
1706a73c046aSJaganath Kanakkassery {
1707a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance = container_of(work, struct adv_info,
1708a73c046aSJaganath Kanakkassery 						     rpa_expired_cb.work);
1709a73c046aSJaganath Kanakkassery 
1710a73c046aSJaganath Kanakkassery 	BT_DBG("");
1711a73c046aSJaganath Kanakkassery 
1712a73c046aSJaganath Kanakkassery 	adv_instance->rpa_expired = true;
1713a73c046aSJaganath Kanakkassery }
1714a73c046aSJaganath Kanakkassery 
1715d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1716eca0ae4aSLuiz Augusto von Dentz struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
1717eca0ae4aSLuiz Augusto von Dentz 				      u32 flags, u16 adv_data_len, u8 *adv_data,
1718d2609b34SFlorian Grandel 				      u16 scan_rsp_len, u8 *scan_rsp_data,
17199bf9f4b6SDaniel Winkler 				      u16 timeout, u16 duration, s8 tx_power,
1720b338d917SBrian Gix 				      u32 min_interval, u32 max_interval,
1721b338d917SBrian Gix 				      u8 mesh_handle)
1722d2609b34SFlorian Grandel {
1723eca0ae4aSLuiz Augusto von Dentz 	struct adv_info *adv;
1724d2609b34SFlorian Grandel 
1725eca0ae4aSLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
1726eca0ae4aSLuiz Augusto von Dentz 	if (adv) {
1727eca0ae4aSLuiz Augusto von Dentz 		memset(adv->adv_data, 0, sizeof(adv->adv_data));
1728eca0ae4aSLuiz Augusto von Dentz 		memset(adv->scan_rsp_data, 0, sizeof(adv->scan_rsp_data));
1729eca0ae4aSLuiz Augusto von Dentz 		memset(adv->per_adv_data, 0, sizeof(adv->per_adv_data));
1730d2609b34SFlorian Grandel 	} else {
17311d0fac2cSLuiz Augusto von Dentz 		if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets ||
1732b338d917SBrian Gix 		    instance < 1 || instance > hdev->le_num_of_adv_sets + 1)
1733eca0ae4aSLuiz Augusto von Dentz 			return ERR_PTR(-EOVERFLOW);
1734d2609b34SFlorian Grandel 
1735eca0ae4aSLuiz Augusto von Dentz 		adv = kzalloc(sizeof(*adv), GFP_KERNEL);
1736eca0ae4aSLuiz Augusto von Dentz 		if (!adv)
1737eca0ae4aSLuiz Augusto von Dentz 			return ERR_PTR(-ENOMEM);
1738d2609b34SFlorian Grandel 
1739eca0ae4aSLuiz Augusto von Dentz 		adv->pending = true;
1740eca0ae4aSLuiz Augusto von Dentz 		adv->instance = instance;
1741eca0ae4aSLuiz Augusto von Dentz 		list_add(&adv->list, &hdev->adv_instances);
1742d2609b34SFlorian Grandel 		hdev->adv_instance_cnt++;
1743d2609b34SFlorian Grandel 	}
1744d2609b34SFlorian Grandel 
1745eca0ae4aSLuiz Augusto von Dentz 	adv->flags = flags;
1746eca0ae4aSLuiz Augusto von Dentz 	adv->min_interval = min_interval;
1747eca0ae4aSLuiz Augusto von Dentz 	adv->max_interval = max_interval;
1748eca0ae4aSLuiz Augusto von Dentz 	adv->tx_power = tx_power;
1749b338d917SBrian Gix 	/* Defining a mesh_handle changes the timing units to ms,
1750b338d917SBrian Gix 	 * rather than seconds, and ties the instance to the requested
1751b338d917SBrian Gix 	 * mesh_tx queue.
1752b338d917SBrian Gix 	 */
1753b338d917SBrian Gix 	adv->mesh = mesh_handle;
1754d2609b34SFlorian Grandel 
175534a718bcSLuiz Augusto von Dentz 	hci_set_adv_instance_data(hdev, instance, adv_data_len, adv_data,
175634a718bcSLuiz Augusto von Dentz 				  scan_rsp_len, scan_rsp_data);
1757d2609b34SFlorian Grandel 
1758eca0ae4aSLuiz Augusto von Dentz 	adv->timeout = timeout;
1759eca0ae4aSLuiz Augusto von Dentz 	adv->remaining_time = timeout;
1760d2609b34SFlorian Grandel 
1761d2609b34SFlorian Grandel 	if (duration == 0)
1762eca0ae4aSLuiz Augusto von Dentz 		adv->duration = hdev->def_multi_adv_rotation_duration;
1763d2609b34SFlorian Grandel 	else
1764eca0ae4aSLuiz Augusto von Dentz 		adv->duration = duration;
1765d2609b34SFlorian Grandel 
1766eca0ae4aSLuiz Augusto von Dentz 	INIT_DELAYED_WORK(&adv->rpa_expired_cb, adv_instance_rpa_expired);
1767a73c046aSJaganath Kanakkassery 
1768d2609b34SFlorian Grandel 	BT_DBG("%s for %dMR", hdev->name, instance);
1769d2609b34SFlorian Grandel 
1770eca0ae4aSLuiz Augusto von Dentz 	return adv;
1771eca0ae4aSLuiz Augusto von Dentz }
1772eca0ae4aSLuiz Augusto von Dentz 
1773eca0ae4aSLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */
1774eca0ae4aSLuiz Augusto von Dentz struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance,
1775eca0ae4aSLuiz Augusto von Dentz 				      u32 flags, u8 data_len, u8 *data,
1776eca0ae4aSLuiz Augusto von Dentz 				      u32 min_interval, u32 max_interval)
1777eca0ae4aSLuiz Augusto von Dentz {
1778eca0ae4aSLuiz Augusto von Dentz 	struct adv_info *adv;
1779eca0ae4aSLuiz Augusto von Dentz 
1780eca0ae4aSLuiz Augusto von Dentz 	adv = hci_add_adv_instance(hdev, instance, flags, 0, NULL, 0, NULL,
1781eca0ae4aSLuiz Augusto von Dentz 				   0, 0, HCI_ADV_TX_POWER_NO_PREFERENCE,
1782b338d917SBrian Gix 				   min_interval, max_interval, 0);
1783eca0ae4aSLuiz Augusto von Dentz 	if (IS_ERR(adv))
1784eca0ae4aSLuiz Augusto von Dentz 		return adv;
1785eca0ae4aSLuiz Augusto von Dentz 
1786eca0ae4aSLuiz Augusto von Dentz 	adv->periodic = true;
1787eca0ae4aSLuiz Augusto von Dentz 	adv->per_adv_data_len = data_len;
1788eca0ae4aSLuiz Augusto von Dentz 
1789eca0ae4aSLuiz Augusto von Dentz 	if (data)
1790eca0ae4aSLuiz Augusto von Dentz 		memcpy(adv->per_adv_data, data, data_len);
1791eca0ae4aSLuiz Augusto von Dentz 
1792eca0ae4aSLuiz Augusto von Dentz 	return adv;
1793d2609b34SFlorian Grandel }
1794d2609b34SFlorian Grandel 
1795e5e1e7fdSMiao-chen Chou /* This function requires the caller holds hdev->lock */
179631aab5c2SDaniel Winkler int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance,
179731aab5c2SDaniel Winkler 			      u16 adv_data_len, u8 *adv_data,
179831aab5c2SDaniel Winkler 			      u16 scan_rsp_len, u8 *scan_rsp_data)
179931aab5c2SDaniel Winkler {
180034a718bcSLuiz Augusto von Dentz 	struct adv_info *adv;
180131aab5c2SDaniel Winkler 
180234a718bcSLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
180331aab5c2SDaniel Winkler 
180431aab5c2SDaniel Winkler 	/* If advertisement doesn't exist, we can't modify its data */
180534a718bcSLuiz Augusto von Dentz 	if (!adv)
180631aab5c2SDaniel Winkler 		return -ENOENT;
180731aab5c2SDaniel Winkler 
180834a718bcSLuiz Augusto von Dentz 	if (adv_data_len && ADV_DATA_CMP(adv, adv_data, adv_data_len)) {
180934a718bcSLuiz Augusto von Dentz 		memset(adv->adv_data, 0, sizeof(adv->adv_data));
181034a718bcSLuiz Augusto von Dentz 		memcpy(adv->adv_data, adv_data, adv_data_len);
181134a718bcSLuiz Augusto von Dentz 		adv->adv_data_len = adv_data_len;
181234a718bcSLuiz Augusto von Dentz 		adv->adv_data_changed = true;
181331aab5c2SDaniel Winkler 	}
181431aab5c2SDaniel Winkler 
181534a718bcSLuiz Augusto von Dentz 	if (scan_rsp_len && SCAN_RSP_CMP(adv, scan_rsp_data, scan_rsp_len)) {
181634a718bcSLuiz Augusto von Dentz 		memset(adv->scan_rsp_data, 0, sizeof(adv->scan_rsp_data));
181734a718bcSLuiz Augusto von Dentz 		memcpy(adv->scan_rsp_data, scan_rsp_data, scan_rsp_len);
181834a718bcSLuiz Augusto von Dentz 		adv->scan_rsp_len = scan_rsp_len;
181934a718bcSLuiz Augusto von Dentz 		adv->scan_rsp_changed = true;
182031aab5c2SDaniel Winkler 	}
182131aab5c2SDaniel Winkler 
182234a718bcSLuiz Augusto von Dentz 	/* Mark as changed if there are flags which would affect it */
182334a718bcSLuiz Augusto von Dentz 	if (((adv->flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance) ||
182434a718bcSLuiz Augusto von Dentz 	    adv->flags & MGMT_ADV_FLAG_LOCAL_NAME)
182534a718bcSLuiz Augusto von Dentz 		adv->scan_rsp_changed = true;
182634a718bcSLuiz Augusto von Dentz 
182731aab5c2SDaniel Winkler 	return 0;
182831aab5c2SDaniel Winkler }
182931aab5c2SDaniel Winkler 
183031aab5c2SDaniel Winkler /* This function requires the caller holds hdev->lock */
183101ce70b0SLuiz Augusto von Dentz u32 hci_adv_instance_flags(struct hci_dev *hdev, u8 instance)
183201ce70b0SLuiz Augusto von Dentz {
183301ce70b0SLuiz Augusto von Dentz 	u32 flags;
183401ce70b0SLuiz Augusto von Dentz 	struct adv_info *adv;
183501ce70b0SLuiz Augusto von Dentz 
183601ce70b0SLuiz Augusto von Dentz 	if (instance == 0x00) {
183701ce70b0SLuiz Augusto von Dentz 		/* Instance 0 always manages the "Tx Power" and "Flags"
183801ce70b0SLuiz Augusto von Dentz 		 * fields
183901ce70b0SLuiz Augusto von Dentz 		 */
184001ce70b0SLuiz Augusto von Dentz 		flags = MGMT_ADV_FLAG_TX_POWER | MGMT_ADV_FLAG_MANAGED_FLAGS;
184101ce70b0SLuiz Augusto von Dentz 
184201ce70b0SLuiz Augusto von Dentz 		/* For instance 0, the HCI_ADVERTISING_CONNECTABLE setting
184301ce70b0SLuiz Augusto von Dentz 		 * corresponds to the "connectable" instance flag.
184401ce70b0SLuiz Augusto von Dentz 		 */
184501ce70b0SLuiz Augusto von Dentz 		if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE))
184601ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_CONNECTABLE;
184701ce70b0SLuiz Augusto von Dentz 
184801ce70b0SLuiz Augusto von Dentz 		if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
184901ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
185001ce70b0SLuiz Augusto von Dentz 		else if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
185101ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_DISCOV;
185201ce70b0SLuiz Augusto von Dentz 
185301ce70b0SLuiz Augusto von Dentz 		return flags;
185401ce70b0SLuiz Augusto von Dentz 	}
185501ce70b0SLuiz Augusto von Dentz 
185601ce70b0SLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
185701ce70b0SLuiz Augusto von Dentz 
185801ce70b0SLuiz Augusto von Dentz 	/* Return 0 when we got an invalid instance identifier. */
185901ce70b0SLuiz Augusto von Dentz 	if (!adv)
186001ce70b0SLuiz Augusto von Dentz 		return 0;
186101ce70b0SLuiz Augusto von Dentz 
186201ce70b0SLuiz Augusto von Dentz 	return adv->flags;
186301ce70b0SLuiz Augusto von Dentz }
186401ce70b0SLuiz Augusto von Dentz 
186501ce70b0SLuiz Augusto von Dentz bool hci_adv_instance_is_scannable(struct hci_dev *hdev, u8 instance)
186601ce70b0SLuiz Augusto von Dentz {
186701ce70b0SLuiz Augusto von Dentz 	struct adv_info *adv;
186801ce70b0SLuiz Augusto von Dentz 
186901ce70b0SLuiz Augusto von Dentz 	/* Instance 0x00 always set local name */
187001ce70b0SLuiz Augusto von Dentz 	if (instance == 0x00)
187101ce70b0SLuiz Augusto von Dentz 		return true;
187201ce70b0SLuiz Augusto von Dentz 
187301ce70b0SLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
187401ce70b0SLuiz Augusto von Dentz 	if (!adv)
187501ce70b0SLuiz Augusto von Dentz 		return false;
187601ce70b0SLuiz Augusto von Dentz 
187701ce70b0SLuiz Augusto von Dentz 	if (adv->flags & MGMT_ADV_FLAG_APPEARANCE ||
187801ce70b0SLuiz Augusto von Dentz 	    adv->flags & MGMT_ADV_FLAG_LOCAL_NAME)
187901ce70b0SLuiz Augusto von Dentz 		return true;
188001ce70b0SLuiz Augusto von Dentz 
188101ce70b0SLuiz Augusto von Dentz 	return adv->scan_rsp_len ? true : false;
188201ce70b0SLuiz Augusto von Dentz }
188301ce70b0SLuiz Augusto von Dentz 
188401ce70b0SLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */
1885e5e1e7fdSMiao-chen Chou void hci_adv_monitors_clear(struct hci_dev *hdev)
1886e5e1e7fdSMiao-chen Chou {
1887b139553dSMiao-chen Chou 	struct adv_monitor *monitor;
1888b139553dSMiao-chen Chou 	int handle;
1889b139553dSMiao-chen Chou 
1890b139553dSMiao-chen Chou 	idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle)
189166bd095aSArchie Pusaka 		hci_free_adv_monitor(hdev, monitor);
1892b139553dSMiao-chen Chou 
1893e5e1e7fdSMiao-chen Chou 	idr_destroy(&hdev->adv_monitors_idr);
1894e5e1e7fdSMiao-chen Chou }
1895e5e1e7fdSMiao-chen Chou 
189666bd095aSArchie Pusaka /* Frees the monitor structure and do some bookkeepings.
189766bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
189866bd095aSArchie Pusaka  */
189966bd095aSArchie Pusaka void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
1900b139553dSMiao-chen Chou {
1901b139553dSMiao-chen Chou 	struct adv_pattern *pattern;
1902b139553dSMiao-chen Chou 	struct adv_pattern *tmp;
1903b139553dSMiao-chen Chou 
1904b139553dSMiao-chen Chou 	if (!monitor)
1905b139553dSMiao-chen Chou 		return;
1906b139553dSMiao-chen Chou 
190766bd095aSArchie Pusaka 	list_for_each_entry_safe(pattern, tmp, &monitor->patterns, list) {
190866bd095aSArchie Pusaka 		list_del(&pattern->list);
1909b139553dSMiao-chen Chou 		kfree(pattern);
191066bd095aSArchie Pusaka 	}
191166bd095aSArchie Pusaka 
191266bd095aSArchie Pusaka 	if (monitor->handle)
191366bd095aSArchie Pusaka 		idr_remove(&hdev->adv_monitors_idr, monitor->handle);
191466bd095aSArchie Pusaka 
191566bd095aSArchie Pusaka 	if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) {
191666bd095aSArchie Pusaka 		hdev->adv_monitors_cnt--;
191766bd095aSArchie Pusaka 		mgmt_adv_monitor_removed(hdev, monitor->handle);
191866bd095aSArchie Pusaka 	}
1919b139553dSMiao-chen Chou 
1920b139553dSMiao-chen Chou 	kfree(monitor);
1921b139553dSMiao-chen Chou }
1922b139553dSMiao-chen Chou 
1923a2a4dedfSArchie Pusaka /* Assigns handle to a monitor, and if offloading is supported and power is on,
1924a2a4dedfSArchie Pusaka  * also attempts to forward the request to the controller.
1925b747a836SManish Mandlik  * This function requires the caller holds hci_req_sync_lock.
1926a2a4dedfSArchie Pusaka  */
1927b747a836SManish Mandlik int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
1928b139553dSMiao-chen Chou {
1929b139553dSMiao-chen Chou 	int min, max, handle;
1930b747a836SManish Mandlik 	int status = 0;
1931b139553dSMiao-chen Chou 
1932b747a836SManish Mandlik 	if (!monitor)
1933b747a836SManish Mandlik 		return -EINVAL;
1934a2a4dedfSArchie Pusaka 
1935b747a836SManish Mandlik 	hci_dev_lock(hdev);
1936b139553dSMiao-chen Chou 
1937b139553dSMiao-chen Chou 	min = HCI_MIN_ADV_MONITOR_HANDLE;
1938b139553dSMiao-chen Chou 	max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES;
1939b139553dSMiao-chen Chou 	handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max,
1940b139553dSMiao-chen Chou 			   GFP_KERNEL);
1941b747a836SManish Mandlik 
1942b747a836SManish Mandlik 	hci_dev_unlock(hdev);
1943b747a836SManish Mandlik 
1944b747a836SManish Mandlik 	if (handle < 0)
1945b747a836SManish Mandlik 		return handle;
1946b139553dSMiao-chen Chou 
1947b139553dSMiao-chen Chou 	monitor->handle = handle;
19488208f5a9SMiao-chen Chou 
1949a2a4dedfSArchie Pusaka 	if (!hdev_is_powered(hdev))
1950b747a836SManish Mandlik 		return status;
19518208f5a9SMiao-chen Chou 
1952a2a4dedfSArchie Pusaka 	switch (hci_get_adv_monitor_offload_ext(hdev)) {
1953a2a4dedfSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_NONE:
19546f55eea1SDouglas Anderson 		bt_dev_dbg(hdev, "add monitor %d status %d",
1955b747a836SManish Mandlik 			   monitor->handle, status);
1956a2a4dedfSArchie Pusaka 		/* Message was not forwarded to controller - not an error */
1957b747a836SManish Mandlik 		break;
1958b747a836SManish Mandlik 
1959a2a4dedfSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_MSFT:
1960b747a836SManish Mandlik 		status = msft_add_monitor_pattern(hdev, monitor);
19616f55eea1SDouglas Anderson 		bt_dev_dbg(hdev, "add monitor %d msft status %d",
1962a2bcd2b6SManish Mandlik 			   handle, status);
1963a2a4dedfSArchie Pusaka 		break;
1964a2a4dedfSArchie Pusaka 	}
1965a2a4dedfSArchie Pusaka 
1966b747a836SManish Mandlik 	return status;
1967b139553dSMiao-chen Chou }
1968b139553dSMiao-chen Chou 
196966bd095aSArchie Pusaka /* Attempts to tell the controller and free the monitor. If somehow the
197066bd095aSArchie Pusaka  * controller doesn't have a corresponding handle, remove anyway.
19717cf5c297SManish Mandlik  * This function requires the caller holds hci_req_sync_lock.
197266bd095aSArchie Pusaka  */
19737cf5c297SManish Mandlik static int hci_remove_adv_monitor(struct hci_dev *hdev,
19747cf5c297SManish Mandlik 				  struct adv_monitor *monitor)
1975bd2fbc6cSMiao-chen Chou {
19767cf5c297SManish Mandlik 	int status = 0;
1977de6dfcefSDouglas Anderson 	int handle;
1978bd2fbc6cSMiao-chen Chou 
197966bd095aSArchie Pusaka 	switch (hci_get_adv_monitor_offload_ext(hdev)) {
198066bd095aSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */
19816f55eea1SDouglas Anderson 		bt_dev_dbg(hdev, "remove monitor %d status %d",
19827cf5c297SManish Mandlik 			   monitor->handle, status);
198366bd095aSArchie Pusaka 		goto free_monitor;
19847cf5c297SManish Mandlik 
198566bd095aSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_MSFT:
1986de6dfcefSDouglas Anderson 		handle = monitor->handle;
19877cf5c297SManish Mandlik 		status = msft_remove_monitor(hdev, monitor);
19886f55eea1SDouglas Anderson 		bt_dev_dbg(hdev, "remove monitor %d msft status %d",
19896f55eea1SDouglas Anderson 			   handle, status);
199066bd095aSArchie Pusaka 		break;
1991bd2fbc6cSMiao-chen Chou 	}
1992bd2fbc6cSMiao-chen Chou 
199366bd095aSArchie Pusaka 	/* In case no matching handle registered, just free the monitor */
19947cf5c297SManish Mandlik 	if (status == -ENOENT)
199566bd095aSArchie Pusaka 		goto free_monitor;
1996bd2fbc6cSMiao-chen Chou 
19977cf5c297SManish Mandlik 	return status;
1998bd2fbc6cSMiao-chen Chou 
199966bd095aSArchie Pusaka free_monitor:
20007cf5c297SManish Mandlik 	if (status == -ENOENT)
200166bd095aSArchie Pusaka 		bt_dev_warn(hdev, "Removing monitor with no matching handle %d",
200266bd095aSArchie Pusaka 			    monitor->handle);
200366bd095aSArchie Pusaka 	hci_free_adv_monitor(hdev, monitor);
200466bd095aSArchie Pusaka 
20057cf5c297SManish Mandlik 	return status;
2006bd2fbc6cSMiao-chen Chou }
2007bd2fbc6cSMiao-chen Chou 
20087cf5c297SManish Mandlik /* This function requires the caller holds hci_req_sync_lock */
20097cf5c297SManish Mandlik int hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle)
201066bd095aSArchie Pusaka {
201166bd095aSArchie Pusaka 	struct adv_monitor *monitor = idr_find(&hdev->adv_monitors_idr, handle);
201266bd095aSArchie Pusaka 
20137cf5c297SManish Mandlik 	if (!monitor)
20147cf5c297SManish Mandlik 		return -EINVAL;
20157cf5c297SManish Mandlik 
20167cf5c297SManish Mandlik 	return hci_remove_adv_monitor(hdev, monitor);
201766bd095aSArchie Pusaka }
201866bd095aSArchie Pusaka 
20197cf5c297SManish Mandlik /* This function requires the caller holds hci_req_sync_lock */
20207cf5c297SManish Mandlik int hci_remove_all_adv_monitor(struct hci_dev *hdev)
202166bd095aSArchie Pusaka {
202266bd095aSArchie Pusaka 	struct adv_monitor *monitor;
202366bd095aSArchie Pusaka 	int idr_next_id = 0;
20247cf5c297SManish Mandlik 	int status = 0;
202566bd095aSArchie Pusaka 
20267cf5c297SManish Mandlik 	while (1) {
202766bd095aSArchie Pusaka 		monitor = idr_get_next(&hdev->adv_monitors_idr, &idr_next_id);
202866bd095aSArchie Pusaka 		if (!monitor)
202966bd095aSArchie Pusaka 			break;
203066bd095aSArchie Pusaka 
20317cf5c297SManish Mandlik 		status = hci_remove_adv_monitor(hdev, monitor);
20327cf5c297SManish Mandlik 		if (status)
20337cf5c297SManish Mandlik 			return status;
203466bd095aSArchie Pusaka 
20357cf5c297SManish Mandlik 		idr_next_id++;
203666bd095aSArchie Pusaka 	}
203766bd095aSArchie Pusaka 
20387cf5c297SManish Mandlik 	return status;
2039bd2fbc6cSMiao-chen Chou }
2040bd2fbc6cSMiao-chen Chou 
20418208f5a9SMiao-chen Chou /* This function requires the caller holds hdev->lock */
20428208f5a9SMiao-chen Chou bool hci_is_adv_monitoring(struct hci_dev *hdev)
20438208f5a9SMiao-chen Chou {
20448208f5a9SMiao-chen Chou 	return !idr_is_empty(&hdev->adv_monitors_idr);
20458208f5a9SMiao-chen Chou }
20468208f5a9SMiao-chen Chou 
2047a2a4dedfSArchie Pusaka int hci_get_adv_monitor_offload_ext(struct hci_dev *hdev)
2048a2a4dedfSArchie Pusaka {
2049a2a4dedfSArchie Pusaka 	if (msft_monitor_supported(hdev))
2050a2a4dedfSArchie Pusaka 		return HCI_ADV_MONITOR_EXT_MSFT;
2051a2a4dedfSArchie Pusaka 
2052a2a4dedfSArchie Pusaka 	return HCI_ADV_MONITOR_EXT_NONE;
2053a2a4dedfSArchie Pusaka }
2054a2a4dedfSArchie Pusaka 
2055dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
2056b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
2057b2a66aadSAntti Julku {
2058b2a66aadSAntti Julku 	struct bdaddr_list *b;
2059b2a66aadSAntti Julku 
2060dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
2061b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2062b2a66aadSAntti Julku 			return b;
2063b9ee0a78SMarcel Holtmann 	}
2064b2a66aadSAntti Julku 
2065b2a66aadSAntti Julku 	return NULL;
2066b2a66aadSAntti Julku }
2067b2a66aadSAntti Julku 
2068b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
2069b950aa88SAnkit Navik 				struct list_head *bdaddr_list, bdaddr_t *bdaddr,
2070b950aa88SAnkit Navik 				u8 type)
2071b950aa88SAnkit Navik {
2072b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *b;
2073b950aa88SAnkit Navik 
2074b950aa88SAnkit Navik 	list_for_each_entry(b, bdaddr_list, list) {
2075b950aa88SAnkit Navik 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2076b950aa88SAnkit Navik 			return b;
2077b950aa88SAnkit Navik 	}
2078b950aa88SAnkit Navik 
2079b950aa88SAnkit Navik 	return NULL;
2080b950aa88SAnkit Navik }
2081b950aa88SAnkit Navik 
20828baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *
20838baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list,
20848baaa403SAbhishek Pandit-Subedi 				  bdaddr_t *bdaddr, u8 type)
20858baaa403SAbhishek Pandit-Subedi {
20868baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *b;
20878baaa403SAbhishek Pandit-Subedi 
20888baaa403SAbhishek Pandit-Subedi 	list_for_each_entry(b, bdaddr_list, list) {
20898baaa403SAbhishek Pandit-Subedi 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
20908baaa403SAbhishek Pandit-Subedi 			return b;
20918baaa403SAbhishek Pandit-Subedi 	}
20928baaa403SAbhishek Pandit-Subedi 
20938baaa403SAbhishek Pandit-Subedi 	return NULL;
20948baaa403SAbhishek Pandit-Subedi }
20958baaa403SAbhishek Pandit-Subedi 
2096dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
2097b2a66aadSAntti Julku {
20987eb7404fSGeliang Tang 	struct bdaddr_list *b, *n;
2099b2a66aadSAntti Julku 
21007eb7404fSGeliang Tang 	list_for_each_entry_safe(b, n, bdaddr_list, list) {
21017eb7404fSGeliang Tang 		list_del(&b->list);
2102b2a66aadSAntti Julku 		kfree(b);
2103b2a66aadSAntti Julku 	}
2104b2a66aadSAntti Julku }
2105b2a66aadSAntti Julku 
2106dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2107b2a66aadSAntti Julku {
2108b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2109b2a66aadSAntti Julku 
2110b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
2111b2a66aadSAntti Julku 		return -EBADF;
2112b2a66aadSAntti Julku 
2113dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
21145e762444SAntti Julku 		return -EEXIST;
2115b2a66aadSAntti Julku 
211627f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
21175e762444SAntti Julku 	if (!entry)
21185e762444SAntti Julku 		return -ENOMEM;
2119b2a66aadSAntti Julku 
2120b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2121b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
2122b2a66aadSAntti Julku 
2123dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
2124b2a66aadSAntti Julku 
21252a8357f2SJohan Hedberg 	return 0;
2126b2a66aadSAntti Julku }
2127b2a66aadSAntti Julku 
2128b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2129b950aa88SAnkit Navik 					u8 type, u8 *peer_irk, u8 *local_irk)
2130b950aa88SAnkit Navik {
2131b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
2132b950aa88SAnkit Navik 
2133b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY))
2134b950aa88SAnkit Navik 		return -EBADF;
2135b950aa88SAnkit Navik 
2136b950aa88SAnkit Navik 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
2137b950aa88SAnkit Navik 		return -EEXIST;
2138b950aa88SAnkit Navik 
2139b950aa88SAnkit Navik 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
2140b950aa88SAnkit Navik 	if (!entry)
2141b950aa88SAnkit Navik 		return -ENOMEM;
2142b950aa88SAnkit Navik 
2143b950aa88SAnkit Navik 	bacpy(&entry->bdaddr, bdaddr);
2144b950aa88SAnkit Navik 	entry->bdaddr_type = type;
2145b950aa88SAnkit Navik 
2146b950aa88SAnkit Navik 	if (peer_irk)
2147b950aa88SAnkit Navik 		memcpy(entry->peer_irk, peer_irk, 16);
2148b950aa88SAnkit Navik 
2149b950aa88SAnkit Navik 	if (local_irk)
2150b950aa88SAnkit Navik 		memcpy(entry->local_irk, local_irk, 16);
2151b950aa88SAnkit Navik 
2152b950aa88SAnkit Navik 	list_add(&entry->list, list);
2153b950aa88SAnkit Navik 
2154b950aa88SAnkit Navik 	return 0;
2155b950aa88SAnkit Navik }
2156b950aa88SAnkit Navik 
21578baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
21588baaa403SAbhishek Pandit-Subedi 				   u8 type, u32 flags)
21598baaa403SAbhishek Pandit-Subedi {
21608baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
21618baaa403SAbhishek Pandit-Subedi 
21628baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY))
21638baaa403SAbhishek Pandit-Subedi 		return -EBADF;
21648baaa403SAbhishek Pandit-Subedi 
21658baaa403SAbhishek Pandit-Subedi 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
21668baaa403SAbhishek Pandit-Subedi 		return -EEXIST;
21678baaa403SAbhishek Pandit-Subedi 
21688baaa403SAbhishek Pandit-Subedi 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
21698baaa403SAbhishek Pandit-Subedi 	if (!entry)
21708baaa403SAbhishek Pandit-Subedi 		return -ENOMEM;
21718baaa403SAbhishek Pandit-Subedi 
21728baaa403SAbhishek Pandit-Subedi 	bacpy(&entry->bdaddr, bdaddr);
21738baaa403SAbhishek Pandit-Subedi 	entry->bdaddr_type = type;
2174e1cff700SLinus Torvalds 	entry->flags = flags;
21758baaa403SAbhishek Pandit-Subedi 
21768baaa403SAbhishek Pandit-Subedi 	list_add(&entry->list, list);
21778baaa403SAbhishek Pandit-Subedi 
21788baaa403SAbhishek Pandit-Subedi 	return 0;
21798baaa403SAbhishek Pandit-Subedi }
21808baaa403SAbhishek Pandit-Subedi 
2181dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2182b2a66aadSAntti Julku {
2183b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2184b2a66aadSAntti Julku 
218535f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2186dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
218735f7498aSJohan Hedberg 		return 0;
218835f7498aSJohan Hedberg 	}
2189b2a66aadSAntti Julku 
2190dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
2191d2ab0ac1SMarcel Holtmann 	if (!entry)
2192d2ab0ac1SMarcel Holtmann 		return -ENOENT;
2193d2ab0ac1SMarcel Holtmann 
2194d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
2195d2ab0ac1SMarcel Holtmann 	kfree(entry);
2196d2ab0ac1SMarcel Holtmann 
2197d2ab0ac1SMarcel Holtmann 	return 0;
2198d2ab0ac1SMarcel Holtmann }
2199d2ab0ac1SMarcel Holtmann 
2200b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2201b950aa88SAnkit Navik 							u8 type)
2202b950aa88SAnkit Navik {
2203b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
2204b950aa88SAnkit Navik 
2205b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2206b950aa88SAnkit Navik 		hci_bdaddr_list_clear(list);
2207b950aa88SAnkit Navik 		return 0;
2208b950aa88SAnkit Navik 	}
2209b950aa88SAnkit Navik 
2210b950aa88SAnkit Navik 	entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type);
2211b950aa88SAnkit Navik 	if (!entry)
2212b950aa88SAnkit Navik 		return -ENOENT;
2213b950aa88SAnkit Navik 
2214b950aa88SAnkit Navik 	list_del(&entry->list);
2215b950aa88SAnkit Navik 	kfree(entry);
2216b950aa88SAnkit Navik 
2217b950aa88SAnkit Navik 	return 0;
2218b950aa88SAnkit Navik }
2219b950aa88SAnkit Navik 
22208baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
22218baaa403SAbhishek Pandit-Subedi 				   u8 type)
22228baaa403SAbhishek Pandit-Subedi {
22238baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
22248baaa403SAbhishek Pandit-Subedi 
22258baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY)) {
22268baaa403SAbhishek Pandit-Subedi 		hci_bdaddr_list_clear(list);
22278baaa403SAbhishek Pandit-Subedi 		return 0;
22288baaa403SAbhishek Pandit-Subedi 	}
22298baaa403SAbhishek Pandit-Subedi 
22308baaa403SAbhishek Pandit-Subedi 	entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type);
22318baaa403SAbhishek Pandit-Subedi 	if (!entry)
22328baaa403SAbhishek Pandit-Subedi 		return -ENOENT;
22338baaa403SAbhishek Pandit-Subedi 
22348baaa403SAbhishek Pandit-Subedi 	list_del(&entry->list);
22358baaa403SAbhishek Pandit-Subedi 	kfree(entry);
22368baaa403SAbhishek Pandit-Subedi 
22378baaa403SAbhishek Pandit-Subedi 	return 0;
22388baaa403SAbhishek Pandit-Subedi }
22398baaa403SAbhishek Pandit-Subedi 
224015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
224115819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
224215819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
224315819a70SAndre Guedes {
224415819a70SAndre Guedes 	struct hci_conn_params *params;
224515819a70SAndre Guedes 
224615819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
224715819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
224815819a70SAndre Guedes 		    params->addr_type == addr_type) {
224915819a70SAndre Guedes 			return params;
225015819a70SAndre Guedes 		}
225115819a70SAndre Guedes 	}
225215819a70SAndre Guedes 
225315819a70SAndre Guedes 	return NULL;
225415819a70SAndre Guedes }
225515819a70SAndre Guedes 
2256195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock or rcu_read_lock */
2257501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
22584b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
2259a9b0a04cSAndre Guedes {
2260912b42efSJohan Hedberg 	struct hci_conn_params *param;
2261a9b0a04cSAndre Guedes 
2262195ef75eSPauli Virtanen 	rcu_read_lock();
2263195ef75eSPauli Virtanen 
2264195ef75eSPauli Virtanen 	list_for_each_entry_rcu(param, list, action) {
2265912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
2266195ef75eSPauli Virtanen 		    param->addr_type == addr_type) {
2267195ef75eSPauli Virtanen 			rcu_read_unlock();
2268912b42efSJohan Hedberg 			return param;
22694b10966fSMarcel Holtmann 		}
2270195ef75eSPauli Virtanen 	}
2271195ef75eSPauli Virtanen 
2272195ef75eSPauli Virtanen 	rcu_read_unlock();
22734b10966fSMarcel Holtmann 
22744b10966fSMarcel Holtmann 	return NULL;
2275a9b0a04cSAndre Guedes }
2276a9b0a04cSAndre Guedes 
227715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
2278195ef75eSPauli Virtanen void hci_pend_le_list_del_init(struct hci_conn_params *param)
2279195ef75eSPauli Virtanen {
2280195ef75eSPauli Virtanen 	if (list_empty(&param->action))
2281195ef75eSPauli Virtanen 		return;
2282195ef75eSPauli Virtanen 
2283195ef75eSPauli Virtanen 	list_del_rcu(&param->action);
2284195ef75eSPauli Virtanen 	synchronize_rcu();
2285195ef75eSPauli Virtanen 	INIT_LIST_HEAD(&param->action);
2286195ef75eSPauli Virtanen }
2287195ef75eSPauli Virtanen 
2288195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock */
2289195ef75eSPauli Virtanen void hci_pend_le_list_add(struct hci_conn_params *param,
2290195ef75eSPauli Virtanen 			  struct list_head *list)
2291195ef75eSPauli Virtanen {
2292195ef75eSPauli Virtanen 	list_add_rcu(&param->action, list);
2293195ef75eSPauli Virtanen }
2294195ef75eSPauli Virtanen 
2295195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock */
229651d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
229751d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
229815819a70SAndre Guedes {
229915819a70SAndre Guedes 	struct hci_conn_params *params;
230015819a70SAndre Guedes 
230115819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
2302cef952ceSAndre Guedes 	if (params)
230351d167c0SMarcel Holtmann 		return params;
230415819a70SAndre Guedes 
230515819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
230615819a70SAndre Guedes 	if (!params) {
23072064ee33SMarcel Holtmann 		bt_dev_err(hdev, "out of memory");
230851d167c0SMarcel Holtmann 		return NULL;
230915819a70SAndre Guedes 	}
231015819a70SAndre Guedes 
231115819a70SAndre Guedes 	bacpy(&params->addr, addr);
231215819a70SAndre Guedes 	params->addr_type = addr_type;
2313cef952ceSAndre Guedes 
2314cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
231593450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
2316cef952ceSAndre Guedes 
2317bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
2318bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
2319bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
2320bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
2321bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
2322bf5b3c8bSMarcel Holtmann 
2323bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
2324bf5b3c8bSMarcel Holtmann 
232551d167c0SMarcel Holtmann 	return params;
2326bf5b3c8bSMarcel Holtmann }
2327bf5b3c8bSMarcel Holtmann 
2328195ef75eSPauli Virtanen void hci_conn_params_free(struct hci_conn_params *params)
2329f6c63249SJohan Hedberg {
2330195ef75eSPauli Virtanen 	hci_pend_le_list_del_init(params);
2331195ef75eSPauli Virtanen 
2332f6c63249SJohan Hedberg 	if (params->conn) {
2333f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
2334f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
2335f6c63249SJohan Hedberg 	}
2336f6c63249SJohan Hedberg 
2337f6c63249SJohan Hedberg 	list_del(&params->list);
2338f6c63249SJohan Hedberg 	kfree(params);
2339f6c63249SJohan Hedberg }
2340f6c63249SJohan Hedberg 
234115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
234215819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
234315819a70SAndre Guedes {
234415819a70SAndre Guedes 	struct hci_conn_params *params;
234515819a70SAndre Guedes 
234615819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
234715819a70SAndre Guedes 	if (!params)
234815819a70SAndre Guedes 		return;
234915819a70SAndre Guedes 
2350f6c63249SJohan Hedberg 	hci_conn_params_free(params);
235115819a70SAndre Guedes 
23525bee2fd6SLuiz Augusto von Dentz 	hci_update_passive_scan(hdev);
235395305baaSJohan Hedberg 
235415819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
235515819a70SAndre Guedes }
235615819a70SAndre Guedes 
235715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
235855af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
235915819a70SAndre Guedes {
236015819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
236115819a70SAndre Guedes 
236215819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
236355af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
236455af49a8SJohan Hedberg 			continue;
2365f75113a2SJakub Pawlowski 
236691641b79SZheng Yongjun 		/* If trying to establish one time connection to disabled
2367f75113a2SJakub Pawlowski 		 * device, leave the params, but mark them as just once.
2368f75113a2SJakub Pawlowski 		 */
2369f75113a2SJakub Pawlowski 		if (params->explicit_connect) {
2370f75113a2SJakub Pawlowski 			params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
2371f75113a2SJakub Pawlowski 			continue;
2372f75113a2SJakub Pawlowski 		}
2373f75113a2SJakub Pawlowski 
2374195ef75eSPauli Virtanen 		hci_conn_params_free(params);
237515819a70SAndre Guedes 	}
237615819a70SAndre Guedes 
237755af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
237855af49a8SJohan Hedberg }
237955af49a8SJohan Hedberg 
238055af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
2381030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev)
238215819a70SAndre Guedes {
238315819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
238415819a70SAndre Guedes 
2385f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
2386f6c63249SJohan Hedberg 		hci_conn_params_free(params);
238715819a70SAndre Guedes 
238815819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
238915819a70SAndre Guedes }
239015819a70SAndre Guedes 
2391a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
2392a1f4c318SJohan Hedberg  *
2393a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
2394a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
2395a1f4c318SJohan Hedberg  * the static random address.
2396a1f4c318SJohan Hedberg  *
2397a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
2398a1f4c318SJohan Hedberg  * public address to use the static random address instead.
239950b5b952SMarcel Holtmann  *
240050b5b952SMarcel Holtmann  * In case BR/EDR has been disabled on a dual-mode controller and
240150b5b952SMarcel Holtmann  * userspace has configured a static address, then that address
240250b5b952SMarcel Holtmann  * becomes the identity address instead of the public BR/EDR address.
2403a1f4c318SJohan Hedberg  */
2404a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
2405a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
2406a1f4c318SJohan Hedberg {
2407b7cb93e5SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
240850b5b952SMarcel Holtmann 	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
2409d7a5a11dSMarcel Holtmann 	    (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
241050b5b952SMarcel Holtmann 	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
2411a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
2412a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
2413a1f4c318SJohan Hedberg 	} else {
2414a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
2415a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
2416a1f4c318SJohan Hedberg 	}
2417a1f4c318SJohan Hedberg }
2418a1f4c318SJohan Hedberg 
24192f20216cSAbhishek Pandit-Subedi static void hci_clear_wake_reason(struct hci_dev *hdev)
24202f20216cSAbhishek Pandit-Subedi {
24212f20216cSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
24222f20216cSAbhishek Pandit-Subedi 
24232f20216cSAbhishek Pandit-Subedi 	hdev->wake_reason = 0;
24242f20216cSAbhishek Pandit-Subedi 	bacpy(&hdev->wake_addr, BDADDR_ANY);
24252f20216cSAbhishek Pandit-Subedi 	hdev->wake_addr_type = 0;
24262f20216cSAbhishek Pandit-Subedi 
24272f20216cSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
24282f20216cSAbhishek Pandit-Subedi }
24292f20216cSAbhishek Pandit-Subedi 
24309952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
24319952d90eSAbhishek Pandit-Subedi 				void *data)
24329952d90eSAbhishek Pandit-Subedi {
24339952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
24349952d90eSAbhishek Pandit-Subedi 		container_of(nb, struct hci_dev, suspend_notifier);
24359952d90eSAbhishek Pandit-Subedi 	int ret = 0;
24369952d90eSAbhishek Pandit-Subedi 
24374b8af331SAbhishek Pandit-Subedi 	/* Userspace has full control of this device. Do nothing. */
24384b8af331SAbhishek Pandit-Subedi 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
24394b8af331SAbhishek Pandit-Subedi 		return NOTIFY_DONE;
24404b8af331SAbhishek Pandit-Subedi 
2441573ebae1SYing Hsu 	/* To avoid a potential race with hci_unregister_dev. */
2442573ebae1SYing Hsu 	hci_dev_hold(hdev);
2443573ebae1SYing Hsu 
2444e1b77d68SLuiz Augusto von Dentz 	if (action == PM_SUSPEND_PREPARE)
2445e1b77d68SLuiz Augusto von Dentz 		ret = hci_suspend_dev(hdev);
2446e1b77d68SLuiz Augusto von Dentz 	else if (action == PM_POST_SUSPEND)
2447e1b77d68SLuiz Augusto von Dentz 		ret = hci_resume_dev(hdev);
24489952d90eSAbhishek Pandit-Subedi 
2449a9ec8423SAbhishek Pandit-Subedi 	if (ret)
2450a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
2451a9ec8423SAbhishek Pandit-Subedi 			   action, ret);
2452a9ec8423SAbhishek Pandit-Subedi 
2453573ebae1SYing Hsu 	hci_dev_put(hdev);
245424b06572SMax Chou 	return NOTIFY_DONE;
24559952d90eSAbhishek Pandit-Subedi }
24568731840aSAbhishek Pandit-Subedi 
24579be0dab7SDavid Herrmann /* Alloc HCI device */
24586ec56613STedd Ho-Jeong An struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
24599be0dab7SDavid Herrmann {
24609be0dab7SDavid Herrmann 	struct hci_dev *hdev;
24616ec56613STedd Ho-Jeong An 	unsigned int alloc_size;
24629be0dab7SDavid Herrmann 
24636ec56613STedd Ho-Jeong An 	alloc_size = sizeof(*hdev);
24646ec56613STedd Ho-Jeong An 	if (sizeof_priv) {
24656ec56613STedd Ho-Jeong An 		/* Fixme: May need ALIGN-ment? */
24666ec56613STedd Ho-Jeong An 		alloc_size += sizeof_priv;
24676ec56613STedd Ho-Jeong An 	}
24686ec56613STedd Ho-Jeong An 
24696ec56613STedd Ho-Jeong An 	hdev = kzalloc(alloc_size, GFP_KERNEL);
24709be0dab7SDavid Herrmann 	if (!hdev)
24719be0dab7SDavid Herrmann 		return NULL;
24729be0dab7SDavid Herrmann 
2473b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2474b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
2475b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
2476b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
2477b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
247896c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
2479bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2480bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2481d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
2482d2609b34SFlorian Grandel 	hdev->cur_adv_instance = 0x00;
24835d900e46SFlorian Grandel 	hdev->adv_instance_timeout = 0;
2484b1b813d4SDavid Herrmann 
2485c4f1f408SHoward Chung 	hdev->advmon_allowlist_duration = 300;
2486c4f1f408SHoward Chung 	hdev->advmon_no_filter_duration = 500;
248780af16a3SHoward Chung 	hdev->enable_advmon_interleave_scan = 0x00;	/* Default to disable */
2488c4f1f408SHoward Chung 
2489b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
2490b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
2491b1b813d4SDavid Herrmann 
24923f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
2493628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
2494628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
2495bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
2496bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
249710873f99SAlain Michaud 	hdev->le_scan_int_suspend = 0x0400;
249810873f99SAlain Michaud 	hdev->le_scan_window_suspend = 0x0012;
249910873f99SAlain Michaud 	hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT;
250010873f99SAlain Michaud 	hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN;
2501ba29d036SMarcel Holtmann 	hdev->le_scan_int_adv_monitor = 0x0060;
2502ba29d036SMarcel Holtmann 	hdev->le_scan_window_adv_monitor = 0x0030;
250310873f99SAlain Michaud 	hdev->le_scan_int_connect = 0x0060;
250410873f99SAlain Michaud 	hdev->le_scan_window_connect = 0x0060;
2505b48c3b59SJonas Holmberg 	hdev->le_conn_min_interval = 0x0018;
2506b48c3b59SJonas Holmberg 	hdev->le_conn_max_interval = 0x0028;
250704fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
250804fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
2509a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = 0x001b;
2510a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = 0x0148;
2511a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = 0x001b;
2512a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = 0x0148;
2513a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = 0x001b;
2514a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = 0x0148;
251530d65e08SMatias Karhumaa 	hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE;
251630d65e08SMatias Karhumaa 	hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE;
25176decb5b4SJaganath Kanakkassery 	hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
25186decb5b4SJaganath Kanakkassery 	hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
25191d0fac2cSLuiz Augusto von Dentz 	hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES;
252010873f99SAlain Michaud 	hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION;
252149b020c1SAlain Michaud 	hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT;
25227c395ea5SDaniel Winkler 	hdev->min_le_tx_power = HCI_TX_POWER_INVALID;
25237c395ea5SDaniel Winkler 	hdev->max_le_tx_power = HCI_TX_POWER_INVALID;
2524bef64738SMarcel Holtmann 
2525d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
2526b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
252731ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
252831ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
2529302975cbSSpoorthi Ravishankar Koppad 	hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT;
253058a96fc3SMarcel Holtmann 	hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE;
2531d6bfd59cSJohan Hedberg 
253210873f99SAlain Michaud 	/* default 1.28 sec page scan */
253310873f99SAlain Michaud 	hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD;
253410873f99SAlain Michaud 	hdev->def_page_scan_int = 0x0800;
253510873f99SAlain Michaud 	hdev->def_page_scan_window = 0x0012;
253610873f99SAlain Michaud 
2537b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
2538b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
2539b1b813d4SDavid Herrmann 
254084cb0143SZiyang Xuan 	ida_init(&hdev->unset_handle_ida);
254184cb0143SZiyang Xuan 
2542b338d917SBrian Gix 	INIT_LIST_HEAD(&hdev->mesh_pending);
2543b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
25443d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->reject_list);
25453d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->accept_list);
2546b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
2547b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
2548b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
2549970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
2550b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
25513d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->le_accept_list);
2552cfdb0c2dSAnkit Navik 	INIT_LIST_HEAD(&hdev->le_resolv_list);
255315819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
255477a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
255566f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
25566b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
2557d2609b34SFlorian Grandel 	INIT_LIST_HEAD(&hdev->adv_instances);
2558600a8749SAlain Michaud 	INIT_LIST_HEAD(&hdev->blocked_keys);
25593368aa35SManish Mandlik 	INIT_LIST_HEAD(&hdev->monitored_devices);
2560b1b813d4SDavid Herrmann 
25618961987fSKiran K 	INIT_LIST_HEAD(&hdev->local_codecs);
2562b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2563b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2564b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2565b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2566c7741d16SMarcel Holtmann 	INIT_WORK(&hdev->error_reset, hci_error_reset);
2567b1b813d4SDavid Herrmann 
25686a98e383SMarcel Holtmann 	hci_cmd_sync_init(hdev);
25696a98e383SMarcel Holtmann 
2570b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2571b1b813d4SDavid Herrmann 
2572b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2573b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2574b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2575b1b813d4SDavid Herrmann 
2576b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2577b1b813d4SDavid Herrmann 
257865cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
2579de75cd0dSManish Mandlik 	INIT_DELAYED_WORK(&hdev->ncmd_timer, hci_ncmd_timeout);
2580b1b813d4SDavid Herrmann 
25819695ef87SAbhishek Pandit-Subedi 	hci_devcd_setup(hdev);
25825fc16cc4SJohan Hedberg 	hci_request_setup(hdev);
25835fc16cc4SJohan Hedberg 
2584b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2585b1b813d4SDavid Herrmann 	discovery_init(hdev);
25869be0dab7SDavid Herrmann 
25879be0dab7SDavid Herrmann 	return hdev;
25889be0dab7SDavid Herrmann }
25896ec56613STedd Ho-Jeong An EXPORT_SYMBOL(hci_alloc_dev_priv);
25909be0dab7SDavid Herrmann 
25919be0dab7SDavid Herrmann /* Free HCI device */
25929be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
25939be0dab7SDavid Herrmann {
25949be0dab7SDavid Herrmann 	/* will free via device release */
25959be0dab7SDavid Herrmann 	put_device(&hdev->dev);
25969be0dab7SDavid Herrmann }
25979be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
25989be0dab7SDavid Herrmann 
25991da177e4SLinus Torvalds /* Register HCI device */
26001da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
26011da177e4SLinus Torvalds {
2602b1b813d4SDavid Herrmann 	int id, error;
26031da177e4SLinus Torvalds 
260474292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
26051da177e4SLinus Torvalds 		return -EINVAL;
26061da177e4SLinus Torvalds 
260708add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
260808add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
260908add513SMat Martineau 	 */
26103df92b31SSasha Levin 	switch (hdev->dev_type) {
2611ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
2612103a2f32SItay Iellin 		id = ida_simple_get(&hci_index_ida, 0, HCI_MAX_ID, GFP_KERNEL);
26131da177e4SLinus Torvalds 		break;
26143df92b31SSasha Levin 	case HCI_AMP:
2615103a2f32SItay Iellin 		id = ida_simple_get(&hci_index_ida, 1, HCI_MAX_ID, GFP_KERNEL);
26163df92b31SSasha Levin 		break;
26173df92b31SSasha Levin 	default:
26183df92b31SSasha Levin 		return -EINVAL;
26191da177e4SLinus Torvalds 	}
26201da177e4SLinus Torvalds 
26213df92b31SSasha Levin 	if (id < 0)
26223df92b31SSasha Levin 		return id;
26233df92b31SSasha Levin 
2624dcda1657SLuiz Augusto von Dentz 	error = dev_set_name(&hdev->dev, "hci%u", id);
2625dcda1657SLuiz Augusto von Dentz 	if (error)
2626dcda1657SLuiz Augusto von Dentz 		return error;
2627dcda1657SLuiz Augusto von Dentz 
2628dcda1657SLuiz Augusto von Dentz 	hdev->name = dev_name(&hdev->dev);
26291da177e4SLinus Torvalds 	hdev->id = id;
26302d8b3a11SAndrei Emeltchenko 
26312d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
26322d8b3a11SAndrei Emeltchenko 
263329e2dd0dSTejun Heo 	hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name);
263433ca954dSDavid Herrmann 	if (!hdev->workqueue) {
263533ca954dSDavid Herrmann 		error = -ENOMEM;
263633ca954dSDavid Herrmann 		goto err;
263733ca954dSDavid Herrmann 	}
2638f48fd9c8SMarcel Holtmann 
263929e2dd0dSTejun Heo 	hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI,
264029e2dd0dSTejun Heo 						      hdev->name);
26416ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
26426ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
26436ead1bbcSJohan Hedberg 		error = -ENOMEM;
26446ead1bbcSJohan Hedberg 		goto err;
26456ead1bbcSJohan Hedberg 	}
26466ead1bbcSJohan Hedberg 
26470153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
26480153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
26490153e2ecSMarcel Holtmann 
2650bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
265133ca954dSDavid Herrmann 	if (error < 0)
265254506918SJohan Hedberg 		goto err_wqueue;
26531da177e4SLinus Torvalds 
26546d5d2ee6SHeiner Kallweit 	hci_leds_init(hdev);
26556d5d2ee6SHeiner Kallweit 
2656611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2657a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2658a8c5fb1aSGustavo Padovan 				    hdev);
2659611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2660611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
2661611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
2662611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
2663611b30f7SMarcel Holtmann 		}
2664611b30f7SMarcel Holtmann 	}
2665611b30f7SMarcel Holtmann 
26665e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
2667a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
26685e130367SJohan Hedberg 
2669a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_SETUP);
2670a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_AUTO_OFF);
2671ce2be9acSAndrei Emeltchenko 
2672ca8bee5dSMarcel Holtmann 	if (hdev->dev_type == HCI_PRIMARY) {
267356f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
267456f87901SJohan Hedberg 		 * through reading supported features during init.
267556f87901SJohan Hedberg 		 */
2676a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
267756f87901SJohan Hedberg 	}
2678ce2be9acSAndrei Emeltchenko 
2679fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
2680fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
2681fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
2682fcee3377SGustavo Padovan 
26834a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
26844a964404SMarcel Holtmann 	 * and should not be included in normal operation.
2685fee746b0SMarcel Holtmann 	 */
2686fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
2687a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
2688fee746b0SMarcel Holtmann 
2689fe92ee64SLuiz Augusto von Dentz 	/* Mark Remote Wakeup connection flag as supported if driver has wakeup
2690fe92ee64SLuiz Augusto von Dentz 	 * callback.
2691fe92ee64SLuiz Augusto von Dentz 	 */
2692fe92ee64SLuiz Augusto von Dentz 	if (hdev->wakeup)
2693e1cff700SLinus Torvalds 		hdev->conn_flags |= HCI_CONN_FLAG_REMOTE_WAKEUP;
2694fe92ee64SLuiz Augusto von Dentz 
269505fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_REG);
2696dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
26971da177e4SLinus Torvalds 
269891117864SDan Carpenter 	error = hci_register_suspend_notifier(hdev);
269991117864SDan Carpenter 	if (error)
27000d75da38SYang Yingliang 		BT_WARN("register suspend notifier failed error:%d\n", error);
27019952d90eSAbhishek Pandit-Subedi 
270219202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2703fbe96d6fSMarcel Holtmann 
2704e5e1e7fdSMiao-chen Chou 	idr_init(&hdev->adv_monitors_idr);
27055031ffccSMiao-chen Chou 	msft_register(hdev);
2706e5e1e7fdSMiao-chen Chou 
27071da177e4SLinus Torvalds 	return id;
2708f48fd9c8SMarcel Holtmann 
270933ca954dSDavid Herrmann err_wqueue:
27105a4bb6a8SWei Yongjun 	debugfs_remove_recursive(hdev->debugfs);
271133ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
27126ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
271333ca954dSDavid Herrmann err:
27143df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
2715f48fd9c8SMarcel Holtmann 
271633ca954dSDavid Herrmann 	return error;
27171da177e4SLinus Torvalds }
27181da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
27191da177e4SLinus Torvalds 
27201da177e4SLinus Torvalds /* Unregister HCI device */
272159735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
27221da177e4SLinus Torvalds {
2723c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
27241da177e4SLinus Torvalds 
27251857c199SZhengping Jiang 	mutex_lock(&hdev->unregister_lock);
2726a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_UNREGISTER);
27271857c199SZhengping Jiang 	mutex_unlock(&hdev->unregister_lock);
272894324962SJohan Hovold 
2729f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
27301da177e4SLinus Torvalds 	list_del(&hdev->list);
2731f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
27321da177e4SLinus Torvalds 
2733e36bea6eSVasyl Vavrychuk 	cancel_work_sync(&hdev->power_on);
2734e36bea6eSVasyl Vavrychuk 
27356a98e383SMarcel Holtmann 	hci_cmd_sync_clear(hdev);
27366a98e383SMarcel Holtmann 
2737359ee4f8SAbhishek Pandit-Subedi 	hci_unregister_suspend_notifier(hdev);
27384e8c36c3SAbhishek Pandit-Subedi 
27395031ffccSMiao-chen Chou 	msft_unregister(hdev);
27405031ffccSMiao-chen Chou 
27414e8c36c3SAbhishek Pandit-Subedi 	hci_dev_do_close(hdev);
27429952d90eSAbhishek Pandit-Subedi 
2743ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2744d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_SETUP) &&
2745d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
274609fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2747744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
274809fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
274956e5cb86SJohan Hedberg 	}
2750ab81cbf9SJohan Hedberg 
27512e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
27522e58ef3eSJohan Hedberg 	 * pending list */
27532e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
27542e58ef3eSJohan Hedberg 
275505fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_UNREG);
27561da177e4SLinus Torvalds 
2757611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2758611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2759611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2760611b30f7SMarcel Holtmann 	}
2761611b30f7SMarcel Holtmann 
2762bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
2763e61fbee7SDavid S. Miller 	/* Actual cleanup is deferred until hci_release_dev(). */
2764e0448092STetsuo Handa 	hci_dev_put(hdev);
2765e0448092STetsuo Handa }
2766e0448092STetsuo Handa EXPORT_SYMBOL(hci_unregister_dev);
2767147e2d59SDave Young 
276858ce6d5bSTetsuo Handa /* Release HCI device */
276958ce6d5bSTetsuo Handa void hci_release_dev(struct hci_dev *hdev)
2770e0448092STetsuo Handa {
27710153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
27725177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
27735177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
27740153e2ecSMarcel Holtmann 
2775f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
27766ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2777f48fd9c8SMarcel Holtmann 
277809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
27793d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->reject_list);
27803d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->accept_list);
27812aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
278255ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2783b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
2784970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
27852763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
2786d2609b34SFlorian Grandel 	hci_adv_instances_clear(hdev);
2787e5e1e7fdSMiao-chen Chou 	hci_adv_monitors_clear(hdev);
27883d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
2789cfdb0c2dSAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
2790373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
279122078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
2792600a8749SAlain Michaud 	hci_blocked_keys_clear(hdev);
2793b938790eSLuiz Augusto von Dentz 	hci_codec_list_clear(&hdev->local_codecs);
279409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2795e2e0cacbSJohan Hedberg 
279684cb0143SZiyang Xuan 	ida_destroy(&hdev->unset_handle_ida);
2797e0448092STetsuo Handa 	ida_simple_remove(&hci_index_ida, hdev->id);
2798dd3b1dc3SLuiz Augusto von Dentz 	kfree_skb(hdev->sent_cmd);
27992af7aa66SLuiz Augusto von Dentz 	kfree_skb(hdev->req_skb);
2800dfe6d5c3SLuiz Augusto von Dentz 	kfree_skb(hdev->recv_event);
280158ce6d5bSTetsuo Handa 	kfree(hdev);
28021da177e4SLinus Torvalds }
280358ce6d5bSTetsuo Handa EXPORT_SYMBOL(hci_release_dev);
28041da177e4SLinus Torvalds 
2805359ee4f8SAbhishek Pandit-Subedi int hci_register_suspend_notifier(struct hci_dev *hdev)
2806359ee4f8SAbhishek Pandit-Subedi {
2807359ee4f8SAbhishek Pandit-Subedi 	int ret = 0;
2808359ee4f8SAbhishek Pandit-Subedi 
2809b5ca3387SLuiz Augusto von Dentz 	if (!hdev->suspend_notifier.notifier_call &&
2810b5ca3387SLuiz Augusto von Dentz 	    !test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
2811359ee4f8SAbhishek Pandit-Subedi 		hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
2812359ee4f8SAbhishek Pandit-Subedi 		ret = register_pm_notifier(&hdev->suspend_notifier);
2813359ee4f8SAbhishek Pandit-Subedi 	}
2814359ee4f8SAbhishek Pandit-Subedi 
2815359ee4f8SAbhishek Pandit-Subedi 	return ret;
2816359ee4f8SAbhishek Pandit-Subedi }
2817359ee4f8SAbhishek Pandit-Subedi 
2818359ee4f8SAbhishek Pandit-Subedi int hci_unregister_suspend_notifier(struct hci_dev *hdev)
2819359ee4f8SAbhishek Pandit-Subedi {
2820359ee4f8SAbhishek Pandit-Subedi 	int ret = 0;
2821359ee4f8SAbhishek Pandit-Subedi 
2822b5ca3387SLuiz Augusto von Dentz 	if (hdev->suspend_notifier.notifier_call) {
2823359ee4f8SAbhishek Pandit-Subedi 		ret = unregister_pm_notifier(&hdev->suspend_notifier);
2824b5ca3387SLuiz Augusto von Dentz 		if (!ret)
2825b5ca3387SLuiz Augusto von Dentz 			hdev->suspend_notifier.notifier_call = NULL;
2826b5ca3387SLuiz Augusto von Dentz 	}
2827359ee4f8SAbhishek Pandit-Subedi 
2828359ee4f8SAbhishek Pandit-Subedi 	return ret;
2829359ee4f8SAbhishek Pandit-Subedi }
2830359ee4f8SAbhishek Pandit-Subedi 
28310ce1229cSLuiz Augusto von Dentz /* Cancel ongoing command synchronously:
28320ce1229cSLuiz Augusto von Dentz  *
28330ce1229cSLuiz Augusto von Dentz  * - Cancel command timer
28340ce1229cSLuiz Augusto von Dentz  * - Reset command counter
28350ce1229cSLuiz Augusto von Dentz  * - Cancel command request
28360ce1229cSLuiz Augusto von Dentz  */
28370ce1229cSLuiz Augusto von Dentz static void hci_cancel_cmd_sync(struct hci_dev *hdev, int err)
28380ce1229cSLuiz Augusto von Dentz {
28390ce1229cSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "err 0x%2.2x", err);
28400ce1229cSLuiz Augusto von Dentz 
28410ce1229cSLuiz Augusto von Dentz 	cancel_delayed_work_sync(&hdev->cmd_timer);
28420ce1229cSLuiz Augusto von Dentz 	cancel_delayed_work_sync(&hdev->ncmd_timer);
28430ce1229cSLuiz Augusto von Dentz 	atomic_set(&hdev->cmd_cnt, 1);
28440ce1229cSLuiz Augusto von Dentz 
28450ce1229cSLuiz Augusto von Dentz 	hci_cmd_sync_cancel_sync(hdev, -err);
28460ce1229cSLuiz Augusto von Dentz }
28470ce1229cSLuiz Augusto von Dentz 
28481da177e4SLinus Torvalds /* Suspend HCI device */
28491da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
28501da177e4SLinus Torvalds {
2851e1b77d68SLuiz Augusto von Dentz 	int ret;
2852e1b77d68SLuiz Augusto von Dentz 
2853e1b77d68SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
2854e1b77d68SLuiz Augusto von Dentz 
2855e1b77d68SLuiz Augusto von Dentz 	/* Suspend should only act on when powered. */
2856e1b77d68SLuiz Augusto von Dentz 	if (!hdev_is_powered(hdev) ||
2857e1b77d68SLuiz Augusto von Dentz 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
28581da177e4SLinus Torvalds 		return 0;
2859e1b77d68SLuiz Augusto von Dentz 
2860182ee45dSLuiz Augusto von Dentz 	/* If powering down don't attempt to suspend */
2861182ee45dSLuiz Augusto von Dentz 	if (mgmt_powering_down(hdev))
2862182ee45dSLuiz Augusto von Dentz 		return 0;
2863e1b77d68SLuiz Augusto von Dentz 
2864f4198635SArchie Pusaka 	/* Cancel potentially blocking sync operation before suspend */
28650ce1229cSLuiz Augusto von Dentz 	hci_cancel_cmd_sync(hdev, -EHOSTDOWN);
2866f4198635SArchie Pusaka 
2867182ee45dSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
2868182ee45dSLuiz Augusto von Dentz 	ret = hci_suspend_sync(hdev);
2869182ee45dSLuiz Augusto von Dentz 	hci_req_sync_unlock(hdev);
28704539ca67SLuiz Augusto von Dentz 
2871e1b77d68SLuiz Augusto von Dentz 	hci_clear_wake_reason(hdev);
2872182ee45dSLuiz Augusto von Dentz 	mgmt_suspending(hdev, hdev->suspend_state);
2873e1b77d68SLuiz Augusto von Dentz 
2874e1b77d68SLuiz Augusto von Dentz 	hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
2875e1b77d68SLuiz Augusto von Dentz 	return ret;
28761da177e4SLinus Torvalds }
28771da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
28781da177e4SLinus Torvalds 
28791da177e4SLinus Torvalds /* Resume HCI device */
28801da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
28811da177e4SLinus Torvalds {
2882e1b77d68SLuiz Augusto von Dentz 	int ret;
2883e1b77d68SLuiz Augusto von Dentz 
2884e1b77d68SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
2885e1b77d68SLuiz Augusto von Dentz 
2886e1b77d68SLuiz Augusto von Dentz 	/* Resume should only act on when powered. */
2887e1b77d68SLuiz Augusto von Dentz 	if (!hdev_is_powered(hdev) ||
2888e1b77d68SLuiz Augusto von Dentz 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
28891da177e4SLinus Torvalds 		return 0;
2890e1b77d68SLuiz Augusto von Dentz 
2891e1b77d68SLuiz Augusto von Dentz 	/* If powering down don't attempt to resume */
2892e1b77d68SLuiz Augusto von Dentz 	if (mgmt_powering_down(hdev))
2893e1b77d68SLuiz Augusto von Dentz 		return 0;
2894e1b77d68SLuiz Augusto von Dentz 
2895182ee45dSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
2896182ee45dSLuiz Augusto von Dentz 	ret = hci_resume_sync(hdev);
2897182ee45dSLuiz Augusto von Dentz 	hci_req_sync_unlock(hdev);
2898e1b77d68SLuiz Augusto von Dentz 
2899e1b77d68SLuiz Augusto von Dentz 	mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr,
2900e1b77d68SLuiz Augusto von Dentz 		      hdev->wake_addr_type);
2901e1b77d68SLuiz Augusto von Dentz 
2902e1b77d68SLuiz Augusto von Dentz 	hci_sock_dev_event(hdev, HCI_DEV_RESUME);
2903e1b77d68SLuiz Augusto von Dentz 	return ret;
29041da177e4SLinus Torvalds }
29051da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
29061da177e4SLinus Torvalds 
290775e0569fSMarcel Holtmann /* Reset HCI device */
290875e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
290975e0569fSMarcel Holtmann {
29101e4b6e91SColin Ian King 	static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
291175e0569fSMarcel Holtmann 	struct sk_buff *skb;
291275e0569fSMarcel Holtmann 
291375e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
291475e0569fSMarcel Holtmann 	if (!skb)
291575e0569fSMarcel Holtmann 		return -ENOMEM;
291675e0569fSMarcel Holtmann 
2917d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
291859ae1d12SJohannes Berg 	skb_put_data(skb, hw_err, 3);
291975e0569fSMarcel Holtmann 
2920de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Injecting HCI hardware error event");
2921de75cd0dSManish Mandlik 
292275e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
292375e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
292475e0569fSMarcel Holtmann }
292575e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
292675e0569fSMarcel Holtmann 
292776bca880SMarcel Holtmann /* Receive frame from HCI drivers */
2928e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
292976bca880SMarcel Holtmann {
293076bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
293176bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
293276bca880SMarcel Holtmann 		kfree_skb(skb);
293376bca880SMarcel Holtmann 		return -ENXIO;
293476bca880SMarcel Holtmann 	}
293576bca880SMarcel Holtmann 
2936876e7810SLuiz Augusto von Dentz 	switch (hci_skb_pkt_type(skb)) {
2937876e7810SLuiz Augusto von Dentz 	case HCI_EVENT_PKT:
2938876e7810SLuiz Augusto von Dentz 		break;
2939876e7810SLuiz Augusto von Dentz 	case HCI_ACLDATA_PKT:
2940876e7810SLuiz Augusto von Dentz 		/* Detect if ISO packet has been sent as ACL */
2941876e7810SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, ISO_LINK)) {
2942876e7810SLuiz Augusto von Dentz 			__u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle);
2943876e7810SLuiz Augusto von Dentz 			__u8 type;
2944876e7810SLuiz Augusto von Dentz 
2945876e7810SLuiz Augusto von Dentz 			type = hci_conn_lookup_type(hdev, hci_handle(handle));
2946876e7810SLuiz Augusto von Dentz 			if (type == ISO_LINK)
2947876e7810SLuiz Augusto von Dentz 				hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
2948876e7810SLuiz Augusto von Dentz 		}
2949876e7810SLuiz Augusto von Dentz 		break;
2950876e7810SLuiz Augusto von Dentz 	case HCI_SCODATA_PKT:
2951876e7810SLuiz Augusto von Dentz 		break;
2952876e7810SLuiz Augusto von Dentz 	case HCI_ISODATA_PKT:
2953876e7810SLuiz Augusto von Dentz 		break;
2954876e7810SLuiz Augusto von Dentz 	default:
2955fe806dceSMarcel Holtmann 		kfree_skb(skb);
2956fe806dceSMarcel Holtmann 		return -EINVAL;
2957fe806dceSMarcel Holtmann 	}
2958fe806dceSMarcel Holtmann 
2959d82603c6SJorrit Schippers 	/* Incoming skb */
296076bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
296176bca880SMarcel Holtmann 
296276bca880SMarcel Holtmann 	/* Time stamp */
296376bca880SMarcel Holtmann 	__net_timestamp(skb);
296476bca880SMarcel Holtmann 
296576bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2966b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2967c78ae283SMarcel Holtmann 
296876bca880SMarcel Holtmann 	return 0;
296976bca880SMarcel Holtmann }
297076bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
297176bca880SMarcel Holtmann 
2972e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */
2973e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
2974e875ff84SMarcel Holtmann {
2975581d6fd6SMarcel Holtmann 	/* Mark as diagnostic packet */
2976d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_DIAG_PKT;
2977581d6fd6SMarcel Holtmann 
2978e875ff84SMarcel Holtmann 	/* Time stamp */
2979e875ff84SMarcel Holtmann 	__net_timestamp(skb);
2980e875ff84SMarcel Holtmann 
2981581d6fd6SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2982581d6fd6SMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2983e875ff84SMarcel Holtmann 
2984e875ff84SMarcel Holtmann 	return 0;
2985e875ff84SMarcel Holtmann }
2986e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag);
2987e875ff84SMarcel Holtmann 
29885177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...)
29895177a838SMarcel Holtmann {
29905177a838SMarcel Holtmann 	va_list vargs;
29915177a838SMarcel Holtmann 
29925177a838SMarcel Holtmann 	va_start(vargs, fmt);
29935177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
29945177a838SMarcel Holtmann 	hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
29955177a838SMarcel Holtmann 	va_end(vargs);
29965177a838SMarcel Holtmann }
29975177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info);
29985177a838SMarcel Holtmann 
29995177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...)
30005177a838SMarcel Holtmann {
30015177a838SMarcel Holtmann 	va_list vargs;
30025177a838SMarcel Holtmann 
30035177a838SMarcel Holtmann 	va_start(vargs, fmt);
30045177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
30055177a838SMarcel Holtmann 	hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
30065177a838SMarcel Holtmann 	va_end(vargs);
30075177a838SMarcel Holtmann }
30085177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info);
30095177a838SMarcel Holtmann 
30101da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
30111da177e4SLinus Torvalds 
30121da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
30131da177e4SLinus Torvalds {
30141da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
30151da177e4SLinus Torvalds 
3016fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
301700629e0fSJohan Hedberg 	list_add_tail(&cb->list, &hci_cb_list);
3018fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
30191da177e4SLinus Torvalds 
30201da177e4SLinus Torvalds 	return 0;
30211da177e4SLinus Torvalds }
30221da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
30231da177e4SLinus Torvalds 
30241da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
30251da177e4SLinus Torvalds {
30261da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
30271da177e4SLinus Torvalds 
3028fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
30291da177e4SLinus Torvalds 	list_del(&cb->list);
3030fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
30311da177e4SLinus Torvalds 
30321da177e4SLinus Torvalds 	return 0;
30331da177e4SLinus Torvalds }
30341da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
30351da177e4SLinus Torvalds 
30362250abadSBenjamin Berg static int hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
30371da177e4SLinus Torvalds {
3038cdc52faaSMarcel Holtmann 	int err;
3039cdc52faaSMarcel Holtmann 
3040d79f34e3SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb),
3041d79f34e3SMarcel Holtmann 	       skb->len);
30421da177e4SLinus Torvalds 
30431da177e4SLinus Torvalds 	/* Time stamp */
3044a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
30451da177e4SLinus Torvalds 
3046cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
3047cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
3048cd82e61cSMarcel Holtmann 
3049cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
3050cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
3051470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
30521da177e4SLinus Torvalds 	}
30531da177e4SLinus Torvalds 
30541da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
30551da177e4SLinus Torvalds 	skb_orphan(skb);
30561da177e4SLinus Torvalds 
305773d0d3c8SMarcel Holtmann 	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
305873d0d3c8SMarcel Holtmann 		kfree_skb(skb);
30592250abadSBenjamin Berg 		return -EINVAL;
306073d0d3c8SMarcel Holtmann 	}
306173d0d3c8SMarcel Holtmann 
3062cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
3063cdc52faaSMarcel Holtmann 	if (err < 0) {
30642064ee33SMarcel Holtmann 		bt_dev_err(hdev, "sending frame failed (%d)", err);
3065cdc52faaSMarcel Holtmann 		kfree_skb(skb);
30662250abadSBenjamin Berg 		return err;
3067cdc52faaSMarcel Holtmann 	}
30682250abadSBenjamin Berg 
30692250abadSBenjamin Berg 	return 0;
30701da177e4SLinus Torvalds }
30711da177e4SLinus Torvalds 
30721ca3a9d0SJohan Hedberg /* Send HCI command */
307307dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
307407dc93ddSJohan Hedberg 		 const void *param)
30751ca3a9d0SJohan Hedberg {
30761ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
30771ca3a9d0SJohan Hedberg 
30781ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
30791ca3a9d0SJohan Hedberg 
30801ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
30811ca3a9d0SJohan Hedberg 	if (!skb) {
30822064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no memory for command");
30831ca3a9d0SJohan Hedberg 		return -ENOMEM;
30841ca3a9d0SJohan Hedberg 	}
30851ca3a9d0SJohan Hedberg 
308649c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
308711714b3dSJohan Hedberg 	 * single-command requests.
308811714b3dSJohan Hedberg 	 */
308944d27137SJohan Hedberg 	bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
309011714b3dSJohan Hedberg 
30911da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
3092c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
30931da177e4SLinus Torvalds 
30941da177e4SLinus Torvalds 	return 0;
30951da177e4SLinus Torvalds }
30961da177e4SLinus Torvalds 
3097d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
3098d6ee6ad7SLoic Poulain 		   const void *param)
3099d6ee6ad7SLoic Poulain {
3100d6ee6ad7SLoic Poulain 	struct sk_buff *skb;
3101d6ee6ad7SLoic Poulain 
3102d6ee6ad7SLoic Poulain 	if (hci_opcode_ogf(opcode) != 0x3f) {
3103d6ee6ad7SLoic Poulain 		/* A controller receiving a command shall respond with either
3104d6ee6ad7SLoic Poulain 		 * a Command Status Event or a Command Complete Event.
3105d6ee6ad7SLoic Poulain 		 * Therefore, all standard HCI commands must be sent via the
3106d6ee6ad7SLoic Poulain 		 * standard API, using hci_send_cmd or hci_cmd_sync helpers.
3107d6ee6ad7SLoic Poulain 		 * Some vendors do not comply with this rule for vendor-specific
3108d6ee6ad7SLoic Poulain 		 * commands and do not return any event. We want to support
3109d6ee6ad7SLoic Poulain 		 * unresponded commands for such cases only.
3110d6ee6ad7SLoic Poulain 		 */
3111d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "unresponded command not supported");
3112d6ee6ad7SLoic Poulain 		return -EINVAL;
3113d6ee6ad7SLoic Poulain 	}
3114d6ee6ad7SLoic Poulain 
3115d6ee6ad7SLoic Poulain 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
3116d6ee6ad7SLoic Poulain 	if (!skb) {
3117d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)",
3118d6ee6ad7SLoic Poulain 			   opcode);
3119d6ee6ad7SLoic Poulain 		return -ENOMEM;
3120d6ee6ad7SLoic Poulain 	}
3121d6ee6ad7SLoic Poulain 
3122d6ee6ad7SLoic Poulain 	hci_send_frame(hdev, skb);
3123d6ee6ad7SLoic Poulain 
3124d6ee6ad7SLoic Poulain 	return 0;
3125d6ee6ad7SLoic Poulain }
3126d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send);
3127d6ee6ad7SLoic Poulain 
31281da177e4SLinus Torvalds /* Get data from the previously sent command */
31292af7aa66SLuiz Augusto von Dentz static void *hci_cmd_data(struct sk_buff *skb, __u16 opcode)
31301da177e4SLinus Torvalds {
31311da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
31321da177e4SLinus Torvalds 
31332af7aa66SLuiz Augusto von Dentz 	if (!skb || skb->len < HCI_COMMAND_HDR_SIZE)
31341da177e4SLinus Torvalds 		return NULL;
31351da177e4SLinus Torvalds 
31362af7aa66SLuiz Augusto von Dentz 	hdr = (void *)skb->data;
31371da177e4SLinus Torvalds 
3138a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
31391da177e4SLinus Torvalds 		return NULL;
31401da177e4SLinus Torvalds 
31412af7aa66SLuiz Augusto von Dentz 	return skb->data + HCI_COMMAND_HDR_SIZE;
31422af7aa66SLuiz Augusto von Dentz }
31431da177e4SLinus Torvalds 
31442af7aa66SLuiz Augusto von Dentz /* Get data from the previously sent command */
31452af7aa66SLuiz Augusto von Dentz void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
31462af7aa66SLuiz Augusto von Dentz {
31472af7aa66SLuiz Augusto von Dentz 	void *data;
31482af7aa66SLuiz Augusto von Dentz 
31492af7aa66SLuiz Augusto von Dentz 	/* Check if opcode matches last sent command */
31502af7aa66SLuiz Augusto von Dentz 	data = hci_cmd_data(hdev->sent_cmd, opcode);
31512af7aa66SLuiz Augusto von Dentz 	if (!data)
31522af7aa66SLuiz Augusto von Dentz 		/* Check if opcode matches last request */
31532af7aa66SLuiz Augusto von Dentz 		data = hci_cmd_data(hdev->req_skb, opcode);
31542af7aa66SLuiz Augusto von Dentz 
31552af7aa66SLuiz Augusto von Dentz 	return data;
31561da177e4SLinus Torvalds }
31571da177e4SLinus Torvalds 
3158dfe6d5c3SLuiz Augusto von Dentz /* Get data from last received event */
3159dfe6d5c3SLuiz Augusto von Dentz void *hci_recv_event_data(struct hci_dev *hdev, __u8 event)
3160dfe6d5c3SLuiz Augusto von Dentz {
3161dfe6d5c3SLuiz Augusto von Dentz 	struct hci_event_hdr *hdr;
3162dfe6d5c3SLuiz Augusto von Dentz 	int offset;
3163dfe6d5c3SLuiz Augusto von Dentz 
3164dfe6d5c3SLuiz Augusto von Dentz 	if (!hdev->recv_event)
3165dfe6d5c3SLuiz Augusto von Dentz 		return NULL;
3166dfe6d5c3SLuiz Augusto von Dentz 
3167dfe6d5c3SLuiz Augusto von Dentz 	hdr = (void *)hdev->recv_event->data;
3168dfe6d5c3SLuiz Augusto von Dentz 	offset = sizeof(*hdr);
3169dfe6d5c3SLuiz Augusto von Dentz 
3170dfe6d5c3SLuiz Augusto von Dentz 	if (hdr->evt != event) {
3171dfe6d5c3SLuiz Augusto von Dentz 		/* In case of LE metaevent check the subevent match */
3172dfe6d5c3SLuiz Augusto von Dentz 		if (hdr->evt == HCI_EV_LE_META) {
3173dfe6d5c3SLuiz Augusto von Dentz 			struct hci_ev_le_meta *ev;
3174dfe6d5c3SLuiz Augusto von Dentz 
3175dfe6d5c3SLuiz Augusto von Dentz 			ev = (void *)hdev->recv_event->data + offset;
3176dfe6d5c3SLuiz Augusto von Dentz 			offset += sizeof(*ev);
3177dfe6d5c3SLuiz Augusto von Dentz 			if (ev->subevent == event)
3178dfe6d5c3SLuiz Augusto von Dentz 				goto found;
3179dfe6d5c3SLuiz Augusto von Dentz 		}
3180dfe6d5c3SLuiz Augusto von Dentz 		return NULL;
3181dfe6d5c3SLuiz Augusto von Dentz 	}
3182dfe6d5c3SLuiz Augusto von Dentz 
3183dfe6d5c3SLuiz Augusto von Dentz found:
3184dfe6d5c3SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "event 0x%2.2x", event);
3185dfe6d5c3SLuiz Augusto von Dentz 
3186dfe6d5c3SLuiz Augusto von Dentz 	return hdev->recv_event->data + offset;
3187dfe6d5c3SLuiz Augusto von Dentz }
3188dfe6d5c3SLuiz Augusto von Dentz 
31891da177e4SLinus Torvalds /* Send ACL data */
31901da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
31911da177e4SLinus Torvalds {
31921da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
31931da177e4SLinus Torvalds 	int len = skb->len;
31941da177e4SLinus Torvalds 
3195badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3196badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
31979c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
3198aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3199aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
32001da177e4SLinus Torvalds }
32011da177e4SLinus Torvalds 
3202ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
320373d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
32041da177e4SLinus Torvalds {
3205ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
32061da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
32071da177e4SLinus Torvalds 	struct sk_buff *list;
32081da177e4SLinus Torvalds 
3209087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3210087bfd99SGustavo Padovan 	skb->data_len = 0;
3211087bfd99SGustavo Padovan 
3212d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3213204a6e54SAndrei Emeltchenko 
3214204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
3215ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
3216087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
3217204a6e54SAndrei Emeltchenko 		break;
3218204a6e54SAndrei Emeltchenko 	case HCI_AMP:
3219204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
3220204a6e54SAndrei Emeltchenko 		break;
3221204a6e54SAndrei Emeltchenko 	default:
32222064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type);
3223204a6e54SAndrei Emeltchenko 		return;
3224204a6e54SAndrei Emeltchenko 	}
3225087bfd99SGustavo Padovan 
322670f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
322770f23020SAndrei Emeltchenko 	if (!list) {
32281da177e4SLinus Torvalds 		/* Non fragmented */
32291da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
32301da177e4SLinus Torvalds 
323173d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
32321da177e4SLinus Torvalds 	} else {
32331da177e4SLinus Torvalds 		/* Fragmented */
32341da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
32351da177e4SLinus Torvalds 
32361da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
32371da177e4SLinus Torvalds 
32389cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
32399cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
32409cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
32419cfd5a23SJukka Rissanen 		 * deadlocks.
32429cfd5a23SJukka Rissanen 		 */
32439cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
32441da177e4SLinus Torvalds 
324573d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3246e702112fSAndrei Emeltchenko 
3247e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3248e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
32491da177e4SLinus Torvalds 		do {
32501da177e4SLinus Torvalds 			skb = list; list = list->next;
32511da177e4SLinus Torvalds 
3252d79f34e3SMarcel Holtmann 			hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3253e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
32541da177e4SLinus Torvalds 
32551da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
32561da177e4SLinus Torvalds 
325773d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
32581da177e4SLinus Torvalds 		} while (list);
32591da177e4SLinus Torvalds 
32609cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
32611da177e4SLinus Torvalds 	}
326273d80debSLuiz Augusto von Dentz }
326373d80debSLuiz Augusto von Dentz 
326473d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
326573d80debSLuiz Augusto von Dentz {
3266ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
326773d80debSLuiz Augusto von Dentz 
3268f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
326973d80debSLuiz Augusto von Dentz 
3270ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
32711da177e4SLinus Torvalds 
32723eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
32731da177e4SLinus Torvalds }
32741da177e4SLinus Torvalds 
32751da177e4SLinus Torvalds /* Send SCO data */
32760d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
32771da177e4SLinus Torvalds {
32781da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
32791da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
32801da177e4SLinus Torvalds 
32811da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
32821da177e4SLinus Torvalds 
3283aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
32841da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
32851da177e4SLinus Torvalds 
3286badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3287badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
32889c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
32891da177e4SLinus Torvalds 
3290d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
3291c78ae283SMarcel Holtmann 
32921da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
32933eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
32941da177e4SLinus Torvalds }
32951da177e4SLinus Torvalds 
329626afbd82SLuiz Augusto von Dentz /* Send ISO data */
329726afbd82SLuiz Augusto von Dentz static void hci_add_iso_hdr(struct sk_buff *skb, __u16 handle, __u8 flags)
329826afbd82SLuiz Augusto von Dentz {
329926afbd82SLuiz Augusto von Dentz 	struct hci_iso_hdr *hdr;
330026afbd82SLuiz Augusto von Dentz 	int len = skb->len;
330126afbd82SLuiz Augusto von Dentz 
330226afbd82SLuiz Augusto von Dentz 	skb_push(skb, HCI_ISO_HDR_SIZE);
330326afbd82SLuiz Augusto von Dentz 	skb_reset_transport_header(skb);
330426afbd82SLuiz Augusto von Dentz 	hdr = (struct hci_iso_hdr *)skb_transport_header(skb);
330526afbd82SLuiz Augusto von Dentz 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
330626afbd82SLuiz Augusto von Dentz 	hdr->dlen   = cpu_to_le16(len);
330726afbd82SLuiz Augusto von Dentz }
330826afbd82SLuiz Augusto von Dentz 
330926afbd82SLuiz Augusto von Dentz static void hci_queue_iso(struct hci_conn *conn, struct sk_buff_head *queue,
331026afbd82SLuiz Augusto von Dentz 			  struct sk_buff *skb)
331126afbd82SLuiz Augusto von Dentz {
331226afbd82SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
331326afbd82SLuiz Augusto von Dentz 	struct sk_buff *list;
331426afbd82SLuiz Augusto von Dentz 	__u16 flags;
331526afbd82SLuiz Augusto von Dentz 
331626afbd82SLuiz Augusto von Dentz 	skb->len = skb_headlen(skb);
331726afbd82SLuiz Augusto von Dentz 	skb->data_len = 0;
331826afbd82SLuiz Augusto von Dentz 
331926afbd82SLuiz Augusto von Dentz 	hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
332026afbd82SLuiz Augusto von Dentz 
332126afbd82SLuiz Augusto von Dentz 	list = skb_shinfo(skb)->frag_list;
332226afbd82SLuiz Augusto von Dentz 
332326afbd82SLuiz Augusto von Dentz 	flags = hci_iso_flags_pack(list ? ISO_START : ISO_SINGLE, 0x00);
332426afbd82SLuiz Augusto von Dentz 	hci_add_iso_hdr(skb, conn->handle, flags);
332526afbd82SLuiz Augusto von Dentz 
332626afbd82SLuiz Augusto von Dentz 	if (!list) {
332726afbd82SLuiz Augusto von Dentz 		/* Non fragmented */
332826afbd82SLuiz Augusto von Dentz 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
332926afbd82SLuiz Augusto von Dentz 
333026afbd82SLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
333126afbd82SLuiz Augusto von Dentz 	} else {
333226afbd82SLuiz Augusto von Dentz 		/* Fragmented */
333326afbd82SLuiz Augusto von Dentz 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
333426afbd82SLuiz Augusto von Dentz 
333526afbd82SLuiz Augusto von Dentz 		skb_shinfo(skb)->frag_list = NULL;
333626afbd82SLuiz Augusto von Dentz 
333726afbd82SLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
333826afbd82SLuiz Augusto von Dentz 
333926afbd82SLuiz Augusto von Dentz 		do {
334026afbd82SLuiz Augusto von Dentz 			skb = list; list = list->next;
334126afbd82SLuiz Augusto von Dentz 
334226afbd82SLuiz Augusto von Dentz 			hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
334326afbd82SLuiz Augusto von Dentz 			flags = hci_iso_flags_pack(list ? ISO_CONT : ISO_END,
334426afbd82SLuiz Augusto von Dentz 						   0x00);
334526afbd82SLuiz Augusto von Dentz 			hci_add_iso_hdr(skb, conn->handle, flags);
334626afbd82SLuiz Augusto von Dentz 
334726afbd82SLuiz Augusto von Dentz 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
334826afbd82SLuiz Augusto von Dentz 
334926afbd82SLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
335026afbd82SLuiz Augusto von Dentz 		} while (list);
335126afbd82SLuiz Augusto von Dentz 	}
335226afbd82SLuiz Augusto von Dentz }
335326afbd82SLuiz Augusto von Dentz 
335426afbd82SLuiz Augusto von Dentz void hci_send_iso(struct hci_conn *conn, struct sk_buff *skb)
335526afbd82SLuiz Augusto von Dentz {
335626afbd82SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
335726afbd82SLuiz Augusto von Dentz 
335826afbd82SLuiz Augusto von Dentz 	BT_DBG("%s len %d", hdev->name, skb->len);
335926afbd82SLuiz Augusto von Dentz 
336026afbd82SLuiz Augusto von Dentz 	hci_queue_iso(conn, &conn->data_q, skb);
336126afbd82SLuiz Augusto von Dentz 
336226afbd82SLuiz Augusto von Dentz 	queue_work(hdev->workqueue, &hdev->tx_work);
336326afbd82SLuiz Augusto von Dentz }
336426afbd82SLuiz Augusto von Dentz 
33651da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
33661da177e4SLinus Torvalds 
33671da177e4SLinus Torvalds /* HCI Connection scheduler */
336826afbd82SLuiz Augusto von Dentz static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote)
336926afbd82SLuiz Augusto von Dentz {
337026afbd82SLuiz Augusto von Dentz 	struct hci_dev *hdev;
337126afbd82SLuiz Augusto von Dentz 	int cnt, q;
337226afbd82SLuiz Augusto von Dentz 
337326afbd82SLuiz Augusto von Dentz 	if (!conn) {
337426afbd82SLuiz Augusto von Dentz 		*quote = 0;
337526afbd82SLuiz Augusto von Dentz 		return;
337626afbd82SLuiz Augusto von Dentz 	}
337726afbd82SLuiz Augusto von Dentz 
337826afbd82SLuiz Augusto von Dentz 	hdev = conn->hdev;
337926afbd82SLuiz Augusto von Dentz 
338026afbd82SLuiz Augusto von Dentz 	switch (conn->type) {
338126afbd82SLuiz Augusto von Dentz 	case ACL_LINK:
338226afbd82SLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
338326afbd82SLuiz Augusto von Dentz 		break;
338426afbd82SLuiz Augusto von Dentz 	case AMP_LINK:
338526afbd82SLuiz Augusto von Dentz 		cnt = hdev->block_cnt;
338626afbd82SLuiz Augusto von Dentz 		break;
338726afbd82SLuiz Augusto von Dentz 	case SCO_LINK:
338826afbd82SLuiz Augusto von Dentz 	case ESCO_LINK:
338926afbd82SLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
339026afbd82SLuiz Augusto von Dentz 		break;
339126afbd82SLuiz Augusto von Dentz 	case LE_LINK:
339226afbd82SLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
339326afbd82SLuiz Augusto von Dentz 		break;
339426afbd82SLuiz Augusto von Dentz 	case ISO_LINK:
339526afbd82SLuiz Augusto von Dentz 		cnt = hdev->iso_mtu ? hdev->iso_cnt :
339626afbd82SLuiz Augusto von Dentz 			hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
339726afbd82SLuiz Augusto von Dentz 		break;
339826afbd82SLuiz Augusto von Dentz 	default:
339926afbd82SLuiz Augusto von Dentz 		cnt = 0;
340026afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev, "unknown link type %d", conn->type);
340126afbd82SLuiz Augusto von Dentz 	}
340226afbd82SLuiz Augusto von Dentz 
340326afbd82SLuiz Augusto von Dentz 	q = cnt / num;
340426afbd82SLuiz Augusto von Dentz 	*quote = q ? q : 1;
340526afbd82SLuiz Augusto von Dentz }
340626afbd82SLuiz Augusto von Dentz 
34076039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3408a8c5fb1aSGustavo Padovan 				     int *quote)
34091da177e4SLinus Torvalds {
34101da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
34118035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
3412abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
34131da177e4SLinus Torvalds 
34141da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
34151da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
3416bf4c6325SGustavo F. Padovan 
3417bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3418bf4c6325SGustavo F. Padovan 
3419bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3420769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
34211da177e4SLinus Torvalds 			continue;
3422769be974SMarcel Holtmann 
3423769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3424769be974SMarcel Holtmann 			continue;
3425769be974SMarcel Holtmann 
34261da177e4SLinus Torvalds 		num++;
34271da177e4SLinus Torvalds 
34281da177e4SLinus Torvalds 		if (c->sent < min) {
34291da177e4SLinus Torvalds 			min  = c->sent;
34301da177e4SLinus Torvalds 			conn = c;
34311da177e4SLinus Torvalds 		}
343252087a79SLuiz Augusto von Dentz 
343352087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
343452087a79SLuiz Augusto von Dentz 			break;
34351da177e4SLinus Torvalds 	}
34361da177e4SLinus Torvalds 
3437bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3438bf4c6325SGustavo F. Padovan 
343926afbd82SLuiz Augusto von Dentz 	hci_quote_sent(conn, num, quote);
34401da177e4SLinus Torvalds 
34411da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
34421da177e4SLinus Torvalds 	return conn;
34431da177e4SLinus Torvalds }
34441da177e4SLinus Torvalds 
34456039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
34461da177e4SLinus Torvalds {
34471da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
34481da177e4SLinus Torvalds 	struct hci_conn *c;
34491da177e4SLinus Torvalds 
34502064ee33SMarcel Holtmann 	bt_dev_err(hdev, "link tx timeout");
34511da177e4SLinus Torvalds 
3452bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3453bf4c6325SGustavo F. Padovan 
34541da177e4SLinus Torvalds 	/* Kill stalled connections */
3455bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3456bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
34572064ee33SMarcel Holtmann 			bt_dev_err(hdev, "killing stalled connection %pMR",
34582064ee33SMarcel Holtmann 				   &c->dst);
3459c7eaf80bSYing Hsu 			/* hci_disconnect might sleep, so, we have to release
3460c7eaf80bSYing Hsu 			 * the RCU read lock before calling it.
3461c7eaf80bSYing Hsu 			 */
3462c7eaf80bSYing Hsu 			rcu_read_unlock();
3463bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
3464c7eaf80bSYing Hsu 			rcu_read_lock();
34651da177e4SLinus Torvalds 		}
34661da177e4SLinus Torvalds 	}
3467bf4c6325SGustavo F. Padovan 
3468bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
34691da177e4SLinus Torvalds }
34701da177e4SLinus Torvalds 
34716039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
347273d80debSLuiz Augusto von Dentz 				      int *quote)
347373d80debSLuiz Augusto von Dentz {
347473d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
347573d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3476abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
347773d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
347826afbd82SLuiz Augusto von Dentz 	int conn_num = 0;
347973d80debSLuiz Augusto von Dentz 
348073d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
348173d80debSLuiz Augusto von Dentz 
3482bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3483bf4c6325SGustavo F. Padovan 
3484bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
348573d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
348673d80debSLuiz Augusto von Dentz 
348773d80debSLuiz Augusto von Dentz 		if (conn->type != type)
348873d80debSLuiz Augusto von Dentz 			continue;
348973d80debSLuiz Augusto von Dentz 
349073d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
349173d80debSLuiz Augusto von Dentz 			continue;
349273d80debSLuiz Augusto von Dentz 
349373d80debSLuiz Augusto von Dentz 		conn_num++;
349473d80debSLuiz Augusto von Dentz 
34958192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
349673d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
349773d80debSLuiz Augusto von Dentz 
349873d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
349973d80debSLuiz Augusto von Dentz 				continue;
350073d80debSLuiz Augusto von Dentz 
350173d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
350273d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
350373d80debSLuiz Augusto von Dentz 				continue;
350473d80debSLuiz Augusto von Dentz 
350573d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
350673d80debSLuiz Augusto von Dentz 				num = 0;
350773d80debSLuiz Augusto von Dentz 				min = ~0;
350873d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
350973d80debSLuiz Augusto von Dentz 			}
351073d80debSLuiz Augusto von Dentz 
351173d80debSLuiz Augusto von Dentz 			num++;
351273d80debSLuiz Augusto von Dentz 
351373d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
351473d80debSLuiz Augusto von Dentz 				min  = conn->sent;
351573d80debSLuiz Augusto von Dentz 				chan = tmp;
351673d80debSLuiz Augusto von Dentz 			}
351773d80debSLuiz Augusto von Dentz 		}
351873d80debSLuiz Augusto von Dentz 
351973d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
352073d80debSLuiz Augusto von Dentz 			break;
352173d80debSLuiz Augusto von Dentz 	}
352273d80debSLuiz Augusto von Dentz 
3523bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3524bf4c6325SGustavo F. Padovan 
352573d80debSLuiz Augusto von Dentz 	if (!chan)
352673d80debSLuiz Augusto von Dentz 		return NULL;
352773d80debSLuiz Augusto von Dentz 
352826afbd82SLuiz Augusto von Dentz 	hci_quote_sent(chan->conn, num, quote);
352973d80debSLuiz Augusto von Dentz 
353073d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
353173d80debSLuiz Augusto von Dentz 	return chan;
353273d80debSLuiz Augusto von Dentz }
353373d80debSLuiz Augusto von Dentz 
353402b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
353502b20f0bSLuiz Augusto von Dentz {
353602b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
353702b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
353802b20f0bSLuiz Augusto von Dentz 	int num = 0;
353902b20f0bSLuiz Augusto von Dentz 
354002b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
354102b20f0bSLuiz Augusto von Dentz 
3542bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3543bf4c6325SGustavo F. Padovan 
3544bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
354502b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
354602b20f0bSLuiz Augusto von Dentz 
354702b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
354802b20f0bSLuiz Augusto von Dentz 			continue;
354902b20f0bSLuiz Augusto von Dentz 
355002b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
355102b20f0bSLuiz Augusto von Dentz 			continue;
355202b20f0bSLuiz Augusto von Dentz 
355302b20f0bSLuiz Augusto von Dentz 		num++;
355402b20f0bSLuiz Augusto von Dentz 
35558192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
355602b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
355702b20f0bSLuiz Augusto von Dentz 
355802b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
355902b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
356002b20f0bSLuiz Augusto von Dentz 				continue;
356102b20f0bSLuiz Augusto von Dentz 			}
356202b20f0bSLuiz Augusto von Dentz 
356302b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
356402b20f0bSLuiz Augusto von Dentz 				continue;
356502b20f0bSLuiz Augusto von Dentz 
356602b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
356702b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
356802b20f0bSLuiz Augusto von Dentz 				continue;
356902b20f0bSLuiz Augusto von Dentz 
357002b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
357102b20f0bSLuiz Augusto von Dentz 
357202b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
357302b20f0bSLuiz Augusto von Dentz 			       skb->priority);
357402b20f0bSLuiz Augusto von Dentz 		}
357502b20f0bSLuiz Augusto von Dentz 
357602b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
357702b20f0bSLuiz Augusto von Dentz 			break;
357802b20f0bSLuiz Augusto von Dentz 	}
3579bf4c6325SGustavo F. Padovan 
3580bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3581bf4c6325SGustavo F. Padovan 
358202b20f0bSLuiz Augusto von Dentz }
358302b20f0bSLuiz Augusto von Dentz 
3584b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3585b71d385aSAndrei Emeltchenko {
3586b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3587b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3588b71d385aSAndrei Emeltchenko }
3589b71d385aSAndrei Emeltchenko 
3590116523c8SLuiz Augusto von Dentz static void __check_timeout(struct hci_dev *hdev, unsigned int cnt, u8 type)
35911da177e4SLinus Torvalds {
3592116523c8SLuiz Augusto von Dentz 	unsigned long last_tx;
3593116523c8SLuiz Augusto von Dentz 
3594116523c8SLuiz Augusto von Dentz 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
3595116523c8SLuiz Augusto von Dentz 		return;
3596116523c8SLuiz Augusto von Dentz 
3597116523c8SLuiz Augusto von Dentz 	switch (type) {
3598116523c8SLuiz Augusto von Dentz 	case LE_LINK:
3599116523c8SLuiz Augusto von Dentz 		last_tx = hdev->le_last_tx;
3600116523c8SLuiz Augusto von Dentz 		break;
3601116523c8SLuiz Augusto von Dentz 	default:
3602116523c8SLuiz Augusto von Dentz 		last_tx = hdev->acl_last_tx;
3603116523c8SLuiz Augusto von Dentz 		break;
36041da177e4SLinus Torvalds 	}
3605116523c8SLuiz Augusto von Dentz 
3606116523c8SLuiz Augusto von Dentz 	/* tx timeout must be longer than maximum link supervision timeout
3607116523c8SLuiz Augusto von Dentz 	 * (40.9 seconds)
3608116523c8SLuiz Augusto von Dentz 	 */
3609116523c8SLuiz Augusto von Dentz 	if (!cnt && time_after(jiffies, last_tx + HCI_ACL_TX_TIMEOUT))
3610116523c8SLuiz Augusto von Dentz 		hci_link_tx_to(hdev, type);
361163d2bc1bSAndrei Emeltchenko }
36121da177e4SLinus Torvalds 
36137fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */
36147fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev)
36157fedd3bbSAbhishek Pandit-Subedi {
36167fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
36177fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
36187fedd3bbSAbhishek Pandit-Subedi 	int quote;
36197fedd3bbSAbhishek Pandit-Subedi 
36207fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
36217fedd3bbSAbhishek Pandit-Subedi 
36227fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, SCO_LINK))
36237fedd3bbSAbhishek Pandit-Subedi 		return;
36247fedd3bbSAbhishek Pandit-Subedi 
36257fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
36267fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
36277fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
36287fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
36297fedd3bbSAbhishek Pandit-Subedi 
36307fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
36317fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
36327fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
36337fedd3bbSAbhishek Pandit-Subedi 		}
36347fedd3bbSAbhishek Pandit-Subedi 	}
36357fedd3bbSAbhishek Pandit-Subedi }
36367fedd3bbSAbhishek Pandit-Subedi 
36377fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev)
36387fedd3bbSAbhishek Pandit-Subedi {
36397fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
36407fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
36417fedd3bbSAbhishek Pandit-Subedi 	int quote;
36427fedd3bbSAbhishek Pandit-Subedi 
36437fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
36447fedd3bbSAbhishek Pandit-Subedi 
36457fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, ESCO_LINK))
36467fedd3bbSAbhishek Pandit-Subedi 		return;
36477fedd3bbSAbhishek Pandit-Subedi 
36487fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
36497fedd3bbSAbhishek Pandit-Subedi 						     &quote))) {
36507fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
36517fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
36527fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
36537fedd3bbSAbhishek Pandit-Subedi 
36547fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
36557fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
36567fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
36577fedd3bbSAbhishek Pandit-Subedi 		}
36587fedd3bbSAbhishek Pandit-Subedi 	}
36597fedd3bbSAbhishek Pandit-Subedi }
36607fedd3bbSAbhishek Pandit-Subedi 
36616039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
366263d2bc1bSAndrei Emeltchenko {
366363d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
366463d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
366563d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
366663d2bc1bSAndrei Emeltchenko 	int quote;
366763d2bc1bSAndrei Emeltchenko 
3668116523c8SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt, ACL_LINK);
366904837f64SMarcel Holtmann 
367073d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
367173d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3672ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3673ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
367473d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
367573d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
367673d80debSLuiz Augusto von Dentz 
3677ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3678ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3679ec1cce24SLuiz Augusto von Dentz 				break;
3680ec1cce24SLuiz Augusto von Dentz 
3681ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3682ec1cce24SLuiz Augusto von Dentz 
368373d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
368473d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
368504837f64SMarcel Holtmann 
368657d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
36871da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
36881da177e4SLinus Torvalds 
36891da177e4SLinus Torvalds 			hdev->acl_cnt--;
369073d80debSLuiz Augusto von Dentz 			chan->sent++;
369173d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
36927fedd3bbSAbhishek Pandit-Subedi 
36937fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
36947fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
36957fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
36961da177e4SLinus Torvalds 		}
36971da177e4SLinus Torvalds 	}
369802b20f0bSLuiz Augusto von Dentz 
369902b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
370002b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
37011da177e4SLinus Torvalds }
37021da177e4SLinus Torvalds 
37036039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3704b71d385aSAndrei Emeltchenko {
370563d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3706b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3707b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3708b71d385aSAndrei Emeltchenko 	int quote;
3709bd1eb66bSAndrei Emeltchenko 	u8 type;
3710b71d385aSAndrei Emeltchenko 
3711bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3712bd1eb66bSAndrei Emeltchenko 
3713bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3714bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3715bd1eb66bSAndrei Emeltchenko 	else
3716bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3717bd1eb66bSAndrei Emeltchenko 
3718116523c8SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt, type);
3719116523c8SLuiz Augusto von Dentz 
3720b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3721bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3722b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3723b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3724b71d385aSAndrei Emeltchenko 			int blocks;
3725b71d385aSAndrei Emeltchenko 
3726b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3727b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3728b71d385aSAndrei Emeltchenko 
3729b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3730b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3731b71d385aSAndrei Emeltchenko 				break;
3732b71d385aSAndrei Emeltchenko 
3733b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3734b71d385aSAndrei Emeltchenko 
3735b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3736b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3737b71d385aSAndrei Emeltchenko 				return;
3738b71d385aSAndrei Emeltchenko 
3739b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3740b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3741b71d385aSAndrei Emeltchenko 
374257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3743b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3744b71d385aSAndrei Emeltchenko 
3745b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3746b71d385aSAndrei Emeltchenko 			quote -= blocks;
3747b71d385aSAndrei Emeltchenko 
3748b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3749b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3750b71d385aSAndrei Emeltchenko 		}
3751b71d385aSAndrei Emeltchenko 	}
3752b71d385aSAndrei Emeltchenko 
3753b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3754bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3755b71d385aSAndrei Emeltchenko }
3756b71d385aSAndrei Emeltchenko 
37576039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3758b71d385aSAndrei Emeltchenko {
3759b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3760b71d385aSAndrei Emeltchenko 
3761bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3762ca8bee5dSMarcel Holtmann 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY)
3763bd1eb66bSAndrei Emeltchenko 		return;
3764bd1eb66bSAndrei Emeltchenko 
3765bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3766bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3767b71d385aSAndrei Emeltchenko 		return;
3768b71d385aSAndrei Emeltchenko 
3769b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3770b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3771b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3772b71d385aSAndrei Emeltchenko 		break;
3773b71d385aSAndrei Emeltchenko 
3774b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3775b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3776b71d385aSAndrei Emeltchenko 		break;
3777b71d385aSAndrei Emeltchenko 	}
3778b71d385aSAndrei Emeltchenko }
3779b71d385aSAndrei Emeltchenko 
37806039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
37816ed58ec5SVille Tervo {
378273d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
37836ed58ec5SVille Tervo 	struct sk_buff *skb;
378402b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
37856ed58ec5SVille Tervo 
37866ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
37876ed58ec5SVille Tervo 
378852087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
378952087a79SLuiz Augusto von Dentz 		return;
379052087a79SLuiz Augusto von Dentz 
37916ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
37921b1d29e5SLuiz Augusto von Dentz 
3793116523c8SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt, LE_LINK);
37941b1d29e5SLuiz Augusto von Dentz 
379502b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
379673d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3797ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3798ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
379973d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
380073d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
38016ed58ec5SVille Tervo 
3802ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3803ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3804ec1cce24SLuiz Augusto von Dentz 				break;
3805ec1cce24SLuiz Augusto von Dentz 
3806ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3807ec1cce24SLuiz Augusto von Dentz 
380857d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
38096ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
38106ed58ec5SVille Tervo 
38116ed58ec5SVille Tervo 			cnt--;
381273d80debSLuiz Augusto von Dentz 			chan->sent++;
381373d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
38147fedd3bbSAbhishek Pandit-Subedi 
38157fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
38167fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
38177fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
38186ed58ec5SVille Tervo 		}
38196ed58ec5SVille Tervo 	}
382073d80debSLuiz Augusto von Dentz 
38216ed58ec5SVille Tervo 	if (hdev->le_pkts)
38226ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
38236ed58ec5SVille Tervo 	else
38246ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
382502b20f0bSLuiz Augusto von Dentz 
382602b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
382702b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
38286ed58ec5SVille Tervo }
38296ed58ec5SVille Tervo 
383026afbd82SLuiz Augusto von Dentz /* Schedule CIS */
383126afbd82SLuiz Augusto von Dentz static void hci_sched_iso(struct hci_dev *hdev)
383226afbd82SLuiz Augusto von Dentz {
383326afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
383426afbd82SLuiz Augusto von Dentz 	struct sk_buff *skb;
383526afbd82SLuiz Augusto von Dentz 	int quote, *cnt;
383626afbd82SLuiz Augusto von Dentz 
383726afbd82SLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
383826afbd82SLuiz Augusto von Dentz 
383926afbd82SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ISO_LINK))
384026afbd82SLuiz Augusto von Dentz 		return;
384126afbd82SLuiz Augusto von Dentz 
384226afbd82SLuiz Augusto von Dentz 	cnt = hdev->iso_pkts ? &hdev->iso_cnt :
384326afbd82SLuiz Augusto von Dentz 		hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt;
384426afbd82SLuiz Augusto von Dentz 	while (*cnt && (conn = hci_low_sent(hdev, ISO_LINK, &quote))) {
384526afbd82SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
384626afbd82SLuiz Augusto von Dentz 			BT_DBG("skb %p len %d", skb, skb->len);
384726afbd82SLuiz Augusto von Dentz 			hci_send_frame(hdev, skb);
384826afbd82SLuiz Augusto von Dentz 
384926afbd82SLuiz Augusto von Dentz 			conn->sent++;
385026afbd82SLuiz Augusto von Dentz 			if (conn->sent == ~0)
385126afbd82SLuiz Augusto von Dentz 				conn->sent = 0;
385226afbd82SLuiz Augusto von Dentz 			(*cnt)--;
385326afbd82SLuiz Augusto von Dentz 		}
385426afbd82SLuiz Augusto von Dentz 	}
385526afbd82SLuiz Augusto von Dentz }
385626afbd82SLuiz Augusto von Dentz 
38573eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
38581da177e4SLinus Torvalds {
38593eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
38601da177e4SLinus Torvalds 	struct sk_buff *skb;
38611da177e4SLinus Torvalds 
386226afbd82SLuiz Augusto von Dentz 	BT_DBG("%s acl %d sco %d le %d iso %d", hdev->name, hdev->acl_cnt,
386326afbd82SLuiz Augusto von Dentz 	       hdev->sco_cnt, hdev->le_cnt, hdev->iso_cnt);
38641da177e4SLinus Torvalds 
3865d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
38661da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
38671da177e4SLinus Torvalds 		hci_sched_sco(hdev);
3868b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
386926afbd82SLuiz Augusto von Dentz 		hci_sched_iso(hdev);
38707fedd3bbSAbhishek Pandit-Subedi 		hci_sched_acl(hdev);
38716ed58ec5SVille Tervo 		hci_sched_le(hdev);
387252de599eSMarcel Holtmann 	}
38736ed58ec5SVille Tervo 
38741da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
38751da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
387657d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
38771da177e4SLinus Torvalds }
38781da177e4SLinus Torvalds 
387925985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
38801da177e4SLinus Torvalds 
38811da177e4SLinus Torvalds /* ACL data packet */
38826039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
38831da177e4SLinus Torvalds {
38841da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
38851da177e4SLinus Torvalds 	struct hci_conn *conn;
38861da177e4SLinus Torvalds 	__u16 handle, flags;
38871da177e4SLinus Torvalds 
38881da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
38891da177e4SLinus Torvalds 
38901da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
38911da177e4SLinus Torvalds 	flags  = hci_flags(handle);
38921da177e4SLinus Torvalds 	handle = hci_handle(handle);
38931da177e4SLinus Torvalds 
3894f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3895a8c5fb1aSGustavo Padovan 	       handle, flags);
38961da177e4SLinus Torvalds 
38971da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
38981da177e4SLinus Torvalds 
38991da177e4SLinus Torvalds 	hci_dev_lock(hdev);
39001da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
39011da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
39021da177e4SLinus Torvalds 
39031da177e4SLinus Torvalds 	if (conn) {
390465983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
390504837f64SMarcel Holtmann 
39061da177e4SLinus Torvalds 		/* Send to upper protocol */
3907686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
39081da177e4SLinus Torvalds 		return;
39091da177e4SLinus Torvalds 	} else {
39102064ee33SMarcel Holtmann 		bt_dev_err(hdev, "ACL packet for unknown connection handle %d",
39112064ee33SMarcel Holtmann 			   handle);
39121da177e4SLinus Torvalds 	}
39131da177e4SLinus Torvalds 
39141da177e4SLinus Torvalds 	kfree_skb(skb);
39151da177e4SLinus Torvalds }
39161da177e4SLinus Torvalds 
39171da177e4SLinus Torvalds /* SCO data packet */
39186039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
39191da177e4SLinus Torvalds {
39201da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
39211da177e4SLinus Torvalds 	struct hci_conn *conn;
3922debdedf2SMarcel Holtmann 	__u16 handle, flags;
39231da177e4SLinus Torvalds 
39241da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
39251da177e4SLinus Torvalds 
39261da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
3927debdedf2SMarcel Holtmann 	flags  = hci_flags(handle);
3928debdedf2SMarcel Holtmann 	handle = hci_handle(handle);
39291da177e4SLinus Torvalds 
3930debdedf2SMarcel Holtmann 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3931debdedf2SMarcel Holtmann 	       handle, flags);
39321da177e4SLinus Torvalds 
39331da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
39341da177e4SLinus Torvalds 
39351da177e4SLinus Torvalds 	hci_dev_lock(hdev);
39361da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
39371da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
39381da177e4SLinus Torvalds 
39391da177e4SLinus Torvalds 	if (conn) {
39401da177e4SLinus Torvalds 		/* Send to upper protocol */
39413f19ffb2SLuiz Augusto von Dentz 		hci_skb_pkt_status(skb) = flags & 0x03;
3942686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
39431da177e4SLinus Torvalds 		return;
39441da177e4SLinus Torvalds 	} else {
39452d4b37b6SLuiz Augusto von Dentz 		bt_dev_err_ratelimited(hdev, "SCO packet for unknown connection handle %d",
39462064ee33SMarcel Holtmann 				       handle);
39471da177e4SLinus Torvalds 	}
39481da177e4SLinus Torvalds 
39491da177e4SLinus Torvalds 	kfree_skb(skb);
39501da177e4SLinus Torvalds }
39511da177e4SLinus Torvalds 
395226afbd82SLuiz Augusto von Dentz static void hci_isodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
395326afbd82SLuiz Augusto von Dentz {
395426afbd82SLuiz Augusto von Dentz 	struct hci_iso_hdr *hdr;
395526afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
395626afbd82SLuiz Augusto von Dentz 	__u16 handle, flags;
395726afbd82SLuiz Augusto von Dentz 
395826afbd82SLuiz Augusto von Dentz 	hdr = skb_pull_data(skb, sizeof(*hdr));
395926afbd82SLuiz Augusto von Dentz 	if (!hdr) {
396026afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev, "ISO packet too small");
396126afbd82SLuiz Augusto von Dentz 		goto drop;
396226afbd82SLuiz Augusto von Dentz 	}
396326afbd82SLuiz Augusto von Dentz 
396426afbd82SLuiz Augusto von Dentz 	handle = __le16_to_cpu(hdr->handle);
396526afbd82SLuiz Augusto von Dentz 	flags  = hci_flags(handle);
396626afbd82SLuiz Augusto von Dentz 	handle = hci_handle(handle);
396726afbd82SLuiz Augusto von Dentz 
396826afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "len %d handle 0x%4.4x flags 0x%4.4x", skb->len,
396926afbd82SLuiz Augusto von Dentz 		   handle, flags);
397026afbd82SLuiz Augusto von Dentz 
397126afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
397226afbd82SLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_handle(hdev, handle);
397326afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
397426afbd82SLuiz Augusto von Dentz 
397526afbd82SLuiz Augusto von Dentz 	if (!conn) {
397626afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev, "ISO packet for unknown connection handle %d",
397726afbd82SLuiz Augusto von Dentz 			   handle);
3978ccf74f23SLuiz Augusto von Dentz 		goto drop;
397926afbd82SLuiz Augusto von Dentz 	}
398026afbd82SLuiz Augusto von Dentz 
3981ccf74f23SLuiz Augusto von Dentz 	/* Send to upper protocol */
3982ccf74f23SLuiz Augusto von Dentz 	iso_recv(conn, skb, flags);
3983ccf74f23SLuiz Augusto von Dentz 	return;
3984ccf74f23SLuiz Augusto von Dentz 
398526afbd82SLuiz Augusto von Dentz drop:
398626afbd82SLuiz Augusto von Dentz 	kfree_skb(skb);
398726afbd82SLuiz Augusto von Dentz }
398826afbd82SLuiz Augusto von Dentz 
39899238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
39909238f36aSJohan Hedberg {
39919238f36aSJohan Hedberg 	struct sk_buff *skb;
39929238f36aSJohan Hedberg 
39939238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
39949238f36aSJohan Hedberg 	if (!skb)
39959238f36aSJohan Hedberg 		return true;
39969238f36aSJohan Hedberg 
399744d27137SJohan Hedberg 	return (bt_cb(skb)->hci.req_flags & HCI_REQ_START);
39989238f36aSJohan Hedberg }
39999238f36aSJohan Hedberg 
400042c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
400142c6b129SJohan Hedberg {
400242c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
400342c6b129SJohan Hedberg 	struct sk_buff *skb;
400442c6b129SJohan Hedberg 	u16 opcode;
400542c6b129SJohan Hedberg 
400642c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
400742c6b129SJohan Hedberg 		return;
400842c6b129SJohan Hedberg 
400942c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
401042c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
401142c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
401242c6b129SJohan Hedberg 		return;
401342c6b129SJohan Hedberg 
401442c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
401542c6b129SJohan Hedberg 	if (!skb)
401642c6b129SJohan Hedberg 		return;
401742c6b129SJohan Hedberg 
401842c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
401942c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
402042c6b129SJohan Hedberg }
402142c6b129SJohan Hedberg 
4022e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
4023e6214487SJohan Hedberg 			  hci_req_complete_t *req_complete,
4024e6214487SJohan Hedberg 			  hci_req_complete_skb_t *req_complete_skb)
40259238f36aSJohan Hedberg {
40269238f36aSJohan Hedberg 	struct sk_buff *skb;
40279238f36aSJohan Hedberg 	unsigned long flags;
40289238f36aSJohan Hedberg 
40299238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
40309238f36aSJohan Hedberg 
403142c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
403242c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
40339238f36aSJohan Hedberg 	 */
403442c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
403542c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
403642c6b129SJohan Hedberg 		 * reset complete event during init and any pending
403742c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
403842c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
403942c6b129SJohan Hedberg 		 * command.
404042c6b129SJohan Hedberg 		 */
404142c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
404242c6b129SJohan Hedberg 			hci_resend_last(hdev);
404342c6b129SJohan Hedberg 
40449238f36aSJohan Hedberg 		return;
404542c6b129SJohan Hedberg 	}
40469238f36aSJohan Hedberg 
4047f80c5dadSJoão Paulo Rechi Vita 	/* If we reach this point this event matches the last command sent */
4048f80c5dadSJoão Paulo Rechi Vita 	hci_dev_clear_flag(hdev, HCI_CMD_PENDING);
4049f80c5dadSJoão Paulo Rechi Vita 
40509238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
40519238f36aSJohan Hedberg 	 * this request the request is not yet complete.
40529238f36aSJohan Hedberg 	 */
40539238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
40549238f36aSJohan Hedberg 		return;
40559238f36aSJohan Hedberg 
40562af7aa66SLuiz Augusto von Dentz 	skb = hdev->req_skb;
40572af7aa66SLuiz Augusto von Dentz 
40589238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
40592af7aa66SLuiz Augusto von Dentz 	 * callback would be found in hdev->req_skb instead of the
40609238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
40619238f36aSJohan Hedberg 	 */
40622af7aa66SLuiz Augusto von Dentz 	if (skb && bt_cb(skb)->hci.req_flags & HCI_REQ_SKB) {
40632af7aa66SLuiz Augusto von Dentz 		*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
4064e6214487SJohan Hedberg 		return;
40659238f36aSJohan Hedberg 	}
4066e6214487SJohan Hedberg 
40672af7aa66SLuiz Augusto von Dentz 	if (skb && bt_cb(skb)->hci.req_complete) {
40682af7aa66SLuiz Augusto von Dentz 		*req_complete = bt_cb(skb)->hci.req_complete;
4069e6214487SJohan Hedberg 		return;
407053e21fbcSJohan Hedberg 	}
40719238f36aSJohan Hedberg 
40729238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
40739238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
40749238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
407544d27137SJohan Hedberg 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) {
40769238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
40779238f36aSJohan Hedberg 			break;
40789238f36aSJohan Hedberg 		}
40799238f36aSJohan Hedberg 
40803bd7594eSDouglas Anderson 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB)
4081242c0ebdSMarcel Holtmann 			*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
40823bd7594eSDouglas Anderson 		else
40833bd7594eSDouglas Anderson 			*req_complete = bt_cb(skb)->hci.req_complete;
408439c1eb6fSYang Yingliang 		dev_kfree_skb_irq(skb);
40859238f36aSJohan Hedberg 	}
40869238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
40879238f36aSJohan Hedberg }
40889238f36aSJohan Hedberg 
4089b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
40901da177e4SLinus Torvalds {
4091b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
40921da177e4SLinus Torvalds 	struct sk_buff *skb;
40931da177e4SLinus Torvalds 
40941da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
40951da177e4SLinus Torvalds 
40969f30de9eSTamas Koczka 	/* The kcov_remote functions used for collecting packet parsing
40979f30de9eSTamas Koczka 	 * coverage information from this background thread and associate
40989f30de9eSTamas Koczka 	 * the coverage with the syscall's thread which originally injected
40999f30de9eSTamas Koczka 	 * the packet. This helps fuzzing the kernel.
41009f30de9eSTamas Koczka 	 */
41019f30de9eSTamas Koczka 	for (; (skb = skb_dequeue(&hdev->rx_q)); kcov_remote_stop()) {
41029f30de9eSTamas Koczka 		kcov_remote_start_common(skb_get_kcov_handle(skb));
41039f30de9eSTamas Koczka 
4104cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
4105cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
4106cd82e61cSMarcel Holtmann 
41071da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
41081da177e4SLinus Torvalds 			/* Send copy to the sockets */
4109470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
41101da177e4SLinus Torvalds 		}
41111da177e4SLinus Torvalds 
4112eb8c101eSMattijs Korpershoek 		/* If the device has been opened in HCI_USER_CHANNEL,
4113eb8c101eSMattijs Korpershoek 		 * the userspace has exclusive access to device.
4114eb8c101eSMattijs Korpershoek 		 * When device is HCI_INIT, we still need to process
4115eb8c101eSMattijs Korpershoek 		 * the data packets to the driver in order
4116eb8c101eSMattijs Korpershoek 		 * to complete its setup().
4117eb8c101eSMattijs Korpershoek 		 */
4118eb8c101eSMattijs Korpershoek 		if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
4119eb8c101eSMattijs Korpershoek 		    !test_bit(HCI_INIT, &hdev->flags)) {
41201da177e4SLinus Torvalds 			kfree_skb(skb);
41211da177e4SLinus Torvalds 			continue;
41221da177e4SLinus Torvalds 		}
41231da177e4SLinus Torvalds 
41241da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
41251da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
4126d79f34e3SMarcel Holtmann 			switch (hci_skb_pkt_type(skb)) {
41271da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
41281da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
4129cc974003SMarcel Holtmann 			case HCI_ISODATA_PKT:
41301da177e4SLinus Torvalds 				kfree_skb(skb);
41311da177e4SLinus Torvalds 				continue;
41323ff50b79SStephen Hemminger 			}
41331da177e4SLinus Torvalds 		}
41341da177e4SLinus Torvalds 
41351da177e4SLinus Torvalds 		/* Process frame */
4136d79f34e3SMarcel Holtmann 		switch (hci_skb_pkt_type(skb)) {
41371da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
4138b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
41391da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
41401da177e4SLinus Torvalds 			break;
41411da177e4SLinus Torvalds 
41421da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
41431da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
41441da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
41451da177e4SLinus Torvalds 			break;
41461da177e4SLinus Torvalds 
41471da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
41481da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
41491da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
41501da177e4SLinus Torvalds 			break;
41511da177e4SLinus Torvalds 
415226afbd82SLuiz Augusto von Dentz 		case HCI_ISODATA_PKT:
415326afbd82SLuiz Augusto von Dentz 			BT_DBG("%s ISO data packet", hdev->name);
415426afbd82SLuiz Augusto von Dentz 			hci_isodata_packet(hdev, skb);
415526afbd82SLuiz Augusto von Dentz 			break;
415626afbd82SLuiz Augusto von Dentz 
41571da177e4SLinus Torvalds 		default:
41581da177e4SLinus Torvalds 			kfree_skb(skb);
41591da177e4SLinus Torvalds 			break;
41601da177e4SLinus Torvalds 		}
41611da177e4SLinus Torvalds 	}
41621da177e4SLinus Torvalds }
41631da177e4SLinus Torvalds 
41640ce1229cSLuiz Augusto von Dentz static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
41650ce1229cSLuiz Augusto von Dentz {
41660ce1229cSLuiz Augusto von Dentz 	int err;
41670ce1229cSLuiz Augusto von Dentz 
41680ce1229cSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "skb %p", skb);
41690ce1229cSLuiz Augusto von Dentz 
41700ce1229cSLuiz Augusto von Dentz 	kfree_skb(hdev->sent_cmd);
41710ce1229cSLuiz Augusto von Dentz 
41720ce1229cSLuiz Augusto von Dentz 	hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
41730ce1229cSLuiz Augusto von Dentz 	if (!hdev->sent_cmd) {
41740ce1229cSLuiz Augusto von Dentz 		skb_queue_head(&hdev->cmd_q, skb);
41750ce1229cSLuiz Augusto von Dentz 		queue_work(hdev->workqueue, &hdev->cmd_work);
41760ce1229cSLuiz Augusto von Dentz 		return;
41770ce1229cSLuiz Augusto von Dentz 	}
41780ce1229cSLuiz Augusto von Dentz 
41790ce1229cSLuiz Augusto von Dentz 	err = hci_send_frame(hdev, skb);
41800ce1229cSLuiz Augusto von Dentz 	if (err < 0) {
41810ce1229cSLuiz Augusto von Dentz 		hci_cmd_sync_cancel_sync(hdev, err);
41820ce1229cSLuiz Augusto von Dentz 		return;
41830ce1229cSLuiz Augusto von Dentz 	}
41840ce1229cSLuiz Augusto von Dentz 
41852af7aa66SLuiz Augusto von Dentz 	if (hci_req_status_pend(hdev) &&
41862af7aa66SLuiz Augusto von Dentz 	    !hci_dev_test_and_set_flag(hdev, HCI_CMD_PENDING)) {
41872af7aa66SLuiz Augusto von Dentz 		kfree_skb(hdev->req_skb);
41882af7aa66SLuiz Augusto von Dentz 		hdev->req_skb = skb_clone(skb, GFP_KERNEL);
41892af7aa66SLuiz Augusto von Dentz 	}
41900ce1229cSLuiz Augusto von Dentz 
41910ce1229cSLuiz Augusto von Dentz 	atomic_dec(&hdev->cmd_cnt);
41920ce1229cSLuiz Augusto von Dentz }
41930ce1229cSLuiz Augusto von Dentz 
4194c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
41951da177e4SLinus Torvalds {
4196c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
41971da177e4SLinus Torvalds 	struct sk_buff *skb;
41981da177e4SLinus Torvalds 
41992104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
42002104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
42011da177e4SLinus Torvalds 
42021da177e4SLinus Torvalds 	/* Send queued commands */
42035a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
42045a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
42055a08ecceSAndrei Emeltchenko 		if (!skb)
42065a08ecceSAndrei Emeltchenko 			return;
42075a08ecceSAndrei Emeltchenko 
42080ce1229cSLuiz Augusto von Dentz 		hci_send_cmd_sync(hdev, skb);
42092250abadSBenjamin Berg 
4210deee93d1STetsuo Handa 		rcu_read_lock();
4211877afadaSSchspa Shi 		if (test_bit(HCI_RESET, &hdev->flags) ||
4212877afadaSSchspa Shi 		    hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
421365cc2b49SMarcel Holtmann 			cancel_delayed_work(&hdev->cmd_timer);
42147bdb8a5cSSzymon Janc 		else
4215deee93d1STetsuo Handa 			queue_delayed_work(hdev->workqueue, &hdev->cmd_timer,
421665cc2b49SMarcel Holtmann 					   HCI_CMD_TIMEOUT);
4217deee93d1STetsuo Handa 		rcu_read_unlock();
42181da177e4SLinus Torvalds 	}
42191da177e4SLinus Torvalds }
4220