xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 310a3d48)
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>
293df92b31SSasha Levin #include <linux/idr.h>
301da177e4SLinus Torvalds 
31611b30f7SMarcel Holtmann #include <linux/rfkill.h>
321da177e4SLinus Torvalds 
331da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
341da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
351da177e4SLinus Torvalds 
36b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
37c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
383eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
391da177e4SLinus Torvalds 
401da177e4SLinus Torvalds /* HCI device list */
411da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
421da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
431da177e4SLinus Torvalds 
441da177e4SLinus Torvalds /* HCI callback list */
451da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
461da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
471da177e4SLinus Torvalds 
483df92b31SSasha Levin /* HCI ID Numbering */
493df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
503df92b31SSasha Levin 
511da177e4SLinus Torvalds /* ---- HCI notifications ---- */
521da177e4SLinus Torvalds 
536516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
541da177e4SLinus Torvalds {
55040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
561da177e4SLinus Torvalds }
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds /* ---- HCI requests ---- */
591da177e4SLinus Torvalds 
6042c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
611da177e4SLinus Torvalds {
6242c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
6375fb0e32SJohan Hedberg 
641da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
651da177e4SLinus Torvalds 		hdev->req_result = result;
661da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
671da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
681da177e4SLinus Torvalds 	}
691da177e4SLinus Torvalds }
701da177e4SLinus Torvalds 
711da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
721da177e4SLinus Torvalds {
731da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
741da177e4SLinus Torvalds 
751da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
761da177e4SLinus Torvalds 		hdev->req_result = err;
771da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
781da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
791da177e4SLinus Torvalds 	}
801da177e4SLinus Torvalds }
811da177e4SLinus Torvalds 
8277a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
8377a63e0aSFengguang Wu 					    u8 event)
8475e84b7cSJohan Hedberg {
8575e84b7cSJohan Hedberg 	struct hci_ev_cmd_complete *ev;
8675e84b7cSJohan Hedberg 	struct hci_event_hdr *hdr;
8775e84b7cSJohan Hedberg 	struct sk_buff *skb;
8875e84b7cSJohan Hedberg 
8975e84b7cSJohan Hedberg 	hci_dev_lock(hdev);
9075e84b7cSJohan Hedberg 
9175e84b7cSJohan Hedberg 	skb = hdev->recv_evt;
9275e84b7cSJohan Hedberg 	hdev->recv_evt = NULL;
9375e84b7cSJohan Hedberg 
9475e84b7cSJohan Hedberg 	hci_dev_unlock(hdev);
9575e84b7cSJohan Hedberg 
9675e84b7cSJohan Hedberg 	if (!skb)
9775e84b7cSJohan Hedberg 		return ERR_PTR(-ENODATA);
9875e84b7cSJohan Hedberg 
9975e84b7cSJohan Hedberg 	if (skb->len < sizeof(*hdr)) {
10075e84b7cSJohan Hedberg 		BT_ERR("Too short HCI event");
10175e84b7cSJohan Hedberg 		goto failed;
10275e84b7cSJohan Hedberg 	}
10375e84b7cSJohan Hedberg 
10475e84b7cSJohan Hedberg 	hdr = (void *) skb->data;
10575e84b7cSJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
10675e84b7cSJohan Hedberg 
1077b1abbbeSJohan Hedberg 	if (event) {
1087b1abbbeSJohan Hedberg 		if (hdr->evt != event)
1097b1abbbeSJohan Hedberg 			goto failed;
1107b1abbbeSJohan Hedberg 		return skb;
1117b1abbbeSJohan Hedberg 	}
1127b1abbbeSJohan Hedberg 
11375e84b7cSJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
11475e84b7cSJohan Hedberg 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
11575e84b7cSJohan Hedberg 		goto failed;
11675e84b7cSJohan Hedberg 	}
11775e84b7cSJohan Hedberg 
11875e84b7cSJohan Hedberg 	if (skb->len < sizeof(*ev)) {
11975e84b7cSJohan Hedberg 		BT_ERR("Too short cmd_complete event");
12075e84b7cSJohan Hedberg 		goto failed;
12175e84b7cSJohan Hedberg 	}
12275e84b7cSJohan Hedberg 
12375e84b7cSJohan Hedberg 	ev = (void *) skb->data;
12475e84b7cSJohan Hedberg 	skb_pull(skb, sizeof(*ev));
12575e84b7cSJohan Hedberg 
12675e84b7cSJohan Hedberg 	if (opcode == __le16_to_cpu(ev->opcode))
12775e84b7cSJohan Hedberg 		return skb;
12875e84b7cSJohan Hedberg 
12975e84b7cSJohan Hedberg 	BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
13075e84b7cSJohan Hedberg 	       __le16_to_cpu(ev->opcode));
13175e84b7cSJohan Hedberg 
13275e84b7cSJohan Hedberg failed:
13375e84b7cSJohan Hedberg 	kfree_skb(skb);
13475e84b7cSJohan Hedberg 	return ERR_PTR(-ENODATA);
13575e84b7cSJohan Hedberg }
13675e84b7cSJohan Hedberg 
1377b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
13807dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
13975e84b7cSJohan Hedberg {
14075e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
14175e84b7cSJohan Hedberg 	struct hci_request req;
14275e84b7cSJohan Hedberg 	int err = 0;
14375e84b7cSJohan Hedberg 
14475e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
14575e84b7cSJohan Hedberg 
14675e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
14775e84b7cSJohan Hedberg 
1487b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
14975e84b7cSJohan Hedberg 
15075e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
15175e84b7cSJohan Hedberg 
15275e84b7cSJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
15375e84b7cSJohan Hedberg 	if (err < 0)
15475e84b7cSJohan Hedberg 		return ERR_PTR(err);
15575e84b7cSJohan Hedberg 
15675e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
15775e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
15875e84b7cSJohan Hedberg 
15975e84b7cSJohan Hedberg 	schedule_timeout(timeout);
16075e84b7cSJohan Hedberg 
16175e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
16275e84b7cSJohan Hedberg 
16375e84b7cSJohan Hedberg 	if (signal_pending(current))
16475e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
16575e84b7cSJohan Hedberg 
16675e84b7cSJohan Hedberg 	switch (hdev->req_status) {
16775e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
16875e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
16975e84b7cSJohan Hedberg 		break;
17075e84b7cSJohan Hedberg 
17175e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
17275e84b7cSJohan Hedberg 		err = -hdev->req_result;
17375e84b7cSJohan Hedberg 		break;
17475e84b7cSJohan Hedberg 
17575e84b7cSJohan Hedberg 	default:
17675e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
17775e84b7cSJohan Hedberg 		break;
17875e84b7cSJohan Hedberg 	}
17975e84b7cSJohan Hedberg 
18075e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
18175e84b7cSJohan Hedberg 
18275e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
18375e84b7cSJohan Hedberg 
18475e84b7cSJohan Hedberg 	if (err < 0)
18575e84b7cSJohan Hedberg 		return ERR_PTR(err);
18675e84b7cSJohan Hedberg 
1877b1abbbeSJohan Hedberg 	return hci_get_cmd_complete(hdev, opcode, event);
1887b1abbbeSJohan Hedberg }
1897b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
1907b1abbbeSJohan Hedberg 
1917b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
19207dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
1937b1abbbeSJohan Hedberg {
1947b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
19575e84b7cSJohan Hedberg }
19675e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
19775e84b7cSJohan Hedberg 
1981da177e4SLinus Torvalds /* Execute request and wait for completion. */
19901178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
20042c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
20142c6b129SJohan Hedberg 				      unsigned long opt),
2021da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
2031da177e4SLinus Torvalds {
20442c6b129SJohan Hedberg 	struct hci_request req;
2051da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
2061da177e4SLinus Torvalds 	int err = 0;
2071da177e4SLinus Torvalds 
2081da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
2091da177e4SLinus Torvalds 
21042c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
21142c6b129SJohan Hedberg 
2121da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
2131da177e4SLinus Torvalds 
21442c6b129SJohan Hedberg 	func(&req, opt);
21553cce22dSJohan Hedberg 
21642c6b129SJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
21742c6b129SJohan Hedberg 	if (err < 0) {
21853cce22dSJohan Hedberg 		hdev->req_status = 0;
219920c8300SAndre Guedes 
220920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
221920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
222920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
223920c8300SAndre Guedes 		 * and should not trigger an error return.
22442c6b129SJohan Hedberg 		 */
225920c8300SAndre Guedes 		if (err == -ENODATA)
22642c6b129SJohan Hedberg 			return 0;
227920c8300SAndre Guedes 
228920c8300SAndre Guedes 		return err;
22953cce22dSJohan Hedberg 	}
23053cce22dSJohan Hedberg 
231bc4445c7SAndre Guedes 	add_wait_queue(&hdev->req_wait_q, &wait);
232bc4445c7SAndre Guedes 	set_current_state(TASK_INTERRUPTIBLE);
233bc4445c7SAndre Guedes 
2341da177e4SLinus Torvalds 	schedule_timeout(timeout);
2351da177e4SLinus Torvalds 
2361da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
2371da177e4SLinus Torvalds 
2381da177e4SLinus Torvalds 	if (signal_pending(current))
2391da177e4SLinus Torvalds 		return -EINTR;
2401da177e4SLinus Torvalds 
2411da177e4SLinus Torvalds 	switch (hdev->req_status) {
2421da177e4SLinus Torvalds 	case HCI_REQ_DONE:
243e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
2441da177e4SLinus Torvalds 		break;
2451da177e4SLinus Torvalds 
2461da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
2471da177e4SLinus Torvalds 		err = -hdev->req_result;
2481da177e4SLinus Torvalds 		break;
2491da177e4SLinus Torvalds 
2501da177e4SLinus Torvalds 	default:
2511da177e4SLinus Torvalds 		err = -ETIMEDOUT;
2521da177e4SLinus Torvalds 		break;
2533ff50b79SStephen Hemminger 	}
2541da177e4SLinus Torvalds 
255a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
2561da177e4SLinus Torvalds 
2571da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
2581da177e4SLinus Torvalds 
2591da177e4SLinus Torvalds 	return err;
2601da177e4SLinus Torvalds }
2611da177e4SLinus Torvalds 
26201178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
26342c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
26442c6b129SJohan Hedberg 				    unsigned long opt),
2651da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
2661da177e4SLinus Torvalds {
2671da177e4SLinus Torvalds 	int ret;
2681da177e4SLinus Torvalds 
2697c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
2707c6a329eSMarcel Holtmann 		return -ENETDOWN;
2717c6a329eSMarcel Holtmann 
2721da177e4SLinus Torvalds 	/* Serialize all requests */
2731da177e4SLinus Torvalds 	hci_req_lock(hdev);
27401178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
2751da177e4SLinus Torvalds 	hci_req_unlock(hdev);
2761da177e4SLinus Torvalds 
2771da177e4SLinus Torvalds 	return ret;
2781da177e4SLinus Torvalds }
2791da177e4SLinus Torvalds 
28042c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
2811da177e4SLinus Torvalds {
28242c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
2831da177e4SLinus Torvalds 
2841da177e4SLinus Torvalds 	/* Reset device */
28542c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
28642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
2871da177e4SLinus Torvalds }
2881da177e4SLinus Torvalds 
28942c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
2901da177e4SLinus Torvalds {
29142c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
2922455a3eaSAndrei Emeltchenko 
2931da177e4SLinus Torvalds 	/* Read Local Supported Features */
29442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
2951da177e4SLinus Torvalds 
2961143e5a6SMarcel Holtmann 	/* Read Local Version */
29742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2982177bab5SJohan Hedberg 
2992177bab5SJohan Hedberg 	/* Read BD Address */
30042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
3011da177e4SLinus Torvalds }
3021da177e4SLinus Torvalds 
30342c6b129SJohan Hedberg static void amp_init(struct hci_request *req)
304e61ef499SAndrei Emeltchenko {
30542c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
3062455a3eaSAndrei Emeltchenko 
307e61ef499SAndrei Emeltchenko 	/* Read Local Version */
30842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
3096bcbc489SAndrei Emeltchenko 
310f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
311f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
312f6996cfeSMarcel Holtmann 
313f6996cfeSMarcel Holtmann 	/* Read Local Supported Features */
314f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
315f6996cfeSMarcel Holtmann 
3166bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
31742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
318e71dfabaSAndrei Emeltchenko 
319e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
32042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
3217528ca1cSMarcel Holtmann 
322f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
323f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
324f38ba941SMarcel Holtmann 
3257528ca1cSMarcel Holtmann 	/* Read Location Data */
3267528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
327e61ef499SAndrei Emeltchenko }
328e61ef499SAndrei Emeltchenko 
32942c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
330e61ef499SAndrei Emeltchenko {
33142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
332e61ef499SAndrei Emeltchenko 
333e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
334e61ef499SAndrei Emeltchenko 
33511778716SAndrei Emeltchenko 	/* Reset */
33611778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
33742c6b129SJohan Hedberg 		hci_reset_req(req, 0);
33811778716SAndrei Emeltchenko 
339e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
340e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
34142c6b129SJohan Hedberg 		bredr_init(req);
342e61ef499SAndrei Emeltchenko 		break;
343e61ef499SAndrei Emeltchenko 
344e61ef499SAndrei Emeltchenko 	case HCI_AMP:
34542c6b129SJohan Hedberg 		amp_init(req);
346e61ef499SAndrei Emeltchenko 		break;
347e61ef499SAndrei Emeltchenko 
348e61ef499SAndrei Emeltchenko 	default:
349e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
350e61ef499SAndrei Emeltchenko 		break;
351e61ef499SAndrei Emeltchenko 	}
352e61ef499SAndrei Emeltchenko }
353e61ef499SAndrei Emeltchenko 
35442c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
3552177bab5SJohan Hedberg {
3564ca048e3SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
3574ca048e3SMarcel Holtmann 
3582177bab5SJohan Hedberg 	__le16 param;
3592177bab5SJohan Hedberg 	__u8 flt_type;
3602177bab5SJohan Hedberg 
3612177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
36242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
3632177bab5SJohan Hedberg 
3642177bab5SJohan Hedberg 	/* Read Class of Device */
36542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
3662177bab5SJohan Hedberg 
3672177bab5SJohan Hedberg 	/* Read Local Name */
36842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
3692177bab5SJohan Hedberg 
3702177bab5SJohan Hedberg 	/* Read Voice Setting */
37142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
3722177bab5SJohan Hedberg 
373b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
374b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
375b4cb9fb2SMarcel Holtmann 
3764b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
3774b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
3784b836f39SMarcel Holtmann 
3792177bab5SJohan Hedberg 	/* Clear Event Filters */
3802177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
38142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
3822177bab5SJohan Hedberg 
3832177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
3842177bab5SJohan Hedberg 	param = __constant_cpu_to_le16(0x7d00);
38542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
3862177bab5SJohan Hedberg 
3874ca048e3SMarcel Holtmann 	/* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2,
3884ca048e3SMarcel Holtmann 	 * but it does not support page scan related HCI commands.
3894ca048e3SMarcel Holtmann 	 */
3904ca048e3SMarcel Holtmann 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) {
391f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
392f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
393f332ec66SJohan Hedberg 	}
3942177bab5SJohan Hedberg }
3952177bab5SJohan Hedberg 
39642c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
3972177bab5SJohan Hedberg {
398c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
399c73eee91SJohan Hedberg 
4002177bab5SJohan Hedberg 	/* Read LE Buffer Size */
40142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
4022177bab5SJohan Hedberg 
4032177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
40442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
4052177bab5SJohan Hedberg 
4062177bab5SJohan Hedberg 	/* Read LE Advertising Channel TX Power */
40742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
4082177bab5SJohan Hedberg 
4092177bab5SJohan Hedberg 	/* Read LE White List Size */
41042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
4112177bab5SJohan Hedberg 
4122177bab5SJohan Hedberg 	/* Read LE Supported States */
41342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
414c73eee91SJohan Hedberg 
415c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
416c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
417c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
4182177bab5SJohan Hedberg }
4192177bab5SJohan Hedberg 
4202177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
4212177bab5SJohan Hedberg {
4222177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
4232177bab5SJohan Hedberg 		return 0x02;
4242177bab5SJohan Hedberg 
4252177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4262177bab5SJohan Hedberg 		return 0x01;
4272177bab5SJohan Hedberg 
4282177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
4292177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
4302177bab5SJohan Hedberg 		return 0x01;
4312177bab5SJohan Hedberg 
4322177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
4332177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
4342177bab5SJohan Hedberg 			return 0x01;
4352177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
4362177bab5SJohan Hedberg 			return 0x01;
4372177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
4382177bab5SJohan Hedberg 			return 0x01;
4392177bab5SJohan Hedberg 	}
4402177bab5SJohan Hedberg 
4412177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
4422177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
4432177bab5SJohan Hedberg 		return 0x01;
4442177bab5SJohan Hedberg 
4452177bab5SJohan Hedberg 	return 0x00;
4462177bab5SJohan Hedberg }
4472177bab5SJohan Hedberg 
44842c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
4492177bab5SJohan Hedberg {
4502177bab5SJohan Hedberg 	u8 mode;
4512177bab5SJohan Hedberg 
45242c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
4532177bab5SJohan Hedberg 
45442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
4552177bab5SJohan Hedberg }
4562177bab5SJohan Hedberg 
45742c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
4582177bab5SJohan Hedberg {
45942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
46042c6b129SJohan Hedberg 
4612177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
4622177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
4632177bab5SJohan Hedberg 	 * command otherwise.
4642177bab5SJohan Hedberg 	 */
4652177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
4662177bab5SJohan Hedberg 
4672177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
4682177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
4692177bab5SJohan Hedberg 	 */
4702177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
4712177bab5SJohan Hedberg 		return;
4722177bab5SJohan Hedberg 
4732177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
4742177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
4752177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4762177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
4772177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
4782177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
479c7882cbdSMarcel Holtmann 	} else {
480c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
481c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
482c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
483c7882cbdSMarcel Holtmann 		events[0] |= 0x80; /* Encryption Change */
484c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
485c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
486c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
487c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
488c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
489c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
490c7882cbdSMarcel Holtmann 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
4912177bab5SJohan Hedberg 	}
4922177bab5SJohan Hedberg 
4932177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4942177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4952177bab5SJohan Hedberg 
4962177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
4972177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
4982177bab5SJohan Hedberg 
4992177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
5002177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
5012177bab5SJohan Hedberg 
5022177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
5032177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
5042177bab5SJohan Hedberg 
5052177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
5062177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
5072177bab5SJohan Hedberg 
5082177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
5092177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
5102177bab5SJohan Hedberg 
5112177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5122177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
5132177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
5142177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
5152177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
5162177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
5172177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
5182177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
5192177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
5202177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
5212177bab5SJohan Hedberg 					 * Features Notification
5222177bab5SJohan Hedberg 					 */
5232177bab5SJohan Hedberg 	}
5242177bab5SJohan Hedberg 
5252177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
5262177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
5272177bab5SJohan Hedberg 
52842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
5292177bab5SJohan Hedberg 
5302177bab5SJohan Hedberg 	if (lmp_le_capable(hdev)) {
5312177bab5SJohan Hedberg 		memset(events, 0, sizeof(events));
5322177bab5SJohan Hedberg 		events[0] = 0x1f;
53342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
5342177bab5SJohan Hedberg 			    sizeof(events), events);
5352177bab5SJohan Hedberg 	}
5362177bab5SJohan Hedberg }
5372177bab5SJohan Hedberg 
53842c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
5392177bab5SJohan Hedberg {
54042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
54142c6b129SJohan Hedberg 
5422177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
54342c6b129SJohan Hedberg 		bredr_setup(req);
54456f87901SJohan Hedberg 	else
54556f87901SJohan Hedberg 		clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
5462177bab5SJohan Hedberg 
5472177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
54842c6b129SJohan Hedberg 		le_setup(req);
5492177bab5SJohan Hedberg 
55042c6b129SJohan Hedberg 	hci_setup_event_mask(req);
5512177bab5SJohan Hedberg 
5523f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
5533f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
5543f8e2d75SJohan Hedberg 	 */
5553f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
55642c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
5572177bab5SJohan Hedberg 
5582177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5592177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
5602177bab5SJohan Hedberg 			u8 mode = 0x01;
56142c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
5622177bab5SJohan Hedberg 				    sizeof(mode), &mode);
5632177bab5SJohan Hedberg 		} else {
5642177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
5652177bab5SJohan Hedberg 
5662177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
5672177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
5682177bab5SJohan Hedberg 
56942c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
5702177bab5SJohan Hedberg 		}
5712177bab5SJohan Hedberg 	}
5722177bab5SJohan Hedberg 
5732177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
57442c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
5752177bab5SJohan Hedberg 
5762177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
57742c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
5782177bab5SJohan Hedberg 
5792177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
5802177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
5812177bab5SJohan Hedberg 
5822177bab5SJohan Hedberg 		cp.page = 0x01;
58342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
58442c6b129SJohan Hedberg 			    sizeof(cp), &cp);
5852177bab5SJohan Hedberg 	}
5862177bab5SJohan Hedberg 
5872177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
5882177bab5SJohan Hedberg 		u8 enable = 1;
58942c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
5902177bab5SJohan Hedberg 			    &enable);
5912177bab5SJohan Hedberg 	}
5922177bab5SJohan Hedberg }
5932177bab5SJohan Hedberg 
59442c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
5952177bab5SJohan Hedberg {
59642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5972177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
5982177bab5SJohan Hedberg 	u16 link_policy = 0;
5992177bab5SJohan Hedberg 
6002177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
6012177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
6022177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
6032177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
6042177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
6052177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
6062177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
6072177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
6082177bab5SJohan Hedberg 
6092177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
61042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
6112177bab5SJohan Hedberg }
6122177bab5SJohan Hedberg 
61342c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
6142177bab5SJohan Hedberg {
61542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
6162177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
6172177bab5SJohan Hedberg 
618c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
619c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
620c73eee91SJohan Hedberg 		return;
621c73eee91SJohan Hedberg 
6222177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
6232177bab5SJohan Hedberg 
6242177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
6252177bab5SJohan Hedberg 		cp.le = 0x01;
6262177bab5SJohan Hedberg 		cp.simul = lmp_le_br_capable(hdev);
6272177bab5SJohan Hedberg 	}
6282177bab5SJohan Hedberg 
6292177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
63042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
6312177bab5SJohan Hedberg 			    &cp);
6322177bab5SJohan Hedberg }
6332177bab5SJohan Hedberg 
634d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
635d62e6d67SJohan Hedberg {
636d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
637d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
638d62e6d67SJohan Hedberg 
639d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
640d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
641d62e6d67SJohan Hedberg 	 */
642d62e6d67SJohan Hedberg 	if (hdev->features[2][0] & 0x01) {
643d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
644d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
645d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
646d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
647d62e6d67SJohan Hedberg 	}
648d62e6d67SJohan Hedberg 
649d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
650d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
651d62e6d67SJohan Hedberg 	 */
652d62e6d67SJohan Hedberg 	if (hdev->features[2][0] & 0x02) {
653d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
654d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
655d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
656d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
657d62e6d67SJohan Hedberg 	}
658d62e6d67SJohan Hedberg 
659d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
660d62e6d67SJohan Hedberg }
661d62e6d67SJohan Hedberg 
66242c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
6632177bab5SJohan Hedberg {
66442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
665d2c5d77fSJohan Hedberg 	u8 p;
66642c6b129SJohan Hedberg 
667b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
668b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
669b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
670b8f4e068SGustavo Padovan 	 *
671b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
672b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
673b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
674b8f4e068SGustavo Padovan 	 * command redundant anyway.
675b8f4e068SGustavo Padovan 	 */
67659f45d57SJohan Hedberg 	if (hdev->commands[6] & 0x80) {
67759f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
67859f45d57SJohan Hedberg 
67959f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
68059f45d57SJohan Hedberg 		cp.delete_all = 0x01;
68159f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
68259f45d57SJohan Hedberg 			    sizeof(cp), &cp);
68359f45d57SJohan Hedberg 	}
68459f45d57SJohan Hedberg 
6852177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
68642c6b129SJohan Hedberg 		hci_setup_link_policy(req);
6872177bab5SJohan Hedberg 
688441ad2d0SMarcel Holtmann 	if (lmp_le_capable(hdev))
68942c6b129SJohan Hedberg 		hci_set_le_support(req);
690d2c5d77fSJohan Hedberg 
691d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
692d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
693d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
694d2c5d77fSJohan Hedberg 
695d2c5d77fSJohan Hedberg 		cp.page = p;
696d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
697d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
698d2c5d77fSJohan Hedberg 	}
6992177bab5SJohan Hedberg }
7002177bab5SJohan Hedberg 
7015d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
7025d4e7e8dSJohan Hedberg {
7035d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
7045d4e7e8dSJohan Hedberg 
705d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
706d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
707d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
708d62e6d67SJohan Hedberg 
7095d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
7105d4e7e8dSJohan Hedberg 	if (hdev->features[2][0] & 0x04)
7115d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
7125d4e7e8dSJohan Hedberg }
7135d4e7e8dSJohan Hedberg 
7142177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
7152177bab5SJohan Hedberg {
7162177bab5SJohan Hedberg 	int err;
7172177bab5SJohan Hedberg 
7182177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
7192177bab5SJohan Hedberg 	if (err < 0)
7202177bab5SJohan Hedberg 		return err;
7212177bab5SJohan Hedberg 
7222177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
7232177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
7242177bab5SJohan Hedberg 	 * first stage init.
7252177bab5SJohan Hedberg 	 */
7262177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
7272177bab5SJohan Hedberg 		return 0;
7282177bab5SJohan Hedberg 
7292177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
7302177bab5SJohan Hedberg 	if (err < 0)
7312177bab5SJohan Hedberg 		return err;
7322177bab5SJohan Hedberg 
7335d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
7345d4e7e8dSJohan Hedberg 	if (err < 0)
7355d4e7e8dSJohan Hedberg 		return err;
7365d4e7e8dSJohan Hedberg 
7375d4e7e8dSJohan Hedberg 	return __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
7382177bab5SJohan Hedberg }
7392177bab5SJohan Hedberg 
74042c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
7411da177e4SLinus Torvalds {
7421da177e4SLinus Torvalds 	__u8 scan = opt;
7431da177e4SLinus Torvalds 
74442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
7451da177e4SLinus Torvalds 
7461da177e4SLinus Torvalds 	/* Inquiry and Page scans */
74742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
7481da177e4SLinus Torvalds }
7491da177e4SLinus Torvalds 
75042c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
7511da177e4SLinus Torvalds {
7521da177e4SLinus Torvalds 	__u8 auth = opt;
7531da177e4SLinus Torvalds 
75442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
7551da177e4SLinus Torvalds 
7561da177e4SLinus Torvalds 	/* Authentication */
75742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
7581da177e4SLinus Torvalds }
7591da177e4SLinus Torvalds 
76042c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
7611da177e4SLinus Torvalds {
7621da177e4SLinus Torvalds 	__u8 encrypt = opt;
7631da177e4SLinus Torvalds 
76442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
7651da177e4SLinus Torvalds 
766e4e8e37cSMarcel Holtmann 	/* Encryption */
76742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
7681da177e4SLinus Torvalds }
7691da177e4SLinus Torvalds 
77042c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
771e4e8e37cSMarcel Holtmann {
772e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
773e4e8e37cSMarcel Holtmann 
77442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
775e4e8e37cSMarcel Holtmann 
776e4e8e37cSMarcel Holtmann 	/* Default link policy */
77742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
778e4e8e37cSMarcel Holtmann }
779e4e8e37cSMarcel Holtmann 
7801da177e4SLinus Torvalds /* Get HCI device by index.
7811da177e4SLinus Torvalds  * Device is held on return. */
7821da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
7831da177e4SLinus Torvalds {
7848035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
7851da177e4SLinus Torvalds 
7861da177e4SLinus Torvalds 	BT_DBG("%d", index);
7871da177e4SLinus Torvalds 
7881da177e4SLinus Torvalds 	if (index < 0)
7891da177e4SLinus Torvalds 		return NULL;
7901da177e4SLinus Torvalds 
7911da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
7928035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
7931da177e4SLinus Torvalds 		if (d->id == index) {
7941da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
7951da177e4SLinus Torvalds 			break;
7961da177e4SLinus Torvalds 		}
7971da177e4SLinus Torvalds 	}
7981da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
7991da177e4SLinus Torvalds 	return hdev;
8001da177e4SLinus Torvalds }
8011da177e4SLinus Torvalds 
8021da177e4SLinus Torvalds /* ---- Inquiry support ---- */
803ff9ef578SJohan Hedberg 
80430dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
80530dc78e1SJohan Hedberg {
80630dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
80730dc78e1SJohan Hedberg 
8086fbe195dSAndre Guedes 	switch (discov->state) {
809343f935bSAndre Guedes 	case DISCOVERY_FINDING:
8106fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
81130dc78e1SJohan Hedberg 		return true;
81230dc78e1SJohan Hedberg 
8136fbe195dSAndre Guedes 	default:
81430dc78e1SJohan Hedberg 		return false;
81530dc78e1SJohan Hedberg 	}
8166fbe195dSAndre Guedes }
81730dc78e1SJohan Hedberg 
818ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
819ff9ef578SJohan Hedberg {
820ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
821ff9ef578SJohan Hedberg 
822ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
823ff9ef578SJohan Hedberg 		return;
824ff9ef578SJohan Hedberg 
825ff9ef578SJohan Hedberg 	switch (state) {
826ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
8277b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
828ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
829ff9ef578SJohan Hedberg 		break;
830ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
831ff9ef578SJohan Hedberg 		break;
832343f935bSAndre Guedes 	case DISCOVERY_FINDING:
833ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
834ff9ef578SJohan Hedberg 		break;
83530dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
83630dc78e1SJohan Hedberg 		break;
837ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
838ff9ef578SJohan Hedberg 		break;
839ff9ef578SJohan Hedberg 	}
840ff9ef578SJohan Hedberg 
841ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
842ff9ef578SJohan Hedberg }
843ff9ef578SJohan Hedberg 
8441f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
8451da177e4SLinus Torvalds {
84630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
847b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
8481da177e4SLinus Torvalds 
849561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
850561aafbcSJohan Hedberg 		list_del(&p->all);
851b57c1a56SJohan Hedberg 		kfree(p);
8521da177e4SLinus Torvalds 	}
853561aafbcSJohan Hedberg 
854561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
855561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
8561da177e4SLinus Torvalds }
8571da177e4SLinus Torvalds 
858a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
859a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
8601da177e4SLinus Torvalds {
86130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
8621da177e4SLinus Torvalds 	struct inquiry_entry *e;
8631da177e4SLinus Torvalds 
8646ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
8651da177e4SLinus Torvalds 
866561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
8671da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
8681da177e4SLinus Torvalds 			return e;
8691da177e4SLinus Torvalds 	}
8701da177e4SLinus Torvalds 
871b57c1a56SJohan Hedberg 	return NULL;
872b57c1a56SJohan Hedberg }
873b57c1a56SJohan Hedberg 
874561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
875561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
876561aafbcSJohan Hedberg {
87730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
878561aafbcSJohan Hedberg 	struct inquiry_entry *e;
879561aafbcSJohan Hedberg 
8806ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
881561aafbcSJohan Hedberg 
882561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
883561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
884561aafbcSJohan Hedberg 			return e;
885561aafbcSJohan Hedberg 	}
886561aafbcSJohan Hedberg 
887561aafbcSJohan Hedberg 	return NULL;
888561aafbcSJohan Hedberg }
889561aafbcSJohan Hedberg 
89030dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
89130dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
89230dc78e1SJohan Hedberg 						       int state)
89330dc78e1SJohan Hedberg {
89430dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
89530dc78e1SJohan Hedberg 	struct inquiry_entry *e;
89630dc78e1SJohan Hedberg 
8976ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
89830dc78e1SJohan Hedberg 
89930dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
90030dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
90130dc78e1SJohan Hedberg 			return e;
90230dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
90330dc78e1SJohan Hedberg 			return e;
90430dc78e1SJohan Hedberg 	}
90530dc78e1SJohan Hedberg 
90630dc78e1SJohan Hedberg 	return NULL;
90730dc78e1SJohan Hedberg }
90830dc78e1SJohan Hedberg 
909a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
910a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
911a3d4e20aSJohan Hedberg {
912a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
913a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
914a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
915a3d4e20aSJohan Hedberg 
916a3d4e20aSJohan Hedberg 	list_del(&ie->list);
917a3d4e20aSJohan Hedberg 
918a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
919a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
920a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
921a3d4e20aSJohan Hedberg 			break;
922a3d4e20aSJohan Hedberg 		pos = &p->list;
923a3d4e20aSJohan Hedberg 	}
924a3d4e20aSJohan Hedberg 
925a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
926a3d4e20aSJohan Hedberg }
927a3d4e20aSJohan Hedberg 
9283175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
929388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
9301da177e4SLinus Torvalds {
93130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
93270f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
9331da177e4SLinus Torvalds 
9346ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
9351da177e4SLinus Torvalds 
9362b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
9372b2fec4dSSzymon Janc 
938388fc8faSJohan Hedberg 	if (ssp)
939388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
940388fc8faSJohan Hedberg 
94170f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
942a3d4e20aSJohan Hedberg 	if (ie) {
943388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
944388fc8faSJohan Hedberg 			*ssp = true;
945388fc8faSJohan Hedberg 
946a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
947a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
948a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
949a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
950a3d4e20aSJohan Hedberg 		}
951a3d4e20aSJohan Hedberg 
952561aafbcSJohan Hedberg 		goto update;
953a3d4e20aSJohan Hedberg 	}
954561aafbcSJohan Hedberg 
9551da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
95670f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
95770f23020SAndrei Emeltchenko 	if (!ie)
9583175405bSJohan Hedberg 		return false;
95970f23020SAndrei Emeltchenko 
960561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
961561aafbcSJohan Hedberg 
962561aafbcSJohan Hedberg 	if (name_known) {
963561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
964561aafbcSJohan Hedberg 	} else {
965561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
966561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
967561aafbcSJohan Hedberg 	}
968561aafbcSJohan Hedberg 
969561aafbcSJohan Hedberg update:
970561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
971561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
972561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
973561aafbcSJohan Hedberg 		list_del(&ie->list);
9741da177e4SLinus Torvalds 	}
9751da177e4SLinus Torvalds 
97670f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
97770f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
9781da177e4SLinus Torvalds 	cache->timestamp = jiffies;
9793175405bSJohan Hedberg 
9803175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
9813175405bSJohan Hedberg 		return false;
9823175405bSJohan Hedberg 
9833175405bSJohan Hedberg 	return true;
9841da177e4SLinus Torvalds }
9851da177e4SLinus Torvalds 
9861da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
9871da177e4SLinus Torvalds {
98830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
9891da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
9901da177e4SLinus Torvalds 	struct inquiry_entry *e;
9911da177e4SLinus Torvalds 	int copied = 0;
9921da177e4SLinus Torvalds 
993561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
9941da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
995b57c1a56SJohan Hedberg 
996b57c1a56SJohan Hedberg 		if (copied >= num)
997b57c1a56SJohan Hedberg 			break;
998b57c1a56SJohan Hedberg 
9991da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
10001da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
10011da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
10021da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
10031da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
10041da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
1005b57c1a56SJohan Hedberg 
10061da177e4SLinus Torvalds 		info++;
1007b57c1a56SJohan Hedberg 		copied++;
10081da177e4SLinus Torvalds 	}
10091da177e4SLinus Torvalds 
10101da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
10111da177e4SLinus Torvalds 	return copied;
10121da177e4SLinus Torvalds }
10131da177e4SLinus Torvalds 
101442c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
10151da177e4SLinus Torvalds {
10161da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
101742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
10181da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
10191da177e4SLinus Torvalds 
10201da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
10211da177e4SLinus Torvalds 
10221da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
10231da177e4SLinus Torvalds 		return;
10241da177e4SLinus Torvalds 
10251da177e4SLinus Torvalds 	/* Start Inquiry */
10261da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
10271da177e4SLinus Torvalds 	cp.length  = ir->length;
10281da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
102942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
10301da177e4SLinus Torvalds }
10311da177e4SLinus Torvalds 
10323e13fa1eSAndre Guedes static int wait_inquiry(void *word)
10333e13fa1eSAndre Guedes {
10343e13fa1eSAndre Guedes 	schedule();
10353e13fa1eSAndre Guedes 	return signal_pending(current);
10363e13fa1eSAndre Guedes }
10373e13fa1eSAndre Guedes 
10381da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
10391da177e4SLinus Torvalds {
10401da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
10411da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
10421da177e4SLinus Torvalds 	struct hci_dev *hdev;
10431da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
10441da177e4SLinus Torvalds 	long timeo;
10451da177e4SLinus Torvalds 	__u8 *buf;
10461da177e4SLinus Torvalds 
10471da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
10481da177e4SLinus Torvalds 		return -EFAULT;
10491da177e4SLinus Torvalds 
10505a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
10515a08ecceSAndrei Emeltchenko 	if (!hdev)
10521da177e4SLinus Torvalds 		return -ENODEV;
10531da177e4SLinus Torvalds 
10540736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
10550736cfa8SMarcel Holtmann 		err = -EBUSY;
10560736cfa8SMarcel Holtmann 		goto done;
10570736cfa8SMarcel Holtmann 	}
10580736cfa8SMarcel Holtmann 
10595b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
10605b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
10615b69bef5SMarcel Holtmann 		goto done;
10625b69bef5SMarcel Holtmann 	}
10635b69bef5SMarcel Holtmann 
106456f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
106556f87901SJohan Hedberg 		err = -EOPNOTSUPP;
106656f87901SJohan Hedberg 		goto done;
106756f87901SJohan Hedberg 	}
106856f87901SJohan Hedberg 
106909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
10701da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1071a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
10721f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
10731da177e4SLinus Torvalds 		do_inquiry = 1;
10741da177e4SLinus Torvalds 	}
107509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
10761da177e4SLinus Torvalds 
107704837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
107870f23020SAndrei Emeltchenko 
107970f23020SAndrei Emeltchenko 	if (do_inquiry) {
108001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
108101178cd4SJohan Hedberg 				   timeo);
108270f23020SAndrei Emeltchenko 		if (err < 0)
10831da177e4SLinus Torvalds 			goto done;
10843e13fa1eSAndre Guedes 
10853e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
10863e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
10873e13fa1eSAndre Guedes 		 */
10883e13fa1eSAndre Guedes 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry,
10893e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
10903e13fa1eSAndre Guedes 			return -EINTR;
109170f23020SAndrei Emeltchenko 	}
10921da177e4SLinus Torvalds 
10938fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
10948fc9ced3SGustavo Padovan 	 * 255 entries
10958fc9ced3SGustavo Padovan 	 */
10961da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
10971da177e4SLinus Torvalds 
10981da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
10991da177e4SLinus Torvalds 	 * copy it to the user space.
11001da177e4SLinus Torvalds 	 */
110170f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
110270f23020SAndrei Emeltchenko 	if (!buf) {
11031da177e4SLinus Torvalds 		err = -ENOMEM;
11041da177e4SLinus Torvalds 		goto done;
11051da177e4SLinus Torvalds 	}
11061da177e4SLinus Torvalds 
110709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
11081da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
110909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
11101da177e4SLinus Torvalds 
11111da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
11121da177e4SLinus Torvalds 
11131da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
11141da177e4SLinus Torvalds 		ptr += sizeof(ir);
11151da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
11161da177e4SLinus Torvalds 				 ir.num_rsp))
11171da177e4SLinus Torvalds 			err = -EFAULT;
11181da177e4SLinus Torvalds 	} else
11191da177e4SLinus Torvalds 		err = -EFAULT;
11201da177e4SLinus Torvalds 
11211da177e4SLinus Torvalds 	kfree(buf);
11221da177e4SLinus Torvalds 
11231da177e4SLinus Torvalds done:
11241da177e4SLinus Torvalds 	hci_dev_put(hdev);
11251da177e4SLinus Torvalds 	return err;
11261da177e4SLinus Torvalds }
11271da177e4SLinus Torvalds 
1128cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
11291da177e4SLinus Torvalds {
11301da177e4SLinus Torvalds 	int ret = 0;
11311da177e4SLinus Torvalds 
11321da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
11331da177e4SLinus Torvalds 
11341da177e4SLinus Torvalds 	hci_req_lock(hdev);
11351da177e4SLinus Torvalds 
113694324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
113794324962SJohan Hovold 		ret = -ENODEV;
113894324962SJohan Hovold 		goto done;
113994324962SJohan Hovold 	}
114094324962SJohan Hovold 
1141a5c8f270SMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
1142a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1143a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1144bf543036SJohan Hedberg 		 */
1145a5c8f270SMarcel Holtmann 		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
1146611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1147611b30f7SMarcel Holtmann 			goto done;
1148611b30f7SMarcel Holtmann 		}
1149611b30f7SMarcel Holtmann 
1150a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
1151a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
1152a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1153a5c8f270SMarcel Holtmann 		 * or not.
1154a5c8f270SMarcel Holtmann 		 *
1155a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1156a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1157a5c8f270SMarcel Holtmann 		 */
1158a5c8f270SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR &&
1159a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1160a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1161a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1162a5c8f270SMarcel Holtmann 			goto done;
1163a5c8f270SMarcel Holtmann 		}
1164a5c8f270SMarcel Holtmann 	}
1165a5c8f270SMarcel Holtmann 
11661da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
11671da177e4SLinus Torvalds 		ret = -EALREADY;
11681da177e4SLinus Torvalds 		goto done;
11691da177e4SLinus Torvalds 	}
11701da177e4SLinus Torvalds 
11711da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
11721da177e4SLinus Torvalds 		ret = -EIO;
11731da177e4SLinus Torvalds 		goto done;
11741da177e4SLinus Torvalds 	}
11751da177e4SLinus Torvalds 
11761da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
11771da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1178f41c70c4SMarcel Holtmann 
1179f41c70c4SMarcel Holtmann 	if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
1180f41c70c4SMarcel Holtmann 		ret = hdev->setup(hdev);
1181f41c70c4SMarcel Holtmann 
1182f41c70c4SMarcel Holtmann 	if (!ret) {
1183f41c70c4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1184f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
1185f41c70c4SMarcel Holtmann 
11860736cfa8SMarcel Holtmann 		if (!test_bit(HCI_RAW, &hdev->flags) &&
11870736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
11882177bab5SJohan Hedberg 			ret = __hci_init(hdev);
11891da177e4SLinus Torvalds 	}
11901da177e4SLinus Torvalds 
1191f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1192f41c70c4SMarcel Holtmann 
11931da177e4SLinus Torvalds 	if (!ret) {
11941da177e4SLinus Torvalds 		hci_dev_hold(hdev);
11951da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
11961da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
1197bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
11980736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
11991514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
120009fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1201744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
120209fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
120356e5cb86SJohan Hedberg 		}
12041da177e4SLinus Torvalds 	} else {
12051da177e4SLinus Torvalds 		/* Init failed, cleanup */
12063eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1207c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1208b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
12091da177e4SLinus Torvalds 
12101da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
12111da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
12121da177e4SLinus Torvalds 
12131da177e4SLinus Torvalds 		if (hdev->flush)
12141da177e4SLinus Torvalds 			hdev->flush(hdev);
12151da177e4SLinus Torvalds 
12161da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
12171da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
12181da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
12191da177e4SLinus Torvalds 		}
12201da177e4SLinus Torvalds 
12211da177e4SLinus Torvalds 		hdev->close(hdev);
12221da177e4SLinus Torvalds 		hdev->flags = 0;
12231da177e4SLinus Torvalds 	}
12241da177e4SLinus Torvalds 
12251da177e4SLinus Torvalds done:
12261da177e4SLinus Torvalds 	hci_req_unlock(hdev);
12271da177e4SLinus Torvalds 	return ret;
12281da177e4SLinus Torvalds }
12291da177e4SLinus Torvalds 
1230cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
1231cbed0ca1SJohan Hedberg 
1232cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
1233cbed0ca1SJohan Hedberg {
1234cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
1235cbed0ca1SJohan Hedberg 	int err;
1236cbed0ca1SJohan Hedberg 
1237cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
1238cbed0ca1SJohan Hedberg 	if (!hdev)
1239cbed0ca1SJohan Hedberg 		return -ENODEV;
1240cbed0ca1SJohan Hedberg 
1241e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
1242e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
1243e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
1244e1d08f40SJohan Hedberg 	 * completed.
1245e1d08f40SJohan Hedberg 	 */
1246e1d08f40SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1247e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
1248e1d08f40SJohan Hedberg 
1249a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
1250a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
1251a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
1252a5c8f270SMarcel Holtmann 	 */
1253e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
1254e1d08f40SJohan Hedberg 
1255cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
1256cbed0ca1SJohan Hedberg 
1257cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
1258cbed0ca1SJohan Hedberg 
1259cbed0ca1SJohan Hedberg 	return err;
1260cbed0ca1SJohan Hedberg }
1261cbed0ca1SJohan Hedberg 
12621da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
12631da177e4SLinus Torvalds {
12641da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
12651da177e4SLinus Torvalds 
126678c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
126778c04c0bSVinicius Costa Gomes 
12681da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
12691da177e4SLinus Torvalds 	hci_req_lock(hdev);
12701da177e4SLinus Torvalds 
12711da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
1272b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
12731da177e4SLinus Torvalds 		hci_req_unlock(hdev);
12741da177e4SLinus Torvalds 		return 0;
12751da177e4SLinus Torvalds 	}
12761da177e4SLinus Torvalds 
12773eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
12783eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1279b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
12801da177e4SLinus Torvalds 
128116ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
1282e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
128316ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
12845e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
1285310a3d48SMarcel Holtmann 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
128616ab91abSJohan Hedberg 	}
128716ab91abSJohan Hedberg 
1288a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
12897d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
12907d78525dSJohan Hedberg 
12917ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
12927ba8b4beSAndre Guedes 
129309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
12941f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
12951da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
129609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
12971da177e4SLinus Torvalds 
12981da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
12991da177e4SLinus Torvalds 
13001da177e4SLinus Torvalds 	if (hdev->flush)
13011da177e4SLinus Torvalds 		hdev->flush(hdev);
13021da177e4SLinus Torvalds 
13031da177e4SLinus Torvalds 	/* Reset device */
13041da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
13051da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
13068af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
13073a6afbd2SMarcel Holtmann 	    !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
1308a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
13091da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
131001178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
13111da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
13121da177e4SLinus Torvalds 	}
13131da177e4SLinus Torvalds 
1314c347b765SGustavo F. Padovan 	/* flush cmd  work */
1315c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
13161da177e4SLinus Torvalds 
13171da177e4SLinus Torvalds 	/* Drop queues */
13181da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
13191da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
13201da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
13211da177e4SLinus Torvalds 
13221da177e4SLinus Torvalds 	/* Drop last sent command */
13231da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
1324b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
13251da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
13261da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
13271da177e4SLinus Torvalds 	}
13281da177e4SLinus Torvalds 
1329b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
1330b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
1331b6ddb638SJohan Hedberg 
13321da177e4SLinus Torvalds 	/* After this point our queues are empty
13331da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
13341da177e4SLinus Torvalds 	hdev->close(hdev);
13351da177e4SLinus Torvalds 
133635b973c9SJohan Hedberg 	/* Clear flags */
133735b973c9SJohan Hedberg 	hdev->flags = 0;
133835b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
133935b973c9SJohan Hedberg 
134093c311a0SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
134193c311a0SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR) {
134209fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1343744cf19eSJohan Hedberg 			mgmt_powered(hdev, 0);
134409fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
13458ee56540SMarcel Holtmann 		}
134693c311a0SMarcel Holtmann 	}
13475add6af8SJohan Hedberg 
1348ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1349536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
1350ced5c338SAndrei Emeltchenko 
1351e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
135209b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
1353e59fda8dSJohan Hedberg 
13541da177e4SLinus Torvalds 	hci_req_unlock(hdev);
13551da177e4SLinus Torvalds 
13561da177e4SLinus Torvalds 	hci_dev_put(hdev);
13571da177e4SLinus Torvalds 	return 0;
13581da177e4SLinus Torvalds }
13591da177e4SLinus Torvalds 
13601da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
13611da177e4SLinus Torvalds {
13621da177e4SLinus Torvalds 	struct hci_dev *hdev;
13631da177e4SLinus Torvalds 	int err;
13641da177e4SLinus Torvalds 
136570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
136670f23020SAndrei Emeltchenko 	if (!hdev)
13671da177e4SLinus Torvalds 		return -ENODEV;
13688ee56540SMarcel Holtmann 
13690736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
13700736cfa8SMarcel Holtmann 		err = -EBUSY;
13710736cfa8SMarcel Holtmann 		goto done;
13720736cfa8SMarcel Holtmann 	}
13730736cfa8SMarcel Holtmann 
13748ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
13758ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
13768ee56540SMarcel Holtmann 
13771da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
13788ee56540SMarcel Holtmann 
13790736cfa8SMarcel Holtmann done:
13801da177e4SLinus Torvalds 	hci_dev_put(hdev);
13811da177e4SLinus Torvalds 	return err;
13821da177e4SLinus Torvalds }
13831da177e4SLinus Torvalds 
13841da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
13851da177e4SLinus Torvalds {
13861da177e4SLinus Torvalds 	struct hci_dev *hdev;
13871da177e4SLinus Torvalds 	int ret = 0;
13881da177e4SLinus Torvalds 
138970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
139070f23020SAndrei Emeltchenko 	if (!hdev)
13911da177e4SLinus Torvalds 		return -ENODEV;
13921da177e4SLinus Torvalds 
13931da177e4SLinus Torvalds 	hci_req_lock(hdev);
13941da177e4SLinus Torvalds 
1395808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
1396808a049eSMarcel Holtmann 		ret = -ENETDOWN;
13971da177e4SLinus Torvalds 		goto done;
1398808a049eSMarcel Holtmann 	}
13991da177e4SLinus Torvalds 
14000736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
14010736cfa8SMarcel Holtmann 		ret = -EBUSY;
14020736cfa8SMarcel Holtmann 		goto done;
14030736cfa8SMarcel Holtmann 	}
14040736cfa8SMarcel Holtmann 
14051da177e4SLinus Torvalds 	/* Drop queues */
14061da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
14071da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
14081da177e4SLinus Torvalds 
140909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
14101f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
14111da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
141209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
14131da177e4SLinus Torvalds 
14141da177e4SLinus Torvalds 	if (hdev->flush)
14151da177e4SLinus Torvalds 		hdev->flush(hdev);
14161da177e4SLinus Torvalds 
14171da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
14186ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
14191da177e4SLinus Torvalds 
14201da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
142101178cd4SJohan Hedberg 		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
14221da177e4SLinus Torvalds 
14231da177e4SLinus Torvalds done:
14241da177e4SLinus Torvalds 	hci_req_unlock(hdev);
14251da177e4SLinus Torvalds 	hci_dev_put(hdev);
14261da177e4SLinus Torvalds 	return ret;
14271da177e4SLinus Torvalds }
14281da177e4SLinus Torvalds 
14291da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
14301da177e4SLinus Torvalds {
14311da177e4SLinus Torvalds 	struct hci_dev *hdev;
14321da177e4SLinus Torvalds 	int ret = 0;
14331da177e4SLinus Torvalds 
143470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
143570f23020SAndrei Emeltchenko 	if (!hdev)
14361da177e4SLinus Torvalds 		return -ENODEV;
14371da177e4SLinus Torvalds 
14380736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
14390736cfa8SMarcel Holtmann 		ret = -EBUSY;
14400736cfa8SMarcel Holtmann 		goto done;
14410736cfa8SMarcel Holtmann 	}
14420736cfa8SMarcel Holtmann 
14431da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
14441da177e4SLinus Torvalds 
14450736cfa8SMarcel Holtmann done:
14461da177e4SLinus Torvalds 	hci_dev_put(hdev);
14471da177e4SLinus Torvalds 	return ret;
14481da177e4SLinus Torvalds }
14491da177e4SLinus Torvalds 
14501da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
14511da177e4SLinus Torvalds {
14521da177e4SLinus Torvalds 	struct hci_dev *hdev;
14531da177e4SLinus Torvalds 	struct hci_dev_req dr;
14541da177e4SLinus Torvalds 	int err = 0;
14551da177e4SLinus Torvalds 
14561da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
14571da177e4SLinus Torvalds 		return -EFAULT;
14581da177e4SLinus Torvalds 
145970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
146070f23020SAndrei Emeltchenko 	if (!hdev)
14611da177e4SLinus Torvalds 		return -ENODEV;
14621da177e4SLinus Torvalds 
14630736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
14640736cfa8SMarcel Holtmann 		err = -EBUSY;
14650736cfa8SMarcel Holtmann 		goto done;
14660736cfa8SMarcel Holtmann 	}
14670736cfa8SMarcel Holtmann 
14685b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
14695b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
14705b69bef5SMarcel Holtmann 		goto done;
14715b69bef5SMarcel Holtmann 	}
14725b69bef5SMarcel Holtmann 
147356f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
147456f87901SJohan Hedberg 		err = -EOPNOTSUPP;
147556f87901SJohan Hedberg 		goto done;
147656f87901SJohan Hedberg 	}
147756f87901SJohan Hedberg 
14781da177e4SLinus Torvalds 	switch (cmd) {
14791da177e4SLinus Torvalds 	case HCISETAUTH:
148001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
14815f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
14821da177e4SLinus Torvalds 		break;
14831da177e4SLinus Torvalds 
14841da177e4SLinus Torvalds 	case HCISETENCRYPT:
14851da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
14861da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
14871da177e4SLinus Torvalds 			break;
14881da177e4SLinus Torvalds 		}
14891da177e4SLinus Torvalds 
14901da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
14911da177e4SLinus Torvalds 			/* Auth must be enabled first */
149201178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
14935f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
14941da177e4SLinus Torvalds 			if (err)
14951da177e4SLinus Torvalds 				break;
14961da177e4SLinus Torvalds 		}
14971da177e4SLinus Torvalds 
149801178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
14995f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15001da177e4SLinus Torvalds 		break;
15011da177e4SLinus Torvalds 
15021da177e4SLinus Torvalds 	case HCISETSCAN:
150301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
15045f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15051da177e4SLinus Torvalds 		break;
15061da177e4SLinus Torvalds 
15071da177e4SLinus Torvalds 	case HCISETLINKPOL:
150801178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
15095f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15101da177e4SLinus Torvalds 		break;
15111da177e4SLinus Torvalds 
15121da177e4SLinus Torvalds 	case HCISETLINKMODE:
1513e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
1514e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
1515e4e8e37cSMarcel Holtmann 		break;
1516e4e8e37cSMarcel Holtmann 
1517e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
1518e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
15191da177e4SLinus Torvalds 		break;
15201da177e4SLinus Torvalds 
15211da177e4SLinus Torvalds 	case HCISETACLMTU:
15221da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
15231da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
15241da177e4SLinus Torvalds 		break;
15251da177e4SLinus Torvalds 
15261da177e4SLinus Torvalds 	case HCISETSCOMTU:
15271da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
15281da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
15291da177e4SLinus Torvalds 		break;
15301da177e4SLinus Torvalds 
15311da177e4SLinus Torvalds 	default:
15321da177e4SLinus Torvalds 		err = -EINVAL;
15331da177e4SLinus Torvalds 		break;
15341da177e4SLinus Torvalds 	}
1535e4e8e37cSMarcel Holtmann 
15360736cfa8SMarcel Holtmann done:
15371da177e4SLinus Torvalds 	hci_dev_put(hdev);
15381da177e4SLinus Torvalds 	return err;
15391da177e4SLinus Torvalds }
15401da177e4SLinus Torvalds 
15411da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
15421da177e4SLinus Torvalds {
15438035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
15441da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
15451da177e4SLinus Torvalds 	struct hci_dev_req *dr;
15461da177e4SLinus Torvalds 	int n = 0, size, err;
15471da177e4SLinus Torvalds 	__u16 dev_num;
15481da177e4SLinus Torvalds 
15491da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
15501da177e4SLinus Torvalds 		return -EFAULT;
15511da177e4SLinus Torvalds 
15521da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
15531da177e4SLinus Torvalds 		return -EINVAL;
15541da177e4SLinus Torvalds 
15551da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
15561da177e4SLinus Torvalds 
155770f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
155870f23020SAndrei Emeltchenko 	if (!dl)
15591da177e4SLinus Torvalds 		return -ENOMEM;
15601da177e4SLinus Torvalds 
15611da177e4SLinus Torvalds 	dr = dl->dev_req;
15621da177e4SLinus Torvalds 
1563f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
15648035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
1565a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1566e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
1567c542a06cSJohan Hedberg 
1568a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1569a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1570c542a06cSJohan Hedberg 
15711da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
15721da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
1573c542a06cSJohan Hedberg 
15741da177e4SLinus Torvalds 		if (++n >= dev_num)
15751da177e4SLinus Torvalds 			break;
15761da177e4SLinus Torvalds 	}
1577f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
15781da177e4SLinus Torvalds 
15791da177e4SLinus Torvalds 	dl->dev_num = n;
15801da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
15811da177e4SLinus Torvalds 
15821da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
15831da177e4SLinus Torvalds 	kfree(dl);
15841da177e4SLinus Torvalds 
15851da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
15861da177e4SLinus Torvalds }
15871da177e4SLinus Torvalds 
15881da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
15891da177e4SLinus Torvalds {
15901da177e4SLinus Torvalds 	struct hci_dev *hdev;
15911da177e4SLinus Torvalds 	struct hci_dev_info di;
15921da177e4SLinus Torvalds 	int err = 0;
15931da177e4SLinus Torvalds 
15941da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
15951da177e4SLinus Torvalds 		return -EFAULT;
15961da177e4SLinus Torvalds 
159770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
159870f23020SAndrei Emeltchenko 	if (!hdev)
15991da177e4SLinus Torvalds 		return -ENODEV;
16001da177e4SLinus Torvalds 
1601a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
16023243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1603ab81cbf9SJohan Hedberg 
1604a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1605a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1606c542a06cSJohan Hedberg 
16071da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
16081da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
160960f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
16101da177e4SLinus Torvalds 	di.flags    = hdev->flags;
16111da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
1612572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
16131da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
16141da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
16151da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
16161da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
1617572c7f84SJohan Hedberg 	} else {
1618572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
1619572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
1620572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
1621572c7f84SJohan Hedberg 		di.sco_pkts = 0;
1622572c7f84SJohan Hedberg 	}
16231da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
16241da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
16251da177e4SLinus Torvalds 
16261da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
16271da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
16281da177e4SLinus Torvalds 
16291da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
16301da177e4SLinus Torvalds 		err = -EFAULT;
16311da177e4SLinus Torvalds 
16321da177e4SLinus Torvalds 	hci_dev_put(hdev);
16331da177e4SLinus Torvalds 
16341da177e4SLinus Torvalds 	return err;
16351da177e4SLinus Torvalds }
16361da177e4SLinus Torvalds 
16371da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
16381da177e4SLinus Torvalds 
1639611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1640611b30f7SMarcel Holtmann {
1641611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1642611b30f7SMarcel Holtmann 
1643611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1644611b30f7SMarcel Holtmann 
16450736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
16460736cfa8SMarcel Holtmann 		return -EBUSY;
16470736cfa8SMarcel Holtmann 
16485e130367SJohan Hedberg 	if (blocked) {
16495e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
1650bf543036SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags))
1651611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
16525e130367SJohan Hedberg 	} else {
16535e130367SJohan Hedberg 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
16545e130367SJohan Hedberg 	}
1655611b30f7SMarcel Holtmann 
1656611b30f7SMarcel Holtmann 	return 0;
1657611b30f7SMarcel Holtmann }
1658611b30f7SMarcel Holtmann 
1659611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1660611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1661611b30f7SMarcel Holtmann };
1662611b30f7SMarcel Holtmann 
1663ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1664ab81cbf9SJohan Hedberg {
1665ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
166696570ffcSJohan Hedberg 	int err;
1667ab81cbf9SJohan Hedberg 
1668ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1669ab81cbf9SJohan Hedberg 
1670cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
167196570ffcSJohan Hedberg 	if (err < 0) {
167296570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
1673ab81cbf9SJohan Hedberg 		return;
167496570ffcSJohan Hedberg 	}
1675ab81cbf9SJohan Hedberg 
1676a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
1677a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
1678a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
1679a5c8f270SMarcel Holtmann 	 */
1680a5c8f270SMarcel Holtmann 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
1681a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
1682a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1683a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
1684bf543036SJohan Hedberg 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
1685bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
1686bf543036SJohan Hedberg 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
168719202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
168819202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
1689bf543036SJohan Hedberg 	}
1690ab81cbf9SJohan Hedberg 
1691a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1692744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1693ab81cbf9SJohan Hedberg }
1694ab81cbf9SJohan Hedberg 
1695ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1696ab81cbf9SJohan Hedberg {
16973243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
16983243553fSJohan Hedberg 					    power_off.work);
1699ab81cbf9SJohan Hedberg 
1700ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1701ab81cbf9SJohan Hedberg 
17028ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1703ab81cbf9SJohan Hedberg }
1704ab81cbf9SJohan Hedberg 
170516ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
170616ab91abSJohan Hedberg {
170716ab91abSJohan Hedberg 	struct hci_dev *hdev;
1708b1e73124SMarcel Holtmann 	struct hci_request req;
170916ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
171016ab91abSJohan Hedberg 
171116ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
171216ab91abSJohan Hedberg 
171316ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
171416ab91abSJohan Hedberg 
171509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
171616ab91abSJohan Hedberg 
1717b1e73124SMarcel Holtmann 	hci_req_init(&req, hdev);
1718b1e73124SMarcel Holtmann 	hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
1719b1e73124SMarcel Holtmann 	hci_req_run(&req, NULL);
172016ab91abSJohan Hedberg 
1721310a3d48SMarcel Holtmann 	/* When discoverable timeout triggers, then just make sure
1722310a3d48SMarcel Holtmann 	 * the limited discoverable flag is cleared. Even in the case
1723310a3d48SMarcel Holtmann 	 * of a timeout triggered from general discoverable, it is
1724310a3d48SMarcel Holtmann 	 * safe to unconditionally clear the flag.
1725310a3d48SMarcel Holtmann 	 */
1726310a3d48SMarcel Holtmann 	clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
1727310a3d48SMarcel Holtmann 
172816ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
172916ab91abSJohan Hedberg 
173009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
173116ab91abSJohan Hedberg }
173216ab91abSJohan Hedberg 
17332aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
17342aeb9a1aSJohan Hedberg {
17354821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
17362aeb9a1aSJohan Hedberg 
17374821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
17384821002cSJohan Hedberg 		list_del(&uuid->list);
17392aeb9a1aSJohan Hedberg 		kfree(uuid);
17402aeb9a1aSJohan Hedberg 	}
17412aeb9a1aSJohan Hedberg 
17422aeb9a1aSJohan Hedberg 	return 0;
17432aeb9a1aSJohan Hedberg }
17442aeb9a1aSJohan Hedberg 
174555ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
174655ed8ca1SJohan Hedberg {
174755ed8ca1SJohan Hedberg 	struct list_head *p, *n;
174855ed8ca1SJohan Hedberg 
174955ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
175055ed8ca1SJohan Hedberg 		struct link_key *key;
175155ed8ca1SJohan Hedberg 
175255ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
175355ed8ca1SJohan Hedberg 
175455ed8ca1SJohan Hedberg 		list_del(p);
175555ed8ca1SJohan Hedberg 		kfree(key);
175655ed8ca1SJohan Hedberg 	}
175755ed8ca1SJohan Hedberg 
175855ed8ca1SJohan Hedberg 	return 0;
175955ed8ca1SJohan Hedberg }
176055ed8ca1SJohan Hedberg 
1761b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1762b899efafSVinicius Costa Gomes {
1763b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1764b899efafSVinicius Costa Gomes 
1765b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1766b899efafSVinicius Costa Gomes 		list_del(&k->list);
1767b899efafSVinicius Costa Gomes 		kfree(k);
1768b899efafSVinicius Costa Gomes 	}
1769b899efafSVinicius Costa Gomes 
1770b899efafSVinicius Costa Gomes 	return 0;
1771b899efafSVinicius Costa Gomes }
1772b899efafSVinicius Costa Gomes 
177355ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
177455ed8ca1SJohan Hedberg {
177555ed8ca1SJohan Hedberg 	struct link_key *k;
177655ed8ca1SJohan Hedberg 
17778035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
177855ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
177955ed8ca1SJohan Hedberg 			return k;
178055ed8ca1SJohan Hedberg 
178155ed8ca1SJohan Hedberg 	return NULL;
178255ed8ca1SJohan Hedberg }
178355ed8ca1SJohan Hedberg 
1784745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1785d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1786d25e28abSJohan Hedberg {
1787d25e28abSJohan Hedberg 	/* Legacy key */
1788d25e28abSJohan Hedberg 	if (key_type < 0x03)
1789745c0ce3SVishal Agarwal 		return true;
1790d25e28abSJohan Hedberg 
1791d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1792d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1793745c0ce3SVishal Agarwal 		return false;
1794d25e28abSJohan Hedberg 
1795d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1796d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1797745c0ce3SVishal Agarwal 		return false;
1798d25e28abSJohan Hedberg 
1799d25e28abSJohan Hedberg 	/* Security mode 3 case */
1800d25e28abSJohan Hedberg 	if (!conn)
1801745c0ce3SVishal Agarwal 		return true;
1802d25e28abSJohan Hedberg 
1803d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1804d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1805745c0ce3SVishal Agarwal 		return true;
1806d25e28abSJohan Hedberg 
1807d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1808d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1809745c0ce3SVishal Agarwal 		return true;
1810d25e28abSJohan Hedberg 
1811d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1812d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1813745c0ce3SVishal Agarwal 		return true;
1814d25e28abSJohan Hedberg 
1815d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1816d25e28abSJohan Hedberg 	 * persistently */
1817745c0ce3SVishal Agarwal 	return false;
1818d25e28abSJohan Hedberg }
1819d25e28abSJohan Hedberg 
1820c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
182175d262c2SVinicius Costa Gomes {
1822c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
182375d262c2SVinicius Costa Gomes 
1824c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1825c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1826c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
182775d262c2SVinicius Costa Gomes 			continue;
182875d262c2SVinicius Costa Gomes 
182975d262c2SVinicius Costa Gomes 		return k;
183075d262c2SVinicius Costa Gomes 	}
183175d262c2SVinicius Costa Gomes 
183275d262c2SVinicius Costa Gomes 	return NULL;
183375d262c2SVinicius Costa Gomes }
183475d262c2SVinicius Costa Gomes 
1835c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1836c9839a11SVinicius Costa Gomes 				     u8 addr_type)
183775d262c2SVinicius Costa Gomes {
1838c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
183975d262c2SVinicius Costa Gomes 
1840c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1841c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1842c9839a11SVinicius Costa Gomes 		    bacmp(bdaddr, &k->bdaddr) == 0)
184375d262c2SVinicius Costa Gomes 			return k;
184475d262c2SVinicius Costa Gomes 
184575d262c2SVinicius Costa Gomes 	return NULL;
184675d262c2SVinicius Costa Gomes }
184775d262c2SVinicius Costa Gomes 
1848d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1849d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
185055ed8ca1SJohan Hedberg {
185155ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1852745c0ce3SVishal Agarwal 	u8 old_key_type;
1853745c0ce3SVishal Agarwal 	bool persistent;
185455ed8ca1SJohan Hedberg 
185555ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
185655ed8ca1SJohan Hedberg 	if (old_key) {
185755ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
185855ed8ca1SJohan Hedberg 		key = old_key;
185955ed8ca1SJohan Hedberg 	} else {
186012adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
186155ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
186255ed8ca1SJohan Hedberg 		if (!key)
186355ed8ca1SJohan Hedberg 			return -ENOMEM;
186455ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
186555ed8ca1SJohan Hedberg 	}
186655ed8ca1SJohan Hedberg 
18676ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
186855ed8ca1SJohan Hedberg 
1869d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1870d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1871d25e28abSJohan Hedberg 	 * previous key */
1872d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1873a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1874d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1875655fe6ecSJohan Hedberg 		if (conn)
1876655fe6ecSJohan Hedberg 			conn->key_type = type;
1877655fe6ecSJohan Hedberg 	}
1878d25e28abSJohan Hedberg 
187955ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
18809b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
188155ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
188255ed8ca1SJohan Hedberg 
1883b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
188455ed8ca1SJohan Hedberg 		key->type = old_key_type;
18854748fed2SJohan Hedberg 	else
18864748fed2SJohan Hedberg 		key->type = type;
18874748fed2SJohan Hedberg 
18884df378a1SJohan Hedberg 	if (!new_key)
18894df378a1SJohan Hedberg 		return 0;
18904df378a1SJohan Hedberg 
18914df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
18924df378a1SJohan Hedberg 
1893744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
18944df378a1SJohan Hedberg 
18956ec5bcadSVishal Agarwal 	if (conn)
18966ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
189755ed8ca1SJohan Hedberg 
189855ed8ca1SJohan Hedberg 	return 0;
189955ed8ca1SJohan Hedberg }
190055ed8ca1SJohan Hedberg 
1901c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
19029a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
190304124681SGustavo F. Padovan 		ediv, u8 rand[8])
190475d262c2SVinicius Costa Gomes {
1905c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
190675d262c2SVinicius Costa Gomes 
1907c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1908c9839a11SVinicius Costa Gomes 		return 0;
190975d262c2SVinicius Costa Gomes 
1910c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1911c9839a11SVinicius Costa Gomes 	if (old_key)
191275d262c2SVinicius Costa Gomes 		key = old_key;
1913c9839a11SVinicius Costa Gomes 	else {
1914c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
191575d262c2SVinicius Costa Gomes 		if (!key)
191675d262c2SVinicius Costa Gomes 			return -ENOMEM;
1917c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
191875d262c2SVinicius Costa Gomes 	}
191975d262c2SVinicius Costa Gomes 
192075d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1921c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1922c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1923c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1924c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1925c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1926c9839a11SVinicius Costa Gomes 	key->type = type;
1927c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
192875d262c2SVinicius Costa Gomes 
1929c9839a11SVinicius Costa Gomes 	if (!new_key)
1930c9839a11SVinicius Costa Gomes 		return 0;
193175d262c2SVinicius Costa Gomes 
1932261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1933261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1934261cc5aaSVinicius Costa Gomes 
193575d262c2SVinicius Costa Gomes 	return 0;
193675d262c2SVinicius Costa Gomes }
193775d262c2SVinicius Costa Gomes 
193855ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
193955ed8ca1SJohan Hedberg {
194055ed8ca1SJohan Hedberg 	struct link_key *key;
194155ed8ca1SJohan Hedberg 
194255ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
194355ed8ca1SJohan Hedberg 	if (!key)
194455ed8ca1SJohan Hedberg 		return -ENOENT;
194555ed8ca1SJohan Hedberg 
19466ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
194755ed8ca1SJohan Hedberg 
194855ed8ca1SJohan Hedberg 	list_del(&key->list);
194955ed8ca1SJohan Hedberg 	kfree(key);
195055ed8ca1SJohan Hedberg 
195155ed8ca1SJohan Hedberg 	return 0;
195255ed8ca1SJohan Hedberg }
195355ed8ca1SJohan Hedberg 
1954b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1955b899efafSVinicius Costa Gomes {
1956b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1957b899efafSVinicius Costa Gomes 
1958b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1959b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1960b899efafSVinicius Costa Gomes 			continue;
1961b899efafSVinicius Costa Gomes 
19626ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1963b899efafSVinicius Costa Gomes 
1964b899efafSVinicius Costa Gomes 		list_del(&k->list);
1965b899efafSVinicius Costa Gomes 		kfree(k);
1966b899efafSVinicius Costa Gomes 	}
1967b899efafSVinicius Costa Gomes 
1968b899efafSVinicius Costa Gomes 	return 0;
1969b899efafSVinicius Costa Gomes }
1970b899efafSVinicius Costa Gomes 
19716bd32326SVille Tervo /* HCI command timer function */
1972bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
19736bd32326SVille Tervo {
19746bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
19756bd32326SVille Tervo 
1976bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
1977bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
1978bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
1979bda4f23aSAndrei Emeltchenko 
1980bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
1981bda4f23aSAndrei Emeltchenko 	} else {
19826bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
1983bda4f23aSAndrei Emeltchenko 	}
1984bda4f23aSAndrei Emeltchenko 
19856bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1986c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
19876bd32326SVille Tervo }
19886bd32326SVille Tervo 
19892763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
19902763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
19912763eda6SSzymon Janc {
19922763eda6SSzymon Janc 	struct oob_data *data;
19932763eda6SSzymon Janc 
19942763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
19952763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
19962763eda6SSzymon Janc 			return data;
19972763eda6SSzymon Janc 
19982763eda6SSzymon Janc 	return NULL;
19992763eda6SSzymon Janc }
20002763eda6SSzymon Janc 
20012763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
20022763eda6SSzymon Janc {
20032763eda6SSzymon Janc 	struct oob_data *data;
20042763eda6SSzymon Janc 
20052763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
20062763eda6SSzymon Janc 	if (!data)
20072763eda6SSzymon Janc 		return -ENOENT;
20082763eda6SSzymon Janc 
20096ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
20102763eda6SSzymon Janc 
20112763eda6SSzymon Janc 	list_del(&data->list);
20122763eda6SSzymon Janc 	kfree(data);
20132763eda6SSzymon Janc 
20142763eda6SSzymon Janc 	return 0;
20152763eda6SSzymon Janc }
20162763eda6SSzymon Janc 
20172763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
20182763eda6SSzymon Janc {
20192763eda6SSzymon Janc 	struct oob_data *data, *n;
20202763eda6SSzymon Janc 
20212763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
20222763eda6SSzymon Janc 		list_del(&data->list);
20232763eda6SSzymon Janc 		kfree(data);
20242763eda6SSzymon Janc 	}
20252763eda6SSzymon Janc 
20262763eda6SSzymon Janc 	return 0;
20272763eda6SSzymon Janc }
20282763eda6SSzymon Janc 
20292763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
20302763eda6SSzymon Janc 			    u8 *randomizer)
20312763eda6SSzymon Janc {
20322763eda6SSzymon Janc 	struct oob_data *data;
20332763eda6SSzymon Janc 
20342763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
20352763eda6SSzymon Janc 
20362763eda6SSzymon Janc 	if (!data) {
20372763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
20382763eda6SSzymon Janc 		if (!data)
20392763eda6SSzymon Janc 			return -ENOMEM;
20402763eda6SSzymon Janc 
20412763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
20422763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
20432763eda6SSzymon Janc 	}
20442763eda6SSzymon Janc 
20452763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
20462763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
20472763eda6SSzymon Janc 
20486ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
20492763eda6SSzymon Janc 
20502763eda6SSzymon Janc 	return 0;
20512763eda6SSzymon Janc }
20522763eda6SSzymon Janc 
205304124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
2054b2a66aadSAntti Julku {
2055b2a66aadSAntti Julku 	struct bdaddr_list *b;
2056b2a66aadSAntti Julku 
20578035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
2058b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
2059b2a66aadSAntti Julku 			return b;
2060b2a66aadSAntti Julku 
2061b2a66aadSAntti Julku 	return NULL;
2062b2a66aadSAntti Julku }
2063b2a66aadSAntti Julku 
2064b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
2065b2a66aadSAntti Julku {
2066b2a66aadSAntti Julku 	struct list_head *p, *n;
2067b2a66aadSAntti Julku 
2068b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
2069b2a66aadSAntti Julku 		struct bdaddr_list *b;
2070b2a66aadSAntti Julku 
2071b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
2072b2a66aadSAntti Julku 
2073b2a66aadSAntti Julku 		list_del(p);
2074b2a66aadSAntti Julku 		kfree(b);
2075b2a66aadSAntti Julku 	}
2076b2a66aadSAntti Julku 
2077b2a66aadSAntti Julku 	return 0;
2078b2a66aadSAntti Julku }
2079b2a66aadSAntti Julku 
208088c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2081b2a66aadSAntti Julku {
2082b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2083b2a66aadSAntti Julku 
2084b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
2085b2a66aadSAntti Julku 		return -EBADF;
2086b2a66aadSAntti Julku 
20875e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
20885e762444SAntti Julku 		return -EEXIST;
2089b2a66aadSAntti Julku 
2090b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
20915e762444SAntti Julku 	if (!entry)
20925e762444SAntti Julku 		return -ENOMEM;
2093b2a66aadSAntti Julku 
2094b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2095b2a66aadSAntti Julku 
2096b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
2097b2a66aadSAntti Julku 
209888c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
2099b2a66aadSAntti Julku }
2100b2a66aadSAntti Julku 
210188c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2102b2a66aadSAntti Julku {
2103b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2104b2a66aadSAntti Julku 
21051ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
21065e762444SAntti Julku 		return hci_blacklist_clear(hdev);
2107b2a66aadSAntti Julku 
2108b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
21091ec918ceSSzymon Janc 	if (!entry)
21105e762444SAntti Julku 		return -ENOENT;
2111b2a66aadSAntti Julku 
2112b2a66aadSAntti Julku 	list_del(&entry->list);
2113b2a66aadSAntti Julku 	kfree(entry);
2114b2a66aadSAntti Julku 
211588c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
2116b2a66aadSAntti Julku }
2117b2a66aadSAntti Julku 
21184c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
21197ba8b4beSAndre Guedes {
21204c87eaabSAndre Guedes 	if (status) {
21214c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
21227ba8b4beSAndre Guedes 
21234c87eaabSAndre Guedes 		hci_dev_lock(hdev);
21244c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
21254c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
21264c87eaabSAndre Guedes 		return;
21274c87eaabSAndre Guedes 	}
21287ba8b4beSAndre Guedes }
21297ba8b4beSAndre Guedes 
21304c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
21317ba8b4beSAndre Guedes {
21324c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
21334c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
21344c87eaabSAndre Guedes 	struct hci_request req;
21354c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
21367ba8b4beSAndre Guedes 	int err;
21377ba8b4beSAndre Guedes 
21384c87eaabSAndre Guedes 	if (status) {
21394c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
21404c87eaabSAndre Guedes 		return;
21417ba8b4beSAndre Guedes 	}
21427ba8b4beSAndre Guedes 
21434c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
21444c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
21454c87eaabSAndre Guedes 		hci_dev_lock(hdev);
21464c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
21474c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
21484c87eaabSAndre Guedes 		break;
21497dbfac1dSAndre Guedes 
21504c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
21514c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
21527dbfac1dSAndre Guedes 
21537dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
21544c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
21554c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
21564c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
21574c87eaabSAndre Guedes 
21584c87eaabSAndre Guedes 		hci_dev_lock(hdev);
21594c87eaabSAndre Guedes 
21604c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
21614c87eaabSAndre Guedes 
21624c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
21634c87eaabSAndre Guedes 		if (err) {
21644c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
21654c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
21667dbfac1dSAndre Guedes 		}
21677dbfac1dSAndre Guedes 
21684c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
21694c87eaabSAndre Guedes 		break;
21704c87eaabSAndre Guedes 	}
21717dbfac1dSAndre Guedes }
21727dbfac1dSAndre Guedes 
21737ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
21747ba8b4beSAndre Guedes {
21757ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
21767ba8b4beSAndre Guedes 					    le_scan_disable.work);
21777ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
21784c87eaabSAndre Guedes 	struct hci_request req;
21794c87eaabSAndre Guedes 	int err;
21807ba8b4beSAndre Guedes 
21817ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
21827ba8b4beSAndre Guedes 
21834c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
21847ba8b4beSAndre Guedes 
21857ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
21864c87eaabSAndre Guedes 	cp.enable = LE_SCAN_DISABLE;
21874c87eaabSAndre Guedes 	hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
21887ba8b4beSAndre Guedes 
21894c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
21904c87eaabSAndre Guedes 	if (err)
21914c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
219228b75a89SAndre Guedes }
219328b75a89SAndre Guedes 
21949be0dab7SDavid Herrmann /* Alloc HCI device */
21959be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
21969be0dab7SDavid Herrmann {
21979be0dab7SDavid Herrmann 	struct hci_dev *hdev;
21989be0dab7SDavid Herrmann 
21999be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
22009be0dab7SDavid Herrmann 	if (!hdev)
22019be0dab7SDavid Herrmann 		return NULL;
22029be0dab7SDavid Herrmann 
2203b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2204b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
2205b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
2206b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
2207b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
2208bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2209bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2210b1b813d4SDavid Herrmann 
2211b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
2212b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
2213b1b813d4SDavid Herrmann 
2214bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
2215bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
2216bef64738SMarcel Holtmann 
2217b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
2218b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
2219b1b813d4SDavid Herrmann 
2220b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
2221b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
2222b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
2223b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
2224b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
2225b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
22266b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
2227b1b813d4SDavid Herrmann 
2228b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2229b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2230b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2231b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2232b1b813d4SDavid Herrmann 
2233b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2234b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
2235b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
2236b1b813d4SDavid Herrmann 
2237b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2238b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2239b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2240b1b813d4SDavid Herrmann 
2241b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2242b1b813d4SDavid Herrmann 
2243bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
2244b1b813d4SDavid Herrmann 
2245b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2246b1b813d4SDavid Herrmann 	discovery_init(hdev);
22479be0dab7SDavid Herrmann 
22489be0dab7SDavid Herrmann 	return hdev;
22499be0dab7SDavid Herrmann }
22509be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
22519be0dab7SDavid Herrmann 
22529be0dab7SDavid Herrmann /* Free HCI device */
22539be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
22549be0dab7SDavid Herrmann {
22559be0dab7SDavid Herrmann 	/* will free via device release */
22569be0dab7SDavid Herrmann 	put_device(&hdev->dev);
22579be0dab7SDavid Herrmann }
22589be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
22599be0dab7SDavid Herrmann 
22601da177e4SLinus Torvalds /* Register HCI device */
22611da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
22621da177e4SLinus Torvalds {
2263b1b813d4SDavid Herrmann 	int id, error;
22641da177e4SLinus Torvalds 
2265010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
22661da177e4SLinus Torvalds 		return -EINVAL;
22671da177e4SLinus Torvalds 
226808add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
226908add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
227008add513SMat Martineau 	 */
22713df92b31SSasha Levin 	switch (hdev->dev_type) {
22723df92b31SSasha Levin 	case HCI_BREDR:
22733df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
22741da177e4SLinus Torvalds 		break;
22753df92b31SSasha Levin 	case HCI_AMP:
22763df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
22773df92b31SSasha Levin 		break;
22783df92b31SSasha Levin 	default:
22793df92b31SSasha Levin 		return -EINVAL;
22801da177e4SLinus Torvalds 	}
22811da177e4SLinus Torvalds 
22823df92b31SSasha Levin 	if (id < 0)
22833df92b31SSasha Levin 		return id;
22843df92b31SSasha Levin 
22851da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
22861da177e4SLinus Torvalds 	hdev->id = id;
22872d8b3a11SAndrei Emeltchenko 
22882d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
22892d8b3a11SAndrei Emeltchenko 
2290d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
2291d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
229233ca954dSDavid Herrmann 	if (!hdev->workqueue) {
229333ca954dSDavid Herrmann 		error = -ENOMEM;
229433ca954dSDavid Herrmann 		goto err;
229533ca954dSDavid Herrmann 	}
2296f48fd9c8SMarcel Holtmann 
2297d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
2298d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
22996ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
23006ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
23016ead1bbcSJohan Hedberg 		error = -ENOMEM;
23026ead1bbcSJohan Hedberg 		goto err;
23036ead1bbcSJohan Hedberg 	}
23046ead1bbcSJohan Hedberg 
230533ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
230633ca954dSDavid Herrmann 	if (error < 0)
230733ca954dSDavid Herrmann 		goto err_wqueue;
23081da177e4SLinus Torvalds 
2309611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2310a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2311a8c5fb1aSGustavo Padovan 				    hdev);
2312611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2313611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
2314611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
2315611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
2316611b30f7SMarcel Holtmann 		}
2317611b30f7SMarcel Holtmann 	}
2318611b30f7SMarcel Holtmann 
23195e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
23205e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
23215e130367SJohan Hedberg 
2322a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
2323004b0258SMarcel Holtmann 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2324ce2be9acSAndrei Emeltchenko 
232501cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
232656f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
232756f87901SJohan Hedberg 		 * through reading supported features during init.
232856f87901SJohan Hedberg 		 */
232956f87901SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
233056f87901SJohan Hedberg 	}
2331ce2be9acSAndrei Emeltchenko 
2332fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
2333fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
2334fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
2335fcee3377SGustavo Padovan 
23361da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
2337dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
23381da177e4SLinus Torvalds 
233919202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2340fbe96d6fSMarcel Holtmann 
23411da177e4SLinus Torvalds 	return id;
2342f48fd9c8SMarcel Holtmann 
234333ca954dSDavid Herrmann err_wqueue:
234433ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
23456ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
234633ca954dSDavid Herrmann err:
23473df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
2348f48fd9c8SMarcel Holtmann 
234933ca954dSDavid Herrmann 	return error;
23501da177e4SLinus Torvalds }
23511da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
23521da177e4SLinus Torvalds 
23531da177e4SLinus Torvalds /* Unregister HCI device */
235459735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
23551da177e4SLinus Torvalds {
23563df92b31SSasha Levin 	int i, id;
2357ef222013SMarcel Holtmann 
2358c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
23591da177e4SLinus Torvalds 
236094324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
236194324962SJohan Hovold 
23623df92b31SSasha Levin 	id = hdev->id;
23633df92b31SSasha Levin 
2364f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
23651da177e4SLinus Torvalds 	list_del(&hdev->list);
2366f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
23671da177e4SLinus Torvalds 
23681da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
23691da177e4SLinus Torvalds 
2370cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
2371ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
2372ef222013SMarcel Holtmann 
2373b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
2374b9b5ef18SGustavo Padovan 
2375ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2376a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
237709fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2378744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
237909fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
238056e5cb86SJohan Hedberg 	}
2381ab81cbf9SJohan Hedberg 
23822e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
23832e58ef3eSJohan Hedberg 	 * pending list */
23842e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
23852e58ef3eSJohan Hedberg 
23861da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
23871da177e4SLinus Torvalds 
2388611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2389611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2390611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2391611b30f7SMarcel Holtmann 	}
2392611b30f7SMarcel Holtmann 
2393ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
2394147e2d59SDave Young 
2395f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
23966ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2397f48fd9c8SMarcel Holtmann 
239809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
2399e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
24002aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
240155ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2402b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
24032763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
240409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2405e2e0cacbSJohan Hedberg 
2406dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
24073df92b31SSasha Levin 
24083df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
24091da177e4SLinus Torvalds }
24101da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
24111da177e4SLinus Torvalds 
24121da177e4SLinus Torvalds /* Suspend HCI device */
24131da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
24141da177e4SLinus Torvalds {
24151da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
24161da177e4SLinus Torvalds 	return 0;
24171da177e4SLinus Torvalds }
24181da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
24191da177e4SLinus Torvalds 
24201da177e4SLinus Torvalds /* Resume HCI device */
24211da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
24221da177e4SLinus Torvalds {
24231da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
24241da177e4SLinus Torvalds 	return 0;
24251da177e4SLinus Torvalds }
24261da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
24271da177e4SLinus Torvalds 
242876bca880SMarcel Holtmann /* Receive frame from HCI drivers */
2429e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
243076bca880SMarcel Holtmann {
243176bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
243276bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
243376bca880SMarcel Holtmann 		kfree_skb(skb);
243476bca880SMarcel Holtmann 		return -ENXIO;
243576bca880SMarcel Holtmann 	}
243676bca880SMarcel Holtmann 
2437d82603c6SJorrit Schippers 	/* Incoming skb */
243876bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
243976bca880SMarcel Holtmann 
244076bca880SMarcel Holtmann 	/* Time stamp */
244176bca880SMarcel Holtmann 	__net_timestamp(skb);
244276bca880SMarcel Holtmann 
244376bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2444b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2445c78ae283SMarcel Holtmann 
244676bca880SMarcel Holtmann 	return 0;
244776bca880SMarcel Holtmann }
244876bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
244976bca880SMarcel Holtmann 
245033e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
24511e429f38SGustavo F. Padovan 			  int count, __u8 index)
245233e882a5SSuraj Sumangala {
245333e882a5SSuraj Sumangala 	int len = 0;
245433e882a5SSuraj Sumangala 	int hlen = 0;
245533e882a5SSuraj Sumangala 	int remain = count;
245633e882a5SSuraj Sumangala 	struct sk_buff *skb;
245733e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
245833e882a5SSuraj Sumangala 
245933e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
246033e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
246133e882a5SSuraj Sumangala 		return -EILSEQ;
246233e882a5SSuraj Sumangala 
246333e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
246433e882a5SSuraj Sumangala 
246533e882a5SSuraj Sumangala 	if (!skb) {
246633e882a5SSuraj Sumangala 		switch (type) {
246733e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
246833e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
246933e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
247033e882a5SSuraj Sumangala 			break;
247133e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
247233e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
247333e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
247433e882a5SSuraj Sumangala 			break;
247533e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
247633e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
247733e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
247833e882a5SSuraj Sumangala 			break;
247933e882a5SSuraj Sumangala 		}
248033e882a5SSuraj Sumangala 
24811e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
248233e882a5SSuraj Sumangala 		if (!skb)
248333e882a5SSuraj Sumangala 			return -ENOMEM;
248433e882a5SSuraj Sumangala 
248533e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
248633e882a5SSuraj Sumangala 		scb->expect = hlen;
248733e882a5SSuraj Sumangala 		scb->pkt_type = type;
248833e882a5SSuraj Sumangala 
248933e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
249033e882a5SSuraj Sumangala 	}
249133e882a5SSuraj Sumangala 
249233e882a5SSuraj Sumangala 	while (count) {
249333e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
249489bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
249533e882a5SSuraj Sumangala 
249633e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
249733e882a5SSuraj Sumangala 
249833e882a5SSuraj Sumangala 		count -= len;
249933e882a5SSuraj Sumangala 		data += len;
250033e882a5SSuraj Sumangala 		scb->expect -= len;
250133e882a5SSuraj Sumangala 		remain = count;
250233e882a5SSuraj Sumangala 
250333e882a5SSuraj Sumangala 		switch (type) {
250433e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
250533e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
250633e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
250733e882a5SSuraj Sumangala 				scb->expect = h->plen;
250833e882a5SSuraj Sumangala 
250933e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
251033e882a5SSuraj Sumangala 					kfree_skb(skb);
251133e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
251233e882a5SSuraj Sumangala 					return -ENOMEM;
251333e882a5SSuraj Sumangala 				}
251433e882a5SSuraj Sumangala 			}
251533e882a5SSuraj Sumangala 			break;
251633e882a5SSuraj Sumangala 
251733e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
251833e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
251933e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
252033e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
252133e882a5SSuraj Sumangala 
252233e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
252333e882a5SSuraj Sumangala 					kfree_skb(skb);
252433e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
252533e882a5SSuraj Sumangala 					return -ENOMEM;
252633e882a5SSuraj Sumangala 				}
252733e882a5SSuraj Sumangala 			}
252833e882a5SSuraj Sumangala 			break;
252933e882a5SSuraj Sumangala 
253033e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
253133e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
253233e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
253333e882a5SSuraj Sumangala 				scb->expect = h->dlen;
253433e882a5SSuraj Sumangala 
253533e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
253633e882a5SSuraj Sumangala 					kfree_skb(skb);
253733e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
253833e882a5SSuraj Sumangala 					return -ENOMEM;
253933e882a5SSuraj Sumangala 				}
254033e882a5SSuraj Sumangala 			}
254133e882a5SSuraj Sumangala 			break;
254233e882a5SSuraj Sumangala 		}
254333e882a5SSuraj Sumangala 
254433e882a5SSuraj Sumangala 		if (scb->expect == 0) {
254533e882a5SSuraj Sumangala 			/* Complete frame */
254633e882a5SSuraj Sumangala 
254733e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
2548e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
254933e882a5SSuraj Sumangala 
255033e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
255133e882a5SSuraj Sumangala 			return remain;
255233e882a5SSuraj Sumangala 		}
255333e882a5SSuraj Sumangala 	}
255433e882a5SSuraj Sumangala 
255533e882a5SSuraj Sumangala 	return remain;
255633e882a5SSuraj Sumangala }
255733e882a5SSuraj Sumangala 
2558ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
2559ef222013SMarcel Holtmann {
2560f39a3c06SSuraj Sumangala 	int rem = 0;
2561f39a3c06SSuraj Sumangala 
2562ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
2563ef222013SMarcel Holtmann 		return -EILSEQ;
2564ef222013SMarcel Holtmann 
2565da5f6c37SGustavo F. Padovan 	while (count) {
25661e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
2567f39a3c06SSuraj Sumangala 		if (rem < 0)
2568f39a3c06SSuraj Sumangala 			return rem;
2569ef222013SMarcel Holtmann 
2570f39a3c06SSuraj Sumangala 		data += (count - rem);
2571f39a3c06SSuraj Sumangala 		count = rem;
2572f81c6224SJoe Perches 	}
2573ef222013SMarcel Holtmann 
2574f39a3c06SSuraj Sumangala 	return rem;
2575ef222013SMarcel Holtmann }
2576ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
2577ef222013SMarcel Holtmann 
257899811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
257999811510SSuraj Sumangala 
258099811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
258199811510SSuraj Sumangala {
258299811510SSuraj Sumangala 	int type;
258399811510SSuraj Sumangala 	int rem = 0;
258499811510SSuraj Sumangala 
2585da5f6c37SGustavo F. Padovan 	while (count) {
258699811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
258799811510SSuraj Sumangala 
258899811510SSuraj Sumangala 		if (!skb) {
258999811510SSuraj Sumangala 			struct { char type; } *pkt;
259099811510SSuraj Sumangala 
259199811510SSuraj Sumangala 			/* Start of the frame */
259299811510SSuraj Sumangala 			pkt = data;
259399811510SSuraj Sumangala 			type = pkt->type;
259499811510SSuraj Sumangala 
259599811510SSuraj Sumangala 			data++;
259699811510SSuraj Sumangala 			count--;
259799811510SSuraj Sumangala 		} else
259899811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
259999811510SSuraj Sumangala 
26001e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
26011e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
260299811510SSuraj Sumangala 		if (rem < 0)
260399811510SSuraj Sumangala 			return rem;
260499811510SSuraj Sumangala 
260599811510SSuraj Sumangala 		data += (count - rem);
260699811510SSuraj Sumangala 		count = rem;
2607f81c6224SJoe Perches 	}
260899811510SSuraj Sumangala 
260999811510SSuraj Sumangala 	return rem;
261099811510SSuraj Sumangala }
261199811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
261299811510SSuraj Sumangala 
26131da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
26141da177e4SLinus Torvalds 
26151da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
26161da177e4SLinus Torvalds {
26171da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
26181da177e4SLinus Torvalds 
2619f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
26201da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2621f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
26221da177e4SLinus Torvalds 
26231da177e4SLinus Torvalds 	return 0;
26241da177e4SLinus Torvalds }
26251da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
26261da177e4SLinus Torvalds 
26271da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
26281da177e4SLinus Torvalds {
26291da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
26301da177e4SLinus Torvalds 
2631f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
26321da177e4SLinus Torvalds 	list_del(&cb->list);
2633f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
26341da177e4SLinus Torvalds 
26351da177e4SLinus Torvalds 	return 0;
26361da177e4SLinus Torvalds }
26371da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
26381da177e4SLinus Torvalds 
263951086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
26401da177e4SLinus Torvalds {
26410d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
26421da177e4SLinus Torvalds 
26431da177e4SLinus Torvalds 	/* Time stamp */
2644a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
26451da177e4SLinus Torvalds 
2646cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2647cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2648cd82e61cSMarcel Holtmann 
2649cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2650cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2651470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
26521da177e4SLinus Torvalds 	}
26531da177e4SLinus Torvalds 
26541da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
26551da177e4SLinus Torvalds 	skb_orphan(skb);
26561da177e4SLinus Torvalds 
26577bd8f09fSMarcel Holtmann 	if (hdev->send(hdev, skb) < 0)
265851086991SMarcel Holtmann 		BT_ERR("%s sending frame failed", hdev->name);
26591da177e4SLinus Torvalds }
26601da177e4SLinus Torvalds 
26613119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
26623119ae95SJohan Hedberg {
26633119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
26643119ae95SJohan Hedberg 	req->hdev = hdev;
26655d73e034SAndre Guedes 	req->err = 0;
26663119ae95SJohan Hedberg }
26673119ae95SJohan Hedberg 
26683119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
26693119ae95SJohan Hedberg {
26703119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
26713119ae95SJohan Hedberg 	struct sk_buff *skb;
26723119ae95SJohan Hedberg 	unsigned long flags;
26733119ae95SJohan Hedberg 
26743119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
26753119ae95SJohan Hedberg 
26765d73e034SAndre Guedes 	/* If an error occured during request building, remove all HCI
26775d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
26785d73e034SAndre Guedes 	 */
26795d73e034SAndre Guedes 	if (req->err) {
26805d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
26815d73e034SAndre Guedes 		return req->err;
26825d73e034SAndre Guedes 	}
26835d73e034SAndre Guedes 
26843119ae95SJohan Hedberg 	/* Do not allow empty requests */
26853119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
2686382b0c39SAndre Guedes 		return -ENODATA;
26873119ae95SJohan Hedberg 
26883119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
26893119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
26903119ae95SJohan Hedberg 
26913119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
26923119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
26933119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
26943119ae95SJohan Hedberg 
26953119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
26963119ae95SJohan Hedberg 
26973119ae95SJohan Hedberg 	return 0;
26983119ae95SJohan Hedberg }
26993119ae95SJohan Hedberg 
27001ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
270107dc93ddSJohan Hedberg 				       u32 plen, const void *param)
27021da177e4SLinus Torvalds {
27031da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
27041da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
27051da177e4SLinus Torvalds 	struct sk_buff *skb;
27061da177e4SLinus Torvalds 
27071da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
27081ca3a9d0SJohan Hedberg 	if (!skb)
27091ca3a9d0SJohan Hedberg 		return NULL;
27101da177e4SLinus Torvalds 
27111da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2712a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
27131da177e4SLinus Torvalds 	hdr->plen   = plen;
27141da177e4SLinus Torvalds 
27151da177e4SLinus Torvalds 	if (plen)
27161da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
27171da177e4SLinus Torvalds 
27181da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
27191da177e4SLinus Torvalds 
27200d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
2721c78ae283SMarcel Holtmann 
27221ca3a9d0SJohan Hedberg 	return skb;
27231ca3a9d0SJohan Hedberg }
27241ca3a9d0SJohan Hedberg 
27251ca3a9d0SJohan Hedberg /* Send HCI command */
272607dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
272707dc93ddSJohan Hedberg 		 const void *param)
27281ca3a9d0SJohan Hedberg {
27291ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
27301ca3a9d0SJohan Hedberg 
27311ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
27321ca3a9d0SJohan Hedberg 
27331ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
27341ca3a9d0SJohan Hedberg 	if (!skb) {
27351ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
27361ca3a9d0SJohan Hedberg 		return -ENOMEM;
27371ca3a9d0SJohan Hedberg 	}
27381ca3a9d0SJohan Hedberg 
273911714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
274011714b3dSJohan Hedberg 	 * single-command requests.
274111714b3dSJohan Hedberg 	 */
274211714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
274311714b3dSJohan Hedberg 
27441da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2745c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
27461da177e4SLinus Torvalds 
27471da177e4SLinus Torvalds 	return 0;
27481da177e4SLinus Torvalds }
27491da177e4SLinus Torvalds 
275071c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
275107dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
275207dc93ddSJohan Hedberg 		    const void *param, u8 event)
275371c76a17SJohan Hedberg {
275471c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
275571c76a17SJohan Hedberg 	struct sk_buff *skb;
275671c76a17SJohan Hedberg 
275771c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
275871c76a17SJohan Hedberg 
275934739c1eSAndre Guedes 	/* If an error occured during request building, there is no point in
276034739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
276134739c1eSAndre Guedes 	 */
276234739c1eSAndre Guedes 	if (req->err)
276334739c1eSAndre Guedes 		return;
276434739c1eSAndre Guedes 
276571c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
276671c76a17SJohan Hedberg 	if (!skb) {
27675d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
27685d73e034SAndre Guedes 		       hdev->name, opcode);
27695d73e034SAndre Guedes 		req->err = -ENOMEM;
2770e348fe6bSAndre Guedes 		return;
277171c76a17SJohan Hedberg 	}
277271c76a17SJohan Hedberg 
277371c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
277471c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
277571c76a17SJohan Hedberg 
277602350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
277702350a72SJohan Hedberg 
277871c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
277971c76a17SJohan Hedberg }
278071c76a17SJohan Hedberg 
278107dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
278207dc93ddSJohan Hedberg 		 const void *param)
278302350a72SJohan Hedberg {
278402350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
278502350a72SJohan Hedberg }
278602350a72SJohan Hedberg 
27871da177e4SLinus Torvalds /* Get data from the previously sent command */
2788a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
27891da177e4SLinus Torvalds {
27901da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
27911da177e4SLinus Torvalds 
27921da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
27931da177e4SLinus Torvalds 		return NULL;
27941da177e4SLinus Torvalds 
27951da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
27961da177e4SLinus Torvalds 
2797a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
27981da177e4SLinus Torvalds 		return NULL;
27991da177e4SLinus Torvalds 
2800f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
28011da177e4SLinus Torvalds 
28021da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
28031da177e4SLinus Torvalds }
28041da177e4SLinus Torvalds 
28051da177e4SLinus Torvalds /* Send ACL data */
28061da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
28071da177e4SLinus Torvalds {
28081da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
28091da177e4SLinus Torvalds 	int len = skb->len;
28101da177e4SLinus Torvalds 
2811badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2812badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
28139c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2814aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2815aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
28161da177e4SLinus Torvalds }
28171da177e4SLinus Torvalds 
2818ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
281973d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
28201da177e4SLinus Torvalds {
2821ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
28221da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
28231da177e4SLinus Torvalds 	struct sk_buff *list;
28241da177e4SLinus Torvalds 
2825087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
2826087bfd99SGustavo Padovan 	skb->data_len = 0;
2827087bfd99SGustavo Padovan 
2828087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2829204a6e54SAndrei Emeltchenko 
2830204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
2831204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
2832087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
2833204a6e54SAndrei Emeltchenko 		break;
2834204a6e54SAndrei Emeltchenko 	case HCI_AMP:
2835204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
2836204a6e54SAndrei Emeltchenko 		break;
2837204a6e54SAndrei Emeltchenko 	default:
2838204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2839204a6e54SAndrei Emeltchenko 		return;
2840204a6e54SAndrei Emeltchenko 	}
2841087bfd99SGustavo Padovan 
284270f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
284370f23020SAndrei Emeltchenko 	if (!list) {
28441da177e4SLinus Torvalds 		/* Non fragmented */
28451da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
28461da177e4SLinus Torvalds 
284773d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
28481da177e4SLinus Torvalds 	} else {
28491da177e4SLinus Torvalds 		/* Fragmented */
28501da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
28511da177e4SLinus Torvalds 
28521da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
28531da177e4SLinus Torvalds 
28541da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2855af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
28561da177e4SLinus Torvalds 
285773d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2858e702112fSAndrei Emeltchenko 
2859e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2860e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
28611da177e4SLinus Torvalds 		do {
28621da177e4SLinus Torvalds 			skb = list; list = list->next;
28631da177e4SLinus Torvalds 
28640d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2865e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
28661da177e4SLinus Torvalds 
28671da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
28681da177e4SLinus Torvalds 
286973d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
28701da177e4SLinus Torvalds 		} while (list);
28711da177e4SLinus Torvalds 
2872af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
28731da177e4SLinus Torvalds 	}
287473d80debSLuiz Augusto von Dentz }
287573d80debSLuiz Augusto von Dentz 
287673d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
287773d80debSLuiz Augusto von Dentz {
2878ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
287973d80debSLuiz Augusto von Dentz 
2880f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
288173d80debSLuiz Augusto von Dentz 
2882ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
28831da177e4SLinus Torvalds 
28843eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
28851da177e4SLinus Torvalds }
28861da177e4SLinus Torvalds 
28871da177e4SLinus Torvalds /* Send SCO data */
28880d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
28891da177e4SLinus Torvalds {
28901da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
28911da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
28921da177e4SLinus Torvalds 
28931da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
28941da177e4SLinus Torvalds 
2895aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
28961da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
28971da177e4SLinus Torvalds 
2898badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2899badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
29009c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
29011da177e4SLinus Torvalds 
29020d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2903c78ae283SMarcel Holtmann 
29041da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
29053eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
29061da177e4SLinus Torvalds }
29071da177e4SLinus Torvalds 
29081da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
29091da177e4SLinus Torvalds 
29101da177e4SLinus Torvalds /* HCI Connection scheduler */
29116039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
2912a8c5fb1aSGustavo Padovan 				     int *quote)
29131da177e4SLinus Torvalds {
29141da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
29158035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
2916abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
29171da177e4SLinus Torvalds 
29181da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
29191da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2920bf4c6325SGustavo F. Padovan 
2921bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2922bf4c6325SGustavo F. Padovan 
2923bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2924769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
29251da177e4SLinus Torvalds 			continue;
2926769be974SMarcel Holtmann 
2927769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2928769be974SMarcel Holtmann 			continue;
2929769be974SMarcel Holtmann 
29301da177e4SLinus Torvalds 		num++;
29311da177e4SLinus Torvalds 
29321da177e4SLinus Torvalds 		if (c->sent < min) {
29331da177e4SLinus Torvalds 			min  = c->sent;
29341da177e4SLinus Torvalds 			conn = c;
29351da177e4SLinus Torvalds 		}
293652087a79SLuiz Augusto von Dentz 
293752087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
293852087a79SLuiz Augusto von Dentz 			break;
29391da177e4SLinus Torvalds 	}
29401da177e4SLinus Torvalds 
2941bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2942bf4c6325SGustavo F. Padovan 
29431da177e4SLinus Torvalds 	if (conn) {
29446ed58ec5SVille Tervo 		int cnt, q;
29456ed58ec5SVille Tervo 
29466ed58ec5SVille Tervo 		switch (conn->type) {
29476ed58ec5SVille Tervo 		case ACL_LINK:
29486ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
29496ed58ec5SVille Tervo 			break;
29506ed58ec5SVille Tervo 		case SCO_LINK:
29516ed58ec5SVille Tervo 		case ESCO_LINK:
29526ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
29536ed58ec5SVille Tervo 			break;
29546ed58ec5SVille Tervo 		case LE_LINK:
29556ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
29566ed58ec5SVille Tervo 			break;
29576ed58ec5SVille Tervo 		default:
29586ed58ec5SVille Tervo 			cnt = 0;
29596ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
29606ed58ec5SVille Tervo 		}
29616ed58ec5SVille Tervo 
29626ed58ec5SVille Tervo 		q = cnt / num;
29631da177e4SLinus Torvalds 		*quote = q ? q : 1;
29641da177e4SLinus Torvalds 	} else
29651da177e4SLinus Torvalds 		*quote = 0;
29661da177e4SLinus Torvalds 
29671da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
29681da177e4SLinus Torvalds 	return conn;
29691da177e4SLinus Torvalds }
29701da177e4SLinus Torvalds 
29716039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
29721da177e4SLinus Torvalds {
29731da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
29741da177e4SLinus Torvalds 	struct hci_conn *c;
29751da177e4SLinus Torvalds 
2976bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
29771da177e4SLinus Torvalds 
2978bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2979bf4c6325SGustavo F. Padovan 
29801da177e4SLinus Torvalds 	/* Kill stalled connections */
2981bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2982bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
29836ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
29846ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
2985bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
29861da177e4SLinus Torvalds 		}
29871da177e4SLinus Torvalds 	}
2988bf4c6325SGustavo F. Padovan 
2989bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
29901da177e4SLinus Torvalds }
29911da177e4SLinus Torvalds 
29926039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
299373d80debSLuiz Augusto von Dentz 				      int *quote)
299473d80debSLuiz Augusto von Dentz {
299573d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
299673d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
2997abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
299873d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
299973d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
300073d80debSLuiz Augusto von Dentz 
300173d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
300273d80debSLuiz Augusto von Dentz 
3003bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3004bf4c6325SGustavo F. Padovan 
3005bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
300673d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
300773d80debSLuiz Augusto von Dentz 
300873d80debSLuiz Augusto von Dentz 		if (conn->type != type)
300973d80debSLuiz Augusto von Dentz 			continue;
301073d80debSLuiz Augusto von Dentz 
301173d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
301273d80debSLuiz Augusto von Dentz 			continue;
301373d80debSLuiz Augusto von Dentz 
301473d80debSLuiz Augusto von Dentz 		conn_num++;
301573d80debSLuiz Augusto von Dentz 
30168192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
301773d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
301873d80debSLuiz Augusto von Dentz 
301973d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
302073d80debSLuiz Augusto von Dentz 				continue;
302173d80debSLuiz Augusto von Dentz 
302273d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
302373d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
302473d80debSLuiz Augusto von Dentz 				continue;
302573d80debSLuiz Augusto von Dentz 
302673d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
302773d80debSLuiz Augusto von Dentz 				num = 0;
302873d80debSLuiz Augusto von Dentz 				min = ~0;
302973d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
303073d80debSLuiz Augusto von Dentz 			}
303173d80debSLuiz Augusto von Dentz 
303273d80debSLuiz Augusto von Dentz 			num++;
303373d80debSLuiz Augusto von Dentz 
303473d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
303573d80debSLuiz Augusto von Dentz 				min  = conn->sent;
303673d80debSLuiz Augusto von Dentz 				chan = tmp;
303773d80debSLuiz Augusto von Dentz 			}
303873d80debSLuiz Augusto von Dentz 		}
303973d80debSLuiz Augusto von Dentz 
304073d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
304173d80debSLuiz Augusto von Dentz 			break;
304273d80debSLuiz Augusto von Dentz 	}
304373d80debSLuiz Augusto von Dentz 
3044bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3045bf4c6325SGustavo F. Padovan 
304673d80debSLuiz Augusto von Dentz 	if (!chan)
304773d80debSLuiz Augusto von Dentz 		return NULL;
304873d80debSLuiz Augusto von Dentz 
304973d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
305073d80debSLuiz Augusto von Dentz 	case ACL_LINK:
305173d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
305273d80debSLuiz Augusto von Dentz 		break;
3053bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
3054bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
3055bd1eb66bSAndrei Emeltchenko 		break;
305673d80debSLuiz Augusto von Dentz 	case SCO_LINK:
305773d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
305873d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
305973d80debSLuiz Augusto von Dentz 		break;
306073d80debSLuiz Augusto von Dentz 	case LE_LINK:
306173d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
306273d80debSLuiz Augusto von Dentz 		break;
306373d80debSLuiz Augusto von Dentz 	default:
306473d80debSLuiz Augusto von Dentz 		cnt = 0;
306573d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
306673d80debSLuiz Augusto von Dentz 	}
306773d80debSLuiz Augusto von Dentz 
306873d80debSLuiz Augusto von Dentz 	q = cnt / num;
306973d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
307073d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
307173d80debSLuiz Augusto von Dentz 	return chan;
307273d80debSLuiz Augusto von Dentz }
307373d80debSLuiz Augusto von Dentz 
307402b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
307502b20f0bSLuiz Augusto von Dentz {
307602b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
307702b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
307802b20f0bSLuiz Augusto von Dentz 	int num = 0;
307902b20f0bSLuiz Augusto von Dentz 
308002b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
308102b20f0bSLuiz Augusto von Dentz 
3082bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3083bf4c6325SGustavo F. Padovan 
3084bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
308502b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
308602b20f0bSLuiz Augusto von Dentz 
308702b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
308802b20f0bSLuiz Augusto von Dentz 			continue;
308902b20f0bSLuiz Augusto von Dentz 
309002b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
309102b20f0bSLuiz Augusto von Dentz 			continue;
309202b20f0bSLuiz Augusto von Dentz 
309302b20f0bSLuiz Augusto von Dentz 		num++;
309402b20f0bSLuiz Augusto von Dentz 
30958192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
309602b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
309702b20f0bSLuiz Augusto von Dentz 
309802b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
309902b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
310002b20f0bSLuiz Augusto von Dentz 				continue;
310102b20f0bSLuiz Augusto von Dentz 			}
310202b20f0bSLuiz Augusto von Dentz 
310302b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
310402b20f0bSLuiz Augusto von Dentz 				continue;
310502b20f0bSLuiz Augusto von Dentz 
310602b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
310702b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
310802b20f0bSLuiz Augusto von Dentz 				continue;
310902b20f0bSLuiz Augusto von Dentz 
311002b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
311102b20f0bSLuiz Augusto von Dentz 
311202b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
311302b20f0bSLuiz Augusto von Dentz 			       skb->priority);
311402b20f0bSLuiz Augusto von Dentz 		}
311502b20f0bSLuiz Augusto von Dentz 
311602b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
311702b20f0bSLuiz Augusto von Dentz 			break;
311802b20f0bSLuiz Augusto von Dentz 	}
3119bf4c6325SGustavo F. Padovan 
3120bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3121bf4c6325SGustavo F. Padovan 
312202b20f0bSLuiz Augusto von Dentz }
312302b20f0bSLuiz Augusto von Dentz 
3124b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3125b71d385aSAndrei Emeltchenko {
3126b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3127b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3128b71d385aSAndrei Emeltchenko }
3129b71d385aSAndrei Emeltchenko 
31306039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
31311da177e4SLinus Torvalds {
31321da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
31331da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
31341da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
313563d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
31365f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
3137bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
31381da177e4SLinus Torvalds 	}
313963d2bc1bSAndrei Emeltchenko }
31401da177e4SLinus Torvalds 
31416039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
314263d2bc1bSAndrei Emeltchenko {
314363d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
314463d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
314563d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
314663d2bc1bSAndrei Emeltchenko 	int quote;
314763d2bc1bSAndrei Emeltchenko 
314863d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
314904837f64SMarcel Holtmann 
315073d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
315173d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3152ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3153ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
315473d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
315573d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
315673d80debSLuiz Augusto von Dentz 
3157ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3158ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3159ec1cce24SLuiz Augusto von Dentz 				break;
3160ec1cce24SLuiz Augusto von Dentz 
3161ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3162ec1cce24SLuiz Augusto von Dentz 
316373d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
316473d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
316504837f64SMarcel Holtmann 
316657d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
31671da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
31681da177e4SLinus Torvalds 
31691da177e4SLinus Torvalds 			hdev->acl_cnt--;
317073d80debSLuiz Augusto von Dentz 			chan->sent++;
317173d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
31721da177e4SLinus Torvalds 		}
31731da177e4SLinus Torvalds 	}
317402b20f0bSLuiz Augusto von Dentz 
317502b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
317602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
31771da177e4SLinus Torvalds }
31781da177e4SLinus Torvalds 
31796039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3180b71d385aSAndrei Emeltchenko {
318163d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3182b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3183b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3184b71d385aSAndrei Emeltchenko 	int quote;
3185bd1eb66bSAndrei Emeltchenko 	u8 type;
3186b71d385aSAndrei Emeltchenko 
318763d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
3188b71d385aSAndrei Emeltchenko 
3189bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3190bd1eb66bSAndrei Emeltchenko 
3191bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3192bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3193bd1eb66bSAndrei Emeltchenko 	else
3194bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3195bd1eb66bSAndrei Emeltchenko 
3196b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3197bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3198b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3199b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3200b71d385aSAndrei Emeltchenko 			int blocks;
3201b71d385aSAndrei Emeltchenko 
3202b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3203b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3204b71d385aSAndrei Emeltchenko 
3205b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3206b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3207b71d385aSAndrei Emeltchenko 				break;
3208b71d385aSAndrei Emeltchenko 
3209b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3210b71d385aSAndrei Emeltchenko 
3211b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3212b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3213b71d385aSAndrei Emeltchenko 				return;
3214b71d385aSAndrei Emeltchenko 
3215b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3216b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3217b71d385aSAndrei Emeltchenko 
321857d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3219b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3220b71d385aSAndrei Emeltchenko 
3221b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3222b71d385aSAndrei Emeltchenko 			quote -= blocks;
3223b71d385aSAndrei Emeltchenko 
3224b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3225b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3226b71d385aSAndrei Emeltchenko 		}
3227b71d385aSAndrei Emeltchenko 	}
3228b71d385aSAndrei Emeltchenko 
3229b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3230bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3231b71d385aSAndrei Emeltchenko }
3232b71d385aSAndrei Emeltchenko 
32336039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3234b71d385aSAndrei Emeltchenko {
3235b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3236b71d385aSAndrei Emeltchenko 
3237bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3238bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
3239bd1eb66bSAndrei Emeltchenko 		return;
3240bd1eb66bSAndrei Emeltchenko 
3241bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3242bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3243b71d385aSAndrei Emeltchenko 		return;
3244b71d385aSAndrei Emeltchenko 
3245b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3246b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3247b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3248b71d385aSAndrei Emeltchenko 		break;
3249b71d385aSAndrei Emeltchenko 
3250b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3251b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3252b71d385aSAndrei Emeltchenko 		break;
3253b71d385aSAndrei Emeltchenko 	}
3254b71d385aSAndrei Emeltchenko }
3255b71d385aSAndrei Emeltchenko 
32561da177e4SLinus Torvalds /* Schedule SCO */
32576039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
32581da177e4SLinus Torvalds {
32591da177e4SLinus Torvalds 	struct hci_conn *conn;
32601da177e4SLinus Torvalds 	struct sk_buff *skb;
32611da177e4SLinus Torvalds 	int quote;
32621da177e4SLinus Torvalds 
32631da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
32641da177e4SLinus Torvalds 
326552087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
326652087a79SLuiz Augusto von Dentz 		return;
326752087a79SLuiz Augusto von Dentz 
32681da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
32691da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
32701da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
327157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
32721da177e4SLinus Torvalds 
32731da177e4SLinus Torvalds 			conn->sent++;
32741da177e4SLinus Torvalds 			if (conn->sent == ~0)
32751da177e4SLinus Torvalds 				conn->sent = 0;
32761da177e4SLinus Torvalds 		}
32771da177e4SLinus Torvalds 	}
32781da177e4SLinus Torvalds }
32791da177e4SLinus Torvalds 
32806039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
3281b6a0dc82SMarcel Holtmann {
3282b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
3283b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
3284b6a0dc82SMarcel Holtmann 	int quote;
3285b6a0dc82SMarcel Holtmann 
3286b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
3287b6a0dc82SMarcel Holtmann 
328852087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
328952087a79SLuiz Augusto von Dentz 		return;
329052087a79SLuiz Augusto von Dentz 
32918fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
32928fc9ced3SGustavo Padovan 						     &quote))) {
3293b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
3294b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
329557d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3296b6a0dc82SMarcel Holtmann 
3297b6a0dc82SMarcel Holtmann 			conn->sent++;
3298b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
3299b6a0dc82SMarcel Holtmann 				conn->sent = 0;
3300b6a0dc82SMarcel Holtmann 		}
3301b6a0dc82SMarcel Holtmann 	}
3302b6a0dc82SMarcel Holtmann }
3303b6a0dc82SMarcel Holtmann 
33046039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
33056ed58ec5SVille Tervo {
330673d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
33076ed58ec5SVille Tervo 	struct sk_buff *skb;
330802b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
33096ed58ec5SVille Tervo 
33106ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
33116ed58ec5SVille Tervo 
331252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
331352087a79SLuiz Augusto von Dentz 		return;
331452087a79SLuiz Augusto von Dentz 
33156ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
33166ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
33176ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
3318bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
33196ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
3320bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
33216ed58ec5SVille Tervo 	}
33226ed58ec5SVille Tervo 
33236ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
332402b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
332573d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3326ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3327ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
332873d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
332973d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
33306ed58ec5SVille Tervo 
3331ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3332ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3333ec1cce24SLuiz Augusto von Dentz 				break;
3334ec1cce24SLuiz Augusto von Dentz 
3335ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3336ec1cce24SLuiz Augusto von Dentz 
333757d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
33386ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
33396ed58ec5SVille Tervo 
33406ed58ec5SVille Tervo 			cnt--;
334173d80debSLuiz Augusto von Dentz 			chan->sent++;
334273d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
33436ed58ec5SVille Tervo 		}
33446ed58ec5SVille Tervo 	}
334573d80debSLuiz Augusto von Dentz 
33466ed58ec5SVille Tervo 	if (hdev->le_pkts)
33476ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
33486ed58ec5SVille Tervo 	else
33496ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
335002b20f0bSLuiz Augusto von Dentz 
335102b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
335202b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
33536ed58ec5SVille Tervo }
33546ed58ec5SVille Tervo 
33553eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
33561da177e4SLinus Torvalds {
33573eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
33581da177e4SLinus Torvalds 	struct sk_buff *skb;
33591da177e4SLinus Torvalds 
33606ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
33616ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
33621da177e4SLinus Torvalds 
336352de599eSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
33641da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
33651da177e4SLinus Torvalds 		hci_sched_acl(hdev);
33661da177e4SLinus Torvalds 		hci_sched_sco(hdev);
3367b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
33686ed58ec5SVille Tervo 		hci_sched_le(hdev);
336952de599eSMarcel Holtmann 	}
33706ed58ec5SVille Tervo 
33711da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
33721da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
337357d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
33741da177e4SLinus Torvalds }
33751da177e4SLinus Torvalds 
337625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
33771da177e4SLinus Torvalds 
33781da177e4SLinus Torvalds /* ACL data packet */
33796039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
33801da177e4SLinus Torvalds {
33811da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
33821da177e4SLinus Torvalds 	struct hci_conn *conn;
33831da177e4SLinus Torvalds 	__u16 handle, flags;
33841da177e4SLinus Torvalds 
33851da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
33861da177e4SLinus Torvalds 
33871da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
33881da177e4SLinus Torvalds 	flags  = hci_flags(handle);
33891da177e4SLinus Torvalds 	handle = hci_handle(handle);
33901da177e4SLinus Torvalds 
3391f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3392a8c5fb1aSGustavo Padovan 	       handle, flags);
33931da177e4SLinus Torvalds 
33941da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
33951da177e4SLinus Torvalds 
33961da177e4SLinus Torvalds 	hci_dev_lock(hdev);
33971da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
33981da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
33991da177e4SLinus Torvalds 
34001da177e4SLinus Torvalds 	if (conn) {
340165983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
340204837f64SMarcel Holtmann 
34031da177e4SLinus Torvalds 		/* Send to upper protocol */
3404686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
34051da177e4SLinus Torvalds 		return;
34061da177e4SLinus Torvalds 	} else {
34071da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
34081da177e4SLinus Torvalds 		       hdev->name, handle);
34091da177e4SLinus Torvalds 	}
34101da177e4SLinus Torvalds 
34111da177e4SLinus Torvalds 	kfree_skb(skb);
34121da177e4SLinus Torvalds }
34131da177e4SLinus Torvalds 
34141da177e4SLinus Torvalds /* SCO data packet */
34156039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
34161da177e4SLinus Torvalds {
34171da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
34181da177e4SLinus Torvalds 	struct hci_conn *conn;
34191da177e4SLinus Torvalds 	__u16 handle;
34201da177e4SLinus Torvalds 
34211da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
34221da177e4SLinus Torvalds 
34231da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
34241da177e4SLinus Torvalds 
3425f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
34261da177e4SLinus Torvalds 
34271da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
34281da177e4SLinus Torvalds 
34291da177e4SLinus Torvalds 	hci_dev_lock(hdev);
34301da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
34311da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
34321da177e4SLinus Torvalds 
34331da177e4SLinus Torvalds 	if (conn) {
34341da177e4SLinus Torvalds 		/* Send to upper protocol */
3435686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
34361da177e4SLinus Torvalds 		return;
34371da177e4SLinus Torvalds 	} else {
34381da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
34391da177e4SLinus Torvalds 		       hdev->name, handle);
34401da177e4SLinus Torvalds 	}
34411da177e4SLinus Torvalds 
34421da177e4SLinus Torvalds 	kfree_skb(skb);
34431da177e4SLinus Torvalds }
34441da177e4SLinus Torvalds 
34459238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
34469238f36aSJohan Hedberg {
34479238f36aSJohan Hedberg 	struct sk_buff *skb;
34489238f36aSJohan Hedberg 
34499238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
34509238f36aSJohan Hedberg 	if (!skb)
34519238f36aSJohan Hedberg 		return true;
34529238f36aSJohan Hedberg 
34539238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
34549238f36aSJohan Hedberg }
34559238f36aSJohan Hedberg 
345642c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
345742c6b129SJohan Hedberg {
345842c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
345942c6b129SJohan Hedberg 	struct sk_buff *skb;
346042c6b129SJohan Hedberg 	u16 opcode;
346142c6b129SJohan Hedberg 
346242c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
346342c6b129SJohan Hedberg 		return;
346442c6b129SJohan Hedberg 
346542c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
346642c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
346742c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
346842c6b129SJohan Hedberg 		return;
346942c6b129SJohan Hedberg 
347042c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
347142c6b129SJohan Hedberg 	if (!skb)
347242c6b129SJohan Hedberg 		return;
347342c6b129SJohan Hedberg 
347442c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
347542c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
347642c6b129SJohan Hedberg }
347742c6b129SJohan Hedberg 
34789238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
34799238f36aSJohan Hedberg {
34809238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
34819238f36aSJohan Hedberg 	struct sk_buff *skb;
34829238f36aSJohan Hedberg 	unsigned long flags;
34839238f36aSJohan Hedberg 
34849238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
34859238f36aSJohan Hedberg 
348642c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
348742c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
34889238f36aSJohan Hedberg 	 */
348942c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
349042c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
349142c6b129SJohan Hedberg 		 * reset complete event during init and any pending
349242c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
349342c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
349442c6b129SJohan Hedberg 		 * command.
349542c6b129SJohan Hedberg 		 */
349642c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
349742c6b129SJohan Hedberg 			hci_resend_last(hdev);
349842c6b129SJohan Hedberg 
34999238f36aSJohan Hedberg 		return;
350042c6b129SJohan Hedberg 	}
35019238f36aSJohan Hedberg 
35029238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
35039238f36aSJohan Hedberg 	 * this request the request is not yet complete.
35049238f36aSJohan Hedberg 	 */
35059238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
35069238f36aSJohan Hedberg 		return;
35079238f36aSJohan Hedberg 
35089238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
35099238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
35109238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
35119238f36aSJohan Hedberg 	 */
35129238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
35139238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
351453e21fbcSJohan Hedberg 
351553e21fbcSJohan Hedberg 		if (req_complete) {
351653e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
351753e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
351853e21fbcSJohan Hedberg 			 * this function gets called again.
351953e21fbcSJohan Hedberg 			 */
352053e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
352153e21fbcSJohan Hedberg 
35229238f36aSJohan Hedberg 			goto call_complete;
35239238f36aSJohan Hedberg 		}
352453e21fbcSJohan Hedberg 	}
35259238f36aSJohan Hedberg 
35269238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
35279238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
35289238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
35299238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
35309238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
35319238f36aSJohan Hedberg 			break;
35329238f36aSJohan Hedberg 		}
35339238f36aSJohan Hedberg 
35349238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
35359238f36aSJohan Hedberg 		kfree_skb(skb);
35369238f36aSJohan Hedberg 	}
35379238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
35389238f36aSJohan Hedberg 
35399238f36aSJohan Hedberg call_complete:
35409238f36aSJohan Hedberg 	if (req_complete)
35419238f36aSJohan Hedberg 		req_complete(hdev, status);
35429238f36aSJohan Hedberg }
35439238f36aSJohan Hedberg 
3544b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
35451da177e4SLinus Torvalds {
3546b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
35471da177e4SLinus Torvalds 	struct sk_buff *skb;
35481da177e4SLinus Torvalds 
35491da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
35501da177e4SLinus Torvalds 
35511da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
3552cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
3553cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
3554cd82e61cSMarcel Holtmann 
35551da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
35561da177e4SLinus Torvalds 			/* Send copy to the sockets */
3557470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
35581da177e4SLinus Torvalds 		}
35591da177e4SLinus Torvalds 
35600736cfa8SMarcel Holtmann 		if (test_bit(HCI_RAW, &hdev->flags) ||
35610736cfa8SMarcel Holtmann 		    test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
35621da177e4SLinus Torvalds 			kfree_skb(skb);
35631da177e4SLinus Torvalds 			continue;
35641da177e4SLinus Torvalds 		}
35651da177e4SLinus Torvalds 
35661da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
35671da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
35680d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
35691da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
35701da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
35711da177e4SLinus Torvalds 				kfree_skb(skb);
35721da177e4SLinus Torvalds 				continue;
35733ff50b79SStephen Hemminger 			}
35741da177e4SLinus Torvalds 		}
35751da177e4SLinus Torvalds 
35761da177e4SLinus Torvalds 		/* Process frame */
35770d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
35781da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
3579b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
35801da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
35811da177e4SLinus Torvalds 			break;
35821da177e4SLinus Torvalds 
35831da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
35841da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
35851da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
35861da177e4SLinus Torvalds 			break;
35871da177e4SLinus Torvalds 
35881da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
35891da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
35901da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
35911da177e4SLinus Torvalds 			break;
35921da177e4SLinus Torvalds 
35931da177e4SLinus Torvalds 		default:
35941da177e4SLinus Torvalds 			kfree_skb(skb);
35951da177e4SLinus Torvalds 			break;
35961da177e4SLinus Torvalds 		}
35971da177e4SLinus Torvalds 	}
35981da177e4SLinus Torvalds }
35991da177e4SLinus Torvalds 
3600c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
36011da177e4SLinus Torvalds {
3602c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
36031da177e4SLinus Torvalds 	struct sk_buff *skb;
36041da177e4SLinus Torvalds 
36052104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
36062104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
36071da177e4SLinus Torvalds 
36081da177e4SLinus Torvalds 	/* Send queued commands */
36095a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
36105a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
36115a08ecceSAndrei Emeltchenko 		if (!skb)
36125a08ecceSAndrei Emeltchenko 			return;
36135a08ecceSAndrei Emeltchenko 
36141da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
36151da177e4SLinus Torvalds 
3616a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
361770f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
36181da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
361957d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
36207bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
36217bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
36227bdb8a5cSSzymon Janc 			else
36236bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
36245f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
36251da177e4SLinus Torvalds 		} else {
36261da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
3627c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
36281da177e4SLinus Torvalds 		}
36291da177e4SLinus Torvalds 	}
36301da177e4SLinus Torvalds }
3631