xref: /openbmc/linux/net/bluetooth/hci_core.c (revision d0b13706)
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>
327a0e5b15SMatthias Kaehlcke #include <linux/property.h>
339952d90eSAbhishek Pandit-Subedi #include <linux/suspend.h>
349952d90eSAbhishek Pandit-Subedi #include <linux/wait.h>
3547219839SMarcel Holtmann #include <asm/unaligned.h>
361da177e4SLinus Torvalds 
371da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
381da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
394bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h>
40af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h>
411da177e4SLinus Torvalds 
420857dd3bSJohan Hedberg #include "hci_request.h"
4360c5f5fbSMarcel Holtmann #include "hci_debugfs.h"
44970c4e46SJohan Hedberg #include "smp.h"
456d5d2ee6SHeiner Kallweit #include "leds.h"
46145373cbSMiao-chen Chou #include "msft.h"
47f67743f9SMarcel Holtmann #include "aosp.h"
488961987fSKiran K #include "hci_codec.h"
49970c4e46SJohan Hedberg 
50b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
51c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
523eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
531da177e4SLinus Torvalds 
541da177e4SLinus Torvalds /* HCI device list */
551da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
561da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds /* HCI callback list */
591da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
60fba7ecf0SJohan Hedberg DEFINE_MUTEX(hci_cb_list_lock);
611da177e4SLinus Torvalds 
623df92b31SSasha Levin /* HCI ID Numbering */
633df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
643df92b31SSasha Levin 
65a1d01db1SJohan Hedberg static int hci_scan_req(struct hci_request *req, unsigned long opt)
661da177e4SLinus Torvalds {
671da177e4SLinus Torvalds 	__u8 scan = opt;
681da177e4SLinus Torvalds 
6942c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
701da177e4SLinus Torvalds 
711da177e4SLinus Torvalds 	/* Inquiry and Page scans */
7242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
73a1d01db1SJohan Hedberg 	return 0;
741da177e4SLinus Torvalds }
751da177e4SLinus Torvalds 
76a1d01db1SJohan Hedberg static int hci_auth_req(struct hci_request *req, unsigned long opt)
771da177e4SLinus Torvalds {
781da177e4SLinus Torvalds 	__u8 auth = opt;
791da177e4SLinus Torvalds 
8042c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds 	/* Authentication */
8342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
84a1d01db1SJohan Hedberg 	return 0;
851da177e4SLinus Torvalds }
861da177e4SLinus Torvalds 
87a1d01db1SJohan Hedberg static int hci_encrypt_req(struct hci_request *req, unsigned long opt)
881da177e4SLinus Torvalds {
891da177e4SLinus Torvalds 	__u8 encrypt = opt;
901da177e4SLinus Torvalds 
9142c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
921da177e4SLinus Torvalds 
93e4e8e37cSMarcel Holtmann 	/* Encryption */
9442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
95a1d01db1SJohan Hedberg 	return 0;
961da177e4SLinus Torvalds }
971da177e4SLinus Torvalds 
98a1d01db1SJohan Hedberg static int hci_linkpol_req(struct hci_request *req, unsigned long opt)
99e4e8e37cSMarcel Holtmann {
100e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
101e4e8e37cSMarcel Holtmann 
10242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
103e4e8e37cSMarcel Holtmann 
104e4e8e37cSMarcel Holtmann 	/* Default link policy */
10542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
106a1d01db1SJohan Hedberg 	return 0;
107e4e8e37cSMarcel Holtmann }
108e4e8e37cSMarcel Holtmann 
1091da177e4SLinus Torvalds /* Get HCI device by index.
1101da177e4SLinus Torvalds  * Device is held on return. */
1111da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
1121da177e4SLinus Torvalds {
1138035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
1141da177e4SLinus Torvalds 
1151da177e4SLinus Torvalds 	BT_DBG("%d", index);
1161da177e4SLinus Torvalds 
1171da177e4SLinus Torvalds 	if (index < 0)
1181da177e4SLinus Torvalds 		return NULL;
1191da177e4SLinus Torvalds 
1201da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
1218035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
1221da177e4SLinus Torvalds 		if (d->id == index) {
1231da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
1241da177e4SLinus Torvalds 			break;
1251da177e4SLinus Torvalds 		}
1261da177e4SLinus Torvalds 	}
1271da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
1281da177e4SLinus Torvalds 	return hdev;
1291da177e4SLinus Torvalds }
1301da177e4SLinus Torvalds 
1311da177e4SLinus Torvalds /* ---- Inquiry support ---- */
132ff9ef578SJohan Hedberg 
13330dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
13430dc78e1SJohan Hedberg {
13530dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
13630dc78e1SJohan Hedberg 
1376fbe195dSAndre Guedes 	switch (discov->state) {
138343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1396fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
14030dc78e1SJohan Hedberg 		return true;
14130dc78e1SJohan Hedberg 
1426fbe195dSAndre Guedes 	default:
14330dc78e1SJohan Hedberg 		return false;
14430dc78e1SJohan Hedberg 	}
1456fbe195dSAndre Guedes }
14630dc78e1SJohan Hedberg 
147ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
148ff9ef578SJohan Hedberg {
149bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
150bb3e0a33SJohan Hedberg 
151ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
152ff9ef578SJohan Hedberg 
153bb3e0a33SJohan Hedberg 	if (old_state == state)
154ff9ef578SJohan Hedberg 		return;
155ff9ef578SJohan Hedberg 
156bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
157bb3e0a33SJohan Hedberg 
158ff9ef578SJohan Hedberg 	switch (state) {
159ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
1605bee2fd6SLuiz Augusto von Dentz 		hci_update_passive_scan(hdev);
161c54c3860SAndre Guedes 
162bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
163ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
164ff9ef578SJohan Hedberg 		break;
165ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
166ff9ef578SJohan Hedberg 		break;
167343f935bSAndre Guedes 	case DISCOVERY_FINDING:
168ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
169ff9ef578SJohan Hedberg 		break;
17030dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
17130dc78e1SJohan Hedberg 		break;
172ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
173ff9ef578SJohan Hedberg 		break;
174ff9ef578SJohan Hedberg 	}
175ff9ef578SJohan Hedberg }
176ff9ef578SJohan Hedberg 
1771f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
1781da177e4SLinus Torvalds {
17930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
180b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
1811da177e4SLinus Torvalds 
182561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
183561aafbcSJohan Hedberg 		list_del(&p->all);
184b57c1a56SJohan Hedberg 		kfree(p);
1851da177e4SLinus Torvalds 	}
186561aafbcSJohan Hedberg 
187561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
188561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
1891da177e4SLinus Torvalds }
1901da177e4SLinus Torvalds 
191a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
192a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
1931da177e4SLinus Torvalds {
19430883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1951da177e4SLinus Torvalds 	struct inquiry_entry *e;
1961da177e4SLinus Torvalds 
1976ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1981da177e4SLinus Torvalds 
199561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
2001da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
2011da177e4SLinus Torvalds 			return e;
2021da177e4SLinus Torvalds 	}
2031da177e4SLinus Torvalds 
204b57c1a56SJohan Hedberg 	return NULL;
205b57c1a56SJohan Hedberg }
206b57c1a56SJohan Hedberg 
207561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
208561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
209561aafbcSJohan Hedberg {
21030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
211561aafbcSJohan Hedberg 	struct inquiry_entry *e;
212561aafbcSJohan Hedberg 
2136ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
214561aafbcSJohan Hedberg 
215561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
216561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
217561aafbcSJohan Hedberg 			return e;
218561aafbcSJohan Hedberg 	}
219561aafbcSJohan Hedberg 
220561aafbcSJohan Hedberg 	return NULL;
221561aafbcSJohan Hedberg }
222561aafbcSJohan Hedberg 
22330dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
22430dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
22530dc78e1SJohan Hedberg 						       int state)
22630dc78e1SJohan Hedberg {
22730dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
22830dc78e1SJohan Hedberg 	struct inquiry_entry *e;
22930dc78e1SJohan Hedberg 
2306ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
23130dc78e1SJohan Hedberg 
23230dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
23330dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
23430dc78e1SJohan Hedberg 			return e;
23530dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
23630dc78e1SJohan Hedberg 			return e;
23730dc78e1SJohan Hedberg 	}
23830dc78e1SJohan Hedberg 
23930dc78e1SJohan Hedberg 	return NULL;
24030dc78e1SJohan Hedberg }
24130dc78e1SJohan Hedberg 
242a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
243a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
244a3d4e20aSJohan Hedberg {
245a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
246a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
247a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
248a3d4e20aSJohan Hedberg 
249a3d4e20aSJohan Hedberg 	list_del(&ie->list);
250a3d4e20aSJohan Hedberg 
251a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
252a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
253a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
254a3d4e20aSJohan Hedberg 			break;
255a3d4e20aSJohan Hedberg 		pos = &p->list;
256a3d4e20aSJohan Hedberg 	}
257a3d4e20aSJohan Hedberg 
258a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
259a3d4e20aSJohan Hedberg }
260a3d4e20aSJohan Hedberg 
261af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
262af58925cSMarcel Holtmann 			     bool name_known)
2631da177e4SLinus Torvalds {
26430883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
26570f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
266af58925cSMarcel Holtmann 	u32 flags = 0;
2671da177e4SLinus Torvalds 
2686ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
2691da177e4SLinus Torvalds 
2706928a924SJohan Hedberg 	hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
2712b2fec4dSSzymon Janc 
272af58925cSMarcel Holtmann 	if (!data->ssp_mode)
273af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
274388fc8faSJohan Hedberg 
27570f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
276a3d4e20aSJohan Hedberg 	if (ie) {
277af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
278af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
279388fc8faSJohan Hedberg 
280a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
281a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
282a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
283a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
284a3d4e20aSJohan Hedberg 		}
285a3d4e20aSJohan Hedberg 
286561aafbcSJohan Hedberg 		goto update;
287a3d4e20aSJohan Hedberg 	}
288561aafbcSJohan Hedberg 
2891da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
29027f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
291af58925cSMarcel Holtmann 	if (!ie) {
292af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
293af58925cSMarcel Holtmann 		goto done;
294af58925cSMarcel Holtmann 	}
29570f23020SAndrei Emeltchenko 
296561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
297561aafbcSJohan Hedberg 
298561aafbcSJohan Hedberg 	if (name_known) {
299561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
300561aafbcSJohan Hedberg 	} else {
301561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
302561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
303561aafbcSJohan Hedberg 	}
304561aafbcSJohan Hedberg 
305561aafbcSJohan Hedberg update:
306561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
307561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
308561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
309561aafbcSJohan Hedberg 		list_del(&ie->list);
3101da177e4SLinus Torvalds 	}
3111da177e4SLinus Torvalds 
31270f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
31370f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
3141da177e4SLinus Torvalds 	cache->timestamp = jiffies;
3153175405bSJohan Hedberg 
3163175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
317af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
3183175405bSJohan Hedberg 
319af58925cSMarcel Holtmann done:
320af58925cSMarcel Holtmann 	return flags;
3211da177e4SLinus Torvalds }
3221da177e4SLinus Torvalds 
3231da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
3241da177e4SLinus Torvalds {
32530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
3261da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
3271da177e4SLinus Torvalds 	struct inquiry_entry *e;
3281da177e4SLinus Torvalds 	int copied = 0;
3291da177e4SLinus Torvalds 
330561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
3311da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
332b57c1a56SJohan Hedberg 
333b57c1a56SJohan Hedberg 		if (copied >= num)
334b57c1a56SJohan Hedberg 			break;
335b57c1a56SJohan Hedberg 
3361da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
3371da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
3381da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
3391da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
3401da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
3411da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
342b57c1a56SJohan Hedberg 
3431da177e4SLinus Torvalds 		info++;
344b57c1a56SJohan Hedberg 		copied++;
3451da177e4SLinus Torvalds 	}
3461da177e4SLinus Torvalds 
3471da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
3481da177e4SLinus Torvalds 	return copied;
3491da177e4SLinus Torvalds }
3501da177e4SLinus Torvalds 
351a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt)
3521da177e4SLinus Torvalds {
3531da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
35442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
3551da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
3561da177e4SLinus Torvalds 
3571da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
3581da177e4SLinus Torvalds 
3591da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
360a1d01db1SJohan Hedberg 		return 0;
3611da177e4SLinus Torvalds 
3621da177e4SLinus Torvalds 	/* Start Inquiry */
3631da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
3641da177e4SLinus Torvalds 	cp.length  = ir->length;
3651da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
36642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
367a1d01db1SJohan Hedberg 
368a1d01db1SJohan Hedberg 	return 0;
3691da177e4SLinus Torvalds }
3701da177e4SLinus Torvalds 
3711da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
3721da177e4SLinus Torvalds {
3731da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
3741da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
3751da177e4SLinus Torvalds 	struct hci_dev *hdev;
3761da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
3771da177e4SLinus Torvalds 	long timeo;
3781da177e4SLinus Torvalds 	__u8 *buf;
3791da177e4SLinus Torvalds 
3801da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
3811da177e4SLinus Torvalds 		return -EFAULT;
3821da177e4SLinus Torvalds 
3835a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
3845a08ecceSAndrei Emeltchenko 	if (!hdev)
3851da177e4SLinus Torvalds 		return -ENODEV;
3861da177e4SLinus Torvalds 
387d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
3880736cfa8SMarcel Holtmann 		err = -EBUSY;
3890736cfa8SMarcel Holtmann 		goto done;
3900736cfa8SMarcel Holtmann 	}
3910736cfa8SMarcel Holtmann 
392d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
393fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
394fee746b0SMarcel Holtmann 		goto done;
395fee746b0SMarcel Holtmann 	}
396fee746b0SMarcel Holtmann 
397ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY) {
3985b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
3995b69bef5SMarcel Holtmann 		goto done;
4005b69bef5SMarcel Holtmann 	}
4015b69bef5SMarcel Holtmann 
402d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
40356f87901SJohan Hedberg 		err = -EOPNOTSUPP;
40456f87901SJohan Hedberg 		goto done;
40556f87901SJohan Hedberg 	}
40656f87901SJohan Hedberg 
407f41a4b2bSPavel Skripkin 	/* Restrict maximum inquiry length to 60 seconds */
408f41a4b2bSPavel Skripkin 	if (ir.length > 60) {
409f41a4b2bSPavel Skripkin 		err = -EINVAL;
410f41a4b2bSPavel Skripkin 		goto done;
411f41a4b2bSPavel Skripkin 	}
412f41a4b2bSPavel Skripkin 
41309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4141da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
415a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
4161f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
4171da177e4SLinus Torvalds 		do_inquiry = 1;
4181da177e4SLinus Torvalds 	}
41909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4201da177e4SLinus Torvalds 
42104837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
42270f23020SAndrei Emeltchenko 
42370f23020SAndrei Emeltchenko 	if (do_inquiry) {
42401178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
4254ebeee2dSJohan Hedberg 				   timeo, NULL);
42670f23020SAndrei Emeltchenko 		if (err < 0)
4271da177e4SLinus Torvalds 			goto done;
4283e13fa1eSAndre Guedes 
4293e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
4303e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
4313e13fa1eSAndre Guedes 		 */
43274316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
43328a758c8SPan Bian 				TASK_INTERRUPTIBLE)) {
43428a758c8SPan Bian 			err = -EINTR;
43528a758c8SPan Bian 			goto done;
43628a758c8SPan Bian 		}
43770f23020SAndrei Emeltchenko 	}
4381da177e4SLinus Torvalds 
4398fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
4408fc9ced3SGustavo Padovan 	 * 255 entries
4418fc9ced3SGustavo Padovan 	 */
4421da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
4431da177e4SLinus Torvalds 
4441da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
4451da177e4SLinus Torvalds 	 * copy it to the user space.
4461da177e4SLinus Torvalds 	 */
4476da2ec56SKees Cook 	buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL);
44870f23020SAndrei Emeltchenko 	if (!buf) {
4491da177e4SLinus Torvalds 		err = -ENOMEM;
4501da177e4SLinus Torvalds 		goto done;
4511da177e4SLinus Torvalds 	}
4521da177e4SLinus Torvalds 
45309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4541da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
45509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4561da177e4SLinus Torvalds 
4571da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
4581da177e4SLinus Torvalds 
4591da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
4601da177e4SLinus Torvalds 		ptr += sizeof(ir);
4611da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
4621da177e4SLinus Torvalds 				 ir.num_rsp))
4631da177e4SLinus Torvalds 			err = -EFAULT;
4641da177e4SLinus Torvalds 	} else
4651da177e4SLinus Torvalds 		err = -EFAULT;
4661da177e4SLinus Torvalds 
4671da177e4SLinus Torvalds 	kfree(buf);
4681da177e4SLinus Torvalds 
4691da177e4SLinus Torvalds done:
4701da177e4SLinus Torvalds 	hci_dev_put(hdev);
4711da177e4SLinus Torvalds 	return err;
4721da177e4SLinus Torvalds }
4731da177e4SLinus Torvalds 
474cf75ad8bSLuiz Augusto von Dentz static int hci_dev_do_open(struct hci_dev *hdev)
475cf75ad8bSLuiz Augusto von Dentz {
476cf75ad8bSLuiz Augusto von Dentz 	int ret = 0;
477cf75ad8bSLuiz Augusto von Dentz 
478cf75ad8bSLuiz Augusto von Dentz 	BT_DBG("%s %p", hdev->name, hdev);
479cf75ad8bSLuiz Augusto von Dentz 
480cf75ad8bSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
481cf75ad8bSLuiz Augusto von Dentz 
482cf75ad8bSLuiz Augusto von Dentz 	ret = hci_dev_open_sync(hdev);
483cf75ad8bSLuiz Augusto von Dentz 
484b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
4851da177e4SLinus Torvalds 	return ret;
4861da177e4SLinus Torvalds }
4871da177e4SLinus Torvalds 
488cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
489cbed0ca1SJohan Hedberg 
490cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
491cbed0ca1SJohan Hedberg {
492cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
493cbed0ca1SJohan Hedberg 	int err;
494cbed0ca1SJohan Hedberg 
495cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
496cbed0ca1SJohan Hedberg 	if (!hdev)
497cbed0ca1SJohan Hedberg 		return -ENODEV;
498cbed0ca1SJohan Hedberg 
4994a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
500fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
501fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
502fee746b0SMarcel Holtmann 	 * possible.
503fee746b0SMarcel Holtmann 	 *
504fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
505fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
506fee746b0SMarcel Holtmann 	 * open the device.
507fee746b0SMarcel Holtmann 	 */
508d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
509d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
510fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
511fee746b0SMarcel Holtmann 		goto done;
512fee746b0SMarcel Holtmann 	}
513fee746b0SMarcel Holtmann 
514e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
515e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
516e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
517e1d08f40SJohan Hedberg 	 * completed.
518e1d08f40SJohan Hedberg 	 */
519a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
520e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
521e1d08f40SJohan Hedberg 
522a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
523a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
524a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
525a5c8f270SMarcel Holtmann 	 */
526e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
527e1d08f40SJohan Hedberg 
52812aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
529b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
53012aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
53112aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
53212aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
53312aa4f0aSMarcel Holtmann 	 */
534d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
535d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_MGMT))
536a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BONDABLE);
53712aa4f0aSMarcel Holtmann 
538cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
539cbed0ca1SJohan Hedberg 
540fee746b0SMarcel Holtmann done:
541cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
542cbed0ca1SJohan Hedberg 	return err;
543cbed0ca1SJohan Hedberg }
544cbed0ca1SJohan Hedberg 
545cf75ad8bSLuiz Augusto von Dentz int hci_dev_do_close(struct hci_dev *hdev)
546cf75ad8bSLuiz Augusto von Dentz {
547cf75ad8bSLuiz Augusto von Dentz 	int err;
548cf75ad8bSLuiz Augusto von Dentz 
549cf75ad8bSLuiz Augusto von Dentz 	BT_DBG("%s %p", hdev->name, hdev);
550cf75ad8bSLuiz Augusto von Dentz 
551cf75ad8bSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
552cf75ad8bSLuiz Augusto von Dentz 
553cf75ad8bSLuiz Augusto von Dentz 	err = hci_dev_close_sync(hdev);
554cf75ad8bSLuiz Augusto von Dentz 
555b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
5561da177e4SLinus Torvalds 
55761969ef8SKangmin Park 	return err;
5581da177e4SLinus Torvalds }
5591da177e4SLinus Torvalds 
5601da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
5611da177e4SLinus Torvalds {
5621da177e4SLinus Torvalds 	struct hci_dev *hdev;
5631da177e4SLinus Torvalds 	int err;
5641da177e4SLinus Torvalds 
56570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
56670f23020SAndrei Emeltchenko 	if (!hdev)
5671da177e4SLinus Torvalds 		return -ENODEV;
5688ee56540SMarcel Holtmann 
569d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
5700736cfa8SMarcel Holtmann 		err = -EBUSY;
5710736cfa8SMarcel Holtmann 		goto done;
5720736cfa8SMarcel Holtmann 	}
5730736cfa8SMarcel Holtmann 
574a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
5758ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
5768ee56540SMarcel Holtmann 
5771da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
5788ee56540SMarcel Holtmann 
5790736cfa8SMarcel Holtmann done:
5801da177e4SLinus Torvalds 	hci_dev_put(hdev);
5811da177e4SLinus Torvalds 	return err;
5821da177e4SLinus Torvalds }
5831da177e4SLinus Torvalds 
5845c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev)
5851da177e4SLinus Torvalds {
5865c912495SMarcel Holtmann 	int ret;
5871da177e4SLinus Torvalds 
5885c912495SMarcel Holtmann 	BT_DBG("%s %p", hdev->name, hdev);
5891da177e4SLinus Torvalds 
590b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
5911da177e4SLinus Torvalds 
5921da177e4SLinus Torvalds 	/* Drop queues */
5931da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
5941da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
5951da177e4SLinus Torvalds 
59676727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
59776727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
59876727c02SJohan Hedberg 	 */
59976727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
60076727c02SJohan Hedberg 
60109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6021f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
6031da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
60409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6051da177e4SLinus Torvalds 
6061da177e4SLinus Torvalds 	if (hdev->flush)
6071da177e4SLinus Torvalds 		hdev->flush(hdev);
6081da177e4SLinus Torvalds 
6091da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
6106ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
6111da177e4SLinus Torvalds 
612*d0b13706SLuiz Augusto von Dentz 	ret = hci_reset_sync(hdev);
6131da177e4SLinus Torvalds 
614b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
6151da177e4SLinus Torvalds 	return ret;
6161da177e4SLinus Torvalds }
6171da177e4SLinus Torvalds 
6185c912495SMarcel Holtmann int hci_dev_reset(__u16 dev)
6195c912495SMarcel Holtmann {
6205c912495SMarcel Holtmann 	struct hci_dev *hdev;
6215c912495SMarcel Holtmann 	int err;
6225c912495SMarcel Holtmann 
6235c912495SMarcel Holtmann 	hdev = hci_dev_get(dev);
6245c912495SMarcel Holtmann 	if (!hdev)
6255c912495SMarcel Holtmann 		return -ENODEV;
6265c912495SMarcel Holtmann 
6275c912495SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
6285c912495SMarcel Holtmann 		err = -ENETDOWN;
6295c912495SMarcel Holtmann 		goto done;
6305c912495SMarcel Holtmann 	}
6315c912495SMarcel Holtmann 
632d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6335c912495SMarcel Holtmann 		err = -EBUSY;
6345c912495SMarcel Holtmann 		goto done;
6355c912495SMarcel Holtmann 	}
6365c912495SMarcel Holtmann 
637d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
6385c912495SMarcel Holtmann 		err = -EOPNOTSUPP;
6395c912495SMarcel Holtmann 		goto done;
6405c912495SMarcel Holtmann 	}
6415c912495SMarcel Holtmann 
6425c912495SMarcel Holtmann 	err = hci_dev_do_reset(hdev);
6435c912495SMarcel Holtmann 
6445c912495SMarcel Holtmann done:
6455c912495SMarcel Holtmann 	hci_dev_put(hdev);
6465c912495SMarcel Holtmann 	return err;
6475c912495SMarcel Holtmann }
6485c912495SMarcel Holtmann 
6491da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
6501da177e4SLinus Torvalds {
6511da177e4SLinus Torvalds 	struct hci_dev *hdev;
6521da177e4SLinus Torvalds 	int ret = 0;
6531da177e4SLinus Torvalds 
65470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
65570f23020SAndrei Emeltchenko 	if (!hdev)
6561da177e4SLinus Torvalds 		return -ENODEV;
6571da177e4SLinus Torvalds 
658d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6590736cfa8SMarcel Holtmann 		ret = -EBUSY;
6600736cfa8SMarcel Holtmann 		goto done;
6610736cfa8SMarcel Holtmann 	}
6620736cfa8SMarcel Holtmann 
663d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
664fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
665fee746b0SMarcel Holtmann 		goto done;
666fee746b0SMarcel Holtmann 	}
667fee746b0SMarcel Holtmann 
6681da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
6691da177e4SLinus Torvalds 
6700736cfa8SMarcel Holtmann done:
6711da177e4SLinus Torvalds 	hci_dev_put(hdev);
6721da177e4SLinus Torvalds 	return ret;
6731da177e4SLinus Torvalds }
6741da177e4SLinus Torvalds 
6755bee2fd6SLuiz Augusto von Dentz static void hci_update_passive_scan_state(struct hci_dev *hdev, u8 scan)
676123abc08SJohan Hedberg {
677bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
678123abc08SJohan Hedberg 
679123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
680123abc08SJohan Hedberg 
681123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
682238be788SMarcel Holtmann 		conn_changed = !hci_dev_test_and_set_flag(hdev,
683238be788SMarcel Holtmann 							  HCI_CONNECTABLE);
684123abc08SJohan Hedberg 	else
685a69d8927SMarcel Holtmann 		conn_changed = hci_dev_test_and_clear_flag(hdev,
686a69d8927SMarcel Holtmann 							   HCI_CONNECTABLE);
687123abc08SJohan Hedberg 
688bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
689238be788SMarcel Holtmann 		discov_changed = !hci_dev_test_and_set_flag(hdev,
690238be788SMarcel Holtmann 							    HCI_DISCOVERABLE);
691bc6d2d04SJohan Hedberg 	} else {
692a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
693a69d8927SMarcel Holtmann 		discov_changed = hci_dev_test_and_clear_flag(hdev,
694a69d8927SMarcel Holtmann 							     HCI_DISCOVERABLE);
695bc6d2d04SJohan Hedberg 	}
696bc6d2d04SJohan Hedberg 
697d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
698123abc08SJohan Hedberg 		return;
699123abc08SJohan Hedberg 
700bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
701bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
702a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
703bc6d2d04SJohan Hedberg 
704d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
705cab054abSJohan Hedberg 			hci_req_update_adv_data(hdev, hdev->cur_adv_instance);
706bc6d2d04SJohan Hedberg 
707123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
708123abc08SJohan Hedberg 	}
709bc6d2d04SJohan Hedberg }
710123abc08SJohan Hedberg 
7111da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
7121da177e4SLinus Torvalds {
7131da177e4SLinus Torvalds 	struct hci_dev *hdev;
7141da177e4SLinus Torvalds 	struct hci_dev_req dr;
7151da177e4SLinus Torvalds 	int err = 0;
7161da177e4SLinus Torvalds 
7171da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
7181da177e4SLinus Torvalds 		return -EFAULT;
7191da177e4SLinus Torvalds 
72070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
72170f23020SAndrei Emeltchenko 	if (!hdev)
7221da177e4SLinus Torvalds 		return -ENODEV;
7231da177e4SLinus Torvalds 
724d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
7250736cfa8SMarcel Holtmann 		err = -EBUSY;
7260736cfa8SMarcel Holtmann 		goto done;
7270736cfa8SMarcel Holtmann 	}
7280736cfa8SMarcel Holtmann 
729d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
730fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
731fee746b0SMarcel Holtmann 		goto done;
732fee746b0SMarcel Holtmann 	}
733fee746b0SMarcel Holtmann 
734ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY) {
7355b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
7365b69bef5SMarcel Holtmann 		goto done;
7375b69bef5SMarcel Holtmann 	}
7385b69bef5SMarcel Holtmann 
739d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
74056f87901SJohan Hedberg 		err = -EOPNOTSUPP;
74156f87901SJohan Hedberg 		goto done;
74256f87901SJohan Hedberg 	}
74356f87901SJohan Hedberg 
7441da177e4SLinus Torvalds 	switch (cmd) {
7451da177e4SLinus Torvalds 	case HCISETAUTH:
74601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
7474ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
7481da177e4SLinus Torvalds 		break;
7491da177e4SLinus Torvalds 
7501da177e4SLinus Torvalds 	case HCISETENCRYPT:
7511da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
7521da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
7531da177e4SLinus Torvalds 			break;
7541da177e4SLinus Torvalds 		}
7551da177e4SLinus Torvalds 
7561da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
7571da177e4SLinus Torvalds 			/* Auth must be enabled first */
75801178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
7594ebeee2dSJohan Hedberg 					   HCI_INIT_TIMEOUT, NULL);
7601da177e4SLinus Torvalds 			if (err)
7611da177e4SLinus Torvalds 				break;
7621da177e4SLinus Torvalds 		}
7631da177e4SLinus Torvalds 
76401178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
7654ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
7661da177e4SLinus Torvalds 		break;
7671da177e4SLinus Torvalds 
7681da177e4SLinus Torvalds 	case HCISETSCAN:
76901178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
7704ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
77191a668b0SJohan Hedberg 
772bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
773bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
77491a668b0SJohan Hedberg 		 */
775123abc08SJohan Hedberg 		if (!err)
7765bee2fd6SLuiz Augusto von Dentz 			hci_update_passive_scan_state(hdev, dr.dev_opt);
7771da177e4SLinus Torvalds 		break;
7781da177e4SLinus Torvalds 
7791da177e4SLinus Torvalds 	case HCISETLINKPOL:
78001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
7814ebeee2dSJohan Hedberg 				   HCI_INIT_TIMEOUT, NULL);
7821da177e4SLinus Torvalds 		break;
7831da177e4SLinus Torvalds 
7841da177e4SLinus Torvalds 	case HCISETLINKMODE:
785e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
786e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
787e4e8e37cSMarcel Holtmann 		break;
788e4e8e37cSMarcel Holtmann 
789e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
790b7c23df8SJaganath Kanakkassery 		if (hdev->pkt_type == (__u16) dr.dev_opt)
791b7c23df8SJaganath Kanakkassery 			break;
792b7c23df8SJaganath Kanakkassery 
793e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
794b7c23df8SJaganath Kanakkassery 		mgmt_phy_configuration_changed(hdev, NULL);
7951da177e4SLinus Torvalds 		break;
7961da177e4SLinus Torvalds 
7971da177e4SLinus Torvalds 	case HCISETACLMTU:
7981da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
7991da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
8001da177e4SLinus Torvalds 		break;
8011da177e4SLinus Torvalds 
8021da177e4SLinus Torvalds 	case HCISETSCOMTU:
8031da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
8041da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
8051da177e4SLinus Torvalds 		break;
8061da177e4SLinus Torvalds 
8071da177e4SLinus Torvalds 	default:
8081da177e4SLinus Torvalds 		err = -EINVAL;
8091da177e4SLinus Torvalds 		break;
8101da177e4SLinus Torvalds 	}
811e4e8e37cSMarcel Holtmann 
8120736cfa8SMarcel Holtmann done:
8131da177e4SLinus Torvalds 	hci_dev_put(hdev);
8141da177e4SLinus Torvalds 	return err;
8151da177e4SLinus Torvalds }
8161da177e4SLinus Torvalds 
8171da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
8181da177e4SLinus Torvalds {
8198035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
8201da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
8211da177e4SLinus Torvalds 	struct hci_dev_req *dr;
8221da177e4SLinus Torvalds 	int n = 0, size, err;
8231da177e4SLinus Torvalds 	__u16 dev_num;
8241da177e4SLinus Torvalds 
8251da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
8261da177e4SLinus Torvalds 		return -EFAULT;
8271da177e4SLinus Torvalds 
8281da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
8291da177e4SLinus Torvalds 		return -EINVAL;
8301da177e4SLinus Torvalds 
8311da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
8321da177e4SLinus Torvalds 
83370f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
83470f23020SAndrei Emeltchenko 	if (!dl)
8351da177e4SLinus Torvalds 		return -ENOMEM;
8361da177e4SLinus Torvalds 
8371da177e4SLinus Torvalds 	dr = dl->dev_req;
8381da177e4SLinus Torvalds 
839f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
8408035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
8412e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
842c542a06cSJohan Hedberg 
8432e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
8442e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
8452e84d8dbSMarcel Holtmann 		 * device is actually down.
8462e84d8dbSMarcel Holtmann 		 */
847d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
8482e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
849c542a06cSJohan Hedberg 
8501da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
8512e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
852c542a06cSJohan Hedberg 
8531da177e4SLinus Torvalds 		if (++n >= dev_num)
8541da177e4SLinus Torvalds 			break;
8551da177e4SLinus Torvalds 	}
856f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
8571da177e4SLinus Torvalds 
8581da177e4SLinus Torvalds 	dl->dev_num = n;
8591da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
8601da177e4SLinus Torvalds 
8611da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
8621da177e4SLinus Torvalds 	kfree(dl);
8631da177e4SLinus Torvalds 
8641da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
8651da177e4SLinus Torvalds }
8661da177e4SLinus Torvalds 
8671da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
8681da177e4SLinus Torvalds {
8691da177e4SLinus Torvalds 	struct hci_dev *hdev;
8701da177e4SLinus Torvalds 	struct hci_dev_info di;
8712e84d8dbSMarcel Holtmann 	unsigned long flags;
8721da177e4SLinus Torvalds 	int err = 0;
8731da177e4SLinus Torvalds 
8741da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
8751da177e4SLinus Torvalds 		return -EFAULT;
8761da177e4SLinus Torvalds 
87770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
87870f23020SAndrei Emeltchenko 	if (!hdev)
8791da177e4SLinus Torvalds 		return -ENODEV;
8801da177e4SLinus Torvalds 
8812e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
8822e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
8832e84d8dbSMarcel Holtmann 	 * device is actually down.
8842e84d8dbSMarcel Holtmann 	 */
885d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
8862e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
8872e84d8dbSMarcel Holtmann 	else
8882e84d8dbSMarcel Holtmann 		flags = hdev->flags;
889c542a06cSJohan Hedberg 
8901da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
8911da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
89260f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
8932e84d8dbSMarcel Holtmann 	di.flags    = flags;
8941da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
895572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
8961da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
8971da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
8981da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
8991da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
900572c7f84SJohan Hedberg 	} else {
901572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
902572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
903572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
904572c7f84SJohan Hedberg 		di.sco_pkts = 0;
905572c7f84SJohan Hedberg 	}
9061da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
9071da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
9081da177e4SLinus Torvalds 
9091da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
9101da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
9111da177e4SLinus Torvalds 
9121da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
9131da177e4SLinus Torvalds 		err = -EFAULT;
9141da177e4SLinus Torvalds 
9151da177e4SLinus Torvalds 	hci_dev_put(hdev);
9161da177e4SLinus Torvalds 
9171da177e4SLinus Torvalds 	return err;
9181da177e4SLinus Torvalds }
9191da177e4SLinus Torvalds 
9201da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
9211da177e4SLinus Torvalds 
922611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
923611b30f7SMarcel Holtmann {
924611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
925611b30f7SMarcel Holtmann 
926611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
927611b30f7SMarcel Holtmann 
928d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
9290736cfa8SMarcel Holtmann 		return -EBUSY;
9300736cfa8SMarcel Holtmann 
9315e130367SJohan Hedberg 	if (blocked) {
932a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
933d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
934d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG))
935611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
9365e130367SJohan Hedberg 	} else {
937a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_RFKILLED);
9385e130367SJohan Hedberg 	}
939611b30f7SMarcel Holtmann 
940611b30f7SMarcel Holtmann 	return 0;
941611b30f7SMarcel Holtmann }
942611b30f7SMarcel Holtmann 
943611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
944611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
945611b30f7SMarcel Holtmann };
946611b30f7SMarcel Holtmann 
947ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
948ab81cbf9SJohan Hedberg {
949ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
95096570ffcSJohan Hedberg 	int err;
951ab81cbf9SJohan Hedberg 
952ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
953ab81cbf9SJohan Hedberg 
9542ff13894SJohan Hedberg 	if (test_bit(HCI_UP, &hdev->flags) &&
9552ff13894SJohan Hedberg 	    hci_dev_test_flag(hdev, HCI_MGMT) &&
9562ff13894SJohan Hedberg 	    hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
957d82142a8SWei-Ning Huang 		cancel_delayed_work(&hdev->power_off);
958cf75ad8bSLuiz Augusto von Dentz 		err = hci_powered_update_sync(hdev);
9592ff13894SJohan Hedberg 		mgmt_power_on(hdev, err);
9602ff13894SJohan Hedberg 		return;
9612ff13894SJohan Hedberg 	}
9622ff13894SJohan Hedberg 
963cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
96496570ffcSJohan Hedberg 	if (err < 0) {
9653ad67582SJaganath Kanakkassery 		hci_dev_lock(hdev);
96696570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
9673ad67582SJaganath Kanakkassery 		hci_dev_unlock(hdev);
968ab81cbf9SJohan Hedberg 		return;
96996570ffcSJohan Hedberg 	}
970ab81cbf9SJohan Hedberg 
971a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
972a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
973a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
974a5c8f270SMarcel Holtmann 	 */
975d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
976d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
977ca8bee5dSMarcel Holtmann 	    (hdev->dev_type == HCI_PRIMARY &&
978a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
979a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
980a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
981bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
982d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
98319202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
98419202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
985bf543036SJohan Hedberg 	}
986ab81cbf9SJohan Hedberg 
987a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
9884a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
9894a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
9904a964404SMarcel Holtmann 		 */
991d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
9924a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
9930602a8adSMarcel Holtmann 
9940602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
9950602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
9960602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
9970602a8adSMarcel Holtmann 		 *
9980602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
9990602a8adSMarcel Holtmann 		 * and no event will be send.
10000602a8adSMarcel Holtmann 		 */
1001744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1002a69d8927SMarcel Holtmann 	} else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
10035ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
10045ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
10055ea234d3SMarcel Holtmann 		 */
1006d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
10075ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
10085ea234d3SMarcel Holtmann 
1009d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
1010d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
1011d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
1012d603b76bSMarcel Holtmann 		 */
1013d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
1014ab81cbf9SJohan Hedberg 	}
1015ab81cbf9SJohan Hedberg }
1016ab81cbf9SJohan Hedberg 
1017ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1018ab81cbf9SJohan Hedberg {
10193243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
10203243553fSJohan Hedberg 					    power_off.work);
1021ab81cbf9SJohan Hedberg 
1022ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1023ab81cbf9SJohan Hedberg 
10248ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1025ab81cbf9SJohan Hedberg }
1026ab81cbf9SJohan Hedberg 
1027c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work)
1028c7741d16SMarcel Holtmann {
1029c7741d16SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
1030c7741d16SMarcel Holtmann 
1031c7741d16SMarcel Holtmann 	BT_DBG("%s", hdev->name);
1032c7741d16SMarcel Holtmann 
1033c7741d16SMarcel Holtmann 	if (hdev->hw_error)
1034c7741d16SMarcel Holtmann 		hdev->hw_error(hdev, hdev->hw_error_code);
1035c7741d16SMarcel Holtmann 	else
10362064ee33SMarcel Holtmann 		bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code);
1037c7741d16SMarcel Holtmann 
1038c7741d16SMarcel Holtmann 	if (hci_dev_do_close(hdev))
1039c7741d16SMarcel Holtmann 		return;
1040c7741d16SMarcel Holtmann 
1041c7741d16SMarcel Holtmann 	hci_dev_do_open(hdev);
1042c7741d16SMarcel Holtmann }
1043c7741d16SMarcel Holtmann 
104435f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
10452aeb9a1aSJohan Hedberg {
10464821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
10472aeb9a1aSJohan Hedberg 
10484821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
10494821002cSJohan Hedberg 		list_del(&uuid->list);
10502aeb9a1aSJohan Hedberg 		kfree(uuid);
10512aeb9a1aSJohan Hedberg 	}
10522aeb9a1aSJohan Hedberg }
10532aeb9a1aSJohan Hedberg 
105435f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
105555ed8ca1SJohan Hedberg {
105655ed8ca1SJohan Hedberg 	struct link_key *key;
105755ed8ca1SJohan Hedberg 
1058d7d41682SMadhuparna Bhowmik 	list_for_each_entry(key, &hdev->link_keys, list) {
10590378b597SJohan Hedberg 		list_del_rcu(&key->list);
10600378b597SJohan Hedberg 		kfree_rcu(key, rcu);
106155ed8ca1SJohan Hedberg 	}
106255ed8ca1SJohan Hedberg }
106355ed8ca1SJohan Hedberg 
106435f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
1065b899efafSVinicius Costa Gomes {
1066970d0f1bSJohan Hedberg 	struct smp_ltk *k;
1067b899efafSVinicius Costa Gomes 
1068d7d41682SMadhuparna Bhowmik 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1069970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
1070970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
1071b899efafSVinicius Costa Gomes 	}
1072b899efafSVinicius Costa Gomes }
1073b899efafSVinicius Costa Gomes 
1074970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
1075970c4e46SJohan Hedberg {
1076adae20cbSJohan Hedberg 	struct smp_irk *k;
1077970c4e46SJohan Hedberg 
1078d7d41682SMadhuparna Bhowmik 	list_for_each_entry(k, &hdev->identity_resolving_keys, list) {
1079adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
1080adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
1081970c4e46SJohan Hedberg 	}
1082970c4e46SJohan Hedberg }
1083970c4e46SJohan Hedberg 
1084600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev)
1085600a8749SAlain Michaud {
1086600a8749SAlain Michaud 	struct blocked_key *b;
1087600a8749SAlain Michaud 
1088d7d41682SMadhuparna Bhowmik 	list_for_each_entry(b, &hdev->blocked_keys, list) {
1089600a8749SAlain Michaud 		list_del_rcu(&b->list);
1090600a8749SAlain Michaud 		kfree_rcu(b, rcu);
1091600a8749SAlain Michaud 	}
1092600a8749SAlain Michaud }
1093600a8749SAlain Michaud 
1094600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16])
1095600a8749SAlain Michaud {
1096600a8749SAlain Michaud 	bool blocked = false;
1097600a8749SAlain Michaud 	struct blocked_key *b;
1098600a8749SAlain Michaud 
1099600a8749SAlain Michaud 	rcu_read_lock();
11000c2ac7d4SMadhuparna Bhowmik 	list_for_each_entry_rcu(b, &hdev->blocked_keys, list) {
1101600a8749SAlain Michaud 		if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) {
1102600a8749SAlain Michaud 			blocked = true;
1103600a8749SAlain Michaud 			break;
1104600a8749SAlain Michaud 		}
1105600a8749SAlain Michaud 	}
1106600a8749SAlain Michaud 
1107600a8749SAlain Michaud 	rcu_read_unlock();
1108600a8749SAlain Michaud 	return blocked;
1109600a8749SAlain Michaud }
1110600a8749SAlain Michaud 
111155ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
111255ed8ca1SJohan Hedberg {
111355ed8ca1SJohan Hedberg 	struct link_key *k;
111455ed8ca1SJohan Hedberg 
11150378b597SJohan Hedberg 	rcu_read_lock();
11160378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
11170378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
11180378b597SJohan Hedberg 			rcu_read_unlock();
1119600a8749SAlain Michaud 
1120600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev,
1121600a8749SAlain Michaud 					       HCI_BLOCKED_KEY_TYPE_LINKKEY,
1122600a8749SAlain Michaud 					       k->val)) {
1123600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
1124600a8749SAlain Michaud 							"Link key blocked for %pMR",
1125600a8749SAlain Michaud 							&k->bdaddr);
1126600a8749SAlain Michaud 				return NULL;
1127600a8749SAlain Michaud 			}
1128600a8749SAlain Michaud 
112955ed8ca1SJohan Hedberg 			return k;
11300378b597SJohan Hedberg 		}
11310378b597SJohan Hedberg 	}
11320378b597SJohan Hedberg 	rcu_read_unlock();
113355ed8ca1SJohan Hedberg 
113455ed8ca1SJohan Hedberg 	return NULL;
113555ed8ca1SJohan Hedberg }
113655ed8ca1SJohan Hedberg 
1137745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1138d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1139d25e28abSJohan Hedberg {
1140d25e28abSJohan Hedberg 	/* Legacy key */
1141d25e28abSJohan Hedberg 	if (key_type < 0x03)
1142745c0ce3SVishal Agarwal 		return true;
1143d25e28abSJohan Hedberg 
1144d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1145d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1146745c0ce3SVishal Agarwal 		return false;
1147d25e28abSJohan Hedberg 
1148d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1149d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1150745c0ce3SVishal Agarwal 		return false;
1151d25e28abSJohan Hedberg 
1152d25e28abSJohan Hedberg 	/* Security mode 3 case */
1153d25e28abSJohan Hedberg 	if (!conn)
1154745c0ce3SVishal Agarwal 		return true;
1155d25e28abSJohan Hedberg 
1156e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
1157e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
1158e3befab9SJohan Hedberg 		return true;
1159e3befab9SJohan Hedberg 
1160d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1161d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1162745c0ce3SVishal Agarwal 		return true;
1163d25e28abSJohan Hedberg 
1164d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1165d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1166745c0ce3SVishal Agarwal 		return true;
1167d25e28abSJohan Hedberg 
1168d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1169d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1170745c0ce3SVishal Agarwal 		return true;
1171d25e28abSJohan Hedberg 
1172d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1173d25e28abSJohan Hedberg 	 * persistently */
1174745c0ce3SVishal Agarwal 	return false;
1175d25e28abSJohan Hedberg }
1176d25e28abSJohan Hedberg 
1177e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
117898a0b845SJohan Hedberg {
1179e804d25dSJohan Hedberg 	if (type == SMP_LTK)
1180e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
118198a0b845SJohan Hedberg 
1182e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
118398a0b845SJohan Hedberg }
118498a0b845SJohan Hedberg 
1185f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
1186e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
118775d262c2SVinicius Costa Gomes {
1188c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
118975d262c2SVinicius Costa Gomes 
1190970d0f1bSJohan Hedberg 	rcu_read_lock();
1191970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
11925378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
11935378bc56SJohan Hedberg 			continue;
11945378bc56SJohan Hedberg 
1195923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
1196970d0f1bSJohan Hedberg 			rcu_read_unlock();
1197600a8749SAlain Michaud 
1198600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK,
1199600a8749SAlain Michaud 					       k->val)) {
1200600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
1201600a8749SAlain Michaud 							"LTK blocked for %pMR",
1202600a8749SAlain Michaud 							&k->bdaddr);
1203600a8749SAlain Michaud 				return NULL;
1204600a8749SAlain Michaud 			}
1205600a8749SAlain Michaud 
120675d262c2SVinicius Costa Gomes 			return k;
1207970d0f1bSJohan Hedberg 		}
1208970d0f1bSJohan Hedberg 	}
1209970d0f1bSJohan Hedberg 	rcu_read_unlock();
121075d262c2SVinicius Costa Gomes 
121175d262c2SVinicius Costa Gomes 	return NULL;
121275d262c2SVinicius Costa Gomes }
121375d262c2SVinicius Costa Gomes 
1214970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
1215970c4e46SJohan Hedberg {
1216600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
1217970c4e46SJohan Hedberg 	struct smp_irk *irk;
1218970c4e46SJohan Hedberg 
1219adae20cbSJohan Hedberg 	rcu_read_lock();
1220adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1221adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
1222600a8749SAlain Michaud 			irk_to_return = irk;
1223600a8749SAlain Michaud 			goto done;
1224970c4e46SJohan Hedberg 		}
1225adae20cbSJohan Hedberg 	}
1226970c4e46SJohan Hedberg 
1227adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1228defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
1229970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
1230600a8749SAlain Michaud 			irk_to_return = irk;
1231600a8749SAlain Michaud 			goto done;
1232970c4e46SJohan Hedberg 		}
1233970c4e46SJohan Hedberg 	}
1234600a8749SAlain Michaud 
1235600a8749SAlain Michaud done:
1236600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
1237600a8749SAlain Michaud 						irk_to_return->val)) {
1238600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
1239600a8749SAlain Michaud 					&irk_to_return->bdaddr);
1240600a8749SAlain Michaud 		irk_to_return = NULL;
1241600a8749SAlain Michaud 	}
1242600a8749SAlain Michaud 
1243adae20cbSJohan Hedberg 	rcu_read_unlock();
1244970c4e46SJohan Hedberg 
1245600a8749SAlain Michaud 	return irk_to_return;
1246970c4e46SJohan Hedberg }
1247970c4e46SJohan Hedberg 
1248970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1249970c4e46SJohan Hedberg 				     u8 addr_type)
1250970c4e46SJohan Hedberg {
1251600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
1252970c4e46SJohan Hedberg 	struct smp_irk *irk;
1253970c4e46SJohan Hedberg 
12546cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
12556cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
12566cfc9988SJohan Hedberg 		return NULL;
12576cfc9988SJohan Hedberg 
1258adae20cbSJohan Hedberg 	rcu_read_lock();
1259adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1260970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
1261adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
1262600a8749SAlain Michaud 			irk_to_return = irk;
1263600a8749SAlain Michaud 			goto done;
1264970c4e46SJohan Hedberg 		}
1265adae20cbSJohan Hedberg 	}
1266600a8749SAlain Michaud 
1267600a8749SAlain Michaud done:
1268600a8749SAlain Michaud 
1269600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
1270600a8749SAlain Michaud 						irk_to_return->val)) {
1271600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
1272600a8749SAlain Michaud 					&irk_to_return->bdaddr);
1273600a8749SAlain Michaud 		irk_to_return = NULL;
1274600a8749SAlain Michaud 	}
1275600a8749SAlain Michaud 
1276adae20cbSJohan Hedberg 	rcu_read_unlock();
1277970c4e46SJohan Hedberg 
1278600a8749SAlain Michaud 	return irk_to_return;
1279970c4e46SJohan Hedberg }
1280970c4e46SJohan Hedberg 
1281567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
12827652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
12837652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
128455ed8ca1SJohan Hedberg {
128555ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1286745c0ce3SVishal Agarwal 	u8 old_key_type;
128755ed8ca1SJohan Hedberg 
128855ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
128955ed8ca1SJohan Hedberg 	if (old_key) {
129055ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
129155ed8ca1SJohan Hedberg 		key = old_key;
129255ed8ca1SJohan Hedberg 	} else {
129312adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
12940a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
129555ed8ca1SJohan Hedberg 		if (!key)
1296567fa2aaSJohan Hedberg 			return NULL;
12970378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
129855ed8ca1SJohan Hedberg 	}
129955ed8ca1SJohan Hedberg 
13006ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
130155ed8ca1SJohan Hedberg 
1302d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1303d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1304d25e28abSJohan Hedberg 	 * previous key */
1305d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1306a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1307d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1308655fe6ecSJohan Hedberg 		if (conn)
1309655fe6ecSJohan Hedberg 			conn->key_type = type;
1310655fe6ecSJohan Hedberg 	}
1311d25e28abSJohan Hedberg 
131255ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
13139b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
131455ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
131555ed8ca1SJohan Hedberg 
1316b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
131755ed8ca1SJohan Hedberg 		key->type = old_key_type;
13184748fed2SJohan Hedberg 	else
13194748fed2SJohan Hedberg 		key->type = type;
13204748fed2SJohan Hedberg 
13217652ff6aSJohan Hedberg 	if (persistent)
13227652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
13237652ff6aSJohan Hedberg 						 old_key_type);
13244df378a1SJohan Hedberg 
1325567fa2aaSJohan Hedberg 	return key;
132655ed8ca1SJohan Hedberg }
132755ed8ca1SJohan Hedberg 
1328ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
132935d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
1330fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
133175d262c2SVinicius Costa Gomes {
1332c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
1333e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
133475d262c2SVinicius Costa Gomes 
1335f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
1336c9839a11SVinicius Costa Gomes 	if (old_key)
133775d262c2SVinicius Costa Gomes 		key = old_key;
1338c9839a11SVinicius Costa Gomes 	else {
13390a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
134075d262c2SVinicius Costa Gomes 		if (!key)
1341ca9142b8SJohan Hedberg 			return NULL;
1342970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
134375d262c2SVinicius Costa Gomes 	}
134475d262c2SVinicius Costa Gomes 
134575d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1346c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1347c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1348c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1349c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1350fe39c7b2SMarcel Holtmann 	key->rand = rand;
1351c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1352c9839a11SVinicius Costa Gomes 	key->type = type;
135375d262c2SVinicius Costa Gomes 
1354ca9142b8SJohan Hedberg 	return key;
135575d262c2SVinicius Costa Gomes }
135675d262c2SVinicius Costa Gomes 
1357ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
1358ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
1359970c4e46SJohan Hedberg {
1360970c4e46SJohan Hedberg 	struct smp_irk *irk;
1361970c4e46SJohan Hedberg 
1362970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
1363970c4e46SJohan Hedberg 	if (!irk) {
1364970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
1365970c4e46SJohan Hedberg 		if (!irk)
1366ca9142b8SJohan Hedberg 			return NULL;
1367970c4e46SJohan Hedberg 
1368970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
1369970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
1370970c4e46SJohan Hedberg 
1371adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
1372970c4e46SJohan Hedberg 	}
1373970c4e46SJohan Hedberg 
1374970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
1375970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
1376970c4e46SJohan Hedberg 
1377ca9142b8SJohan Hedberg 	return irk;
1378970c4e46SJohan Hedberg }
1379970c4e46SJohan Hedberg 
138055ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
138155ed8ca1SJohan Hedberg {
138255ed8ca1SJohan Hedberg 	struct link_key *key;
138355ed8ca1SJohan Hedberg 
138455ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
138555ed8ca1SJohan Hedberg 	if (!key)
138655ed8ca1SJohan Hedberg 		return -ENOENT;
138755ed8ca1SJohan Hedberg 
13886ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
138955ed8ca1SJohan Hedberg 
13900378b597SJohan Hedberg 	list_del_rcu(&key->list);
13910378b597SJohan Hedberg 	kfree_rcu(key, rcu);
139255ed8ca1SJohan Hedberg 
139355ed8ca1SJohan Hedberg 	return 0;
139455ed8ca1SJohan Hedberg }
139555ed8ca1SJohan Hedberg 
1396e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
1397b899efafSVinicius Costa Gomes {
1398970d0f1bSJohan Hedberg 	struct smp_ltk *k;
1399c51ffa0bSJohan Hedberg 	int removed = 0;
1400b899efafSVinicius Costa Gomes 
1401970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
1402e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
1403b899efafSVinicius Costa Gomes 			continue;
1404b899efafSVinicius Costa Gomes 
14056ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1406b899efafSVinicius Costa Gomes 
1407970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
1408970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
1409c51ffa0bSJohan Hedberg 		removed++;
1410b899efafSVinicius Costa Gomes 	}
1411b899efafSVinicius Costa Gomes 
1412c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
1413b899efafSVinicius Costa Gomes }
1414b899efafSVinicius Costa Gomes 
1415a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
1416a7ec7338SJohan Hedberg {
1417adae20cbSJohan Hedberg 	struct smp_irk *k;
1418a7ec7338SJohan Hedberg 
1419adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
1420a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
1421a7ec7338SJohan Hedberg 			continue;
1422a7ec7338SJohan Hedberg 
1423a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1424a7ec7338SJohan Hedberg 
1425adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
1426adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
1427a7ec7338SJohan Hedberg 	}
1428a7ec7338SJohan Hedberg }
1429a7ec7338SJohan Hedberg 
143055e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
143155e76b38SJohan Hedberg {
143255e76b38SJohan Hedberg 	struct smp_ltk *k;
14334ba9faf3SJohan Hedberg 	struct smp_irk *irk;
143455e76b38SJohan Hedberg 	u8 addr_type;
143555e76b38SJohan Hedberg 
143655e76b38SJohan Hedberg 	if (type == BDADDR_BREDR) {
143755e76b38SJohan Hedberg 		if (hci_find_link_key(hdev, bdaddr))
143855e76b38SJohan Hedberg 			return true;
143955e76b38SJohan Hedberg 		return false;
144055e76b38SJohan Hedberg 	}
144155e76b38SJohan Hedberg 
144255e76b38SJohan Hedberg 	/* Convert to HCI addr type which struct smp_ltk uses */
144355e76b38SJohan Hedberg 	if (type == BDADDR_LE_PUBLIC)
144455e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_PUBLIC;
144555e76b38SJohan Hedberg 	else
144655e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_RANDOM;
144755e76b38SJohan Hedberg 
14484ba9faf3SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, addr_type);
14494ba9faf3SJohan Hedberg 	if (irk) {
14504ba9faf3SJohan Hedberg 		bdaddr = &irk->bdaddr;
14514ba9faf3SJohan Hedberg 		addr_type = irk->addr_type;
14524ba9faf3SJohan Hedberg 	}
14534ba9faf3SJohan Hedberg 
145455e76b38SJohan Hedberg 	rcu_read_lock();
145555e76b38SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
145687c8b28dSJohan Hedberg 		if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) {
145787c8b28dSJohan Hedberg 			rcu_read_unlock();
145855e76b38SJohan Hedberg 			return true;
145955e76b38SJohan Hedberg 		}
146087c8b28dSJohan Hedberg 	}
146155e76b38SJohan Hedberg 	rcu_read_unlock();
146255e76b38SJohan Hedberg 
146355e76b38SJohan Hedberg 	return false;
146455e76b38SJohan Hedberg }
146555e76b38SJohan Hedberg 
14666bd32326SVille Tervo /* HCI command timer function */
146765cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
14686bd32326SVille Tervo {
146965cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
147065cc2b49SMarcel Holtmann 					    cmd_timer.work);
14716bd32326SVille Tervo 
1472bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
1473bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
1474bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
1475bda4f23aSAndrei Emeltchenko 
14762064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode);
1477bda4f23aSAndrei Emeltchenko 	} else {
14782064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command tx timeout");
1479bda4f23aSAndrei Emeltchenko 	}
1480bda4f23aSAndrei Emeltchenko 
1481e2bef384SRajat Jain 	if (hdev->cmd_timeout)
1482e2bef384SRajat Jain 		hdev->cmd_timeout(hdev);
1483e2bef384SRajat Jain 
14846bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1485c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
14866bd32326SVille Tervo }
14876bd32326SVille Tervo 
1488de75cd0dSManish Mandlik /* HCI ncmd timer function */
1489de75cd0dSManish Mandlik static void hci_ncmd_timeout(struct work_struct *work)
1490de75cd0dSManish Mandlik {
1491de75cd0dSManish Mandlik 	struct hci_dev *hdev = container_of(work, struct hci_dev,
1492de75cd0dSManish Mandlik 					    ncmd_timer.work);
1493de75cd0dSManish Mandlik 
1494de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Controller not accepting commands anymore: ncmd = 0");
1495de75cd0dSManish Mandlik 
1496de75cd0dSManish Mandlik 	/* During HCI_INIT phase no events can be injected if the ncmd timer
1497de75cd0dSManish Mandlik 	 * triggers since the procedure has its own timeout handling.
1498de75cd0dSManish Mandlik 	 */
1499de75cd0dSManish Mandlik 	if (test_bit(HCI_INIT, &hdev->flags))
1500de75cd0dSManish Mandlik 		return;
1501de75cd0dSManish Mandlik 
1502de75cd0dSManish Mandlik 	/* This is an irrecoverable state, inject hardware error event */
1503de75cd0dSManish Mandlik 	hci_reset_dev(hdev);
1504de75cd0dSManish Mandlik }
1505de75cd0dSManish Mandlik 
15062763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
15076928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
15082763eda6SSzymon Janc {
15092763eda6SSzymon Janc 	struct oob_data *data;
15102763eda6SSzymon Janc 
15116928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
15126928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
15136928a924SJohan Hedberg 			continue;
15146928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
15156928a924SJohan Hedberg 			continue;
15162763eda6SSzymon Janc 		return data;
15176928a924SJohan Hedberg 	}
15182763eda6SSzymon Janc 
15192763eda6SSzymon Janc 	return NULL;
15202763eda6SSzymon Janc }
15212763eda6SSzymon Janc 
15226928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
15236928a924SJohan Hedberg 			       u8 bdaddr_type)
15242763eda6SSzymon Janc {
15252763eda6SSzymon Janc 	struct oob_data *data;
15262763eda6SSzymon Janc 
15276928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
15282763eda6SSzymon Janc 	if (!data)
15292763eda6SSzymon Janc 		return -ENOENT;
15302763eda6SSzymon Janc 
15316928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
15322763eda6SSzymon Janc 
15332763eda6SSzymon Janc 	list_del(&data->list);
15342763eda6SSzymon Janc 	kfree(data);
15352763eda6SSzymon Janc 
15362763eda6SSzymon Janc 	return 0;
15372763eda6SSzymon Janc }
15382763eda6SSzymon Janc 
153935f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
15402763eda6SSzymon Janc {
15412763eda6SSzymon Janc 	struct oob_data *data, *n;
15422763eda6SSzymon Janc 
15432763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
15442763eda6SSzymon Janc 		list_del(&data->list);
15452763eda6SSzymon Janc 		kfree(data);
15462763eda6SSzymon Janc 	}
15472763eda6SSzymon Janc }
15482763eda6SSzymon Janc 
15490798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
15506928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
155138da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
15520798872eSMarcel Holtmann {
15530798872eSMarcel Holtmann 	struct oob_data *data;
15540798872eSMarcel Holtmann 
15556928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
15560798872eSMarcel Holtmann 	if (!data) {
15570a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
15580798872eSMarcel Holtmann 		if (!data)
15590798872eSMarcel Holtmann 			return -ENOMEM;
15600798872eSMarcel Holtmann 
15610798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
15626928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
15630798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
15640798872eSMarcel Holtmann 	}
15650798872eSMarcel Holtmann 
156681328d5cSJohan Hedberg 	if (hash192 && rand192) {
15670798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
156838da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
1569f7697b16SMarcel Holtmann 		if (hash256 && rand256)
1570f7697b16SMarcel Holtmann 			data->present = 0x03;
157181328d5cSJohan Hedberg 	} else {
157281328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
157381328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
1574f7697b16SMarcel Holtmann 		if (hash256 && rand256)
1575f7697b16SMarcel Holtmann 			data->present = 0x02;
1576f7697b16SMarcel Holtmann 		else
1577f7697b16SMarcel Holtmann 			data->present = 0x00;
157881328d5cSJohan Hedberg 	}
15790798872eSMarcel Holtmann 
158081328d5cSJohan Hedberg 	if (hash256 && rand256) {
15810798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
158238da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
158381328d5cSJohan Hedberg 	} else {
158481328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
158581328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
1586f7697b16SMarcel Holtmann 		if (hash192 && rand192)
1587f7697b16SMarcel Holtmann 			data->present = 0x01;
158881328d5cSJohan Hedberg 	}
15890798872eSMarcel Holtmann 
15906ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
15912763eda6SSzymon Janc 
15922763eda6SSzymon Janc 	return 0;
15932763eda6SSzymon Janc }
15942763eda6SSzymon Janc 
1595d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1596d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance)
1597d2609b34SFlorian Grandel {
1598d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
1599d2609b34SFlorian Grandel 
1600d2609b34SFlorian Grandel 	list_for_each_entry(adv_instance, &hdev->adv_instances, list) {
1601d2609b34SFlorian Grandel 		if (adv_instance->instance == instance)
1602d2609b34SFlorian Grandel 			return adv_instance;
1603d2609b34SFlorian Grandel 	}
1604d2609b34SFlorian Grandel 
1605d2609b34SFlorian Grandel 	return NULL;
1606d2609b34SFlorian Grandel }
1607d2609b34SFlorian Grandel 
1608d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
160974b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance)
161074b93e9fSPrasanna Karthik {
1611d2609b34SFlorian Grandel 	struct adv_info *cur_instance;
1612d2609b34SFlorian Grandel 
1613d2609b34SFlorian Grandel 	cur_instance = hci_find_adv_instance(hdev, instance);
1614d2609b34SFlorian Grandel 	if (!cur_instance)
1615d2609b34SFlorian Grandel 		return NULL;
1616d2609b34SFlorian Grandel 
1617d2609b34SFlorian Grandel 	if (cur_instance == list_last_entry(&hdev->adv_instances,
1618d2609b34SFlorian Grandel 					    struct adv_info, list))
1619d2609b34SFlorian Grandel 		return list_first_entry(&hdev->adv_instances,
1620d2609b34SFlorian Grandel 						 struct adv_info, list);
1621d2609b34SFlorian Grandel 	else
1622d2609b34SFlorian Grandel 		return list_next_entry(cur_instance, list);
1623d2609b34SFlorian Grandel }
1624d2609b34SFlorian Grandel 
1625d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1626d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance)
1627d2609b34SFlorian Grandel {
1628d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
1629d2609b34SFlorian Grandel 
1630d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
1631d2609b34SFlorian Grandel 	if (!adv_instance)
1632d2609b34SFlorian Grandel 		return -ENOENT;
1633d2609b34SFlorian Grandel 
1634d2609b34SFlorian Grandel 	BT_DBG("%s removing %dMR", hdev->name, instance);
1635d2609b34SFlorian Grandel 
1636cab054abSJohan Hedberg 	if (hdev->cur_adv_instance == instance) {
1637cab054abSJohan Hedberg 		if (hdev->adv_instance_timeout) {
16385d900e46SFlorian Grandel 			cancel_delayed_work(&hdev->adv_instance_expire);
16395d900e46SFlorian Grandel 			hdev->adv_instance_timeout = 0;
16405d900e46SFlorian Grandel 		}
1641cab054abSJohan Hedberg 		hdev->cur_adv_instance = 0x00;
1642cab054abSJohan Hedberg 	}
16435d900e46SFlorian Grandel 
1644a73c046aSJaganath Kanakkassery 	cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1645a73c046aSJaganath Kanakkassery 
1646d2609b34SFlorian Grandel 	list_del(&adv_instance->list);
1647d2609b34SFlorian Grandel 	kfree(adv_instance);
1648d2609b34SFlorian Grandel 
1649d2609b34SFlorian Grandel 	hdev->adv_instance_cnt--;
1650d2609b34SFlorian Grandel 
1651d2609b34SFlorian Grandel 	return 0;
1652d2609b34SFlorian Grandel }
1653d2609b34SFlorian Grandel 
1654a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired)
1655a73c046aSJaganath Kanakkassery {
1656a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance, *n;
1657a73c046aSJaganath Kanakkassery 
1658a73c046aSJaganath Kanakkassery 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list)
1659a73c046aSJaganath Kanakkassery 		adv_instance->rpa_expired = rpa_expired;
1660a73c046aSJaganath Kanakkassery }
1661a73c046aSJaganath Kanakkassery 
1662d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1663d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev)
1664d2609b34SFlorian Grandel {
1665d2609b34SFlorian Grandel 	struct adv_info *adv_instance, *n;
1666d2609b34SFlorian Grandel 
16675d900e46SFlorian Grandel 	if (hdev->adv_instance_timeout) {
16685d900e46SFlorian Grandel 		cancel_delayed_work(&hdev->adv_instance_expire);
16695d900e46SFlorian Grandel 		hdev->adv_instance_timeout = 0;
16705d900e46SFlorian Grandel 	}
16715d900e46SFlorian Grandel 
1672d2609b34SFlorian Grandel 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
1673a73c046aSJaganath Kanakkassery 		cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1674d2609b34SFlorian Grandel 		list_del(&adv_instance->list);
1675d2609b34SFlorian Grandel 		kfree(adv_instance);
1676d2609b34SFlorian Grandel 	}
1677d2609b34SFlorian Grandel 
1678d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
1679cab054abSJohan Hedberg 	hdev->cur_adv_instance = 0x00;
1680d2609b34SFlorian Grandel }
1681d2609b34SFlorian Grandel 
1682a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work)
1683a73c046aSJaganath Kanakkassery {
1684a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance = container_of(work, struct adv_info,
1685a73c046aSJaganath Kanakkassery 						     rpa_expired_cb.work);
1686a73c046aSJaganath Kanakkassery 
1687a73c046aSJaganath Kanakkassery 	BT_DBG("");
1688a73c046aSJaganath Kanakkassery 
1689a73c046aSJaganath Kanakkassery 	adv_instance->rpa_expired = true;
1690a73c046aSJaganath Kanakkassery }
1691a73c046aSJaganath Kanakkassery 
1692d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1693d2609b34SFlorian Grandel int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
1694d2609b34SFlorian Grandel 			 u16 adv_data_len, u8 *adv_data,
1695d2609b34SFlorian Grandel 			 u16 scan_rsp_len, u8 *scan_rsp_data,
16969bf9f4b6SDaniel Winkler 			 u16 timeout, u16 duration, s8 tx_power,
16979bf9f4b6SDaniel Winkler 			 u32 min_interval, u32 max_interval)
1698d2609b34SFlorian Grandel {
1699d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
1700d2609b34SFlorian Grandel 
1701d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
1702d2609b34SFlorian Grandel 	if (adv_instance) {
1703d2609b34SFlorian Grandel 		memset(adv_instance->adv_data, 0,
1704d2609b34SFlorian Grandel 		       sizeof(adv_instance->adv_data));
1705d2609b34SFlorian Grandel 		memset(adv_instance->scan_rsp_data, 0,
1706d2609b34SFlorian Grandel 		       sizeof(adv_instance->scan_rsp_data));
1707d2609b34SFlorian Grandel 	} else {
17081d0fac2cSLuiz Augusto von Dentz 		if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets ||
170987597482SDaniel Winkler 		    instance < 1 || instance > hdev->le_num_of_adv_sets)
1710d2609b34SFlorian Grandel 			return -EOVERFLOW;
1711d2609b34SFlorian Grandel 
171239ecfad6SJohan Hedberg 		adv_instance = kzalloc(sizeof(*adv_instance), GFP_KERNEL);
1713d2609b34SFlorian Grandel 		if (!adv_instance)
1714d2609b34SFlorian Grandel 			return -ENOMEM;
1715d2609b34SFlorian Grandel 
1716fffd38bcSFlorian Grandel 		adv_instance->pending = true;
1717d2609b34SFlorian Grandel 		adv_instance->instance = instance;
1718d2609b34SFlorian Grandel 		list_add(&adv_instance->list, &hdev->adv_instances);
1719d2609b34SFlorian Grandel 		hdev->adv_instance_cnt++;
1720d2609b34SFlorian Grandel 	}
1721d2609b34SFlorian Grandel 
1722d2609b34SFlorian Grandel 	adv_instance->flags = flags;
1723d2609b34SFlorian Grandel 	adv_instance->adv_data_len = adv_data_len;
1724d2609b34SFlorian Grandel 	adv_instance->scan_rsp_len = scan_rsp_len;
17259bf9f4b6SDaniel Winkler 	adv_instance->min_interval = min_interval;
17269bf9f4b6SDaniel Winkler 	adv_instance->max_interval = max_interval;
17279bf9f4b6SDaniel Winkler 	adv_instance->tx_power = tx_power;
1728d2609b34SFlorian Grandel 
1729d2609b34SFlorian Grandel 	if (adv_data_len)
1730d2609b34SFlorian Grandel 		memcpy(adv_instance->adv_data, adv_data, adv_data_len);
1731d2609b34SFlorian Grandel 
1732d2609b34SFlorian Grandel 	if (scan_rsp_len)
1733d2609b34SFlorian Grandel 		memcpy(adv_instance->scan_rsp_data,
1734d2609b34SFlorian Grandel 		       scan_rsp_data, scan_rsp_len);
1735d2609b34SFlorian Grandel 
1736d2609b34SFlorian Grandel 	adv_instance->timeout = timeout;
17375d900e46SFlorian Grandel 	adv_instance->remaining_time = timeout;
1738d2609b34SFlorian Grandel 
1739d2609b34SFlorian Grandel 	if (duration == 0)
174010873f99SAlain Michaud 		adv_instance->duration = hdev->def_multi_adv_rotation_duration;
1741d2609b34SFlorian Grandel 	else
1742d2609b34SFlorian Grandel 		adv_instance->duration = duration;
1743d2609b34SFlorian Grandel 
1744a73c046aSJaganath Kanakkassery 	INIT_DELAYED_WORK(&adv_instance->rpa_expired_cb,
1745a73c046aSJaganath Kanakkassery 			  adv_instance_rpa_expired);
1746a73c046aSJaganath Kanakkassery 
1747d2609b34SFlorian Grandel 	BT_DBG("%s for %dMR", hdev->name, instance);
1748d2609b34SFlorian Grandel 
1749d2609b34SFlorian Grandel 	return 0;
1750d2609b34SFlorian Grandel }
1751d2609b34SFlorian Grandel 
1752e5e1e7fdSMiao-chen Chou /* This function requires the caller holds hdev->lock */
175331aab5c2SDaniel Winkler int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance,
175431aab5c2SDaniel Winkler 			      u16 adv_data_len, u8 *adv_data,
175531aab5c2SDaniel Winkler 			      u16 scan_rsp_len, u8 *scan_rsp_data)
175631aab5c2SDaniel Winkler {
175731aab5c2SDaniel Winkler 	struct adv_info *adv_instance;
175831aab5c2SDaniel Winkler 
175931aab5c2SDaniel Winkler 	adv_instance = hci_find_adv_instance(hdev, instance);
176031aab5c2SDaniel Winkler 
176131aab5c2SDaniel Winkler 	/* If advertisement doesn't exist, we can't modify its data */
176231aab5c2SDaniel Winkler 	if (!adv_instance)
176331aab5c2SDaniel Winkler 		return -ENOENT;
176431aab5c2SDaniel Winkler 
176531aab5c2SDaniel Winkler 	if (adv_data_len) {
176631aab5c2SDaniel Winkler 		memset(adv_instance->adv_data, 0,
176731aab5c2SDaniel Winkler 		       sizeof(adv_instance->adv_data));
176831aab5c2SDaniel Winkler 		memcpy(adv_instance->adv_data, adv_data, adv_data_len);
176931aab5c2SDaniel Winkler 		adv_instance->adv_data_len = adv_data_len;
177031aab5c2SDaniel Winkler 	}
177131aab5c2SDaniel Winkler 
177231aab5c2SDaniel Winkler 	if (scan_rsp_len) {
177331aab5c2SDaniel Winkler 		memset(adv_instance->scan_rsp_data, 0,
177431aab5c2SDaniel Winkler 		       sizeof(adv_instance->scan_rsp_data));
177531aab5c2SDaniel Winkler 		memcpy(adv_instance->scan_rsp_data,
177631aab5c2SDaniel Winkler 		       scan_rsp_data, scan_rsp_len);
177731aab5c2SDaniel Winkler 		adv_instance->scan_rsp_len = scan_rsp_len;
177831aab5c2SDaniel Winkler 	}
177931aab5c2SDaniel Winkler 
178031aab5c2SDaniel Winkler 	return 0;
178131aab5c2SDaniel Winkler }
178231aab5c2SDaniel Winkler 
178331aab5c2SDaniel Winkler /* This function requires the caller holds hdev->lock */
178401ce70b0SLuiz Augusto von Dentz u32 hci_adv_instance_flags(struct hci_dev *hdev, u8 instance)
178501ce70b0SLuiz Augusto von Dentz {
178601ce70b0SLuiz Augusto von Dentz 	u32 flags;
178701ce70b0SLuiz Augusto von Dentz 	struct adv_info *adv;
178801ce70b0SLuiz Augusto von Dentz 
178901ce70b0SLuiz Augusto von Dentz 	if (instance == 0x00) {
179001ce70b0SLuiz Augusto von Dentz 		/* Instance 0 always manages the "Tx Power" and "Flags"
179101ce70b0SLuiz Augusto von Dentz 		 * fields
179201ce70b0SLuiz Augusto von Dentz 		 */
179301ce70b0SLuiz Augusto von Dentz 		flags = MGMT_ADV_FLAG_TX_POWER | MGMT_ADV_FLAG_MANAGED_FLAGS;
179401ce70b0SLuiz Augusto von Dentz 
179501ce70b0SLuiz Augusto von Dentz 		/* For instance 0, the HCI_ADVERTISING_CONNECTABLE setting
179601ce70b0SLuiz Augusto von Dentz 		 * corresponds to the "connectable" instance flag.
179701ce70b0SLuiz Augusto von Dentz 		 */
179801ce70b0SLuiz Augusto von Dentz 		if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE))
179901ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_CONNECTABLE;
180001ce70b0SLuiz Augusto von Dentz 
180101ce70b0SLuiz Augusto von Dentz 		if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
180201ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
180301ce70b0SLuiz Augusto von Dentz 		else if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
180401ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_DISCOV;
180501ce70b0SLuiz Augusto von Dentz 
180601ce70b0SLuiz Augusto von Dentz 		return flags;
180701ce70b0SLuiz Augusto von Dentz 	}
180801ce70b0SLuiz Augusto von Dentz 
180901ce70b0SLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
181001ce70b0SLuiz Augusto von Dentz 
181101ce70b0SLuiz Augusto von Dentz 	/* Return 0 when we got an invalid instance identifier. */
181201ce70b0SLuiz Augusto von Dentz 	if (!adv)
181301ce70b0SLuiz Augusto von Dentz 		return 0;
181401ce70b0SLuiz Augusto von Dentz 
181501ce70b0SLuiz Augusto von Dentz 	return adv->flags;
181601ce70b0SLuiz Augusto von Dentz }
181701ce70b0SLuiz Augusto von Dentz 
181801ce70b0SLuiz Augusto von Dentz bool hci_adv_instance_is_scannable(struct hci_dev *hdev, u8 instance)
181901ce70b0SLuiz Augusto von Dentz {
182001ce70b0SLuiz Augusto von Dentz 	struct adv_info *adv;
182101ce70b0SLuiz Augusto von Dentz 
182201ce70b0SLuiz Augusto von Dentz 	/* Instance 0x00 always set local name */
182301ce70b0SLuiz Augusto von Dentz 	if (instance == 0x00)
182401ce70b0SLuiz Augusto von Dentz 		return true;
182501ce70b0SLuiz Augusto von Dentz 
182601ce70b0SLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
182701ce70b0SLuiz Augusto von Dentz 	if (!adv)
182801ce70b0SLuiz Augusto von Dentz 		return false;
182901ce70b0SLuiz Augusto von Dentz 
183001ce70b0SLuiz Augusto von Dentz 	if (adv->flags & MGMT_ADV_FLAG_APPEARANCE ||
183101ce70b0SLuiz Augusto von Dentz 	    adv->flags & MGMT_ADV_FLAG_LOCAL_NAME)
183201ce70b0SLuiz Augusto von Dentz 		return true;
183301ce70b0SLuiz Augusto von Dentz 
183401ce70b0SLuiz Augusto von Dentz 	return adv->scan_rsp_len ? true : false;
183501ce70b0SLuiz Augusto von Dentz }
183601ce70b0SLuiz Augusto von Dentz 
183701ce70b0SLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */
1838e5e1e7fdSMiao-chen Chou void hci_adv_monitors_clear(struct hci_dev *hdev)
1839e5e1e7fdSMiao-chen Chou {
1840b139553dSMiao-chen Chou 	struct adv_monitor *monitor;
1841b139553dSMiao-chen Chou 	int handle;
1842b139553dSMiao-chen Chou 
1843b139553dSMiao-chen Chou 	idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle)
184466bd095aSArchie Pusaka 		hci_free_adv_monitor(hdev, monitor);
1845b139553dSMiao-chen Chou 
1846e5e1e7fdSMiao-chen Chou 	idr_destroy(&hdev->adv_monitors_idr);
1847e5e1e7fdSMiao-chen Chou }
1848e5e1e7fdSMiao-chen Chou 
184966bd095aSArchie Pusaka /* Frees the monitor structure and do some bookkeepings.
185066bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
185166bd095aSArchie Pusaka  */
185266bd095aSArchie Pusaka void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
1853b139553dSMiao-chen Chou {
1854b139553dSMiao-chen Chou 	struct adv_pattern *pattern;
1855b139553dSMiao-chen Chou 	struct adv_pattern *tmp;
1856b139553dSMiao-chen Chou 
1857b139553dSMiao-chen Chou 	if (!monitor)
1858b139553dSMiao-chen Chou 		return;
1859b139553dSMiao-chen Chou 
186066bd095aSArchie Pusaka 	list_for_each_entry_safe(pattern, tmp, &monitor->patterns, list) {
186166bd095aSArchie Pusaka 		list_del(&pattern->list);
1862b139553dSMiao-chen Chou 		kfree(pattern);
186366bd095aSArchie Pusaka 	}
186466bd095aSArchie Pusaka 
186566bd095aSArchie Pusaka 	if (monitor->handle)
186666bd095aSArchie Pusaka 		idr_remove(&hdev->adv_monitors_idr, monitor->handle);
186766bd095aSArchie Pusaka 
186866bd095aSArchie Pusaka 	if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) {
186966bd095aSArchie Pusaka 		hdev->adv_monitors_cnt--;
187066bd095aSArchie Pusaka 		mgmt_adv_monitor_removed(hdev, monitor->handle);
187166bd095aSArchie Pusaka 	}
1872b139553dSMiao-chen Chou 
1873b139553dSMiao-chen Chou 	kfree(monitor);
1874b139553dSMiao-chen Chou }
1875b139553dSMiao-chen Chou 
1876a2a4dedfSArchie Pusaka int hci_add_adv_patterns_monitor_complete(struct hci_dev *hdev, u8 status)
1877a2a4dedfSArchie Pusaka {
1878a2a4dedfSArchie Pusaka 	return mgmt_add_adv_patterns_monitor_complete(hdev, status);
1879a2a4dedfSArchie Pusaka }
1880a2a4dedfSArchie Pusaka 
188166bd095aSArchie Pusaka int hci_remove_adv_monitor_complete(struct hci_dev *hdev, u8 status)
188266bd095aSArchie Pusaka {
188366bd095aSArchie Pusaka 	return mgmt_remove_adv_monitor_complete(hdev, status);
188466bd095aSArchie Pusaka }
188566bd095aSArchie Pusaka 
1886a2a4dedfSArchie Pusaka /* Assigns handle to a monitor, and if offloading is supported and power is on,
1887a2a4dedfSArchie Pusaka  * also attempts to forward the request to the controller.
1888a2a4dedfSArchie Pusaka  * Returns true if request is forwarded (result is pending), false otherwise.
1889a2a4dedfSArchie Pusaka  * This function requires the caller holds hdev->lock.
1890a2a4dedfSArchie Pusaka  */
1891a2a4dedfSArchie Pusaka bool hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor,
1892a2a4dedfSArchie Pusaka 			 int *err)
1893b139553dSMiao-chen Chou {
1894b139553dSMiao-chen Chou 	int min, max, handle;
1895b139553dSMiao-chen Chou 
1896a2a4dedfSArchie Pusaka 	*err = 0;
1897a2a4dedfSArchie Pusaka 
1898a2a4dedfSArchie Pusaka 	if (!monitor) {
1899a2a4dedfSArchie Pusaka 		*err = -EINVAL;
1900a2a4dedfSArchie Pusaka 		return false;
1901a2a4dedfSArchie Pusaka 	}
1902b139553dSMiao-chen Chou 
1903b139553dSMiao-chen Chou 	min = HCI_MIN_ADV_MONITOR_HANDLE;
1904b139553dSMiao-chen Chou 	max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES;
1905b139553dSMiao-chen Chou 	handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max,
1906b139553dSMiao-chen Chou 			   GFP_KERNEL);
1907a2a4dedfSArchie Pusaka 	if (handle < 0) {
1908a2a4dedfSArchie Pusaka 		*err = handle;
1909a2a4dedfSArchie Pusaka 		return false;
1910a2a4dedfSArchie Pusaka 	}
1911b139553dSMiao-chen Chou 
1912b139553dSMiao-chen Chou 	monitor->handle = handle;
19138208f5a9SMiao-chen Chou 
1914a2a4dedfSArchie Pusaka 	if (!hdev_is_powered(hdev))
1915a2a4dedfSArchie Pusaka 		return false;
19168208f5a9SMiao-chen Chou 
1917a2a4dedfSArchie Pusaka 	switch (hci_get_adv_monitor_offload_ext(hdev)) {
1918a2a4dedfSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_NONE:
19195bee2fd6SLuiz Augusto von Dentz 		hci_update_passive_scan(hdev);
1920a2a4dedfSArchie Pusaka 		bt_dev_dbg(hdev, "%s add monitor status %d", hdev->name, *err);
1921a2a4dedfSArchie Pusaka 		/* Message was not forwarded to controller - not an error */
1922a2a4dedfSArchie Pusaka 		return false;
1923a2a4dedfSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_MSFT:
1924a2a4dedfSArchie Pusaka 		*err = msft_add_monitor_pattern(hdev, monitor);
1925a2a4dedfSArchie Pusaka 		bt_dev_dbg(hdev, "%s add monitor msft status %d", hdev->name,
1926a2a4dedfSArchie Pusaka 			   *err);
1927a2a4dedfSArchie Pusaka 		break;
1928a2a4dedfSArchie Pusaka 	}
1929a2a4dedfSArchie Pusaka 
1930a2a4dedfSArchie Pusaka 	return (*err == 0);
1931b139553dSMiao-chen Chou }
1932b139553dSMiao-chen Chou 
193366bd095aSArchie Pusaka /* Attempts to tell the controller and free the monitor. If somehow the
193466bd095aSArchie Pusaka  * controller doesn't have a corresponding handle, remove anyway.
193566bd095aSArchie Pusaka  * Returns true if request is forwarded (result is pending), false otherwise.
193666bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
193766bd095aSArchie Pusaka  */
193866bd095aSArchie Pusaka static bool hci_remove_adv_monitor(struct hci_dev *hdev,
193966bd095aSArchie Pusaka 				   struct adv_monitor *monitor,
194066bd095aSArchie Pusaka 				   u16 handle, int *err)
1941bd2fbc6cSMiao-chen Chou {
194266bd095aSArchie Pusaka 	*err = 0;
1943bd2fbc6cSMiao-chen Chou 
194466bd095aSArchie Pusaka 	switch (hci_get_adv_monitor_offload_ext(hdev)) {
194566bd095aSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */
194666bd095aSArchie Pusaka 		goto free_monitor;
194766bd095aSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_MSFT:
194866bd095aSArchie Pusaka 		*err = msft_remove_monitor(hdev, monitor, handle);
194966bd095aSArchie Pusaka 		break;
1950bd2fbc6cSMiao-chen Chou 	}
1951bd2fbc6cSMiao-chen Chou 
195266bd095aSArchie Pusaka 	/* In case no matching handle registered, just free the monitor */
195366bd095aSArchie Pusaka 	if (*err == -ENOENT)
195466bd095aSArchie Pusaka 		goto free_monitor;
1955bd2fbc6cSMiao-chen Chou 
195666bd095aSArchie Pusaka 	return (*err == 0);
1957bd2fbc6cSMiao-chen Chou 
195866bd095aSArchie Pusaka free_monitor:
195966bd095aSArchie Pusaka 	if (*err == -ENOENT)
196066bd095aSArchie Pusaka 		bt_dev_warn(hdev, "Removing monitor with no matching handle %d",
196166bd095aSArchie Pusaka 			    monitor->handle);
196266bd095aSArchie Pusaka 	hci_free_adv_monitor(hdev, monitor);
196366bd095aSArchie Pusaka 
196466bd095aSArchie Pusaka 	*err = 0;
196566bd095aSArchie Pusaka 	return false;
1966bd2fbc6cSMiao-chen Chou }
1967bd2fbc6cSMiao-chen Chou 
196866bd095aSArchie Pusaka /* Returns true if request is forwarded (result is pending), false otherwise.
196966bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
197066bd095aSArchie Pusaka  */
197166bd095aSArchie Pusaka bool hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle, int *err)
197266bd095aSArchie Pusaka {
197366bd095aSArchie Pusaka 	struct adv_monitor *monitor = idr_find(&hdev->adv_monitors_idr, handle);
197466bd095aSArchie Pusaka 	bool pending;
197566bd095aSArchie Pusaka 
197666bd095aSArchie Pusaka 	if (!monitor) {
197766bd095aSArchie Pusaka 		*err = -EINVAL;
197866bd095aSArchie Pusaka 		return false;
197966bd095aSArchie Pusaka 	}
198066bd095aSArchie Pusaka 
198166bd095aSArchie Pusaka 	pending = hci_remove_adv_monitor(hdev, monitor, handle, err);
198266bd095aSArchie Pusaka 	if (!*err && !pending)
19835bee2fd6SLuiz Augusto von Dentz 		hci_update_passive_scan(hdev);
19848208f5a9SMiao-chen Chou 
198566bd095aSArchie Pusaka 	bt_dev_dbg(hdev, "%s remove monitor handle %d, status %d, %spending",
198666bd095aSArchie Pusaka 		   hdev->name, handle, *err, pending ? "" : "not ");
198766bd095aSArchie Pusaka 
198866bd095aSArchie Pusaka 	return pending;
198966bd095aSArchie Pusaka }
199066bd095aSArchie Pusaka 
199166bd095aSArchie Pusaka /* Returns true if request is forwarded (result is pending), false otherwise.
199266bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
199366bd095aSArchie Pusaka  */
199466bd095aSArchie Pusaka bool hci_remove_all_adv_monitor(struct hci_dev *hdev, int *err)
199566bd095aSArchie Pusaka {
199666bd095aSArchie Pusaka 	struct adv_monitor *monitor;
199766bd095aSArchie Pusaka 	int idr_next_id = 0;
199866bd095aSArchie Pusaka 	bool pending = false;
199966bd095aSArchie Pusaka 	bool update = false;
200066bd095aSArchie Pusaka 
200166bd095aSArchie Pusaka 	*err = 0;
200266bd095aSArchie Pusaka 
200366bd095aSArchie Pusaka 	while (!*err && !pending) {
200466bd095aSArchie Pusaka 		monitor = idr_get_next(&hdev->adv_monitors_idr, &idr_next_id);
200566bd095aSArchie Pusaka 		if (!monitor)
200666bd095aSArchie Pusaka 			break;
200766bd095aSArchie Pusaka 
200866bd095aSArchie Pusaka 		pending = hci_remove_adv_monitor(hdev, monitor, 0, err);
200966bd095aSArchie Pusaka 
201066bd095aSArchie Pusaka 		if (!*err && !pending)
201166bd095aSArchie Pusaka 			update = true;
201266bd095aSArchie Pusaka 	}
201366bd095aSArchie Pusaka 
201466bd095aSArchie Pusaka 	if (update)
20155bee2fd6SLuiz Augusto von Dentz 		hci_update_passive_scan(hdev);
201666bd095aSArchie Pusaka 
201766bd095aSArchie Pusaka 	bt_dev_dbg(hdev, "%s remove all monitors status %d, %spending",
201866bd095aSArchie Pusaka 		   hdev->name, *err, pending ? "" : "not ");
201966bd095aSArchie Pusaka 
202066bd095aSArchie Pusaka 	return pending;
2021bd2fbc6cSMiao-chen Chou }
2022bd2fbc6cSMiao-chen Chou 
20238208f5a9SMiao-chen Chou /* This function requires the caller holds hdev->lock */
20248208f5a9SMiao-chen Chou bool hci_is_adv_monitoring(struct hci_dev *hdev)
20258208f5a9SMiao-chen Chou {
20268208f5a9SMiao-chen Chou 	return !idr_is_empty(&hdev->adv_monitors_idr);
20278208f5a9SMiao-chen Chou }
20288208f5a9SMiao-chen Chou 
2029a2a4dedfSArchie Pusaka int hci_get_adv_monitor_offload_ext(struct hci_dev *hdev)
2030a2a4dedfSArchie Pusaka {
2031a2a4dedfSArchie Pusaka 	if (msft_monitor_supported(hdev))
2032a2a4dedfSArchie Pusaka 		return HCI_ADV_MONITOR_EXT_MSFT;
2033a2a4dedfSArchie Pusaka 
2034a2a4dedfSArchie Pusaka 	return HCI_ADV_MONITOR_EXT_NONE;
2035a2a4dedfSArchie Pusaka }
2036a2a4dedfSArchie Pusaka 
2037dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
2038b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
2039b2a66aadSAntti Julku {
2040b2a66aadSAntti Julku 	struct bdaddr_list *b;
2041b2a66aadSAntti Julku 
2042dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
2043b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2044b2a66aadSAntti Julku 			return b;
2045b9ee0a78SMarcel Holtmann 	}
2046b2a66aadSAntti Julku 
2047b2a66aadSAntti Julku 	return NULL;
2048b2a66aadSAntti Julku }
2049b2a66aadSAntti Julku 
2050b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
2051b950aa88SAnkit Navik 				struct list_head *bdaddr_list, bdaddr_t *bdaddr,
2052b950aa88SAnkit Navik 				u8 type)
2053b950aa88SAnkit Navik {
2054b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *b;
2055b950aa88SAnkit Navik 
2056b950aa88SAnkit Navik 	list_for_each_entry(b, bdaddr_list, list) {
2057b950aa88SAnkit Navik 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2058b950aa88SAnkit Navik 			return b;
2059b950aa88SAnkit Navik 	}
2060b950aa88SAnkit Navik 
2061b950aa88SAnkit Navik 	return NULL;
2062b950aa88SAnkit Navik }
2063b950aa88SAnkit Navik 
20648baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *
20658baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list,
20668baaa403SAbhishek Pandit-Subedi 				  bdaddr_t *bdaddr, u8 type)
20678baaa403SAbhishek Pandit-Subedi {
20688baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *b;
20698baaa403SAbhishek Pandit-Subedi 
20708baaa403SAbhishek Pandit-Subedi 	list_for_each_entry(b, bdaddr_list, list) {
20718baaa403SAbhishek Pandit-Subedi 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
20728baaa403SAbhishek Pandit-Subedi 			return b;
20738baaa403SAbhishek Pandit-Subedi 	}
20748baaa403SAbhishek Pandit-Subedi 
20758baaa403SAbhishek Pandit-Subedi 	return NULL;
20768baaa403SAbhishek Pandit-Subedi }
20778baaa403SAbhishek Pandit-Subedi 
2078dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
2079b2a66aadSAntti Julku {
20807eb7404fSGeliang Tang 	struct bdaddr_list *b, *n;
2081b2a66aadSAntti Julku 
20827eb7404fSGeliang Tang 	list_for_each_entry_safe(b, n, bdaddr_list, list) {
20837eb7404fSGeliang Tang 		list_del(&b->list);
2084b2a66aadSAntti Julku 		kfree(b);
2085b2a66aadSAntti Julku 	}
2086b2a66aadSAntti Julku }
2087b2a66aadSAntti Julku 
2088dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2089b2a66aadSAntti Julku {
2090b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2091b2a66aadSAntti Julku 
2092b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
2093b2a66aadSAntti Julku 		return -EBADF;
2094b2a66aadSAntti Julku 
2095dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
20965e762444SAntti Julku 		return -EEXIST;
2097b2a66aadSAntti Julku 
209827f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
20995e762444SAntti Julku 	if (!entry)
21005e762444SAntti Julku 		return -ENOMEM;
2101b2a66aadSAntti Julku 
2102b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2103b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
2104b2a66aadSAntti Julku 
2105dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
2106b2a66aadSAntti Julku 
21072a8357f2SJohan Hedberg 	return 0;
2108b2a66aadSAntti Julku }
2109b2a66aadSAntti Julku 
2110b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2111b950aa88SAnkit Navik 					u8 type, u8 *peer_irk, u8 *local_irk)
2112b950aa88SAnkit Navik {
2113b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
2114b950aa88SAnkit Navik 
2115b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY))
2116b950aa88SAnkit Navik 		return -EBADF;
2117b950aa88SAnkit Navik 
2118b950aa88SAnkit Navik 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
2119b950aa88SAnkit Navik 		return -EEXIST;
2120b950aa88SAnkit Navik 
2121b950aa88SAnkit Navik 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
2122b950aa88SAnkit Navik 	if (!entry)
2123b950aa88SAnkit Navik 		return -ENOMEM;
2124b950aa88SAnkit Navik 
2125b950aa88SAnkit Navik 	bacpy(&entry->bdaddr, bdaddr);
2126b950aa88SAnkit Navik 	entry->bdaddr_type = type;
2127b950aa88SAnkit Navik 
2128b950aa88SAnkit Navik 	if (peer_irk)
2129b950aa88SAnkit Navik 		memcpy(entry->peer_irk, peer_irk, 16);
2130b950aa88SAnkit Navik 
2131b950aa88SAnkit Navik 	if (local_irk)
2132b950aa88SAnkit Navik 		memcpy(entry->local_irk, local_irk, 16);
2133b950aa88SAnkit Navik 
2134b950aa88SAnkit Navik 	list_add(&entry->list, list);
2135b950aa88SAnkit Navik 
2136b950aa88SAnkit Navik 	return 0;
2137b950aa88SAnkit Navik }
2138b950aa88SAnkit Navik 
21398baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
21408baaa403SAbhishek Pandit-Subedi 				   u8 type, u32 flags)
21418baaa403SAbhishek Pandit-Subedi {
21428baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
21438baaa403SAbhishek Pandit-Subedi 
21448baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY))
21458baaa403SAbhishek Pandit-Subedi 		return -EBADF;
21468baaa403SAbhishek Pandit-Subedi 
21478baaa403SAbhishek Pandit-Subedi 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
21488baaa403SAbhishek Pandit-Subedi 		return -EEXIST;
21498baaa403SAbhishek Pandit-Subedi 
21508baaa403SAbhishek Pandit-Subedi 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
21518baaa403SAbhishek Pandit-Subedi 	if (!entry)
21528baaa403SAbhishek Pandit-Subedi 		return -ENOMEM;
21538baaa403SAbhishek Pandit-Subedi 
21548baaa403SAbhishek Pandit-Subedi 	bacpy(&entry->bdaddr, bdaddr);
21558baaa403SAbhishek Pandit-Subedi 	entry->bdaddr_type = type;
21568baaa403SAbhishek Pandit-Subedi 	entry->current_flags = flags;
21578baaa403SAbhishek Pandit-Subedi 
21588baaa403SAbhishek Pandit-Subedi 	list_add(&entry->list, list);
21598baaa403SAbhishek Pandit-Subedi 
21608baaa403SAbhishek Pandit-Subedi 	return 0;
21618baaa403SAbhishek Pandit-Subedi }
21628baaa403SAbhishek Pandit-Subedi 
2163dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2164b2a66aadSAntti Julku {
2165b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2166b2a66aadSAntti Julku 
216735f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2168dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
216935f7498aSJohan Hedberg 		return 0;
217035f7498aSJohan Hedberg 	}
2171b2a66aadSAntti Julku 
2172dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
2173d2ab0ac1SMarcel Holtmann 	if (!entry)
2174d2ab0ac1SMarcel Holtmann 		return -ENOENT;
2175d2ab0ac1SMarcel Holtmann 
2176d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
2177d2ab0ac1SMarcel Holtmann 	kfree(entry);
2178d2ab0ac1SMarcel Holtmann 
2179d2ab0ac1SMarcel Holtmann 	return 0;
2180d2ab0ac1SMarcel Holtmann }
2181d2ab0ac1SMarcel Holtmann 
2182b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2183b950aa88SAnkit Navik 							u8 type)
2184b950aa88SAnkit Navik {
2185b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
2186b950aa88SAnkit Navik 
2187b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2188b950aa88SAnkit Navik 		hci_bdaddr_list_clear(list);
2189b950aa88SAnkit Navik 		return 0;
2190b950aa88SAnkit Navik 	}
2191b950aa88SAnkit Navik 
2192b950aa88SAnkit Navik 	entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type);
2193b950aa88SAnkit Navik 	if (!entry)
2194b950aa88SAnkit Navik 		return -ENOENT;
2195b950aa88SAnkit Navik 
2196b950aa88SAnkit Navik 	list_del(&entry->list);
2197b950aa88SAnkit Navik 	kfree(entry);
2198b950aa88SAnkit Navik 
2199b950aa88SAnkit Navik 	return 0;
2200b950aa88SAnkit Navik }
2201b950aa88SAnkit Navik 
22028baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
22038baaa403SAbhishek Pandit-Subedi 				   u8 type)
22048baaa403SAbhishek Pandit-Subedi {
22058baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
22068baaa403SAbhishek Pandit-Subedi 
22078baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY)) {
22088baaa403SAbhishek Pandit-Subedi 		hci_bdaddr_list_clear(list);
22098baaa403SAbhishek Pandit-Subedi 		return 0;
22108baaa403SAbhishek Pandit-Subedi 	}
22118baaa403SAbhishek Pandit-Subedi 
22128baaa403SAbhishek Pandit-Subedi 	entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type);
22138baaa403SAbhishek Pandit-Subedi 	if (!entry)
22148baaa403SAbhishek Pandit-Subedi 		return -ENOENT;
22158baaa403SAbhishek Pandit-Subedi 
22168baaa403SAbhishek Pandit-Subedi 	list_del(&entry->list);
22178baaa403SAbhishek Pandit-Subedi 	kfree(entry);
22188baaa403SAbhishek Pandit-Subedi 
22198baaa403SAbhishek Pandit-Subedi 	return 0;
22208baaa403SAbhishek Pandit-Subedi }
22218baaa403SAbhishek Pandit-Subedi 
222215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
222315819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
222415819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
222515819a70SAndre Guedes {
222615819a70SAndre Guedes 	struct hci_conn_params *params;
222715819a70SAndre Guedes 
222815819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
222915819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
223015819a70SAndre Guedes 		    params->addr_type == addr_type) {
223115819a70SAndre Guedes 			return params;
223215819a70SAndre Guedes 		}
223315819a70SAndre Guedes 	}
223415819a70SAndre Guedes 
223515819a70SAndre Guedes 	return NULL;
223615819a70SAndre Guedes }
223715819a70SAndre Guedes 
223815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
2239501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
22404b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
224115819a70SAndre Guedes {
2242912b42efSJohan Hedberg 	struct hci_conn_params *param;
224315819a70SAndre Guedes 
2244501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
2245912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
2246912b42efSJohan Hedberg 		    param->addr_type == addr_type)
2247912b42efSJohan Hedberg 			return param;
22484b10966fSMarcel Holtmann 	}
22494b10966fSMarcel Holtmann 
22504b10966fSMarcel Holtmann 	return NULL;
225115819a70SAndre Guedes }
225215819a70SAndre Guedes 
225315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
225451d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
225551d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
225615819a70SAndre Guedes {
225715819a70SAndre Guedes 	struct hci_conn_params *params;
225815819a70SAndre Guedes 
225915819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
2260cef952ceSAndre Guedes 	if (params)
226151d167c0SMarcel Holtmann 		return params;
226215819a70SAndre Guedes 
226315819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
226415819a70SAndre Guedes 	if (!params) {
22652064ee33SMarcel Holtmann 		bt_dev_err(hdev, "out of memory");
226651d167c0SMarcel Holtmann 		return NULL;
226715819a70SAndre Guedes 	}
226815819a70SAndre Guedes 
226915819a70SAndre Guedes 	bacpy(&params->addr, addr);
227015819a70SAndre Guedes 	params->addr_type = addr_type;
2271cef952ceSAndre Guedes 
2272cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
227393450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
2274cef952ceSAndre Guedes 
2275bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
2276bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
2277bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
2278bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
2279bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
2280bf5b3c8bSMarcel Holtmann 
2281bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
2282bf5b3c8bSMarcel Holtmann 
228351d167c0SMarcel Holtmann 	return params;
2284bf5b3c8bSMarcel Holtmann }
2285bf5b3c8bSMarcel Holtmann 
2286f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params)
2287f6c63249SJohan Hedberg {
2288f6c63249SJohan Hedberg 	if (params->conn) {
2289f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
2290f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
2291f6c63249SJohan Hedberg 	}
2292f6c63249SJohan Hedberg 
2293f6c63249SJohan Hedberg 	list_del(&params->action);
2294f6c63249SJohan Hedberg 	list_del(&params->list);
2295f6c63249SJohan Hedberg 	kfree(params);
2296f6c63249SJohan Hedberg }
2297f6c63249SJohan Hedberg 
229815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
229915819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
230015819a70SAndre Guedes {
230115819a70SAndre Guedes 	struct hci_conn_params *params;
230215819a70SAndre Guedes 
230315819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
230415819a70SAndre Guedes 	if (!params)
230515819a70SAndre Guedes 		return;
230615819a70SAndre Guedes 
2307f6c63249SJohan Hedberg 	hci_conn_params_free(params);
230815819a70SAndre Guedes 
23095bee2fd6SLuiz Augusto von Dentz 	hci_update_passive_scan(hdev);
231095305baaSJohan Hedberg 
231115819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
231215819a70SAndre Guedes }
231315819a70SAndre Guedes 
231415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
231555af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
231615819a70SAndre Guedes {
231715819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
231815819a70SAndre Guedes 
231915819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
232055af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
232155af49a8SJohan Hedberg 			continue;
2322f75113a2SJakub Pawlowski 
232391641b79SZheng Yongjun 		/* If trying to establish one time connection to disabled
2324f75113a2SJakub Pawlowski 		 * device, leave the params, but mark them as just once.
2325f75113a2SJakub Pawlowski 		 */
2326f75113a2SJakub Pawlowski 		if (params->explicit_connect) {
2327f75113a2SJakub Pawlowski 			params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
2328f75113a2SJakub Pawlowski 			continue;
2329f75113a2SJakub Pawlowski 		}
2330f75113a2SJakub Pawlowski 
233115819a70SAndre Guedes 		list_del(&params->list);
233215819a70SAndre Guedes 		kfree(params);
233315819a70SAndre Guedes 	}
233415819a70SAndre Guedes 
233555af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
233655af49a8SJohan Hedberg }
233755af49a8SJohan Hedberg 
233855af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
2339030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev)
234015819a70SAndre Guedes {
234115819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
234215819a70SAndre Guedes 
2343f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
2344f6c63249SJohan Hedberg 		hci_conn_params_free(params);
234515819a70SAndre Guedes 
234615819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
234715819a70SAndre Guedes }
234815819a70SAndre Guedes 
2349a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
2350a1f4c318SJohan Hedberg  *
2351a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
2352a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
2353a1f4c318SJohan Hedberg  * the static random address.
2354a1f4c318SJohan Hedberg  *
2355a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
2356a1f4c318SJohan Hedberg  * public address to use the static random address instead.
235750b5b952SMarcel Holtmann  *
235850b5b952SMarcel Holtmann  * In case BR/EDR has been disabled on a dual-mode controller and
235950b5b952SMarcel Holtmann  * userspace has configured a static address, then that address
236050b5b952SMarcel Holtmann  * becomes the identity address instead of the public BR/EDR address.
2361a1f4c318SJohan Hedberg  */
2362a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
2363a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
2364a1f4c318SJohan Hedberg {
2365b7cb93e5SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
236650b5b952SMarcel Holtmann 	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
2367d7a5a11dSMarcel Holtmann 	    (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
236850b5b952SMarcel Holtmann 	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
2369a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
2370a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
2371a1f4c318SJohan Hedberg 	} else {
2372a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
2373a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
2374a1f4c318SJohan Hedberg 	}
2375a1f4c318SJohan Hedberg }
2376a1f4c318SJohan Hedberg 
23770e995280SAbhishek Pandit-Subedi static void hci_suspend_clear_tasks(struct hci_dev *hdev)
23780e995280SAbhishek Pandit-Subedi {
23790e995280SAbhishek Pandit-Subedi 	int i;
23800e995280SAbhishek Pandit-Subedi 
23810e995280SAbhishek Pandit-Subedi 	for (i = 0; i < __SUSPEND_NUM_TASKS; i++)
23820e995280SAbhishek Pandit-Subedi 		clear_bit(i, hdev->suspend_tasks);
23830e995280SAbhishek Pandit-Subedi 
23840e995280SAbhishek Pandit-Subedi 	wake_up(&hdev->suspend_wait_q);
23850e995280SAbhishek Pandit-Subedi }
23860e995280SAbhishek Pandit-Subedi 
23879952d90eSAbhishek Pandit-Subedi static int hci_suspend_wait_event(struct hci_dev *hdev)
23889952d90eSAbhishek Pandit-Subedi {
23899952d90eSAbhishek Pandit-Subedi #define WAKE_COND                                                              \
23909952d90eSAbhishek Pandit-Subedi 	(find_first_bit(hdev->suspend_tasks, __SUSPEND_NUM_TASKS) ==           \
23919952d90eSAbhishek Pandit-Subedi 	 __SUSPEND_NUM_TASKS)
23929952d90eSAbhishek Pandit-Subedi 
23939952d90eSAbhishek Pandit-Subedi 	int i;
23949952d90eSAbhishek Pandit-Subedi 	int ret = wait_event_timeout(hdev->suspend_wait_q,
23959952d90eSAbhishek Pandit-Subedi 				     WAKE_COND, SUSPEND_NOTIFIER_TIMEOUT);
23969952d90eSAbhishek Pandit-Subedi 
23979952d90eSAbhishek Pandit-Subedi 	if (ret == 0) {
2398a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Timed out waiting for suspend events");
23999952d90eSAbhishek Pandit-Subedi 		for (i = 0; i < __SUSPEND_NUM_TASKS; ++i) {
24009952d90eSAbhishek Pandit-Subedi 			if (test_bit(i, hdev->suspend_tasks))
2401a9ec8423SAbhishek Pandit-Subedi 				bt_dev_err(hdev, "Suspend timeout bit: %d", i);
24029952d90eSAbhishek Pandit-Subedi 			clear_bit(i, hdev->suspend_tasks);
24039952d90eSAbhishek Pandit-Subedi 		}
24049952d90eSAbhishek Pandit-Subedi 
24059952d90eSAbhishek Pandit-Subedi 		ret = -ETIMEDOUT;
24069952d90eSAbhishek Pandit-Subedi 	} else {
24079952d90eSAbhishek Pandit-Subedi 		ret = 0;
24089952d90eSAbhishek Pandit-Subedi 	}
24099952d90eSAbhishek Pandit-Subedi 
24109952d90eSAbhishek Pandit-Subedi 	return ret;
24119952d90eSAbhishek Pandit-Subedi }
24129952d90eSAbhishek Pandit-Subedi 
24139952d90eSAbhishek Pandit-Subedi static void hci_prepare_suspend(struct work_struct *work)
24149952d90eSAbhishek Pandit-Subedi {
24159952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
24169952d90eSAbhishek Pandit-Subedi 		container_of(work, struct hci_dev, suspend_prepare);
24179952d90eSAbhishek Pandit-Subedi 
24189952d90eSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
24199952d90eSAbhishek Pandit-Subedi 	hci_req_prepare_suspend(hdev, hdev->suspend_state_next);
24209952d90eSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
24219952d90eSAbhishek Pandit-Subedi }
24229952d90eSAbhishek Pandit-Subedi 
24238731840aSAbhishek Pandit-Subedi static int hci_change_suspend_state(struct hci_dev *hdev,
24248731840aSAbhishek Pandit-Subedi 				    enum suspended_state next)
24258731840aSAbhishek Pandit-Subedi {
24268731840aSAbhishek Pandit-Subedi 	hdev->suspend_state_next = next;
24278731840aSAbhishek Pandit-Subedi 	set_bit(SUSPEND_PREPARE_NOTIFIER, hdev->suspend_tasks);
24288731840aSAbhishek Pandit-Subedi 	queue_work(hdev->req_workqueue, &hdev->suspend_prepare);
24298731840aSAbhishek Pandit-Subedi 	return hci_suspend_wait_event(hdev);
24308731840aSAbhishek Pandit-Subedi }
24318731840aSAbhishek Pandit-Subedi 
24322f20216cSAbhishek Pandit-Subedi static void hci_clear_wake_reason(struct hci_dev *hdev)
24332f20216cSAbhishek Pandit-Subedi {
24342f20216cSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
24352f20216cSAbhishek Pandit-Subedi 
24362f20216cSAbhishek Pandit-Subedi 	hdev->wake_reason = 0;
24372f20216cSAbhishek Pandit-Subedi 	bacpy(&hdev->wake_addr, BDADDR_ANY);
24382f20216cSAbhishek Pandit-Subedi 	hdev->wake_addr_type = 0;
24392f20216cSAbhishek Pandit-Subedi 
24402f20216cSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
24412f20216cSAbhishek Pandit-Subedi }
24422f20216cSAbhishek Pandit-Subedi 
24439952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
24449952d90eSAbhishek Pandit-Subedi 				void *data)
24459952d90eSAbhishek Pandit-Subedi {
24469952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
24479952d90eSAbhishek Pandit-Subedi 		container_of(nb, struct hci_dev, suspend_notifier);
24489952d90eSAbhishek Pandit-Subedi 	int ret = 0;
24499952d90eSAbhishek Pandit-Subedi 
2450e1b77d68SLuiz Augusto von Dentz 	if (action == PM_SUSPEND_PREPARE)
2451e1b77d68SLuiz Augusto von Dentz 		ret = hci_suspend_dev(hdev);
2452e1b77d68SLuiz Augusto von Dentz 	else if (action == PM_POST_SUSPEND)
2453e1b77d68SLuiz Augusto von Dentz 		ret = hci_resume_dev(hdev);
24549952d90eSAbhishek Pandit-Subedi 
2455a9ec8423SAbhishek Pandit-Subedi 	if (ret)
2456a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
2457a9ec8423SAbhishek Pandit-Subedi 			   action, ret);
2458a9ec8423SAbhishek Pandit-Subedi 
245924b06572SMax Chou 	return NOTIFY_DONE;
24609952d90eSAbhishek Pandit-Subedi }
24618731840aSAbhishek Pandit-Subedi 
24629be0dab7SDavid Herrmann /* Alloc HCI device */
24636ec56613STedd Ho-Jeong An struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
24649be0dab7SDavid Herrmann {
24659be0dab7SDavid Herrmann 	struct hci_dev *hdev;
24666ec56613STedd Ho-Jeong An 	unsigned int alloc_size;
24679be0dab7SDavid Herrmann 
24686ec56613STedd Ho-Jeong An 	alloc_size = sizeof(*hdev);
24696ec56613STedd Ho-Jeong An 	if (sizeof_priv) {
24706ec56613STedd Ho-Jeong An 		/* Fixme: May need ALIGN-ment? */
24716ec56613STedd Ho-Jeong An 		alloc_size += sizeof_priv;
24726ec56613STedd Ho-Jeong An 	}
24736ec56613STedd Ho-Jeong An 
24746ec56613STedd Ho-Jeong An 	hdev = kzalloc(alloc_size, GFP_KERNEL);
24759be0dab7SDavid Herrmann 	if (!hdev)
24769be0dab7SDavid Herrmann 		return NULL;
24779be0dab7SDavid Herrmann 
2478b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2479b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
2480b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
2481b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
2482b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
248396c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
2484bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2485bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2486d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
2487d2609b34SFlorian Grandel 	hdev->cur_adv_instance = 0x00;
24885d900e46SFlorian Grandel 	hdev->adv_instance_timeout = 0;
2489b1b813d4SDavid Herrmann 
2490c4f1f408SHoward Chung 	hdev->advmon_allowlist_duration = 300;
2491c4f1f408SHoward Chung 	hdev->advmon_no_filter_duration = 500;
249280af16a3SHoward Chung 	hdev->enable_advmon_interleave_scan = 0x00;	/* Default to disable */
2493c4f1f408SHoward Chung 
2494b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
2495b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
2496b1b813d4SDavid Herrmann 
24973f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
2498628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
2499628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
2500bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
2501bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
250210873f99SAlain Michaud 	hdev->le_scan_int_suspend = 0x0400;
250310873f99SAlain Michaud 	hdev->le_scan_window_suspend = 0x0012;
250410873f99SAlain Michaud 	hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT;
250510873f99SAlain Michaud 	hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN;
2506ba29d036SMarcel Holtmann 	hdev->le_scan_int_adv_monitor = 0x0060;
2507ba29d036SMarcel Holtmann 	hdev->le_scan_window_adv_monitor = 0x0030;
250810873f99SAlain Michaud 	hdev->le_scan_int_connect = 0x0060;
250910873f99SAlain Michaud 	hdev->le_scan_window_connect = 0x0060;
2510b48c3b59SJonas Holmberg 	hdev->le_conn_min_interval = 0x0018;
2511b48c3b59SJonas Holmberg 	hdev->le_conn_max_interval = 0x0028;
251204fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
251304fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
2514a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = 0x001b;
2515a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = 0x0148;
2516a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = 0x001b;
2517a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = 0x0148;
2518a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = 0x001b;
2519a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = 0x0148;
252030d65e08SMatias Karhumaa 	hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE;
252130d65e08SMatias Karhumaa 	hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE;
25226decb5b4SJaganath Kanakkassery 	hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
25236decb5b4SJaganath Kanakkassery 	hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
25241d0fac2cSLuiz Augusto von Dentz 	hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES;
252510873f99SAlain Michaud 	hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION;
252649b020c1SAlain Michaud 	hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT;
25277c395ea5SDaniel Winkler 	hdev->min_le_tx_power = HCI_TX_POWER_INVALID;
25287c395ea5SDaniel Winkler 	hdev->max_le_tx_power = HCI_TX_POWER_INVALID;
2529bef64738SMarcel Holtmann 
2530d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
2531b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
253231ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
253331ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
2534302975cbSSpoorthi Ravishankar Koppad 	hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT;
253558a96fc3SMarcel Holtmann 	hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE;
2536d6bfd59cSJohan Hedberg 
253710873f99SAlain Michaud 	/* default 1.28 sec page scan */
253810873f99SAlain Michaud 	hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD;
253910873f99SAlain Michaud 	hdev->def_page_scan_int = 0x0800;
254010873f99SAlain Michaud 	hdev->def_page_scan_window = 0x0012;
254110873f99SAlain Michaud 
2542b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
2543b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
2544b1b813d4SDavid Herrmann 
2545b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
25463d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->reject_list);
25473d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->accept_list);
2548b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
2549b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
2550b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
2551970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
2552b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
25533d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->le_accept_list);
2554cfdb0c2dSAnkit Navik 	INIT_LIST_HEAD(&hdev->le_resolv_list);
255515819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
255677a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
255766f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
25586b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
2559d2609b34SFlorian Grandel 	INIT_LIST_HEAD(&hdev->adv_instances);
2560600a8749SAlain Michaud 	INIT_LIST_HEAD(&hdev->blocked_keys);
2561b1b813d4SDavid Herrmann 
25628961987fSKiran K 	INIT_LIST_HEAD(&hdev->local_codecs);
2563b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2564b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2565b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2566b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2567c7741d16SMarcel Holtmann 	INIT_WORK(&hdev->error_reset, hci_error_reset);
25689952d90eSAbhishek Pandit-Subedi 	INIT_WORK(&hdev->suspend_prepare, hci_prepare_suspend);
2569b1b813d4SDavid Herrmann 
25706a98e383SMarcel Holtmann 	hci_cmd_sync_init(hdev);
25716a98e383SMarcel Holtmann 
2572b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2573b1b813d4SDavid Herrmann 
2574b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2575b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2576b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2577b1b813d4SDavid Herrmann 
2578b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
25799952d90eSAbhishek Pandit-Subedi 	init_waitqueue_head(&hdev->suspend_wait_q);
2580b1b813d4SDavid Herrmann 
258165cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
2582de75cd0dSManish Mandlik 	INIT_DELAYED_WORK(&hdev->ncmd_timer, hci_ncmd_timeout);
2583b1b813d4SDavid Herrmann 
25845fc16cc4SJohan Hedberg 	hci_request_setup(hdev);
25855fc16cc4SJohan Hedberg 
2586b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2587b1b813d4SDavid Herrmann 	discovery_init(hdev);
25889be0dab7SDavid Herrmann 
25899be0dab7SDavid Herrmann 	return hdev;
25909be0dab7SDavid Herrmann }
25916ec56613STedd Ho-Jeong An EXPORT_SYMBOL(hci_alloc_dev_priv);
25929be0dab7SDavid Herrmann 
25939be0dab7SDavid Herrmann /* Free HCI device */
25949be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
25959be0dab7SDavid Herrmann {
25969be0dab7SDavid Herrmann 	/* will free via device release */
25979be0dab7SDavid Herrmann 	put_device(&hdev->dev);
25989be0dab7SDavid Herrmann }
25999be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
26009be0dab7SDavid Herrmann 
26011da177e4SLinus Torvalds /* Register HCI device */
26021da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
26031da177e4SLinus Torvalds {
2604b1b813d4SDavid Herrmann 	int id, error;
26051da177e4SLinus Torvalds 
260674292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
26071da177e4SLinus Torvalds 		return -EINVAL;
26081da177e4SLinus Torvalds 
260908add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
261008add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
261108add513SMat Martineau 	 */
26123df92b31SSasha Levin 	switch (hdev->dev_type) {
2613ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
26143df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
26151da177e4SLinus Torvalds 		break;
26163df92b31SSasha Levin 	case HCI_AMP:
26173df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
26183df92b31SSasha Levin 		break;
26193df92b31SSasha Levin 	default:
26203df92b31SSasha Levin 		return -EINVAL;
26211da177e4SLinus Torvalds 	}
26221da177e4SLinus Torvalds 
26233df92b31SSasha Levin 	if (id < 0)
26243df92b31SSasha Levin 		return id;
26253df92b31SSasha Levin 
26261da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
26271da177e4SLinus Torvalds 	hdev->id = id;
26282d8b3a11SAndrei Emeltchenko 
26292d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
26302d8b3a11SAndrei Emeltchenko 
263129e2dd0dSTejun Heo 	hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name);
263233ca954dSDavid Herrmann 	if (!hdev->workqueue) {
263333ca954dSDavid Herrmann 		error = -ENOMEM;
263433ca954dSDavid Herrmann 		goto err;
263533ca954dSDavid Herrmann 	}
2636f48fd9c8SMarcel Holtmann 
263729e2dd0dSTejun Heo 	hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI,
263829e2dd0dSTejun Heo 						      hdev->name);
26396ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
26406ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
26416ead1bbcSJohan Hedberg 		error = -ENOMEM;
26426ead1bbcSJohan Hedberg 		goto err;
26436ead1bbcSJohan Hedberg 	}
26446ead1bbcSJohan Hedberg 
26450153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
26460153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
26470153e2ecSMarcel Holtmann 
2648bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
2649bdc3e0f1SMarcel 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 
268905fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_REG);
2690dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
26911da177e4SLinus Torvalds 
2692219991e6SHans de Goede 	if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
26939952d90eSAbhishek Pandit-Subedi 		hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
26949952d90eSAbhishek Pandit-Subedi 		error = register_pm_notifier(&hdev->suspend_notifier);
26959952d90eSAbhishek Pandit-Subedi 		if (error)
26969952d90eSAbhishek Pandit-Subedi 			goto err_wqueue;
2697219991e6SHans de Goede 	}
26989952d90eSAbhishek Pandit-Subedi 
269919202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2700fbe96d6fSMarcel Holtmann 
2701e5e1e7fdSMiao-chen Chou 	idr_init(&hdev->adv_monitors_idr);
27025031ffccSMiao-chen Chou 	msft_register(hdev);
2703e5e1e7fdSMiao-chen Chou 
27041da177e4SLinus Torvalds 	return id;
2705f48fd9c8SMarcel Holtmann 
270633ca954dSDavid Herrmann err_wqueue:
27075a4bb6a8SWei Yongjun 	debugfs_remove_recursive(hdev->debugfs);
270833ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
27096ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
271033ca954dSDavid Herrmann err:
27113df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
2712f48fd9c8SMarcel Holtmann 
271333ca954dSDavid Herrmann 	return error;
27141da177e4SLinus Torvalds }
27151da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
27161da177e4SLinus Torvalds 
27171da177e4SLinus Torvalds /* Unregister HCI device */
271859735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
27191da177e4SLinus Torvalds {
2720c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
27211da177e4SLinus Torvalds 
2722a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_UNREGISTER);
272394324962SJohan Hovold 
2724f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
27251da177e4SLinus Torvalds 	list_del(&hdev->list);
2726f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
27271da177e4SLinus Torvalds 
2728b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
2729b9b5ef18SGustavo Padovan 
27306a98e383SMarcel Holtmann 	hci_cmd_sync_clear(hdev);
27316a98e383SMarcel Holtmann 
2732219991e6SHans de Goede 	if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
27330e995280SAbhishek Pandit-Subedi 		hci_suspend_clear_tasks(hdev);
27349952d90eSAbhishek Pandit-Subedi 		unregister_pm_notifier(&hdev->suspend_notifier);
27354e8c36c3SAbhishek Pandit-Subedi 		cancel_work_sync(&hdev->suspend_prepare);
2736219991e6SHans de Goede 	}
27374e8c36c3SAbhishek Pandit-Subedi 
27385031ffccSMiao-chen Chou 	msft_unregister(hdev);
27395031ffccSMiao-chen Chou 
27404e8c36c3SAbhishek Pandit-Subedi 	hci_dev_do_close(hdev);
27419952d90eSAbhishek Pandit-Subedi 
2742ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2743d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_SETUP) &&
2744d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
274509fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2746744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
274709fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
274856e5cb86SJohan Hedberg 	}
2749ab81cbf9SJohan Hedberg 
27502e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
27512e58ef3eSJohan Hedberg 	 * pending list */
27522e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
27532e58ef3eSJohan Hedberg 
275405fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_UNREG);
27551da177e4SLinus Torvalds 
2756611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2757611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2758611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2759611b30f7SMarcel Holtmann 	}
2760611b30f7SMarcel Holtmann 
2761bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
2762e61fbee7SDavid S. Miller 	/* Actual cleanup is deferred until hci_release_dev(). */
2763e0448092STetsuo Handa 	hci_dev_put(hdev);
2764e0448092STetsuo Handa }
2765e0448092STetsuo Handa EXPORT_SYMBOL(hci_unregister_dev);
2766147e2d59SDave Young 
276758ce6d5bSTetsuo Handa /* Release HCI device */
276858ce6d5bSTetsuo Handa void hci_release_dev(struct hci_dev *hdev)
2769e0448092STetsuo Handa {
27700153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
27715177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
27725177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
27730153e2ecSMarcel Holtmann 
2774f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
27756ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2776f48fd9c8SMarcel Holtmann 
277709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
27783d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->reject_list);
27793d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->accept_list);
27802aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
278155ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2782b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
2783970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
27842763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
2785d2609b34SFlorian Grandel 	hci_adv_instances_clear(hdev);
2786e5e1e7fdSMiao-chen Chou 	hci_adv_monitors_clear(hdev);
27873d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
2788cfdb0c2dSAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
2789373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
279022078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
2791600a8749SAlain Michaud 	hci_blocked_keys_clear(hdev);
279209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2793e2e0cacbSJohan Hedberg 
2794e0448092STetsuo Handa 	ida_simple_remove(&hci_index_ida, hdev->id);
279558ce6d5bSTetsuo Handa 	kfree(hdev);
27961da177e4SLinus Torvalds }
279758ce6d5bSTetsuo Handa EXPORT_SYMBOL(hci_release_dev);
27981da177e4SLinus Torvalds 
27991da177e4SLinus Torvalds /* Suspend HCI device */
28001da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
28011da177e4SLinus Torvalds {
2802e1b77d68SLuiz Augusto von Dentz 	int ret;
2803e1b77d68SLuiz Augusto von Dentz 	u8 state = BT_RUNNING;
2804e1b77d68SLuiz Augusto von Dentz 
2805e1b77d68SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
2806e1b77d68SLuiz Augusto von Dentz 
2807e1b77d68SLuiz Augusto von Dentz 	/* Suspend should only act on when powered. */
2808e1b77d68SLuiz Augusto von Dentz 	if (!hdev_is_powered(hdev) ||
2809e1b77d68SLuiz Augusto von Dentz 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
28101da177e4SLinus Torvalds 		return 0;
2811e1b77d68SLuiz Augusto von Dentz 
2812e1b77d68SLuiz Augusto von Dentz 	/* If powering down, wait for completion. */
2813e1b77d68SLuiz Augusto von Dentz 	if (mgmt_powering_down(hdev)) {
2814e1b77d68SLuiz Augusto von Dentz 		set_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks);
2815e1b77d68SLuiz Augusto von Dentz 		ret = hci_suspend_wait_event(hdev);
2816e1b77d68SLuiz Augusto von Dentz 		if (ret)
2817e1b77d68SLuiz Augusto von Dentz 			goto done;
2818e1b77d68SLuiz Augusto von Dentz 	}
2819e1b77d68SLuiz Augusto von Dentz 
2820e1b77d68SLuiz Augusto von Dentz 	/* Suspend consists of two actions:
2821e1b77d68SLuiz Augusto von Dentz 	 *  - First, disconnect everything and make the controller not
2822e1b77d68SLuiz Augusto von Dentz 	 *    connectable (disabling scanning)
2823e1b77d68SLuiz Augusto von Dentz 	 *  - Second, program event filter/accept list and enable scan
2824e1b77d68SLuiz Augusto von Dentz 	 */
2825e1b77d68SLuiz Augusto von Dentz 	ret = hci_change_suspend_state(hdev, BT_SUSPEND_DISCONNECT);
28264539ca67SLuiz Augusto von Dentz 	if (ret)
28274539ca67SLuiz Augusto von Dentz 		goto clear;
28284539ca67SLuiz Augusto von Dentz 
2829e1b77d68SLuiz Augusto von Dentz 	state = BT_SUSPEND_DISCONNECT;
2830e1b77d68SLuiz Augusto von Dentz 
28314539ca67SLuiz Augusto von Dentz 	/* Only configure accept list if device may wakeup. */
28324539ca67SLuiz Augusto von Dentz 	if (hdev->wakeup && hdev->wakeup(hdev)) {
2833e1b77d68SLuiz Augusto von Dentz 		ret = hci_change_suspend_state(hdev, BT_SUSPEND_CONFIGURE_WAKE);
2834e1b77d68SLuiz Augusto von Dentz 		if (!ret)
2835e1b77d68SLuiz Augusto von Dentz 			state = BT_SUSPEND_CONFIGURE_WAKE;
2836e1b77d68SLuiz Augusto von Dentz 	}
2837e1b77d68SLuiz Augusto von Dentz 
28384539ca67SLuiz Augusto von Dentz clear:
2839e1b77d68SLuiz Augusto von Dentz 	hci_clear_wake_reason(hdev);
2840e1b77d68SLuiz Augusto von Dentz 	mgmt_suspending(hdev, state);
2841e1b77d68SLuiz Augusto von Dentz 
2842e1b77d68SLuiz Augusto von Dentz done:
2843e1b77d68SLuiz Augusto von Dentz 	/* We always allow suspend even if suspend preparation failed and
2844e1b77d68SLuiz Augusto von Dentz 	 * attempt to recover in resume.
2845e1b77d68SLuiz Augusto von Dentz 	 */
2846e1b77d68SLuiz Augusto von Dentz 	hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
2847e1b77d68SLuiz Augusto von Dentz 	return ret;
28481da177e4SLinus Torvalds }
28491da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
28501da177e4SLinus Torvalds 
28511da177e4SLinus Torvalds /* Resume HCI device */
28521da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
28531da177e4SLinus Torvalds {
2854e1b77d68SLuiz Augusto von Dentz 	int ret;
2855e1b77d68SLuiz Augusto von Dentz 
2856e1b77d68SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
2857e1b77d68SLuiz Augusto von Dentz 
2858e1b77d68SLuiz Augusto von Dentz 	/* Resume should only act on when powered. */
2859e1b77d68SLuiz Augusto von Dentz 	if (!hdev_is_powered(hdev) ||
2860e1b77d68SLuiz Augusto von Dentz 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
28611da177e4SLinus Torvalds 		return 0;
2862e1b77d68SLuiz Augusto von Dentz 
2863e1b77d68SLuiz Augusto von Dentz 	/* If powering down don't attempt to resume */
2864e1b77d68SLuiz Augusto von Dentz 	if (mgmt_powering_down(hdev))
2865e1b77d68SLuiz Augusto von Dentz 		return 0;
2866e1b77d68SLuiz Augusto von Dentz 
2867e1b77d68SLuiz Augusto von Dentz 	ret = hci_change_suspend_state(hdev, BT_RUNNING);
2868e1b77d68SLuiz Augusto von Dentz 
2869e1b77d68SLuiz Augusto von Dentz 	mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr,
2870e1b77d68SLuiz Augusto von Dentz 			      hdev->wake_addr_type);
2871e1b77d68SLuiz Augusto von Dentz 
2872e1b77d68SLuiz Augusto von Dentz 	hci_sock_dev_event(hdev, HCI_DEV_RESUME);
2873e1b77d68SLuiz Augusto von Dentz 	return ret;
28741da177e4SLinus Torvalds }
28751da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
28761da177e4SLinus Torvalds 
287775e0569fSMarcel Holtmann /* Reset HCI device */
287875e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
287975e0569fSMarcel Holtmann {
28801e4b6e91SColin Ian King 	static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
288175e0569fSMarcel Holtmann 	struct sk_buff *skb;
288275e0569fSMarcel Holtmann 
288375e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
288475e0569fSMarcel Holtmann 	if (!skb)
288575e0569fSMarcel Holtmann 		return -ENOMEM;
288675e0569fSMarcel Holtmann 
2887d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
288859ae1d12SJohannes Berg 	skb_put_data(skb, hw_err, 3);
288975e0569fSMarcel Holtmann 
2890de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Injecting HCI hardware error event");
2891de75cd0dSManish Mandlik 
289275e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
289375e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
289475e0569fSMarcel Holtmann }
289575e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
289675e0569fSMarcel Holtmann 
289776bca880SMarcel Holtmann /* Receive frame from HCI drivers */
2898e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
289976bca880SMarcel Holtmann {
290076bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
290176bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
290276bca880SMarcel Holtmann 		kfree_skb(skb);
290376bca880SMarcel Holtmann 		return -ENXIO;
290476bca880SMarcel Holtmann 	}
290576bca880SMarcel Holtmann 
2906d79f34e3SMarcel Holtmann 	if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT &&
2907d79f34e3SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
2908cc974003SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT &&
2909cc974003SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) {
2910fe806dceSMarcel Holtmann 		kfree_skb(skb);
2911fe806dceSMarcel Holtmann 		return -EINVAL;
2912fe806dceSMarcel Holtmann 	}
2913fe806dceSMarcel Holtmann 
2914d82603c6SJorrit Schippers 	/* Incoming skb */
291576bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
291676bca880SMarcel Holtmann 
291776bca880SMarcel Holtmann 	/* Time stamp */
291876bca880SMarcel Holtmann 	__net_timestamp(skb);
291976bca880SMarcel Holtmann 
292076bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2921b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2922c78ae283SMarcel Holtmann 
292376bca880SMarcel Holtmann 	return 0;
292476bca880SMarcel Holtmann }
292576bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
292676bca880SMarcel Holtmann 
2927e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */
2928e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
2929e875ff84SMarcel Holtmann {
2930581d6fd6SMarcel Holtmann 	/* Mark as diagnostic packet */
2931d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_DIAG_PKT;
2932581d6fd6SMarcel Holtmann 
2933e875ff84SMarcel Holtmann 	/* Time stamp */
2934e875ff84SMarcel Holtmann 	__net_timestamp(skb);
2935e875ff84SMarcel Holtmann 
2936581d6fd6SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2937581d6fd6SMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2938e875ff84SMarcel Holtmann 
2939e875ff84SMarcel Holtmann 	return 0;
2940e875ff84SMarcel Holtmann }
2941e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag);
2942e875ff84SMarcel Holtmann 
29435177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...)
29445177a838SMarcel Holtmann {
29455177a838SMarcel Holtmann 	va_list vargs;
29465177a838SMarcel Holtmann 
29475177a838SMarcel Holtmann 	va_start(vargs, fmt);
29485177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
29495177a838SMarcel Holtmann 	hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
29505177a838SMarcel Holtmann 	va_end(vargs);
29515177a838SMarcel Holtmann }
29525177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info);
29535177a838SMarcel Holtmann 
29545177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...)
29555177a838SMarcel Holtmann {
29565177a838SMarcel Holtmann 	va_list vargs;
29575177a838SMarcel Holtmann 
29585177a838SMarcel Holtmann 	va_start(vargs, fmt);
29595177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
29605177a838SMarcel Holtmann 	hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
29615177a838SMarcel Holtmann 	va_end(vargs);
29625177a838SMarcel Holtmann }
29635177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info);
29645177a838SMarcel Holtmann 
29651da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
29661da177e4SLinus Torvalds 
29671da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
29681da177e4SLinus Torvalds {
29691da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
29701da177e4SLinus Torvalds 
2971fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
297200629e0fSJohan Hedberg 	list_add_tail(&cb->list, &hci_cb_list);
2973fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
29741da177e4SLinus Torvalds 
29751da177e4SLinus Torvalds 	return 0;
29761da177e4SLinus Torvalds }
29771da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
29781da177e4SLinus Torvalds 
29791da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
29801da177e4SLinus Torvalds {
29811da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
29821da177e4SLinus Torvalds 
2983fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
29841da177e4SLinus Torvalds 	list_del(&cb->list);
2985fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
29861da177e4SLinus Torvalds 
29871da177e4SLinus Torvalds 	return 0;
29881da177e4SLinus Torvalds }
29891da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
29901da177e4SLinus Torvalds 
299151086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
29921da177e4SLinus Torvalds {
2993cdc52faaSMarcel Holtmann 	int err;
2994cdc52faaSMarcel Holtmann 
2995d79f34e3SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb),
2996d79f34e3SMarcel Holtmann 	       skb->len);
29971da177e4SLinus Torvalds 
29981da177e4SLinus Torvalds 	/* Time stamp */
2999a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
30001da177e4SLinus Torvalds 
3001cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
3002cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
3003cd82e61cSMarcel Holtmann 
3004cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
3005cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
3006470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
30071da177e4SLinus Torvalds 	}
30081da177e4SLinus Torvalds 
30091da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
30101da177e4SLinus Torvalds 	skb_orphan(skb);
30111da177e4SLinus Torvalds 
301273d0d3c8SMarcel Holtmann 	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
301373d0d3c8SMarcel Holtmann 		kfree_skb(skb);
301473d0d3c8SMarcel Holtmann 		return;
301573d0d3c8SMarcel Holtmann 	}
301673d0d3c8SMarcel Holtmann 
3017cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
3018cdc52faaSMarcel Holtmann 	if (err < 0) {
30192064ee33SMarcel Holtmann 		bt_dev_err(hdev, "sending frame failed (%d)", err);
3020cdc52faaSMarcel Holtmann 		kfree_skb(skb);
3021cdc52faaSMarcel Holtmann 	}
30221da177e4SLinus Torvalds }
30231da177e4SLinus Torvalds 
30241ca3a9d0SJohan Hedberg /* Send HCI command */
302507dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
302607dc93ddSJohan Hedberg 		 const void *param)
30271ca3a9d0SJohan Hedberg {
30281ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
30291ca3a9d0SJohan Hedberg 
30301ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
30311ca3a9d0SJohan Hedberg 
30321ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
30331ca3a9d0SJohan Hedberg 	if (!skb) {
30342064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no memory for command");
30351ca3a9d0SJohan Hedberg 		return -ENOMEM;
30361ca3a9d0SJohan Hedberg 	}
30371ca3a9d0SJohan Hedberg 
303849c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
303911714b3dSJohan Hedberg 	 * single-command requests.
304011714b3dSJohan Hedberg 	 */
304144d27137SJohan Hedberg 	bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
304211714b3dSJohan Hedberg 
30431da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
3044c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
30451da177e4SLinus Torvalds 
30461da177e4SLinus Torvalds 	return 0;
30471da177e4SLinus Torvalds }
30481da177e4SLinus Torvalds 
3049d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
3050d6ee6ad7SLoic Poulain 		   const void *param)
3051d6ee6ad7SLoic Poulain {
3052d6ee6ad7SLoic Poulain 	struct sk_buff *skb;
3053d6ee6ad7SLoic Poulain 
3054d6ee6ad7SLoic Poulain 	if (hci_opcode_ogf(opcode) != 0x3f) {
3055d6ee6ad7SLoic Poulain 		/* A controller receiving a command shall respond with either
3056d6ee6ad7SLoic Poulain 		 * a Command Status Event or a Command Complete Event.
3057d6ee6ad7SLoic Poulain 		 * Therefore, all standard HCI commands must be sent via the
3058d6ee6ad7SLoic Poulain 		 * standard API, using hci_send_cmd or hci_cmd_sync helpers.
3059d6ee6ad7SLoic Poulain 		 * Some vendors do not comply with this rule for vendor-specific
3060d6ee6ad7SLoic Poulain 		 * commands and do not return any event. We want to support
3061d6ee6ad7SLoic Poulain 		 * unresponded commands for such cases only.
3062d6ee6ad7SLoic Poulain 		 */
3063d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "unresponded command not supported");
3064d6ee6ad7SLoic Poulain 		return -EINVAL;
3065d6ee6ad7SLoic Poulain 	}
3066d6ee6ad7SLoic Poulain 
3067d6ee6ad7SLoic Poulain 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
3068d6ee6ad7SLoic Poulain 	if (!skb) {
3069d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)",
3070d6ee6ad7SLoic Poulain 			   opcode);
3071d6ee6ad7SLoic Poulain 		return -ENOMEM;
3072d6ee6ad7SLoic Poulain 	}
3073d6ee6ad7SLoic Poulain 
3074d6ee6ad7SLoic Poulain 	hci_send_frame(hdev, skb);
3075d6ee6ad7SLoic Poulain 
3076d6ee6ad7SLoic Poulain 	return 0;
3077d6ee6ad7SLoic Poulain }
3078d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send);
3079d6ee6ad7SLoic Poulain 
30801da177e4SLinus Torvalds /* Get data from the previously sent command */
3081a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
30821da177e4SLinus Torvalds {
30831da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
30841da177e4SLinus Torvalds 
30851da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
30861da177e4SLinus Torvalds 		return NULL;
30871da177e4SLinus Torvalds 
30881da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
30891da177e4SLinus Torvalds 
3090a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
30911da177e4SLinus Torvalds 		return NULL;
30921da177e4SLinus Torvalds 
3093f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
30941da177e4SLinus Torvalds 
30951da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
30961da177e4SLinus Torvalds }
30971da177e4SLinus Torvalds 
30981da177e4SLinus Torvalds /* Send ACL data */
30991da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
31001da177e4SLinus Torvalds {
31011da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
31021da177e4SLinus Torvalds 	int len = skb->len;
31031da177e4SLinus Torvalds 
3104badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3105badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
31069c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
3107aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3108aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
31091da177e4SLinus Torvalds }
31101da177e4SLinus Torvalds 
3111ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
311273d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
31131da177e4SLinus Torvalds {
3114ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
31151da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
31161da177e4SLinus Torvalds 	struct sk_buff *list;
31171da177e4SLinus Torvalds 
3118087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3119087bfd99SGustavo Padovan 	skb->data_len = 0;
3120087bfd99SGustavo Padovan 
3121d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3122204a6e54SAndrei Emeltchenko 
3123204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
3124ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
3125087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
3126204a6e54SAndrei Emeltchenko 		break;
3127204a6e54SAndrei Emeltchenko 	case HCI_AMP:
3128204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
3129204a6e54SAndrei Emeltchenko 		break;
3130204a6e54SAndrei Emeltchenko 	default:
31312064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type);
3132204a6e54SAndrei Emeltchenko 		return;
3133204a6e54SAndrei Emeltchenko 	}
3134087bfd99SGustavo Padovan 
313570f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
313670f23020SAndrei Emeltchenko 	if (!list) {
31371da177e4SLinus Torvalds 		/* Non fragmented */
31381da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
31391da177e4SLinus Torvalds 
314073d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
31411da177e4SLinus Torvalds 	} else {
31421da177e4SLinus Torvalds 		/* Fragmented */
31431da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
31441da177e4SLinus Torvalds 
31451da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
31461da177e4SLinus Torvalds 
31479cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
31489cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
31499cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
31509cfd5a23SJukka Rissanen 		 * deadlocks.
31519cfd5a23SJukka Rissanen 		 */
31529cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
31531da177e4SLinus Torvalds 
315473d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3155e702112fSAndrei Emeltchenko 
3156e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3157e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
31581da177e4SLinus Torvalds 		do {
31591da177e4SLinus Torvalds 			skb = list; list = list->next;
31601da177e4SLinus Torvalds 
3161d79f34e3SMarcel Holtmann 			hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3162e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
31631da177e4SLinus Torvalds 
31641da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
31651da177e4SLinus Torvalds 
316673d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
31671da177e4SLinus Torvalds 		} while (list);
31681da177e4SLinus Torvalds 
31699cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
31701da177e4SLinus Torvalds 	}
317173d80debSLuiz Augusto von Dentz }
317273d80debSLuiz Augusto von Dentz 
317373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
317473d80debSLuiz Augusto von Dentz {
3175ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
317673d80debSLuiz Augusto von Dentz 
3177f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
317873d80debSLuiz Augusto von Dentz 
3179ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
31801da177e4SLinus Torvalds 
31813eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
31821da177e4SLinus Torvalds }
31831da177e4SLinus Torvalds 
31841da177e4SLinus Torvalds /* Send SCO data */
31850d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
31861da177e4SLinus Torvalds {
31871da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
31881da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
31891da177e4SLinus Torvalds 
31901da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
31911da177e4SLinus Torvalds 
3192aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
31931da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
31941da177e4SLinus Torvalds 
3195badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3196badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
31979c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
31981da177e4SLinus Torvalds 
3199d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
3200c78ae283SMarcel Holtmann 
32011da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
32023eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
32031da177e4SLinus Torvalds }
32041da177e4SLinus Torvalds 
32051da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
32061da177e4SLinus Torvalds 
32071da177e4SLinus Torvalds /* HCI Connection scheduler */
32086039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3209a8c5fb1aSGustavo Padovan 				     int *quote)
32101da177e4SLinus Torvalds {
32111da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
32128035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
3213abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
32141da177e4SLinus Torvalds 
32151da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
32161da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
3217bf4c6325SGustavo F. Padovan 
3218bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3219bf4c6325SGustavo F. Padovan 
3220bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3221769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
32221da177e4SLinus Torvalds 			continue;
3223769be974SMarcel Holtmann 
3224769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3225769be974SMarcel Holtmann 			continue;
3226769be974SMarcel Holtmann 
32271da177e4SLinus Torvalds 		num++;
32281da177e4SLinus Torvalds 
32291da177e4SLinus Torvalds 		if (c->sent < min) {
32301da177e4SLinus Torvalds 			min  = c->sent;
32311da177e4SLinus Torvalds 			conn = c;
32321da177e4SLinus Torvalds 		}
323352087a79SLuiz Augusto von Dentz 
323452087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
323552087a79SLuiz Augusto von Dentz 			break;
32361da177e4SLinus Torvalds 	}
32371da177e4SLinus Torvalds 
3238bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3239bf4c6325SGustavo F. Padovan 
32401da177e4SLinus Torvalds 	if (conn) {
32416ed58ec5SVille Tervo 		int cnt, q;
32426ed58ec5SVille Tervo 
32436ed58ec5SVille Tervo 		switch (conn->type) {
32446ed58ec5SVille Tervo 		case ACL_LINK:
32456ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
32466ed58ec5SVille Tervo 			break;
32476ed58ec5SVille Tervo 		case SCO_LINK:
32486ed58ec5SVille Tervo 		case ESCO_LINK:
32496ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
32506ed58ec5SVille Tervo 			break;
32516ed58ec5SVille Tervo 		case LE_LINK:
32526ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
32536ed58ec5SVille Tervo 			break;
32546ed58ec5SVille Tervo 		default:
32556ed58ec5SVille Tervo 			cnt = 0;
32562064ee33SMarcel Holtmann 			bt_dev_err(hdev, "unknown link type %d", conn->type);
32576ed58ec5SVille Tervo 		}
32586ed58ec5SVille Tervo 
32596ed58ec5SVille Tervo 		q = cnt / num;
32601da177e4SLinus Torvalds 		*quote = q ? q : 1;
32611da177e4SLinus Torvalds 	} else
32621da177e4SLinus Torvalds 		*quote = 0;
32631da177e4SLinus Torvalds 
32641da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
32651da177e4SLinus Torvalds 	return conn;
32661da177e4SLinus Torvalds }
32671da177e4SLinus Torvalds 
32686039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
32691da177e4SLinus Torvalds {
32701da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
32711da177e4SLinus Torvalds 	struct hci_conn *c;
32721da177e4SLinus Torvalds 
32732064ee33SMarcel Holtmann 	bt_dev_err(hdev, "link tx timeout");
32741da177e4SLinus Torvalds 
3275bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3276bf4c6325SGustavo F. Padovan 
32771da177e4SLinus Torvalds 	/* Kill stalled connections */
3278bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3279bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
32802064ee33SMarcel Holtmann 			bt_dev_err(hdev, "killing stalled connection %pMR",
32812064ee33SMarcel Holtmann 				   &c->dst);
3282bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
32831da177e4SLinus Torvalds 		}
32841da177e4SLinus Torvalds 	}
3285bf4c6325SGustavo F. Padovan 
3286bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
32871da177e4SLinus Torvalds }
32881da177e4SLinus Torvalds 
32896039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
329073d80debSLuiz Augusto von Dentz 				      int *quote)
329173d80debSLuiz Augusto von Dentz {
329273d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
329373d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3294abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
329573d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
329673d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
329773d80debSLuiz Augusto von Dentz 
329873d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
329973d80debSLuiz Augusto von Dentz 
3300bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3301bf4c6325SGustavo F. Padovan 
3302bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
330373d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
330473d80debSLuiz Augusto von Dentz 
330573d80debSLuiz Augusto von Dentz 		if (conn->type != type)
330673d80debSLuiz Augusto von Dentz 			continue;
330773d80debSLuiz Augusto von Dentz 
330873d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
330973d80debSLuiz Augusto von Dentz 			continue;
331073d80debSLuiz Augusto von Dentz 
331173d80debSLuiz Augusto von Dentz 		conn_num++;
331273d80debSLuiz Augusto von Dentz 
33138192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
331473d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
331573d80debSLuiz Augusto von Dentz 
331673d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
331773d80debSLuiz Augusto von Dentz 				continue;
331873d80debSLuiz Augusto von Dentz 
331973d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
332073d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
332173d80debSLuiz Augusto von Dentz 				continue;
332273d80debSLuiz Augusto von Dentz 
332373d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
332473d80debSLuiz Augusto von Dentz 				num = 0;
332573d80debSLuiz Augusto von Dentz 				min = ~0;
332673d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
332773d80debSLuiz Augusto von Dentz 			}
332873d80debSLuiz Augusto von Dentz 
332973d80debSLuiz Augusto von Dentz 			num++;
333073d80debSLuiz Augusto von Dentz 
333173d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
333273d80debSLuiz Augusto von Dentz 				min  = conn->sent;
333373d80debSLuiz Augusto von Dentz 				chan = tmp;
333473d80debSLuiz Augusto von Dentz 			}
333573d80debSLuiz Augusto von Dentz 		}
333673d80debSLuiz Augusto von Dentz 
333773d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
333873d80debSLuiz Augusto von Dentz 			break;
333973d80debSLuiz Augusto von Dentz 	}
334073d80debSLuiz Augusto von Dentz 
3341bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3342bf4c6325SGustavo F. Padovan 
334373d80debSLuiz Augusto von Dentz 	if (!chan)
334473d80debSLuiz Augusto von Dentz 		return NULL;
334573d80debSLuiz Augusto von Dentz 
334673d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
334773d80debSLuiz Augusto von Dentz 	case ACL_LINK:
334873d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
334973d80debSLuiz Augusto von Dentz 		break;
3350bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
3351bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
3352bd1eb66bSAndrei Emeltchenko 		break;
335373d80debSLuiz Augusto von Dentz 	case SCO_LINK:
335473d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
335573d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
335673d80debSLuiz Augusto von Dentz 		break;
335773d80debSLuiz Augusto von Dentz 	case LE_LINK:
335873d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
335973d80debSLuiz Augusto von Dentz 		break;
336073d80debSLuiz Augusto von Dentz 	default:
336173d80debSLuiz Augusto von Dentz 		cnt = 0;
33622064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown link type %d", chan->conn->type);
336373d80debSLuiz Augusto von Dentz 	}
336473d80debSLuiz Augusto von Dentz 
336573d80debSLuiz Augusto von Dentz 	q = cnt / num;
336673d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
336773d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
336873d80debSLuiz Augusto von Dentz 	return chan;
336973d80debSLuiz Augusto von Dentz }
337073d80debSLuiz Augusto von Dentz 
337102b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
337202b20f0bSLuiz Augusto von Dentz {
337302b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
337402b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
337502b20f0bSLuiz Augusto von Dentz 	int num = 0;
337602b20f0bSLuiz Augusto von Dentz 
337702b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
337802b20f0bSLuiz Augusto von Dentz 
3379bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3380bf4c6325SGustavo F. Padovan 
3381bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
338202b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
338302b20f0bSLuiz Augusto von Dentz 
338402b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
338502b20f0bSLuiz Augusto von Dentz 			continue;
338602b20f0bSLuiz Augusto von Dentz 
338702b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
338802b20f0bSLuiz Augusto von Dentz 			continue;
338902b20f0bSLuiz Augusto von Dentz 
339002b20f0bSLuiz Augusto von Dentz 		num++;
339102b20f0bSLuiz Augusto von Dentz 
33928192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
339302b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
339402b20f0bSLuiz Augusto von Dentz 
339502b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
339602b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
339702b20f0bSLuiz Augusto von Dentz 				continue;
339802b20f0bSLuiz Augusto von Dentz 			}
339902b20f0bSLuiz Augusto von Dentz 
340002b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
340102b20f0bSLuiz Augusto von Dentz 				continue;
340202b20f0bSLuiz Augusto von Dentz 
340302b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
340402b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
340502b20f0bSLuiz Augusto von Dentz 				continue;
340602b20f0bSLuiz Augusto von Dentz 
340702b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
340802b20f0bSLuiz Augusto von Dentz 
340902b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
341002b20f0bSLuiz Augusto von Dentz 			       skb->priority);
341102b20f0bSLuiz Augusto von Dentz 		}
341202b20f0bSLuiz Augusto von Dentz 
341302b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
341402b20f0bSLuiz Augusto von Dentz 			break;
341502b20f0bSLuiz Augusto von Dentz 	}
3416bf4c6325SGustavo F. Padovan 
3417bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3418bf4c6325SGustavo F. Padovan 
341902b20f0bSLuiz Augusto von Dentz }
342002b20f0bSLuiz Augusto von Dentz 
3421b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3422b71d385aSAndrei Emeltchenko {
3423b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3424b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3425b71d385aSAndrei Emeltchenko }
3426b71d385aSAndrei Emeltchenko 
34276039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
34281da177e4SLinus Torvalds {
3429d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
34301da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
34311da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
343263d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
34335f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
3434bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
34351da177e4SLinus Torvalds 	}
343663d2bc1bSAndrei Emeltchenko }
34371da177e4SLinus Torvalds 
34387fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */
34397fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev)
34407fedd3bbSAbhishek Pandit-Subedi {
34417fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
34427fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
34437fedd3bbSAbhishek Pandit-Subedi 	int quote;
34447fedd3bbSAbhishek Pandit-Subedi 
34457fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
34467fedd3bbSAbhishek Pandit-Subedi 
34477fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, SCO_LINK))
34487fedd3bbSAbhishek Pandit-Subedi 		return;
34497fedd3bbSAbhishek Pandit-Subedi 
34507fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
34517fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
34527fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
34537fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
34547fedd3bbSAbhishek Pandit-Subedi 
34557fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
34567fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
34577fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
34587fedd3bbSAbhishek Pandit-Subedi 		}
34597fedd3bbSAbhishek Pandit-Subedi 	}
34607fedd3bbSAbhishek Pandit-Subedi }
34617fedd3bbSAbhishek Pandit-Subedi 
34627fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev)
34637fedd3bbSAbhishek Pandit-Subedi {
34647fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
34657fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
34667fedd3bbSAbhishek Pandit-Subedi 	int quote;
34677fedd3bbSAbhishek Pandit-Subedi 
34687fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
34697fedd3bbSAbhishek Pandit-Subedi 
34707fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, ESCO_LINK))
34717fedd3bbSAbhishek Pandit-Subedi 		return;
34727fedd3bbSAbhishek Pandit-Subedi 
34737fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
34747fedd3bbSAbhishek Pandit-Subedi 						     &quote))) {
34757fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
34767fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
34777fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
34787fedd3bbSAbhishek Pandit-Subedi 
34797fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
34807fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
34817fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
34827fedd3bbSAbhishek Pandit-Subedi 		}
34837fedd3bbSAbhishek Pandit-Subedi 	}
34847fedd3bbSAbhishek Pandit-Subedi }
34857fedd3bbSAbhishek Pandit-Subedi 
34866039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
348763d2bc1bSAndrei Emeltchenko {
348863d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
348963d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
349063d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
349163d2bc1bSAndrei Emeltchenko 	int quote;
349263d2bc1bSAndrei Emeltchenko 
349363d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
349404837f64SMarcel Holtmann 
349573d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
349673d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3497ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3498ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
349973d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
350073d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
350173d80debSLuiz Augusto von Dentz 
3502ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3503ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3504ec1cce24SLuiz Augusto von Dentz 				break;
3505ec1cce24SLuiz Augusto von Dentz 
3506ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3507ec1cce24SLuiz Augusto von Dentz 
350873d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
350973d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
351004837f64SMarcel Holtmann 
351157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
35121da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
35131da177e4SLinus Torvalds 
35141da177e4SLinus Torvalds 			hdev->acl_cnt--;
351573d80debSLuiz Augusto von Dentz 			chan->sent++;
351673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
35177fedd3bbSAbhishek Pandit-Subedi 
35187fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
35197fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
35207fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
35211da177e4SLinus Torvalds 		}
35221da177e4SLinus Torvalds 	}
352302b20f0bSLuiz Augusto von Dentz 
352402b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
352502b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
35261da177e4SLinus Torvalds }
35271da177e4SLinus Torvalds 
35286039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3529b71d385aSAndrei Emeltchenko {
353063d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3531b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3532b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3533b71d385aSAndrei Emeltchenko 	int quote;
3534bd1eb66bSAndrei Emeltchenko 	u8 type;
3535b71d385aSAndrei Emeltchenko 
353663d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
3537b71d385aSAndrei Emeltchenko 
3538bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3539bd1eb66bSAndrei Emeltchenko 
3540bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3541bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3542bd1eb66bSAndrei Emeltchenko 	else
3543bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3544bd1eb66bSAndrei Emeltchenko 
3545b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3546bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3547b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3548b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3549b71d385aSAndrei Emeltchenko 			int blocks;
3550b71d385aSAndrei Emeltchenko 
3551b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3552b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3553b71d385aSAndrei Emeltchenko 
3554b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3555b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3556b71d385aSAndrei Emeltchenko 				break;
3557b71d385aSAndrei Emeltchenko 
3558b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3559b71d385aSAndrei Emeltchenko 
3560b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3561b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3562b71d385aSAndrei Emeltchenko 				return;
3563b71d385aSAndrei Emeltchenko 
3564b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3565b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3566b71d385aSAndrei Emeltchenko 
356757d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3568b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3569b71d385aSAndrei Emeltchenko 
3570b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3571b71d385aSAndrei Emeltchenko 			quote -= blocks;
3572b71d385aSAndrei Emeltchenko 
3573b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3574b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3575b71d385aSAndrei Emeltchenko 		}
3576b71d385aSAndrei Emeltchenko 	}
3577b71d385aSAndrei Emeltchenko 
3578b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3579bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3580b71d385aSAndrei Emeltchenko }
3581b71d385aSAndrei Emeltchenko 
35826039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3583b71d385aSAndrei Emeltchenko {
3584b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3585b71d385aSAndrei Emeltchenko 
3586bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3587ca8bee5dSMarcel Holtmann 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY)
3588bd1eb66bSAndrei Emeltchenko 		return;
3589bd1eb66bSAndrei Emeltchenko 
3590bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3591bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3592b71d385aSAndrei Emeltchenko 		return;
3593b71d385aSAndrei Emeltchenko 
3594b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3595b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3596b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3597b71d385aSAndrei Emeltchenko 		break;
3598b71d385aSAndrei Emeltchenko 
3599b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3600b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3601b71d385aSAndrei Emeltchenko 		break;
3602b71d385aSAndrei Emeltchenko 	}
3603b71d385aSAndrei Emeltchenko }
3604b71d385aSAndrei Emeltchenko 
36056039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
36066ed58ec5SVille Tervo {
360773d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
36086ed58ec5SVille Tervo 	struct sk_buff *skb;
360902b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
36106ed58ec5SVille Tervo 
36116ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
36126ed58ec5SVille Tervo 
361352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
361452087a79SLuiz Augusto von Dentz 		return;
361552087a79SLuiz Augusto von Dentz 
36166ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
36171b1d29e5SLuiz Augusto von Dentz 
36181b1d29e5SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt);
36191b1d29e5SLuiz Augusto von Dentz 
362002b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
362173d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3622ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3623ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
362473d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
362573d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
36266ed58ec5SVille Tervo 
3627ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3628ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3629ec1cce24SLuiz Augusto von Dentz 				break;
3630ec1cce24SLuiz Augusto von Dentz 
3631ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3632ec1cce24SLuiz Augusto von Dentz 
363357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
36346ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
36356ed58ec5SVille Tervo 
36366ed58ec5SVille Tervo 			cnt--;
363773d80debSLuiz Augusto von Dentz 			chan->sent++;
363873d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
36397fedd3bbSAbhishek Pandit-Subedi 
36407fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
36417fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
36427fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
36436ed58ec5SVille Tervo 		}
36446ed58ec5SVille Tervo 	}
364573d80debSLuiz Augusto von Dentz 
36466ed58ec5SVille Tervo 	if (hdev->le_pkts)
36476ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
36486ed58ec5SVille Tervo 	else
36496ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
365002b20f0bSLuiz Augusto von Dentz 
365102b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
365202b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
36536ed58ec5SVille Tervo }
36546ed58ec5SVille Tervo 
36553eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
36561da177e4SLinus Torvalds {
36573eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
36581da177e4SLinus Torvalds 	struct sk_buff *skb;
36591da177e4SLinus Torvalds 
36606ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
36616ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
36621da177e4SLinus Torvalds 
3663d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
36641da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
36651da177e4SLinus Torvalds 		hci_sched_sco(hdev);
3666b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
36677fedd3bbSAbhishek Pandit-Subedi 		hci_sched_acl(hdev);
36686ed58ec5SVille Tervo 		hci_sched_le(hdev);
366952de599eSMarcel Holtmann 	}
36706ed58ec5SVille Tervo 
36711da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
36721da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
367357d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
36741da177e4SLinus Torvalds }
36751da177e4SLinus Torvalds 
367625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
36771da177e4SLinus Torvalds 
36781da177e4SLinus Torvalds /* ACL data packet */
36796039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
36801da177e4SLinus Torvalds {
36811da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
36821da177e4SLinus Torvalds 	struct hci_conn *conn;
36831da177e4SLinus Torvalds 	__u16 handle, flags;
36841da177e4SLinus Torvalds 
36851da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
36861da177e4SLinus Torvalds 
36871da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
36881da177e4SLinus Torvalds 	flags  = hci_flags(handle);
36891da177e4SLinus Torvalds 	handle = hci_handle(handle);
36901da177e4SLinus Torvalds 
3691f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3692a8c5fb1aSGustavo Padovan 	       handle, flags);
36931da177e4SLinus Torvalds 
36941da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
36951da177e4SLinus Torvalds 
36961da177e4SLinus Torvalds 	hci_dev_lock(hdev);
36971da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
36981da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
36991da177e4SLinus Torvalds 
37001da177e4SLinus Torvalds 	if (conn) {
370165983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
370204837f64SMarcel Holtmann 
37031da177e4SLinus Torvalds 		/* Send to upper protocol */
3704686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
37051da177e4SLinus Torvalds 		return;
37061da177e4SLinus Torvalds 	} else {
37072064ee33SMarcel Holtmann 		bt_dev_err(hdev, "ACL packet for unknown connection handle %d",
37082064ee33SMarcel Holtmann 			   handle);
37091da177e4SLinus Torvalds 	}
37101da177e4SLinus Torvalds 
37111da177e4SLinus Torvalds 	kfree_skb(skb);
37121da177e4SLinus Torvalds }
37131da177e4SLinus Torvalds 
37141da177e4SLinus Torvalds /* SCO data packet */
37156039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
37161da177e4SLinus Torvalds {
37171da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
37181da177e4SLinus Torvalds 	struct hci_conn *conn;
3719debdedf2SMarcel Holtmann 	__u16 handle, flags;
37201da177e4SLinus Torvalds 
37211da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
37221da177e4SLinus Torvalds 
37231da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
3724debdedf2SMarcel Holtmann 	flags  = hci_flags(handle);
3725debdedf2SMarcel Holtmann 	handle = hci_handle(handle);
37261da177e4SLinus Torvalds 
3727debdedf2SMarcel Holtmann 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3728debdedf2SMarcel Holtmann 	       handle, flags);
37291da177e4SLinus Torvalds 
37301da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
37311da177e4SLinus Torvalds 
37321da177e4SLinus Torvalds 	hci_dev_lock(hdev);
37331da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
37341da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
37351da177e4SLinus Torvalds 
37361da177e4SLinus Torvalds 	if (conn) {
37371da177e4SLinus Torvalds 		/* Send to upper protocol */
373800398e1dSAlain Michaud 		bt_cb(skb)->sco.pkt_status = flags & 0x03;
3739686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
37401da177e4SLinus Torvalds 		return;
37411da177e4SLinus Torvalds 	} else {
37422064ee33SMarcel Holtmann 		bt_dev_err(hdev, "SCO packet for unknown connection handle %d",
37432064ee33SMarcel Holtmann 			   handle);
37441da177e4SLinus Torvalds 	}
37451da177e4SLinus Torvalds 
37461da177e4SLinus Torvalds 	kfree_skb(skb);
37471da177e4SLinus Torvalds }
37481da177e4SLinus Torvalds 
37499238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
37509238f36aSJohan Hedberg {
37519238f36aSJohan Hedberg 	struct sk_buff *skb;
37529238f36aSJohan Hedberg 
37539238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
37549238f36aSJohan Hedberg 	if (!skb)
37559238f36aSJohan Hedberg 		return true;
37569238f36aSJohan Hedberg 
375744d27137SJohan Hedberg 	return (bt_cb(skb)->hci.req_flags & HCI_REQ_START);
37589238f36aSJohan Hedberg }
37599238f36aSJohan Hedberg 
376042c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
376142c6b129SJohan Hedberg {
376242c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
376342c6b129SJohan Hedberg 	struct sk_buff *skb;
376442c6b129SJohan Hedberg 	u16 opcode;
376542c6b129SJohan Hedberg 
376642c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
376742c6b129SJohan Hedberg 		return;
376842c6b129SJohan Hedberg 
376942c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
377042c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
377142c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
377242c6b129SJohan Hedberg 		return;
377342c6b129SJohan Hedberg 
377442c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
377542c6b129SJohan Hedberg 	if (!skb)
377642c6b129SJohan Hedberg 		return;
377742c6b129SJohan Hedberg 
377842c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
377942c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
378042c6b129SJohan Hedberg }
378142c6b129SJohan Hedberg 
3782e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
3783e6214487SJohan Hedberg 			  hci_req_complete_t *req_complete,
3784e6214487SJohan Hedberg 			  hci_req_complete_skb_t *req_complete_skb)
37859238f36aSJohan Hedberg {
37869238f36aSJohan Hedberg 	struct sk_buff *skb;
37879238f36aSJohan Hedberg 	unsigned long flags;
37889238f36aSJohan Hedberg 
37899238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
37909238f36aSJohan Hedberg 
379142c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
379242c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
37939238f36aSJohan Hedberg 	 */
379442c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
379542c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
379642c6b129SJohan Hedberg 		 * reset complete event during init and any pending
379742c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
379842c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
379942c6b129SJohan Hedberg 		 * command.
380042c6b129SJohan Hedberg 		 */
380142c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
380242c6b129SJohan Hedberg 			hci_resend_last(hdev);
380342c6b129SJohan Hedberg 
38049238f36aSJohan Hedberg 		return;
380542c6b129SJohan Hedberg 	}
38069238f36aSJohan Hedberg 
3807f80c5dadSJoão Paulo Rechi Vita 	/* If we reach this point this event matches the last command sent */
3808f80c5dadSJoão Paulo Rechi Vita 	hci_dev_clear_flag(hdev, HCI_CMD_PENDING);
3809f80c5dadSJoão Paulo Rechi Vita 
38109238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
38119238f36aSJohan Hedberg 	 * this request the request is not yet complete.
38129238f36aSJohan Hedberg 	 */
38139238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
38149238f36aSJohan Hedberg 		return;
38159238f36aSJohan Hedberg 
38169238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
38179238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
38189238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
38199238f36aSJohan Hedberg 	 */
382044d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) {
382144d27137SJohan Hedberg 		*req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb;
3822e6214487SJohan Hedberg 		return;
38239238f36aSJohan Hedberg 	}
3824e6214487SJohan Hedberg 
382544d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_complete) {
382644d27137SJohan Hedberg 		*req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete;
3827e6214487SJohan Hedberg 		return;
382853e21fbcSJohan Hedberg 	}
38299238f36aSJohan Hedberg 
38309238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
38319238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
38329238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
383344d27137SJohan Hedberg 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) {
38349238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
38359238f36aSJohan Hedberg 			break;
38369238f36aSJohan Hedberg 		}
38379238f36aSJohan Hedberg 
38383bd7594eSDouglas Anderson 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB)
3839242c0ebdSMarcel Holtmann 			*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
38403bd7594eSDouglas Anderson 		else
38413bd7594eSDouglas Anderson 			*req_complete = bt_cb(skb)->hci.req_complete;
38429238f36aSJohan Hedberg 		kfree_skb(skb);
38439238f36aSJohan Hedberg 	}
38449238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
38459238f36aSJohan Hedberg }
38469238f36aSJohan Hedberg 
3847b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
38481da177e4SLinus Torvalds {
3849b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
38501da177e4SLinus Torvalds 	struct sk_buff *skb;
38511da177e4SLinus Torvalds 
38521da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
38531da177e4SLinus Torvalds 
38541da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
3855cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
3856cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
3857cd82e61cSMarcel Holtmann 
38581da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
38591da177e4SLinus Torvalds 			/* Send copy to the sockets */
3860470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
38611da177e4SLinus Torvalds 		}
38621da177e4SLinus Torvalds 
3863eb8c101eSMattijs Korpershoek 		/* If the device has been opened in HCI_USER_CHANNEL,
3864eb8c101eSMattijs Korpershoek 		 * the userspace has exclusive access to device.
3865eb8c101eSMattijs Korpershoek 		 * When device is HCI_INIT, we still need to process
3866eb8c101eSMattijs Korpershoek 		 * the data packets to the driver in order
3867eb8c101eSMattijs Korpershoek 		 * to complete its setup().
3868eb8c101eSMattijs Korpershoek 		 */
3869eb8c101eSMattijs Korpershoek 		if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
3870eb8c101eSMattijs Korpershoek 		    !test_bit(HCI_INIT, &hdev->flags)) {
38711da177e4SLinus Torvalds 			kfree_skb(skb);
38721da177e4SLinus Torvalds 			continue;
38731da177e4SLinus Torvalds 		}
38741da177e4SLinus Torvalds 
38751da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
38761da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
3877d79f34e3SMarcel Holtmann 			switch (hci_skb_pkt_type(skb)) {
38781da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
38791da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
3880cc974003SMarcel Holtmann 			case HCI_ISODATA_PKT:
38811da177e4SLinus Torvalds 				kfree_skb(skb);
38821da177e4SLinus Torvalds 				continue;
38833ff50b79SStephen Hemminger 			}
38841da177e4SLinus Torvalds 		}
38851da177e4SLinus Torvalds 
38861da177e4SLinus Torvalds 		/* Process frame */
3887d79f34e3SMarcel Holtmann 		switch (hci_skb_pkt_type(skb)) {
38881da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
3889b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
38901da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
38911da177e4SLinus Torvalds 			break;
38921da177e4SLinus Torvalds 
38931da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
38941da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
38951da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
38961da177e4SLinus Torvalds 			break;
38971da177e4SLinus Torvalds 
38981da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
38991da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
39001da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
39011da177e4SLinus Torvalds 			break;
39021da177e4SLinus Torvalds 
39031da177e4SLinus Torvalds 		default:
39041da177e4SLinus Torvalds 			kfree_skb(skb);
39051da177e4SLinus Torvalds 			break;
39061da177e4SLinus Torvalds 		}
39071da177e4SLinus Torvalds 	}
39081da177e4SLinus Torvalds }
39091da177e4SLinus Torvalds 
3910c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
39111da177e4SLinus Torvalds {
3912c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
39131da177e4SLinus Torvalds 	struct sk_buff *skb;
39141da177e4SLinus Torvalds 
39152104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
39162104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
39171da177e4SLinus Torvalds 
39181da177e4SLinus Torvalds 	/* Send queued commands */
39195a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
39205a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
39215a08ecceSAndrei Emeltchenko 		if (!skb)
39225a08ecceSAndrei Emeltchenko 			return;
39235a08ecceSAndrei Emeltchenko 
39241da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
39251da177e4SLinus Torvalds 
3926a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
392770f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
3928f80c5dadSJoão Paulo Rechi Vita 			if (hci_req_status_pend(hdev))
3929f80c5dadSJoão Paulo Rechi Vita 				hci_dev_set_flag(hdev, HCI_CMD_PENDING);
39301da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
393157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
39327bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
393365cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
39347bdb8a5cSSzymon Janc 			else
393565cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
393665cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
39371da177e4SLinus Torvalds 		} else {
39381da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
3939c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
39401da177e4SLinus Torvalds 		}
39411da177e4SLinus Torvalds 	}
39421da177e4SLinus Torvalds }
3943