xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 36db6e8484ed455bbb320d89a119378897ae991c)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
4590051deSGustavo F. Padovan    Copyright (C) 2011 ProFUSION Embedded Systems
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds    published by the Free Software Foundation;
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds /* Bluetooth HCI core. */
271da177e4SLinus Torvalds 
288c520a59SGustavo Padovan #include <linux/export.h>
29611b30f7SMarcel Holtmann #include <linux/rfkill.h>
30baf27f6eSMarcel Holtmann #include <linux/debugfs.h>
3199780a7bSJohan Hedberg #include <linux/crypto.h>
329f30de9eSTamas Koczka #include <linux/kcov.h>
337a0e5b15SMatthias Kaehlcke #include <linux/property.h>
349952d90eSAbhishek Pandit-Subedi #include <linux/suspend.h>
359952d90eSAbhishek Pandit-Subedi #include <linux/wait.h>
3647219839SMarcel Holtmann #include <asm/unaligned.h>
371da177e4SLinus Torvalds 
381da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
391da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
404bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h>
41af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h>
421da177e4SLinus Torvalds 
430857dd3bSJohan Hedberg #include "hci_request.h"
4460c5f5fbSMarcel Holtmann #include "hci_debugfs.h"
45970c4e46SJohan Hedberg #include "smp.h"
466d5d2ee6SHeiner Kallweit #include "leds.h"
47145373cbSMiao-chen Chou #include "msft.h"
48f67743f9SMarcel Holtmann #include "aosp.h"
498961987fSKiran K #include "hci_codec.h"
50970c4e46SJohan Hedberg 
51b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
52c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
533eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
541da177e4SLinus Torvalds 
551da177e4SLinus Torvalds /* HCI device list */
561da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
571da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds /* HCI callback list */
601da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
61*5e8ce74fSLuiz Augusto von Dentz DEFINE_MUTEX(hci_cb_list_lock);
621da177e4SLinus Torvalds 
633df92b31SSasha Levin /* HCI ID Numbering */
643df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
653df92b31SSasha Levin 
661da177e4SLinus Torvalds /* Get HCI device by index.
hci_dev_get(int index)671da177e4SLinus Torvalds  * Device is held on return. */
681da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
691da177e4SLinus Torvalds {
708035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
711da177e4SLinus Torvalds 
721da177e4SLinus Torvalds 	BT_DBG("%d", index);
731da177e4SLinus Torvalds 
741da177e4SLinus Torvalds 	if (index < 0)
751da177e4SLinus Torvalds 		return NULL;
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
788035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
791da177e4SLinus Torvalds 		if (d->id == index) {
801da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
811da177e4SLinus Torvalds 			break;
821da177e4SLinus Torvalds 		}
831da177e4SLinus Torvalds 	}
841da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
851da177e4SLinus Torvalds 	return hdev;
861da177e4SLinus Torvalds }
871da177e4SLinus Torvalds 
881da177e4SLinus Torvalds /* ---- Inquiry support ---- */
hci_discovery_active(struct hci_dev * hdev)89ff9ef578SJohan Hedberg 
9030dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
9130dc78e1SJohan Hedberg {
9230dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
9330dc78e1SJohan Hedberg 
946fbe195dSAndre Guedes 	switch (discov->state) {
95343f935bSAndre Guedes 	case DISCOVERY_FINDING:
966fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
9730dc78e1SJohan Hedberg 		return true;
9830dc78e1SJohan Hedberg 
996fbe195dSAndre Guedes 	default:
10030dc78e1SJohan Hedberg 		return false;
10130dc78e1SJohan Hedberg 	}
1026fbe195dSAndre Guedes }
hci_discovery_set_state(struct hci_dev * hdev,int state)10330dc78e1SJohan Hedberg 
104ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
105ff9ef578SJohan Hedberg {
106bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
107bb3e0a33SJohan Hedberg 
108ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
109ff9ef578SJohan Hedberg 
110bb3e0a33SJohan Hedberg 	if (old_state == state)
111ff9ef578SJohan Hedberg 		return;
112ff9ef578SJohan Hedberg 
113bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
114bb3e0a33SJohan Hedberg 
115ff9ef578SJohan Hedberg 	switch (state) {
116ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
1175bee2fd6SLuiz Augusto von Dentz 		hci_update_passive_scan(hdev);
118c54c3860SAndre Guedes 
119bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
120ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
121ff9ef578SJohan Hedberg 		break;
122ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
123ff9ef578SJohan Hedberg 		break;
124343f935bSAndre Guedes 	case DISCOVERY_FINDING:
125ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
126ff9ef578SJohan Hedberg 		break;
12730dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
12830dc78e1SJohan Hedberg 		break;
129ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
130ff9ef578SJohan Hedberg 		break;
131ff9ef578SJohan Hedberg 	}
132ff9ef578SJohan Hedberg }
hci_inquiry_cache_flush(struct hci_dev * hdev)133ff9ef578SJohan Hedberg 
1341f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
1351da177e4SLinus Torvalds {
13630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
137b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
1381da177e4SLinus Torvalds 
139561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
140561aafbcSJohan Hedberg 		list_del(&p->all);
141b57c1a56SJohan Hedberg 		kfree(p);
1421da177e4SLinus Torvalds 	}
143561aafbcSJohan Hedberg 
144561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
145561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
1461da177e4SLinus Torvalds }
hci_inquiry_cache_lookup(struct hci_dev * hdev,bdaddr_t * bdaddr)1471da177e4SLinus Torvalds 
148a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
149a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
1501da177e4SLinus Torvalds {
15130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1521da177e4SLinus Torvalds 	struct inquiry_entry *e;
1531da177e4SLinus Torvalds 
1546ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1551da177e4SLinus Torvalds 
156561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
1571da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
1581da177e4SLinus Torvalds 			return e;
1591da177e4SLinus Torvalds 	}
1601da177e4SLinus Torvalds 
161b57c1a56SJohan Hedberg 	return NULL;
162b57c1a56SJohan Hedberg }
hci_inquiry_cache_lookup_unknown(struct hci_dev * hdev,bdaddr_t * bdaddr)163b57c1a56SJohan Hedberg 
164561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
165561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
166561aafbcSJohan Hedberg {
16730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
168561aafbcSJohan Hedberg 	struct inquiry_entry *e;
169561aafbcSJohan Hedberg 
1706ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
171561aafbcSJohan Hedberg 
172561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
173561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
174561aafbcSJohan Hedberg 			return e;
175561aafbcSJohan Hedberg 	}
176561aafbcSJohan Hedberg 
177561aafbcSJohan Hedberg 	return NULL;
178561aafbcSJohan Hedberg }
hci_inquiry_cache_lookup_resolve(struct hci_dev * hdev,bdaddr_t * bdaddr,int state)179561aafbcSJohan Hedberg 
18030dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
18130dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
18230dc78e1SJohan Hedberg 						       int state)
18330dc78e1SJohan Hedberg {
18430dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
18530dc78e1SJohan Hedberg 	struct inquiry_entry *e;
18630dc78e1SJohan Hedberg 
1876ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
18830dc78e1SJohan Hedberg 
18930dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
19030dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
19130dc78e1SJohan Hedberg 			return e;
19230dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
19330dc78e1SJohan Hedberg 			return e;
19430dc78e1SJohan Hedberg 	}
19530dc78e1SJohan Hedberg 
19630dc78e1SJohan Hedberg 	return NULL;
19730dc78e1SJohan Hedberg }
hci_inquiry_cache_update_resolve(struct hci_dev * hdev,struct inquiry_entry * ie)19830dc78e1SJohan Hedberg 
199a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
200a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
201a3d4e20aSJohan Hedberg {
202a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
203a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
204a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
205a3d4e20aSJohan Hedberg 
206a3d4e20aSJohan Hedberg 	list_del(&ie->list);
207a3d4e20aSJohan Hedberg 
208a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
209a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
210a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
211a3d4e20aSJohan Hedberg 			break;
212a3d4e20aSJohan Hedberg 		pos = &p->list;
213a3d4e20aSJohan Hedberg 	}
214a3d4e20aSJohan Hedberg 
215a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
216a3d4e20aSJohan Hedberg }
hci_inquiry_cache_update(struct hci_dev * hdev,struct inquiry_data * data,bool name_known)217a3d4e20aSJohan Hedberg 
218af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
219af58925cSMarcel Holtmann 			     bool name_known)
2201da177e4SLinus Torvalds {
22130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
22270f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
223af58925cSMarcel Holtmann 	u32 flags = 0;
2241da177e4SLinus Torvalds 
2256ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
2261da177e4SLinus Torvalds 
2276928a924SJohan Hedberg 	hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
2282b2fec4dSSzymon Janc 
229af58925cSMarcel Holtmann 	if (!data->ssp_mode)
230af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
231388fc8faSJohan Hedberg 
23270f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
233a3d4e20aSJohan Hedberg 	if (ie) {
234af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
235af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
236388fc8faSJohan Hedberg 
237a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
238a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
239a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
240a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
241a3d4e20aSJohan Hedberg 		}
242a3d4e20aSJohan Hedberg 
243561aafbcSJohan Hedberg 		goto update;
244a3d4e20aSJohan Hedberg 	}
245561aafbcSJohan Hedberg 
2461da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
24727f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
248af58925cSMarcel Holtmann 	if (!ie) {
249af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
250af58925cSMarcel Holtmann 		goto done;
251af58925cSMarcel Holtmann 	}
25270f23020SAndrei Emeltchenko 
253561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
254561aafbcSJohan Hedberg 
255561aafbcSJohan Hedberg 	if (name_known) {
256561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
257561aafbcSJohan Hedberg 	} else {
258561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
259561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
260561aafbcSJohan Hedberg 	}
261561aafbcSJohan Hedberg 
262561aafbcSJohan Hedberg update:
263561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
264561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
265561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
266561aafbcSJohan Hedberg 		list_del(&ie->list);
2671da177e4SLinus Torvalds 	}
2681da177e4SLinus Torvalds 
26970f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
27070f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
2711da177e4SLinus Torvalds 	cache->timestamp = jiffies;
2723175405bSJohan Hedberg 
2733175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
274af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
2753175405bSJohan Hedberg 
276af58925cSMarcel Holtmann done:
277af58925cSMarcel Holtmann 	return flags;
2781da177e4SLinus Torvalds }
inquiry_cache_dump(struct hci_dev * hdev,int num,__u8 * buf)2791da177e4SLinus Torvalds 
2801da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
2811da177e4SLinus Torvalds {
28230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2831da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
2841da177e4SLinus Torvalds 	struct inquiry_entry *e;
2851da177e4SLinus Torvalds 	int copied = 0;
2861da177e4SLinus Torvalds 
287561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
2881da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
289b57c1a56SJohan Hedberg 
290b57c1a56SJohan Hedberg 		if (copied >= num)
291b57c1a56SJohan Hedberg 			break;
292b57c1a56SJohan Hedberg 
2931da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
2941da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
2951da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
2961da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
2971da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
2981da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
299b57c1a56SJohan Hedberg 
3001da177e4SLinus Torvalds 		info++;
301b57c1a56SJohan Hedberg 		copied++;
3021da177e4SLinus Torvalds 	}
3031da177e4SLinus Torvalds 
3041da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
3051da177e4SLinus Torvalds 	return copied;
3061da177e4SLinus Torvalds }
hci_inq_req(struct hci_request * req,unsigned long opt)3071da177e4SLinus Torvalds 
308a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt)
3091da177e4SLinus Torvalds {
3101da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
31142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
3121da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
3131da177e4SLinus Torvalds 
3141da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
3151da177e4SLinus Torvalds 
3161da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
317a1d01db1SJohan Hedberg 		return 0;
3181da177e4SLinus Torvalds 
3191da177e4SLinus Torvalds 	/* Start Inquiry */
3201da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
3211da177e4SLinus Torvalds 	cp.length  = ir->length;
3221da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
32342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
324a1d01db1SJohan Hedberg 
325a1d01db1SJohan Hedberg 	return 0;
3261da177e4SLinus Torvalds }
hci_inquiry(void __user * arg)3271da177e4SLinus Torvalds 
3281da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
3291da177e4SLinus Torvalds {
3301da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
3311da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
3321da177e4SLinus Torvalds 	struct hci_dev *hdev;
3331da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
3341da177e4SLinus Torvalds 	long timeo;
3351da177e4SLinus Torvalds 	__u8 *buf;
3361da177e4SLinus Torvalds 
3371da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
3381da177e4SLinus Torvalds 		return -EFAULT;
3391da177e4SLinus Torvalds 
3405a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
3415a08ecceSAndrei Emeltchenko 	if (!hdev)
3421da177e4SLinus Torvalds 		return -ENODEV;
3431da177e4SLinus Torvalds 
344d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
3450736cfa8SMarcel Holtmann 		err = -EBUSY;
3460736cfa8SMarcel Holtmann 		goto done;
3470736cfa8SMarcel Holtmann 	}
3480736cfa8SMarcel Holtmann 
349d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
350fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
351fee746b0SMarcel Holtmann 		goto done;
352fee746b0SMarcel Holtmann 	}
353fee746b0SMarcel Holtmann 
354d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
35556f87901SJohan Hedberg 		err = -EOPNOTSUPP;
35656f87901SJohan Hedberg 		goto done;
35756f87901SJohan Hedberg 	}
35856f87901SJohan Hedberg 
359f41a4b2bSPavel Skripkin 	/* Restrict maximum inquiry length to 60 seconds */
360f41a4b2bSPavel Skripkin 	if (ir.length > 60) {
361f41a4b2bSPavel Skripkin 		err = -EINVAL;
362f41a4b2bSPavel Skripkin 		goto done;
363f41a4b2bSPavel Skripkin 	}
364f41a4b2bSPavel Skripkin 
36509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
3661da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
367a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
3681f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
3691da177e4SLinus Torvalds 		do_inquiry = 1;
3701da177e4SLinus Torvalds 	}
37109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
3721da177e4SLinus Torvalds 
37304837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
37470f23020SAndrei Emeltchenko 
37570f23020SAndrei Emeltchenko 	if (do_inquiry) {
37601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
3774ebeee2dSJohan Hedberg 				   timeo, NULL);
37870f23020SAndrei Emeltchenko 		if (err < 0)
3791da177e4SLinus Torvalds 			goto done;
3803e13fa1eSAndre Guedes 
3813e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
3823e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
3833e13fa1eSAndre Guedes 		 */
38474316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
38528a758c8SPan Bian 				TASK_INTERRUPTIBLE)) {
38628a758c8SPan Bian 			err = -EINTR;
38728a758c8SPan Bian 			goto done;
38828a758c8SPan Bian 		}
38970f23020SAndrei Emeltchenko 	}
3901da177e4SLinus Torvalds 
3918fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
3928fc9ced3SGustavo Padovan 	 * 255 entries
3938fc9ced3SGustavo Padovan 	 */
3941da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
3951da177e4SLinus Torvalds 
3961da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
3971da177e4SLinus Torvalds 	 * copy it to the user space.
3981da177e4SLinus Torvalds 	 */
3996da2ec56SKees Cook 	buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL);
40070f23020SAndrei Emeltchenko 	if (!buf) {
4011da177e4SLinus Torvalds 		err = -ENOMEM;
4021da177e4SLinus Torvalds 		goto done;
4031da177e4SLinus Torvalds 	}
4041da177e4SLinus Torvalds 
40509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4061da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
40709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4081da177e4SLinus Torvalds 
4091da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
4101da177e4SLinus Torvalds 
4111da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
4121da177e4SLinus Torvalds 		ptr += sizeof(ir);
4131da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
4141da177e4SLinus Torvalds 				 ir.num_rsp))
4151da177e4SLinus Torvalds 			err = -EFAULT;
4161da177e4SLinus Torvalds 	} else
4171da177e4SLinus Torvalds 		err = -EFAULT;
4181da177e4SLinus Torvalds 
4191da177e4SLinus Torvalds 	kfree(buf);
4201da177e4SLinus Torvalds 
4211da177e4SLinus Torvalds done:
4221da177e4SLinus Torvalds 	hci_dev_put(hdev);
4231da177e4SLinus Torvalds 	return err;
4241da177e4SLinus Torvalds }
hci_dev_do_open(struct hci_dev * hdev)4251da177e4SLinus Torvalds 
426cf75ad8bSLuiz Augusto von Dentz static int hci_dev_do_open(struct hci_dev *hdev)
427cf75ad8bSLuiz Augusto von Dentz {
428cf75ad8bSLuiz Augusto von Dentz 	int ret = 0;
429cf75ad8bSLuiz Augusto von Dentz 
430cf75ad8bSLuiz Augusto von Dentz 	BT_DBG("%s %p", hdev->name, hdev);
431cf75ad8bSLuiz Augusto von Dentz 
432cf75ad8bSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
433cf75ad8bSLuiz Augusto von Dentz 
434cf75ad8bSLuiz Augusto von Dentz 	ret = hci_dev_open_sync(hdev);
435cf75ad8bSLuiz Augusto von Dentz 
436b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
4371da177e4SLinus Torvalds 	return ret;
4381da177e4SLinus Torvalds }
4391da177e4SLinus Torvalds 
440cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
hci_dev_open(__u16 dev)441cbed0ca1SJohan Hedberg 
442cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
443cbed0ca1SJohan Hedberg {
444cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
445cbed0ca1SJohan Hedberg 	int err;
446cbed0ca1SJohan Hedberg 
447cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
448cbed0ca1SJohan Hedberg 	if (!hdev)
449cbed0ca1SJohan Hedberg 		return -ENODEV;
450cbed0ca1SJohan Hedberg 
4514a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
452fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
453fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
454fee746b0SMarcel Holtmann 	 * possible.
455fee746b0SMarcel Holtmann 	 *
456fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
457fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
458fee746b0SMarcel Holtmann 	 * open the device.
459fee746b0SMarcel Holtmann 	 */
460d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
461d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
462fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
463fee746b0SMarcel Holtmann 		goto done;
464fee746b0SMarcel Holtmann 	}
465fee746b0SMarcel Holtmann 
466e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
467e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
468e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
469e1d08f40SJohan Hedberg 	 * completed.
470e1d08f40SJohan Hedberg 	 */
471a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
472e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
473e1d08f40SJohan Hedberg 
474a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
475a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
476a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
477a5c8f270SMarcel Holtmann 	 */
478e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
479e1d08f40SJohan Hedberg 
48012aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
481b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
48212aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
48312aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
48412aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
48512aa4f0aSMarcel Holtmann 	 */
486d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
487d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_MGMT))
488a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BONDABLE);
48912aa4f0aSMarcel Holtmann 
490cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
491cbed0ca1SJohan Hedberg 
492fee746b0SMarcel Holtmann done:
493cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
494cbed0ca1SJohan Hedberg 	return err;
495cbed0ca1SJohan Hedberg }
hci_dev_do_close(struct hci_dev * hdev)496cbed0ca1SJohan Hedberg 
497cf75ad8bSLuiz Augusto von Dentz int hci_dev_do_close(struct hci_dev *hdev)
498cf75ad8bSLuiz Augusto von Dentz {
499cf75ad8bSLuiz Augusto von Dentz 	int err;
500cf75ad8bSLuiz Augusto von Dentz 
501cf75ad8bSLuiz Augusto von Dentz 	BT_DBG("%s %p", hdev->name, hdev);
502cf75ad8bSLuiz Augusto von Dentz 
503cf75ad8bSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
504cf75ad8bSLuiz Augusto von Dentz 
505cf75ad8bSLuiz Augusto von Dentz 	err = hci_dev_close_sync(hdev);
506cf75ad8bSLuiz Augusto von Dentz 
507b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
5081da177e4SLinus Torvalds 
50961969ef8SKangmin Park 	return err;
5101da177e4SLinus Torvalds }
hci_dev_close(__u16 dev)5111da177e4SLinus Torvalds 
5121da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
5131da177e4SLinus Torvalds {
5141da177e4SLinus Torvalds 	struct hci_dev *hdev;
5151da177e4SLinus Torvalds 	int err;
5161da177e4SLinus Torvalds 
51770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
51870f23020SAndrei Emeltchenko 	if (!hdev)
5191da177e4SLinus Torvalds 		return -ENODEV;
5208ee56540SMarcel Holtmann 
521d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
5220736cfa8SMarcel Holtmann 		err = -EBUSY;
5230736cfa8SMarcel Holtmann 		goto done;
5240736cfa8SMarcel Holtmann 	}
5250736cfa8SMarcel Holtmann 
526e36bea6eSVasyl Vavrychuk 	cancel_work_sync(&hdev->power_on);
527a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
5288ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
5298ee56540SMarcel Holtmann 
5301da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
5318ee56540SMarcel Holtmann 
5320736cfa8SMarcel Holtmann done:
5331da177e4SLinus Torvalds 	hci_dev_put(hdev);
5341da177e4SLinus Torvalds 	return err;
5351da177e4SLinus Torvalds }
hci_dev_do_reset(struct hci_dev * hdev)5361da177e4SLinus Torvalds 
5375c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev)
5381da177e4SLinus Torvalds {
5395c912495SMarcel Holtmann 	int ret;
5401da177e4SLinus Torvalds 
5415c912495SMarcel Holtmann 	BT_DBG("%s %p", hdev->name, hdev);
5421da177e4SLinus Torvalds 
543b504430cSJohan Hedberg 	hci_req_sync_lock(hdev);
5441da177e4SLinus Torvalds 
5451da177e4SLinus Torvalds 	/* Drop queues */
5461da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
5471da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
5481da177e4SLinus Torvalds 
549877afadaSSchspa Shi 	/* Cancel these to avoid queueing non-chained pending work */
550877afadaSSchspa Shi 	hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
551deee93d1STetsuo Handa 	/* Wait for
552deee93d1STetsuo Handa 	 *
553deee93d1STetsuo Handa 	 *    if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
554deee93d1STetsuo Handa 	 *        queue_delayed_work(&hdev->{cmd,ncmd}_timer)
555deee93d1STetsuo Handa 	 *
556deee93d1STetsuo Handa 	 * inside RCU section to see the flag or complete scheduling.
557deee93d1STetsuo Handa 	 */
558deee93d1STetsuo Handa 	synchronize_rcu();
559deee93d1STetsuo Handa 	/* Explicitly cancel works in case scheduled after setting the flag. */
560877afadaSSchspa Shi 	cancel_delayed_work(&hdev->cmd_timer);
561877afadaSSchspa Shi 	cancel_delayed_work(&hdev->ncmd_timer);
562877afadaSSchspa Shi 
56376727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
56476727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
56576727c02SJohan Hedberg 	 */
56676727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
56776727c02SJohan Hedberg 
56809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5691f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
5701da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
57109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
5721da177e4SLinus Torvalds 
5731da177e4SLinus Torvalds 	if (hdev->flush)
5741da177e4SLinus Torvalds 		hdev->flush(hdev);
5751da177e4SLinus Torvalds 
576877afadaSSchspa Shi 	hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
577877afadaSSchspa Shi 
5781da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
57926afbd82SLuiz Augusto von Dentz 	hdev->acl_cnt = 0;
58026afbd82SLuiz Augusto von Dentz 	hdev->sco_cnt = 0;
58126afbd82SLuiz Augusto von Dentz 	hdev->le_cnt = 0;
58226afbd82SLuiz Augusto von Dentz 	hdev->iso_cnt = 0;
5831da177e4SLinus Torvalds 
584d0b13706SLuiz Augusto von Dentz 	ret = hci_reset_sync(hdev);
5851da177e4SLinus Torvalds 
586b504430cSJohan Hedberg 	hci_req_sync_unlock(hdev);
5871da177e4SLinus Torvalds 	return ret;
5881da177e4SLinus Torvalds }
hci_dev_reset(__u16 dev)5891da177e4SLinus Torvalds 
5905c912495SMarcel Holtmann int hci_dev_reset(__u16 dev)
5915c912495SMarcel Holtmann {
5925c912495SMarcel Holtmann 	struct hci_dev *hdev;
5935c912495SMarcel Holtmann 	int err;
5945c912495SMarcel Holtmann 
5955c912495SMarcel Holtmann 	hdev = hci_dev_get(dev);
5965c912495SMarcel Holtmann 	if (!hdev)
5975c912495SMarcel Holtmann 		return -ENODEV;
5985c912495SMarcel Holtmann 
5995c912495SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
6005c912495SMarcel Holtmann 		err = -ENETDOWN;
6015c912495SMarcel Holtmann 		goto done;
6025c912495SMarcel Holtmann 	}
6035c912495SMarcel Holtmann 
604d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6055c912495SMarcel Holtmann 		err = -EBUSY;
6065c912495SMarcel Holtmann 		goto done;
6075c912495SMarcel Holtmann 	}
6085c912495SMarcel Holtmann 
609d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
6105c912495SMarcel Holtmann 		err = -EOPNOTSUPP;
6115c912495SMarcel Holtmann 		goto done;
6125c912495SMarcel Holtmann 	}
6135c912495SMarcel Holtmann 
6145c912495SMarcel Holtmann 	err = hci_dev_do_reset(hdev);
6155c912495SMarcel Holtmann 
6165c912495SMarcel Holtmann done:
6175c912495SMarcel Holtmann 	hci_dev_put(hdev);
6185c912495SMarcel Holtmann 	return err;
6195c912495SMarcel Holtmann }
hci_dev_reset_stat(__u16 dev)6205c912495SMarcel Holtmann 
6211da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
6221da177e4SLinus Torvalds {
6231da177e4SLinus Torvalds 	struct hci_dev *hdev;
6241da177e4SLinus Torvalds 	int ret = 0;
6251da177e4SLinus Torvalds 
62670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
62770f23020SAndrei Emeltchenko 	if (!hdev)
6281da177e4SLinus Torvalds 		return -ENODEV;
6291da177e4SLinus Torvalds 
630d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6310736cfa8SMarcel Holtmann 		ret = -EBUSY;
6320736cfa8SMarcel Holtmann 		goto done;
6330736cfa8SMarcel Holtmann 	}
6340736cfa8SMarcel Holtmann 
635d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
636fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
637fee746b0SMarcel Holtmann 		goto done;
638fee746b0SMarcel Holtmann 	}
639fee746b0SMarcel Holtmann 
6401da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
6411da177e4SLinus Torvalds 
6420736cfa8SMarcel Holtmann done:
6431da177e4SLinus Torvalds 	hci_dev_put(hdev);
6441da177e4SLinus Torvalds 	return ret;
6451da177e4SLinus Torvalds }
hci_update_passive_scan_state(struct hci_dev * hdev,u8 scan)6461da177e4SLinus Torvalds 
6475bee2fd6SLuiz Augusto von Dentz static void hci_update_passive_scan_state(struct hci_dev *hdev, u8 scan)
648123abc08SJohan Hedberg {
649bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
650123abc08SJohan Hedberg 
651123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
652123abc08SJohan Hedberg 
653123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
654238be788SMarcel Holtmann 		conn_changed = !hci_dev_test_and_set_flag(hdev,
655238be788SMarcel Holtmann 							  HCI_CONNECTABLE);
656123abc08SJohan Hedberg 	else
657a69d8927SMarcel Holtmann 		conn_changed = hci_dev_test_and_clear_flag(hdev,
658a69d8927SMarcel Holtmann 							   HCI_CONNECTABLE);
659123abc08SJohan Hedberg 
660bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
661238be788SMarcel Holtmann 		discov_changed = !hci_dev_test_and_set_flag(hdev,
662238be788SMarcel Holtmann 							    HCI_DISCOVERABLE);
663bc6d2d04SJohan Hedberg 	} else {
664a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
665a69d8927SMarcel Holtmann 		discov_changed = hci_dev_test_and_clear_flag(hdev,
666a69d8927SMarcel Holtmann 							     HCI_DISCOVERABLE);
667bc6d2d04SJohan Hedberg 	}
668bc6d2d04SJohan Hedberg 
669d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
670123abc08SJohan Hedberg 		return;
671123abc08SJohan Hedberg 
672bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
673bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
674a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
675bc6d2d04SJohan Hedberg 
676d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
677651cd3d6SBrian Gix 			hci_update_adv_data(hdev, hdev->cur_adv_instance);
678bc6d2d04SJohan Hedberg 
679123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
680123abc08SJohan Hedberg 	}
681bc6d2d04SJohan Hedberg }
hci_dev_cmd(unsigned int cmd,void __user * arg)682123abc08SJohan Hedberg 
6831da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
6841da177e4SLinus Torvalds {
6851da177e4SLinus Torvalds 	struct hci_dev *hdev;
6861da177e4SLinus Torvalds 	struct hci_dev_req dr;
687b0fc1bd2SLuiz Augusto von Dentz 	__le16 policy;
6881da177e4SLinus Torvalds 	int err = 0;
6891da177e4SLinus Torvalds 
6901da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
6911da177e4SLinus Torvalds 		return -EFAULT;
6921da177e4SLinus Torvalds 
69370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
69470f23020SAndrei Emeltchenko 	if (!hdev)
6951da177e4SLinus Torvalds 		return -ENODEV;
6961da177e4SLinus Torvalds 
697d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6980736cfa8SMarcel Holtmann 		err = -EBUSY;
6990736cfa8SMarcel Holtmann 		goto done;
7000736cfa8SMarcel Holtmann 	}
7010736cfa8SMarcel Holtmann 
702d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
703fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
704fee746b0SMarcel Holtmann 		goto done;
705fee746b0SMarcel Holtmann 	}
706fee746b0SMarcel Holtmann 
707d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
70856f87901SJohan Hedberg 		err = -EOPNOTSUPP;
70956f87901SJohan Hedberg 		goto done;
71056f87901SJohan Hedberg 	}
71156f87901SJohan Hedberg 
7121da177e4SLinus Torvalds 	switch (cmd) {
7131da177e4SLinus Torvalds 	case HCISETAUTH:
7145f77c8e8SLuiz Augusto von Dentz 		err = hci_cmd_sync_status(hdev, HCI_OP_WRITE_AUTH_ENABLE,
715b0fc1bd2SLuiz Augusto von Dentz 					  1, &dr.dev_opt, HCI_CMD_TIMEOUT);
7161da177e4SLinus Torvalds 		break;
7171da177e4SLinus Torvalds 
7181da177e4SLinus Torvalds 	case HCISETENCRYPT:
7191da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
7201da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
7211da177e4SLinus Torvalds 			break;
7221da177e4SLinus Torvalds 		}
7231da177e4SLinus Torvalds 
7241da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
7251da177e4SLinus Torvalds 			/* Auth must be enabled first */
7265f77c8e8SLuiz Augusto von Dentz 			err = hci_cmd_sync_status(hdev,
727b0fc1bd2SLuiz Augusto von Dentz 						  HCI_OP_WRITE_AUTH_ENABLE,
728b0fc1bd2SLuiz Augusto von Dentz 						  1, &dr.dev_opt,
729b0fc1bd2SLuiz Augusto von Dentz 						  HCI_CMD_TIMEOUT);
7301da177e4SLinus Torvalds 			if (err)
7311da177e4SLinus Torvalds 				break;
7321da177e4SLinus Torvalds 		}
7331da177e4SLinus Torvalds 
7345f77c8e8SLuiz Augusto von Dentz 		err = hci_cmd_sync_status(hdev, HCI_OP_WRITE_ENCRYPT_MODE,
7355f77c8e8SLuiz Augusto von Dentz 					  1, &dr.dev_opt, HCI_CMD_TIMEOUT);
7361da177e4SLinus Torvalds 		break;
7371da177e4SLinus Torvalds 
7381da177e4SLinus Torvalds 	case HCISETSCAN:
7395f77c8e8SLuiz Augusto von Dentz 		err = hci_cmd_sync_status(hdev, HCI_OP_WRITE_SCAN_ENABLE,
7405f77c8e8SLuiz Augusto von Dentz 					  1, &dr.dev_opt, HCI_CMD_TIMEOUT);
74191a668b0SJohan Hedberg 
742bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
743bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
74491a668b0SJohan Hedberg 		 */
745123abc08SJohan Hedberg 		if (!err)
7465bee2fd6SLuiz Augusto von Dentz 			hci_update_passive_scan_state(hdev, dr.dev_opt);
7471da177e4SLinus Torvalds 		break;
7481da177e4SLinus Torvalds 
7491da177e4SLinus Torvalds 	case HCISETLINKPOL:
750b0fc1bd2SLuiz Augusto von Dentz 		policy = cpu_to_le16(dr.dev_opt);
751b0fc1bd2SLuiz Augusto von Dentz 
7525f77c8e8SLuiz Augusto von Dentz 		err = hci_cmd_sync_status(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
7535f77c8e8SLuiz Augusto von Dentz 					  2, &policy, HCI_CMD_TIMEOUT);
7541da177e4SLinus Torvalds 		break;
7551da177e4SLinus Torvalds 
7561da177e4SLinus Torvalds 	case HCISETLINKMODE:
757e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
758e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
759e4e8e37cSMarcel Holtmann 		break;
760e4e8e37cSMarcel Holtmann 
761e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
762b7c23df8SJaganath Kanakkassery 		if (hdev->pkt_type == (__u16) dr.dev_opt)
763b7c23df8SJaganath Kanakkassery 			break;
764b7c23df8SJaganath Kanakkassery 
765e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
766b7c23df8SJaganath Kanakkassery 		mgmt_phy_configuration_changed(hdev, NULL);
7671da177e4SLinus Torvalds 		break;
7681da177e4SLinus Torvalds 
7691da177e4SLinus Torvalds 	case HCISETACLMTU:
7701da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
7711da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
7721da177e4SLinus Torvalds 		break;
7731da177e4SLinus Torvalds 
7741da177e4SLinus Torvalds 	case HCISETSCOMTU:
7751da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
7761da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
7771da177e4SLinus Torvalds 		break;
7781da177e4SLinus Torvalds 
7791da177e4SLinus Torvalds 	default:
7801da177e4SLinus Torvalds 		err = -EINVAL;
7811da177e4SLinus Torvalds 		break;
7821da177e4SLinus Torvalds 	}
783e4e8e37cSMarcel Holtmann 
7840736cfa8SMarcel Holtmann done:
7851da177e4SLinus Torvalds 	hci_dev_put(hdev);
7861da177e4SLinus Torvalds 	return err;
7871da177e4SLinus Torvalds }
hci_get_dev_list(void __user * arg)7881da177e4SLinus Torvalds 
7891da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
7901da177e4SLinus Torvalds {
7918035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
7921da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
7931da177e4SLinus Torvalds 	struct hci_dev_req *dr;
7941da177e4SLinus Torvalds 	int n = 0, size, err;
7951da177e4SLinus Torvalds 	__u16 dev_num;
7961da177e4SLinus Torvalds 
7971da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
7981da177e4SLinus Torvalds 		return -EFAULT;
7991da177e4SLinus Torvalds 
8001da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
8011da177e4SLinus Torvalds 		return -EINVAL;
8021da177e4SLinus Torvalds 
8031da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
8041da177e4SLinus Torvalds 
80570f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
80670f23020SAndrei Emeltchenko 	if (!dl)
8071da177e4SLinus Torvalds 		return -ENOMEM;
8081da177e4SLinus Torvalds 
8091da177e4SLinus Torvalds 	dr = dl->dev_req;
8101da177e4SLinus Torvalds 
811f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
8128035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
8132e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
814c542a06cSJohan Hedberg 
8152e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
8162e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
8172e84d8dbSMarcel Holtmann 		 * device is actually down.
8182e84d8dbSMarcel Holtmann 		 */
819d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
8202e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
821c542a06cSJohan Hedberg 
8221da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
8232e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
824c542a06cSJohan Hedberg 
8251da177e4SLinus Torvalds 		if (++n >= dev_num)
8261da177e4SLinus Torvalds 			break;
8271da177e4SLinus Torvalds 	}
828f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
8291da177e4SLinus Torvalds 
8301da177e4SLinus Torvalds 	dl->dev_num = n;
8311da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
8321da177e4SLinus Torvalds 
8331da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
8341da177e4SLinus Torvalds 	kfree(dl);
8351da177e4SLinus Torvalds 
8361da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
8371da177e4SLinus Torvalds }
hci_get_dev_info(void __user * arg)8381da177e4SLinus Torvalds 
8391da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
8401da177e4SLinus Torvalds {
8411da177e4SLinus Torvalds 	struct hci_dev *hdev;
8421da177e4SLinus Torvalds 	struct hci_dev_info di;
8432e84d8dbSMarcel Holtmann 	unsigned long flags;
8441da177e4SLinus Torvalds 	int err = 0;
8451da177e4SLinus Torvalds 
8461da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
8471da177e4SLinus Torvalds 		return -EFAULT;
8481da177e4SLinus Torvalds 
84970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
85070f23020SAndrei Emeltchenko 	if (!hdev)
8511da177e4SLinus Torvalds 		return -ENODEV;
8521da177e4SLinus Torvalds 
8532e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
8542e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
8552e84d8dbSMarcel Holtmann 	 * device is actually down.
8562e84d8dbSMarcel Holtmann 	 */
857d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
8582e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
8592e84d8dbSMarcel Holtmann 	else
8602e84d8dbSMarcel Holtmann 		flags = hdev->flags;
861c542a06cSJohan Hedberg 
862a41c8efeSLuiz Augusto von Dentz 	strscpy(di.name, hdev->name, sizeof(di.name));
8631da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
8645af2e235SLuiz Augusto von Dentz 	di.type     = (hdev->bus & 0x0f);
8652e84d8dbSMarcel Holtmann 	di.flags    = flags;
8661da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
867572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
8681da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
8691da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
8701da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
8711da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
872572c7f84SJohan Hedberg 	} else {
873572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
874572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
875572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
876572c7f84SJohan Hedberg 		di.sco_pkts = 0;
877572c7f84SJohan Hedberg 	}
8781da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
8791da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
8801da177e4SLinus Torvalds 
8811da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
8821da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
8831da177e4SLinus Torvalds 
8841da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
8851da177e4SLinus Torvalds 		err = -EFAULT;
8861da177e4SLinus Torvalds 
8871da177e4SLinus Torvalds 	hci_dev_put(hdev);
8881da177e4SLinus Torvalds 
8891da177e4SLinus Torvalds 	return err;
8901da177e4SLinus Torvalds }
8911da177e4SLinus Torvalds 
8921da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
hci_rfkill_set_block(void * data,bool blocked)8931da177e4SLinus Torvalds 
894611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
895611b30f7SMarcel Holtmann {
896611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
897611b30f7SMarcel Holtmann 
898611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
899611b30f7SMarcel Holtmann 
900d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
9010736cfa8SMarcel Holtmann 		return -EBUSY;
9020736cfa8SMarcel Holtmann 
9035e130367SJohan Hedberg 	if (blocked) {
904a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
905d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
906d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG))
907611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
9085e130367SJohan Hedberg 	} else {
909a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_RFKILLED);
9105e130367SJohan Hedberg 	}
911611b30f7SMarcel Holtmann 
912611b30f7SMarcel Holtmann 	return 0;
913611b30f7SMarcel Holtmann }
914611b30f7SMarcel Holtmann 
915611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
916611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
917611b30f7SMarcel Holtmann };
hci_power_on(struct work_struct * work)918611b30f7SMarcel Holtmann 
919ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
920ab81cbf9SJohan Hedberg {
921ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
92296570ffcSJohan Hedberg 	int err;
923ab81cbf9SJohan Hedberg 
924ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
925ab81cbf9SJohan Hedberg 
9262ff13894SJohan Hedberg 	if (test_bit(HCI_UP, &hdev->flags) &&
9272ff13894SJohan Hedberg 	    hci_dev_test_flag(hdev, HCI_MGMT) &&
9282ff13894SJohan Hedberg 	    hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
929d82142a8SWei-Ning Huang 		cancel_delayed_work(&hdev->power_off);
930cf75ad8bSLuiz Augusto von Dentz 		err = hci_powered_update_sync(hdev);
9312ff13894SJohan Hedberg 		mgmt_power_on(hdev, err);
9322ff13894SJohan Hedberg 		return;
9332ff13894SJohan Hedberg 	}
9342ff13894SJohan Hedberg 
935cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
93696570ffcSJohan Hedberg 	if (err < 0) {
9373ad67582SJaganath Kanakkassery 		hci_dev_lock(hdev);
93896570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
9393ad67582SJaganath Kanakkassery 		hci_dev_unlock(hdev);
940ab81cbf9SJohan Hedberg 		return;
94196570ffcSJohan Hedberg 	}
942ab81cbf9SJohan Hedberg 
943a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
944a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
945a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
946a5c8f270SMarcel Holtmann 	 */
947d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
948d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
9495af2e235SLuiz Augusto von Dentz 	    (!bacmp(&hdev->bdaddr, BDADDR_ANY) &&
950a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
951a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
952bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
953d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
95419202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
95519202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
956bf543036SJohan Hedberg 	}
957ab81cbf9SJohan Hedberg 
958a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
9594a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
9604a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
9614a964404SMarcel Holtmann 		 */
962d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
9634a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
9640602a8adSMarcel Holtmann 
9650602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
9660602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
9670602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
9680602a8adSMarcel Holtmann 		 *
9690602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
9700602a8adSMarcel Holtmann 		 * and no event will be send.
9710602a8adSMarcel Holtmann 		 */
972744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
973a69d8927SMarcel Holtmann 	} else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
9745ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
9755ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
9765ea234d3SMarcel Holtmann 		 */
977d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
9785ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
9795ea234d3SMarcel Holtmann 
980d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
981d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
982d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
983d603b76bSMarcel Holtmann 		 */
984d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
985ab81cbf9SJohan Hedberg 	}
986ab81cbf9SJohan Hedberg }
hci_power_off(struct work_struct * work)987ab81cbf9SJohan Hedberg 
988ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
989ab81cbf9SJohan Hedberg {
9903243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
9913243553fSJohan Hedberg 					    power_off.work);
992ab81cbf9SJohan Hedberg 
993ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
994ab81cbf9SJohan Hedberg 
9958ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
996ab81cbf9SJohan Hedberg }
hci_error_reset(struct work_struct * work)997ab81cbf9SJohan Hedberg 
998c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work)
999c7741d16SMarcel Holtmann {
1000c7741d16SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
1001c7741d16SMarcel Holtmann 
10022ab9a19dSYing Hsu 	hci_dev_hold(hdev);
1003c7741d16SMarcel Holtmann 	BT_DBG("%s", hdev->name);
1004c7741d16SMarcel Holtmann 
1005c7741d16SMarcel Holtmann 	if (hdev->hw_error)
1006c7741d16SMarcel Holtmann 		hdev->hw_error(hdev, hdev->hw_error_code);
1007c7741d16SMarcel Holtmann 	else
10082064ee33SMarcel Holtmann 		bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code);
1009c7741d16SMarcel Holtmann 
10102ab9a19dSYing Hsu 	if (!hci_dev_do_close(hdev))
1011c7741d16SMarcel Holtmann 		hci_dev_do_open(hdev);
10122ab9a19dSYing Hsu 
10132ab9a19dSYing Hsu 	hci_dev_put(hdev);
1014c7741d16SMarcel Holtmann }
hci_uuids_clear(struct hci_dev * hdev)1015c7741d16SMarcel Holtmann 
101635f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
10172aeb9a1aSJohan Hedberg {
10184821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
10192aeb9a1aSJohan Hedberg 
10204821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
10214821002cSJohan Hedberg 		list_del(&uuid->list);
10222aeb9a1aSJohan Hedberg 		kfree(uuid);
10232aeb9a1aSJohan Hedberg 	}
10242aeb9a1aSJohan Hedberg }
hci_link_keys_clear(struct hci_dev * hdev)10252aeb9a1aSJohan Hedberg 
102635f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
102755ed8ca1SJohan Hedberg {
10283673952cSMin Li 	struct link_key *key, *tmp;
102955ed8ca1SJohan Hedberg 
10303673952cSMin Li 	list_for_each_entry_safe(key, tmp, &hdev->link_keys, list) {
10310378b597SJohan Hedberg 		list_del_rcu(&key->list);
10320378b597SJohan Hedberg 		kfree_rcu(key, rcu);
103355ed8ca1SJohan Hedberg 	}
103455ed8ca1SJohan Hedberg }
hci_smp_ltks_clear(struct hci_dev * hdev)103555ed8ca1SJohan Hedberg 
103635f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
1037b899efafSVinicius Costa Gomes {
10383673952cSMin Li 	struct smp_ltk *k, *tmp;
1039b899efafSVinicius Costa Gomes 
10403673952cSMin Li 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1041970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
1042970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
1043b899efafSVinicius Costa Gomes 	}
1044b899efafSVinicius Costa Gomes }
hci_smp_irks_clear(struct hci_dev * hdev)1045b899efafSVinicius Costa Gomes 
1046970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
1047970c4e46SJohan Hedberg {
10483673952cSMin Li 	struct smp_irk *k, *tmp;
1049970c4e46SJohan Hedberg 
10503673952cSMin Li 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
1051adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
1052adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
1053970c4e46SJohan Hedberg 	}
1054970c4e46SJohan Hedberg }
hci_blocked_keys_clear(struct hci_dev * hdev)1055970c4e46SJohan Hedberg 
1056600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev)
1057600a8749SAlain Michaud {
10583673952cSMin Li 	struct blocked_key *b, *tmp;
1059600a8749SAlain Michaud 
10603673952cSMin Li 	list_for_each_entry_safe(b, tmp, &hdev->blocked_keys, list) {
1061600a8749SAlain Michaud 		list_del_rcu(&b->list);
1062600a8749SAlain Michaud 		kfree_rcu(b, rcu);
1063600a8749SAlain Michaud 	}
1064600a8749SAlain Michaud }
hci_is_blocked_key(struct hci_dev * hdev,u8 type,u8 val[16])1065600a8749SAlain Michaud 
1066600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16])
1067600a8749SAlain Michaud {
1068600a8749SAlain Michaud 	bool blocked = false;
1069600a8749SAlain Michaud 	struct blocked_key *b;
1070600a8749SAlain Michaud 
1071600a8749SAlain Michaud 	rcu_read_lock();
10720c2ac7d4SMadhuparna Bhowmik 	list_for_each_entry_rcu(b, &hdev->blocked_keys, list) {
1073600a8749SAlain Michaud 		if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) {
1074600a8749SAlain Michaud 			blocked = true;
1075600a8749SAlain Michaud 			break;
1076600a8749SAlain Michaud 		}
1077600a8749SAlain Michaud 	}
1078600a8749SAlain Michaud 
1079600a8749SAlain Michaud 	rcu_read_unlock();
1080600a8749SAlain Michaud 	return blocked;
1081600a8749SAlain Michaud }
hci_find_link_key(struct hci_dev * hdev,bdaddr_t * bdaddr)1082600a8749SAlain Michaud 
108355ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
108455ed8ca1SJohan Hedberg {
108555ed8ca1SJohan Hedberg 	struct link_key *k;
108655ed8ca1SJohan Hedberg 
10870378b597SJohan Hedberg 	rcu_read_lock();
10880378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
10890378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
10900378b597SJohan Hedberg 			rcu_read_unlock();
1091600a8749SAlain Michaud 
1092600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev,
1093600a8749SAlain Michaud 					       HCI_BLOCKED_KEY_TYPE_LINKKEY,
1094600a8749SAlain Michaud 					       k->val)) {
1095600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
1096600a8749SAlain Michaud 							"Link key blocked for %pMR",
1097600a8749SAlain Michaud 							&k->bdaddr);
1098600a8749SAlain Michaud 				return NULL;
1099600a8749SAlain Michaud 			}
1100600a8749SAlain Michaud 
110155ed8ca1SJohan Hedberg 			return k;
11020378b597SJohan Hedberg 		}
11030378b597SJohan Hedberg 	}
11040378b597SJohan Hedberg 	rcu_read_unlock();
110555ed8ca1SJohan Hedberg 
110655ed8ca1SJohan Hedberg 	return NULL;
110755ed8ca1SJohan Hedberg }
hci_persistent_key(struct hci_dev * hdev,struct hci_conn * conn,u8 key_type,u8 old_key_type)110855ed8ca1SJohan Hedberg 
1109745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1110d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1111d25e28abSJohan Hedberg {
1112d25e28abSJohan Hedberg 	/* Legacy key */
1113d25e28abSJohan Hedberg 	if (key_type < 0x03)
1114745c0ce3SVishal Agarwal 		return true;
1115d25e28abSJohan Hedberg 
1116d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1117d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1118745c0ce3SVishal Agarwal 		return false;
1119d25e28abSJohan Hedberg 
1120d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1121d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1122745c0ce3SVishal Agarwal 		return false;
1123d25e28abSJohan Hedberg 
1124d25e28abSJohan Hedberg 	/* Security mode 3 case */
1125d25e28abSJohan Hedberg 	if (!conn)
1126745c0ce3SVishal Agarwal 		return true;
1127d25e28abSJohan Hedberg 
1128e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
1129e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
1130e3befab9SJohan Hedberg 		return true;
1131e3befab9SJohan Hedberg 
1132d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1133d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1134745c0ce3SVishal Agarwal 		return true;
1135d25e28abSJohan Hedberg 
1136d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1137d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1138745c0ce3SVishal Agarwal 		return true;
1139d25e28abSJohan Hedberg 
1140d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1141d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1142745c0ce3SVishal Agarwal 		return true;
1143d25e28abSJohan Hedberg 
1144d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1145d25e28abSJohan Hedberg 	 * persistently */
1146745c0ce3SVishal Agarwal 	return false;
1147d25e28abSJohan Hedberg }
ltk_role(u8 type)1148d25e28abSJohan Hedberg 
1149e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
115098a0b845SJohan Hedberg {
1151e804d25dSJohan Hedberg 	if (type == SMP_LTK)
1152e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
115398a0b845SJohan Hedberg 
1154e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
115598a0b845SJohan Hedberg }
hci_find_ltk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type,u8 role)115698a0b845SJohan Hedberg 
1157f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
1158e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
115975d262c2SVinicius Costa Gomes {
1160c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
116175d262c2SVinicius Costa Gomes 
1162970d0f1bSJohan Hedberg 	rcu_read_lock();
1163970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
11645378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
11655378bc56SJohan Hedberg 			continue;
11665378bc56SJohan Hedberg 
1167923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
1168970d0f1bSJohan Hedberg 			rcu_read_unlock();
1169600a8749SAlain Michaud 
1170600a8749SAlain Michaud 			if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK,
1171600a8749SAlain Michaud 					       k->val)) {
1172600a8749SAlain Michaud 				bt_dev_warn_ratelimited(hdev,
1173600a8749SAlain Michaud 							"LTK blocked for %pMR",
1174600a8749SAlain Michaud 							&k->bdaddr);
1175600a8749SAlain Michaud 				return NULL;
1176600a8749SAlain Michaud 			}
1177600a8749SAlain Michaud 
117875d262c2SVinicius Costa Gomes 			return k;
1179970d0f1bSJohan Hedberg 		}
1180970d0f1bSJohan Hedberg 	}
1181970d0f1bSJohan Hedberg 	rcu_read_unlock();
118275d262c2SVinicius Costa Gomes 
118375d262c2SVinicius Costa Gomes 	return NULL;
118475d262c2SVinicius Costa Gomes }
hci_find_irk_by_rpa(struct hci_dev * hdev,bdaddr_t * rpa)118575d262c2SVinicius Costa Gomes 
1186970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
1187970c4e46SJohan Hedberg {
1188600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
1189970c4e46SJohan Hedberg 	struct smp_irk *irk;
1190970c4e46SJohan Hedberg 
1191adae20cbSJohan Hedberg 	rcu_read_lock();
1192adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1193adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
1194600a8749SAlain Michaud 			irk_to_return = irk;
1195600a8749SAlain Michaud 			goto done;
1196970c4e46SJohan Hedberg 		}
1197adae20cbSJohan Hedberg 	}
1198970c4e46SJohan Hedberg 
1199adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1200defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
1201970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
1202600a8749SAlain Michaud 			irk_to_return = irk;
1203600a8749SAlain Michaud 			goto done;
1204970c4e46SJohan Hedberg 		}
1205970c4e46SJohan Hedberg 	}
1206600a8749SAlain Michaud 
1207600a8749SAlain Michaud done:
1208600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
1209600a8749SAlain Michaud 						irk_to_return->val)) {
1210600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
1211600a8749SAlain Michaud 					&irk_to_return->bdaddr);
1212600a8749SAlain Michaud 		irk_to_return = NULL;
1213600a8749SAlain Michaud 	}
1214600a8749SAlain Michaud 
1215adae20cbSJohan Hedberg 	rcu_read_unlock();
1216970c4e46SJohan Hedberg 
1217600a8749SAlain Michaud 	return irk_to_return;
1218970c4e46SJohan Hedberg }
hci_find_irk_by_addr(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type)1219970c4e46SJohan Hedberg 
1220970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1221970c4e46SJohan Hedberg 				     u8 addr_type)
1222970c4e46SJohan Hedberg {
1223600a8749SAlain Michaud 	struct smp_irk *irk_to_return = NULL;
1224970c4e46SJohan Hedberg 	struct smp_irk *irk;
1225970c4e46SJohan Hedberg 
12266cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
12276cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
12286cfc9988SJohan Hedberg 		return NULL;
12296cfc9988SJohan Hedberg 
1230adae20cbSJohan Hedberg 	rcu_read_lock();
1231adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1232970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
1233adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
1234600a8749SAlain Michaud 			irk_to_return = irk;
1235600a8749SAlain Michaud 			goto done;
1236970c4e46SJohan Hedberg 		}
1237adae20cbSJohan Hedberg 	}
1238600a8749SAlain Michaud 
1239600a8749SAlain Michaud done:
1240600a8749SAlain Michaud 
1241600a8749SAlain Michaud 	if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
1242600a8749SAlain Michaud 						irk_to_return->val)) {
1243600a8749SAlain Michaud 		bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
1244600a8749SAlain Michaud 					&irk_to_return->bdaddr);
1245600a8749SAlain Michaud 		irk_to_return = NULL;
1246600a8749SAlain Michaud 	}
1247600a8749SAlain Michaud 
1248adae20cbSJohan Hedberg 	rcu_read_unlock();
1249970c4e46SJohan Hedberg 
1250600a8749SAlain Michaud 	return irk_to_return;
1251970c4e46SJohan Hedberg }
hci_add_link_key(struct hci_dev * hdev,struct hci_conn * conn,bdaddr_t * bdaddr,u8 * val,u8 type,u8 pin_len,bool * persistent)1252970c4e46SJohan Hedberg 
1253567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
12547652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
12557652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
125655ed8ca1SJohan Hedberg {
125755ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1258745c0ce3SVishal Agarwal 	u8 old_key_type;
125955ed8ca1SJohan Hedberg 
126055ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
126155ed8ca1SJohan Hedberg 	if (old_key) {
126255ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
126355ed8ca1SJohan Hedberg 		key = old_key;
126455ed8ca1SJohan Hedberg 	} else {
126512adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
12660a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
126755ed8ca1SJohan Hedberg 		if (!key)
1268567fa2aaSJohan Hedberg 			return NULL;
12690378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
127055ed8ca1SJohan Hedberg 	}
127155ed8ca1SJohan Hedberg 
12726ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
127355ed8ca1SJohan Hedberg 
1274d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1275d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1276d25e28abSJohan Hedberg 	 * previous key */
1277d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1278a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1279d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1280655fe6ecSJohan Hedberg 		if (conn)
1281655fe6ecSJohan Hedberg 			conn->key_type = type;
1282655fe6ecSJohan Hedberg 	}
1283d25e28abSJohan Hedberg 
128455ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
12859b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
128655ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
128755ed8ca1SJohan Hedberg 
1288b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
128955ed8ca1SJohan Hedberg 		key->type = old_key_type;
12904748fed2SJohan Hedberg 	else
12914748fed2SJohan Hedberg 		key->type = type;
12924748fed2SJohan Hedberg 
12937652ff6aSJohan Hedberg 	if (persistent)
12947652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
12957652ff6aSJohan Hedberg 						 old_key_type);
12964df378a1SJohan Hedberg 
1297567fa2aaSJohan Hedberg 	return key;
129855ed8ca1SJohan Hedberg }
hci_add_ltk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type,u8 type,u8 authenticated,u8 tk[16],u8 enc_size,__le16 ediv,__le64 rand)129955ed8ca1SJohan Hedberg 
1300ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
130135d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
1302fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
130375d262c2SVinicius Costa Gomes {
1304c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
1305e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
130675d262c2SVinicius Costa Gomes 
1307f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
1308c9839a11SVinicius Costa Gomes 	if (old_key)
130975d262c2SVinicius Costa Gomes 		key = old_key;
1310c9839a11SVinicius Costa Gomes 	else {
13110a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
131275d262c2SVinicius Costa Gomes 		if (!key)
1313ca9142b8SJohan Hedberg 			return NULL;
1314970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
131575d262c2SVinicius Costa Gomes 	}
131675d262c2SVinicius Costa Gomes 
131775d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1318c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1319c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1320c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1321c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1322fe39c7b2SMarcel Holtmann 	key->rand = rand;
1323c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1324c9839a11SVinicius Costa Gomes 	key->type = type;
132575d262c2SVinicius Costa Gomes 
1326ca9142b8SJohan Hedberg 	return key;
132775d262c2SVinicius Costa Gomes }
hci_add_irk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type,u8 val[16],bdaddr_t * rpa)132875d262c2SVinicius Costa Gomes 
1329ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
1330ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
1331970c4e46SJohan Hedberg {
1332970c4e46SJohan Hedberg 	struct smp_irk *irk;
1333970c4e46SJohan Hedberg 
1334970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
1335970c4e46SJohan Hedberg 	if (!irk) {
1336970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
1337970c4e46SJohan Hedberg 		if (!irk)
1338ca9142b8SJohan Hedberg 			return NULL;
1339970c4e46SJohan Hedberg 
1340970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
1341970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
1342970c4e46SJohan Hedberg 
1343adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
1344970c4e46SJohan Hedberg 	}
1345970c4e46SJohan Hedberg 
1346970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
1347970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
1348970c4e46SJohan Hedberg 
1349ca9142b8SJohan Hedberg 	return irk;
1350970c4e46SJohan Hedberg }
hci_remove_link_key(struct hci_dev * hdev,bdaddr_t * bdaddr)1351970c4e46SJohan Hedberg 
135255ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
135355ed8ca1SJohan Hedberg {
135455ed8ca1SJohan Hedberg 	struct link_key *key;
135555ed8ca1SJohan Hedberg 
135655ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
135755ed8ca1SJohan Hedberg 	if (!key)
135855ed8ca1SJohan Hedberg 		return -ENOENT;
135955ed8ca1SJohan Hedberg 
13606ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
136155ed8ca1SJohan Hedberg 
13620378b597SJohan Hedberg 	list_del_rcu(&key->list);
13630378b597SJohan Hedberg 	kfree_rcu(key, rcu);
136455ed8ca1SJohan Hedberg 
136555ed8ca1SJohan Hedberg 	return 0;
136655ed8ca1SJohan Hedberg }
hci_remove_ltk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 bdaddr_type)136755ed8ca1SJohan Hedberg 
1368e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
1369b899efafSVinicius Costa Gomes {
1370c5d2b6faSLuiz Augusto von Dentz 	struct smp_ltk *k, *tmp;
1371c51ffa0bSJohan Hedberg 	int removed = 0;
1372b899efafSVinicius Costa Gomes 
1373c5d2b6faSLuiz Augusto von Dentz 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1374e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
1375b899efafSVinicius Costa Gomes 			continue;
1376b899efafSVinicius Costa Gomes 
13776ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1378b899efafSVinicius Costa Gomes 
1379970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
1380970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
1381c51ffa0bSJohan Hedberg 		removed++;
1382b899efafSVinicius Costa Gomes 	}
1383b899efafSVinicius Costa Gomes 
1384c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
1385b899efafSVinicius Costa Gomes }
hci_remove_irk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type)1386b899efafSVinicius Costa Gomes 
1387a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
1388a7ec7338SJohan Hedberg {
1389c5d2b6faSLuiz Augusto von Dentz 	struct smp_irk *k, *tmp;
1390a7ec7338SJohan Hedberg 
1391c5d2b6faSLuiz Augusto von Dentz 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
1392a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
1393a7ec7338SJohan Hedberg 			continue;
1394a7ec7338SJohan Hedberg 
1395a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1396a7ec7338SJohan Hedberg 
1397adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
1398adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
1399a7ec7338SJohan Hedberg 	}
1400a7ec7338SJohan Hedberg }
hci_bdaddr_is_paired(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 type)1401a7ec7338SJohan Hedberg 
140255e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
140355e76b38SJohan Hedberg {
140455e76b38SJohan Hedberg 	struct smp_ltk *k;
14054ba9faf3SJohan Hedberg 	struct smp_irk *irk;
140655e76b38SJohan Hedberg 	u8 addr_type;
140755e76b38SJohan Hedberg 
140855e76b38SJohan Hedberg 	if (type == BDADDR_BREDR) {
140955e76b38SJohan Hedberg 		if (hci_find_link_key(hdev, bdaddr))
141055e76b38SJohan Hedberg 			return true;
141155e76b38SJohan Hedberg 		return false;
141255e76b38SJohan Hedberg 	}
141355e76b38SJohan Hedberg 
141455e76b38SJohan Hedberg 	/* Convert to HCI addr type which struct smp_ltk uses */
141555e76b38SJohan Hedberg 	if (type == BDADDR_LE_PUBLIC)
141655e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_PUBLIC;
141755e76b38SJohan Hedberg 	else
141855e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_RANDOM;
141955e76b38SJohan Hedberg 
14204ba9faf3SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, addr_type);
14214ba9faf3SJohan Hedberg 	if (irk) {
14224ba9faf3SJohan Hedberg 		bdaddr = &irk->bdaddr;
14234ba9faf3SJohan Hedberg 		addr_type = irk->addr_type;
14244ba9faf3SJohan Hedberg 	}
14254ba9faf3SJohan Hedberg 
142655e76b38SJohan Hedberg 	rcu_read_lock();
142755e76b38SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
142887c8b28dSJohan Hedberg 		if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) {
142987c8b28dSJohan Hedberg 			rcu_read_unlock();
143055e76b38SJohan Hedberg 			return true;
143155e76b38SJohan Hedberg 		}
143287c8b28dSJohan Hedberg 	}
143355e76b38SJohan Hedberg 	rcu_read_unlock();
143455e76b38SJohan Hedberg 
143555e76b38SJohan Hedberg 	return false;
143655e76b38SJohan Hedberg }
143755e76b38SJohan Hedberg 
hci_cmd_timeout(struct work_struct * work)14386bd32326SVille Tervo /* HCI command timer function */
143965cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
14406bd32326SVille Tervo {
144165cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
144265cc2b49SMarcel Holtmann 					    cmd_timer.work);
14436bd32326SVille Tervo 
14442af7aa66SLuiz Augusto von Dentz 	if (hdev->req_skb) {
14452af7aa66SLuiz Augusto von Dentz 		u16 opcode = hci_skb_opcode(hdev->req_skb);
1446bda4f23aSAndrei Emeltchenko 
14472064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode);
14480ce1229cSLuiz Augusto von Dentz 
14490ce1229cSLuiz Augusto von Dentz 		hci_cmd_sync_cancel_sync(hdev, ETIMEDOUT);
1450bda4f23aSAndrei Emeltchenko 	} else {
14512064ee33SMarcel Holtmann 		bt_dev_err(hdev, "command tx timeout");
1452bda4f23aSAndrei Emeltchenko 	}
1453bda4f23aSAndrei Emeltchenko 
1454e2bef384SRajat Jain 	if (hdev->cmd_timeout)
1455e2bef384SRajat Jain 		hdev->cmd_timeout(hdev);
1456e2bef384SRajat Jain 
14576bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1458c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
14596bd32326SVille Tervo }
14606bd32326SVille Tervo 
hci_ncmd_timeout(struct work_struct * work)1461de75cd0dSManish Mandlik /* HCI ncmd timer function */
1462de75cd0dSManish Mandlik static void hci_ncmd_timeout(struct work_struct *work)
1463de75cd0dSManish Mandlik {
1464de75cd0dSManish Mandlik 	struct hci_dev *hdev = container_of(work, struct hci_dev,
1465de75cd0dSManish Mandlik 					    ncmd_timer.work);
1466de75cd0dSManish Mandlik 
1467de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Controller not accepting commands anymore: ncmd = 0");
1468de75cd0dSManish Mandlik 
1469de75cd0dSManish Mandlik 	/* During HCI_INIT phase no events can be injected if the ncmd timer
1470de75cd0dSManish Mandlik 	 * triggers since the procedure has its own timeout handling.
1471de75cd0dSManish Mandlik 	 */
1472de75cd0dSManish Mandlik 	if (test_bit(HCI_INIT, &hdev->flags))
1473de75cd0dSManish Mandlik 		return;
1474de75cd0dSManish Mandlik 
1475de75cd0dSManish Mandlik 	/* This is an irrecoverable state, inject hardware error event */
1476de75cd0dSManish Mandlik 	hci_reset_dev(hdev);
1477de75cd0dSManish Mandlik }
hci_find_remote_oob_data(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 bdaddr_type)1478de75cd0dSManish Mandlik 
14792763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
14806928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
14812763eda6SSzymon Janc {
14822763eda6SSzymon Janc 	struct oob_data *data;
14832763eda6SSzymon Janc 
14846928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
14856928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
14866928a924SJohan Hedberg 			continue;
14876928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
14886928a924SJohan Hedberg 			continue;
14892763eda6SSzymon Janc 		return data;
14906928a924SJohan Hedberg 	}
14912763eda6SSzymon Janc 
14922763eda6SSzymon Janc 	return NULL;
14932763eda6SSzymon Janc }
hci_remove_remote_oob_data(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 bdaddr_type)14942763eda6SSzymon Janc 
14956928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
14966928a924SJohan Hedberg 			       u8 bdaddr_type)
14972763eda6SSzymon Janc {
14982763eda6SSzymon Janc 	struct oob_data *data;
14992763eda6SSzymon Janc 
15006928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
15012763eda6SSzymon Janc 	if (!data)
15022763eda6SSzymon Janc 		return -ENOENT;
15032763eda6SSzymon Janc 
15046928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
15052763eda6SSzymon Janc 
15062763eda6SSzymon Janc 	list_del(&data->list);
15072763eda6SSzymon Janc 	kfree(data);
15082763eda6SSzymon Janc 
15092763eda6SSzymon Janc 	return 0;
15102763eda6SSzymon Janc }
hci_remote_oob_data_clear(struct hci_dev * hdev)15112763eda6SSzymon Janc 
151235f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
15132763eda6SSzymon Janc {
15142763eda6SSzymon Janc 	struct oob_data *data, *n;
15152763eda6SSzymon Janc 
15162763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
15172763eda6SSzymon Janc 		list_del(&data->list);
15182763eda6SSzymon Janc 		kfree(data);
15192763eda6SSzymon Janc 	}
15202763eda6SSzymon Janc }
hci_add_remote_oob_data(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 bdaddr_type,u8 * hash192,u8 * rand192,u8 * hash256,u8 * rand256)15212763eda6SSzymon Janc 
15220798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
15236928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
152438da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
15250798872eSMarcel Holtmann {
15260798872eSMarcel Holtmann 	struct oob_data *data;
15270798872eSMarcel Holtmann 
15286928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
15290798872eSMarcel Holtmann 	if (!data) {
15300a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
15310798872eSMarcel Holtmann 		if (!data)
15320798872eSMarcel Holtmann 			return -ENOMEM;
15330798872eSMarcel Holtmann 
15340798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
15356928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
15360798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
15370798872eSMarcel Holtmann 	}
15380798872eSMarcel Holtmann 
153981328d5cSJohan Hedberg 	if (hash192 && rand192) {
15400798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
154138da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
1542f7697b16SMarcel Holtmann 		if (hash256 && rand256)
1543f7697b16SMarcel Holtmann 			data->present = 0x03;
154481328d5cSJohan Hedberg 	} else {
154581328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
154681328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
1547f7697b16SMarcel Holtmann 		if (hash256 && rand256)
1548f7697b16SMarcel Holtmann 			data->present = 0x02;
1549f7697b16SMarcel Holtmann 		else
1550f7697b16SMarcel Holtmann 			data->present = 0x00;
155181328d5cSJohan Hedberg 	}
15520798872eSMarcel Holtmann 
155381328d5cSJohan Hedberg 	if (hash256 && rand256) {
15540798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
155538da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
155681328d5cSJohan Hedberg 	} else {
155781328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
155881328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
1559f7697b16SMarcel Holtmann 		if (hash192 && rand192)
1560f7697b16SMarcel Holtmann 			data->present = 0x01;
156181328d5cSJohan Hedberg 	}
15620798872eSMarcel Holtmann 
15636ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
15642763eda6SSzymon Janc 
15652763eda6SSzymon Janc 	return 0;
15662763eda6SSzymon Janc }
15672763eda6SSzymon Janc 
hci_find_adv_instance(struct hci_dev * hdev,u8 instance)1568d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1569d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance)
1570d2609b34SFlorian Grandel {
1571d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
1572d2609b34SFlorian Grandel 
1573d2609b34SFlorian Grandel 	list_for_each_entry(adv_instance, &hdev->adv_instances, list) {
1574d2609b34SFlorian Grandel 		if (adv_instance->instance == instance)
1575d2609b34SFlorian Grandel 			return adv_instance;
1576d2609b34SFlorian Grandel 	}
1577d2609b34SFlorian Grandel 
1578d2609b34SFlorian Grandel 	return NULL;
1579d2609b34SFlorian Grandel }
1580d2609b34SFlorian Grandel 
hci_get_next_instance(struct hci_dev * hdev,u8 instance)1581d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
158274b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance)
158374b93e9fSPrasanna Karthik {
1584d2609b34SFlorian Grandel 	struct adv_info *cur_instance;
1585d2609b34SFlorian Grandel 
1586d2609b34SFlorian Grandel 	cur_instance = hci_find_adv_instance(hdev, instance);
1587d2609b34SFlorian Grandel 	if (!cur_instance)
1588d2609b34SFlorian Grandel 		return NULL;
1589d2609b34SFlorian Grandel 
1590d2609b34SFlorian Grandel 	if (cur_instance == list_last_entry(&hdev->adv_instances,
1591d2609b34SFlorian Grandel 					    struct adv_info, list))
1592d2609b34SFlorian Grandel 		return list_first_entry(&hdev->adv_instances,
1593d2609b34SFlorian Grandel 						 struct adv_info, list);
1594d2609b34SFlorian Grandel 	else
1595d2609b34SFlorian Grandel 		return list_next_entry(cur_instance, list);
1596d2609b34SFlorian Grandel }
1597d2609b34SFlorian Grandel 
hci_remove_adv_instance(struct hci_dev * hdev,u8 instance)1598d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1599d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance)
1600d2609b34SFlorian Grandel {
1601d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
1602d2609b34SFlorian Grandel 
1603d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
1604d2609b34SFlorian Grandel 	if (!adv_instance)
1605d2609b34SFlorian Grandel 		return -ENOENT;
1606d2609b34SFlorian Grandel 
1607d2609b34SFlorian Grandel 	BT_DBG("%s removing %dMR", hdev->name, instance);
1608d2609b34SFlorian Grandel 
1609cab054abSJohan Hedberg 	if (hdev->cur_adv_instance == instance) {
1610cab054abSJohan Hedberg 		if (hdev->adv_instance_timeout) {
16115d900e46SFlorian Grandel 			cancel_delayed_work(&hdev->adv_instance_expire);
16125d900e46SFlorian Grandel 			hdev->adv_instance_timeout = 0;
16135d900e46SFlorian Grandel 		}
1614cab054abSJohan Hedberg 		hdev->cur_adv_instance = 0x00;
1615cab054abSJohan Hedberg 	}
16165d900e46SFlorian Grandel 
1617a73c046aSJaganath Kanakkassery 	cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1618a73c046aSJaganath Kanakkassery 
1619d2609b34SFlorian Grandel 	list_del(&adv_instance->list);
1620d2609b34SFlorian Grandel 	kfree(adv_instance);
1621d2609b34SFlorian Grandel 
1622d2609b34SFlorian Grandel 	hdev->adv_instance_cnt--;
1623d2609b34SFlorian Grandel 
1624d2609b34SFlorian Grandel 	return 0;
1625d2609b34SFlorian Grandel }
hci_adv_instances_set_rpa_expired(struct hci_dev * hdev,bool rpa_expired)1626d2609b34SFlorian Grandel 
1627a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired)
1628a73c046aSJaganath Kanakkassery {
1629a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance, *n;
1630a73c046aSJaganath Kanakkassery 
1631a73c046aSJaganath Kanakkassery 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list)
1632a73c046aSJaganath Kanakkassery 		adv_instance->rpa_expired = rpa_expired;
1633a73c046aSJaganath Kanakkassery }
1634a73c046aSJaganath Kanakkassery 
hci_adv_instances_clear(struct hci_dev * hdev)1635d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1636d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev)
1637d2609b34SFlorian Grandel {
1638d2609b34SFlorian Grandel 	struct adv_info *adv_instance, *n;
1639d2609b34SFlorian Grandel 
16405d900e46SFlorian Grandel 	if (hdev->adv_instance_timeout) {
16415d900e46SFlorian Grandel 		cancel_delayed_work(&hdev->adv_instance_expire);
16425d900e46SFlorian Grandel 		hdev->adv_instance_timeout = 0;
16435d900e46SFlorian Grandel 	}
16445d900e46SFlorian Grandel 
1645d2609b34SFlorian Grandel 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
1646a73c046aSJaganath Kanakkassery 		cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1647d2609b34SFlorian Grandel 		list_del(&adv_instance->list);
1648d2609b34SFlorian Grandel 		kfree(adv_instance);
1649d2609b34SFlorian Grandel 	}
1650d2609b34SFlorian Grandel 
1651d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
1652cab054abSJohan Hedberg 	hdev->cur_adv_instance = 0x00;
1653d2609b34SFlorian Grandel }
adv_instance_rpa_expired(struct work_struct * work)1654d2609b34SFlorian Grandel 
1655a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work)
1656a73c046aSJaganath Kanakkassery {
1657a73c046aSJaganath Kanakkassery 	struct adv_info *adv_instance = container_of(work, struct adv_info,
1658a73c046aSJaganath Kanakkassery 						     rpa_expired_cb.work);
1659a73c046aSJaganath Kanakkassery 
1660a73c046aSJaganath Kanakkassery 	BT_DBG("");
1661a73c046aSJaganath Kanakkassery 
1662a73c046aSJaganath Kanakkassery 	adv_instance->rpa_expired = true;
1663a73c046aSJaganath Kanakkassery }
1664a73c046aSJaganath Kanakkassery 
hci_add_adv_instance(struct hci_dev * hdev,u8 instance,u32 flags,u16 adv_data_len,u8 * adv_data,u16 scan_rsp_len,u8 * scan_rsp_data,u16 timeout,u16 duration,s8 tx_power,u32 min_interval,u32 max_interval,u8 mesh_handle)1665d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1666eca0ae4aSLuiz Augusto von Dentz struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
1667eca0ae4aSLuiz Augusto von Dentz 				      u32 flags, u16 adv_data_len, u8 *adv_data,
1668d2609b34SFlorian Grandel 				      u16 scan_rsp_len, u8 *scan_rsp_data,
16699bf9f4b6SDaniel Winkler 				      u16 timeout, u16 duration, s8 tx_power,
1670b338d917SBrian Gix 				      u32 min_interval, u32 max_interval,
1671b338d917SBrian Gix 				      u8 mesh_handle)
1672d2609b34SFlorian Grandel {
1673eca0ae4aSLuiz Augusto von Dentz 	struct adv_info *adv;
1674d2609b34SFlorian Grandel 
1675eca0ae4aSLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
1676eca0ae4aSLuiz Augusto von Dentz 	if (adv) {
1677eca0ae4aSLuiz Augusto von Dentz 		memset(adv->adv_data, 0, sizeof(adv->adv_data));
1678eca0ae4aSLuiz Augusto von Dentz 		memset(adv->scan_rsp_data, 0, sizeof(adv->scan_rsp_data));
1679eca0ae4aSLuiz Augusto von Dentz 		memset(adv->per_adv_data, 0, sizeof(adv->per_adv_data));
1680d2609b34SFlorian Grandel 	} else {
16811d0fac2cSLuiz Augusto von Dentz 		if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets ||
1682b338d917SBrian Gix 		    instance < 1 || instance > hdev->le_num_of_adv_sets + 1)
1683eca0ae4aSLuiz Augusto von Dentz 			return ERR_PTR(-EOVERFLOW);
1684d2609b34SFlorian Grandel 
1685eca0ae4aSLuiz Augusto von Dentz 		adv = kzalloc(sizeof(*adv), GFP_KERNEL);
1686eca0ae4aSLuiz Augusto von Dentz 		if (!adv)
1687eca0ae4aSLuiz Augusto von Dentz 			return ERR_PTR(-ENOMEM);
1688d2609b34SFlorian Grandel 
1689eca0ae4aSLuiz Augusto von Dentz 		adv->pending = true;
1690eca0ae4aSLuiz Augusto von Dentz 		adv->instance = instance;
1691eca0ae4aSLuiz Augusto von Dentz 		list_add(&adv->list, &hdev->adv_instances);
1692d2609b34SFlorian Grandel 		hdev->adv_instance_cnt++;
1693d2609b34SFlorian Grandel 	}
1694d2609b34SFlorian Grandel 
1695eca0ae4aSLuiz Augusto von Dentz 	adv->flags = flags;
1696eca0ae4aSLuiz Augusto von Dentz 	adv->min_interval = min_interval;
1697eca0ae4aSLuiz Augusto von Dentz 	adv->max_interval = max_interval;
1698eca0ae4aSLuiz Augusto von Dentz 	adv->tx_power = tx_power;
1699b338d917SBrian Gix 	/* Defining a mesh_handle changes the timing units to ms,
1700b338d917SBrian Gix 	 * rather than seconds, and ties the instance to the requested
1701b338d917SBrian Gix 	 * mesh_tx queue.
1702b338d917SBrian Gix 	 */
1703b338d917SBrian Gix 	adv->mesh = mesh_handle;
1704d2609b34SFlorian Grandel 
170534a718bcSLuiz Augusto von Dentz 	hci_set_adv_instance_data(hdev, instance, adv_data_len, adv_data,
170634a718bcSLuiz Augusto von Dentz 				  scan_rsp_len, scan_rsp_data);
1707d2609b34SFlorian Grandel 
1708eca0ae4aSLuiz Augusto von Dentz 	adv->timeout = timeout;
1709eca0ae4aSLuiz Augusto von Dentz 	adv->remaining_time = timeout;
1710d2609b34SFlorian Grandel 
1711d2609b34SFlorian Grandel 	if (duration == 0)
1712eca0ae4aSLuiz Augusto von Dentz 		adv->duration = hdev->def_multi_adv_rotation_duration;
1713d2609b34SFlorian Grandel 	else
1714eca0ae4aSLuiz Augusto von Dentz 		adv->duration = duration;
1715d2609b34SFlorian Grandel 
1716eca0ae4aSLuiz Augusto von Dentz 	INIT_DELAYED_WORK(&adv->rpa_expired_cb, adv_instance_rpa_expired);
1717a73c046aSJaganath Kanakkassery 
1718d2609b34SFlorian Grandel 	BT_DBG("%s for %dMR", hdev->name, instance);
1719d2609b34SFlorian Grandel 
1720eca0ae4aSLuiz Augusto von Dentz 	return adv;
1721eca0ae4aSLuiz Augusto von Dentz }
1722eca0ae4aSLuiz Augusto von Dentz 
hci_add_per_instance(struct hci_dev * hdev,u8 instance,u32 flags,u8 data_len,u8 * data,u32 min_interval,u32 max_interval)1723eca0ae4aSLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */
1724eca0ae4aSLuiz Augusto von Dentz struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance,
1725eca0ae4aSLuiz Augusto von Dentz 				      u32 flags, u8 data_len, u8 *data,
1726eca0ae4aSLuiz Augusto von Dentz 				      u32 min_interval, u32 max_interval)
1727eca0ae4aSLuiz Augusto von Dentz {
1728eca0ae4aSLuiz Augusto von Dentz 	struct adv_info *adv;
1729eca0ae4aSLuiz Augusto von Dentz 
1730eca0ae4aSLuiz Augusto von Dentz 	adv = hci_add_adv_instance(hdev, instance, flags, 0, NULL, 0, NULL,
1731eca0ae4aSLuiz Augusto von Dentz 				   0, 0, HCI_ADV_TX_POWER_NO_PREFERENCE,
1732b338d917SBrian Gix 				   min_interval, max_interval, 0);
1733eca0ae4aSLuiz Augusto von Dentz 	if (IS_ERR(adv))
1734eca0ae4aSLuiz Augusto von Dentz 		return adv;
1735eca0ae4aSLuiz Augusto von Dentz 
1736eca0ae4aSLuiz Augusto von Dentz 	adv->periodic = true;
1737eca0ae4aSLuiz Augusto von Dentz 	adv->per_adv_data_len = data_len;
1738eca0ae4aSLuiz Augusto von Dentz 
1739eca0ae4aSLuiz Augusto von Dentz 	if (data)
1740eca0ae4aSLuiz Augusto von Dentz 		memcpy(adv->per_adv_data, data, data_len);
1741eca0ae4aSLuiz Augusto von Dentz 
1742eca0ae4aSLuiz Augusto von Dentz 	return adv;
1743d2609b34SFlorian Grandel }
1744d2609b34SFlorian Grandel 
hci_set_adv_instance_data(struct hci_dev * hdev,u8 instance,u16 adv_data_len,u8 * adv_data,u16 scan_rsp_len,u8 * scan_rsp_data)1745e5e1e7fdSMiao-chen Chou /* This function requires the caller holds hdev->lock */
174631aab5c2SDaniel Winkler int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance,
174731aab5c2SDaniel Winkler 			      u16 adv_data_len, u8 *adv_data,
174831aab5c2SDaniel Winkler 			      u16 scan_rsp_len, u8 *scan_rsp_data)
174931aab5c2SDaniel Winkler {
175034a718bcSLuiz Augusto von Dentz 	struct adv_info *adv;
175131aab5c2SDaniel Winkler 
175234a718bcSLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
175331aab5c2SDaniel Winkler 
175431aab5c2SDaniel Winkler 	/* If advertisement doesn't exist, we can't modify its data */
175534a718bcSLuiz Augusto von Dentz 	if (!adv)
175631aab5c2SDaniel Winkler 		return -ENOENT;
175731aab5c2SDaniel Winkler 
175834a718bcSLuiz Augusto von Dentz 	if (adv_data_len && ADV_DATA_CMP(adv, adv_data, adv_data_len)) {
175934a718bcSLuiz Augusto von Dentz 		memset(adv->adv_data, 0, sizeof(adv->adv_data));
176034a718bcSLuiz Augusto von Dentz 		memcpy(adv->adv_data, adv_data, adv_data_len);
176134a718bcSLuiz Augusto von Dentz 		adv->adv_data_len = adv_data_len;
176234a718bcSLuiz Augusto von Dentz 		adv->adv_data_changed = true;
176331aab5c2SDaniel Winkler 	}
176431aab5c2SDaniel Winkler 
176534a718bcSLuiz Augusto von Dentz 	if (scan_rsp_len && SCAN_RSP_CMP(adv, scan_rsp_data, scan_rsp_len)) {
176634a718bcSLuiz Augusto von Dentz 		memset(adv->scan_rsp_data, 0, sizeof(adv->scan_rsp_data));
176734a718bcSLuiz Augusto von Dentz 		memcpy(adv->scan_rsp_data, scan_rsp_data, scan_rsp_len);
176834a718bcSLuiz Augusto von Dentz 		adv->scan_rsp_len = scan_rsp_len;
176934a718bcSLuiz Augusto von Dentz 		adv->scan_rsp_changed = true;
177031aab5c2SDaniel Winkler 	}
177131aab5c2SDaniel Winkler 
177234a718bcSLuiz Augusto von Dentz 	/* Mark as changed if there are flags which would affect it */
177334a718bcSLuiz Augusto von Dentz 	if (((adv->flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance) ||
177434a718bcSLuiz Augusto von Dentz 	    adv->flags & MGMT_ADV_FLAG_LOCAL_NAME)
177534a718bcSLuiz Augusto von Dentz 		adv->scan_rsp_changed = true;
177634a718bcSLuiz Augusto von Dentz 
177731aab5c2SDaniel Winkler 	return 0;
177831aab5c2SDaniel Winkler }
177931aab5c2SDaniel Winkler 
hci_adv_instance_flags(struct hci_dev * hdev,u8 instance)178031aab5c2SDaniel Winkler /* This function requires the caller holds hdev->lock */
178101ce70b0SLuiz Augusto von Dentz u32 hci_adv_instance_flags(struct hci_dev *hdev, u8 instance)
178201ce70b0SLuiz Augusto von Dentz {
178301ce70b0SLuiz Augusto von Dentz 	u32 flags;
178401ce70b0SLuiz Augusto von Dentz 	struct adv_info *adv;
178501ce70b0SLuiz Augusto von Dentz 
178601ce70b0SLuiz Augusto von Dentz 	if (instance == 0x00) {
178701ce70b0SLuiz Augusto von Dentz 		/* Instance 0 always manages the "Tx Power" and "Flags"
178801ce70b0SLuiz Augusto von Dentz 		 * fields
178901ce70b0SLuiz Augusto von Dentz 		 */
179001ce70b0SLuiz Augusto von Dentz 		flags = MGMT_ADV_FLAG_TX_POWER | MGMT_ADV_FLAG_MANAGED_FLAGS;
179101ce70b0SLuiz Augusto von Dentz 
179201ce70b0SLuiz Augusto von Dentz 		/* For instance 0, the HCI_ADVERTISING_CONNECTABLE setting
179301ce70b0SLuiz Augusto von Dentz 		 * corresponds to the "connectable" instance flag.
179401ce70b0SLuiz Augusto von Dentz 		 */
179501ce70b0SLuiz Augusto von Dentz 		if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE))
179601ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_CONNECTABLE;
179701ce70b0SLuiz Augusto von Dentz 
179801ce70b0SLuiz Augusto von Dentz 		if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
179901ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
180001ce70b0SLuiz Augusto von Dentz 		else if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
180101ce70b0SLuiz Augusto von Dentz 			flags |= MGMT_ADV_FLAG_DISCOV;
180201ce70b0SLuiz Augusto von Dentz 
180301ce70b0SLuiz Augusto von Dentz 		return flags;
180401ce70b0SLuiz Augusto von Dentz 	}
180501ce70b0SLuiz Augusto von Dentz 
180601ce70b0SLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
180701ce70b0SLuiz Augusto von Dentz 
180801ce70b0SLuiz Augusto von Dentz 	/* Return 0 when we got an invalid instance identifier. */
180901ce70b0SLuiz Augusto von Dentz 	if (!adv)
181001ce70b0SLuiz Augusto von Dentz 		return 0;
181101ce70b0SLuiz Augusto von Dentz 
181201ce70b0SLuiz Augusto von Dentz 	return adv->flags;
181301ce70b0SLuiz Augusto von Dentz }
hci_adv_instance_is_scannable(struct hci_dev * hdev,u8 instance)181401ce70b0SLuiz Augusto von Dentz 
181501ce70b0SLuiz Augusto von Dentz bool hci_adv_instance_is_scannable(struct hci_dev *hdev, u8 instance)
181601ce70b0SLuiz Augusto von Dentz {
181701ce70b0SLuiz Augusto von Dentz 	struct adv_info *adv;
181801ce70b0SLuiz Augusto von Dentz 
181901ce70b0SLuiz Augusto von Dentz 	/* Instance 0x00 always set local name */
182001ce70b0SLuiz Augusto von Dentz 	if (instance == 0x00)
182101ce70b0SLuiz Augusto von Dentz 		return true;
182201ce70b0SLuiz Augusto von Dentz 
182301ce70b0SLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, instance);
182401ce70b0SLuiz Augusto von Dentz 	if (!adv)
182501ce70b0SLuiz Augusto von Dentz 		return false;
182601ce70b0SLuiz Augusto von Dentz 
182701ce70b0SLuiz Augusto von Dentz 	if (adv->flags & MGMT_ADV_FLAG_APPEARANCE ||
182801ce70b0SLuiz Augusto von Dentz 	    adv->flags & MGMT_ADV_FLAG_LOCAL_NAME)
182901ce70b0SLuiz Augusto von Dentz 		return true;
183001ce70b0SLuiz Augusto von Dentz 
183101ce70b0SLuiz Augusto von Dentz 	return adv->scan_rsp_len ? true : false;
183201ce70b0SLuiz Augusto von Dentz }
183301ce70b0SLuiz Augusto von Dentz 
hci_adv_monitors_clear(struct hci_dev * hdev)183401ce70b0SLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */
1835e5e1e7fdSMiao-chen Chou void hci_adv_monitors_clear(struct hci_dev *hdev)
1836e5e1e7fdSMiao-chen Chou {
1837b139553dSMiao-chen Chou 	struct adv_monitor *monitor;
1838b139553dSMiao-chen Chou 	int handle;
1839b139553dSMiao-chen Chou 
1840b139553dSMiao-chen Chou 	idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle)
184166bd095aSArchie Pusaka 		hci_free_adv_monitor(hdev, monitor);
1842b139553dSMiao-chen Chou 
1843e5e1e7fdSMiao-chen Chou 	idr_destroy(&hdev->adv_monitors_idr);
1844e5e1e7fdSMiao-chen Chou }
1845e5e1e7fdSMiao-chen Chou 
184666bd095aSArchie Pusaka /* Frees the monitor structure and do some bookkeepings.
184766bd095aSArchie Pusaka  * This function requires the caller holds hdev->lock.
hci_free_adv_monitor(struct hci_dev * hdev,struct adv_monitor * monitor)184866bd095aSArchie Pusaka  */
184966bd095aSArchie Pusaka void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
1850b139553dSMiao-chen Chou {
1851b139553dSMiao-chen Chou 	struct adv_pattern *pattern;
1852b139553dSMiao-chen Chou 	struct adv_pattern *tmp;
1853b139553dSMiao-chen Chou 
1854b139553dSMiao-chen Chou 	if (!monitor)
1855b139553dSMiao-chen Chou 		return;
1856b139553dSMiao-chen Chou 
185766bd095aSArchie Pusaka 	list_for_each_entry_safe(pattern, tmp, &monitor->patterns, list) {
185866bd095aSArchie Pusaka 		list_del(&pattern->list);
1859b139553dSMiao-chen Chou 		kfree(pattern);
186066bd095aSArchie Pusaka 	}
186166bd095aSArchie Pusaka 
186266bd095aSArchie Pusaka 	if (monitor->handle)
186366bd095aSArchie Pusaka 		idr_remove(&hdev->adv_monitors_idr, monitor->handle);
186466bd095aSArchie Pusaka 
186566bd095aSArchie Pusaka 	if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) {
186666bd095aSArchie Pusaka 		hdev->adv_monitors_cnt--;
186766bd095aSArchie Pusaka 		mgmt_adv_monitor_removed(hdev, monitor->handle);
186866bd095aSArchie Pusaka 	}
1869b139553dSMiao-chen Chou 
1870b139553dSMiao-chen Chou 	kfree(monitor);
1871b139553dSMiao-chen Chou }
1872b139553dSMiao-chen Chou 
1873a2a4dedfSArchie Pusaka /* Assigns handle to a monitor, and if offloading is supported and power is on,
1874a2a4dedfSArchie Pusaka  * also attempts to forward the request to the controller.
1875b747a836SManish Mandlik  * This function requires the caller holds hci_req_sync_lock.
hci_add_adv_monitor(struct hci_dev * hdev,struct adv_monitor * monitor)1876a2a4dedfSArchie Pusaka  */
1877b747a836SManish Mandlik int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
1878b139553dSMiao-chen Chou {
1879b139553dSMiao-chen Chou 	int min, max, handle;
1880b747a836SManish Mandlik 	int status = 0;
1881b139553dSMiao-chen Chou 
1882b747a836SManish Mandlik 	if (!monitor)
1883b747a836SManish Mandlik 		return -EINVAL;
1884a2a4dedfSArchie Pusaka 
1885b747a836SManish Mandlik 	hci_dev_lock(hdev);
1886b139553dSMiao-chen Chou 
1887b139553dSMiao-chen Chou 	min = HCI_MIN_ADV_MONITOR_HANDLE;
1888b139553dSMiao-chen Chou 	max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES;
1889b139553dSMiao-chen Chou 	handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max,
1890b139553dSMiao-chen Chou 			   GFP_KERNEL);
1891b747a836SManish Mandlik 
1892b747a836SManish Mandlik 	hci_dev_unlock(hdev);
1893b747a836SManish Mandlik 
1894b747a836SManish Mandlik 	if (handle < 0)
1895b747a836SManish Mandlik 		return handle;
1896b139553dSMiao-chen Chou 
1897b139553dSMiao-chen Chou 	monitor->handle = handle;
18988208f5a9SMiao-chen Chou 
1899a2a4dedfSArchie Pusaka 	if (!hdev_is_powered(hdev))
1900b747a836SManish Mandlik 		return status;
19018208f5a9SMiao-chen Chou 
1902a2a4dedfSArchie Pusaka 	switch (hci_get_adv_monitor_offload_ext(hdev)) {
1903a2a4dedfSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_NONE:
19046f55eea1SDouglas Anderson 		bt_dev_dbg(hdev, "add monitor %d status %d",
1905b747a836SManish Mandlik 			   monitor->handle, status);
1906a2a4dedfSArchie Pusaka 		/* Message was not forwarded to controller - not an error */
1907b747a836SManish Mandlik 		break;
1908b747a836SManish Mandlik 
1909a2a4dedfSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_MSFT:
1910b747a836SManish Mandlik 		status = msft_add_monitor_pattern(hdev, monitor);
19116f55eea1SDouglas Anderson 		bt_dev_dbg(hdev, "add monitor %d msft status %d",
1912a2bcd2b6SManish Mandlik 			   handle, status);
1913a2a4dedfSArchie Pusaka 		break;
1914a2a4dedfSArchie Pusaka 	}
1915a2a4dedfSArchie Pusaka 
1916b747a836SManish Mandlik 	return status;
1917b139553dSMiao-chen Chou }
1918b139553dSMiao-chen Chou 
191966bd095aSArchie Pusaka /* Attempts to tell the controller and free the monitor. If somehow the
192066bd095aSArchie Pusaka  * controller doesn't have a corresponding handle, remove anyway.
19217cf5c297SManish Mandlik  * This function requires the caller holds hci_req_sync_lock.
hci_remove_adv_monitor(struct hci_dev * hdev,struct adv_monitor * monitor)192266bd095aSArchie Pusaka  */
19237cf5c297SManish Mandlik static int hci_remove_adv_monitor(struct hci_dev *hdev,
19247cf5c297SManish Mandlik 				  struct adv_monitor *monitor)
1925bd2fbc6cSMiao-chen Chou {
19267cf5c297SManish Mandlik 	int status = 0;
1927de6dfcefSDouglas Anderson 	int handle;
1928bd2fbc6cSMiao-chen Chou 
192966bd095aSArchie Pusaka 	switch (hci_get_adv_monitor_offload_ext(hdev)) {
193066bd095aSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */
19316f55eea1SDouglas Anderson 		bt_dev_dbg(hdev, "remove monitor %d status %d",
19327cf5c297SManish Mandlik 			   monitor->handle, status);
193366bd095aSArchie Pusaka 		goto free_monitor;
19347cf5c297SManish Mandlik 
193566bd095aSArchie Pusaka 	case HCI_ADV_MONITOR_EXT_MSFT:
1936de6dfcefSDouglas Anderson 		handle = monitor->handle;
19377cf5c297SManish Mandlik 		status = msft_remove_monitor(hdev, monitor);
19386f55eea1SDouglas Anderson 		bt_dev_dbg(hdev, "remove monitor %d msft status %d",
19396f55eea1SDouglas Anderson 			   handle, status);
194066bd095aSArchie Pusaka 		break;
1941bd2fbc6cSMiao-chen Chou 	}
1942bd2fbc6cSMiao-chen Chou 
194366bd095aSArchie Pusaka 	/* In case no matching handle registered, just free the monitor */
19447cf5c297SManish Mandlik 	if (status == -ENOENT)
194566bd095aSArchie Pusaka 		goto free_monitor;
1946bd2fbc6cSMiao-chen Chou 
19477cf5c297SManish Mandlik 	return status;
1948bd2fbc6cSMiao-chen Chou 
194966bd095aSArchie Pusaka free_monitor:
19507cf5c297SManish Mandlik 	if (status == -ENOENT)
195166bd095aSArchie Pusaka 		bt_dev_warn(hdev, "Removing monitor with no matching handle %d",
195266bd095aSArchie Pusaka 			    monitor->handle);
195366bd095aSArchie Pusaka 	hci_free_adv_monitor(hdev, monitor);
195466bd095aSArchie Pusaka 
19557cf5c297SManish Mandlik 	return status;
1956bd2fbc6cSMiao-chen Chou }
1957bd2fbc6cSMiao-chen Chou 
hci_remove_single_adv_monitor(struct hci_dev * hdev,u16 handle)19587cf5c297SManish Mandlik /* This function requires the caller holds hci_req_sync_lock */
19597cf5c297SManish Mandlik int hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle)
196066bd095aSArchie Pusaka {
196166bd095aSArchie Pusaka 	struct adv_monitor *monitor = idr_find(&hdev->adv_monitors_idr, handle);
196266bd095aSArchie Pusaka 
19637cf5c297SManish Mandlik 	if (!monitor)
19647cf5c297SManish Mandlik 		return -EINVAL;
19657cf5c297SManish Mandlik 
19667cf5c297SManish Mandlik 	return hci_remove_adv_monitor(hdev, monitor);
196766bd095aSArchie Pusaka }
196866bd095aSArchie Pusaka 
hci_remove_all_adv_monitor(struct hci_dev * hdev)19697cf5c297SManish Mandlik /* This function requires the caller holds hci_req_sync_lock */
19707cf5c297SManish Mandlik int hci_remove_all_adv_monitor(struct hci_dev *hdev)
197166bd095aSArchie Pusaka {
197266bd095aSArchie Pusaka 	struct adv_monitor *monitor;
197366bd095aSArchie Pusaka 	int idr_next_id = 0;
19747cf5c297SManish Mandlik 	int status = 0;
197566bd095aSArchie Pusaka 
19767cf5c297SManish Mandlik 	while (1) {
197766bd095aSArchie Pusaka 		monitor = idr_get_next(&hdev->adv_monitors_idr, &idr_next_id);
197866bd095aSArchie Pusaka 		if (!monitor)
197966bd095aSArchie Pusaka 			break;
198066bd095aSArchie Pusaka 
19817cf5c297SManish Mandlik 		status = hci_remove_adv_monitor(hdev, monitor);
19827cf5c297SManish Mandlik 		if (status)
19837cf5c297SManish Mandlik 			return status;
198466bd095aSArchie Pusaka 
19857cf5c297SManish Mandlik 		idr_next_id++;
198666bd095aSArchie Pusaka 	}
198766bd095aSArchie Pusaka 
19887cf5c297SManish Mandlik 	return status;
1989bd2fbc6cSMiao-chen Chou }
1990bd2fbc6cSMiao-chen Chou 
hci_is_adv_monitoring(struct hci_dev * hdev)19918208f5a9SMiao-chen Chou /* This function requires the caller holds hdev->lock */
19928208f5a9SMiao-chen Chou bool hci_is_adv_monitoring(struct hci_dev *hdev)
19938208f5a9SMiao-chen Chou {
19948208f5a9SMiao-chen Chou 	return !idr_is_empty(&hdev->adv_monitors_idr);
19958208f5a9SMiao-chen Chou }
hci_get_adv_monitor_offload_ext(struct hci_dev * hdev)19968208f5a9SMiao-chen Chou 
1997a2a4dedfSArchie Pusaka int hci_get_adv_monitor_offload_ext(struct hci_dev *hdev)
1998a2a4dedfSArchie Pusaka {
1999a2a4dedfSArchie Pusaka 	if (msft_monitor_supported(hdev))
2000a2a4dedfSArchie Pusaka 		return HCI_ADV_MONITOR_EXT_MSFT;
2001a2a4dedfSArchie Pusaka 
2002a2a4dedfSArchie Pusaka 	return HCI_ADV_MONITOR_EXT_NONE;
2003a2a4dedfSArchie Pusaka }
hci_bdaddr_list_lookup(struct list_head * bdaddr_list,bdaddr_t * bdaddr,u8 type)2004a2a4dedfSArchie Pusaka 
2005dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
2006b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
2007b2a66aadSAntti Julku {
2008b2a66aadSAntti Julku 	struct bdaddr_list *b;
2009b2a66aadSAntti Julku 
2010dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
2011b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2012b2a66aadSAntti Julku 			return b;
2013b9ee0a78SMarcel Holtmann 	}
2014b2a66aadSAntti Julku 
2015b2a66aadSAntti Julku 	return NULL;
2016b2a66aadSAntti Julku }
hci_bdaddr_list_lookup_with_irk(struct list_head * bdaddr_list,bdaddr_t * bdaddr,u8 type)2017b2a66aadSAntti Julku 
2018b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
2019b950aa88SAnkit Navik 				struct list_head *bdaddr_list, bdaddr_t *bdaddr,
2020b950aa88SAnkit Navik 				u8 type)
2021b950aa88SAnkit Navik {
2022b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *b;
2023b950aa88SAnkit Navik 
2024b950aa88SAnkit Navik 	list_for_each_entry(b, bdaddr_list, list) {
2025b950aa88SAnkit Navik 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2026b950aa88SAnkit Navik 			return b;
2027b950aa88SAnkit Navik 	}
2028b950aa88SAnkit Navik 
2029b950aa88SAnkit Navik 	return NULL;
2030b950aa88SAnkit Navik }
2031b950aa88SAnkit Navik 
hci_bdaddr_list_lookup_with_flags(struct list_head * bdaddr_list,bdaddr_t * bdaddr,u8 type)20328baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *
20338baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list,
20348baaa403SAbhishek Pandit-Subedi 				  bdaddr_t *bdaddr, u8 type)
20358baaa403SAbhishek Pandit-Subedi {
20368baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *b;
20378baaa403SAbhishek Pandit-Subedi 
20388baaa403SAbhishek Pandit-Subedi 	list_for_each_entry(b, bdaddr_list, list) {
20398baaa403SAbhishek Pandit-Subedi 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
20408baaa403SAbhishek Pandit-Subedi 			return b;
20418baaa403SAbhishek Pandit-Subedi 	}
20428baaa403SAbhishek Pandit-Subedi 
20438baaa403SAbhishek Pandit-Subedi 	return NULL;
20448baaa403SAbhishek Pandit-Subedi }
hci_bdaddr_list_clear(struct list_head * bdaddr_list)20458baaa403SAbhishek Pandit-Subedi 
2046dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
2047b2a66aadSAntti Julku {
20487eb7404fSGeliang Tang 	struct bdaddr_list *b, *n;
2049b2a66aadSAntti Julku 
20507eb7404fSGeliang Tang 	list_for_each_entry_safe(b, n, bdaddr_list, list) {
20517eb7404fSGeliang Tang 		list_del(&b->list);
2052b2a66aadSAntti Julku 		kfree(b);
2053b2a66aadSAntti Julku 	}
2054b2a66aadSAntti Julku }
hci_bdaddr_list_add(struct list_head * list,bdaddr_t * bdaddr,u8 type)2055b2a66aadSAntti Julku 
2056dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2057b2a66aadSAntti Julku {
2058b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2059b2a66aadSAntti Julku 
2060b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
2061b2a66aadSAntti Julku 		return -EBADF;
2062b2a66aadSAntti Julku 
2063dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
20645e762444SAntti Julku 		return -EEXIST;
2065b2a66aadSAntti Julku 
206627f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
20675e762444SAntti Julku 	if (!entry)
20685e762444SAntti Julku 		return -ENOMEM;
2069b2a66aadSAntti Julku 
2070b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2071b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
2072b2a66aadSAntti Julku 
2073dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
2074b2a66aadSAntti Julku 
20752a8357f2SJohan Hedberg 	return 0;
2076b2a66aadSAntti Julku }
hci_bdaddr_list_add_with_irk(struct list_head * list,bdaddr_t * bdaddr,u8 type,u8 * peer_irk,u8 * local_irk)2077b2a66aadSAntti Julku 
2078b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2079b950aa88SAnkit Navik 					u8 type, u8 *peer_irk, u8 *local_irk)
2080b950aa88SAnkit Navik {
2081b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
2082b950aa88SAnkit Navik 
2083b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY))
2084b950aa88SAnkit Navik 		return -EBADF;
2085b950aa88SAnkit Navik 
2086b950aa88SAnkit Navik 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
2087b950aa88SAnkit Navik 		return -EEXIST;
2088b950aa88SAnkit Navik 
2089b950aa88SAnkit Navik 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
2090b950aa88SAnkit Navik 	if (!entry)
2091b950aa88SAnkit Navik 		return -ENOMEM;
2092b950aa88SAnkit Navik 
2093b950aa88SAnkit Navik 	bacpy(&entry->bdaddr, bdaddr);
2094b950aa88SAnkit Navik 	entry->bdaddr_type = type;
2095b950aa88SAnkit Navik 
2096b950aa88SAnkit Navik 	if (peer_irk)
2097b950aa88SAnkit Navik 		memcpy(entry->peer_irk, peer_irk, 16);
2098b950aa88SAnkit Navik 
2099b950aa88SAnkit Navik 	if (local_irk)
2100b950aa88SAnkit Navik 		memcpy(entry->local_irk, local_irk, 16);
2101b950aa88SAnkit Navik 
2102b950aa88SAnkit Navik 	list_add(&entry->list, list);
2103b950aa88SAnkit Navik 
2104b950aa88SAnkit Navik 	return 0;
2105b950aa88SAnkit Navik }
hci_bdaddr_list_add_with_flags(struct list_head * list,bdaddr_t * bdaddr,u8 type,u32 flags)2106b950aa88SAnkit Navik 
21078baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
21088baaa403SAbhishek Pandit-Subedi 				   u8 type, u32 flags)
21098baaa403SAbhishek Pandit-Subedi {
21108baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
21118baaa403SAbhishek Pandit-Subedi 
21128baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY))
21138baaa403SAbhishek Pandit-Subedi 		return -EBADF;
21148baaa403SAbhishek Pandit-Subedi 
21158baaa403SAbhishek Pandit-Subedi 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
21168baaa403SAbhishek Pandit-Subedi 		return -EEXIST;
21178baaa403SAbhishek Pandit-Subedi 
21188baaa403SAbhishek Pandit-Subedi 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
21198baaa403SAbhishek Pandit-Subedi 	if (!entry)
21208baaa403SAbhishek Pandit-Subedi 		return -ENOMEM;
21218baaa403SAbhishek Pandit-Subedi 
21228baaa403SAbhishek Pandit-Subedi 	bacpy(&entry->bdaddr, bdaddr);
21238baaa403SAbhishek Pandit-Subedi 	entry->bdaddr_type = type;
2124e1cff700SLinus Torvalds 	entry->flags = flags;
21258baaa403SAbhishek Pandit-Subedi 
21268baaa403SAbhishek Pandit-Subedi 	list_add(&entry->list, list);
21278baaa403SAbhishek Pandit-Subedi 
21288baaa403SAbhishek Pandit-Subedi 	return 0;
21298baaa403SAbhishek Pandit-Subedi }
hci_bdaddr_list_del(struct list_head * list,bdaddr_t * bdaddr,u8 type)21308baaa403SAbhishek Pandit-Subedi 
2131dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2132b2a66aadSAntti Julku {
2133b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2134b2a66aadSAntti Julku 
213535f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2136dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
213735f7498aSJohan Hedberg 		return 0;
213835f7498aSJohan Hedberg 	}
2139b2a66aadSAntti Julku 
2140dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
2141d2ab0ac1SMarcel Holtmann 	if (!entry)
2142d2ab0ac1SMarcel Holtmann 		return -ENOENT;
2143d2ab0ac1SMarcel Holtmann 
2144d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
2145d2ab0ac1SMarcel Holtmann 	kfree(entry);
2146d2ab0ac1SMarcel Holtmann 
2147d2ab0ac1SMarcel Holtmann 	return 0;
2148d2ab0ac1SMarcel Holtmann }
hci_bdaddr_list_del_with_irk(struct list_head * list,bdaddr_t * bdaddr,u8 type)2149d2ab0ac1SMarcel Holtmann 
2150b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2151b950aa88SAnkit Navik 							u8 type)
2152b950aa88SAnkit Navik {
2153b950aa88SAnkit Navik 	struct bdaddr_list_with_irk *entry;
2154b950aa88SAnkit Navik 
2155b950aa88SAnkit Navik 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2156b950aa88SAnkit Navik 		hci_bdaddr_list_clear(list);
2157b950aa88SAnkit Navik 		return 0;
2158b950aa88SAnkit Navik 	}
2159b950aa88SAnkit Navik 
2160b950aa88SAnkit Navik 	entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type);
2161b950aa88SAnkit Navik 	if (!entry)
2162b950aa88SAnkit Navik 		return -ENOENT;
2163b950aa88SAnkit Navik 
2164b950aa88SAnkit Navik 	list_del(&entry->list);
2165b950aa88SAnkit Navik 	kfree(entry);
2166b950aa88SAnkit Navik 
2167b950aa88SAnkit Navik 	return 0;
2168b950aa88SAnkit Navik }
hci_bdaddr_list_del_with_flags(struct list_head * list,bdaddr_t * bdaddr,u8 type)2169b950aa88SAnkit Navik 
21708baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
21718baaa403SAbhishek Pandit-Subedi 				   u8 type)
21728baaa403SAbhishek Pandit-Subedi {
21738baaa403SAbhishek Pandit-Subedi 	struct bdaddr_list_with_flags *entry;
21748baaa403SAbhishek Pandit-Subedi 
21758baaa403SAbhishek Pandit-Subedi 	if (!bacmp(bdaddr, BDADDR_ANY)) {
21768baaa403SAbhishek Pandit-Subedi 		hci_bdaddr_list_clear(list);
21778baaa403SAbhishek Pandit-Subedi 		return 0;
21788baaa403SAbhishek Pandit-Subedi 	}
21798baaa403SAbhishek Pandit-Subedi 
21808baaa403SAbhishek Pandit-Subedi 	entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type);
21818baaa403SAbhishek Pandit-Subedi 	if (!entry)
21828baaa403SAbhishek Pandit-Subedi 		return -ENOENT;
21838baaa403SAbhishek Pandit-Subedi 
21848baaa403SAbhishek Pandit-Subedi 	list_del(&entry->list);
21858baaa403SAbhishek Pandit-Subedi 	kfree(entry);
21868baaa403SAbhishek Pandit-Subedi 
21878baaa403SAbhishek Pandit-Subedi 	return 0;
21888baaa403SAbhishek Pandit-Subedi }
21898baaa403SAbhishek Pandit-Subedi 
hci_conn_params_lookup(struct hci_dev * hdev,bdaddr_t * addr,u8 addr_type)219015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
219115819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
219215819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
219315819a70SAndre Guedes {
219415819a70SAndre Guedes 	struct hci_conn_params *params;
219515819a70SAndre Guedes 
219615819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
219715819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
219815819a70SAndre Guedes 		    params->addr_type == addr_type) {
219915819a70SAndre Guedes 			return params;
220015819a70SAndre Guedes 		}
220115819a70SAndre Guedes 	}
220215819a70SAndre Guedes 
220315819a70SAndre Guedes 	return NULL;
220415819a70SAndre Guedes }
220515819a70SAndre Guedes 
hci_pend_le_action_lookup(struct list_head * list,bdaddr_t * addr,u8 addr_type)2206195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock or rcu_read_lock */
2207501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
22084b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
2209a9b0a04cSAndre Guedes {
2210912b42efSJohan Hedberg 	struct hci_conn_params *param;
2211a9b0a04cSAndre Guedes 
2212195ef75eSPauli Virtanen 	rcu_read_lock();
2213195ef75eSPauli Virtanen 
2214195ef75eSPauli Virtanen 	list_for_each_entry_rcu(param, list, action) {
2215912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
2216195ef75eSPauli Virtanen 		    param->addr_type == addr_type) {
2217195ef75eSPauli Virtanen 			rcu_read_unlock();
2218912b42efSJohan Hedberg 			return param;
22194b10966fSMarcel Holtmann 		}
2220195ef75eSPauli Virtanen 	}
2221195ef75eSPauli Virtanen 
2222195ef75eSPauli Virtanen 	rcu_read_unlock();
22234b10966fSMarcel Holtmann 
22244b10966fSMarcel Holtmann 	return NULL;
2225a9b0a04cSAndre Guedes }
2226a9b0a04cSAndre Guedes 
hci_pend_le_list_del_init(struct hci_conn_params * param)222715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
2228195ef75eSPauli Virtanen void hci_pend_le_list_del_init(struct hci_conn_params *param)
2229195ef75eSPauli Virtanen {
2230195ef75eSPauli Virtanen 	if (list_empty(&param->action))
2231195ef75eSPauli Virtanen 		return;
2232195ef75eSPauli Virtanen 
2233195ef75eSPauli Virtanen 	list_del_rcu(&param->action);
2234195ef75eSPauli Virtanen 	synchronize_rcu();
2235195ef75eSPauli Virtanen 	INIT_LIST_HEAD(&param->action);
2236195ef75eSPauli Virtanen }
2237195ef75eSPauli Virtanen 
hci_pend_le_list_add(struct hci_conn_params * param,struct list_head * list)2238195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock */
2239195ef75eSPauli Virtanen void hci_pend_le_list_add(struct hci_conn_params *param,
2240195ef75eSPauli Virtanen 			  struct list_head *list)
2241195ef75eSPauli Virtanen {
2242195ef75eSPauli Virtanen 	list_add_rcu(&param->action, list);
2243195ef75eSPauli Virtanen }
2244195ef75eSPauli Virtanen 
hci_conn_params_add(struct hci_dev * hdev,bdaddr_t * addr,u8 addr_type)2245195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock */
224651d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
224751d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
224815819a70SAndre Guedes {
224915819a70SAndre Guedes 	struct hci_conn_params *params;
225015819a70SAndre Guedes 
225115819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
2252cef952ceSAndre Guedes 	if (params)
225351d167c0SMarcel Holtmann 		return params;
225415819a70SAndre Guedes 
225515819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
225615819a70SAndre Guedes 	if (!params) {
22572064ee33SMarcel Holtmann 		bt_dev_err(hdev, "out of memory");
225851d167c0SMarcel Holtmann 		return NULL;
225915819a70SAndre Guedes 	}
226015819a70SAndre Guedes 
226115819a70SAndre Guedes 	bacpy(&params->addr, addr);
226215819a70SAndre Guedes 	params->addr_type = addr_type;
2263cef952ceSAndre Guedes 
2264cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
226593450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
2266cef952ceSAndre Guedes 
2267bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
2268bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
2269bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
2270bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
2271bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
2272bf5b3c8bSMarcel Holtmann 
2273bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
2274bf5b3c8bSMarcel Holtmann 
227551d167c0SMarcel Holtmann 	return params;
2276bf5b3c8bSMarcel Holtmann }
hci_conn_params_free(struct hci_conn_params * params)2277bf5b3c8bSMarcel Holtmann 
2278195ef75eSPauli Virtanen void hci_conn_params_free(struct hci_conn_params *params)
2279f6c63249SJohan Hedberg {
2280195ef75eSPauli Virtanen 	hci_pend_le_list_del_init(params);
2281195ef75eSPauli Virtanen 
2282f6c63249SJohan Hedberg 	if (params->conn) {
2283f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
2284f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
2285f6c63249SJohan Hedberg 	}
2286f6c63249SJohan Hedberg 
2287f6c63249SJohan Hedberg 	list_del(&params->list);
2288f6c63249SJohan Hedberg 	kfree(params);
2289f6c63249SJohan Hedberg }
2290f6c63249SJohan Hedberg 
hci_conn_params_del(struct hci_dev * hdev,bdaddr_t * addr,u8 addr_type)229115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
229215819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
229315819a70SAndre Guedes {
229415819a70SAndre Guedes 	struct hci_conn_params *params;
229515819a70SAndre Guedes 
229615819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
229715819a70SAndre Guedes 	if (!params)
229815819a70SAndre Guedes 		return;
229915819a70SAndre Guedes 
2300f6c63249SJohan Hedberg 	hci_conn_params_free(params);
230115819a70SAndre Guedes 
23025bee2fd6SLuiz Augusto von Dentz 	hci_update_passive_scan(hdev);
230395305baaSJohan Hedberg 
230415819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
230515819a70SAndre Guedes }
230615819a70SAndre Guedes 
hci_conn_params_clear_disabled(struct hci_dev * hdev)230715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
230855af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
230915819a70SAndre Guedes {
231015819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
231115819a70SAndre Guedes 
231215819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
231355af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
231455af49a8SJohan Hedberg 			continue;
2315f75113a2SJakub Pawlowski 
231691641b79SZheng Yongjun 		/* If trying to establish one time connection to disabled
2317f75113a2SJakub Pawlowski 		 * device, leave the params, but mark them as just once.
2318f75113a2SJakub Pawlowski 		 */
2319f75113a2SJakub Pawlowski 		if (params->explicit_connect) {
2320f75113a2SJakub Pawlowski 			params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
2321f75113a2SJakub Pawlowski 			continue;
2322f75113a2SJakub Pawlowski 		}
2323f75113a2SJakub Pawlowski 
2324195ef75eSPauli Virtanen 		hci_conn_params_free(params);
232515819a70SAndre Guedes 	}
232615819a70SAndre Guedes 
232755af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
232855af49a8SJohan Hedberg }
232955af49a8SJohan Hedberg 
hci_conn_params_clear_all(struct hci_dev * hdev)233055af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
2331030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev)
233215819a70SAndre Guedes {
233315819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
233415819a70SAndre Guedes 
2335f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
2336f6c63249SJohan Hedberg 		hci_conn_params_free(params);
233715819a70SAndre Guedes 
233815819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
233915819a70SAndre Guedes }
234015819a70SAndre Guedes 
2341a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
2342a1f4c318SJohan Hedberg  *
2343a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
2344a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
2345a1f4c318SJohan Hedberg  * the static random address.
2346a1f4c318SJohan Hedberg  *
2347a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
2348a1f4c318SJohan Hedberg  * public address to use the static random address instead.
234950b5b952SMarcel Holtmann  *
235050b5b952SMarcel Holtmann  * In case BR/EDR has been disabled on a dual-mode controller and
235150b5b952SMarcel Holtmann  * userspace has configured a static address, then that address
235250b5b952SMarcel Holtmann  * becomes the identity address instead of the public BR/EDR address.
hci_copy_identity_address(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 * bdaddr_type)2353a1f4c318SJohan Hedberg  */
2354a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
2355a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
2356a1f4c318SJohan Hedberg {
2357b7cb93e5SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
235850b5b952SMarcel Holtmann 	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
2359d7a5a11dSMarcel Holtmann 	    (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
236050b5b952SMarcel Holtmann 	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
2361a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
2362a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
2363a1f4c318SJohan Hedberg 	} else {
2364a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
2365a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
2366a1f4c318SJohan Hedberg 	}
2367a1f4c318SJohan Hedberg }
hci_clear_wake_reason(struct hci_dev * hdev)2368a1f4c318SJohan Hedberg 
23692f20216cSAbhishek Pandit-Subedi static void hci_clear_wake_reason(struct hci_dev *hdev)
23702f20216cSAbhishek Pandit-Subedi {
23712f20216cSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
23722f20216cSAbhishek Pandit-Subedi 
23732f20216cSAbhishek Pandit-Subedi 	hdev->wake_reason = 0;
23742f20216cSAbhishek Pandit-Subedi 	bacpy(&hdev->wake_addr, BDADDR_ANY);
23752f20216cSAbhishek Pandit-Subedi 	hdev->wake_addr_type = 0;
23762f20216cSAbhishek Pandit-Subedi 
23772f20216cSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
23782f20216cSAbhishek Pandit-Subedi }
hci_suspend_notifier(struct notifier_block * nb,unsigned long action,void * data)23792f20216cSAbhishek Pandit-Subedi 
23809952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
23819952d90eSAbhishek Pandit-Subedi 				void *data)
23829952d90eSAbhishek Pandit-Subedi {
23839952d90eSAbhishek Pandit-Subedi 	struct hci_dev *hdev =
23849952d90eSAbhishek Pandit-Subedi 		container_of(nb, struct hci_dev, suspend_notifier);
23859952d90eSAbhishek Pandit-Subedi 	int ret = 0;
23869952d90eSAbhishek Pandit-Subedi 
23874b8af331SAbhishek Pandit-Subedi 	/* Userspace has full control of this device. Do nothing. */
23884b8af331SAbhishek Pandit-Subedi 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
23894b8af331SAbhishek Pandit-Subedi 		return NOTIFY_DONE;
23904b8af331SAbhishek Pandit-Subedi 
2391573ebae1SYing Hsu 	/* To avoid a potential race with hci_unregister_dev. */
2392573ebae1SYing Hsu 	hci_dev_hold(hdev);
2393573ebae1SYing Hsu 
2394c8525821SLuiz Augusto von Dentz 	switch (action) {
2395c8525821SLuiz Augusto von Dentz 	case PM_HIBERNATION_PREPARE:
2396c8525821SLuiz Augusto von Dentz 	case PM_SUSPEND_PREPARE:
2397e1b77d68SLuiz Augusto von Dentz 		ret = hci_suspend_dev(hdev);
2398c8525821SLuiz Augusto von Dentz 		break;
2399c8525821SLuiz Augusto von Dentz 	case PM_POST_HIBERNATION:
2400c8525821SLuiz Augusto von Dentz 	case PM_POST_SUSPEND:
2401e1b77d68SLuiz Augusto von Dentz 		ret = hci_resume_dev(hdev);
2402c8525821SLuiz Augusto von Dentz 		break;
2403c8525821SLuiz Augusto von Dentz 	}
24049952d90eSAbhishek Pandit-Subedi 
2405a9ec8423SAbhishek Pandit-Subedi 	if (ret)
2406a9ec8423SAbhishek Pandit-Subedi 		bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
2407a9ec8423SAbhishek Pandit-Subedi 			   action, ret);
2408a9ec8423SAbhishek Pandit-Subedi 
2409573ebae1SYing Hsu 	hci_dev_put(hdev);
241024b06572SMax Chou 	return NOTIFY_DONE;
24119952d90eSAbhishek Pandit-Subedi }
24128731840aSAbhishek Pandit-Subedi 
hci_alloc_dev_priv(int sizeof_priv)24139be0dab7SDavid Herrmann /* Alloc HCI device */
24146ec56613STedd Ho-Jeong An struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
24159be0dab7SDavid Herrmann {
24169be0dab7SDavid Herrmann 	struct hci_dev *hdev;
24176ec56613STedd Ho-Jeong An 	unsigned int alloc_size;
24189be0dab7SDavid Herrmann 
24196ec56613STedd Ho-Jeong An 	alloc_size = sizeof(*hdev);
24206ec56613STedd Ho-Jeong An 	if (sizeof_priv) {
24216ec56613STedd Ho-Jeong An 		/* Fixme: May need ALIGN-ment? */
24226ec56613STedd Ho-Jeong An 		alloc_size += sizeof_priv;
24236ec56613STedd Ho-Jeong An 	}
24246ec56613STedd Ho-Jeong An 
24256ec56613STedd Ho-Jeong An 	hdev = kzalloc(alloc_size, GFP_KERNEL);
24269be0dab7SDavid Herrmann 	if (!hdev)
24279be0dab7SDavid Herrmann 		return NULL;
24289be0dab7SDavid Herrmann 
2429b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2430b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
2431b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
2432b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
2433b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
243496c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
2435bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2436bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2437d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
2438d2609b34SFlorian Grandel 	hdev->cur_adv_instance = 0x00;
24395d900e46SFlorian Grandel 	hdev->adv_instance_timeout = 0;
2440b1b813d4SDavid Herrmann 
2441c4f1f408SHoward Chung 	hdev->advmon_allowlist_duration = 300;
2442c4f1f408SHoward Chung 	hdev->advmon_no_filter_duration = 500;
244380af16a3SHoward Chung 	hdev->enable_advmon_interleave_scan = 0x00;	/* Default to disable */
2444c4f1f408SHoward Chung 
2445b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
2446b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
2447b1b813d4SDavid Herrmann 
24483f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
2449628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
2450628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
2451bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
2452bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
245310873f99SAlain Michaud 	hdev->le_scan_int_suspend = 0x0400;
245410873f99SAlain Michaud 	hdev->le_scan_window_suspend = 0x0012;
245510873f99SAlain Michaud 	hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT;
245610873f99SAlain Michaud 	hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN;
2457ba29d036SMarcel Holtmann 	hdev->le_scan_int_adv_monitor = 0x0060;
2458ba29d036SMarcel Holtmann 	hdev->le_scan_window_adv_monitor = 0x0030;
245910873f99SAlain Michaud 	hdev->le_scan_int_connect = 0x0060;
246010873f99SAlain Michaud 	hdev->le_scan_window_connect = 0x0060;
2461b48c3b59SJonas Holmberg 	hdev->le_conn_min_interval = 0x0018;
2462b48c3b59SJonas Holmberg 	hdev->le_conn_max_interval = 0x0028;
246304fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
246404fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
2465a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = 0x001b;
2466a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = 0x0148;
2467a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = 0x001b;
2468a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = 0x0148;
2469a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = 0x001b;
2470a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = 0x0148;
247130d65e08SMatias Karhumaa 	hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE;
247230d65e08SMatias Karhumaa 	hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE;
24736decb5b4SJaganath Kanakkassery 	hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
24746decb5b4SJaganath Kanakkassery 	hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
24751d0fac2cSLuiz Augusto von Dentz 	hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES;
247610873f99SAlain Michaud 	hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION;
247749b020c1SAlain Michaud 	hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT;
24787c395ea5SDaniel Winkler 	hdev->min_le_tx_power = HCI_TX_POWER_INVALID;
24797c395ea5SDaniel Winkler 	hdev->max_le_tx_power = HCI_TX_POWER_INVALID;
2480bef64738SMarcel Holtmann 
2481d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
2482b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
248331ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
248431ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
2485302975cbSSpoorthi Ravishankar Koppad 	hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT;
248658a96fc3SMarcel Holtmann 	hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE;
2487d6bfd59cSJohan Hedberg 
248810873f99SAlain Michaud 	/* default 1.28 sec page scan */
248910873f99SAlain Michaud 	hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD;
249010873f99SAlain Michaud 	hdev->def_page_scan_int = 0x0800;
249110873f99SAlain Michaud 	hdev->def_page_scan_window = 0x0012;
249210873f99SAlain Michaud 
2493b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
2494b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
2495b1b813d4SDavid Herrmann 
249684cb0143SZiyang Xuan 	ida_init(&hdev->unset_handle_ida);
249784cb0143SZiyang Xuan 
2498b338d917SBrian Gix 	INIT_LIST_HEAD(&hdev->mesh_pending);
2499b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
25003d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->reject_list);
25013d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->accept_list);
2502b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
2503b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
2504b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
2505970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
2506b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
25073d4f9c00SArchie Pusaka 	INIT_LIST_HEAD(&hdev->le_accept_list);
2508cfdb0c2dSAnkit Navik 	INIT_LIST_HEAD(&hdev->le_resolv_list);
250915819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
251077a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
251166f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
25126b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
2513d2609b34SFlorian Grandel 	INIT_LIST_HEAD(&hdev->adv_instances);
2514600a8749SAlain Michaud 	INIT_LIST_HEAD(&hdev->blocked_keys);
25153368aa35SManish Mandlik 	INIT_LIST_HEAD(&hdev->monitored_devices);
2516b1b813d4SDavid Herrmann 
25178961987fSKiran K 	INIT_LIST_HEAD(&hdev->local_codecs);
2518b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2519b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2520b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2521b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2522c7741d16SMarcel Holtmann 	INIT_WORK(&hdev->error_reset, hci_error_reset);
2523b1b813d4SDavid Herrmann 
25246a98e383SMarcel Holtmann 	hci_cmd_sync_init(hdev);
25256a98e383SMarcel Holtmann 
2526b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2527b1b813d4SDavid Herrmann 
2528b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2529b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2530b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2531b1b813d4SDavid Herrmann 
2532b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2533b1b813d4SDavid Herrmann 
253465cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
2535de75cd0dSManish Mandlik 	INIT_DELAYED_WORK(&hdev->ncmd_timer, hci_ncmd_timeout);
2536b1b813d4SDavid Herrmann 
25379695ef87SAbhishek Pandit-Subedi 	hci_devcd_setup(hdev);
25385fc16cc4SJohan Hedberg 	hci_request_setup(hdev);
25395fc16cc4SJohan Hedberg 
2540b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2541b1b813d4SDavid Herrmann 	discovery_init(hdev);
25429be0dab7SDavid Herrmann 
25439be0dab7SDavid Herrmann 	return hdev;
25449be0dab7SDavid Herrmann }
25456ec56613STedd Ho-Jeong An EXPORT_SYMBOL(hci_alloc_dev_priv);
25469be0dab7SDavid Herrmann 
hci_free_dev(struct hci_dev * hdev)25479be0dab7SDavid Herrmann /* Free HCI device */
25489be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
25499be0dab7SDavid Herrmann {
25509be0dab7SDavid Herrmann 	/* will free via device release */
25519be0dab7SDavid Herrmann 	put_device(&hdev->dev);
25529be0dab7SDavid Herrmann }
25539be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
25549be0dab7SDavid Herrmann 
hci_register_dev(struct hci_dev * hdev)25551da177e4SLinus Torvalds /* Register HCI device */
25561da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
25571da177e4SLinus Torvalds {
2558b1b813d4SDavid Herrmann 	int id, error;
25591da177e4SLinus Torvalds 
256074292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
25611da177e4SLinus Torvalds 		return -EINVAL;
25621da177e4SLinus Torvalds 
25630a8af30aSChristophe JAILLET 	id = ida_alloc_max(&hci_index_ida, HCI_MAX_ID - 1, GFP_KERNEL);
25643df92b31SSasha Levin 	if (id < 0)
25653df92b31SSasha Levin 		return id;
25663df92b31SSasha Levin 
2567dcda1657SLuiz Augusto von Dentz 	error = dev_set_name(&hdev->dev, "hci%u", id);
2568dcda1657SLuiz Augusto von Dentz 	if (error)
2569dcda1657SLuiz Augusto von Dentz 		return error;
2570dcda1657SLuiz Augusto von Dentz 
2571dcda1657SLuiz Augusto von Dentz 	hdev->name = dev_name(&hdev->dev);
25721da177e4SLinus Torvalds 	hdev->id = id;
25732d8b3a11SAndrei Emeltchenko 
25742d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
25752d8b3a11SAndrei Emeltchenko 
257629e2dd0dSTejun Heo 	hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name);
257733ca954dSDavid Herrmann 	if (!hdev->workqueue) {
257833ca954dSDavid Herrmann 		error = -ENOMEM;
257933ca954dSDavid Herrmann 		goto err;
258033ca954dSDavid Herrmann 	}
2581f48fd9c8SMarcel Holtmann 
258229e2dd0dSTejun Heo 	hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI,
258329e2dd0dSTejun Heo 						      hdev->name);
25846ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
25856ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
25866ead1bbcSJohan Hedberg 		error = -ENOMEM;
25876ead1bbcSJohan Hedberg 		goto err;
25886ead1bbcSJohan Hedberg 	}
25896ead1bbcSJohan Hedberg 
25900153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
25910153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
25920153e2ecSMarcel 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 
261556f87901SJohan Hedberg 	/* Assume BR/EDR support until proven otherwise (such as
261656f87901SJohan Hedberg 	 * through reading supported features during init.
261756f87901SJohan Hedberg 	 */
2618a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
2619ce2be9acSAndrei Emeltchenko 
2620fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
2621fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
2622fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
2623fcee3377SGustavo Padovan 
26244a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
26254a964404SMarcel Holtmann 	 * and should not be included in normal operation.
2626fee746b0SMarcel Holtmann 	 */
2627fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
2628a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
2629fee746b0SMarcel Holtmann 
2630fe92ee64SLuiz Augusto von Dentz 	/* Mark Remote Wakeup connection flag as supported if driver has wakeup
2631fe92ee64SLuiz Augusto von Dentz 	 * callback.
2632fe92ee64SLuiz Augusto von Dentz 	 */
2633fe92ee64SLuiz Augusto von Dentz 	if (hdev->wakeup)
2634e1cff700SLinus Torvalds 		hdev->conn_flags |= HCI_CONN_FLAG_REMOTE_WAKEUP;
2635fe92ee64SLuiz Augusto von Dentz 
263605fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_REG);
2637dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
26381da177e4SLinus Torvalds 
263991117864SDan Carpenter 	error = hci_register_suspend_notifier(hdev);
264091117864SDan Carpenter 	if (error)
26410d75da38SYang Yingliang 		BT_WARN("register suspend notifier failed error:%d\n", error);
26429952d90eSAbhishek Pandit-Subedi 
264319202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2644fbe96d6fSMarcel Holtmann 
2645e5e1e7fdSMiao-chen Chou 	idr_init(&hdev->adv_monitors_idr);
26465031ffccSMiao-chen Chou 	msft_register(hdev);
2647e5e1e7fdSMiao-chen Chou 
26481da177e4SLinus Torvalds 	return id;
2649f48fd9c8SMarcel Holtmann 
265033ca954dSDavid Herrmann err_wqueue:
26515a4bb6a8SWei Yongjun 	debugfs_remove_recursive(hdev->debugfs);
265233ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
26536ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
265433ca954dSDavid Herrmann err:
26550a8af30aSChristophe JAILLET 	ida_free(&hci_index_ida, hdev->id);
2656f48fd9c8SMarcel Holtmann 
265733ca954dSDavid Herrmann 	return error;
26581da177e4SLinus Torvalds }
26591da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
26601da177e4SLinus Torvalds 
hci_unregister_dev(struct hci_dev * hdev)26611da177e4SLinus Torvalds /* Unregister HCI device */
266259735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
26631da177e4SLinus Torvalds {
2664c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
26651da177e4SLinus Torvalds 
26661857c199SZhengping Jiang 	mutex_lock(&hdev->unregister_lock);
2667a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_UNREGISTER);
26681857c199SZhengping Jiang 	mutex_unlock(&hdev->unregister_lock);
266994324962SJohan Hovold 
2670f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
26711da177e4SLinus Torvalds 	list_del(&hdev->list);
2672f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
26731da177e4SLinus Torvalds 
2674d6cbce18STetsuo Handa 	cancel_work_sync(&hdev->rx_work);
2675d6cbce18STetsuo Handa 	cancel_work_sync(&hdev->cmd_work);
2676d6cbce18STetsuo Handa 	cancel_work_sync(&hdev->tx_work);
2677e36bea6eSVasyl Vavrychuk 	cancel_work_sync(&hdev->power_on);
2678d6cbce18STetsuo Handa 	cancel_work_sync(&hdev->error_reset);
2679e36bea6eSVasyl Vavrychuk 
26806a98e383SMarcel Holtmann 	hci_cmd_sync_clear(hdev);
26816a98e383SMarcel Holtmann 
2682359ee4f8SAbhishek Pandit-Subedi 	hci_unregister_suspend_notifier(hdev);
26834e8c36c3SAbhishek Pandit-Subedi 
26844e8c36c3SAbhishek Pandit-Subedi 	hci_dev_do_close(hdev);
26859952d90eSAbhishek Pandit-Subedi 
2686ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2687d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_SETUP) &&
2688d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
268909fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2690744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
269109fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
269256e5cb86SJohan Hedberg 	}
2693ab81cbf9SJohan Hedberg 
26942e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
26952e58ef3eSJohan Hedberg 	 * pending list */
26962e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
26972e58ef3eSJohan Hedberg 
269805fcd4c4SMarcel Holtmann 	hci_sock_dev_event(hdev, HCI_DEV_UNREG);
26991da177e4SLinus Torvalds 
2700611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2701611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2702611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2703611b30f7SMarcel Holtmann 	}
2704611b30f7SMarcel Holtmann 
2705bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
2706e61fbee7SDavid S. Miller 	/* Actual cleanup is deferred until hci_release_dev(). */
2707e0448092STetsuo Handa 	hci_dev_put(hdev);
2708e0448092STetsuo Handa }
2709e0448092STetsuo Handa EXPORT_SYMBOL(hci_unregister_dev);
2710147e2d59SDave Young 
hci_release_dev(struct hci_dev * hdev)271158ce6d5bSTetsuo Handa /* Release HCI device */
271258ce6d5bSTetsuo Handa void hci_release_dev(struct hci_dev *hdev)
2713e0448092STetsuo Handa {
27140153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
27155177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
27165177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
27170153e2ecSMarcel Holtmann 
2718f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
27196ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2720f48fd9c8SMarcel Holtmann 
272109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
27223d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->reject_list);
27233d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->accept_list);
27242aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
272555ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2726b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
2727970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
27282763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
2729d2609b34SFlorian Grandel 	hci_adv_instances_clear(hdev);
2730e5e1e7fdSMiao-chen Chou 	hci_adv_monitors_clear(hdev);
27313d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
2732cfdb0c2dSAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
2733373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
273422078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
2735600a8749SAlain Michaud 	hci_blocked_keys_clear(hdev);
2736b938790eSLuiz Augusto von Dentz 	hci_codec_list_clear(&hdev->local_codecs);
2737a85a60e6SSungwoo Kim 	msft_release(hdev);
273809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2739e2e0cacbSJohan Hedberg 
274084cb0143SZiyang Xuan 	ida_destroy(&hdev->unset_handle_ida);
27410a8af30aSChristophe JAILLET 	ida_free(&hci_index_ida, hdev->id);
2742dd3b1dc3SLuiz Augusto von Dentz 	kfree_skb(hdev->sent_cmd);
27432af7aa66SLuiz Augusto von Dentz 	kfree_skb(hdev->req_skb);
2744dfe6d5c3SLuiz Augusto von Dentz 	kfree_skb(hdev->recv_event);
274558ce6d5bSTetsuo Handa 	kfree(hdev);
27461da177e4SLinus Torvalds }
274758ce6d5bSTetsuo Handa EXPORT_SYMBOL(hci_release_dev);
hci_register_suspend_notifier(struct hci_dev * hdev)27481da177e4SLinus Torvalds 
2749359ee4f8SAbhishek Pandit-Subedi int hci_register_suspend_notifier(struct hci_dev *hdev)
2750359ee4f8SAbhishek Pandit-Subedi {
2751359ee4f8SAbhishek Pandit-Subedi 	int ret = 0;
2752359ee4f8SAbhishek Pandit-Subedi 
2753b5ca3387SLuiz Augusto von Dentz 	if (!hdev->suspend_notifier.notifier_call &&
2754b5ca3387SLuiz Augusto von Dentz 	    !test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
2755359ee4f8SAbhishek Pandit-Subedi 		hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
2756359ee4f8SAbhishek Pandit-Subedi 		ret = register_pm_notifier(&hdev->suspend_notifier);
2757359ee4f8SAbhishek Pandit-Subedi 	}
2758359ee4f8SAbhishek Pandit-Subedi 
2759359ee4f8SAbhishek Pandit-Subedi 	return ret;
2760359ee4f8SAbhishek Pandit-Subedi }
hci_unregister_suspend_notifier(struct hci_dev * hdev)2761359ee4f8SAbhishek Pandit-Subedi 
2762359ee4f8SAbhishek Pandit-Subedi int hci_unregister_suspend_notifier(struct hci_dev *hdev)
2763359ee4f8SAbhishek Pandit-Subedi {
2764359ee4f8SAbhishek Pandit-Subedi 	int ret = 0;
2765359ee4f8SAbhishek Pandit-Subedi 
2766b5ca3387SLuiz Augusto von Dentz 	if (hdev->suspend_notifier.notifier_call) {
2767359ee4f8SAbhishek Pandit-Subedi 		ret = unregister_pm_notifier(&hdev->suspend_notifier);
2768b5ca3387SLuiz Augusto von Dentz 		if (!ret)
2769b5ca3387SLuiz Augusto von Dentz 			hdev->suspend_notifier.notifier_call = NULL;
2770b5ca3387SLuiz Augusto von Dentz 	}
2771359ee4f8SAbhishek Pandit-Subedi 
2772359ee4f8SAbhishek Pandit-Subedi 	return ret;
2773359ee4f8SAbhishek Pandit-Subedi }
2774359ee4f8SAbhishek Pandit-Subedi 
27750ce1229cSLuiz Augusto von Dentz /* Cancel ongoing command synchronously:
27760ce1229cSLuiz Augusto von Dentz  *
27770ce1229cSLuiz Augusto von Dentz  * - Cancel command timer
27780ce1229cSLuiz Augusto von Dentz  * - Reset command counter
27790ce1229cSLuiz Augusto von Dentz  * - Cancel command request
hci_cancel_cmd_sync(struct hci_dev * hdev,int err)27800ce1229cSLuiz Augusto von Dentz  */
27810ce1229cSLuiz Augusto von Dentz static void hci_cancel_cmd_sync(struct hci_dev *hdev, int err)
27820ce1229cSLuiz Augusto von Dentz {
27830ce1229cSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "err 0x%2.2x", err);
27840ce1229cSLuiz Augusto von Dentz 
27850ce1229cSLuiz Augusto von Dentz 	cancel_delayed_work_sync(&hdev->cmd_timer);
27860ce1229cSLuiz Augusto von Dentz 	cancel_delayed_work_sync(&hdev->ncmd_timer);
27870ce1229cSLuiz Augusto von Dentz 	atomic_set(&hdev->cmd_cnt, 1);
27880ce1229cSLuiz Augusto von Dentz 
27899ae3954dSLuiz Augusto von Dentz 	hci_cmd_sync_cancel_sync(hdev, err);
27900ce1229cSLuiz Augusto von Dentz }
27910ce1229cSLuiz Augusto von Dentz 
hci_suspend_dev(struct hci_dev * hdev)27921da177e4SLinus Torvalds /* Suspend HCI device */
27931da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
27941da177e4SLinus Torvalds {
2795e1b77d68SLuiz Augusto von Dentz 	int ret;
2796e1b77d68SLuiz Augusto von Dentz 
2797e1b77d68SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
2798e1b77d68SLuiz Augusto von Dentz 
2799e1b77d68SLuiz Augusto von Dentz 	/* Suspend should only act on when powered. */
2800e1b77d68SLuiz Augusto von Dentz 	if (!hdev_is_powered(hdev) ||
2801e1b77d68SLuiz Augusto von Dentz 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
28021da177e4SLinus Torvalds 		return 0;
2803e1b77d68SLuiz Augusto von Dentz 
2804182ee45dSLuiz Augusto von Dentz 	/* If powering down don't attempt to suspend */
2805182ee45dSLuiz Augusto von Dentz 	if (mgmt_powering_down(hdev))
2806182ee45dSLuiz Augusto von Dentz 		return 0;
2807e1b77d68SLuiz Augusto von Dentz 
2808f4198635SArchie Pusaka 	/* Cancel potentially blocking sync operation before suspend */
28099ae3954dSLuiz Augusto von Dentz 	hci_cancel_cmd_sync(hdev, EHOSTDOWN);
2810f4198635SArchie Pusaka 
2811182ee45dSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
2812182ee45dSLuiz Augusto von Dentz 	ret = hci_suspend_sync(hdev);
2813182ee45dSLuiz Augusto von Dentz 	hci_req_sync_unlock(hdev);
28144539ca67SLuiz Augusto von Dentz 
2815e1b77d68SLuiz Augusto von Dentz 	hci_clear_wake_reason(hdev);
2816182ee45dSLuiz Augusto von Dentz 	mgmt_suspending(hdev, hdev->suspend_state);
2817e1b77d68SLuiz Augusto von Dentz 
2818e1b77d68SLuiz Augusto von Dentz 	hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
2819e1b77d68SLuiz Augusto von Dentz 	return ret;
28201da177e4SLinus Torvalds }
28211da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
28221da177e4SLinus Torvalds 
hci_resume_dev(struct hci_dev * hdev)28231da177e4SLinus Torvalds /* Resume HCI device */
28241da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
28251da177e4SLinus Torvalds {
2826e1b77d68SLuiz Augusto von Dentz 	int ret;
2827e1b77d68SLuiz Augusto von Dentz 
2828e1b77d68SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
2829e1b77d68SLuiz Augusto von Dentz 
2830e1b77d68SLuiz Augusto von Dentz 	/* Resume should only act on when powered. */
2831e1b77d68SLuiz Augusto von Dentz 	if (!hdev_is_powered(hdev) ||
2832e1b77d68SLuiz Augusto von Dentz 	    hci_dev_test_flag(hdev, HCI_UNREGISTER))
28331da177e4SLinus Torvalds 		return 0;
2834e1b77d68SLuiz Augusto von Dentz 
2835e1b77d68SLuiz Augusto von Dentz 	/* If powering down don't attempt to resume */
2836e1b77d68SLuiz Augusto von Dentz 	if (mgmt_powering_down(hdev))
2837e1b77d68SLuiz Augusto von Dentz 		return 0;
2838e1b77d68SLuiz Augusto von Dentz 
2839182ee45dSLuiz Augusto von Dentz 	hci_req_sync_lock(hdev);
2840182ee45dSLuiz Augusto von Dentz 	ret = hci_resume_sync(hdev);
2841182ee45dSLuiz Augusto von Dentz 	hci_req_sync_unlock(hdev);
2842e1b77d68SLuiz Augusto von Dentz 
2843e1b77d68SLuiz Augusto von Dentz 	mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr,
2844e1b77d68SLuiz Augusto von Dentz 		      hdev->wake_addr_type);
2845e1b77d68SLuiz Augusto von Dentz 
2846e1b77d68SLuiz Augusto von Dentz 	hci_sock_dev_event(hdev, HCI_DEV_RESUME);
2847e1b77d68SLuiz Augusto von Dentz 	return ret;
28481da177e4SLinus Torvalds }
28491da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
28501da177e4SLinus Torvalds 
hci_reset_dev(struct hci_dev * hdev)285175e0569fSMarcel Holtmann /* Reset HCI device */
285275e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
285375e0569fSMarcel Holtmann {
28541e4b6e91SColin Ian King 	static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
285575e0569fSMarcel Holtmann 	struct sk_buff *skb;
285675e0569fSMarcel Holtmann 
285775e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
285875e0569fSMarcel Holtmann 	if (!skb)
285975e0569fSMarcel Holtmann 		return -ENOMEM;
286075e0569fSMarcel Holtmann 
2861d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
286259ae1d12SJohannes Berg 	skb_put_data(skb, hw_err, 3);
286375e0569fSMarcel Holtmann 
2864de75cd0dSManish Mandlik 	bt_dev_err(hdev, "Injecting HCI hardware error event");
2865de75cd0dSManish Mandlik 
286675e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
286775e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
286875e0569fSMarcel Holtmann }
286975e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
287075e0569fSMarcel Holtmann 
hci_recv_frame(struct hci_dev * hdev,struct sk_buff * skb)287176bca880SMarcel Holtmann /* Receive frame from HCI drivers */
2872e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
287376bca880SMarcel Holtmann {
287476bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
287576bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
287676bca880SMarcel Holtmann 		kfree_skb(skb);
287776bca880SMarcel Holtmann 		return -ENXIO;
287876bca880SMarcel Holtmann 	}
287976bca880SMarcel Holtmann 
2880876e7810SLuiz Augusto von Dentz 	switch (hci_skb_pkt_type(skb)) {
2881876e7810SLuiz Augusto von Dentz 	case HCI_EVENT_PKT:
2882876e7810SLuiz Augusto von Dentz 		break;
2883876e7810SLuiz Augusto von Dentz 	case HCI_ACLDATA_PKT:
2884876e7810SLuiz Augusto von Dentz 		/* Detect if ISO packet has been sent as ACL */
2885876e7810SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, ISO_LINK)) {
2886876e7810SLuiz Augusto von Dentz 			__u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle);
2887876e7810SLuiz Augusto von Dentz 			__u8 type;
2888876e7810SLuiz Augusto von Dentz 
2889876e7810SLuiz Augusto von Dentz 			type = hci_conn_lookup_type(hdev, hci_handle(handle));
2890876e7810SLuiz Augusto von Dentz 			if (type == ISO_LINK)
2891876e7810SLuiz Augusto von Dentz 				hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
2892876e7810SLuiz Augusto von Dentz 		}
2893876e7810SLuiz Augusto von Dentz 		break;
2894876e7810SLuiz Augusto von Dentz 	case HCI_SCODATA_PKT:
2895876e7810SLuiz Augusto von Dentz 		break;
2896876e7810SLuiz Augusto von Dentz 	case HCI_ISODATA_PKT:
2897876e7810SLuiz Augusto von Dentz 		break;
2898876e7810SLuiz Augusto von Dentz 	default:
2899fe806dceSMarcel Holtmann 		kfree_skb(skb);
2900fe806dceSMarcel Holtmann 		return -EINVAL;
2901fe806dceSMarcel Holtmann 	}
2902fe806dceSMarcel Holtmann 
2903d82603c6SJorrit Schippers 	/* Incoming skb */
290476bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
290576bca880SMarcel Holtmann 
290676bca880SMarcel Holtmann 	/* Time stamp */
290776bca880SMarcel Holtmann 	__net_timestamp(skb);
290876bca880SMarcel Holtmann 
290976bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2910b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2911c78ae283SMarcel Holtmann 
291276bca880SMarcel Holtmann 	return 0;
291376bca880SMarcel Holtmann }
291476bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
291576bca880SMarcel Holtmann 
hci_recv_diag(struct hci_dev * hdev,struct sk_buff * skb)2916e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */
2917e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
2918e875ff84SMarcel Holtmann {
2919581d6fd6SMarcel Holtmann 	/* Mark as diagnostic packet */
2920d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_DIAG_PKT;
2921581d6fd6SMarcel Holtmann 
2922e875ff84SMarcel Holtmann 	/* Time stamp */
2923e875ff84SMarcel Holtmann 	__net_timestamp(skb);
2924e875ff84SMarcel Holtmann 
2925581d6fd6SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2926581d6fd6SMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2927e875ff84SMarcel Holtmann 
2928e875ff84SMarcel Holtmann 	return 0;
2929e875ff84SMarcel Holtmann }
2930e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag);
hci_set_hw_info(struct hci_dev * hdev,const char * fmt,...)2931e875ff84SMarcel Holtmann 
29325177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...)
29335177a838SMarcel Holtmann {
29345177a838SMarcel Holtmann 	va_list vargs;
29355177a838SMarcel Holtmann 
29365177a838SMarcel Holtmann 	va_start(vargs, fmt);
29375177a838SMarcel Holtmann 	kfree_const(hdev->hw_info);
29385177a838SMarcel Holtmann 	hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
29395177a838SMarcel Holtmann 	va_end(vargs);
29405177a838SMarcel Holtmann }
29415177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info);
hci_set_fw_info(struct hci_dev * hdev,const char * fmt,...)29425177a838SMarcel Holtmann 
29435177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...)
29445177a838SMarcel Holtmann {
29455177a838SMarcel Holtmann 	va_list vargs;
29465177a838SMarcel Holtmann 
29475177a838SMarcel Holtmann 	va_start(vargs, fmt);
29485177a838SMarcel Holtmann 	kfree_const(hdev->fw_info);
29495177a838SMarcel Holtmann 	hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
29505177a838SMarcel Holtmann 	va_end(vargs);
29515177a838SMarcel Holtmann }
29525177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info);
29535177a838SMarcel Holtmann 
29541da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
hci_register_cb(struct hci_cb * cb)29551da177e4SLinus Torvalds 
29561da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
29571da177e4SLinus Torvalds {
29581da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
29591da177e4SLinus Torvalds 
2960*5e8ce74fSLuiz Augusto von Dentz 	mutex_lock(&hci_cb_list_lock);
2961*5e8ce74fSLuiz Augusto von Dentz 	list_add_tail(&cb->list, &hci_cb_list);
2962*5e8ce74fSLuiz Augusto von Dentz 	mutex_unlock(&hci_cb_list_lock);
29631da177e4SLinus Torvalds 
29641da177e4SLinus Torvalds 	return 0;
29651da177e4SLinus Torvalds }
29661da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
29671da177e4SLinus Torvalds 
29681da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
29691da177e4SLinus Torvalds {
29701da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
29711da177e4SLinus Torvalds 
2972*5e8ce74fSLuiz Augusto von Dentz 	mutex_lock(&hci_cb_list_lock);
2973*5e8ce74fSLuiz Augusto von Dentz 	list_del(&cb->list);
2974*5e8ce74fSLuiz Augusto von Dentz 	mutex_unlock(&hci_cb_list_lock);
29751da177e4SLinus Torvalds 
hci_send_frame(struct hci_dev * hdev,struct sk_buff * skb)29761da177e4SLinus Torvalds 	return 0;
29771da177e4SLinus Torvalds }
29781da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
29791da177e4SLinus Torvalds 
29802250abadSBenjamin Berg static int hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
29811da177e4SLinus Torvalds {
2982cdc52faaSMarcel Holtmann 	int err;
2983cdc52faaSMarcel Holtmann 
2984d79f34e3SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb),
2985d79f34e3SMarcel Holtmann 	       skb->len);
29861da177e4SLinus Torvalds 
29871da177e4SLinus Torvalds 	/* Time stamp */
2988a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
29891da177e4SLinus Torvalds 
2990cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2991cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2992cd82e61cSMarcel Holtmann 
2993cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2994cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2995470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
29961da177e4SLinus Torvalds 	}
29971da177e4SLinus Torvalds 
29981da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
29991da177e4SLinus Torvalds 	skb_orphan(skb);
30001da177e4SLinus Torvalds 
300173d0d3c8SMarcel Holtmann 	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
300273d0d3c8SMarcel Holtmann 		kfree_skb(skb);
30032250abadSBenjamin Berg 		return -EINVAL;
300473d0d3c8SMarcel Holtmann 	}
300573d0d3c8SMarcel Holtmann 
3006cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
3007cdc52faaSMarcel Holtmann 	if (err < 0) {
30082064ee33SMarcel Holtmann 		bt_dev_err(hdev, "sending frame failed (%d)", err);
3009cdc52faaSMarcel Holtmann 		kfree_skb(skb);
30102250abadSBenjamin Berg 		return err;
3011cdc52faaSMarcel Holtmann 	}
30122250abadSBenjamin Berg 
hci_send_cmd(struct hci_dev * hdev,__u16 opcode,__u32 plen,const void * param)30132250abadSBenjamin Berg 	return 0;
30141da177e4SLinus Torvalds }
30151da177e4SLinus Torvalds 
30161ca3a9d0SJohan Hedberg /* Send HCI command */
301707dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
301807dc93ddSJohan Hedberg 		 const void *param)
30191ca3a9d0SJohan Hedberg {
30201ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
30211ca3a9d0SJohan Hedberg 
30221ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
30231ca3a9d0SJohan Hedberg 
30241ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
30251ca3a9d0SJohan Hedberg 	if (!skb) {
30262064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no memory for command");
30271ca3a9d0SJohan Hedberg 		return -ENOMEM;
30281ca3a9d0SJohan Hedberg 	}
30291ca3a9d0SJohan Hedberg 
303049c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
303111714b3dSJohan Hedberg 	 * single-command requests.
303211714b3dSJohan Hedberg 	 */
303344d27137SJohan Hedberg 	bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
303411714b3dSJohan Hedberg 
30351da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
3036c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
__hci_cmd_send(struct hci_dev * hdev,u16 opcode,u32 plen,const void * param)30371da177e4SLinus Torvalds 
30381da177e4SLinus Torvalds 	return 0;
30391da177e4SLinus Torvalds }
30401da177e4SLinus Torvalds 
3041d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
3042d6ee6ad7SLoic Poulain 		   const void *param)
3043d6ee6ad7SLoic Poulain {
3044d6ee6ad7SLoic Poulain 	struct sk_buff *skb;
3045d6ee6ad7SLoic Poulain 
3046d6ee6ad7SLoic Poulain 	if (hci_opcode_ogf(opcode) != 0x3f) {
3047d6ee6ad7SLoic Poulain 		/* A controller receiving a command shall respond with either
3048d6ee6ad7SLoic Poulain 		 * a Command Status Event or a Command Complete Event.
3049d6ee6ad7SLoic Poulain 		 * Therefore, all standard HCI commands must be sent via the
3050d6ee6ad7SLoic Poulain 		 * standard API, using hci_send_cmd or hci_cmd_sync helpers.
3051d6ee6ad7SLoic Poulain 		 * Some vendors do not comply with this rule for vendor-specific
3052d6ee6ad7SLoic Poulain 		 * commands and do not return any event. We want to support
3053d6ee6ad7SLoic Poulain 		 * unresponded commands for such cases only.
3054d6ee6ad7SLoic Poulain 		 */
3055d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "unresponded command not supported");
3056d6ee6ad7SLoic Poulain 		return -EINVAL;
3057d6ee6ad7SLoic Poulain 	}
3058d6ee6ad7SLoic Poulain 
3059d6ee6ad7SLoic Poulain 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
3060d6ee6ad7SLoic Poulain 	if (!skb) {
3061d6ee6ad7SLoic Poulain 		bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)",
3062d6ee6ad7SLoic Poulain 			   opcode);
3063d6ee6ad7SLoic Poulain 		return -ENOMEM;
3064d6ee6ad7SLoic Poulain 	}
3065d6ee6ad7SLoic Poulain 
3066d6ee6ad7SLoic Poulain 	hci_send_frame(hdev, skb);
3067d6ee6ad7SLoic Poulain 
3068d6ee6ad7SLoic Poulain 	return 0;
hci_cmd_data(struct sk_buff * skb,__u16 opcode)3069d6ee6ad7SLoic Poulain }
3070d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send);
3071d6ee6ad7SLoic Poulain 
30721da177e4SLinus Torvalds /* Get data from the previously sent command */
30732af7aa66SLuiz Augusto von Dentz static void *hci_cmd_data(struct sk_buff *skb, __u16 opcode)
30741da177e4SLinus Torvalds {
30751da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
30761da177e4SLinus Torvalds 
30772af7aa66SLuiz Augusto von Dentz 	if (!skb || skb->len < HCI_COMMAND_HDR_SIZE)
30781da177e4SLinus Torvalds 		return NULL;
30791da177e4SLinus Torvalds 
30802af7aa66SLuiz Augusto von Dentz 	hdr = (void *)skb->data;
30811da177e4SLinus Torvalds 
3082a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
30831da177e4SLinus Torvalds 		return NULL;
30841da177e4SLinus Torvalds 
hci_sent_cmd_data(struct hci_dev * hdev,__u16 opcode)30852af7aa66SLuiz Augusto von Dentz 	return skb->data + HCI_COMMAND_HDR_SIZE;
30862af7aa66SLuiz Augusto von Dentz }
30871da177e4SLinus Torvalds 
30882af7aa66SLuiz Augusto von Dentz /* Get data from the previously sent command */
30892af7aa66SLuiz Augusto von Dentz void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
30902af7aa66SLuiz Augusto von Dentz {
30912af7aa66SLuiz Augusto von Dentz 	void *data;
30922af7aa66SLuiz Augusto von Dentz 
30932af7aa66SLuiz Augusto von Dentz 	/* Check if opcode matches last sent command */
30942af7aa66SLuiz Augusto von Dentz 	data = hci_cmd_data(hdev->sent_cmd, opcode);
30952af7aa66SLuiz Augusto von Dentz 	if (!data)
30962af7aa66SLuiz Augusto von Dentz 		/* Check if opcode matches last request */
30972af7aa66SLuiz Augusto von Dentz 		data = hci_cmd_data(hdev->req_skb, opcode);
30982af7aa66SLuiz Augusto von Dentz 
hci_recv_event_data(struct hci_dev * hdev,__u8 event)30992af7aa66SLuiz Augusto von Dentz 	return data;
31001da177e4SLinus Torvalds }
31011da177e4SLinus Torvalds 
3102dfe6d5c3SLuiz Augusto von Dentz /* Get data from last received event */
3103dfe6d5c3SLuiz Augusto von Dentz void *hci_recv_event_data(struct hci_dev *hdev, __u8 event)
3104dfe6d5c3SLuiz Augusto von Dentz {
3105dfe6d5c3SLuiz Augusto von Dentz 	struct hci_event_hdr *hdr;
3106dfe6d5c3SLuiz Augusto von Dentz 	int offset;
3107dfe6d5c3SLuiz Augusto von Dentz 
3108dfe6d5c3SLuiz Augusto von Dentz 	if (!hdev->recv_event)
3109dfe6d5c3SLuiz Augusto von Dentz 		return NULL;
3110dfe6d5c3SLuiz Augusto von Dentz 
3111dfe6d5c3SLuiz Augusto von Dentz 	hdr = (void *)hdev->recv_event->data;
3112dfe6d5c3SLuiz Augusto von Dentz 	offset = sizeof(*hdr);
3113dfe6d5c3SLuiz Augusto von Dentz 
3114dfe6d5c3SLuiz Augusto von Dentz 	if (hdr->evt != event) {
3115dfe6d5c3SLuiz Augusto von Dentz 		/* In case of LE metaevent check the subevent match */
3116dfe6d5c3SLuiz Augusto von Dentz 		if (hdr->evt == HCI_EV_LE_META) {
3117dfe6d5c3SLuiz Augusto von Dentz 			struct hci_ev_le_meta *ev;
3118dfe6d5c3SLuiz Augusto von Dentz 
3119dfe6d5c3SLuiz Augusto von Dentz 			ev = (void *)hdev->recv_event->data + offset;
3120dfe6d5c3SLuiz Augusto von Dentz 			offset += sizeof(*ev);
3121dfe6d5c3SLuiz Augusto von Dentz 			if (ev->subevent == event)
3122dfe6d5c3SLuiz Augusto von Dentz 				goto found;
3123dfe6d5c3SLuiz Augusto von Dentz 		}
3124dfe6d5c3SLuiz Augusto von Dentz 		return NULL;
3125dfe6d5c3SLuiz Augusto von Dentz 	}
3126dfe6d5c3SLuiz Augusto von Dentz 
3127dfe6d5c3SLuiz Augusto von Dentz found:
3128dfe6d5c3SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "event 0x%2.2x", event);
3129dfe6d5c3SLuiz Augusto von Dentz 
hci_add_acl_hdr(struct sk_buff * skb,__u16 handle,__u16 flags)3130dfe6d5c3SLuiz Augusto von Dentz 	return hdev->recv_event->data + offset;
3131dfe6d5c3SLuiz Augusto von Dentz }
3132dfe6d5c3SLuiz Augusto von Dentz 
31331da177e4SLinus Torvalds /* Send ACL data */
31341da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
31351da177e4SLinus Torvalds {
31361da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
31371da177e4SLinus Torvalds 	int len = skb->len;
31381da177e4SLinus Torvalds 
3139badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3140badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
31419c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
hci_queue_acl(struct hci_chan * chan,struct sk_buff_head * queue,struct sk_buff * skb,__u16 flags)3142aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3143aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
31441da177e4SLinus Torvalds }
31451da177e4SLinus Torvalds 
3146ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
314773d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
31481da177e4SLinus Torvalds {
3149ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
31501da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
31511da177e4SLinus Torvalds 	struct sk_buff *list;
31521da177e4SLinus Torvalds 
3153087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3154087bfd99SGustavo Padovan 	skb->data_len = 0;
3155087bfd99SGustavo Padovan 
3156d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3157204a6e54SAndrei Emeltchenko 
3158087bfd99SGustavo Padovan 	hci_add_acl_hdr(skb, conn->handle, flags);
3159087bfd99SGustavo Padovan 
316070f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
316170f23020SAndrei Emeltchenko 	if (!list) {
31621da177e4SLinus Torvalds 		/* Non fragmented */
31631da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
31641da177e4SLinus Torvalds 
316573d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
31661da177e4SLinus Torvalds 	} else {
31671da177e4SLinus Torvalds 		/* Fragmented */
31681da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
31691da177e4SLinus Torvalds 
31701da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
31711da177e4SLinus Torvalds 
31729cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
31739cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
31749cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
31759cfd5a23SJukka Rissanen 		 * deadlocks.
31769cfd5a23SJukka Rissanen 		 */
31779cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
31781da177e4SLinus Torvalds 
317973d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3180e702112fSAndrei Emeltchenko 
3181e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3182e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
31831da177e4SLinus Torvalds 		do {
31841da177e4SLinus Torvalds 			skb = list; list = list->next;
31851da177e4SLinus Torvalds 
3186d79f34e3SMarcel Holtmann 			hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3187e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
31881da177e4SLinus Torvalds 
31891da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
31901da177e4SLinus Torvalds 
319173d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
31921da177e4SLinus Torvalds 		} while (list);
31931da177e4SLinus Torvalds 
hci_send_acl(struct hci_chan * chan,struct sk_buff * skb,__u16 flags)31949cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
31951da177e4SLinus Torvalds 	}
319673d80debSLuiz Augusto von Dentz }
319773d80debSLuiz Augusto von Dentz 
319873d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
319973d80debSLuiz Augusto von Dentz {
3200ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
320173d80debSLuiz Augusto von Dentz 
3202f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
320373d80debSLuiz Augusto von Dentz 
3204ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
32051da177e4SLinus Torvalds 
hci_send_sco(struct hci_conn * conn,struct sk_buff * skb)32063eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
32071da177e4SLinus Torvalds }
32081da177e4SLinus Torvalds 
32091da177e4SLinus Torvalds /* Send SCO data */
32100d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
32111da177e4SLinus Torvalds {
32121da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
32131da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
32141da177e4SLinus Torvalds 
32151da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
32161da177e4SLinus Torvalds 
3217aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
32181da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
32191da177e4SLinus Torvalds 
3220badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3221badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
32229c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
32231da177e4SLinus Torvalds 
3224d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
3225c78ae283SMarcel Holtmann 
32261da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
hci_add_iso_hdr(struct sk_buff * skb,__u16 handle,__u8 flags)32273eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
32281da177e4SLinus Torvalds }
32291da177e4SLinus Torvalds 
323026afbd82SLuiz Augusto von Dentz /* Send ISO data */
323126afbd82SLuiz Augusto von Dentz static void hci_add_iso_hdr(struct sk_buff *skb, __u16 handle, __u8 flags)
323226afbd82SLuiz Augusto von Dentz {
323326afbd82SLuiz Augusto von Dentz 	struct hci_iso_hdr *hdr;
323426afbd82SLuiz Augusto von Dentz 	int len = skb->len;
323526afbd82SLuiz Augusto von Dentz 
323626afbd82SLuiz Augusto von Dentz 	skb_push(skb, HCI_ISO_HDR_SIZE);
323726afbd82SLuiz Augusto von Dentz 	skb_reset_transport_header(skb);
323826afbd82SLuiz Augusto von Dentz 	hdr = (struct hci_iso_hdr *)skb_transport_header(skb);
hci_queue_iso(struct hci_conn * conn,struct sk_buff_head * queue,struct sk_buff * skb)323926afbd82SLuiz Augusto von Dentz 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
324026afbd82SLuiz Augusto von Dentz 	hdr->dlen   = cpu_to_le16(len);
324126afbd82SLuiz Augusto von Dentz }
324226afbd82SLuiz Augusto von Dentz 
324326afbd82SLuiz Augusto von Dentz static void hci_queue_iso(struct hci_conn *conn, struct sk_buff_head *queue,
324426afbd82SLuiz Augusto von Dentz 			  struct sk_buff *skb)
324526afbd82SLuiz Augusto von Dentz {
324626afbd82SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
324726afbd82SLuiz Augusto von Dentz 	struct sk_buff *list;
324826afbd82SLuiz Augusto von Dentz 	__u16 flags;
324926afbd82SLuiz Augusto von Dentz 
325026afbd82SLuiz Augusto von Dentz 	skb->len = skb_headlen(skb);
325126afbd82SLuiz Augusto von Dentz 	skb->data_len = 0;
325226afbd82SLuiz Augusto von Dentz 
325326afbd82SLuiz Augusto von Dentz 	hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
325426afbd82SLuiz Augusto von Dentz 
325526afbd82SLuiz Augusto von Dentz 	list = skb_shinfo(skb)->frag_list;
325626afbd82SLuiz Augusto von Dentz 
325726afbd82SLuiz Augusto von Dentz 	flags = hci_iso_flags_pack(list ? ISO_START : ISO_SINGLE, 0x00);
325826afbd82SLuiz Augusto von Dentz 	hci_add_iso_hdr(skb, conn->handle, flags);
325926afbd82SLuiz Augusto von Dentz 
326026afbd82SLuiz Augusto von Dentz 	if (!list) {
326126afbd82SLuiz Augusto von Dentz 		/* Non fragmented */
326226afbd82SLuiz Augusto von Dentz 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
326326afbd82SLuiz Augusto von Dentz 
326426afbd82SLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
326526afbd82SLuiz Augusto von Dentz 	} else {
326626afbd82SLuiz Augusto von Dentz 		/* Fragmented */
326726afbd82SLuiz Augusto von Dentz 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
326826afbd82SLuiz Augusto von Dentz 
326926afbd82SLuiz Augusto von Dentz 		skb_shinfo(skb)->frag_list = NULL;
327026afbd82SLuiz Augusto von Dentz 
327126afbd82SLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
327226afbd82SLuiz Augusto von Dentz 
327326afbd82SLuiz Augusto von Dentz 		do {
327426afbd82SLuiz Augusto von Dentz 			skb = list; list = list->next;
327526afbd82SLuiz Augusto von Dentz 
327626afbd82SLuiz Augusto von Dentz 			hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
327726afbd82SLuiz Augusto von Dentz 			flags = hci_iso_flags_pack(list ? ISO_CONT : ISO_END,
327826afbd82SLuiz Augusto von Dentz 						   0x00);
327926afbd82SLuiz Augusto von Dentz 			hci_add_iso_hdr(skb, conn->handle, flags);
328026afbd82SLuiz Augusto von Dentz 
328126afbd82SLuiz Augusto von Dentz 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
328226afbd82SLuiz Augusto von Dentz 
328326afbd82SLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
hci_send_iso(struct hci_conn * conn,struct sk_buff * skb)328426afbd82SLuiz Augusto von Dentz 		} while (list);
328526afbd82SLuiz Augusto von Dentz 	}
328626afbd82SLuiz Augusto von Dentz }
328726afbd82SLuiz Augusto von Dentz 
328826afbd82SLuiz Augusto von Dentz void hci_send_iso(struct hci_conn *conn, struct sk_buff *skb)
328926afbd82SLuiz Augusto von Dentz {
329026afbd82SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
329126afbd82SLuiz Augusto von Dentz 
329226afbd82SLuiz Augusto von Dentz 	BT_DBG("%s len %d", hdev->name, skb->len);
329326afbd82SLuiz Augusto von Dentz 
329426afbd82SLuiz Augusto von Dentz 	hci_queue_iso(conn, &conn->data_q, skb);
329526afbd82SLuiz Augusto von Dentz 
329626afbd82SLuiz Augusto von Dentz 	queue_work(hdev->workqueue, &hdev->tx_work);
329726afbd82SLuiz Augusto von Dentz }
hci_quote_sent(struct hci_conn * conn,int num,int * quote)329826afbd82SLuiz Augusto von Dentz 
32991da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
33001da177e4SLinus Torvalds 
33011da177e4SLinus Torvalds /* HCI Connection scheduler */
330226afbd82SLuiz Augusto von Dentz static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote)
330326afbd82SLuiz Augusto von Dentz {
330426afbd82SLuiz Augusto von Dentz 	struct hci_dev *hdev;
330526afbd82SLuiz Augusto von Dentz 	int cnt, q;
330626afbd82SLuiz Augusto von Dentz 
330726afbd82SLuiz Augusto von Dentz 	if (!conn) {
330826afbd82SLuiz Augusto von Dentz 		*quote = 0;
330926afbd82SLuiz Augusto von Dentz 		return;
331026afbd82SLuiz Augusto von Dentz 	}
331126afbd82SLuiz Augusto von Dentz 
331226afbd82SLuiz Augusto von Dentz 	hdev = conn->hdev;
331326afbd82SLuiz Augusto von Dentz 
331426afbd82SLuiz Augusto von Dentz 	switch (conn->type) {
331526afbd82SLuiz Augusto von Dentz 	case ACL_LINK:
331626afbd82SLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
331726afbd82SLuiz Augusto von Dentz 		break;
331826afbd82SLuiz Augusto von Dentz 	case SCO_LINK:
331926afbd82SLuiz Augusto von Dentz 	case ESCO_LINK:
332026afbd82SLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
332126afbd82SLuiz Augusto von Dentz 		break;
332226afbd82SLuiz Augusto von Dentz 	case LE_LINK:
332326afbd82SLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
332426afbd82SLuiz Augusto von Dentz 		break;
332526afbd82SLuiz Augusto von Dentz 	case ISO_LINK:
332626afbd82SLuiz Augusto von Dentz 		cnt = hdev->iso_mtu ? hdev->iso_cnt :
332726afbd82SLuiz Augusto von Dentz 			hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
332826afbd82SLuiz Augusto von Dentz 		break;
332926afbd82SLuiz Augusto von Dentz 	default:
333026afbd82SLuiz Augusto von Dentz 		cnt = 0;
333126afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev, "unknown link type %d", conn->type);
333226afbd82SLuiz Augusto von Dentz 	}
333326afbd82SLuiz Augusto von Dentz 
333426afbd82SLuiz Augusto von Dentz 	q = cnt / num;
333526afbd82SLuiz Augusto von Dentz 	*quote = q ? q : 1;
333626afbd82SLuiz Augusto von Dentz }
333726afbd82SLuiz Augusto von Dentz 
33386039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3339a8c5fb1aSGustavo Padovan 				     int *quote)
33401da177e4SLinus Torvalds {
33411da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
33428035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
3343abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
33441da177e4SLinus Torvalds 
33451da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
33461da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
3347bf4c6325SGustavo F. Padovan 
3348bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3349bf4c6325SGustavo F. Padovan 
3350bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3351769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
33521da177e4SLinus Torvalds 			continue;
3353769be974SMarcel Holtmann 
3354769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3355769be974SMarcel Holtmann 			continue;
3356769be974SMarcel Holtmann 
33571da177e4SLinus Torvalds 		num++;
33581da177e4SLinus Torvalds 
33591da177e4SLinus Torvalds 		if (c->sent < min) {
33601da177e4SLinus Torvalds 			min  = c->sent;
33611da177e4SLinus Torvalds 			conn = c;
33621da177e4SLinus Torvalds 		}
336352087a79SLuiz Augusto von Dentz 
336452087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
336552087a79SLuiz Augusto von Dentz 			break;
33661da177e4SLinus Torvalds 	}
33671da177e4SLinus Torvalds 
3368bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3369bf4c6325SGustavo F. Padovan 
337026afbd82SLuiz Augusto von Dentz 	hci_quote_sent(conn, num, quote);
33711da177e4SLinus Torvalds 
hci_link_tx_to(struct hci_dev * hdev,__u8 type)33721da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
33731da177e4SLinus Torvalds 	return conn;
33741da177e4SLinus Torvalds }
33751da177e4SLinus Torvalds 
33766039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
33771da177e4SLinus Torvalds {
33781da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
33791da177e4SLinus Torvalds 	struct hci_conn *c;
33801da177e4SLinus Torvalds 
33812064ee33SMarcel Holtmann 	bt_dev_err(hdev, "link tx timeout");
33821da177e4SLinus Torvalds 
3383bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3384bf4c6325SGustavo F. Padovan 
33851da177e4SLinus Torvalds 	/* Kill stalled connections */
3386bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3387bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
33882064ee33SMarcel Holtmann 			bt_dev_err(hdev, "killing stalled connection %pMR",
33892064ee33SMarcel Holtmann 				   &c->dst);
3390c7eaf80bSYing Hsu 			/* hci_disconnect might sleep, so, we have to release
3391c7eaf80bSYing Hsu 			 * the RCU read lock before calling it.
3392c7eaf80bSYing Hsu 			 */
3393c7eaf80bSYing Hsu 			rcu_read_unlock();
3394bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
3395c7eaf80bSYing Hsu 			rcu_read_lock();
33961da177e4SLinus Torvalds 		}
33971da177e4SLinus Torvalds 	}
hci_chan_sent(struct hci_dev * hdev,__u8 type,int * quote)3398bf4c6325SGustavo F. Padovan 
3399bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
34001da177e4SLinus Torvalds }
34011da177e4SLinus Torvalds 
34026039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
340373d80debSLuiz Augusto von Dentz 				      int *quote)
340473d80debSLuiz Augusto von Dentz {
340573d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
340673d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3407abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
340873d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
340926afbd82SLuiz Augusto von Dentz 	int conn_num = 0;
341073d80debSLuiz Augusto von Dentz 
341173d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
341273d80debSLuiz Augusto von Dentz 
3413bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3414bf4c6325SGustavo F. Padovan 
3415bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
341673d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
341773d80debSLuiz Augusto von Dentz 
341873d80debSLuiz Augusto von Dentz 		if (conn->type != type)
341973d80debSLuiz Augusto von Dentz 			continue;
342073d80debSLuiz Augusto von Dentz 
342173d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
342273d80debSLuiz Augusto von Dentz 			continue;
342373d80debSLuiz Augusto von Dentz 
342473d80debSLuiz Augusto von Dentz 		conn_num++;
342573d80debSLuiz Augusto von Dentz 
34268192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
342773d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
342873d80debSLuiz Augusto von Dentz 
342973d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
343073d80debSLuiz Augusto von Dentz 				continue;
343173d80debSLuiz Augusto von Dentz 
343273d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
343373d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
343473d80debSLuiz Augusto von Dentz 				continue;
343573d80debSLuiz Augusto von Dentz 
343673d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
343773d80debSLuiz Augusto von Dentz 				num = 0;
343873d80debSLuiz Augusto von Dentz 				min = ~0;
343973d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
344073d80debSLuiz Augusto von Dentz 			}
344173d80debSLuiz Augusto von Dentz 
344273d80debSLuiz Augusto von Dentz 			num++;
344373d80debSLuiz Augusto von Dentz 
344473d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
344573d80debSLuiz Augusto von Dentz 				min  = conn->sent;
344673d80debSLuiz Augusto von Dentz 				chan = tmp;
344773d80debSLuiz Augusto von Dentz 			}
344873d80debSLuiz Augusto von Dentz 		}
344973d80debSLuiz Augusto von Dentz 
345073d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
345173d80debSLuiz Augusto von Dentz 			break;
345273d80debSLuiz Augusto von Dentz 	}
345373d80debSLuiz Augusto von Dentz 
3454bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3455bf4c6325SGustavo F. Padovan 
345673d80debSLuiz Augusto von Dentz 	if (!chan)
345773d80debSLuiz Augusto von Dentz 		return NULL;
345873d80debSLuiz Augusto von Dentz 
345926afbd82SLuiz Augusto von Dentz 	hci_quote_sent(chan->conn, num, quote);
346073d80debSLuiz Augusto von Dentz 
hci_prio_recalculate(struct hci_dev * hdev,__u8 type)346173d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
346273d80debSLuiz Augusto von Dentz 	return chan;
346373d80debSLuiz Augusto von Dentz }
346473d80debSLuiz Augusto von Dentz 
346502b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
346602b20f0bSLuiz Augusto von Dentz {
346702b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
346802b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
346902b20f0bSLuiz Augusto von Dentz 	int num = 0;
347002b20f0bSLuiz Augusto von Dentz 
347102b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
347202b20f0bSLuiz Augusto von Dentz 
3473bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3474bf4c6325SGustavo F. Padovan 
3475bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
347602b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
347702b20f0bSLuiz Augusto von Dentz 
347802b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
347902b20f0bSLuiz Augusto von Dentz 			continue;
348002b20f0bSLuiz Augusto von Dentz 
348102b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
348202b20f0bSLuiz Augusto von Dentz 			continue;
348302b20f0bSLuiz Augusto von Dentz 
348402b20f0bSLuiz Augusto von Dentz 		num++;
348502b20f0bSLuiz Augusto von Dentz 
34868192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
348702b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
348802b20f0bSLuiz Augusto von Dentz 
348902b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
349002b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
349102b20f0bSLuiz Augusto von Dentz 				continue;
349202b20f0bSLuiz Augusto von Dentz 			}
349302b20f0bSLuiz Augusto von Dentz 
349402b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
349502b20f0bSLuiz Augusto von Dentz 				continue;
349602b20f0bSLuiz Augusto von Dentz 
349702b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
349802b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
349902b20f0bSLuiz Augusto von Dentz 				continue;
350002b20f0bSLuiz Augusto von Dentz 
350102b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
350202b20f0bSLuiz Augusto von Dentz 
350302b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
350402b20f0bSLuiz Augusto von Dentz 			       skb->priority);
350502b20f0bSLuiz Augusto von Dentz 		}
350602b20f0bSLuiz Augusto von Dentz 
350702b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
350802b20f0bSLuiz Augusto von Dentz 			break;
350902b20f0bSLuiz Augusto von Dentz 	}
3510bf4c6325SGustavo F. Padovan 
__check_timeout(struct hci_dev * hdev,unsigned int cnt,u8 type)3511bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3512bf4c6325SGustavo F. Padovan 
351302b20f0bSLuiz Augusto von Dentz }
351402b20f0bSLuiz Augusto von Dentz 
3515116523c8SLuiz Augusto von Dentz static void __check_timeout(struct hci_dev *hdev, unsigned int cnt, u8 type)
35161da177e4SLinus Torvalds {
3517116523c8SLuiz Augusto von Dentz 	unsigned long last_tx;
3518116523c8SLuiz Augusto von Dentz 
3519116523c8SLuiz Augusto von Dentz 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
3520116523c8SLuiz Augusto von Dentz 		return;
3521116523c8SLuiz Augusto von Dentz 
3522116523c8SLuiz Augusto von Dentz 	switch (type) {
3523116523c8SLuiz Augusto von Dentz 	case LE_LINK:
3524116523c8SLuiz Augusto von Dentz 		last_tx = hdev->le_last_tx;
3525116523c8SLuiz Augusto von Dentz 		break;
3526116523c8SLuiz Augusto von Dentz 	default:
3527116523c8SLuiz Augusto von Dentz 		last_tx = hdev->acl_last_tx;
3528116523c8SLuiz Augusto von Dentz 		break;
35291da177e4SLinus Torvalds 	}
3530116523c8SLuiz Augusto von Dentz 
3531116523c8SLuiz Augusto von Dentz 	/* tx timeout must be longer than maximum link supervision timeout
3532116523c8SLuiz Augusto von Dentz 	 * (40.9 seconds)
3533116523c8SLuiz Augusto von Dentz 	 */
3534116523c8SLuiz Augusto von Dentz 	if (!cnt && time_after(jiffies, last_tx + HCI_ACL_TX_TIMEOUT))
hci_sched_sco(struct hci_dev * hdev)3535116523c8SLuiz Augusto von Dentz 		hci_link_tx_to(hdev, type);
353663d2bc1bSAndrei Emeltchenko }
35371da177e4SLinus Torvalds 
35387fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */
35397fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev)
35407fedd3bbSAbhishek Pandit-Subedi {
35417fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
35427fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
35437fedd3bbSAbhishek Pandit-Subedi 	int quote;
35447fedd3bbSAbhishek Pandit-Subedi 
35457fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
35467fedd3bbSAbhishek Pandit-Subedi 
35477fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, SCO_LINK))
35487fedd3bbSAbhishek Pandit-Subedi 		return;
35497fedd3bbSAbhishek Pandit-Subedi 
35507fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
35517fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
35527fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
35537fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
35547fedd3bbSAbhishek Pandit-Subedi 
35557fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
35567fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
35577fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
hci_sched_esco(struct hci_dev * hdev)35587fedd3bbSAbhishek Pandit-Subedi 		}
35597fedd3bbSAbhishek Pandit-Subedi 	}
35607fedd3bbSAbhishek Pandit-Subedi }
35617fedd3bbSAbhishek Pandit-Subedi 
35627fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev)
35637fedd3bbSAbhishek Pandit-Subedi {
35647fedd3bbSAbhishek Pandit-Subedi 	struct hci_conn *conn;
35657fedd3bbSAbhishek Pandit-Subedi 	struct sk_buff *skb;
35667fedd3bbSAbhishek Pandit-Subedi 	int quote;
35677fedd3bbSAbhishek Pandit-Subedi 
35687fedd3bbSAbhishek Pandit-Subedi 	BT_DBG("%s", hdev->name);
35697fedd3bbSAbhishek Pandit-Subedi 
35707fedd3bbSAbhishek Pandit-Subedi 	if (!hci_conn_num(hdev, ESCO_LINK))
35717fedd3bbSAbhishek Pandit-Subedi 		return;
35727fedd3bbSAbhishek Pandit-Subedi 
35737fedd3bbSAbhishek Pandit-Subedi 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
35747fedd3bbSAbhishek Pandit-Subedi 						     &quote))) {
35757fedd3bbSAbhishek Pandit-Subedi 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
35767fedd3bbSAbhishek Pandit-Subedi 			BT_DBG("skb %p len %d", skb, skb->len);
35777fedd3bbSAbhishek Pandit-Subedi 			hci_send_frame(hdev, skb);
35787fedd3bbSAbhishek Pandit-Subedi 
35797fedd3bbSAbhishek Pandit-Subedi 			conn->sent++;
35807fedd3bbSAbhishek Pandit-Subedi 			if (conn->sent == ~0)
35817fedd3bbSAbhishek Pandit-Subedi 				conn->sent = 0;
35827fedd3bbSAbhishek Pandit-Subedi 		}
35837fedd3bbSAbhishek Pandit-Subedi 	}
35847fedd3bbSAbhishek Pandit-Subedi }
35857fedd3bbSAbhishek Pandit-Subedi 
35866039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
358763d2bc1bSAndrei Emeltchenko {
358863d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
358963d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
359063d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
359163d2bc1bSAndrei Emeltchenko 	int quote;
359263d2bc1bSAndrei Emeltchenko 
3593116523c8SLuiz Augusto von Dentz 	__check_timeout(hdev, cnt, ACL_LINK);
359404837f64SMarcel Holtmann 
359573d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
359673d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3597ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3598ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
359973d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
360073d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
360173d80debSLuiz Augusto von Dentz 
3602ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3603ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3604ec1cce24SLuiz Augusto von Dentz 				break;
3605ec1cce24SLuiz Augusto von Dentz 
3606ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3607ec1cce24SLuiz Augusto von Dentz 
360873d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
360973d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
361004837f64SMarcel Holtmann 
361157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
36121da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
36131da177e4SLinus Torvalds 
36141da177e4SLinus Torvalds 			hdev->acl_cnt--;
361573d80debSLuiz Augusto von Dentz 			chan->sent++;
361673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
36177fedd3bbSAbhishek Pandit-Subedi 
36187fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
36197fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
36207fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
36211da177e4SLinus Torvalds 		}
36221da177e4SLinus Torvalds 	}
362302b20f0bSLuiz Augusto von Dentz 
hci_sched_acl(struct hci_dev * hdev)362402b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
362502b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
36261da177e4SLinus Torvalds }
36271da177e4SLinus Torvalds 
36286039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3629b71d385aSAndrei Emeltchenko {
3630b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3631b71d385aSAndrei Emeltchenko 
3632bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
36335af2e235SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ACL_LINK))
3634bd1eb66bSAndrei Emeltchenko 		return;
hci_sched_le(struct hci_dev * hdev)3635bd1eb66bSAndrei Emeltchenko 
3636b71d385aSAndrei Emeltchenko 	hci_sched_acl_pkt(hdev);
3637b71d385aSAndrei Emeltchenko }
3638b71d385aSAndrei Emeltchenko 
36396039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
36406ed58ec5SVille Tervo {
364173d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
36426ed58ec5SVille Tervo 	struct sk_buff *skb;
364350ce4911SLuiz Augusto von Dentz 	int quote, *cnt, tmp;
36446ed58ec5SVille Tervo 
36456ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
36466ed58ec5SVille Tervo 
364752087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
364852087a79SLuiz Augusto von Dentz 		return;
364952087a79SLuiz Augusto von Dentz 
365050ce4911SLuiz Augusto von Dentz 	cnt = hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt;
36511b1d29e5SLuiz Augusto von Dentz 
365250ce4911SLuiz Augusto von Dentz 	__check_timeout(hdev, *cnt, LE_LINK);
36531b1d29e5SLuiz Augusto von Dentz 
365450ce4911SLuiz Augusto von Dentz 	tmp = *cnt;
365550ce4911SLuiz Augusto von Dentz 	while (*cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3656ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3657ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
365873d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
365973d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
36606ed58ec5SVille Tervo 
3661ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3662ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3663ec1cce24SLuiz Augusto von Dentz 				break;
3664ec1cce24SLuiz Augusto von Dentz 
3665ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3666ec1cce24SLuiz Augusto von Dentz 
366757d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
36686ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
36696ed58ec5SVille Tervo 
367050ce4911SLuiz Augusto von Dentz 			(*cnt)--;
367173d80debSLuiz Augusto von Dentz 			chan->sent++;
367273d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
36737fedd3bbSAbhishek Pandit-Subedi 
36747fedd3bbSAbhishek Pandit-Subedi 			/* Send pending SCO packets right away */
36757fedd3bbSAbhishek Pandit-Subedi 			hci_sched_sco(hdev);
36767fedd3bbSAbhishek Pandit-Subedi 			hci_sched_esco(hdev);
36776ed58ec5SVille Tervo 		}
36786ed58ec5SVille Tervo 	}
367973d80debSLuiz Augusto von Dentz 
368050ce4911SLuiz Augusto von Dentz 	if (*cnt != tmp)
hci_sched_iso(struct hci_dev * hdev)368102b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
36826ed58ec5SVille Tervo }
36836ed58ec5SVille Tervo 
368426afbd82SLuiz Augusto von Dentz /* Schedule CIS */
368526afbd82SLuiz Augusto von Dentz static void hci_sched_iso(struct hci_dev *hdev)
368626afbd82SLuiz Augusto von Dentz {
368726afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
368826afbd82SLuiz Augusto von Dentz 	struct sk_buff *skb;
368926afbd82SLuiz Augusto von Dentz 	int quote, *cnt;
369026afbd82SLuiz Augusto von Dentz 
369126afbd82SLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
369226afbd82SLuiz Augusto von Dentz 
369326afbd82SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ISO_LINK))
369426afbd82SLuiz Augusto von Dentz 		return;
369526afbd82SLuiz Augusto von Dentz 
369626afbd82SLuiz Augusto von Dentz 	cnt = hdev->iso_pkts ? &hdev->iso_cnt :
369726afbd82SLuiz Augusto von Dentz 		hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt;
369826afbd82SLuiz Augusto von Dentz 	while (*cnt && (conn = hci_low_sent(hdev, ISO_LINK, &quote))) {
369926afbd82SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
370026afbd82SLuiz Augusto von Dentz 			BT_DBG("skb %p len %d", skb, skb->len);
370126afbd82SLuiz Augusto von Dentz 			hci_send_frame(hdev, skb);
370226afbd82SLuiz Augusto von Dentz 
370326afbd82SLuiz Augusto von Dentz 			conn->sent++;
370426afbd82SLuiz Augusto von Dentz 			if (conn->sent == ~0)
370526afbd82SLuiz Augusto von Dentz 				conn->sent = 0;
370626afbd82SLuiz Augusto von Dentz 			(*cnt)--;
hci_tx_work(struct work_struct * work)370726afbd82SLuiz Augusto von Dentz 		}
370826afbd82SLuiz Augusto von Dentz 	}
370926afbd82SLuiz Augusto von Dentz }
371026afbd82SLuiz Augusto von Dentz 
37113eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
37121da177e4SLinus Torvalds {
37133eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
37141da177e4SLinus Torvalds 	struct sk_buff *skb;
37151da177e4SLinus Torvalds 
371626afbd82SLuiz Augusto von Dentz 	BT_DBG("%s acl %d sco %d le %d iso %d", hdev->name, hdev->acl_cnt,
371726afbd82SLuiz Augusto von Dentz 	       hdev->sco_cnt, hdev->le_cnt, hdev->iso_cnt);
37181da177e4SLinus Torvalds 
3719d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
37201da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
37211da177e4SLinus Torvalds 		hci_sched_sco(hdev);
3722b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
372326afbd82SLuiz Augusto von Dentz 		hci_sched_iso(hdev);
37247fedd3bbSAbhishek Pandit-Subedi 		hci_sched_acl(hdev);
37256ed58ec5SVille Tervo 		hci_sched_le(hdev);
372652de599eSMarcel Holtmann 	}
37276ed58ec5SVille Tervo 
37281da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
37291da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
373057d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
37311da177e4SLinus Torvalds }
hci_acldata_packet(struct hci_dev * hdev,struct sk_buff * skb)37321da177e4SLinus Torvalds 
373325985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
37341da177e4SLinus Torvalds 
37351da177e4SLinus Torvalds /* ACL data packet */
37366039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
37371da177e4SLinus Torvalds {
37385e50d12cSLuiz Augusto von Dentz 	struct hci_acl_hdr *hdr;
37391da177e4SLinus Torvalds 	struct hci_conn *conn;
37401da177e4SLinus Torvalds 	__u16 handle, flags;
37411da177e4SLinus Torvalds 
37425e50d12cSLuiz Augusto von Dentz 	hdr = skb_pull_data(skb, sizeof(*hdr));
37435e50d12cSLuiz Augusto von Dentz 	if (!hdr) {
37445e50d12cSLuiz Augusto von Dentz 		bt_dev_err(hdev, "ACL packet too small");
37455e50d12cSLuiz Augusto von Dentz 		goto drop;
37465e50d12cSLuiz Augusto von Dentz 	}
37471da177e4SLinus Torvalds 
37481da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
37491da177e4SLinus Torvalds 	flags  = hci_flags(handle);
37501da177e4SLinus Torvalds 	handle = hci_handle(handle);
37511da177e4SLinus Torvalds 
37525e50d12cSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "len %d handle 0x%4.4x flags 0x%4.4x", skb->len,
3753a8c5fb1aSGustavo Padovan 		   handle, flags);
37541da177e4SLinus Torvalds 
37551da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
37561da177e4SLinus Torvalds 
37571da177e4SLinus Torvalds 	hci_dev_lock(hdev);
37581da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
37591da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
37601da177e4SLinus Torvalds 
37611da177e4SLinus Torvalds 	if (conn) {
376265983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
376304837f64SMarcel Holtmann 
37641da177e4SLinus Torvalds 		/* Send to upper protocol */
3765686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
37661da177e4SLinus Torvalds 		return;
37671da177e4SLinus Torvalds 	} else {
37682064ee33SMarcel Holtmann 		bt_dev_err(hdev, "ACL packet for unknown connection handle %d",
37692064ee33SMarcel Holtmann 			   handle);
37701da177e4SLinus Torvalds 	}
37711da177e4SLinus Torvalds 
37725e50d12cSLuiz Augusto von Dentz drop:
37731da177e4SLinus Torvalds 	kfree_skb(skb);
37741da177e4SLinus Torvalds }
37751da177e4SLinus Torvalds 
37761da177e4SLinus Torvalds /* SCO data packet */
37776039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
37781da177e4SLinus Torvalds {
37791da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
37801da177e4SLinus Torvalds 	struct hci_conn *conn;
3781debdedf2SMarcel Holtmann 	__u16 handle, flags;
37821da177e4SLinus Torvalds 
37831da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
37841da177e4SLinus Torvalds 
37851da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
3786debdedf2SMarcel Holtmann 	flags  = hci_flags(handle);
3787debdedf2SMarcel Holtmann 	handle = hci_handle(handle);
37881da177e4SLinus Torvalds 
3789debdedf2SMarcel Holtmann 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3790debdedf2SMarcel Holtmann 	       handle, flags);
37911da177e4SLinus Torvalds 
37921da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
37931da177e4SLinus Torvalds 
37941da177e4SLinus Torvalds 	hci_dev_lock(hdev);
37951da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
37961da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
37971da177e4SLinus Torvalds 
37981da177e4SLinus Torvalds 	if (conn) {
37991da177e4SLinus Torvalds 		/* Send to upper protocol */
38003f19ffb2SLuiz Augusto von Dentz 		hci_skb_pkt_status(skb) = flags & 0x03;
3801686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
38021da177e4SLinus Torvalds 		return;
38031da177e4SLinus Torvalds 	} else {
38042d4b37b6SLuiz Augusto von Dentz 		bt_dev_err_ratelimited(hdev, "SCO packet for unknown connection handle %d",
38052064ee33SMarcel Holtmann 				       handle);
38061da177e4SLinus Torvalds 	}
hci_isodata_packet(struct hci_dev * hdev,struct sk_buff * skb)38071da177e4SLinus Torvalds 
38081da177e4SLinus Torvalds 	kfree_skb(skb);
38091da177e4SLinus Torvalds }
38101da177e4SLinus Torvalds 
381126afbd82SLuiz Augusto von Dentz static void hci_isodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
381226afbd82SLuiz Augusto von Dentz {
381326afbd82SLuiz Augusto von Dentz 	struct hci_iso_hdr *hdr;
381426afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
381526afbd82SLuiz Augusto von Dentz 	__u16 handle, flags;
381626afbd82SLuiz Augusto von Dentz 
381726afbd82SLuiz Augusto von Dentz 	hdr = skb_pull_data(skb, sizeof(*hdr));
381826afbd82SLuiz Augusto von Dentz 	if (!hdr) {
381926afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev, "ISO packet too small");
382026afbd82SLuiz Augusto von Dentz 		goto drop;
382126afbd82SLuiz Augusto von Dentz 	}
382226afbd82SLuiz Augusto von Dentz 
382326afbd82SLuiz Augusto von Dentz 	handle = __le16_to_cpu(hdr->handle);
382426afbd82SLuiz Augusto von Dentz 	flags  = hci_flags(handle);
382526afbd82SLuiz Augusto von Dentz 	handle = hci_handle(handle);
382626afbd82SLuiz Augusto von Dentz 
382726afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "len %d handle 0x%4.4x flags 0x%4.4x", skb->len,
382826afbd82SLuiz Augusto von Dentz 		   handle, flags);
382926afbd82SLuiz Augusto von Dentz 
383026afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
383126afbd82SLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_handle(hdev, handle);
383226afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
383326afbd82SLuiz Augusto von Dentz 
383426afbd82SLuiz Augusto von Dentz 	if (!conn) {
383526afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev, "ISO packet for unknown connection handle %d",
383626afbd82SLuiz Augusto von Dentz 			   handle);
3837ccf74f23SLuiz Augusto von Dentz 		goto drop;
383826afbd82SLuiz Augusto von Dentz 	}
383926afbd82SLuiz Augusto von Dentz 
3840ccf74f23SLuiz Augusto von Dentz 	/* Send to upper protocol */
3841ccf74f23SLuiz Augusto von Dentz 	iso_recv(conn, skb, flags);
3842ccf74f23SLuiz Augusto von Dentz 	return;
3843ccf74f23SLuiz Augusto von Dentz 
hci_req_is_complete(struct hci_dev * hdev)384426afbd82SLuiz Augusto von Dentz drop:
384526afbd82SLuiz Augusto von Dentz 	kfree_skb(skb);
384626afbd82SLuiz Augusto von Dentz }
384726afbd82SLuiz Augusto von Dentz 
38489238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
38499238f36aSJohan Hedberg {
38509238f36aSJohan Hedberg 	struct sk_buff *skb;
38519238f36aSJohan Hedberg 
38529238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
38539238f36aSJohan Hedberg 	if (!skb)
38549238f36aSJohan Hedberg 		return true;
hci_resend_last(struct hci_dev * hdev)38559238f36aSJohan Hedberg 
385644d27137SJohan Hedberg 	return (bt_cb(skb)->hci.req_flags & HCI_REQ_START);
38579238f36aSJohan Hedberg }
38589238f36aSJohan Hedberg 
385942c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
386042c6b129SJohan Hedberg {
386142c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
386242c6b129SJohan Hedberg 	struct sk_buff *skb;
386342c6b129SJohan Hedberg 	u16 opcode;
386442c6b129SJohan Hedberg 
386542c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
386642c6b129SJohan Hedberg 		return;
386742c6b129SJohan Hedberg 
386842c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
386942c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
387042c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
387142c6b129SJohan Hedberg 		return;
387242c6b129SJohan Hedberg 
387342c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
387442c6b129SJohan Hedberg 	if (!skb)
387542c6b129SJohan Hedberg 		return;
387642c6b129SJohan Hedberg 
hci_req_cmd_complete(struct hci_dev * hdev,u16 opcode,u8 status,hci_req_complete_t * req_complete,hci_req_complete_skb_t * req_complete_skb)387742c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
387842c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
387942c6b129SJohan Hedberg }
388042c6b129SJohan Hedberg 
3881e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
3882e6214487SJohan Hedberg 			  hci_req_complete_t *req_complete,
3883e6214487SJohan Hedberg 			  hci_req_complete_skb_t *req_complete_skb)
38849238f36aSJohan Hedberg {
38859238f36aSJohan Hedberg 	struct sk_buff *skb;
38869238f36aSJohan Hedberg 	unsigned long flags;
38879238f36aSJohan Hedberg 
38889238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
38899238f36aSJohan Hedberg 
389042c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
389142c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
38929238f36aSJohan Hedberg 	 */
389342c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
389442c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
389542c6b129SJohan Hedberg 		 * reset complete event during init and any pending
389642c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
389742c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
389842c6b129SJohan Hedberg 		 * command.
389942c6b129SJohan Hedberg 		 */
390042c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
390142c6b129SJohan Hedberg 			hci_resend_last(hdev);
390242c6b129SJohan Hedberg 
39039238f36aSJohan Hedberg 		return;
390442c6b129SJohan Hedberg 	}
39059238f36aSJohan Hedberg 
3906f80c5dadSJoão Paulo Rechi Vita 	/* If we reach this point this event matches the last command sent */
3907f80c5dadSJoão Paulo Rechi Vita 	hci_dev_clear_flag(hdev, HCI_CMD_PENDING);
3908f80c5dadSJoão Paulo Rechi Vita 
39099238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
39109238f36aSJohan Hedberg 	 * this request the request is not yet complete.
39119238f36aSJohan Hedberg 	 */
39129238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
39139238f36aSJohan Hedberg 		return;
39149238f36aSJohan Hedberg 
39152af7aa66SLuiz Augusto von Dentz 	skb = hdev->req_skb;
39162af7aa66SLuiz Augusto von Dentz 
39179238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
39182af7aa66SLuiz Augusto von Dentz 	 * callback would be found in hdev->req_skb instead of the
39199238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
39209238f36aSJohan Hedberg 	 */
39212af7aa66SLuiz Augusto von Dentz 	if (skb && bt_cb(skb)->hci.req_flags & HCI_REQ_SKB) {
39222af7aa66SLuiz Augusto von Dentz 		*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
3923e6214487SJohan Hedberg 		return;
39249238f36aSJohan Hedberg 	}
3925e6214487SJohan Hedberg 
39262af7aa66SLuiz Augusto von Dentz 	if (skb && bt_cb(skb)->hci.req_complete) {
39272af7aa66SLuiz Augusto von Dentz 		*req_complete = bt_cb(skb)->hci.req_complete;
3928e6214487SJohan Hedberg 		return;
392953e21fbcSJohan Hedberg 	}
39309238f36aSJohan Hedberg 
39319238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
39329238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
39339238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
393444d27137SJohan Hedberg 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) {
39359238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
39369238f36aSJohan Hedberg 			break;
39379238f36aSJohan Hedberg 		}
39389238f36aSJohan Hedberg 
39393bd7594eSDouglas Anderson 		if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB)
3940242c0ebdSMarcel Holtmann 			*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
39413bd7594eSDouglas Anderson 		else
39423bd7594eSDouglas Anderson 			*req_complete = bt_cb(skb)->hci.req_complete;
394339c1eb6fSYang Yingliang 		dev_kfree_skb_irq(skb);
hci_rx_work(struct work_struct * work)39449238f36aSJohan Hedberg 	}
39459238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
39469238f36aSJohan Hedberg }
39479238f36aSJohan Hedberg 
3948b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
39491da177e4SLinus Torvalds {
3950b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
39511da177e4SLinus Torvalds 	struct sk_buff *skb;
39521da177e4SLinus Torvalds 
39531da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
39541da177e4SLinus Torvalds 
39559f30de9eSTamas Koczka 	/* The kcov_remote functions used for collecting packet parsing
39569f30de9eSTamas Koczka 	 * coverage information from this background thread and associate
39579f30de9eSTamas Koczka 	 * the coverage with the syscall's thread which originally injected
39589f30de9eSTamas Koczka 	 * the packet. This helps fuzzing the kernel.
39599f30de9eSTamas Koczka 	 */
39609f30de9eSTamas Koczka 	for (; (skb = skb_dequeue(&hdev->rx_q)); kcov_remote_stop()) {
39619f30de9eSTamas Koczka 		kcov_remote_start_common(skb_get_kcov_handle(skb));
39629f30de9eSTamas Koczka 
3963cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
3964cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
3965cd82e61cSMarcel Holtmann 
39661da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
39671da177e4SLinus Torvalds 			/* Send copy to the sockets */
3968470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
39691da177e4SLinus Torvalds 		}
39701da177e4SLinus Torvalds 
3971eb8c101eSMattijs Korpershoek 		/* If the device has been opened in HCI_USER_CHANNEL,
3972eb8c101eSMattijs Korpershoek 		 * the userspace has exclusive access to device.
3973eb8c101eSMattijs Korpershoek 		 * When device is HCI_INIT, we still need to process
3974eb8c101eSMattijs Korpershoek 		 * the data packets to the driver in order
3975eb8c101eSMattijs Korpershoek 		 * to complete its setup().
3976eb8c101eSMattijs Korpershoek 		 */
3977eb8c101eSMattijs Korpershoek 		if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
3978eb8c101eSMattijs Korpershoek 		    !test_bit(HCI_INIT, &hdev->flags)) {
39791da177e4SLinus Torvalds 			kfree_skb(skb);
39801da177e4SLinus Torvalds 			continue;
39811da177e4SLinus Torvalds 		}
39821da177e4SLinus Torvalds 
39831da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
39841da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
3985d79f34e3SMarcel Holtmann 			switch (hci_skb_pkt_type(skb)) {
39861da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
39871da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
3988cc974003SMarcel Holtmann 			case HCI_ISODATA_PKT:
39891da177e4SLinus Torvalds 				kfree_skb(skb);
39901da177e4SLinus Torvalds 				continue;
39913ff50b79SStephen Hemminger 			}
39921da177e4SLinus Torvalds 		}
39931da177e4SLinus Torvalds 
39941da177e4SLinus Torvalds 		/* Process frame */
3995d79f34e3SMarcel Holtmann 		switch (hci_skb_pkt_type(skb)) {
39961da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
3997b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
39981da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
39991da177e4SLinus Torvalds 			break;
40001da177e4SLinus Torvalds 
40011da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
40021da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
40031da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
40041da177e4SLinus Torvalds 			break;
40051da177e4SLinus Torvalds 
40061da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
40071da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
40081da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
40091da177e4SLinus Torvalds 			break;
40101da177e4SLinus Torvalds 
401126afbd82SLuiz Augusto von Dentz 		case HCI_ISODATA_PKT:
401226afbd82SLuiz Augusto von Dentz 			BT_DBG("%s ISO data packet", hdev->name);
401326afbd82SLuiz Augusto von Dentz 			hci_isodata_packet(hdev, skb);
401426afbd82SLuiz Augusto von Dentz 			break;
401526afbd82SLuiz Augusto von Dentz 
40161da177e4SLinus Torvalds 		default:
40171da177e4SLinus Torvalds 			kfree_skb(skb);
40181da177e4SLinus Torvalds 			break;
hci_send_cmd_sync(struct hci_dev * hdev,struct sk_buff * skb)40191da177e4SLinus Torvalds 		}
40201da177e4SLinus Torvalds 	}
40211da177e4SLinus Torvalds }
40221da177e4SLinus Torvalds 
40230ce1229cSLuiz Augusto von Dentz static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
40240ce1229cSLuiz Augusto von Dentz {
40250ce1229cSLuiz Augusto von Dentz 	int err;
40260ce1229cSLuiz Augusto von Dentz 
40270ce1229cSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "skb %p", skb);
40280ce1229cSLuiz Augusto von Dentz 
40290ce1229cSLuiz Augusto von Dentz 	kfree_skb(hdev->sent_cmd);
40300ce1229cSLuiz Augusto von Dentz 
40310ce1229cSLuiz Augusto von Dentz 	hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
40320ce1229cSLuiz Augusto von Dentz 	if (!hdev->sent_cmd) {
40330ce1229cSLuiz Augusto von Dentz 		skb_queue_head(&hdev->cmd_q, skb);
40340ce1229cSLuiz Augusto von Dentz 		queue_work(hdev->workqueue, &hdev->cmd_work);
40350ce1229cSLuiz Augusto von Dentz 		return;
40360ce1229cSLuiz Augusto von Dentz 	}
40370ce1229cSLuiz Augusto von Dentz 
40380ce1229cSLuiz Augusto von Dentz 	err = hci_send_frame(hdev, skb);
40390ce1229cSLuiz Augusto von Dentz 	if (err < 0) {
40409ae3954dSLuiz Augusto von Dentz 		hci_cmd_sync_cancel_sync(hdev, -err);
40410ce1229cSLuiz Augusto von Dentz 		return;
40420ce1229cSLuiz Augusto von Dentz 	}
40430ce1229cSLuiz Augusto von Dentz 
40442af7aa66SLuiz Augusto von Dentz 	if (hci_req_status_pend(hdev) &&
40452af7aa66SLuiz Augusto von Dentz 	    !hci_dev_test_and_set_flag(hdev, HCI_CMD_PENDING)) {
40462af7aa66SLuiz Augusto von Dentz 		kfree_skb(hdev->req_skb);
4047a2354605SPauli Virtanen 		hdev->req_skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
40482af7aa66SLuiz Augusto von Dentz 	}
40490ce1229cSLuiz Augusto von Dentz 
40500ce1229cSLuiz Augusto von Dentz 	atomic_dec(&hdev->cmd_cnt);
40510ce1229cSLuiz Augusto von Dentz }
40520ce1229cSLuiz Augusto von Dentz 
4053c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
40541da177e4SLinus Torvalds {
4055c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
40561da177e4SLinus Torvalds 	struct sk_buff *skb;
40571da177e4SLinus Torvalds 
40582104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
40592104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
40601da177e4SLinus Torvalds 
40611da177e4SLinus Torvalds 	/* Send queued commands */
40625a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
40635a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
40645a08ecceSAndrei Emeltchenko 		if (!skb)
40655a08ecceSAndrei Emeltchenko 			return;
40665a08ecceSAndrei Emeltchenko 
40670ce1229cSLuiz Augusto von Dentz 		hci_send_cmd_sync(hdev, skb);
40682250abadSBenjamin Berg 
4069deee93d1STetsuo Handa 		rcu_read_lock();
4070877afadaSSchspa Shi 		if (test_bit(HCI_RESET, &hdev->flags) ||
4071877afadaSSchspa Shi 		    hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
407265cc2b49SMarcel Holtmann 			cancel_delayed_work(&hdev->cmd_timer);
40737bdb8a5cSSzymon Janc 		else
4074deee93d1STetsuo Handa 			queue_delayed_work(hdev->workqueue, &hdev->cmd_timer,
407565cc2b49SMarcel Holtmann 					   HCI_CMD_TIMEOUT);
4076deee93d1STetsuo Handa 		rcu_read_unlock();
40771da177e4SLinus Torvalds 	}
40781da177e4SLinus Torvalds }
4079