xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 2250abad)
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;
21568baaa403SAbhishek Pandit-Subedi 	entry->current_flags = flags;
21578baaa403SAbhishek Pandit-Subedi 
21588baaa403SAbhishek Pandit-Subedi 	list_add(&entry->list, list);
21598baaa403SAbhishek Pandit-Subedi 
21608baaa403SAbhishek Pandit-Subedi 	return 0;
21618baaa403SAbhishek Pandit-Subedi }
21628baaa403SAbhishek Pandit-Subedi 
2163dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2164b2a66aadSAntti Julku {
2165b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2166b2a66aadSAntti Julku 
216735f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2168dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
216935f7498aSJohan Hedberg 		return 0;
217035f7498aSJohan Hedberg 	}
2171b2a66aadSAntti Julku 
2172dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
2173d2ab0ac1SMarcel Holtmann 	if (!entry)
2174d2ab0ac1SMarcel Holtmann 		return -ENOENT;
2175d2ab0ac1SMarcel Holtmann 
2176d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
2177d2ab0ac1SMarcel Holtmann 	kfree(entry);
2178d2ab0ac1SMarcel Holtmann 
2179d2ab0ac1SMarcel Holtmann 	return 0;
2180d2ab0ac1SMarcel Holtmann }
2181d2ab0ac1SMarcel Holtmann 
2182b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2183b950aa88SAnkit Navik 							u8 type)
2184b950aa88SAnkit Navik {
2185b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
2186b950aa88SAnkit Navik 
2187b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2188b950aa88SAnkit Navik 		hci_bdaddr_list_clear(list);
2189b950aa88SAnkit Navik 		return 0;
2190b950aa88SAnkit Navik 	}
2191b950aa88SAnkit Navik 
2192b950aa88SAnkit Navik 	entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type);
2193b950aa88SAnkit Navik 	if (!entry)
2194b950aa88SAnkit Navik 		return -ENOENT;
2195b950aa88SAnkit Navik 
2196b950aa88SAnkit Navik 	list_del(&entry->list);
2197b950aa88SAnkit Navik 	kfree(entry);
2198b950aa88SAnkit Navik 
2199b950aa88SAnkit Navik 	return 0;
2200b950aa88SAnkit Navik }
2201b950aa88SAnkit Navik 
22028baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
22038baaa403SAbhishek Pandit-Subedi 				   u8 type)
22048baaa403SAbhishek Pandit-Subedi {
22058baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
22068baaa403SAbhishek Pandit-Subedi 
22078baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY)) {
22088baaa403SAbhishek Pandit-Subedi 		hci_bdaddr_list_clear(list);
22098baaa403SAbhishek Pandit-Subedi 		return 0;
22108baaa403SAbhishek Pandit-Subedi 	}
22118baaa403SAbhishek Pandit-Subedi 
22128baaa403SAbhishek Pandit-Subedi 	entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type);
22138baaa403SAbhishek Pandit-Subedi 	if (!entry)
22148baaa403SAbhishek Pandit-Subedi 		return -ENOENT;
22158baaa403SAbhishek Pandit-Subedi 
22168baaa403SAbhishek Pandit-Subedi 	list_del(&entry->list);
22178baaa403SAbhishek Pandit-Subedi 	kfree(entry);
22188baaa403SAbhishek Pandit-Subedi 
22198baaa403SAbhishek Pandit-Subedi 	return 0;
22208baaa403SAbhishek Pandit-Subedi }
22218baaa403SAbhishek Pandit-Subedi 
222215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
222315819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
222415819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
222515819a70SAndre Guedes {
222615819a70SAndre Guedes 	struct hci_conn_params *params;
222715819a70SAndre Guedes 
222815819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
222915819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
223015819a70SAndre Guedes 		    params->addr_type == addr_type) {
223115819a70SAndre Guedes 			return params;
223215819a70SAndre Guedes 		}
223315819a70SAndre Guedes 	}
223415819a70SAndre Guedes 
223515819a70SAndre Guedes 	return NULL;
223615819a70SAndre Guedes }
223715819a70SAndre Guedes 
223815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
2239501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
22404b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
224115819a70SAndre Guedes {
2242912b42efSJohan Hedberg 	struct hci_conn_params *param;
224315819a70SAndre Guedes 
2244501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
2245912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
2246912b42efSJohan Hedberg 		    param->addr_type == addr_type)
2247912b42efSJohan Hedberg 			return param;
22484b10966fSMarcel Holtmann 	}
22494b10966fSMarcel Holtmann 
22504b10966fSMarcel Holtmann 	return NULL;
225115819a70SAndre Guedes }
225215819a70SAndre Guedes 
225315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
225451d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
225551d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
225615819a70SAndre Guedes {
225715819a70SAndre Guedes 	struct hci_conn_params *params;
225815819a70SAndre Guedes 
225915819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
2260cef952ceSAndre Guedes 	if (params)
226151d167c0SMarcel Holtmann 		return params;
226215819a70SAndre Guedes 
226315819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
226415819a70SAndre Guedes 	if (!params) {
22652064ee33SMarcel Holtmann 		bt_dev_err(hdev, "out of memory");
226651d167c0SMarcel Holtmann 		return NULL;
226715819a70SAndre Guedes 	}
226815819a70SAndre Guedes 
226915819a70SAndre Guedes 	bacpy(&params->addr, addr);
227015819a70SAndre Guedes 	params->addr_type = addr_type;
2271cef952ceSAndre Guedes 
2272cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
227393450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
2274cef952ceSAndre Guedes 
2275bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
2276bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
2277bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
2278bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
2279bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
2280bf5b3c8bSMarcel Holtmann 
2281bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
2282bf5b3c8bSMarcel Holtmann 
228351d167c0SMarcel Holtmann 	return params;
2284bf5b3c8bSMarcel Holtmann }
2285bf5b3c8bSMarcel Holtmann 
2286f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params)
2287f6c63249SJohan Hedberg {
2288f6c63249SJohan Hedberg 	if (params->conn) {
2289f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
2290f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
2291f6c63249SJohan Hedberg 	}
2292f6c63249SJohan Hedberg 
2293f6c63249SJohan Hedberg 	list_del(&params->action);
2294f6c63249SJohan Hedberg 	list_del(&params->list);
2295f6c63249SJohan Hedberg 	kfree(params);
2296f6c63249SJohan Hedberg }
2297f6c63249SJohan Hedberg 
229815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
229915819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
230015819a70SAndre Guedes {
230115819a70SAndre Guedes 	struct hci_conn_params *params;
230215819a70SAndre Guedes 
230315819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
230415819a70SAndre Guedes 	if (!params)
230515819a70SAndre Guedes 		return;
230615819a70SAndre Guedes 
2307f6c63249SJohan Hedberg 	hci_conn_params_free(params);
230815819a70SAndre Guedes 
23095bee2fd6SLuiz Augusto von Dentz 	hci_update_passive_scan(hdev);
231095305baaSJohan Hedberg 
231115819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
231215819a70SAndre Guedes }
231315819a70SAndre Guedes 
231415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
231555af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
231615819a70SAndre Guedes {
231715819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
231815819a70SAndre Guedes 
231915819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
232055af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
232155af49a8SJohan Hedberg 			continue;
2322f75113a2SJakub Pawlowski 
232391641b79SZheng Yongjun 		/* If trying to establish one time connection to disabled
2324f75113a2SJakub Pawlowski 		 * device, leave the params, but mark them as just once.
2325f75113a2SJakub Pawlowski 		 */
2326f75113a2SJakub Pawlowski 		if (params->explicit_connect) {
2327f75113a2SJakub Pawlowski 			params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
2328f75113a2SJakub Pawlowski 			continue;
2329f75113a2SJakub Pawlowski 		}
2330f75113a2SJakub Pawlowski 
233115819a70SAndre Guedes 		list_del(&params->list);
233215819a70SAndre Guedes 		kfree(params);
233315819a70SAndre Guedes 	}
233415819a70SAndre Guedes 
233555af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
233655af49a8SJohan Hedberg }
233755af49a8SJohan Hedberg 
233855af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
2339030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev)
234015819a70SAndre Guedes {
234115819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
234215819a70SAndre Guedes 
2343f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
2344f6c63249SJohan Hedberg 		hci_conn_params_free(params);
234515819a70SAndre Guedes 
234615819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
234715819a70SAndre Guedes }
234815819a70SAndre Guedes 
2349a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
2350a1f4c318SJohan Hedberg  *
2351a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
2352a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
2353a1f4c318SJohan Hedberg  * the static random address.
2354a1f4c318SJohan Hedberg  *
2355a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
2356a1f4c318SJohan Hedberg  * public address to use the static random address instead.
235750b5b952SMarcel Holtmann  *
235850b5b952SMarcel Holtmann  * In case BR/EDR has been disabled on a dual-mode controller and
235950b5b952SMarcel Holtmann  * userspace has configured a static address, then that address
236050b5b952SMarcel Holtmann  * becomes the identity address instead of the public BR/EDR address.
2361a1f4c318SJohan Hedberg  */
2362a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
2363a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
2364a1f4c318SJohan Hedberg {
2365b7cb93e5SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
236650b5b952SMarcel Holtmann 	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
2367d7a5a11dSMarcel Holtmann 	    (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
236850b5b952SMarcel Holtmann 	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
2369a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
2370a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
2371a1f4c318SJohan Hedberg 	} else {
2372a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
2373a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
2374a1f4c318SJohan Hedberg 	}
2375a1f4c318SJohan Hedberg }
2376a1f4c318SJohan Hedberg 
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);
2506b1b813d4SDavid Herrmann 
25078961987fSKiran K 	INIT_LIST_HEAD(&hdev->local_codecs);
2508b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2509b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2510b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2511b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2512c7741d16SMarcel Holtmann 	INIT_WORK(&hdev->error_reset, hci_error_reset);
2513b1b813d4SDavid Herrmann 
25146a98e383SMarcel Holtmann 	hci_cmd_sync_init(hdev);
25156a98e383SMarcel Holtmann 
2516b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2517b1b813d4SDavid Herrmann 
2518b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2519b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2520b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2521b1b813d4SDavid Herrmann 
2522b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2523b1b813d4SDavid Herrmann 
252465cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
2525de75cd0dSManish Mandlik 	INIT_DELAYED_WORK(&hdev->ncmd_timer, hci_ncmd_timeout);
2526b1b813d4SDavid Herrmann 
25275fc16cc4SJohan Hedberg 	hci_request_setup(hdev);
25285fc16cc4SJohan Hedberg 
2529b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2530b1b813d4SDavid Herrmann 	discovery_init(hdev);
25319be0dab7SDavid Herrmann 
25329be0dab7SDavid Herrmann 	return hdev;
25339be0dab7SDavid Herrmann }
25346ec56613STedd Ho-Jeong An EXPORT_SYMBOL(hci_alloc_dev_priv);
25359be0dab7SDavid Herrmann 
25369be0dab7SDavid Herrmann /* Free HCI device */
25379be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
25389be0dab7SDavid Herrmann {
25399be0dab7SDavid Herrmann 	/* will free via device release */
25409be0dab7SDavid Herrmann 	put_device(&hdev->dev);
25419be0dab7SDavid Herrmann }
25429be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
25439be0dab7SDavid Herrmann 
25441da177e4SLinus Torvalds /* Register HCI device */
25451da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
25461da177e4SLinus Torvalds {
2547b1b813d4SDavid Herrmann 	int id, error;
25481da177e4SLinus Torvalds 
254974292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
25501da177e4SLinus Torvalds 		return -EINVAL;
25511da177e4SLinus Torvalds 
255208add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
255308add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
255408add513SMat Martineau 	 */
25553df92b31SSasha Levin 	switch (hdev->dev_type) {
2556ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
25573df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
25581da177e4SLinus Torvalds 		break;
25593df92b31SSasha Levin 	case HCI_AMP:
25603df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
25613df92b31SSasha Levin 		break;
25623df92b31SSasha Levin 	default:
25633df92b31SSasha Levin 		return -EINVAL;
25641da177e4SLinus Torvalds 	}
25651da177e4SLinus Torvalds 
25663df92b31SSasha Levin 	if (id < 0)
25673df92b31SSasha Levin 		return id;
25683df92b31SSasha Levin 
25691da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
25701da177e4SLinus Torvalds 	hdev->id = id;
25712d8b3a11SAndrei Emeltchenko 
25722d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
25732d8b3a11SAndrei Emeltchenko 
257429e2dd0dSTejun Heo 	hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name);
257533ca954dSDavid Herrmann 	if (!hdev->workqueue) {
257633ca954dSDavid Herrmann 		error = -ENOMEM;
257733ca954dSDavid Herrmann 		goto err;
257833ca954dSDavid Herrmann 	}
2579f48fd9c8SMarcel Holtmann 
258029e2dd0dSTejun Heo 	hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI,
258129e2dd0dSTejun Heo 						      hdev->name);
25826ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
25836ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
25846ead1bbcSJohan Hedberg 		error = -ENOMEM;
25856ead1bbcSJohan Hedberg 		goto err;
25866ead1bbcSJohan Hedberg 	}
25876ead1bbcSJohan Hedberg 
25880153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
25890153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
25900153e2ecSMarcel Holtmann 
2591bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
2592bdc3e0f1SMarcel Holtmann 
2593bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
259433ca954dSDavid Herrmann 	if (error < 0)
259554506918SJohan Hedberg 		goto err_wqueue;
25961da177e4SLinus Torvalds 
25976d5d2ee6SHeiner Kallweit 	hci_leds_init(hdev);
25986d5d2ee6SHeiner Kallweit 
2599611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2600a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2601a8c5fb1aSGustavo Padovan 				    hdev);
2602611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2603611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
2604611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
2605611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
2606611b30f7SMarcel Holtmann 		}
2607611b30f7SMarcel Holtmann 	}
2608611b30f7SMarcel Holtmann 
26095e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
2610a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
26115e130367SJohan Hedberg 
2612a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_SETUP);
2613a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_AUTO_OFF);
2614ce2be9acSAndrei Emeltchenko 
2615ca8bee5dSMarcel Holtmann 	if (hdev->dev_type == HCI_PRIMARY) {
261656f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
261756f87901SJohan Hedberg 		 * through reading supported features during init.
261856f87901SJohan Hedberg 		 */
2619a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
262056f87901SJohan Hedberg 	}
2621ce2be9acSAndrei Emeltchenko 
2622fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
2623fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
2624fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
2625fcee3377SGustavo Padovan 
26264a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
26274a964404SMarcel Holtmann 	 * and should not be included in normal operation.
2628fee746b0SMarcel Holtmann 	 */
2629fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
2630a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
2631fee746b0SMarcel Holtmann 
263205fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_REG);
2633dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
26341da177e4SLinus Torvalds 
2635219991e6SHans de Goede 	if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
26369952d90eSAbhishek Pandit-Subedi 		hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
26379952d90eSAbhishek Pandit-Subedi 		error = register_pm_notifier(&hdev->suspend_notifier);
26389952d90eSAbhishek Pandit-Subedi 		if (error)
26399952d90eSAbhishek Pandit-Subedi 			goto err_wqueue;
2640219991e6SHans de Goede 	}
26419952d90eSAbhishek Pandit-Subedi 
264219202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2643fbe96d6fSMarcel Holtmann 
2644e5e1e7fdSMiao-chen Chou 	idr_init(&hdev->adv_monitors_idr);
26455031ffccSMiao-chen Chou 	msft_register(hdev);
2646e5e1e7fdSMiao-chen Chou 
26471da177e4SLinus Torvalds 	return id;
2648f48fd9c8SMarcel Holtmann 
264933ca954dSDavid Herrmann err_wqueue:
26505a4bb6a8SWei Yongjun 	debugfs_remove_recursive(hdev->debugfs);
265133ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
26526ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
265333ca954dSDavid Herrmann err:
26543df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
2655f48fd9c8SMarcel Holtmann 
265633ca954dSDavid Herrmann 	return error;
26571da177e4SLinus Torvalds }
26581da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
26591da177e4SLinus Torvalds 
26601da177e4SLinus Torvalds /* Unregister HCI device */
266159735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
26621da177e4SLinus Torvalds {
2663c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
26641da177e4SLinus Torvalds 
2665a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_UNREGISTER);
266694324962SJohan Hovold 
2667f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
26681da177e4SLinus Torvalds 	list_del(&hdev->list);
2669f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
26701da177e4SLinus Torvalds 
2671b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
2672b9b5ef18SGustavo Padovan 
26736a98e383SMarcel Holtmann 	hci_cmd_sync_clear(hdev);
26746a98e383SMarcel Holtmann 
2675182ee45dSLuiz Augusto von Dentz 	if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks))
26769952d90eSAbhishek Pandit-Subedi 		unregister_pm_notifier(&hdev->suspend_notifier);
26774e8c36c3SAbhishek Pandit-Subedi 
26785031ffccSMiao-chen Chou 	msft_unregister(hdev);
26795031ffccSMiao-chen Chou 
26804e8c36c3SAbhishek Pandit-Subedi 	hci_dev_do_close(hdev);
26819952d90eSAbhishek Pandit-Subedi 
2682ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2683d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_SETUP) &&
2684d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
268509fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2686744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
268709fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
268856e5cb86SJohan Hedberg 	}
2689ab81cbf9SJohan Hedberg 
26902e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
26912e58ef3eSJohan Hedberg 	 * pending list */
26922e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
26932e58ef3eSJohan Hedberg 
269405fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_UNREG);
26951da177e4SLinus Torvalds 
2696611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2697611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2698611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2699611b30f7SMarcel Holtmann 	}
2700611b30f7SMarcel Holtmann 
2701bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
2702e61fbee7SDavid S. Miller 	/* Actual cleanup is deferred until hci_release_dev(). */
2703e0448092STetsuo Handa 	hci_dev_put(hdev);
2704e0448092STetsuo Handa }
2705e0448092STetsuo Handa EXPORT_SYMBOL(hci_unregister_dev);
2706147e2d59SDave Young 
270758ce6d5bSTetsuo Handa /* Release HCI device */
270858ce6d5bSTetsuo Handa void hci_release_dev(struct hci_dev *hdev)
2709e0448092STetsuo Handa {
27100153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
27115177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
27125177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
27130153e2ecSMarcel Holtmann 
2714f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
27156ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2716f48fd9c8SMarcel Holtmann 
271709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
27183d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->reject_list);
27193d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->accept_list);
27202aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
272155ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2722b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
2723970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
27242763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
2725d2609b34SFlorian Grandel 	hci_adv_instances_clear(hdev);
2726e5e1e7fdSMiao-chen Chou 	hci_adv_monitors_clear(hdev);
27273d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
2728cfdb0c2dSAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
2729373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
273022078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
2731600a8749SAlain Michaud 	hci_blocked_keys_clear(hdev);
273209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2733e2e0cacbSJohan Hedberg 
2734e0448092STetsuo Handa 	ida_simple_remove(&hci_index_ida, hdev->id);
273558ce6d5bSTetsuo Handa 	kfree(hdev);
27361da177e4SLinus Torvalds }
273758ce6d5bSTetsuo Handa EXPORT_SYMBOL(hci_release_dev);
27381da177e4SLinus Torvalds 
27391da177e4SLinus Torvalds /* Suspend HCI device */
27401da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
27411da177e4SLinus Torvalds {
2742e1b77d68SLuiz Augusto von Dentz 	int ret;
2743e1b77d68SLuiz Augusto von Dentz 
2744e1b77d68SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
2745e1b77d68SLuiz Augusto von Dentz 
2746e1b77d68SLuiz Augusto von Dentz 	/* Suspend should only act on when powered. */
2747e1b77d68SLuiz Augusto von Dentz 	if (!hdev_is_powered(hdev) ||
2748e1b77d68SLuiz Augusto von Dentz 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
27491da177e4SLinus Torvalds 		return 0;
2750e1b77d68SLuiz Augusto von Dentz 
2751182ee45dSLuiz Augusto von Dentz 	/* If powering down don't attempt to suspend */
2752182ee45dSLuiz Augusto von Dentz 	if (mgmt_powering_down(hdev))
2753182ee45dSLuiz Augusto von Dentz 		return 0;
2754e1b77d68SLuiz Augusto von Dentz 
2755182ee45dSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
2756182ee45dSLuiz Augusto von Dentz 	ret = hci_suspend_sync(hdev);
2757182ee45dSLuiz Augusto von Dentz 	hci_req_sync_unlock(hdev);
27584539ca67SLuiz Augusto von Dentz 
2759e1b77d68SLuiz Augusto von Dentz 	hci_clear_wake_reason(hdev);
2760182ee45dSLuiz Augusto von Dentz 	mgmt_suspending(hdev, hdev->suspend_state);
2761e1b77d68SLuiz Augusto von Dentz 
2762e1b77d68SLuiz Augusto von Dentz 	hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
2763e1b77d68SLuiz Augusto von Dentz 	return ret;
27641da177e4SLinus Torvalds }
27651da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
27661da177e4SLinus Torvalds 
27671da177e4SLinus Torvalds /* Resume HCI device */
27681da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
27691da177e4SLinus Torvalds {
2770e1b77d68SLuiz Augusto von Dentz 	int ret;
2771e1b77d68SLuiz Augusto von Dentz 
2772e1b77d68SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
2773e1b77d68SLuiz Augusto von Dentz 
2774e1b77d68SLuiz Augusto von Dentz 	/* Resume should only act on when powered. */
2775e1b77d68SLuiz Augusto von Dentz 	if (!hdev_is_powered(hdev) ||
2776e1b77d68SLuiz Augusto von Dentz 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
27771da177e4SLinus Torvalds 		return 0;
2778e1b77d68SLuiz Augusto von Dentz 
2779e1b77d68SLuiz Augusto von Dentz 	/* If powering down don't attempt to resume */
2780e1b77d68SLuiz Augusto von Dentz 	if (mgmt_powering_down(hdev))
2781e1b77d68SLuiz Augusto von Dentz 		return 0;
2782e1b77d68SLuiz Augusto von Dentz 
2783182ee45dSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
2784182ee45dSLuiz Augusto von Dentz 	ret = hci_resume_sync(hdev);
2785182ee45dSLuiz Augusto von Dentz 	hci_req_sync_unlock(hdev);
2786e1b77d68SLuiz Augusto von Dentz 
2787e1b77d68SLuiz Augusto von Dentz 	mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr,
2788e1b77d68SLuiz Augusto von Dentz 		      hdev->wake_addr_type);
2789e1b77d68SLuiz Augusto von Dentz 
2790e1b77d68SLuiz Augusto von Dentz 	hci_sock_dev_event(hdev, HCI_DEV_RESUME);
2791e1b77d68SLuiz Augusto von Dentz 	return ret;
27921da177e4SLinus Torvalds }
27931da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
27941da177e4SLinus Torvalds 
279575e0569fSMarcel Holtmann /* Reset HCI device */
279675e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
279775e0569fSMarcel Holtmann {
27981e4b6e91SColin Ian King 	static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
279975e0569fSMarcel Holtmann 	struct sk_buff *skb;
280075e0569fSMarcel Holtmann 
280175e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
280275e0569fSMarcel Holtmann 	if (!skb)
280375e0569fSMarcel Holtmann 		return -ENOMEM;
280475e0569fSMarcel Holtmann 
2805d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
280659ae1d12SJohannes Berg 	skb_put_data(skb, hw_err, 3);
280775e0569fSMarcel Holtmann 
2808de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Injecting HCI hardware error event");
2809de75cd0dSManish Mandlik 
281075e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
281175e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
281275e0569fSMarcel Holtmann }
281375e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
281475e0569fSMarcel Holtmann 
281576bca880SMarcel Holtmann /* Receive frame from HCI drivers */
2816e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
281776bca880SMarcel Holtmann {
281876bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
281976bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
282076bca880SMarcel Holtmann 		kfree_skb(skb);
282176bca880SMarcel Holtmann 		return -ENXIO;
282276bca880SMarcel Holtmann 	}
282376bca880SMarcel Holtmann 
2824d79f34e3SMarcel Holtmann 	if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT &&
2825d79f34e3SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
2826cc974003SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT &&
2827cc974003SMarcel Holtmann 	    hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) {
2828fe806dceSMarcel Holtmann 		kfree_skb(skb);
2829fe806dceSMarcel Holtmann 		return -EINVAL;
2830fe806dceSMarcel Holtmann 	}
2831fe806dceSMarcel Holtmann 
2832d82603c6SJorrit Schippers 	/* Incoming skb */
283376bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
283476bca880SMarcel Holtmann 
283576bca880SMarcel Holtmann 	/* Time stamp */
283676bca880SMarcel Holtmann 	__net_timestamp(skb);
283776bca880SMarcel Holtmann 
283876bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2839b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2840c78ae283SMarcel Holtmann 
284176bca880SMarcel Holtmann 	return 0;
284276bca880SMarcel Holtmann }
284376bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
284476bca880SMarcel Holtmann 
2845e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */
2846e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
2847e875ff84SMarcel Holtmann {
2848581d6fd6SMarcel Holtmann 	/* Mark as diagnostic packet */
2849d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_DIAG_PKT;
2850581d6fd6SMarcel Holtmann 
2851e875ff84SMarcel Holtmann 	/* Time stamp */
2852e875ff84SMarcel Holtmann 	__net_timestamp(skb);
2853e875ff84SMarcel Holtmann 
2854581d6fd6SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2855581d6fd6SMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2856e875ff84SMarcel Holtmann 
2857e875ff84SMarcel Holtmann 	return 0;
2858e875ff84SMarcel Holtmann }
2859e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag);
2860e875ff84SMarcel Holtmann 
28615177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...)
28625177a838SMarcel Holtmann {
28635177a838SMarcel Holtmann 	va_list vargs;
28645177a838SMarcel Holtmann 
28655177a838SMarcel Holtmann 	va_start(vargs, fmt);
28665177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
28675177a838SMarcel Holtmann 	hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
28685177a838SMarcel Holtmann 	va_end(vargs);
28695177a838SMarcel Holtmann }
28705177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info);
28715177a838SMarcel Holtmann 
28725177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...)
28735177a838SMarcel Holtmann {
28745177a838SMarcel Holtmann 	va_list vargs;
28755177a838SMarcel Holtmann 
28765177a838SMarcel Holtmann 	va_start(vargs, fmt);
28775177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
28785177a838SMarcel Holtmann 	hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
28795177a838SMarcel Holtmann 	va_end(vargs);
28805177a838SMarcel Holtmann }
28815177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info);
28825177a838SMarcel Holtmann 
28831da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
28841da177e4SLinus Torvalds 
28851da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
28861da177e4SLinus Torvalds {
28871da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
28881da177e4SLinus Torvalds 
2889fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
289000629e0fSJohan Hedberg 	list_add_tail(&cb->list, &hci_cb_list);
2891fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
28921da177e4SLinus Torvalds 
28931da177e4SLinus Torvalds 	return 0;
28941da177e4SLinus Torvalds }
28951da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
28961da177e4SLinus Torvalds 
28971da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
28981da177e4SLinus Torvalds {
28991da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
29001da177e4SLinus Torvalds 
2901fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
29021da177e4SLinus Torvalds 	list_del(&cb->list);
2903fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
29041da177e4SLinus Torvalds 
29051da177e4SLinus Torvalds 	return 0;
29061da177e4SLinus Torvalds }
29071da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
29081da177e4SLinus Torvalds 
2909*2250abadSBenjamin Berg static int hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
29101da177e4SLinus Torvalds {
2911cdc52faaSMarcel Holtmann 	int err;
2912cdc52faaSMarcel Holtmann 
2913d79f34e3SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb),
2914d79f34e3SMarcel Holtmann 	       skb->len);
29151da177e4SLinus Torvalds 
29161da177e4SLinus Torvalds 	/* Time stamp */
2917a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
29181da177e4SLinus Torvalds 
2919cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2920cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2921cd82e61cSMarcel Holtmann 
2922cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2923cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2924470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
29251da177e4SLinus Torvalds 	}
29261da177e4SLinus Torvalds 
29271da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
29281da177e4SLinus Torvalds 	skb_orphan(skb);
29291da177e4SLinus Torvalds 
293073d0d3c8SMarcel Holtmann 	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
293173d0d3c8SMarcel Holtmann 		kfree_skb(skb);
2932*2250abadSBenjamin Berg 		return -EINVAL;
293373d0d3c8SMarcel Holtmann 	}
293473d0d3c8SMarcel Holtmann 
2935cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
2936cdc52faaSMarcel Holtmann 	if (err < 0) {
29372064ee33SMarcel Holtmann 		bt_dev_err(hdev, "sending frame failed (%d)", err);
2938cdc52faaSMarcel Holtmann 		kfree_skb(skb);
2939*2250abadSBenjamin Berg 		return err;
2940cdc52faaSMarcel Holtmann 	}
2941*2250abadSBenjamin Berg 
2942*2250abadSBenjamin Berg 	return 0;
29431da177e4SLinus Torvalds }
29441da177e4SLinus Torvalds 
29451ca3a9d0SJohan Hedberg /* Send HCI command */
294607dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
294707dc93ddSJohan Hedberg 		 const void *param)
29481ca3a9d0SJohan Hedberg {
29491ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
29501ca3a9d0SJohan Hedberg 
29511ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
29521ca3a9d0SJohan Hedberg 
29531ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
29541ca3a9d0SJohan Hedberg 	if (!skb) {
29552064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no memory for command");
29561ca3a9d0SJohan Hedberg 		return -ENOMEM;
29571ca3a9d0SJohan Hedberg 	}
29581ca3a9d0SJohan Hedberg 
295949c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
296011714b3dSJohan Hedberg 	 * single-command requests.
296111714b3dSJohan Hedberg 	 */
296244d27137SJohan Hedberg 	bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
296311714b3dSJohan Hedberg 
29641da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2965c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
29661da177e4SLinus Torvalds 
29671da177e4SLinus Torvalds 	return 0;
29681da177e4SLinus Torvalds }
29691da177e4SLinus Torvalds 
2970d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
2971d6ee6ad7SLoic Poulain 		   const void *param)
2972d6ee6ad7SLoic Poulain {
2973d6ee6ad7SLoic Poulain 	struct sk_buff *skb;
2974d6ee6ad7SLoic Poulain 
2975d6ee6ad7SLoic Poulain 	if (hci_opcode_ogf(opcode) != 0x3f) {
2976d6ee6ad7SLoic Poulain 		/* A controller receiving a command shall respond with either
2977d6ee6ad7SLoic Poulain 		 * a Command Status Event or a Command Complete Event.
2978d6ee6ad7SLoic Poulain 		 * Therefore, all standard HCI commands must be sent via the
2979d6ee6ad7SLoic Poulain 		 * standard API, using hci_send_cmd or hci_cmd_sync helpers.
2980d6ee6ad7SLoic Poulain 		 * Some vendors do not comply with this rule for vendor-specific
2981d6ee6ad7SLoic Poulain 		 * commands and do not return any event. We want to support
2982d6ee6ad7SLoic Poulain 		 * unresponded commands for such cases only.
2983d6ee6ad7SLoic Poulain 		 */
2984d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "unresponded command not supported");
2985d6ee6ad7SLoic Poulain 		return -EINVAL;
2986d6ee6ad7SLoic Poulain 	}
2987d6ee6ad7SLoic Poulain 
2988d6ee6ad7SLoic Poulain 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
2989d6ee6ad7SLoic Poulain 	if (!skb) {
2990d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)",
2991d6ee6ad7SLoic Poulain 			   opcode);
2992d6ee6ad7SLoic Poulain 		return -ENOMEM;
2993d6ee6ad7SLoic Poulain 	}
2994d6ee6ad7SLoic Poulain 
2995d6ee6ad7SLoic Poulain 	hci_send_frame(hdev, skb);
2996d6ee6ad7SLoic Poulain 
2997d6ee6ad7SLoic Poulain 	return 0;
2998d6ee6ad7SLoic Poulain }
2999d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send);
3000d6ee6ad7SLoic Poulain 
30011da177e4SLinus Torvalds /* Get data from the previously sent command */
3002a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
30031da177e4SLinus Torvalds {
30041da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
30051da177e4SLinus Torvalds 
30061da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
30071da177e4SLinus Torvalds 		return NULL;
30081da177e4SLinus Torvalds 
30091da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
30101da177e4SLinus Torvalds 
3011a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
30121da177e4SLinus Torvalds 		return NULL;
30131da177e4SLinus Torvalds 
3014f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
30151da177e4SLinus Torvalds 
30161da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
30171da177e4SLinus Torvalds }
30181da177e4SLinus Torvalds 
30191da177e4SLinus Torvalds /* Send ACL data */
30201da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
30211da177e4SLinus Torvalds {
30221da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
30231da177e4SLinus Torvalds 	int len = skb->len;
30241da177e4SLinus Torvalds 
3025badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3026badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
30279c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
3028aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3029aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
30301da177e4SLinus Torvalds }
30311da177e4SLinus Torvalds 
3032ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
303373d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
30341da177e4SLinus Torvalds {
3035ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
30361da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
30371da177e4SLinus Torvalds 	struct sk_buff *list;
30381da177e4SLinus Torvalds 
3039087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3040087bfd99SGustavo Padovan 	skb->data_len = 0;
3041087bfd99SGustavo Padovan 
3042d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3043204a6e54SAndrei Emeltchenko 
3044204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
3045ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
3046087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
3047204a6e54SAndrei Emeltchenko 		break;
3048204a6e54SAndrei Emeltchenko 	case HCI_AMP:
3049204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
3050204a6e54SAndrei Emeltchenko 		break;
3051204a6e54SAndrei Emeltchenko 	default:
30522064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type);
3053204a6e54SAndrei Emeltchenko 		return;
3054204a6e54SAndrei Emeltchenko 	}
3055087bfd99SGustavo Padovan 
305670f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
305770f23020SAndrei Emeltchenko 	if (!list) {
30581da177e4SLinus Torvalds 		/* Non fragmented */
30591da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
30601da177e4SLinus Torvalds 
306173d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
30621da177e4SLinus Torvalds 	} else {
30631da177e4SLinus Torvalds 		/* Fragmented */
30641da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
30651da177e4SLinus Torvalds 
30661da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
30671da177e4SLinus Torvalds 
30689cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
30699cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
30709cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
30719cfd5a23SJukka Rissanen 		 * deadlocks.
30729cfd5a23SJukka Rissanen 		 */
30739cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
30741da177e4SLinus Torvalds 
307573d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3076e702112fSAndrei Emeltchenko 
3077e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3078e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
30791da177e4SLinus Torvalds 		do {
30801da177e4SLinus Torvalds 			skb = list; list = list->next;
30811da177e4SLinus Torvalds 
3082d79f34e3SMarcel Holtmann 			hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3083e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
30841da177e4SLinus Torvalds 
30851da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
30861da177e4SLinus Torvalds 
308773d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
30881da177e4SLinus Torvalds 		} while (list);
30891da177e4SLinus Torvalds 
30909cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
30911da177e4SLinus Torvalds 	}
309273d80debSLuiz Augusto von Dentz }
309373d80debSLuiz Augusto von Dentz 
309473d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
309573d80debSLuiz Augusto von Dentz {
3096ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
309773d80debSLuiz Augusto von Dentz 
3098f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
309973d80debSLuiz Augusto von Dentz 
3100ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
31011da177e4SLinus Torvalds 
31023eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
31031da177e4SLinus Torvalds }
31041da177e4SLinus Torvalds 
31051da177e4SLinus Torvalds /* Send SCO data */
31060d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
31071da177e4SLinus Torvalds {
31081da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
31091da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
31101da177e4SLinus Torvalds 
31111da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
31121da177e4SLinus Torvalds 
3113aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
31141da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
31151da177e4SLinus Torvalds 
3116badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3117badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
31189c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
31191da177e4SLinus Torvalds 
3120d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
3121c78ae283SMarcel Holtmann 
31221da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
31233eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
31241da177e4SLinus Torvalds }
31251da177e4SLinus Torvalds 
31261da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
31271da177e4SLinus Torvalds 
31281da177e4SLinus Torvalds /* HCI Connection scheduler */
31296039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3130a8c5fb1aSGustavo Padovan 				     int *quote)
31311da177e4SLinus Torvalds {
31321da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
31338035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
3134abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
31351da177e4SLinus Torvalds 
31361da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
31371da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
3138bf4c6325SGustavo F. Padovan 
3139bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3140bf4c6325SGustavo F. Padovan 
3141bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3142769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
31431da177e4SLinus Torvalds 			continue;
3144769be974SMarcel Holtmann 
3145769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3146769be974SMarcel Holtmann 			continue;
3147769be974SMarcel Holtmann 
31481da177e4SLinus Torvalds 		num++;
31491da177e4SLinus Torvalds 
31501da177e4SLinus Torvalds 		if (c->sent < min) {
31511da177e4SLinus Torvalds 			min  = c->sent;
31521da177e4SLinus Torvalds 			conn = c;
31531da177e4SLinus Torvalds 		}
315452087a79SLuiz Augusto von Dentz 
315552087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
315652087a79SLuiz Augusto von Dentz 			break;
31571da177e4SLinus Torvalds 	}
31581da177e4SLinus Torvalds 
3159bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3160bf4c6325SGustavo F. Padovan 
31611da177e4SLinus Torvalds 	if (conn) {
31626ed58ec5SVille Tervo 		int cnt, q;
31636ed58ec5SVille Tervo 
31646ed58ec5SVille Tervo 		switch (conn->type) {
31656ed58ec5SVille Tervo 		case ACL_LINK:
31666ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
31676ed58ec5SVille Tervo 			break;
31686ed58ec5SVille Tervo 		case SCO_LINK:
31696ed58ec5SVille Tervo 		case ESCO_LINK:
31706ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
31716ed58ec5SVille Tervo 			break;
31726ed58ec5SVille Tervo 		case LE_LINK:
31736ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
31746ed58ec5SVille Tervo 			break;
31756ed58ec5SVille Tervo 		default:
31766ed58ec5SVille Tervo 			cnt = 0;
31772064ee33SMarcel Holtmann 			bt_dev_err(hdev, "unknown link type %d", conn->type);
31786ed58ec5SVille Tervo 		}
31796ed58ec5SVille Tervo 
31806ed58ec5SVille Tervo 		q = cnt / num;
31811da177e4SLinus Torvalds 		*quote = q ? q : 1;
31821da177e4SLinus Torvalds 	} else
31831da177e4SLinus Torvalds 		*quote = 0;
31841da177e4SLinus Torvalds 
31851da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
31861da177e4SLinus Torvalds 	return conn;
31871da177e4SLinus Torvalds }
31881da177e4SLinus Torvalds 
31896039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
31901da177e4SLinus Torvalds {
31911da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
31921da177e4SLinus Torvalds 	struct hci_conn *c;
31931da177e4SLinus Torvalds 
31942064ee33SMarcel Holtmann 	bt_dev_err(hdev, "link tx timeout");
31951da177e4SLinus Torvalds 
3196bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3197bf4c6325SGustavo F. Padovan 
31981da177e4SLinus Torvalds 	/* Kill stalled connections */
3199bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3200bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
32012064ee33SMarcel Holtmann 			bt_dev_err(hdev, "killing stalled connection %pMR",
32022064ee33SMarcel Holtmann 				   &c->dst);
3203bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
32041da177e4SLinus Torvalds 		}
32051da177e4SLinus Torvalds 	}
3206bf4c6325SGustavo F. Padovan 
3207bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
32081da177e4SLinus Torvalds }
32091da177e4SLinus Torvalds 
32106039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
321173d80debSLuiz Augusto von Dentz 				      int *quote)
321273d80debSLuiz Augusto von Dentz {
321373d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
321473d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3215abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
321673d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
321773d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
321873d80debSLuiz Augusto von Dentz 
321973d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
322073d80debSLuiz Augusto von Dentz 
3221bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3222bf4c6325SGustavo F. Padovan 
3223bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
322473d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
322573d80debSLuiz Augusto von Dentz 
322673d80debSLuiz Augusto von Dentz 		if (conn->type != type)
322773d80debSLuiz Augusto von Dentz 			continue;
322873d80debSLuiz Augusto von Dentz 
322973d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
323073d80debSLuiz Augusto von Dentz 			continue;
323173d80debSLuiz Augusto von Dentz 
323273d80debSLuiz Augusto von Dentz 		conn_num++;
323373d80debSLuiz Augusto von Dentz 
32348192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
323573d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
323673d80debSLuiz Augusto von Dentz 
323773d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
323873d80debSLuiz Augusto von Dentz 				continue;
323973d80debSLuiz Augusto von Dentz 
324073d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
324173d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
324273d80debSLuiz Augusto von Dentz 				continue;
324373d80debSLuiz Augusto von Dentz 
324473d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
324573d80debSLuiz Augusto von Dentz 				num = 0;
324673d80debSLuiz Augusto von Dentz 				min = ~0;
324773d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
324873d80debSLuiz Augusto von Dentz 			}
324973d80debSLuiz Augusto von Dentz 
325073d80debSLuiz Augusto von Dentz 			num++;
325173d80debSLuiz Augusto von Dentz 
325273d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
325373d80debSLuiz Augusto von Dentz 				min  = conn->sent;
325473d80debSLuiz Augusto von Dentz 				chan = tmp;
325573d80debSLuiz Augusto von Dentz 			}
325673d80debSLuiz Augusto von Dentz 		}
325773d80debSLuiz Augusto von Dentz 
325873d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
325973d80debSLuiz Augusto von Dentz 			break;
326073d80debSLuiz Augusto von Dentz 	}
326173d80debSLuiz Augusto von Dentz 
3262bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3263bf4c6325SGustavo F. Padovan 
326473d80debSLuiz Augusto von Dentz 	if (!chan)
326573d80debSLuiz Augusto von Dentz 		return NULL;
326673d80debSLuiz Augusto von Dentz 
326773d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
326873d80debSLuiz Augusto von Dentz 	case ACL_LINK:
326973d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
327073d80debSLuiz Augusto von Dentz 		break;
3271bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
3272bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
3273bd1eb66bSAndrei Emeltchenko 		break;
327473d80debSLuiz Augusto von Dentz 	case SCO_LINK:
327573d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
327673d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
327773d80debSLuiz Augusto von Dentz 		break;
327873d80debSLuiz Augusto von Dentz 	case LE_LINK:
327973d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
328073d80debSLuiz Augusto von Dentz 		break;
328173d80debSLuiz Augusto von Dentz 	default:
328273d80debSLuiz Augusto von Dentz 		cnt = 0;
32832064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown link type %d", chan->conn->type);
328473d80debSLuiz Augusto von Dentz 	}
328573d80debSLuiz Augusto von Dentz 
328673d80debSLuiz Augusto von Dentz 	q = cnt / num;
328773d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
328873d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
328973d80debSLuiz Augusto von Dentz 	return chan;
329073d80debSLuiz Augusto von Dentz }
329173d80debSLuiz Augusto von Dentz 
329202b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
329302b20f0bSLuiz Augusto von Dentz {
329402b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
329502b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
329602b20f0bSLuiz Augusto von Dentz 	int num = 0;
329702b20f0bSLuiz Augusto von Dentz 
329802b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
329902b20f0bSLuiz Augusto von Dentz 
3300bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3301bf4c6325SGustavo F. Padovan 
3302bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
330302b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
330402b20f0bSLuiz Augusto von Dentz 
330502b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
330602b20f0bSLuiz Augusto von Dentz 			continue;
330702b20f0bSLuiz Augusto von Dentz 
330802b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
330902b20f0bSLuiz Augusto von Dentz 			continue;
331002b20f0bSLuiz Augusto von Dentz 
331102b20f0bSLuiz Augusto von Dentz 		num++;
331202b20f0bSLuiz Augusto von Dentz 
33138192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
331402b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
331502b20f0bSLuiz Augusto von Dentz 
331602b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
331702b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
331802b20f0bSLuiz Augusto von Dentz 				continue;
331902b20f0bSLuiz Augusto von Dentz 			}
332002b20f0bSLuiz Augusto von Dentz 
332102b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
332202b20f0bSLuiz Augusto von Dentz 				continue;
332302b20f0bSLuiz Augusto von Dentz 
332402b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
332502b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
332602b20f0bSLuiz Augusto von Dentz 				continue;
332702b20f0bSLuiz Augusto von Dentz 
332802b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
332902b20f0bSLuiz Augusto von Dentz 
333002b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
333102b20f0bSLuiz Augusto von Dentz 			       skb->priority);
333202b20f0bSLuiz Augusto von Dentz 		}
333302b20f0bSLuiz Augusto von Dentz 
333402b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
333502b20f0bSLuiz Augusto von Dentz 			break;
333602b20f0bSLuiz Augusto von Dentz 	}
3337bf4c6325SGustavo F. Padovan 
3338bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3339bf4c6325SGustavo F. Padovan 
334002b20f0bSLuiz Augusto von Dentz }
334102b20f0bSLuiz Augusto von Dentz 
3342b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3343b71d385aSAndrei Emeltchenko {
3344b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3345b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3346b71d385aSAndrei Emeltchenko }
3347b71d385aSAndrei Emeltchenko 
33486039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
33491da177e4SLinus Torvalds {
3350d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
33511da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
33521da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
335363d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
33545f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
3355bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
33561da177e4SLinus Torvalds 	}
335763d2bc1bSAndrei Emeltchenko }
33581da177e4SLinus Torvalds 
33597fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */
33607fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev)
33617fedd3bbSAbhishek Pandit-Subedi {
33627fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
33637fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
33647fedd3bbSAbhishek Pandit-Subedi 	int quote;
33657fedd3bbSAbhishek Pandit-Subedi 
33667fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
33677fedd3bbSAbhishek Pandit-Subedi 
33687fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, SCO_LINK))
33697fedd3bbSAbhishek Pandit-Subedi 		return;
33707fedd3bbSAbhishek Pandit-Subedi 
33717fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
33727fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
33737fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
33747fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
33757fedd3bbSAbhishek Pandit-Subedi 
33767fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
33777fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
33787fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
33797fedd3bbSAbhishek Pandit-Subedi 		}
33807fedd3bbSAbhishek Pandit-Subedi 	}
33817fedd3bbSAbhishek Pandit-Subedi }
33827fedd3bbSAbhishek Pandit-Subedi 
33837fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev)
33847fedd3bbSAbhishek Pandit-Subedi {
33857fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
33867fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
33877fedd3bbSAbhishek Pandit-Subedi 	int quote;
33887fedd3bbSAbhishek Pandit-Subedi 
33897fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
33907fedd3bbSAbhishek Pandit-Subedi 
33917fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, ESCO_LINK))
33927fedd3bbSAbhishek Pandit-Subedi 		return;
33937fedd3bbSAbhishek Pandit-Subedi 
33947fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
33957fedd3bbSAbhishek Pandit-Subedi 						     &quote))) {
33967fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
33977fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
33987fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
33997fedd3bbSAbhishek Pandit-Subedi 
34007fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
34017fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
34027fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
34037fedd3bbSAbhishek Pandit-Subedi 		}
34047fedd3bbSAbhishek Pandit-Subedi 	}
34057fedd3bbSAbhishek Pandit-Subedi }
34067fedd3bbSAbhishek Pandit-Subedi 
34076039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
340863d2bc1bSAndrei Emeltchenko {
340963d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
341063d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
341163d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
341263d2bc1bSAndrei Emeltchenko 	int quote;
341363d2bc1bSAndrei Emeltchenko 
341463d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
341504837f64SMarcel Holtmann 
341673d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
341773d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3418ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3419ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
342073d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
342173d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
342273d80debSLuiz Augusto von Dentz 
3423ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3424ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3425ec1cce24SLuiz Augusto von Dentz 				break;
3426ec1cce24SLuiz Augusto von Dentz 
3427ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3428ec1cce24SLuiz Augusto von Dentz 
342973d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
343073d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
343104837f64SMarcel Holtmann 
343257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
34331da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
34341da177e4SLinus Torvalds 
34351da177e4SLinus Torvalds 			hdev->acl_cnt--;
343673d80debSLuiz Augusto von Dentz 			chan->sent++;
343773d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
34387fedd3bbSAbhishek Pandit-Subedi 
34397fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
34407fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
34417fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
34421da177e4SLinus Torvalds 		}
34431da177e4SLinus Torvalds 	}
344402b20f0bSLuiz Augusto von Dentz 
344502b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
344602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
34471da177e4SLinus Torvalds }
34481da177e4SLinus Torvalds 
34496039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3450b71d385aSAndrei Emeltchenko {
345163d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3452b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3453b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3454b71d385aSAndrei Emeltchenko 	int quote;
3455bd1eb66bSAndrei Emeltchenko 	u8 type;
3456b71d385aSAndrei Emeltchenko 
345763d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
3458b71d385aSAndrei Emeltchenko 
3459bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3460bd1eb66bSAndrei Emeltchenko 
3461bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3462bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3463bd1eb66bSAndrei Emeltchenko 	else
3464bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3465bd1eb66bSAndrei Emeltchenko 
3466b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3467bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3468b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3469b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3470b71d385aSAndrei Emeltchenko 			int blocks;
3471b71d385aSAndrei Emeltchenko 
3472b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3473b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3474b71d385aSAndrei Emeltchenko 
3475b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3476b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3477b71d385aSAndrei Emeltchenko 				break;
3478b71d385aSAndrei Emeltchenko 
3479b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3480b71d385aSAndrei Emeltchenko 
3481b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3482b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3483b71d385aSAndrei Emeltchenko 				return;
3484b71d385aSAndrei Emeltchenko 
3485b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3486b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3487b71d385aSAndrei Emeltchenko 
348857d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3489b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3490b71d385aSAndrei Emeltchenko 
3491b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3492b71d385aSAndrei Emeltchenko 			quote -= blocks;
3493b71d385aSAndrei Emeltchenko 
3494b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3495b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3496b71d385aSAndrei Emeltchenko 		}
3497b71d385aSAndrei Emeltchenko 	}
3498b71d385aSAndrei Emeltchenko 
3499b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3500bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3501b71d385aSAndrei Emeltchenko }
3502b71d385aSAndrei Emeltchenko 
35036039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3504b71d385aSAndrei Emeltchenko {
3505b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3506b71d385aSAndrei Emeltchenko 
3507bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3508ca8bee5dSMarcel Holtmann 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_PRIMARY)
3509bd1eb66bSAndrei Emeltchenko 		return;
3510bd1eb66bSAndrei Emeltchenko 
3511bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3512bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3513b71d385aSAndrei Emeltchenko 		return;
3514b71d385aSAndrei Emeltchenko 
3515b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3516b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3517b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3518b71d385aSAndrei Emeltchenko 		break;
3519b71d385aSAndrei Emeltchenko 
3520b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3521b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3522b71d385aSAndrei Emeltchenko 		break;
3523b71d385aSAndrei Emeltchenko 	}
3524b71d385aSAndrei Emeltchenko }
3525b71d385aSAndrei Emeltchenko 
35266039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
35276ed58ec5SVille Tervo {
352873d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
35296ed58ec5SVille Tervo 	struct sk_buff *skb;
353002b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
35316ed58ec5SVille Tervo 
35326ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
35336ed58ec5SVille Tervo 
353452087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
353552087a79SLuiz Augusto von Dentz 		return;
353652087a79SLuiz Augusto von Dentz 
35376ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
35381b1d29e5SLuiz Augusto von Dentz 
35391b1d29e5SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt);
35401b1d29e5SLuiz Augusto von Dentz 
354102b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
354273d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3543ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3544ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
354573d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
354673d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
35476ed58ec5SVille Tervo 
3548ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3549ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3550ec1cce24SLuiz Augusto von Dentz 				break;
3551ec1cce24SLuiz Augusto von Dentz 
3552ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3553ec1cce24SLuiz Augusto von Dentz 
355457d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
35556ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
35566ed58ec5SVille Tervo 
35576ed58ec5SVille Tervo 			cnt--;
355873d80debSLuiz Augusto von Dentz 			chan->sent++;
355973d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
35607fedd3bbSAbhishek Pandit-Subedi 
35617fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
35627fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
35637fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
35646ed58ec5SVille Tervo 		}
35656ed58ec5SVille Tervo 	}
356673d80debSLuiz Augusto von Dentz 
35676ed58ec5SVille Tervo 	if (hdev->le_pkts)
35686ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
35696ed58ec5SVille Tervo 	else
35706ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
357102b20f0bSLuiz Augusto von Dentz 
357202b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
357302b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
35746ed58ec5SVille Tervo }
35756ed58ec5SVille Tervo 
35763eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
35771da177e4SLinus Torvalds {
35783eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
35791da177e4SLinus Torvalds 	struct sk_buff *skb;
35801da177e4SLinus Torvalds 
35816ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
35826ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
35831da177e4SLinus Torvalds 
3584d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
35851da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
35861da177e4SLinus Torvalds 		hci_sched_sco(hdev);
3587b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
35887fedd3bbSAbhishek Pandit-Subedi 		hci_sched_acl(hdev);
35896ed58ec5SVille Tervo 		hci_sched_le(hdev);
359052de599eSMarcel Holtmann 	}
35916ed58ec5SVille Tervo 
35921da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
35931da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
359457d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
35951da177e4SLinus Torvalds }
35961da177e4SLinus Torvalds 
359725985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
35981da177e4SLinus Torvalds 
35991da177e4SLinus Torvalds /* ACL data packet */
36006039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
36011da177e4SLinus Torvalds {
36021da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
36031da177e4SLinus Torvalds 	struct hci_conn *conn;
36041da177e4SLinus Torvalds 	__u16 handle, flags;
36051da177e4SLinus Torvalds 
36061da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
36071da177e4SLinus Torvalds 
36081da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
36091da177e4SLinus Torvalds 	flags  = hci_flags(handle);
36101da177e4SLinus Torvalds 	handle = hci_handle(handle);
36111da177e4SLinus Torvalds 
3612f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3613a8c5fb1aSGustavo Padovan 	       handle, flags);
36141da177e4SLinus Torvalds 
36151da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
36161da177e4SLinus Torvalds 
36171da177e4SLinus Torvalds 	hci_dev_lock(hdev);
36181da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
36191da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
36201da177e4SLinus Torvalds 
36211da177e4SLinus Torvalds 	if (conn) {
362265983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
362304837f64SMarcel Holtmann 
36241da177e4SLinus Torvalds 		/* Send to upper protocol */
3625686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
36261da177e4SLinus Torvalds 		return;
36271da177e4SLinus Torvalds 	} else {
36282064ee33SMarcel Holtmann 		bt_dev_err(hdev, "ACL packet for unknown connection handle %d",
36292064ee33SMarcel Holtmann 			   handle);
36301da177e4SLinus Torvalds 	}
36311da177e4SLinus Torvalds 
36321da177e4SLinus Torvalds 	kfree_skb(skb);
36331da177e4SLinus Torvalds }
36341da177e4SLinus Torvalds 
36351da177e4SLinus Torvalds /* SCO data packet */
36366039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
36371da177e4SLinus Torvalds {
36381da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
36391da177e4SLinus Torvalds 	struct hci_conn *conn;
3640debdedf2SMarcel Holtmann 	__u16 handle, flags;
36411da177e4SLinus Torvalds 
36421da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
36431da177e4SLinus Torvalds 
36441da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
3645debdedf2SMarcel Holtmann 	flags  = hci_flags(handle);
3646debdedf2SMarcel Holtmann 	handle = hci_handle(handle);
36471da177e4SLinus Torvalds 
3648debdedf2SMarcel Holtmann 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3649debdedf2SMarcel Holtmann 	       handle, flags);
36501da177e4SLinus Torvalds 
36511da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
36521da177e4SLinus Torvalds 
36531da177e4SLinus Torvalds 	hci_dev_lock(hdev);
36541da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
36551da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
36561da177e4SLinus Torvalds 
36571da177e4SLinus Torvalds 	if (conn) {
36581da177e4SLinus Torvalds 		/* Send to upper protocol */
365900398e1dSAlain Michaud 		bt_cb(skb)->sco.pkt_status = flags & 0x03;
3660686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
36611da177e4SLinus Torvalds 		return;
36621da177e4SLinus Torvalds 	} else {
36632064ee33SMarcel Holtmann 		bt_dev_err(hdev, "SCO packet for unknown connection handle %d",
36642064ee33SMarcel Holtmann 			   handle);
36651da177e4SLinus Torvalds 	}
36661da177e4SLinus Torvalds 
36671da177e4SLinus Torvalds 	kfree_skb(skb);
36681da177e4SLinus Torvalds }
36691da177e4SLinus Torvalds 
36709238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
36719238f36aSJohan Hedberg {
36729238f36aSJohan Hedberg 	struct sk_buff *skb;
36739238f36aSJohan Hedberg 
36749238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
36759238f36aSJohan Hedberg 	if (!skb)
36769238f36aSJohan Hedberg 		return true;
36779238f36aSJohan Hedberg 
367844d27137SJohan Hedberg 	return (bt_cb(skb)->hci.req_flags & HCI_REQ_START);
36799238f36aSJohan Hedberg }
36809238f36aSJohan Hedberg 
368142c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
368242c6b129SJohan Hedberg {
368342c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
368442c6b129SJohan Hedberg 	struct sk_buff *skb;
368542c6b129SJohan Hedberg 	u16 opcode;
368642c6b129SJohan Hedberg 
368742c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
368842c6b129SJohan Hedberg 		return;
368942c6b129SJohan Hedberg 
369042c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
369142c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
369242c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
369342c6b129SJohan Hedberg 		return;
369442c6b129SJohan Hedberg 
369542c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
369642c6b129SJohan Hedberg 	if (!skb)
369742c6b129SJohan Hedberg 		return;
369842c6b129SJohan Hedberg 
369942c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
370042c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
370142c6b129SJohan Hedberg }
370242c6b129SJohan Hedberg 
3703e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
3704e6214487SJohan Hedberg 			  hci_req_complete_t *req_complete,
3705e6214487SJohan Hedberg 			  hci_req_complete_skb_t *req_complete_skb)
37069238f36aSJohan Hedberg {
37079238f36aSJohan Hedberg 	struct sk_buff *skb;
37089238f36aSJohan Hedberg 	unsigned long flags;
37099238f36aSJohan Hedberg 
37109238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
37119238f36aSJohan Hedberg 
371242c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
371342c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
37149238f36aSJohan Hedberg 	 */
371542c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
371642c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
371742c6b129SJohan Hedberg 		 * reset complete event during init and any pending
371842c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
371942c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
372042c6b129SJohan Hedberg 		 * command.
372142c6b129SJohan Hedberg 		 */
372242c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
372342c6b129SJohan Hedberg 			hci_resend_last(hdev);
372442c6b129SJohan Hedberg 
37259238f36aSJohan Hedberg 		return;
372642c6b129SJohan Hedberg 	}
37279238f36aSJohan Hedberg 
3728f80c5dadSJoão Paulo Rechi Vita 	/* If we reach this point this event matches the last command sent */
3729f80c5dadSJoão Paulo Rechi Vita 	hci_dev_clear_flag(hdev, HCI_CMD_PENDING);
3730f80c5dadSJoão Paulo Rechi Vita 
37319238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
37329238f36aSJohan Hedberg 	 * this request the request is not yet complete.
37339238f36aSJohan Hedberg 	 */
37349238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
37359238f36aSJohan Hedberg 		return;
37369238f36aSJohan Hedberg 
37379238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
37389238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
37399238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
37409238f36aSJohan Hedberg 	 */
374144d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) {
374244d27137SJohan Hedberg 		*req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb;
3743e6214487SJohan Hedberg 		return;
37449238f36aSJohan Hedberg 	}
3745e6214487SJohan Hedberg 
374644d27137SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->hci.req_complete) {
374744d27137SJohan Hedberg 		*req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete;
3748e6214487SJohan Hedberg 		return;
374953e21fbcSJohan Hedberg 	}
37509238f36aSJohan Hedberg 
37519238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
37529238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
37539238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
375444d27137SJohan Hedberg 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) {
37559238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
37569238f36aSJohan Hedberg 			break;
37579238f36aSJohan Hedberg 		}
37589238f36aSJohan Hedberg 
37593bd7594eSDouglas Anderson 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB)
3760242c0ebdSMarcel Holtmann 			*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
37613bd7594eSDouglas Anderson 		else
37623bd7594eSDouglas Anderson 			*req_complete = bt_cb(skb)->hci.req_complete;
37639238f36aSJohan Hedberg 		kfree_skb(skb);
37649238f36aSJohan Hedberg 	}
37659238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
37669238f36aSJohan Hedberg }
37679238f36aSJohan Hedberg 
3768b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
37691da177e4SLinus Torvalds {
3770b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
37711da177e4SLinus Torvalds 	struct sk_buff *skb;
37721da177e4SLinus Torvalds 
37731da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
37741da177e4SLinus Torvalds 
37751da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
3776cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
3777cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
3778cd82e61cSMarcel Holtmann 
37791da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
37801da177e4SLinus Torvalds 			/* Send copy to the sockets */
3781470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
37821da177e4SLinus Torvalds 		}
37831da177e4SLinus Torvalds 
3784eb8c101eSMattijs Korpershoek 		/* If the device has been opened in HCI_USER_CHANNEL,
3785eb8c101eSMattijs Korpershoek 		 * the userspace has exclusive access to device.
3786eb8c101eSMattijs Korpershoek 		 * When device is HCI_INIT, we still need to process
3787eb8c101eSMattijs Korpershoek 		 * the data packets to the driver in order
3788eb8c101eSMattijs Korpershoek 		 * to complete its setup().
3789eb8c101eSMattijs Korpershoek 		 */
3790eb8c101eSMattijs Korpershoek 		if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
3791eb8c101eSMattijs Korpershoek 		    !test_bit(HCI_INIT, &hdev->flags)) {
37921da177e4SLinus Torvalds 			kfree_skb(skb);
37931da177e4SLinus Torvalds 			continue;
37941da177e4SLinus Torvalds 		}
37951da177e4SLinus Torvalds 
37961da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
37971da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
3798d79f34e3SMarcel Holtmann 			switch (hci_skb_pkt_type(skb)) {
37991da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
38001da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
3801cc974003SMarcel Holtmann 			case HCI_ISODATA_PKT:
38021da177e4SLinus Torvalds 				kfree_skb(skb);
38031da177e4SLinus Torvalds 				continue;
38043ff50b79SStephen Hemminger 			}
38051da177e4SLinus Torvalds 		}
38061da177e4SLinus Torvalds 
38071da177e4SLinus Torvalds 		/* Process frame */
3808d79f34e3SMarcel Holtmann 		switch (hci_skb_pkt_type(skb)) {
38091da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
3810b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
38111da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
38121da177e4SLinus Torvalds 			break;
38131da177e4SLinus Torvalds 
38141da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
38151da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
38161da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
38171da177e4SLinus Torvalds 			break;
38181da177e4SLinus Torvalds 
38191da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
38201da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
38211da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
38221da177e4SLinus Torvalds 			break;
38231da177e4SLinus Torvalds 
38241da177e4SLinus Torvalds 		default:
38251da177e4SLinus Torvalds 			kfree_skb(skb);
38261da177e4SLinus Torvalds 			break;
38271da177e4SLinus Torvalds 		}
38281da177e4SLinus Torvalds 	}
38291da177e4SLinus Torvalds }
38301da177e4SLinus Torvalds 
3831c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
38321da177e4SLinus Torvalds {
3833c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
38341da177e4SLinus Torvalds 	struct sk_buff *skb;
38351da177e4SLinus Torvalds 
38362104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
38372104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
38381da177e4SLinus Torvalds 
38391da177e4SLinus Torvalds 	/* Send queued commands */
38405a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
38415a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
38425a08ecceSAndrei Emeltchenko 		if (!skb)
38435a08ecceSAndrei Emeltchenko 			return;
38445a08ecceSAndrei Emeltchenko 
38451da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
38461da177e4SLinus Torvalds 
3847a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
384870f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
3849*2250abadSBenjamin Berg 			int res;
3850f80c5dadSJoão Paulo Rechi Vita 			if (hci_req_status_pend(hdev))
3851f80c5dadSJoão Paulo Rechi Vita 				hci_dev_set_flag(hdev, HCI_CMD_PENDING);
38521da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
3853*2250abadSBenjamin Berg 
3854*2250abadSBenjamin Berg 			res = hci_send_frame(hdev, skb);
3855*2250abadSBenjamin Berg 			if (res < 0)
3856*2250abadSBenjamin Berg 				hci_cmd_sync_cancel(hdev, -res);
3857*2250abadSBenjamin Berg 
38587bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
385965cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
38607bdb8a5cSSzymon Janc 			else
386165cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
386265cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
38631da177e4SLinus Torvalds 		} else {
38641da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
3865c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
38661da177e4SLinus Torvalds 		}
38671da177e4SLinus Torvalds 	}
38681da177e4SLinus Torvalds }
3869