xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 103a2f32)
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 
612d0b13706SLuiz 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;
2156fe92ee64SLuiz Augusto von Dentz 	bitmap_from_u64(entry->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 
23772f20216cSAbhishek Pandit-Subedi static void hci_clear_wake_reason(struct hci_dev *hdev)
23782f20216cSAbhishek Pandit-Subedi {
23792f20216cSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
23802f20216cSAbhishek Pandit-Subedi 
23812f20216cSAbhishek Pandit-Subedi 	hdev->wake_reason = 0;
23822f20216cSAbhishek Pandit-Subedi 	bacpy(&hdev->wake_addr, BDADDR_ANY);
23832f20216cSAbhishek Pandit-Subedi 	hdev->wake_addr_type = 0;
23842f20216cSAbhishek Pandit-Subedi 
23852f20216cSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
23862f20216cSAbhishek Pandit-Subedi }
23872f20216cSAbhishek Pandit-Subedi 
23889952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
23899952d90eSAbhishek Pandit-Subedi 				void *data)
23909952d90eSAbhishek Pandit-Subedi {
23919952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
23929952d90eSAbhishek Pandit-Subedi 		container_of(nb, struct hci_dev, suspend_notifier);
23939952d90eSAbhishek Pandit-Subedi 	int ret = 0;
23949952d90eSAbhishek Pandit-Subedi 
2395e1b77d68SLuiz Augusto von Dentz 	if (action == PM_SUSPEND_PREPARE)
2396e1b77d68SLuiz Augusto von Dentz 		ret = hci_suspend_dev(hdev);
2397e1b77d68SLuiz Augusto von Dentz 	else if (action == PM_POST_SUSPEND)
2398e1b77d68SLuiz Augusto von Dentz 		ret = hci_resume_dev(hdev);
23999952d90eSAbhishek Pandit-Subedi 
2400a9ec8423SAbhishek Pandit-Subedi 	if (ret)
2401a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
2402a9ec8423SAbhishek Pandit-Subedi 			   action, ret);
2403a9ec8423SAbhishek Pandit-Subedi 
240424b06572SMax Chou 	return NOTIFY_DONE;
24059952d90eSAbhishek Pandit-Subedi }
24068731840aSAbhishek Pandit-Subedi 
24079be0dab7SDavid Herrmann /* Alloc HCI device */
24086ec56613STedd Ho-Jeong An struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
24099be0dab7SDavid Herrmann {
24109be0dab7SDavid Herrmann 	struct hci_dev *hdev;
24116ec56613STedd Ho-Jeong An 	unsigned int alloc_size;
24129be0dab7SDavid Herrmann 
24136ec56613STedd Ho-Jeong An 	alloc_size = sizeof(*hdev);
24146ec56613STedd Ho-Jeong An 	if (sizeof_priv) {
24156ec56613STedd Ho-Jeong An 		/* Fixme: May need ALIGN-ment? */
24166ec56613STedd Ho-Jeong An 		alloc_size += sizeof_priv;
24176ec56613STedd Ho-Jeong An 	}
24186ec56613STedd Ho-Jeong An 
24196ec56613STedd Ho-Jeong An 	hdev = kzalloc(alloc_size, GFP_KERNEL);
24209be0dab7SDavid Herrmann 	if (!hdev)
24219be0dab7SDavid Herrmann 		return NULL;
24229be0dab7SDavid Herrmann 
2423b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2424b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
2425b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
2426b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
2427b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
242896c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
2429bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2430bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2431d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
2432d2609b34SFlorian Grandel 	hdev->cur_adv_instance = 0x00;
24335d900e46SFlorian Grandel 	hdev->adv_instance_timeout = 0;
2434b1b813d4SDavid Herrmann 
2435c4f1f408SHoward Chung 	hdev->advmon_allowlist_duration = 300;
2436c4f1f408SHoward Chung 	hdev->advmon_no_filter_duration = 500;
243780af16a3SHoward Chung 	hdev->enable_advmon_interleave_scan = 0x00;	/* Default to disable */
2438c4f1f408SHoward Chung 
2439b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
2440b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
2441b1b813d4SDavid Herrmann 
24423f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
2443628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
2444628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
2445bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
2446bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
244710873f99SAlain Michaud 	hdev->le_scan_int_suspend = 0x0400;
244810873f99SAlain Michaud 	hdev->le_scan_window_suspend = 0x0012;
244910873f99SAlain Michaud 	hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT;
245010873f99SAlain Michaud 	hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN;
2451ba29d036SMarcel Holtmann 	hdev->le_scan_int_adv_monitor = 0x0060;
2452ba29d036SMarcel Holtmann 	hdev->le_scan_window_adv_monitor = 0x0030;
245310873f99SAlain Michaud 	hdev->le_scan_int_connect = 0x0060;
245410873f99SAlain Michaud 	hdev->le_scan_window_connect = 0x0060;
2455b48c3b59SJonas Holmberg 	hdev->le_conn_min_interval = 0x0018;
2456b48c3b59SJonas Holmberg 	hdev->le_conn_max_interval = 0x0028;
245704fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
245804fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
2459a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = 0x001b;
2460a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = 0x0148;
2461a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = 0x001b;
2462a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = 0x0148;
2463a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = 0x001b;
2464a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = 0x0148;
246530d65e08SMatias Karhumaa 	hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE;
246630d65e08SMatias Karhumaa 	hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE;
24676decb5b4SJaganath Kanakkassery 	hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
24686decb5b4SJaganath Kanakkassery 	hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
24691d0fac2cSLuiz Augusto von Dentz 	hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES;
247010873f99SAlain Michaud 	hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION;
247149b020c1SAlain Michaud 	hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT;
24727c395ea5SDaniel Winkler 	hdev->min_le_tx_power = HCI_TX_POWER_INVALID;
24737c395ea5SDaniel Winkler 	hdev->max_le_tx_power = HCI_TX_POWER_INVALID;
2474bef64738SMarcel Holtmann 
2475d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
2476b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
247731ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
247831ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
2479302975cbSSpoorthi Ravishankar Koppad 	hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT;
248058a96fc3SMarcel Holtmann 	hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE;
2481d6bfd59cSJohan Hedberg 
248210873f99SAlain Michaud 	/* default 1.28 sec page scan */
248310873f99SAlain Michaud 	hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD;
248410873f99SAlain Michaud 	hdev->def_page_scan_int = 0x0800;
248510873f99SAlain Michaud 	hdev->def_page_scan_window = 0x0012;
248610873f99SAlain Michaud 
2487b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
2488b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
2489b1b813d4SDavid Herrmann 
2490b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
24913d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->reject_list);
24923d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->accept_list);
2493b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
2494b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
2495b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
2496970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
2497b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
24983d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->le_accept_list);
2499cfdb0c2dSAnkit Navik 	INIT_LIST_HEAD(&hdev->le_resolv_list);
250015819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
250177a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
250266f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
25036b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
2504d2609b34SFlorian Grandel 	INIT_LIST_HEAD(&hdev->adv_instances);
2505600a8749SAlain Michaud 	INIT_LIST_HEAD(&hdev->blocked_keys);
25063368aa35SManish Mandlik 	INIT_LIST_HEAD(&hdev->monitored_devices);
2507b1b813d4SDavid Herrmann 
25088961987fSKiran K 	INIT_LIST_HEAD(&hdev->local_codecs);
2509b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2510b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2511b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2512b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2513c7741d16SMarcel Holtmann 	INIT_WORK(&hdev->error_reset, hci_error_reset);
2514b1b813d4SDavid Herrmann 
25156a98e383SMarcel Holtmann 	hci_cmd_sync_init(hdev);
25166a98e383SMarcel Holtmann 
2517b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2518b1b813d4SDavid Herrmann 
2519b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2520b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2521b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2522b1b813d4SDavid Herrmann 
2523b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2524b1b813d4SDavid Herrmann 
252565cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
2526de75cd0dSManish Mandlik 	INIT_DELAYED_WORK(&hdev->ncmd_timer, hci_ncmd_timeout);
2527b1b813d4SDavid Herrmann 
25285fc16cc4SJohan Hedberg 	hci_request_setup(hdev);
25295fc16cc4SJohan Hedberg 
2530b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2531b1b813d4SDavid Herrmann 	discovery_init(hdev);
25329be0dab7SDavid Herrmann 
25339be0dab7SDavid Herrmann 	return hdev;
25349be0dab7SDavid Herrmann }
25356ec56613STedd Ho-Jeong An EXPORT_SYMBOL(hci_alloc_dev_priv);
25369be0dab7SDavid Herrmann 
25379be0dab7SDavid Herrmann /* Free HCI device */
25389be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
25399be0dab7SDavid Herrmann {
25409be0dab7SDavid Herrmann 	/* will free via device release */
25419be0dab7SDavid Herrmann 	put_device(&hdev->dev);
25429be0dab7SDavid Herrmann }
25439be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
25449be0dab7SDavid Herrmann 
25451da177e4SLinus Torvalds /* Register HCI device */
25461da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
25471da177e4SLinus Torvalds {
2548b1b813d4SDavid Herrmann 	int id, error;
25491da177e4SLinus Torvalds 
255074292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
25511da177e4SLinus Torvalds 		return -EINVAL;
25521da177e4SLinus Torvalds 
255308add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
255408add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
255508add513SMat Martineau 	 */
25563df92b31SSasha Levin 	switch (hdev->dev_type) {
2557ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
2558*103a2f32SItay Iellin 		id = ida_simple_get(&hci_index_ida, 0, HCI_MAX_ID, GFP_KERNEL);
25591da177e4SLinus Torvalds 		break;
25603df92b31SSasha Levin 	case HCI_AMP:
2561*103a2f32SItay Iellin 		id = ida_simple_get(&hci_index_ida, 1, HCI_MAX_ID, GFP_KERNEL);
25623df92b31SSasha Levin 		break;
25633df92b31SSasha Levin 	default:
25643df92b31SSasha Levin 		return -EINVAL;
25651da177e4SLinus Torvalds 	}
25661da177e4SLinus Torvalds 
25673df92b31SSasha Levin 	if (id < 0)
25683df92b31SSasha Levin 		return id;
25693df92b31SSasha Levin 
2570*103a2f32SItay Iellin 	snprintf(hdev->name, sizeof(hdev->name), "hci%d", id);
25711da177e4SLinus Torvalds 	hdev->id = id;
25722d8b3a11SAndrei Emeltchenko 
25732d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
25742d8b3a11SAndrei Emeltchenko 
257529e2dd0dSTejun Heo 	hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name);
257633ca954dSDavid Herrmann 	if (!hdev->workqueue) {
257733ca954dSDavid Herrmann 		error = -ENOMEM;
257833ca954dSDavid Herrmann 		goto err;
257933ca954dSDavid Herrmann 	}
2580f48fd9c8SMarcel Holtmann 
258129e2dd0dSTejun Heo 	hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI,
258229e2dd0dSTejun Heo 						      hdev->name);
25836ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
25846ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
25856ead1bbcSJohan Hedberg 		error = -ENOMEM;
25866ead1bbcSJohan Hedberg 		goto err;
25876ead1bbcSJohan Hedberg 	}
25886ead1bbcSJohan Hedberg 
25890153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
25900153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
25910153e2ecSMarcel Holtmann 
2592bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
2593bdc3e0f1SMarcel Holtmann 
2594bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
259533ca954dSDavid Herrmann 	if (error < 0)
259654506918SJohan Hedberg 		goto err_wqueue;
25971da177e4SLinus Torvalds 
25986d5d2ee6SHeiner Kallweit 	hci_leds_init(hdev);
25996d5d2ee6SHeiner Kallweit 
2600611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2601a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2602a8c5fb1aSGustavo Padovan 				    hdev);
2603611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2604611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
2605611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
2606611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
2607611b30f7SMarcel Holtmann 		}
2608611b30f7SMarcel Holtmann 	}
2609611b30f7SMarcel Holtmann 
26105e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
2611a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
26125e130367SJohan Hedberg 
2613a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_SETUP);
2614a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_AUTO_OFF);
2615ce2be9acSAndrei Emeltchenko 
2616ca8bee5dSMarcel Holtmann 	if (hdev->dev_type == HCI_PRIMARY) {
261756f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
261856f87901SJohan Hedberg 		 * through reading supported features during init.
261956f87901SJohan Hedberg 		 */
2620a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
262156f87901SJohan Hedberg 	}
2622ce2be9acSAndrei Emeltchenko 
2623fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
2624fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
2625fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
2626fcee3377SGustavo Padovan 
26274a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
26284a964404SMarcel Holtmann 	 * and should not be included in normal operation.
2629fee746b0SMarcel Holtmann 	 */
2630fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
2631a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
2632fee746b0SMarcel Holtmann 
2633fe92ee64SLuiz Augusto von Dentz 	/* Mark Remote Wakeup connection flag as supported if driver has wakeup
2634fe92ee64SLuiz Augusto von Dentz 	 * callback.
2635fe92ee64SLuiz Augusto von Dentz 	 */
2636fe92ee64SLuiz Augusto von Dentz 	if (hdev->wakeup)
2637fe92ee64SLuiz Augusto von Dentz 		set_bit(HCI_CONN_FLAG_REMOTE_WAKEUP, hdev->conn_flags);
2638fe92ee64SLuiz Augusto von Dentz 
263905fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_REG);
2640dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
26411da177e4SLinus Torvalds 
2642219991e6SHans de Goede 	if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
26439952d90eSAbhishek Pandit-Subedi 		hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
26449952d90eSAbhishek Pandit-Subedi 		error = register_pm_notifier(&hdev->suspend_notifier);
26459952d90eSAbhishek Pandit-Subedi 		if (error)
26469952d90eSAbhishek Pandit-Subedi 			goto err_wqueue;
2647219991e6SHans de Goede 	}
26489952d90eSAbhishek Pandit-Subedi 
264919202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2650fbe96d6fSMarcel Holtmann 
2651e5e1e7fdSMiao-chen Chou 	idr_init(&hdev->adv_monitors_idr);
26525031ffccSMiao-chen Chou 	msft_register(hdev);
2653e5e1e7fdSMiao-chen Chou 
26541da177e4SLinus Torvalds 	return id;
2655f48fd9c8SMarcel Holtmann 
265633ca954dSDavid Herrmann err_wqueue:
26575a4bb6a8SWei Yongjun 	debugfs_remove_recursive(hdev->debugfs);
265833ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
26596ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
266033ca954dSDavid Herrmann err:
26613df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
2662f48fd9c8SMarcel Holtmann 
266333ca954dSDavid Herrmann 	return error;
26641da177e4SLinus Torvalds }
26651da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
26661da177e4SLinus Torvalds 
26671da177e4SLinus Torvalds /* Unregister HCI device */
266859735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
26691da177e4SLinus Torvalds {
2670c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
26711da177e4SLinus Torvalds 
2672a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_UNREGISTER);
267394324962SJohan Hovold 
2674f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
26751da177e4SLinus Torvalds 	list_del(&hdev->list);
2676f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
26771da177e4SLinus Torvalds 
2678b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
2679b9b5ef18SGustavo Padovan 
26806a98e383SMarcel Holtmann 	hci_cmd_sync_clear(hdev);
26816a98e383SMarcel Holtmann 
2682182ee45dSLuiz Augusto von Dentz 	if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks))
26839952d90eSAbhishek Pandit-Subedi 		unregister_pm_notifier(&hdev->suspend_notifier);
26844e8c36c3SAbhishek Pandit-Subedi 
26855031ffccSMiao-chen Chou 	msft_unregister(hdev);
26865031ffccSMiao-chen Chou 
26874e8c36c3SAbhishek Pandit-Subedi 	hci_dev_do_close(hdev);
26889952d90eSAbhishek Pandit-Subedi 
2689ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2690d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_SETUP) &&
2691d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
269209fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2693744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
269409fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
269556e5cb86SJohan Hedberg 	}
2696ab81cbf9SJohan Hedberg 
26972e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
26982e58ef3eSJohan Hedberg 	 * pending list */
26992e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
27002e58ef3eSJohan Hedberg 
270105fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_UNREG);
27021da177e4SLinus Torvalds 
2703611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2704611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2705611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2706611b30f7SMarcel Holtmann 	}
2707611b30f7SMarcel Holtmann 
2708bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
2709e61fbee7SDavid S. Miller 	/* Actual cleanup is deferred until hci_release_dev(). */
2710e0448092STetsuo Handa 	hci_dev_put(hdev);
2711e0448092STetsuo Handa }
2712e0448092STetsuo Handa EXPORT_SYMBOL(hci_unregister_dev);
2713147e2d59SDave Young 
271458ce6d5bSTetsuo Handa /* Release HCI device */
271558ce6d5bSTetsuo Handa void hci_release_dev(struct hci_dev *hdev)
2716e0448092STetsuo Handa {
27170153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
27185177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
27195177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
27200153e2ecSMarcel Holtmann 
2721f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
27226ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2723f48fd9c8SMarcel Holtmann 
272409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
27253d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->reject_list);
27263d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->accept_list);
27272aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
272855ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2729b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
2730970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
27312763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
2732d2609b34SFlorian Grandel 	hci_adv_instances_clear(hdev);
2733e5e1e7fdSMiao-chen Chou 	hci_adv_monitors_clear(hdev);
27343d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
2735cfdb0c2dSAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
2736373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
273722078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
2738600a8749SAlain Michaud 	hci_blocked_keys_clear(hdev);
273909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2740e2e0cacbSJohan Hedberg 
2741e0448092STetsuo Handa 	ida_simple_remove(&hci_index_ida, hdev->id);
2742dd3b1dc3SLuiz Augusto von Dentz 	kfree_skb(hdev->sent_cmd);
274358ce6d5bSTetsuo Handa 	kfree(hdev);
27441da177e4SLinus Torvalds }
274558ce6d5bSTetsuo Handa EXPORT_SYMBOL(hci_release_dev);
27461da177e4SLinus Torvalds 
27471da177e4SLinus Torvalds /* Suspend HCI device */
27481da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
27491da177e4SLinus Torvalds {
2750e1b77d68SLuiz Augusto von Dentz 	int ret;
2751e1b77d68SLuiz Augusto von Dentz 
2752e1b77d68SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
2753e1b77d68SLuiz Augusto von Dentz 
2754e1b77d68SLuiz Augusto von Dentz 	/* Suspend should only act on when powered. */
2755e1b77d68SLuiz Augusto von Dentz 	if (!hdev_is_powered(hdev) ||
2756e1b77d68SLuiz Augusto von Dentz 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
27571da177e4SLinus Torvalds 		return 0;
2758e1b77d68SLuiz Augusto von Dentz 
2759182ee45dSLuiz Augusto von Dentz 	/* If powering down don't attempt to suspend */
2760182ee45dSLuiz Augusto von Dentz 	if (mgmt_powering_down(hdev))
2761182ee45dSLuiz Augusto von Dentz 		return 0;
2762e1b77d68SLuiz Augusto von Dentz 
2763182ee45dSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
2764182ee45dSLuiz Augusto von Dentz 	ret = hci_suspend_sync(hdev);
2765182ee45dSLuiz Augusto von Dentz 	hci_req_sync_unlock(hdev);
27664539ca67SLuiz Augusto von Dentz 
2767e1b77d68SLuiz Augusto von Dentz 	hci_clear_wake_reason(hdev);
2768182ee45dSLuiz Augusto von Dentz 	mgmt_suspending(hdev, hdev->suspend_state);
2769e1b77d68SLuiz Augusto von Dentz 
2770e1b77d68SLuiz Augusto von Dentz 	hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
2771e1b77d68SLuiz Augusto von Dentz 	return ret;
27721da177e4SLinus Torvalds }
27731da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
27741da177e4SLinus Torvalds 
27751da177e4SLinus Torvalds /* Resume HCI device */
27761da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
27771da177e4SLinus Torvalds {
2778e1b77d68SLuiz Augusto von Dentz 	int ret;
2779e1b77d68SLuiz Augusto von Dentz 
2780e1b77d68SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
2781e1b77d68SLuiz Augusto von Dentz 
2782e1b77d68SLuiz Augusto von Dentz 	/* Resume should only act on when powered. */
2783e1b77d68SLuiz Augusto von Dentz 	if (!hdev_is_powered(hdev) ||
2784e1b77d68SLuiz Augusto von Dentz 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
27851da177e4SLinus Torvalds 		return 0;
2786e1b77d68SLuiz Augusto von Dentz 
2787e1b77d68SLuiz Augusto von Dentz 	/* If powering down don't attempt to resume */
2788e1b77d68SLuiz Augusto von Dentz 	if (mgmt_powering_down(hdev))
2789e1b77d68SLuiz Augusto von Dentz 		return 0;
2790e1b77d68SLuiz Augusto von Dentz 
2791182ee45dSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
2792182ee45dSLuiz Augusto von Dentz 	ret = hci_resume_sync(hdev);
2793182ee45dSLuiz Augusto von Dentz 	hci_req_sync_unlock(hdev);
2794e1b77d68SLuiz Augusto von Dentz 
2795e1b77d68SLuiz Augusto von Dentz 	mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr,
2796e1b77d68SLuiz Augusto von Dentz 		      hdev->wake_addr_type);
2797e1b77d68SLuiz Augusto von Dentz 
2798e1b77d68SLuiz Augusto von Dentz 	hci_sock_dev_event(hdev, HCI_DEV_RESUME);
2799e1b77d68SLuiz Augusto von Dentz 	return ret;
28001da177e4SLinus Torvalds }
28011da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
28021da177e4SLinus Torvalds 
280375e0569fSMarcel Holtmann /* Reset HCI device */
280475e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
280575e0569fSMarcel Holtmann {
28061e4b6e91SColin Ian King 	static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
280775e0569fSMarcel Holtmann 	struct sk_buff *skb;
280875e0569fSMarcel Holtmann 
280975e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
281075e0569fSMarcel Holtmann 	if (!skb)
281175e0569fSMarcel Holtmann 		return -ENOMEM;
281275e0569fSMarcel Holtmann 
2813d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
281459ae1d12SJohannes Berg 	skb_put_data(skb, hw_err, 3);
281575e0569fSMarcel Holtmann 
2816de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Injecting HCI hardware error event");
2817de75cd0dSManish Mandlik 
281875e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
281975e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
282075e0569fSMarcel Holtmann }
282175e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
282275e0569fSMarcel Holtmann 
282376bca880SMarcel Holtmann /* Receive frame from HCI drivers */
2824e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
282576bca880SMarcel Holtmann {
282676bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
282776bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
282876bca880SMarcel Holtmann 		kfree_skb(skb);
282976bca880SMarcel Holtmann 		return -ENXIO;
283076bca880SMarcel Holtmann 	}
283176bca880SMarcel Holtmann 
2832d79f34e3SMarcel Holtmann 	if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT &&
2833d79f34e3SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
2834cc974003SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT &&
2835cc974003SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) {
2836fe806dceSMarcel Holtmann 		kfree_skb(skb);
2837fe806dceSMarcel Holtmann 		return -EINVAL;
2838fe806dceSMarcel Holtmann 	}
2839fe806dceSMarcel Holtmann 
2840d82603c6SJorrit Schippers 	/* Incoming skb */
284176bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
284276bca880SMarcel Holtmann 
284376bca880SMarcel Holtmann 	/* Time stamp */
284476bca880SMarcel Holtmann 	__net_timestamp(skb);
284576bca880SMarcel Holtmann 
284676bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2847b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2848c78ae283SMarcel Holtmann 
284976bca880SMarcel Holtmann 	return 0;
285076bca880SMarcel Holtmann }
285176bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
285276bca880SMarcel Holtmann 
2853e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */
2854e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
2855e875ff84SMarcel Holtmann {
2856581d6fd6SMarcel Holtmann 	/* Mark as diagnostic packet */
2857d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_DIAG_PKT;
2858581d6fd6SMarcel Holtmann 
2859e875ff84SMarcel Holtmann 	/* Time stamp */
2860e875ff84SMarcel Holtmann 	__net_timestamp(skb);
2861e875ff84SMarcel Holtmann 
2862581d6fd6SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2863581d6fd6SMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2864e875ff84SMarcel Holtmann 
2865e875ff84SMarcel Holtmann 	return 0;
2866e875ff84SMarcel Holtmann }
2867e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag);
2868e875ff84SMarcel Holtmann 
28695177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...)
28705177a838SMarcel Holtmann {
28715177a838SMarcel Holtmann 	va_list vargs;
28725177a838SMarcel Holtmann 
28735177a838SMarcel Holtmann 	va_start(vargs, fmt);
28745177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
28755177a838SMarcel Holtmann 	hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
28765177a838SMarcel Holtmann 	va_end(vargs);
28775177a838SMarcel Holtmann }
28785177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info);
28795177a838SMarcel Holtmann 
28805177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...)
28815177a838SMarcel Holtmann {
28825177a838SMarcel Holtmann 	va_list vargs;
28835177a838SMarcel Holtmann 
28845177a838SMarcel Holtmann 	va_start(vargs, fmt);
28855177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
28865177a838SMarcel Holtmann 	hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
28875177a838SMarcel Holtmann 	va_end(vargs);
28885177a838SMarcel Holtmann }
28895177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info);
28905177a838SMarcel Holtmann 
28911da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
28921da177e4SLinus Torvalds 
28931da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
28941da177e4SLinus Torvalds {
28951da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
28961da177e4SLinus Torvalds 
2897fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
289800629e0fSJohan Hedberg 	list_add_tail(&cb->list, &hci_cb_list);
2899fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
29001da177e4SLinus Torvalds 
29011da177e4SLinus Torvalds 	return 0;
29021da177e4SLinus Torvalds }
29031da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
29041da177e4SLinus Torvalds 
29051da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
29061da177e4SLinus Torvalds {
29071da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
29081da177e4SLinus Torvalds 
2909fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
29101da177e4SLinus Torvalds 	list_del(&cb->list);
2911fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
29121da177e4SLinus Torvalds 
29131da177e4SLinus Torvalds 	return 0;
29141da177e4SLinus Torvalds }
29151da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
29161da177e4SLinus Torvalds 
29172250abadSBenjamin Berg static int hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
29181da177e4SLinus Torvalds {
2919cdc52faaSMarcel Holtmann 	int err;
2920cdc52faaSMarcel Holtmann 
2921d79f34e3SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb),
2922d79f34e3SMarcel Holtmann 	       skb->len);
29231da177e4SLinus Torvalds 
29241da177e4SLinus Torvalds 	/* Time stamp */
2925a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
29261da177e4SLinus Torvalds 
2927cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2928cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2929cd82e61cSMarcel Holtmann 
2930cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2931cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2932470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
29331da177e4SLinus Torvalds 	}
29341da177e4SLinus Torvalds 
29351da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
29361da177e4SLinus Torvalds 	skb_orphan(skb);
29371da177e4SLinus Torvalds 
293873d0d3c8SMarcel Holtmann 	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
293973d0d3c8SMarcel Holtmann 		kfree_skb(skb);
29402250abadSBenjamin Berg 		return -EINVAL;
294173d0d3c8SMarcel Holtmann 	}
294273d0d3c8SMarcel Holtmann 
2943cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
2944cdc52faaSMarcel Holtmann 	if (err < 0) {
29452064ee33SMarcel Holtmann 		bt_dev_err(hdev, "sending frame failed (%d)", err);
2946cdc52faaSMarcel Holtmann 		kfree_skb(skb);
29472250abadSBenjamin Berg 		return err;
2948cdc52faaSMarcel Holtmann 	}
29492250abadSBenjamin Berg 
29502250abadSBenjamin Berg 	return 0;
29511da177e4SLinus Torvalds }
29521da177e4SLinus Torvalds 
29531ca3a9d0SJohan Hedberg /* Send HCI command */
295407dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
295507dc93ddSJohan Hedberg 		 const void *param)
29561ca3a9d0SJohan Hedberg {
29571ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
29581ca3a9d0SJohan Hedberg 
29591ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
29601ca3a9d0SJohan Hedberg 
29611ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
29621ca3a9d0SJohan Hedberg 	if (!skb) {
29632064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no memory for command");
29641ca3a9d0SJohan Hedberg 		return -ENOMEM;
29651ca3a9d0SJohan Hedberg 	}
29661ca3a9d0SJohan Hedberg 
296749c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
296811714b3dSJohan Hedberg 	 * single-command requests.
296911714b3dSJohan Hedberg 	 */
297044d27137SJohan Hedberg 	bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
297111714b3dSJohan Hedberg 
29721da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2973c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
29741da177e4SLinus Torvalds 
29751da177e4SLinus Torvalds 	return 0;
29761da177e4SLinus Torvalds }
29771da177e4SLinus Torvalds 
2978d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
2979d6ee6ad7SLoic Poulain 		   const void *param)
2980d6ee6ad7SLoic Poulain {
2981d6ee6ad7SLoic Poulain 	struct sk_buff *skb;
2982d6ee6ad7SLoic Poulain 
2983d6ee6ad7SLoic Poulain 	if (hci_opcode_ogf(opcode) != 0x3f) {
2984d6ee6ad7SLoic Poulain 		/* A controller receiving a command shall respond with either
2985d6ee6ad7SLoic Poulain 		 * a Command Status Event or a Command Complete Event.
2986d6ee6ad7SLoic Poulain 		 * Therefore, all standard HCI commands must be sent via the
2987d6ee6ad7SLoic Poulain 		 * standard API, using hci_send_cmd or hci_cmd_sync helpers.
2988d6ee6ad7SLoic Poulain 		 * Some vendors do not comply with this rule for vendor-specific
2989d6ee6ad7SLoic Poulain 		 * commands and do not return any event. We want to support
2990d6ee6ad7SLoic Poulain 		 * unresponded commands for such cases only.
2991d6ee6ad7SLoic Poulain 		 */
2992d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "unresponded command not supported");
2993d6ee6ad7SLoic Poulain 		return -EINVAL;
2994d6ee6ad7SLoic Poulain 	}
2995d6ee6ad7SLoic Poulain 
2996d6ee6ad7SLoic Poulain 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
2997d6ee6ad7SLoic Poulain 	if (!skb) {
2998d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)",
2999d6ee6ad7SLoic Poulain 			   opcode);
3000d6ee6ad7SLoic Poulain 		return -ENOMEM;
3001d6ee6ad7SLoic Poulain 	}
3002d6ee6ad7SLoic Poulain 
3003d6ee6ad7SLoic Poulain 	hci_send_frame(hdev, skb);
3004d6ee6ad7SLoic Poulain 
3005d6ee6ad7SLoic Poulain 	return 0;
3006d6ee6ad7SLoic Poulain }
3007d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send);
3008d6ee6ad7SLoic Poulain 
30091da177e4SLinus Torvalds /* Get data from the previously sent command */
3010a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
30111da177e4SLinus Torvalds {
30121da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
30131da177e4SLinus Torvalds 
30141da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
30151da177e4SLinus Torvalds 		return NULL;
30161da177e4SLinus Torvalds 
30171da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
30181da177e4SLinus Torvalds 
3019a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
30201da177e4SLinus Torvalds 		return NULL;
30211da177e4SLinus Torvalds 
3022f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
30231da177e4SLinus Torvalds 
30241da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
30251da177e4SLinus Torvalds }
30261da177e4SLinus Torvalds 
30271da177e4SLinus Torvalds /* Send ACL data */
30281da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
30291da177e4SLinus Torvalds {
30301da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
30311da177e4SLinus Torvalds 	int len = skb->len;
30321da177e4SLinus Torvalds 
3033badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3034badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
30359c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
3036aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3037aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
30381da177e4SLinus Torvalds }
30391da177e4SLinus Torvalds 
3040ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
304173d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
30421da177e4SLinus Torvalds {
3043ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
30441da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
30451da177e4SLinus Torvalds 	struct sk_buff *list;
30461da177e4SLinus Torvalds 
3047087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3048087bfd99SGustavo Padovan 	skb->data_len = 0;
3049087bfd99SGustavo Padovan 
3050d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3051204a6e54SAndrei Emeltchenko 
3052204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
3053ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
3054087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
3055204a6e54SAndrei Emeltchenko 		break;
3056204a6e54SAndrei Emeltchenko 	case HCI_AMP:
3057204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
3058204a6e54SAndrei Emeltchenko 		break;
3059204a6e54SAndrei Emeltchenko 	default:
30602064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type);
3061204a6e54SAndrei Emeltchenko 		return;
3062204a6e54SAndrei Emeltchenko 	}
3063087bfd99SGustavo Padovan 
306470f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
306570f23020SAndrei Emeltchenko 	if (!list) {
30661da177e4SLinus Torvalds 		/* Non fragmented */
30671da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
30681da177e4SLinus Torvalds 
306973d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
30701da177e4SLinus Torvalds 	} else {
30711da177e4SLinus Torvalds 		/* Fragmented */
30721da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
30731da177e4SLinus Torvalds 
30741da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
30751da177e4SLinus Torvalds 
30769cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
30779cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
30789cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
30799cfd5a23SJukka Rissanen 		 * deadlocks.
30809cfd5a23SJukka Rissanen 		 */
30819cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
30821da177e4SLinus Torvalds 
308373d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3084e702112fSAndrei Emeltchenko 
3085e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3086e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
30871da177e4SLinus Torvalds 		do {
30881da177e4SLinus Torvalds 			skb = list; list = list->next;
30891da177e4SLinus Torvalds 
3090d79f34e3SMarcel Holtmann 			hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3091e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
30921da177e4SLinus Torvalds 
30931da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
30941da177e4SLinus Torvalds 
309573d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
30961da177e4SLinus Torvalds 		} while (list);
30971da177e4SLinus Torvalds 
30989cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
30991da177e4SLinus Torvalds 	}
310073d80debSLuiz Augusto von Dentz }
310173d80debSLuiz Augusto von Dentz 
310273d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
310373d80debSLuiz Augusto von Dentz {
3104ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
310573d80debSLuiz Augusto von Dentz 
3106f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
310773d80debSLuiz Augusto von Dentz 
3108ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
31091da177e4SLinus Torvalds 
31103eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
31111da177e4SLinus Torvalds }
31121da177e4SLinus Torvalds 
31131da177e4SLinus Torvalds /* Send SCO data */
31140d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
31151da177e4SLinus Torvalds {
31161da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
31171da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
31181da177e4SLinus Torvalds 
31191da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
31201da177e4SLinus Torvalds 
3121aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
31221da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
31231da177e4SLinus Torvalds 
3124badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3125badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
31269c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
31271da177e4SLinus Torvalds 
3128d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
3129c78ae283SMarcel Holtmann 
31301da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
31313eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
31321da177e4SLinus Torvalds }
31331da177e4SLinus Torvalds 
31341da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
31351da177e4SLinus Torvalds 
31361da177e4SLinus Torvalds /* HCI Connection scheduler */
31376039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3138a8c5fb1aSGustavo Padovan 				     int *quote)
31391da177e4SLinus Torvalds {
31401da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
31418035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
3142abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
31431da177e4SLinus Torvalds 
31441da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
31451da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
3146bf4c6325SGustavo F. Padovan 
3147bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3148bf4c6325SGustavo F. Padovan 
3149bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3150769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
31511da177e4SLinus Torvalds 			continue;
3152769be974SMarcel Holtmann 
3153769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3154769be974SMarcel Holtmann 			continue;
3155769be974SMarcel Holtmann 
31561da177e4SLinus Torvalds 		num++;
31571da177e4SLinus Torvalds 
31581da177e4SLinus Torvalds 		if (c->sent < min) {
31591da177e4SLinus Torvalds 			min  = c->sent;
31601da177e4SLinus Torvalds 			conn = c;
31611da177e4SLinus Torvalds 		}
316252087a79SLuiz Augusto von Dentz 
316352087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
316452087a79SLuiz Augusto von Dentz 			break;
31651da177e4SLinus Torvalds 	}
31661da177e4SLinus Torvalds 
3167bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3168bf4c6325SGustavo F. Padovan 
31691da177e4SLinus Torvalds 	if (conn) {
31706ed58ec5SVille Tervo 		int cnt, q;
31716ed58ec5SVille Tervo 
31726ed58ec5SVille Tervo 		switch (conn->type) {
31736ed58ec5SVille Tervo 		case ACL_LINK:
31746ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
31756ed58ec5SVille Tervo 			break;
31766ed58ec5SVille Tervo 		case SCO_LINK:
31776ed58ec5SVille Tervo 		case ESCO_LINK:
31786ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
31796ed58ec5SVille Tervo 			break;
31806ed58ec5SVille Tervo 		case LE_LINK:
31816ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
31826ed58ec5SVille Tervo 			break;
31836ed58ec5SVille Tervo 		default:
31846ed58ec5SVille Tervo 			cnt = 0;
31852064ee33SMarcel Holtmann 			bt_dev_err(hdev, "unknown link type %d", conn->type);
31866ed58ec5SVille Tervo 		}
31876ed58ec5SVille Tervo 
31886ed58ec5SVille Tervo 		q = cnt / num;
31891da177e4SLinus Torvalds 		*quote = q ? q : 1;
31901da177e4SLinus Torvalds 	} else
31911da177e4SLinus Torvalds 		*quote = 0;
31921da177e4SLinus Torvalds 
31931da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
31941da177e4SLinus Torvalds 	return conn;
31951da177e4SLinus Torvalds }
31961da177e4SLinus Torvalds 
31976039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
31981da177e4SLinus Torvalds {
31991da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
32001da177e4SLinus Torvalds 	struct hci_conn *c;
32011da177e4SLinus Torvalds 
32022064ee33SMarcel Holtmann 	bt_dev_err(hdev, "link tx timeout");
32031da177e4SLinus Torvalds 
3204bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3205bf4c6325SGustavo F. Padovan 
32061da177e4SLinus Torvalds 	/* Kill stalled connections */
3207bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3208bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
32092064ee33SMarcel Holtmann 			bt_dev_err(hdev, "killing stalled connection %pMR",
32102064ee33SMarcel Holtmann 				   &c->dst);
3211bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
32121da177e4SLinus Torvalds 		}
32131da177e4SLinus Torvalds 	}
3214bf4c6325SGustavo F. Padovan 
3215bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
32161da177e4SLinus Torvalds }
32171da177e4SLinus Torvalds 
32186039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
321973d80debSLuiz Augusto von Dentz 				      int *quote)
322073d80debSLuiz Augusto von Dentz {
322173d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
322273d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3223abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
322473d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
322573d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
322673d80debSLuiz Augusto von Dentz 
322773d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
322873d80debSLuiz Augusto von Dentz 
3229bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3230bf4c6325SGustavo F. Padovan 
3231bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
323273d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
323373d80debSLuiz Augusto von Dentz 
323473d80debSLuiz Augusto von Dentz 		if (conn->type != type)
323573d80debSLuiz Augusto von Dentz 			continue;
323673d80debSLuiz Augusto von Dentz 
323773d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
323873d80debSLuiz Augusto von Dentz 			continue;
323973d80debSLuiz Augusto von Dentz 
324073d80debSLuiz Augusto von Dentz 		conn_num++;
324173d80debSLuiz Augusto von Dentz 
32428192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
324373d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
324473d80debSLuiz Augusto von Dentz 
324573d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
324673d80debSLuiz Augusto von Dentz 				continue;
324773d80debSLuiz Augusto von Dentz 
324873d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
324973d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
325073d80debSLuiz Augusto von Dentz 				continue;
325173d80debSLuiz Augusto von Dentz 
325273d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
325373d80debSLuiz Augusto von Dentz 				num = 0;
325473d80debSLuiz Augusto von Dentz 				min = ~0;
325573d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
325673d80debSLuiz Augusto von Dentz 			}
325773d80debSLuiz Augusto von Dentz 
325873d80debSLuiz Augusto von Dentz 			num++;
325973d80debSLuiz Augusto von Dentz 
326073d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
326173d80debSLuiz Augusto von Dentz 				min  = conn->sent;
326273d80debSLuiz Augusto von Dentz 				chan = tmp;
326373d80debSLuiz Augusto von Dentz 			}
326473d80debSLuiz Augusto von Dentz 		}
326573d80debSLuiz Augusto von Dentz 
326673d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
326773d80debSLuiz Augusto von Dentz 			break;
326873d80debSLuiz Augusto von Dentz 	}
326973d80debSLuiz Augusto von Dentz 
3270bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3271bf4c6325SGustavo F. Padovan 
327273d80debSLuiz Augusto von Dentz 	if (!chan)
327373d80debSLuiz Augusto von Dentz 		return NULL;
327473d80debSLuiz Augusto von Dentz 
327573d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
327673d80debSLuiz Augusto von Dentz 	case ACL_LINK:
327773d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
327873d80debSLuiz Augusto von Dentz 		break;
3279bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
3280bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
3281bd1eb66bSAndrei Emeltchenko 		break;
328273d80debSLuiz Augusto von Dentz 	case SCO_LINK:
328373d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
328473d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
328573d80debSLuiz Augusto von Dentz 		break;
328673d80debSLuiz Augusto von Dentz 	case LE_LINK:
328773d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
328873d80debSLuiz Augusto von Dentz 		break;
328973d80debSLuiz Augusto von Dentz 	default:
329073d80debSLuiz Augusto von Dentz 		cnt = 0;
32912064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown link type %d", chan->conn->type);
329273d80debSLuiz Augusto von Dentz 	}
329373d80debSLuiz Augusto von Dentz 
329473d80debSLuiz Augusto von Dentz 	q = cnt / num;
329573d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
329673d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
329773d80debSLuiz Augusto von Dentz 	return chan;
329873d80debSLuiz Augusto von Dentz }
329973d80debSLuiz Augusto von Dentz 
330002b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
330102b20f0bSLuiz Augusto von Dentz {
330202b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
330302b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
330402b20f0bSLuiz Augusto von Dentz 	int num = 0;
330502b20f0bSLuiz Augusto von Dentz 
330602b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
330702b20f0bSLuiz Augusto von Dentz 
3308bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3309bf4c6325SGustavo F. Padovan 
3310bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
331102b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
331202b20f0bSLuiz Augusto von Dentz 
331302b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
331402b20f0bSLuiz Augusto von Dentz 			continue;
331502b20f0bSLuiz Augusto von Dentz 
331602b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
331702b20f0bSLuiz Augusto von Dentz 			continue;
331802b20f0bSLuiz Augusto von Dentz 
331902b20f0bSLuiz Augusto von Dentz 		num++;
332002b20f0bSLuiz Augusto von Dentz 
33218192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
332202b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
332302b20f0bSLuiz Augusto von Dentz 
332402b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
332502b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
332602b20f0bSLuiz Augusto von Dentz 				continue;
332702b20f0bSLuiz Augusto von Dentz 			}
332802b20f0bSLuiz Augusto von Dentz 
332902b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
333002b20f0bSLuiz Augusto von Dentz 				continue;
333102b20f0bSLuiz Augusto von Dentz 
333202b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
333302b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
333402b20f0bSLuiz Augusto von Dentz 				continue;
333502b20f0bSLuiz Augusto von Dentz 
333602b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
333702b20f0bSLuiz Augusto von Dentz 
333802b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
333902b20f0bSLuiz Augusto von Dentz 			       skb->priority);
334002b20f0bSLuiz Augusto von Dentz 		}
334102b20f0bSLuiz Augusto von Dentz 
334202b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
334302b20f0bSLuiz Augusto von Dentz 			break;
334402b20f0bSLuiz Augusto von Dentz 	}
3345bf4c6325SGustavo F. Padovan 
3346bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3347bf4c6325SGustavo F. Padovan 
334802b20f0bSLuiz Augusto von Dentz }
334902b20f0bSLuiz Augusto von Dentz 
3350b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3351b71d385aSAndrei Emeltchenko {
3352b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3353b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3354b71d385aSAndrei Emeltchenko }
3355b71d385aSAndrei Emeltchenko 
33566039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
33571da177e4SLinus Torvalds {
3358d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
33591da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
33601da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
336163d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
33625f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
3363bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
33641da177e4SLinus Torvalds 	}
336563d2bc1bSAndrei Emeltchenko }
33661da177e4SLinus Torvalds 
33677fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */
33687fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev)
33697fedd3bbSAbhishek Pandit-Subedi {
33707fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
33717fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
33727fedd3bbSAbhishek Pandit-Subedi 	int quote;
33737fedd3bbSAbhishek Pandit-Subedi 
33747fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
33757fedd3bbSAbhishek Pandit-Subedi 
33767fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, SCO_LINK))
33777fedd3bbSAbhishek Pandit-Subedi 		return;
33787fedd3bbSAbhishek Pandit-Subedi 
33797fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
33807fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
33817fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
33827fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
33837fedd3bbSAbhishek Pandit-Subedi 
33847fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
33857fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
33867fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
33877fedd3bbSAbhishek Pandit-Subedi 		}
33887fedd3bbSAbhishek Pandit-Subedi 	}
33897fedd3bbSAbhishek Pandit-Subedi }
33907fedd3bbSAbhishek Pandit-Subedi 
33917fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev)
33927fedd3bbSAbhishek Pandit-Subedi {
33937fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
33947fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
33957fedd3bbSAbhishek Pandit-Subedi 	int quote;
33967fedd3bbSAbhishek Pandit-Subedi 
33977fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
33987fedd3bbSAbhishek Pandit-Subedi 
33997fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, ESCO_LINK))
34007fedd3bbSAbhishek Pandit-Subedi 		return;
34017fedd3bbSAbhishek Pandit-Subedi 
34027fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
34037fedd3bbSAbhishek Pandit-Subedi 						     &quote))) {
34047fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
34057fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
34067fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
34077fedd3bbSAbhishek Pandit-Subedi 
34087fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
34097fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
34107fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
34117fedd3bbSAbhishek Pandit-Subedi 		}
34127fedd3bbSAbhishek Pandit-Subedi 	}
34137fedd3bbSAbhishek Pandit-Subedi }
34147fedd3bbSAbhishek Pandit-Subedi 
34156039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
341663d2bc1bSAndrei Emeltchenko {
341763d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
341863d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
341963d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
342063d2bc1bSAndrei Emeltchenko 	int quote;
342163d2bc1bSAndrei Emeltchenko 
342263d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
342304837f64SMarcel Holtmann 
342473d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
342573d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3426ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3427ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
342873d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
342973d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
343073d80debSLuiz Augusto von Dentz 
3431ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3432ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3433ec1cce24SLuiz Augusto von Dentz 				break;
3434ec1cce24SLuiz Augusto von Dentz 
3435ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3436ec1cce24SLuiz Augusto von Dentz 
343773d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
343873d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
343904837f64SMarcel Holtmann 
344057d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
34411da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
34421da177e4SLinus Torvalds 
34431da177e4SLinus Torvalds 			hdev->acl_cnt--;
344473d80debSLuiz Augusto von Dentz 			chan->sent++;
344573d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
34467fedd3bbSAbhishek Pandit-Subedi 
34477fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
34487fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
34497fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
34501da177e4SLinus Torvalds 		}
34511da177e4SLinus Torvalds 	}
345202b20f0bSLuiz Augusto von Dentz 
345302b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
345402b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
34551da177e4SLinus Torvalds }
34561da177e4SLinus Torvalds 
34576039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3458b71d385aSAndrei Emeltchenko {
345963d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3460b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3461b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3462b71d385aSAndrei Emeltchenko 	int quote;
3463bd1eb66bSAndrei Emeltchenko 	u8 type;
3464b71d385aSAndrei Emeltchenko 
346563d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
3466b71d385aSAndrei Emeltchenko 
3467bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3468bd1eb66bSAndrei Emeltchenko 
3469bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3470bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3471bd1eb66bSAndrei Emeltchenko 	else
3472bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3473bd1eb66bSAndrei Emeltchenko 
3474b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3475bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3476b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3477b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3478b71d385aSAndrei Emeltchenko 			int blocks;
3479b71d385aSAndrei Emeltchenko 
3480b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3481b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3482b71d385aSAndrei Emeltchenko 
3483b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3484b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3485b71d385aSAndrei Emeltchenko 				break;
3486b71d385aSAndrei Emeltchenko 
3487b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3488b71d385aSAndrei Emeltchenko 
3489b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3490b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3491b71d385aSAndrei Emeltchenko 				return;
3492b71d385aSAndrei Emeltchenko 
3493b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3494b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3495b71d385aSAndrei Emeltchenko 
349657d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3497b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3498b71d385aSAndrei Emeltchenko 
3499b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3500b71d385aSAndrei Emeltchenko 			quote -= blocks;
3501b71d385aSAndrei Emeltchenko 
3502b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3503b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3504b71d385aSAndrei Emeltchenko 		}
3505b71d385aSAndrei Emeltchenko 	}
3506b71d385aSAndrei Emeltchenko 
3507b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3508bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3509b71d385aSAndrei Emeltchenko }
3510b71d385aSAndrei Emeltchenko 
35116039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3512b71d385aSAndrei Emeltchenko {
3513b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3514b71d385aSAndrei Emeltchenko 
3515bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3516ca8bee5dSMarcel Holtmann 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY)
3517bd1eb66bSAndrei Emeltchenko 		return;
3518bd1eb66bSAndrei Emeltchenko 
3519bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3520bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3521b71d385aSAndrei Emeltchenko 		return;
3522b71d385aSAndrei Emeltchenko 
3523b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3524b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3525b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3526b71d385aSAndrei Emeltchenko 		break;
3527b71d385aSAndrei Emeltchenko 
3528b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3529b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3530b71d385aSAndrei Emeltchenko 		break;
3531b71d385aSAndrei Emeltchenko 	}
3532b71d385aSAndrei Emeltchenko }
3533b71d385aSAndrei Emeltchenko 
35346039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
35356ed58ec5SVille Tervo {
353673d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
35376ed58ec5SVille Tervo 	struct sk_buff *skb;
353802b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
35396ed58ec5SVille Tervo 
35406ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
35416ed58ec5SVille Tervo 
354252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
354352087a79SLuiz Augusto von Dentz 		return;
354452087a79SLuiz Augusto von Dentz 
35456ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
35461b1d29e5SLuiz Augusto von Dentz 
35471b1d29e5SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt);
35481b1d29e5SLuiz Augusto von Dentz 
354902b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
355073d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3551ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3552ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
355373d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
355473d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
35556ed58ec5SVille Tervo 
3556ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3557ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3558ec1cce24SLuiz Augusto von Dentz 				break;
3559ec1cce24SLuiz Augusto von Dentz 
3560ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3561ec1cce24SLuiz Augusto von Dentz 
356257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
35636ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
35646ed58ec5SVille Tervo 
35656ed58ec5SVille Tervo 			cnt--;
356673d80debSLuiz Augusto von Dentz 			chan->sent++;
356773d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
35687fedd3bbSAbhishek Pandit-Subedi 
35697fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
35707fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
35717fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
35726ed58ec5SVille Tervo 		}
35736ed58ec5SVille Tervo 	}
357473d80debSLuiz Augusto von Dentz 
35756ed58ec5SVille Tervo 	if (hdev->le_pkts)
35766ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
35776ed58ec5SVille Tervo 	else
35786ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
357902b20f0bSLuiz Augusto von Dentz 
358002b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
358102b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
35826ed58ec5SVille Tervo }
35836ed58ec5SVille Tervo 
35843eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
35851da177e4SLinus Torvalds {
35863eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
35871da177e4SLinus Torvalds 	struct sk_buff *skb;
35881da177e4SLinus Torvalds 
35896ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
35906ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
35911da177e4SLinus Torvalds 
3592d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
35931da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
35941da177e4SLinus Torvalds 		hci_sched_sco(hdev);
3595b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
35967fedd3bbSAbhishek Pandit-Subedi 		hci_sched_acl(hdev);
35976ed58ec5SVille Tervo 		hci_sched_le(hdev);
359852de599eSMarcel Holtmann 	}
35996ed58ec5SVille Tervo 
36001da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
36011da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
360257d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
36031da177e4SLinus Torvalds }
36041da177e4SLinus Torvalds 
360525985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
36061da177e4SLinus Torvalds 
36071da177e4SLinus Torvalds /* ACL data packet */
36086039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
36091da177e4SLinus Torvalds {
36101da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
36111da177e4SLinus Torvalds 	struct hci_conn *conn;
36121da177e4SLinus Torvalds 	__u16 handle, flags;
36131da177e4SLinus Torvalds 
36141da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
36151da177e4SLinus Torvalds 
36161da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
36171da177e4SLinus Torvalds 	flags  = hci_flags(handle);
36181da177e4SLinus Torvalds 	handle = hci_handle(handle);
36191da177e4SLinus Torvalds 
3620f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3621a8c5fb1aSGustavo Padovan 	       handle, flags);
36221da177e4SLinus Torvalds 
36231da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
36241da177e4SLinus Torvalds 
36251da177e4SLinus Torvalds 	hci_dev_lock(hdev);
36261da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
36271da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
36281da177e4SLinus Torvalds 
36291da177e4SLinus Torvalds 	if (conn) {
363065983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
363104837f64SMarcel Holtmann 
36321da177e4SLinus Torvalds 		/* Send to upper protocol */
3633686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
36341da177e4SLinus Torvalds 		return;
36351da177e4SLinus Torvalds 	} else {
36362064ee33SMarcel Holtmann 		bt_dev_err(hdev, "ACL packet for unknown connection handle %d",
36372064ee33SMarcel Holtmann 			   handle);
36381da177e4SLinus Torvalds 	}
36391da177e4SLinus Torvalds 
36401da177e4SLinus Torvalds 	kfree_skb(skb);
36411da177e4SLinus Torvalds }
36421da177e4SLinus Torvalds 
36431da177e4SLinus Torvalds /* SCO data packet */
36446039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
36451da177e4SLinus Torvalds {
36461da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
36471da177e4SLinus Torvalds 	struct hci_conn *conn;
3648debdedf2SMarcel Holtmann 	__u16 handle, flags;
36491da177e4SLinus Torvalds 
36501da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
36511da177e4SLinus Torvalds 
36521da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
3653debdedf2SMarcel Holtmann 	flags  = hci_flags(handle);
3654debdedf2SMarcel Holtmann 	handle = hci_handle(handle);
36551da177e4SLinus Torvalds 
3656debdedf2SMarcel Holtmann 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3657debdedf2SMarcel Holtmann 	       handle, flags);
36581da177e4SLinus Torvalds 
36591da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
36601da177e4SLinus Torvalds 
36611da177e4SLinus Torvalds 	hci_dev_lock(hdev);
36621da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
36631da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
36641da177e4SLinus Torvalds 
36651da177e4SLinus Torvalds 	if (conn) {
36661da177e4SLinus Torvalds 		/* Send to upper protocol */
366700398e1dSAlain Michaud 		bt_cb(skb)->sco.pkt_status = flags & 0x03;
3668686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
36691da177e4SLinus Torvalds 		return;
36701da177e4SLinus Torvalds 	} else {
36712d4b37b6SLuiz Augusto von Dentz 		bt_dev_err_ratelimited(hdev, "SCO packet for unknown connection handle %d",
36722064ee33SMarcel Holtmann 				       handle);
36731da177e4SLinus Torvalds 	}
36741da177e4SLinus Torvalds 
36751da177e4SLinus Torvalds 	kfree_skb(skb);
36761da177e4SLinus Torvalds }
36771da177e4SLinus Torvalds 
36789238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
36799238f36aSJohan Hedberg {
36809238f36aSJohan Hedberg 	struct sk_buff *skb;
36819238f36aSJohan Hedberg 
36829238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
36839238f36aSJohan Hedberg 	if (!skb)
36849238f36aSJohan Hedberg 		return true;
36859238f36aSJohan Hedberg 
368644d27137SJohan Hedberg 	return (bt_cb(skb)->hci.req_flags & HCI_REQ_START);
36879238f36aSJohan Hedberg }
36889238f36aSJohan Hedberg 
368942c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
369042c6b129SJohan Hedberg {
369142c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
369242c6b129SJohan Hedberg 	struct sk_buff *skb;
369342c6b129SJohan Hedberg 	u16 opcode;
369442c6b129SJohan Hedberg 
369542c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
369642c6b129SJohan Hedberg 		return;
369742c6b129SJohan Hedberg 
369842c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
369942c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
370042c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
370142c6b129SJohan Hedberg 		return;
370242c6b129SJohan Hedberg 
370342c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
370442c6b129SJohan Hedberg 	if (!skb)
370542c6b129SJohan Hedberg 		return;
370642c6b129SJohan Hedberg 
370742c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
370842c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
370942c6b129SJohan Hedberg }
371042c6b129SJohan Hedberg 
3711e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
3712e6214487SJohan Hedberg 			  hci_req_complete_t *req_complete,
3713e6214487SJohan Hedberg 			  hci_req_complete_skb_t *req_complete_skb)
37149238f36aSJohan Hedberg {
37159238f36aSJohan Hedberg 	struct sk_buff *skb;
37169238f36aSJohan Hedberg 	unsigned long flags;
37179238f36aSJohan Hedberg 
37189238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
37199238f36aSJohan Hedberg 
372042c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
372142c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
37229238f36aSJohan Hedberg 	 */
372342c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
372442c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
372542c6b129SJohan Hedberg 		 * reset complete event during init and any pending
372642c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
372742c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
372842c6b129SJohan Hedberg 		 * command.
372942c6b129SJohan Hedberg 		 */
373042c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
373142c6b129SJohan Hedberg 			hci_resend_last(hdev);
373242c6b129SJohan Hedberg 
37339238f36aSJohan Hedberg 		return;
373442c6b129SJohan Hedberg 	}
37359238f36aSJohan Hedberg 
3736f80c5dadSJoão Paulo Rechi Vita 	/* If we reach this point this event matches the last command sent */
3737f80c5dadSJoão Paulo Rechi Vita 	hci_dev_clear_flag(hdev, HCI_CMD_PENDING);
3738f80c5dadSJoão Paulo Rechi Vita 
37399238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
37409238f36aSJohan Hedberg 	 * this request the request is not yet complete.
37419238f36aSJohan Hedberg 	 */
37429238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
37439238f36aSJohan Hedberg 		return;
37449238f36aSJohan Hedberg 
37459238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
37469238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
37479238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
37489238f36aSJohan Hedberg 	 */
374944d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) {
375044d27137SJohan Hedberg 		*req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb;
3751e6214487SJohan Hedberg 		return;
37529238f36aSJohan Hedberg 	}
3753e6214487SJohan Hedberg 
375444d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_complete) {
375544d27137SJohan Hedberg 		*req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete;
3756e6214487SJohan Hedberg 		return;
375753e21fbcSJohan Hedberg 	}
37589238f36aSJohan Hedberg 
37599238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
37609238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
37619238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
376244d27137SJohan Hedberg 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) {
37639238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
37649238f36aSJohan Hedberg 			break;
37659238f36aSJohan Hedberg 		}
37669238f36aSJohan Hedberg 
37673bd7594eSDouglas Anderson 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB)
3768242c0ebdSMarcel Holtmann 			*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
37693bd7594eSDouglas Anderson 		else
37703bd7594eSDouglas Anderson 			*req_complete = bt_cb(skb)->hci.req_complete;
37719238f36aSJohan Hedberg 		kfree_skb(skb);
37729238f36aSJohan Hedberg 	}
37739238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
37749238f36aSJohan Hedberg }
37759238f36aSJohan Hedberg 
3776b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
37771da177e4SLinus Torvalds {
3778b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
37791da177e4SLinus Torvalds 	struct sk_buff *skb;
37801da177e4SLinus Torvalds 
37811da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
37821da177e4SLinus Torvalds 
37831da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
3784cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
3785cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
3786cd82e61cSMarcel Holtmann 
37871da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
37881da177e4SLinus Torvalds 			/* Send copy to the sockets */
3789470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
37901da177e4SLinus Torvalds 		}
37911da177e4SLinus Torvalds 
3792eb8c101eSMattijs Korpershoek 		/* If the device has been opened in HCI_USER_CHANNEL,
3793eb8c101eSMattijs Korpershoek 		 * the userspace has exclusive access to device.
3794eb8c101eSMattijs Korpershoek 		 * When device is HCI_INIT, we still need to process
3795eb8c101eSMattijs Korpershoek 		 * the data packets to the driver in order
3796eb8c101eSMattijs Korpershoek 		 * to complete its setup().
3797eb8c101eSMattijs Korpershoek 		 */
3798eb8c101eSMattijs Korpershoek 		if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
3799eb8c101eSMattijs Korpershoek 		    !test_bit(HCI_INIT, &hdev->flags)) {
38001da177e4SLinus Torvalds 			kfree_skb(skb);
38011da177e4SLinus Torvalds 			continue;
38021da177e4SLinus Torvalds 		}
38031da177e4SLinus Torvalds 
38041da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
38051da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
3806d79f34e3SMarcel Holtmann 			switch (hci_skb_pkt_type(skb)) {
38071da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
38081da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
3809cc974003SMarcel Holtmann 			case HCI_ISODATA_PKT:
38101da177e4SLinus Torvalds 				kfree_skb(skb);
38111da177e4SLinus Torvalds 				continue;
38123ff50b79SStephen Hemminger 			}
38131da177e4SLinus Torvalds 		}
38141da177e4SLinus Torvalds 
38151da177e4SLinus Torvalds 		/* Process frame */
3816d79f34e3SMarcel Holtmann 		switch (hci_skb_pkt_type(skb)) {
38171da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
3818b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
38191da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
38201da177e4SLinus Torvalds 			break;
38211da177e4SLinus Torvalds 
38221da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
38231da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
38241da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
38251da177e4SLinus Torvalds 			break;
38261da177e4SLinus Torvalds 
38271da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
38281da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
38291da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
38301da177e4SLinus Torvalds 			break;
38311da177e4SLinus Torvalds 
38321da177e4SLinus Torvalds 		default:
38331da177e4SLinus Torvalds 			kfree_skb(skb);
38341da177e4SLinus Torvalds 			break;
38351da177e4SLinus Torvalds 		}
38361da177e4SLinus Torvalds 	}
38371da177e4SLinus Torvalds }
38381da177e4SLinus Torvalds 
3839c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
38401da177e4SLinus Torvalds {
3841c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
38421da177e4SLinus Torvalds 	struct sk_buff *skb;
38431da177e4SLinus Torvalds 
38442104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
38452104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
38461da177e4SLinus Torvalds 
38471da177e4SLinus Torvalds 	/* Send queued commands */
38485a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
38495a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
38505a08ecceSAndrei Emeltchenko 		if (!skb)
38515a08ecceSAndrei Emeltchenko 			return;
38525a08ecceSAndrei Emeltchenko 
38531da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
38541da177e4SLinus Torvalds 
3855a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
385670f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
38572250abadSBenjamin Berg 			int res;
3858f80c5dadSJoão Paulo Rechi Vita 			if (hci_req_status_pend(hdev))
3859f80c5dadSJoão Paulo Rechi Vita 				hci_dev_set_flag(hdev, HCI_CMD_PENDING);
38601da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
38612250abadSBenjamin Berg 
38622250abadSBenjamin Berg 			res = hci_send_frame(hdev, skb);
38632250abadSBenjamin Berg 			if (res < 0)
3864744451c1SBenjamin Berg 				__hci_cmd_sync_cancel(hdev, -res);
38652250abadSBenjamin Berg 
38667bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
386765cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
38687bdb8a5cSSzymon Janc 			else
386965cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
387065cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
38711da177e4SLinus Torvalds 		} else {
38721da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
3873c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
38741da177e4SLinus Torvalds 		}
38751da177e4SLinus Torvalds 	}
38761da177e4SLinus Torvalds }
3877