xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 4ca048e3)
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 
3732177bab5SJohan Hedberg 	/* Clear Event Filters */
3742177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
37542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
3762177bab5SJohan Hedberg 
3772177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
3782177bab5SJohan Hedberg 	param = __constant_cpu_to_le16(0x7d00);
37942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
3802177bab5SJohan Hedberg 
3814ca048e3SMarcel Holtmann 	/* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2,
3824ca048e3SMarcel Holtmann 	 * but it does not support page scan related HCI commands.
3834ca048e3SMarcel Holtmann 	 */
3844ca048e3SMarcel Holtmann 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) {
385f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
386f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
387f332ec66SJohan Hedberg 	}
3882177bab5SJohan Hedberg }
3892177bab5SJohan Hedberg 
39042c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
3912177bab5SJohan Hedberg {
392c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
393c73eee91SJohan Hedberg 
3942177bab5SJohan Hedberg 	/* Read LE Buffer Size */
39542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
3962177bab5SJohan Hedberg 
3972177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
39842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
3992177bab5SJohan Hedberg 
4002177bab5SJohan Hedberg 	/* Read LE Advertising Channel TX Power */
40142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
4022177bab5SJohan Hedberg 
4032177bab5SJohan Hedberg 	/* Read LE White List Size */
40442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
4052177bab5SJohan Hedberg 
4062177bab5SJohan Hedberg 	/* Read LE Supported States */
40742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
408c73eee91SJohan Hedberg 
409c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
410c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
411c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
4122177bab5SJohan Hedberg }
4132177bab5SJohan Hedberg 
4142177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
4152177bab5SJohan Hedberg {
4162177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
4172177bab5SJohan Hedberg 		return 0x02;
4182177bab5SJohan Hedberg 
4192177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4202177bab5SJohan Hedberg 		return 0x01;
4212177bab5SJohan Hedberg 
4222177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
4232177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
4242177bab5SJohan Hedberg 		return 0x01;
4252177bab5SJohan Hedberg 
4262177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
4272177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
4282177bab5SJohan Hedberg 			return 0x01;
4292177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
4302177bab5SJohan Hedberg 			return 0x01;
4312177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
4322177bab5SJohan Hedberg 			return 0x01;
4332177bab5SJohan Hedberg 	}
4342177bab5SJohan Hedberg 
4352177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
4362177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
4372177bab5SJohan Hedberg 		return 0x01;
4382177bab5SJohan Hedberg 
4392177bab5SJohan Hedberg 	return 0x00;
4402177bab5SJohan Hedberg }
4412177bab5SJohan Hedberg 
44242c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
4432177bab5SJohan Hedberg {
4442177bab5SJohan Hedberg 	u8 mode;
4452177bab5SJohan Hedberg 
44642c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
4472177bab5SJohan Hedberg 
44842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
4492177bab5SJohan Hedberg }
4502177bab5SJohan Hedberg 
45142c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
4522177bab5SJohan Hedberg {
45342c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
45442c6b129SJohan Hedberg 
4552177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
4562177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
4572177bab5SJohan Hedberg 	 * command otherwise.
4582177bab5SJohan Hedberg 	 */
4592177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
4602177bab5SJohan Hedberg 
4612177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
4622177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
4632177bab5SJohan Hedberg 	 */
4642177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
4652177bab5SJohan Hedberg 		return;
4662177bab5SJohan Hedberg 
4672177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
4682177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
4692177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4702177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
4712177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
4722177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
473c7882cbdSMarcel Holtmann 	} else {
474c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
475c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
476c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
477c7882cbdSMarcel Holtmann 		events[0] |= 0x80; /* Encryption Change */
478c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
479c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
480c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
481c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
482c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
483c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
484c7882cbdSMarcel Holtmann 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
4852177bab5SJohan Hedberg 	}
4862177bab5SJohan Hedberg 
4872177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4882177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4892177bab5SJohan Hedberg 
4902177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
4912177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
4922177bab5SJohan Hedberg 
4932177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
4942177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
4952177bab5SJohan Hedberg 
4962177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
4972177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
4982177bab5SJohan Hedberg 
4992177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
5002177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
5012177bab5SJohan Hedberg 
5022177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
5032177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
5042177bab5SJohan Hedberg 
5052177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5062177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
5072177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
5082177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
5092177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
5102177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
5112177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
5122177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
5132177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
5142177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
5152177bab5SJohan Hedberg 					 * Features Notification
5162177bab5SJohan Hedberg 					 */
5172177bab5SJohan Hedberg 	}
5182177bab5SJohan Hedberg 
5192177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
5202177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
5212177bab5SJohan Hedberg 
52242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
5232177bab5SJohan Hedberg 
5242177bab5SJohan Hedberg 	if (lmp_le_capable(hdev)) {
5252177bab5SJohan Hedberg 		memset(events, 0, sizeof(events));
5262177bab5SJohan Hedberg 		events[0] = 0x1f;
52742c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
5282177bab5SJohan Hedberg 			    sizeof(events), events);
5292177bab5SJohan Hedberg 	}
5302177bab5SJohan Hedberg }
5312177bab5SJohan Hedberg 
53242c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
5332177bab5SJohan Hedberg {
53442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
53542c6b129SJohan Hedberg 
5362177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
53742c6b129SJohan Hedberg 		bredr_setup(req);
53856f87901SJohan Hedberg 	else
53956f87901SJohan Hedberg 		clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
5402177bab5SJohan Hedberg 
5412177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
54242c6b129SJohan Hedberg 		le_setup(req);
5432177bab5SJohan Hedberg 
54442c6b129SJohan Hedberg 	hci_setup_event_mask(req);
5452177bab5SJohan Hedberg 
5463f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
5473f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
5483f8e2d75SJohan Hedberg 	 */
5493f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
55042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
5512177bab5SJohan Hedberg 
5522177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5532177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
5542177bab5SJohan Hedberg 			u8 mode = 0x01;
55542c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
5562177bab5SJohan Hedberg 				    sizeof(mode), &mode);
5572177bab5SJohan Hedberg 		} else {
5582177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
5592177bab5SJohan Hedberg 
5602177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
5612177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
5622177bab5SJohan Hedberg 
56342c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
5642177bab5SJohan Hedberg 		}
5652177bab5SJohan Hedberg 	}
5662177bab5SJohan Hedberg 
5672177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
56842c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
5692177bab5SJohan Hedberg 
5702177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
57142c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
5722177bab5SJohan Hedberg 
5732177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
5742177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
5752177bab5SJohan Hedberg 
5762177bab5SJohan Hedberg 		cp.page = 0x01;
57742c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
57842c6b129SJohan Hedberg 			    sizeof(cp), &cp);
5792177bab5SJohan Hedberg 	}
5802177bab5SJohan Hedberg 
5812177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
5822177bab5SJohan Hedberg 		u8 enable = 1;
58342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
5842177bab5SJohan Hedberg 			    &enable);
5852177bab5SJohan Hedberg 	}
5862177bab5SJohan Hedberg }
5872177bab5SJohan Hedberg 
58842c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
5892177bab5SJohan Hedberg {
59042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5912177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
5922177bab5SJohan Hedberg 	u16 link_policy = 0;
5932177bab5SJohan Hedberg 
5942177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
5952177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
5962177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
5972177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
5982177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
5992177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
6002177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
6012177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
6022177bab5SJohan Hedberg 
6032177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
60442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
6052177bab5SJohan Hedberg }
6062177bab5SJohan Hedberg 
60742c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
6082177bab5SJohan Hedberg {
60942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
6102177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
6112177bab5SJohan Hedberg 
612c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
613c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
614c73eee91SJohan Hedberg 		return;
615c73eee91SJohan Hedberg 
6162177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
6172177bab5SJohan Hedberg 
6182177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
6192177bab5SJohan Hedberg 		cp.le = 0x01;
6202177bab5SJohan Hedberg 		cp.simul = lmp_le_br_capable(hdev);
6212177bab5SJohan Hedberg 	}
6222177bab5SJohan Hedberg 
6232177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
62442c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
6252177bab5SJohan Hedberg 			    &cp);
6262177bab5SJohan Hedberg }
6272177bab5SJohan Hedberg 
628d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
629d62e6d67SJohan Hedberg {
630d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
631d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
632d62e6d67SJohan Hedberg 
633d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
634d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
635d62e6d67SJohan Hedberg 	 */
636d62e6d67SJohan Hedberg 	if (hdev->features[2][0] & 0x01) {
637d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
638d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
639d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
640d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
641d62e6d67SJohan Hedberg 	}
642d62e6d67SJohan Hedberg 
643d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
644d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
645d62e6d67SJohan Hedberg 	 */
646d62e6d67SJohan Hedberg 	if (hdev->features[2][0] & 0x02) {
647d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
648d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
649d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
650d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
651d62e6d67SJohan Hedberg 	}
652d62e6d67SJohan Hedberg 
653d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
654d62e6d67SJohan Hedberg }
655d62e6d67SJohan Hedberg 
65642c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
6572177bab5SJohan Hedberg {
65842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
659d2c5d77fSJohan Hedberg 	u8 p;
66042c6b129SJohan Hedberg 
661b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
662b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
663b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
664b8f4e068SGustavo Padovan 	 *
665b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
666b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
667b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
668b8f4e068SGustavo Padovan 	 * command redundant anyway.
669b8f4e068SGustavo Padovan 	 */
67059f45d57SJohan Hedberg 	if (hdev->commands[6] & 0x80) {
67159f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
67259f45d57SJohan Hedberg 
67359f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
67459f45d57SJohan Hedberg 		cp.delete_all = 0x01;
67559f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
67659f45d57SJohan Hedberg 			    sizeof(cp), &cp);
67759f45d57SJohan Hedberg 	}
67859f45d57SJohan Hedberg 
6792177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
68042c6b129SJohan Hedberg 		hci_setup_link_policy(req);
6812177bab5SJohan Hedberg 
68204b4edcbSJohan Hedberg 	if (lmp_le_capable(hdev)) {
68342c6b129SJohan Hedberg 		hci_set_le_support(req);
68404b4edcbSJohan Hedberg 		hci_update_ad(req);
68504b4edcbSJohan Hedberg 	}
686d2c5d77fSJohan Hedberg 
687d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
688d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
689d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
690d2c5d77fSJohan Hedberg 
691d2c5d77fSJohan Hedberg 		cp.page = p;
692d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
693d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
694d2c5d77fSJohan Hedberg 	}
6952177bab5SJohan Hedberg }
6962177bab5SJohan Hedberg 
6975d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
6985d4e7e8dSJohan Hedberg {
6995d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
7005d4e7e8dSJohan Hedberg 
701d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
702d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
703d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
704d62e6d67SJohan Hedberg 
7055d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
7065d4e7e8dSJohan Hedberg 	if (hdev->features[2][0] & 0x04)
7075d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
7085d4e7e8dSJohan Hedberg }
7095d4e7e8dSJohan Hedberg 
7102177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
7112177bab5SJohan Hedberg {
7122177bab5SJohan Hedberg 	int err;
7132177bab5SJohan Hedberg 
7142177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
7152177bab5SJohan Hedberg 	if (err < 0)
7162177bab5SJohan Hedberg 		return err;
7172177bab5SJohan Hedberg 
7182177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
7192177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
7202177bab5SJohan Hedberg 	 * first stage init.
7212177bab5SJohan Hedberg 	 */
7222177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
7232177bab5SJohan Hedberg 		return 0;
7242177bab5SJohan Hedberg 
7252177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
7262177bab5SJohan Hedberg 	if (err < 0)
7272177bab5SJohan Hedberg 		return err;
7282177bab5SJohan Hedberg 
7295d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
7305d4e7e8dSJohan Hedberg 	if (err < 0)
7315d4e7e8dSJohan Hedberg 		return err;
7325d4e7e8dSJohan Hedberg 
7335d4e7e8dSJohan Hedberg 	return __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
7342177bab5SJohan Hedberg }
7352177bab5SJohan Hedberg 
73642c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
7371da177e4SLinus Torvalds {
7381da177e4SLinus Torvalds 	__u8 scan = opt;
7391da177e4SLinus Torvalds 
74042c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
7411da177e4SLinus Torvalds 
7421da177e4SLinus Torvalds 	/* Inquiry and Page scans */
74342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
7441da177e4SLinus Torvalds }
7451da177e4SLinus Torvalds 
74642c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
7471da177e4SLinus Torvalds {
7481da177e4SLinus Torvalds 	__u8 auth = opt;
7491da177e4SLinus Torvalds 
75042c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
7511da177e4SLinus Torvalds 
7521da177e4SLinus Torvalds 	/* Authentication */
75342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
7541da177e4SLinus Torvalds }
7551da177e4SLinus Torvalds 
75642c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
7571da177e4SLinus Torvalds {
7581da177e4SLinus Torvalds 	__u8 encrypt = opt;
7591da177e4SLinus Torvalds 
76042c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
7611da177e4SLinus Torvalds 
762e4e8e37cSMarcel Holtmann 	/* Encryption */
76342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
7641da177e4SLinus Torvalds }
7651da177e4SLinus Torvalds 
76642c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
767e4e8e37cSMarcel Holtmann {
768e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
769e4e8e37cSMarcel Holtmann 
77042c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
771e4e8e37cSMarcel Holtmann 
772e4e8e37cSMarcel Holtmann 	/* Default link policy */
77342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
774e4e8e37cSMarcel Holtmann }
775e4e8e37cSMarcel Holtmann 
7761da177e4SLinus Torvalds /* Get HCI device by index.
7771da177e4SLinus Torvalds  * Device is held on return. */
7781da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
7791da177e4SLinus Torvalds {
7808035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
7811da177e4SLinus Torvalds 
7821da177e4SLinus Torvalds 	BT_DBG("%d", index);
7831da177e4SLinus Torvalds 
7841da177e4SLinus Torvalds 	if (index < 0)
7851da177e4SLinus Torvalds 		return NULL;
7861da177e4SLinus Torvalds 
7871da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
7888035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
7891da177e4SLinus Torvalds 		if (d->id == index) {
7901da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
7911da177e4SLinus Torvalds 			break;
7921da177e4SLinus Torvalds 		}
7931da177e4SLinus Torvalds 	}
7941da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
7951da177e4SLinus Torvalds 	return hdev;
7961da177e4SLinus Torvalds }
7971da177e4SLinus Torvalds 
7981da177e4SLinus Torvalds /* ---- Inquiry support ---- */
799ff9ef578SJohan Hedberg 
80030dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
80130dc78e1SJohan Hedberg {
80230dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
80330dc78e1SJohan Hedberg 
8046fbe195dSAndre Guedes 	switch (discov->state) {
805343f935bSAndre Guedes 	case DISCOVERY_FINDING:
8066fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
80730dc78e1SJohan Hedberg 		return true;
80830dc78e1SJohan Hedberg 
8096fbe195dSAndre Guedes 	default:
81030dc78e1SJohan Hedberg 		return false;
81130dc78e1SJohan Hedberg 	}
8126fbe195dSAndre Guedes }
81330dc78e1SJohan Hedberg 
814ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
815ff9ef578SJohan Hedberg {
816ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
817ff9ef578SJohan Hedberg 
818ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
819ff9ef578SJohan Hedberg 		return;
820ff9ef578SJohan Hedberg 
821ff9ef578SJohan Hedberg 	switch (state) {
822ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
8237b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
824ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
825ff9ef578SJohan Hedberg 		break;
826ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
827ff9ef578SJohan Hedberg 		break;
828343f935bSAndre Guedes 	case DISCOVERY_FINDING:
829ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
830ff9ef578SJohan Hedberg 		break;
83130dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
83230dc78e1SJohan Hedberg 		break;
833ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
834ff9ef578SJohan Hedberg 		break;
835ff9ef578SJohan Hedberg 	}
836ff9ef578SJohan Hedberg 
837ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
838ff9ef578SJohan Hedberg }
839ff9ef578SJohan Hedberg 
8401f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
8411da177e4SLinus Torvalds {
84230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
843b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
8441da177e4SLinus Torvalds 
845561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
846561aafbcSJohan Hedberg 		list_del(&p->all);
847b57c1a56SJohan Hedberg 		kfree(p);
8481da177e4SLinus Torvalds 	}
849561aafbcSJohan Hedberg 
850561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
851561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
8521da177e4SLinus Torvalds }
8531da177e4SLinus Torvalds 
854a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
855a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
8561da177e4SLinus Torvalds {
85730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
8581da177e4SLinus Torvalds 	struct inquiry_entry *e;
8591da177e4SLinus Torvalds 
8606ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
8611da177e4SLinus Torvalds 
862561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
8631da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
8641da177e4SLinus Torvalds 			return e;
8651da177e4SLinus Torvalds 	}
8661da177e4SLinus Torvalds 
867b57c1a56SJohan Hedberg 	return NULL;
868b57c1a56SJohan Hedberg }
869b57c1a56SJohan Hedberg 
870561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
871561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
872561aafbcSJohan Hedberg {
87330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
874561aafbcSJohan Hedberg 	struct inquiry_entry *e;
875561aafbcSJohan Hedberg 
8766ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
877561aafbcSJohan Hedberg 
878561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
879561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
880561aafbcSJohan Hedberg 			return e;
881561aafbcSJohan Hedberg 	}
882561aafbcSJohan Hedberg 
883561aafbcSJohan Hedberg 	return NULL;
884561aafbcSJohan Hedberg }
885561aafbcSJohan Hedberg 
88630dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
88730dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
88830dc78e1SJohan Hedberg 						       int state)
88930dc78e1SJohan Hedberg {
89030dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
89130dc78e1SJohan Hedberg 	struct inquiry_entry *e;
89230dc78e1SJohan Hedberg 
8936ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
89430dc78e1SJohan Hedberg 
89530dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
89630dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
89730dc78e1SJohan Hedberg 			return e;
89830dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
89930dc78e1SJohan Hedberg 			return e;
90030dc78e1SJohan Hedberg 	}
90130dc78e1SJohan Hedberg 
90230dc78e1SJohan Hedberg 	return NULL;
90330dc78e1SJohan Hedberg }
90430dc78e1SJohan Hedberg 
905a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
906a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
907a3d4e20aSJohan Hedberg {
908a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
909a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
910a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
911a3d4e20aSJohan Hedberg 
912a3d4e20aSJohan Hedberg 	list_del(&ie->list);
913a3d4e20aSJohan Hedberg 
914a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
915a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
916a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
917a3d4e20aSJohan Hedberg 			break;
918a3d4e20aSJohan Hedberg 		pos = &p->list;
919a3d4e20aSJohan Hedberg 	}
920a3d4e20aSJohan Hedberg 
921a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
922a3d4e20aSJohan Hedberg }
923a3d4e20aSJohan Hedberg 
9243175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
925388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
9261da177e4SLinus Torvalds {
92730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
92870f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
9291da177e4SLinus Torvalds 
9306ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
9311da177e4SLinus Torvalds 
9322b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
9332b2fec4dSSzymon Janc 
934388fc8faSJohan Hedberg 	if (ssp)
935388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
936388fc8faSJohan Hedberg 
93770f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
938a3d4e20aSJohan Hedberg 	if (ie) {
939388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
940388fc8faSJohan Hedberg 			*ssp = true;
941388fc8faSJohan Hedberg 
942a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
943a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
944a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
945a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
946a3d4e20aSJohan Hedberg 		}
947a3d4e20aSJohan Hedberg 
948561aafbcSJohan Hedberg 		goto update;
949a3d4e20aSJohan Hedberg 	}
950561aafbcSJohan Hedberg 
9511da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
95270f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
95370f23020SAndrei Emeltchenko 	if (!ie)
9543175405bSJohan Hedberg 		return false;
95570f23020SAndrei Emeltchenko 
956561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
957561aafbcSJohan Hedberg 
958561aafbcSJohan Hedberg 	if (name_known) {
959561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
960561aafbcSJohan Hedberg 	} else {
961561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
962561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
963561aafbcSJohan Hedberg 	}
964561aafbcSJohan Hedberg 
965561aafbcSJohan Hedberg update:
966561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
967561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
968561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
969561aafbcSJohan Hedberg 		list_del(&ie->list);
9701da177e4SLinus Torvalds 	}
9711da177e4SLinus Torvalds 
97270f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
97370f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
9741da177e4SLinus Torvalds 	cache->timestamp = jiffies;
9753175405bSJohan Hedberg 
9763175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
9773175405bSJohan Hedberg 		return false;
9783175405bSJohan Hedberg 
9793175405bSJohan Hedberg 	return true;
9801da177e4SLinus Torvalds }
9811da177e4SLinus Torvalds 
9821da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
9831da177e4SLinus Torvalds {
98430883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
9851da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
9861da177e4SLinus Torvalds 	struct inquiry_entry *e;
9871da177e4SLinus Torvalds 	int copied = 0;
9881da177e4SLinus Torvalds 
989561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
9901da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
991b57c1a56SJohan Hedberg 
992b57c1a56SJohan Hedberg 		if (copied >= num)
993b57c1a56SJohan Hedberg 			break;
994b57c1a56SJohan Hedberg 
9951da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
9961da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
9971da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
9981da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
9991da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
10001da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
1001b57c1a56SJohan Hedberg 
10021da177e4SLinus Torvalds 		info++;
1003b57c1a56SJohan Hedberg 		copied++;
10041da177e4SLinus Torvalds 	}
10051da177e4SLinus Torvalds 
10061da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
10071da177e4SLinus Torvalds 	return copied;
10081da177e4SLinus Torvalds }
10091da177e4SLinus Torvalds 
101042c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
10111da177e4SLinus Torvalds {
10121da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
101342c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
10141da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
10151da177e4SLinus Torvalds 
10161da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
10171da177e4SLinus Torvalds 
10181da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
10191da177e4SLinus Torvalds 		return;
10201da177e4SLinus Torvalds 
10211da177e4SLinus Torvalds 	/* Start Inquiry */
10221da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
10231da177e4SLinus Torvalds 	cp.length  = ir->length;
10241da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
102542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
10261da177e4SLinus Torvalds }
10271da177e4SLinus Torvalds 
10283e13fa1eSAndre Guedes static int wait_inquiry(void *word)
10293e13fa1eSAndre Guedes {
10303e13fa1eSAndre Guedes 	schedule();
10313e13fa1eSAndre Guedes 	return signal_pending(current);
10323e13fa1eSAndre Guedes }
10333e13fa1eSAndre Guedes 
10341da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
10351da177e4SLinus Torvalds {
10361da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
10371da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
10381da177e4SLinus Torvalds 	struct hci_dev *hdev;
10391da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
10401da177e4SLinus Torvalds 	long timeo;
10411da177e4SLinus Torvalds 	__u8 *buf;
10421da177e4SLinus Torvalds 
10431da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
10441da177e4SLinus Torvalds 		return -EFAULT;
10451da177e4SLinus Torvalds 
10465a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
10475a08ecceSAndrei Emeltchenko 	if (!hdev)
10481da177e4SLinus Torvalds 		return -ENODEV;
10491da177e4SLinus Torvalds 
10500736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
10510736cfa8SMarcel Holtmann 		err = -EBUSY;
10520736cfa8SMarcel Holtmann 		goto done;
10530736cfa8SMarcel Holtmann 	}
10540736cfa8SMarcel Holtmann 
10555b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
10565b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
10575b69bef5SMarcel Holtmann 		goto done;
10585b69bef5SMarcel Holtmann 	}
10595b69bef5SMarcel Holtmann 
106056f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
106156f87901SJohan Hedberg 		err = -EOPNOTSUPP;
106256f87901SJohan Hedberg 		goto done;
106356f87901SJohan Hedberg 	}
106456f87901SJohan Hedberg 
106509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
10661da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1067a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
10681f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
10691da177e4SLinus Torvalds 		do_inquiry = 1;
10701da177e4SLinus Torvalds 	}
107109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
10721da177e4SLinus Torvalds 
107304837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
107470f23020SAndrei Emeltchenko 
107570f23020SAndrei Emeltchenko 	if (do_inquiry) {
107601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
107701178cd4SJohan Hedberg 				   timeo);
107870f23020SAndrei Emeltchenko 		if (err < 0)
10791da177e4SLinus Torvalds 			goto done;
10803e13fa1eSAndre Guedes 
10813e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
10823e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
10833e13fa1eSAndre Guedes 		 */
10843e13fa1eSAndre Guedes 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry,
10853e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
10863e13fa1eSAndre Guedes 			return -EINTR;
108770f23020SAndrei Emeltchenko 	}
10881da177e4SLinus Torvalds 
10898fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
10908fc9ced3SGustavo Padovan 	 * 255 entries
10918fc9ced3SGustavo Padovan 	 */
10921da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
10931da177e4SLinus Torvalds 
10941da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
10951da177e4SLinus Torvalds 	 * copy it to the user space.
10961da177e4SLinus Torvalds 	 */
109770f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
109870f23020SAndrei Emeltchenko 	if (!buf) {
10991da177e4SLinus Torvalds 		err = -ENOMEM;
11001da177e4SLinus Torvalds 		goto done;
11011da177e4SLinus Torvalds 	}
11021da177e4SLinus Torvalds 
110309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
11041da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
110509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
11061da177e4SLinus Torvalds 
11071da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
11081da177e4SLinus Torvalds 
11091da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
11101da177e4SLinus Torvalds 		ptr += sizeof(ir);
11111da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
11121da177e4SLinus Torvalds 				 ir.num_rsp))
11131da177e4SLinus Torvalds 			err = -EFAULT;
11141da177e4SLinus Torvalds 	} else
11151da177e4SLinus Torvalds 		err = -EFAULT;
11161da177e4SLinus Torvalds 
11171da177e4SLinus Torvalds 	kfree(buf);
11181da177e4SLinus Torvalds 
11191da177e4SLinus Torvalds done:
11201da177e4SLinus Torvalds 	hci_dev_put(hdev);
11211da177e4SLinus Torvalds 	return err;
11221da177e4SLinus Torvalds }
11231da177e4SLinus Torvalds 
11243f0f524bSJohan Hedberg static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
11253f0f524bSJohan Hedberg {
11263f0f524bSJohan Hedberg 	u8 ad_len = 0, flags = 0;
11273f0f524bSJohan Hedberg 	size_t name_len;
11283f0f524bSJohan Hedberg 
1129f3d3444aSJohan Hedberg 	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
11303f0f524bSJohan Hedberg 		flags |= LE_AD_GENERAL;
11313f0f524bSJohan Hedberg 
113211802b29SJohan Hedberg 	if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
11333f0f524bSJohan Hedberg 		if (lmp_le_br_capable(hdev))
11343f0f524bSJohan Hedberg 			flags |= LE_AD_SIM_LE_BREDR_CTRL;
11353f0f524bSJohan Hedberg 		if (lmp_host_le_br_capable(hdev))
11363f0f524bSJohan Hedberg 			flags |= LE_AD_SIM_LE_BREDR_HOST;
113711802b29SJohan Hedberg 	} else {
113811802b29SJohan Hedberg 		flags |= LE_AD_NO_BREDR;
113911802b29SJohan Hedberg 	}
11403f0f524bSJohan Hedberg 
11413f0f524bSJohan Hedberg 	if (flags) {
11423f0f524bSJohan Hedberg 		BT_DBG("adv flags 0x%02x", flags);
11433f0f524bSJohan Hedberg 
11443f0f524bSJohan Hedberg 		ptr[0] = 2;
11453f0f524bSJohan Hedberg 		ptr[1] = EIR_FLAGS;
11463f0f524bSJohan Hedberg 		ptr[2] = flags;
11473f0f524bSJohan Hedberg 
11483f0f524bSJohan Hedberg 		ad_len += 3;
11493f0f524bSJohan Hedberg 		ptr += 3;
11503f0f524bSJohan Hedberg 	}
11513f0f524bSJohan Hedberg 
11523f0f524bSJohan Hedberg 	if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) {
11533f0f524bSJohan Hedberg 		ptr[0] = 2;
11543f0f524bSJohan Hedberg 		ptr[1] = EIR_TX_POWER;
11553f0f524bSJohan Hedberg 		ptr[2] = (u8) hdev->adv_tx_power;
11563f0f524bSJohan Hedberg 
11573f0f524bSJohan Hedberg 		ad_len += 3;
11583f0f524bSJohan Hedberg 		ptr += 3;
11593f0f524bSJohan Hedberg 	}
11603f0f524bSJohan Hedberg 
11613f0f524bSJohan Hedberg 	name_len = strlen(hdev->dev_name);
11623f0f524bSJohan Hedberg 	if (name_len > 0) {
11633f0f524bSJohan Hedberg 		size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
11643f0f524bSJohan Hedberg 
11653f0f524bSJohan Hedberg 		if (name_len > max_len) {
11663f0f524bSJohan Hedberg 			name_len = max_len;
11673f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_SHORT;
11683f0f524bSJohan Hedberg 		} else
11693f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_COMPLETE;
11703f0f524bSJohan Hedberg 
11713f0f524bSJohan Hedberg 		ptr[0] = name_len + 1;
11723f0f524bSJohan Hedberg 
11733f0f524bSJohan Hedberg 		memcpy(ptr + 2, hdev->dev_name, name_len);
11743f0f524bSJohan Hedberg 
11753f0f524bSJohan Hedberg 		ad_len += (name_len + 2);
11763f0f524bSJohan Hedberg 		ptr += (name_len + 2);
11773f0f524bSJohan Hedberg 	}
11783f0f524bSJohan Hedberg 
11793f0f524bSJohan Hedberg 	return ad_len;
11803f0f524bSJohan Hedberg }
11813f0f524bSJohan Hedberg 
118204b4edcbSJohan Hedberg void hci_update_ad(struct hci_request *req)
11833f0f524bSJohan Hedberg {
118404b4edcbSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
11853f0f524bSJohan Hedberg 	struct hci_cp_le_set_adv_data cp;
11863f0f524bSJohan Hedberg 	u8 len;
11873f0f524bSJohan Hedberg 
118804b4edcbSJohan Hedberg 	if (!lmp_le_capable(hdev))
118904b4edcbSJohan Hedberg 		return;
11903f0f524bSJohan Hedberg 
11913f0f524bSJohan Hedberg 	memset(&cp, 0, sizeof(cp));
11923f0f524bSJohan Hedberg 
11933f0f524bSJohan Hedberg 	len = create_ad(hdev, cp.data);
11943f0f524bSJohan Hedberg 
11953f0f524bSJohan Hedberg 	if (hdev->adv_data_len == len &&
119604b4edcbSJohan Hedberg 	    memcmp(cp.data, hdev->adv_data, len) == 0)
119704b4edcbSJohan Hedberg 		return;
11983f0f524bSJohan Hedberg 
11993f0f524bSJohan Hedberg 	memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
12003f0f524bSJohan Hedberg 	hdev->adv_data_len = len;
12013f0f524bSJohan Hedberg 
12023f0f524bSJohan Hedberg 	cp.length = len;
12033f0f524bSJohan Hedberg 
120404b4edcbSJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
12053f0f524bSJohan Hedberg }
12063f0f524bSJohan Hedberg 
1207cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
12081da177e4SLinus Torvalds {
12091da177e4SLinus Torvalds 	int ret = 0;
12101da177e4SLinus Torvalds 
12111da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
12121da177e4SLinus Torvalds 
12131da177e4SLinus Torvalds 	hci_req_lock(hdev);
12141da177e4SLinus Torvalds 
121594324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
121694324962SJohan Hovold 		ret = -ENODEV;
121794324962SJohan Hovold 		goto done;
121894324962SJohan Hovold 	}
121994324962SJohan Hovold 
1220a5c8f270SMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
1221a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1222a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1223bf543036SJohan Hedberg 		 */
1224a5c8f270SMarcel Holtmann 		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
1225611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1226611b30f7SMarcel Holtmann 			goto done;
1227611b30f7SMarcel Holtmann 		}
1228611b30f7SMarcel Holtmann 
1229a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
1230a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
1231a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1232a5c8f270SMarcel Holtmann 		 * or not.
1233a5c8f270SMarcel Holtmann 		 *
1234a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1235a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1236a5c8f270SMarcel Holtmann 		 */
1237a5c8f270SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR &&
1238a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1239a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1240a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1241a5c8f270SMarcel Holtmann 			goto done;
1242a5c8f270SMarcel Holtmann 		}
1243a5c8f270SMarcel Holtmann 	}
1244a5c8f270SMarcel Holtmann 
12451da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
12461da177e4SLinus Torvalds 		ret = -EALREADY;
12471da177e4SLinus Torvalds 		goto done;
12481da177e4SLinus Torvalds 	}
12491da177e4SLinus Torvalds 
12501da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
12511da177e4SLinus Torvalds 		ret = -EIO;
12521da177e4SLinus Torvalds 		goto done;
12531da177e4SLinus Torvalds 	}
12541da177e4SLinus Torvalds 
12551da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
12561da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1257f41c70c4SMarcel Holtmann 
1258f41c70c4SMarcel Holtmann 	if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
1259f41c70c4SMarcel Holtmann 		ret = hdev->setup(hdev);
1260f41c70c4SMarcel Holtmann 
1261f41c70c4SMarcel Holtmann 	if (!ret) {
1262f41c70c4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1263f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
1264f41c70c4SMarcel Holtmann 
12650736cfa8SMarcel Holtmann 		if (!test_bit(HCI_RAW, &hdev->flags) &&
12660736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
12672177bab5SJohan Hedberg 			ret = __hci_init(hdev);
12681da177e4SLinus Torvalds 	}
12691da177e4SLinus Torvalds 
1270f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1271f41c70c4SMarcel Holtmann 
12721da177e4SLinus Torvalds 	if (!ret) {
12731da177e4SLinus Torvalds 		hci_dev_hold(hdev);
12741da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
12751da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
1276bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
12770736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
12781514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
127909fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1280744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
128109fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
128256e5cb86SJohan Hedberg 		}
12831da177e4SLinus Torvalds 	} else {
12841da177e4SLinus Torvalds 		/* Init failed, cleanup */
12853eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1286c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1287b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
12881da177e4SLinus Torvalds 
12891da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
12901da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
12911da177e4SLinus Torvalds 
12921da177e4SLinus Torvalds 		if (hdev->flush)
12931da177e4SLinus Torvalds 			hdev->flush(hdev);
12941da177e4SLinus Torvalds 
12951da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
12961da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
12971da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
12981da177e4SLinus Torvalds 		}
12991da177e4SLinus Torvalds 
13001da177e4SLinus Torvalds 		hdev->close(hdev);
13011da177e4SLinus Torvalds 		hdev->flags = 0;
13021da177e4SLinus Torvalds 	}
13031da177e4SLinus Torvalds 
13041da177e4SLinus Torvalds done:
13051da177e4SLinus Torvalds 	hci_req_unlock(hdev);
13061da177e4SLinus Torvalds 	return ret;
13071da177e4SLinus Torvalds }
13081da177e4SLinus Torvalds 
1309cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
1310cbed0ca1SJohan Hedberg 
1311cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
1312cbed0ca1SJohan Hedberg {
1313cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
1314cbed0ca1SJohan Hedberg 	int err;
1315cbed0ca1SJohan Hedberg 
1316cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
1317cbed0ca1SJohan Hedberg 	if (!hdev)
1318cbed0ca1SJohan Hedberg 		return -ENODEV;
1319cbed0ca1SJohan Hedberg 
1320e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
1321e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
1322e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
1323e1d08f40SJohan Hedberg 	 * completed.
1324e1d08f40SJohan Hedberg 	 */
1325e1d08f40SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1326e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
1327e1d08f40SJohan Hedberg 
1328a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
1329a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
1330a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
1331a5c8f270SMarcel Holtmann 	 */
1332e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
1333e1d08f40SJohan Hedberg 
1334cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
1335cbed0ca1SJohan Hedberg 
1336cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
1337cbed0ca1SJohan Hedberg 
1338cbed0ca1SJohan Hedberg 	return err;
1339cbed0ca1SJohan Hedberg }
1340cbed0ca1SJohan Hedberg 
13411da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
13421da177e4SLinus Torvalds {
13431da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
13441da177e4SLinus Torvalds 
134578c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
134678c04c0bSVinicius Costa Gomes 
13471da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
13481da177e4SLinus Torvalds 	hci_req_lock(hdev);
13491da177e4SLinus Torvalds 
13501da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
1351b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
13521da177e4SLinus Torvalds 		hci_req_unlock(hdev);
13531da177e4SLinus Torvalds 		return 0;
13541da177e4SLinus Torvalds 	}
13551da177e4SLinus Torvalds 
13563eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
13573eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1358b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
13591da177e4SLinus Torvalds 
136016ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
1361e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
136216ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
13635e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
136416ab91abSJohan Hedberg 	}
136516ab91abSJohan Hedberg 
1366a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
13677d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
13687d78525dSJohan Hedberg 
13697ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
13707ba8b4beSAndre Guedes 
137109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13721f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
13731da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
137409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13751da177e4SLinus Torvalds 
13761da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
13771da177e4SLinus Torvalds 
13781da177e4SLinus Torvalds 	if (hdev->flush)
13791da177e4SLinus Torvalds 		hdev->flush(hdev);
13801da177e4SLinus Torvalds 
13811da177e4SLinus Torvalds 	/* Reset device */
13821da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
13831da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
13848af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
13853a6afbd2SMarcel Holtmann 	    !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
1386a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
13871da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
138801178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
13891da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
13901da177e4SLinus Torvalds 	}
13911da177e4SLinus Torvalds 
1392c347b765SGustavo F. Padovan 	/* flush cmd  work */
1393c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
13941da177e4SLinus Torvalds 
13951da177e4SLinus Torvalds 	/* Drop queues */
13961da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
13971da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
13981da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
13991da177e4SLinus Torvalds 
14001da177e4SLinus Torvalds 	/* Drop last sent command */
14011da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
1402b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
14031da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
14041da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
14051da177e4SLinus Torvalds 	}
14061da177e4SLinus Torvalds 
1407b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
1408b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
1409b6ddb638SJohan Hedberg 
14101da177e4SLinus Torvalds 	/* After this point our queues are empty
14111da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
14121da177e4SLinus Torvalds 	hdev->close(hdev);
14131da177e4SLinus Torvalds 
141435b973c9SJohan Hedberg 	/* Clear flags */
141535b973c9SJohan Hedberg 	hdev->flags = 0;
141635b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
141735b973c9SJohan Hedberg 
141893c311a0SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
141993c311a0SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR) {
142009fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1421744cf19eSJohan Hedberg 			mgmt_powered(hdev, 0);
142209fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
14238ee56540SMarcel Holtmann 		}
142493c311a0SMarcel Holtmann 	}
14255add6af8SJohan Hedberg 
1426ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1427536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
1428ced5c338SAndrei Emeltchenko 
1429e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
143009b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
1431e59fda8dSJohan Hedberg 
14321da177e4SLinus Torvalds 	hci_req_unlock(hdev);
14331da177e4SLinus Torvalds 
14341da177e4SLinus Torvalds 	hci_dev_put(hdev);
14351da177e4SLinus Torvalds 	return 0;
14361da177e4SLinus Torvalds }
14371da177e4SLinus Torvalds 
14381da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
14391da177e4SLinus Torvalds {
14401da177e4SLinus Torvalds 	struct hci_dev *hdev;
14411da177e4SLinus Torvalds 	int err;
14421da177e4SLinus Torvalds 
144370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
144470f23020SAndrei Emeltchenko 	if (!hdev)
14451da177e4SLinus Torvalds 		return -ENODEV;
14468ee56540SMarcel Holtmann 
14470736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
14480736cfa8SMarcel Holtmann 		err = -EBUSY;
14490736cfa8SMarcel Holtmann 		goto done;
14500736cfa8SMarcel Holtmann 	}
14510736cfa8SMarcel Holtmann 
14528ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
14538ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
14548ee56540SMarcel Holtmann 
14551da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
14568ee56540SMarcel Holtmann 
14570736cfa8SMarcel Holtmann done:
14581da177e4SLinus Torvalds 	hci_dev_put(hdev);
14591da177e4SLinus Torvalds 	return err;
14601da177e4SLinus Torvalds }
14611da177e4SLinus Torvalds 
14621da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
14631da177e4SLinus Torvalds {
14641da177e4SLinus Torvalds 	struct hci_dev *hdev;
14651da177e4SLinus Torvalds 	int ret = 0;
14661da177e4SLinus Torvalds 
146770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
146870f23020SAndrei Emeltchenko 	if (!hdev)
14691da177e4SLinus Torvalds 		return -ENODEV;
14701da177e4SLinus Torvalds 
14711da177e4SLinus Torvalds 	hci_req_lock(hdev);
14721da177e4SLinus Torvalds 
1473808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
1474808a049eSMarcel Holtmann 		ret = -ENETDOWN;
14751da177e4SLinus Torvalds 		goto done;
1476808a049eSMarcel Holtmann 	}
14771da177e4SLinus Torvalds 
14780736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
14790736cfa8SMarcel Holtmann 		ret = -EBUSY;
14800736cfa8SMarcel Holtmann 		goto done;
14810736cfa8SMarcel Holtmann 	}
14820736cfa8SMarcel Holtmann 
14831da177e4SLinus Torvalds 	/* Drop queues */
14841da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
14851da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
14861da177e4SLinus Torvalds 
148709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
14881f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
14891da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
149009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
14911da177e4SLinus Torvalds 
14921da177e4SLinus Torvalds 	if (hdev->flush)
14931da177e4SLinus Torvalds 		hdev->flush(hdev);
14941da177e4SLinus Torvalds 
14951da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
14966ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
14971da177e4SLinus Torvalds 
14981da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
149901178cd4SJohan Hedberg 		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
15001da177e4SLinus Torvalds 
15011da177e4SLinus Torvalds done:
15021da177e4SLinus Torvalds 	hci_req_unlock(hdev);
15031da177e4SLinus Torvalds 	hci_dev_put(hdev);
15041da177e4SLinus Torvalds 	return ret;
15051da177e4SLinus Torvalds }
15061da177e4SLinus Torvalds 
15071da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
15081da177e4SLinus Torvalds {
15091da177e4SLinus Torvalds 	struct hci_dev *hdev;
15101da177e4SLinus Torvalds 	int ret = 0;
15111da177e4SLinus Torvalds 
151270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
151370f23020SAndrei Emeltchenko 	if (!hdev)
15141da177e4SLinus Torvalds 		return -ENODEV;
15151da177e4SLinus Torvalds 
15160736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
15170736cfa8SMarcel Holtmann 		ret = -EBUSY;
15180736cfa8SMarcel Holtmann 		goto done;
15190736cfa8SMarcel Holtmann 	}
15200736cfa8SMarcel Holtmann 
15211da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
15221da177e4SLinus Torvalds 
15230736cfa8SMarcel Holtmann done:
15241da177e4SLinus Torvalds 	hci_dev_put(hdev);
15251da177e4SLinus Torvalds 	return ret;
15261da177e4SLinus Torvalds }
15271da177e4SLinus Torvalds 
15281da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
15291da177e4SLinus Torvalds {
15301da177e4SLinus Torvalds 	struct hci_dev *hdev;
15311da177e4SLinus Torvalds 	struct hci_dev_req dr;
15321da177e4SLinus Torvalds 	int err = 0;
15331da177e4SLinus Torvalds 
15341da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
15351da177e4SLinus Torvalds 		return -EFAULT;
15361da177e4SLinus Torvalds 
153770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
153870f23020SAndrei Emeltchenko 	if (!hdev)
15391da177e4SLinus Torvalds 		return -ENODEV;
15401da177e4SLinus Torvalds 
15410736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
15420736cfa8SMarcel Holtmann 		err = -EBUSY;
15430736cfa8SMarcel Holtmann 		goto done;
15440736cfa8SMarcel Holtmann 	}
15450736cfa8SMarcel Holtmann 
15465b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
15475b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
15485b69bef5SMarcel Holtmann 		goto done;
15495b69bef5SMarcel Holtmann 	}
15505b69bef5SMarcel Holtmann 
155156f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
155256f87901SJohan Hedberg 		err = -EOPNOTSUPP;
155356f87901SJohan Hedberg 		goto done;
155456f87901SJohan Hedberg 	}
155556f87901SJohan Hedberg 
15561da177e4SLinus Torvalds 	switch (cmd) {
15571da177e4SLinus Torvalds 	case HCISETAUTH:
155801178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
15595f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15601da177e4SLinus Torvalds 		break;
15611da177e4SLinus Torvalds 
15621da177e4SLinus Torvalds 	case HCISETENCRYPT:
15631da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
15641da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
15651da177e4SLinus Torvalds 			break;
15661da177e4SLinus Torvalds 		}
15671da177e4SLinus Torvalds 
15681da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
15691da177e4SLinus Torvalds 			/* Auth must be enabled first */
157001178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
15715f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
15721da177e4SLinus Torvalds 			if (err)
15731da177e4SLinus Torvalds 				break;
15741da177e4SLinus Torvalds 		}
15751da177e4SLinus Torvalds 
157601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
15775f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15781da177e4SLinus Torvalds 		break;
15791da177e4SLinus Torvalds 
15801da177e4SLinus Torvalds 	case HCISETSCAN:
158101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
15825f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15831da177e4SLinus Torvalds 		break;
15841da177e4SLinus Torvalds 
15851da177e4SLinus Torvalds 	case HCISETLINKPOL:
158601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
15875f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15881da177e4SLinus Torvalds 		break;
15891da177e4SLinus Torvalds 
15901da177e4SLinus Torvalds 	case HCISETLINKMODE:
1591e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
1592e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
1593e4e8e37cSMarcel Holtmann 		break;
1594e4e8e37cSMarcel Holtmann 
1595e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
1596e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
15971da177e4SLinus Torvalds 		break;
15981da177e4SLinus Torvalds 
15991da177e4SLinus Torvalds 	case HCISETACLMTU:
16001da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
16011da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
16021da177e4SLinus Torvalds 		break;
16031da177e4SLinus Torvalds 
16041da177e4SLinus Torvalds 	case HCISETSCOMTU:
16051da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
16061da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
16071da177e4SLinus Torvalds 		break;
16081da177e4SLinus Torvalds 
16091da177e4SLinus Torvalds 	default:
16101da177e4SLinus Torvalds 		err = -EINVAL;
16111da177e4SLinus Torvalds 		break;
16121da177e4SLinus Torvalds 	}
1613e4e8e37cSMarcel Holtmann 
16140736cfa8SMarcel Holtmann done:
16151da177e4SLinus Torvalds 	hci_dev_put(hdev);
16161da177e4SLinus Torvalds 	return err;
16171da177e4SLinus Torvalds }
16181da177e4SLinus Torvalds 
16191da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
16201da177e4SLinus Torvalds {
16218035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
16221da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
16231da177e4SLinus Torvalds 	struct hci_dev_req *dr;
16241da177e4SLinus Torvalds 	int n = 0, size, err;
16251da177e4SLinus Torvalds 	__u16 dev_num;
16261da177e4SLinus Torvalds 
16271da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
16281da177e4SLinus Torvalds 		return -EFAULT;
16291da177e4SLinus Torvalds 
16301da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
16311da177e4SLinus Torvalds 		return -EINVAL;
16321da177e4SLinus Torvalds 
16331da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
16341da177e4SLinus Torvalds 
163570f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
163670f23020SAndrei Emeltchenko 	if (!dl)
16371da177e4SLinus Torvalds 		return -ENOMEM;
16381da177e4SLinus Torvalds 
16391da177e4SLinus Torvalds 	dr = dl->dev_req;
16401da177e4SLinus Torvalds 
1641f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
16428035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
1643a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1644e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
1645c542a06cSJohan Hedberg 
1646a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1647a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1648c542a06cSJohan Hedberg 
16491da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
16501da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
1651c542a06cSJohan Hedberg 
16521da177e4SLinus Torvalds 		if (++n >= dev_num)
16531da177e4SLinus Torvalds 			break;
16541da177e4SLinus Torvalds 	}
1655f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
16561da177e4SLinus Torvalds 
16571da177e4SLinus Torvalds 	dl->dev_num = n;
16581da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
16591da177e4SLinus Torvalds 
16601da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
16611da177e4SLinus Torvalds 	kfree(dl);
16621da177e4SLinus Torvalds 
16631da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
16641da177e4SLinus Torvalds }
16651da177e4SLinus Torvalds 
16661da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
16671da177e4SLinus Torvalds {
16681da177e4SLinus Torvalds 	struct hci_dev *hdev;
16691da177e4SLinus Torvalds 	struct hci_dev_info di;
16701da177e4SLinus Torvalds 	int err = 0;
16711da177e4SLinus Torvalds 
16721da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
16731da177e4SLinus Torvalds 		return -EFAULT;
16741da177e4SLinus Torvalds 
167570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
167670f23020SAndrei Emeltchenko 	if (!hdev)
16771da177e4SLinus Torvalds 		return -ENODEV;
16781da177e4SLinus Torvalds 
1679a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
16803243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1681ab81cbf9SJohan Hedberg 
1682a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1683a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1684c542a06cSJohan Hedberg 
16851da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
16861da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
168760f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
16881da177e4SLinus Torvalds 	di.flags    = hdev->flags;
16891da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
1690572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
16911da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
16921da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
16931da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
16941da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
1695572c7f84SJohan Hedberg 	} else {
1696572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
1697572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
1698572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
1699572c7f84SJohan Hedberg 		di.sco_pkts = 0;
1700572c7f84SJohan Hedberg 	}
17011da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
17021da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
17031da177e4SLinus Torvalds 
17041da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
17051da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
17061da177e4SLinus Torvalds 
17071da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
17081da177e4SLinus Torvalds 		err = -EFAULT;
17091da177e4SLinus Torvalds 
17101da177e4SLinus Torvalds 	hci_dev_put(hdev);
17111da177e4SLinus Torvalds 
17121da177e4SLinus Torvalds 	return err;
17131da177e4SLinus Torvalds }
17141da177e4SLinus Torvalds 
17151da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
17161da177e4SLinus Torvalds 
1717611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1718611b30f7SMarcel Holtmann {
1719611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1720611b30f7SMarcel Holtmann 
1721611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1722611b30f7SMarcel Holtmann 
17230736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
17240736cfa8SMarcel Holtmann 		return -EBUSY;
17250736cfa8SMarcel Holtmann 
17265e130367SJohan Hedberg 	if (blocked) {
17275e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
1728bf543036SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags))
1729611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
17305e130367SJohan Hedberg 	} else {
17315e130367SJohan Hedberg 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
17325e130367SJohan Hedberg 	}
1733611b30f7SMarcel Holtmann 
1734611b30f7SMarcel Holtmann 	return 0;
1735611b30f7SMarcel Holtmann }
1736611b30f7SMarcel Holtmann 
1737611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1738611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1739611b30f7SMarcel Holtmann };
1740611b30f7SMarcel Holtmann 
1741ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1742ab81cbf9SJohan Hedberg {
1743ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
174496570ffcSJohan Hedberg 	int err;
1745ab81cbf9SJohan Hedberg 
1746ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1747ab81cbf9SJohan Hedberg 
1748cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
174996570ffcSJohan Hedberg 	if (err < 0) {
175096570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
1751ab81cbf9SJohan Hedberg 		return;
175296570ffcSJohan Hedberg 	}
1753ab81cbf9SJohan Hedberg 
1754a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
1755a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
1756a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
1757a5c8f270SMarcel Holtmann 	 */
1758a5c8f270SMarcel Holtmann 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
1759a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
1760a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1761a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
1762bf543036SJohan Hedberg 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
1763bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
1764bf543036SJohan Hedberg 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
176519202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
176619202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
1767bf543036SJohan Hedberg 	}
1768ab81cbf9SJohan Hedberg 
1769a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1770744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1771ab81cbf9SJohan Hedberg }
1772ab81cbf9SJohan Hedberg 
1773ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1774ab81cbf9SJohan Hedberg {
17753243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
17763243553fSJohan Hedberg 					    power_off.work);
1777ab81cbf9SJohan Hedberg 
1778ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1779ab81cbf9SJohan Hedberg 
17808ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1781ab81cbf9SJohan Hedberg }
1782ab81cbf9SJohan Hedberg 
178316ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
178416ab91abSJohan Hedberg {
178516ab91abSJohan Hedberg 	struct hci_dev *hdev;
178616ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
178716ab91abSJohan Hedberg 
178816ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
178916ab91abSJohan Hedberg 
179016ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
179116ab91abSJohan Hedberg 
179209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
179316ab91abSJohan Hedberg 
179416ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
179516ab91abSJohan Hedberg 
179616ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
179716ab91abSJohan Hedberg 
179809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
179916ab91abSJohan Hedberg }
180016ab91abSJohan Hedberg 
18012aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
18022aeb9a1aSJohan Hedberg {
18034821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
18042aeb9a1aSJohan Hedberg 
18054821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
18064821002cSJohan Hedberg 		list_del(&uuid->list);
18072aeb9a1aSJohan Hedberg 		kfree(uuid);
18082aeb9a1aSJohan Hedberg 	}
18092aeb9a1aSJohan Hedberg 
18102aeb9a1aSJohan Hedberg 	return 0;
18112aeb9a1aSJohan Hedberg }
18122aeb9a1aSJohan Hedberg 
181355ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
181455ed8ca1SJohan Hedberg {
181555ed8ca1SJohan Hedberg 	struct list_head *p, *n;
181655ed8ca1SJohan Hedberg 
181755ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
181855ed8ca1SJohan Hedberg 		struct link_key *key;
181955ed8ca1SJohan Hedberg 
182055ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
182155ed8ca1SJohan Hedberg 
182255ed8ca1SJohan Hedberg 		list_del(p);
182355ed8ca1SJohan Hedberg 		kfree(key);
182455ed8ca1SJohan Hedberg 	}
182555ed8ca1SJohan Hedberg 
182655ed8ca1SJohan Hedberg 	return 0;
182755ed8ca1SJohan Hedberg }
182855ed8ca1SJohan Hedberg 
1829b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1830b899efafSVinicius Costa Gomes {
1831b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1832b899efafSVinicius Costa Gomes 
1833b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1834b899efafSVinicius Costa Gomes 		list_del(&k->list);
1835b899efafSVinicius Costa Gomes 		kfree(k);
1836b899efafSVinicius Costa Gomes 	}
1837b899efafSVinicius Costa Gomes 
1838b899efafSVinicius Costa Gomes 	return 0;
1839b899efafSVinicius Costa Gomes }
1840b899efafSVinicius Costa Gomes 
184155ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
184255ed8ca1SJohan Hedberg {
184355ed8ca1SJohan Hedberg 	struct link_key *k;
184455ed8ca1SJohan Hedberg 
18458035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
184655ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
184755ed8ca1SJohan Hedberg 			return k;
184855ed8ca1SJohan Hedberg 
184955ed8ca1SJohan Hedberg 	return NULL;
185055ed8ca1SJohan Hedberg }
185155ed8ca1SJohan Hedberg 
1852745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1853d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1854d25e28abSJohan Hedberg {
1855d25e28abSJohan Hedberg 	/* Legacy key */
1856d25e28abSJohan Hedberg 	if (key_type < 0x03)
1857745c0ce3SVishal Agarwal 		return true;
1858d25e28abSJohan Hedberg 
1859d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1860d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1861745c0ce3SVishal Agarwal 		return false;
1862d25e28abSJohan Hedberg 
1863d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1864d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1865745c0ce3SVishal Agarwal 		return false;
1866d25e28abSJohan Hedberg 
1867d25e28abSJohan Hedberg 	/* Security mode 3 case */
1868d25e28abSJohan Hedberg 	if (!conn)
1869745c0ce3SVishal Agarwal 		return true;
1870d25e28abSJohan Hedberg 
1871d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1872d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1873745c0ce3SVishal Agarwal 		return true;
1874d25e28abSJohan Hedberg 
1875d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1876d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1877745c0ce3SVishal Agarwal 		return true;
1878d25e28abSJohan Hedberg 
1879d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1880d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1881745c0ce3SVishal Agarwal 		return true;
1882d25e28abSJohan Hedberg 
1883d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1884d25e28abSJohan Hedberg 	 * persistently */
1885745c0ce3SVishal Agarwal 	return false;
1886d25e28abSJohan Hedberg }
1887d25e28abSJohan Hedberg 
1888c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
188975d262c2SVinicius Costa Gomes {
1890c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
189175d262c2SVinicius Costa Gomes 
1892c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1893c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1894c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
189575d262c2SVinicius Costa Gomes 			continue;
189675d262c2SVinicius Costa Gomes 
189775d262c2SVinicius Costa Gomes 		return k;
189875d262c2SVinicius Costa Gomes 	}
189975d262c2SVinicius Costa Gomes 
190075d262c2SVinicius Costa Gomes 	return NULL;
190175d262c2SVinicius Costa Gomes }
190275d262c2SVinicius Costa Gomes 
1903c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1904c9839a11SVinicius Costa Gomes 				     u8 addr_type)
190575d262c2SVinicius Costa Gomes {
1906c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
190775d262c2SVinicius Costa Gomes 
1908c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1909c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1910c9839a11SVinicius Costa Gomes 		    bacmp(bdaddr, &k->bdaddr) == 0)
191175d262c2SVinicius Costa Gomes 			return k;
191275d262c2SVinicius Costa Gomes 
191375d262c2SVinicius Costa Gomes 	return NULL;
191475d262c2SVinicius Costa Gomes }
191575d262c2SVinicius Costa Gomes 
1916d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1917d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
191855ed8ca1SJohan Hedberg {
191955ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1920745c0ce3SVishal Agarwal 	u8 old_key_type;
1921745c0ce3SVishal Agarwal 	bool persistent;
192255ed8ca1SJohan Hedberg 
192355ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
192455ed8ca1SJohan Hedberg 	if (old_key) {
192555ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
192655ed8ca1SJohan Hedberg 		key = old_key;
192755ed8ca1SJohan Hedberg 	} else {
192812adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
192955ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
193055ed8ca1SJohan Hedberg 		if (!key)
193155ed8ca1SJohan Hedberg 			return -ENOMEM;
193255ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
193355ed8ca1SJohan Hedberg 	}
193455ed8ca1SJohan Hedberg 
19356ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
193655ed8ca1SJohan Hedberg 
1937d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1938d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1939d25e28abSJohan Hedberg 	 * previous key */
1940d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1941a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1942d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1943655fe6ecSJohan Hedberg 		if (conn)
1944655fe6ecSJohan Hedberg 			conn->key_type = type;
1945655fe6ecSJohan Hedberg 	}
1946d25e28abSJohan Hedberg 
194755ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
19489b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
194955ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
195055ed8ca1SJohan Hedberg 
1951b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
195255ed8ca1SJohan Hedberg 		key->type = old_key_type;
19534748fed2SJohan Hedberg 	else
19544748fed2SJohan Hedberg 		key->type = type;
19554748fed2SJohan Hedberg 
19564df378a1SJohan Hedberg 	if (!new_key)
19574df378a1SJohan Hedberg 		return 0;
19584df378a1SJohan Hedberg 
19594df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
19604df378a1SJohan Hedberg 
1961744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
19624df378a1SJohan Hedberg 
19636ec5bcadSVishal Agarwal 	if (conn)
19646ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
196555ed8ca1SJohan Hedberg 
196655ed8ca1SJohan Hedberg 	return 0;
196755ed8ca1SJohan Hedberg }
196855ed8ca1SJohan Hedberg 
1969c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
19709a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
197104124681SGustavo F. Padovan 		ediv, u8 rand[8])
197275d262c2SVinicius Costa Gomes {
1973c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
197475d262c2SVinicius Costa Gomes 
1975c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1976c9839a11SVinicius Costa Gomes 		return 0;
197775d262c2SVinicius Costa Gomes 
1978c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1979c9839a11SVinicius Costa Gomes 	if (old_key)
198075d262c2SVinicius Costa Gomes 		key = old_key;
1981c9839a11SVinicius Costa Gomes 	else {
1982c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
198375d262c2SVinicius Costa Gomes 		if (!key)
198475d262c2SVinicius Costa Gomes 			return -ENOMEM;
1985c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
198675d262c2SVinicius Costa Gomes 	}
198775d262c2SVinicius Costa Gomes 
198875d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1989c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1990c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1991c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1992c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1993c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1994c9839a11SVinicius Costa Gomes 	key->type = type;
1995c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
199675d262c2SVinicius Costa Gomes 
1997c9839a11SVinicius Costa Gomes 	if (!new_key)
1998c9839a11SVinicius Costa Gomes 		return 0;
199975d262c2SVinicius Costa Gomes 
2000261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
2001261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
2002261cc5aaSVinicius Costa Gomes 
200375d262c2SVinicius Costa Gomes 	return 0;
200475d262c2SVinicius Costa Gomes }
200575d262c2SVinicius Costa Gomes 
200655ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
200755ed8ca1SJohan Hedberg {
200855ed8ca1SJohan Hedberg 	struct link_key *key;
200955ed8ca1SJohan Hedberg 
201055ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
201155ed8ca1SJohan Hedberg 	if (!key)
201255ed8ca1SJohan Hedberg 		return -ENOENT;
201355ed8ca1SJohan Hedberg 
20146ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
201555ed8ca1SJohan Hedberg 
201655ed8ca1SJohan Hedberg 	list_del(&key->list);
201755ed8ca1SJohan Hedberg 	kfree(key);
201855ed8ca1SJohan Hedberg 
201955ed8ca1SJohan Hedberg 	return 0;
202055ed8ca1SJohan Hedberg }
202155ed8ca1SJohan Hedberg 
2022b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
2023b899efafSVinicius Costa Gomes {
2024b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
2025b899efafSVinicius Costa Gomes 
2026b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2027b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
2028b899efafSVinicius Costa Gomes 			continue;
2029b899efafSVinicius Costa Gomes 
20306ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2031b899efafSVinicius Costa Gomes 
2032b899efafSVinicius Costa Gomes 		list_del(&k->list);
2033b899efafSVinicius Costa Gomes 		kfree(k);
2034b899efafSVinicius Costa Gomes 	}
2035b899efafSVinicius Costa Gomes 
2036b899efafSVinicius Costa Gomes 	return 0;
2037b899efafSVinicius Costa Gomes }
2038b899efafSVinicius Costa Gomes 
20396bd32326SVille Tervo /* HCI command timer function */
2040bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
20416bd32326SVille Tervo {
20426bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
20436bd32326SVille Tervo 
2044bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2045bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2046bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2047bda4f23aSAndrei Emeltchenko 
2048bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
2049bda4f23aSAndrei Emeltchenko 	} else {
20506bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
2051bda4f23aSAndrei Emeltchenko 	}
2052bda4f23aSAndrei Emeltchenko 
20536bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2054c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
20556bd32326SVille Tervo }
20566bd32326SVille Tervo 
20572763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
20582763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
20592763eda6SSzymon Janc {
20602763eda6SSzymon Janc 	struct oob_data *data;
20612763eda6SSzymon Janc 
20622763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
20632763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
20642763eda6SSzymon Janc 			return data;
20652763eda6SSzymon Janc 
20662763eda6SSzymon Janc 	return NULL;
20672763eda6SSzymon Janc }
20682763eda6SSzymon Janc 
20692763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
20702763eda6SSzymon Janc {
20712763eda6SSzymon Janc 	struct oob_data *data;
20722763eda6SSzymon Janc 
20732763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
20742763eda6SSzymon Janc 	if (!data)
20752763eda6SSzymon Janc 		return -ENOENT;
20762763eda6SSzymon Janc 
20776ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
20782763eda6SSzymon Janc 
20792763eda6SSzymon Janc 	list_del(&data->list);
20802763eda6SSzymon Janc 	kfree(data);
20812763eda6SSzymon Janc 
20822763eda6SSzymon Janc 	return 0;
20832763eda6SSzymon Janc }
20842763eda6SSzymon Janc 
20852763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
20862763eda6SSzymon Janc {
20872763eda6SSzymon Janc 	struct oob_data *data, *n;
20882763eda6SSzymon Janc 
20892763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
20902763eda6SSzymon Janc 		list_del(&data->list);
20912763eda6SSzymon Janc 		kfree(data);
20922763eda6SSzymon Janc 	}
20932763eda6SSzymon Janc 
20942763eda6SSzymon Janc 	return 0;
20952763eda6SSzymon Janc }
20962763eda6SSzymon Janc 
20972763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
20982763eda6SSzymon Janc 			    u8 *randomizer)
20992763eda6SSzymon Janc {
21002763eda6SSzymon Janc 	struct oob_data *data;
21012763eda6SSzymon Janc 
21022763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
21032763eda6SSzymon Janc 
21042763eda6SSzymon Janc 	if (!data) {
21052763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
21062763eda6SSzymon Janc 		if (!data)
21072763eda6SSzymon Janc 			return -ENOMEM;
21082763eda6SSzymon Janc 
21092763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
21102763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
21112763eda6SSzymon Janc 	}
21122763eda6SSzymon Janc 
21132763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
21142763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
21152763eda6SSzymon Janc 
21166ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
21172763eda6SSzymon Janc 
21182763eda6SSzymon Janc 	return 0;
21192763eda6SSzymon Janc }
21202763eda6SSzymon Janc 
212104124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
2122b2a66aadSAntti Julku {
2123b2a66aadSAntti Julku 	struct bdaddr_list *b;
2124b2a66aadSAntti Julku 
21258035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
2126b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
2127b2a66aadSAntti Julku 			return b;
2128b2a66aadSAntti Julku 
2129b2a66aadSAntti Julku 	return NULL;
2130b2a66aadSAntti Julku }
2131b2a66aadSAntti Julku 
2132b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
2133b2a66aadSAntti Julku {
2134b2a66aadSAntti Julku 	struct list_head *p, *n;
2135b2a66aadSAntti Julku 
2136b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
2137b2a66aadSAntti Julku 		struct bdaddr_list *b;
2138b2a66aadSAntti Julku 
2139b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
2140b2a66aadSAntti Julku 
2141b2a66aadSAntti Julku 		list_del(p);
2142b2a66aadSAntti Julku 		kfree(b);
2143b2a66aadSAntti Julku 	}
2144b2a66aadSAntti Julku 
2145b2a66aadSAntti Julku 	return 0;
2146b2a66aadSAntti Julku }
2147b2a66aadSAntti Julku 
214888c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2149b2a66aadSAntti Julku {
2150b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2151b2a66aadSAntti Julku 
2152b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
2153b2a66aadSAntti Julku 		return -EBADF;
2154b2a66aadSAntti Julku 
21555e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
21565e762444SAntti Julku 		return -EEXIST;
2157b2a66aadSAntti Julku 
2158b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
21595e762444SAntti Julku 	if (!entry)
21605e762444SAntti Julku 		return -ENOMEM;
2161b2a66aadSAntti Julku 
2162b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2163b2a66aadSAntti Julku 
2164b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
2165b2a66aadSAntti Julku 
216688c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
2167b2a66aadSAntti Julku }
2168b2a66aadSAntti Julku 
216988c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2170b2a66aadSAntti Julku {
2171b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2172b2a66aadSAntti Julku 
21731ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
21745e762444SAntti Julku 		return hci_blacklist_clear(hdev);
2175b2a66aadSAntti Julku 
2176b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
21771ec918ceSSzymon Janc 	if (!entry)
21785e762444SAntti Julku 		return -ENOENT;
2179b2a66aadSAntti Julku 
2180b2a66aadSAntti Julku 	list_del(&entry->list);
2181b2a66aadSAntti Julku 	kfree(entry);
2182b2a66aadSAntti Julku 
218388c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
2184b2a66aadSAntti Julku }
2185b2a66aadSAntti Julku 
21864c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
21877ba8b4beSAndre Guedes {
21884c87eaabSAndre Guedes 	if (status) {
21894c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
21907ba8b4beSAndre Guedes 
21914c87eaabSAndre Guedes 		hci_dev_lock(hdev);
21924c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
21934c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
21944c87eaabSAndre Guedes 		return;
21954c87eaabSAndre Guedes 	}
21967ba8b4beSAndre Guedes }
21977ba8b4beSAndre Guedes 
21984c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
21997ba8b4beSAndre Guedes {
22004c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
22014c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
22024c87eaabSAndre Guedes 	struct hci_request req;
22034c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
22047ba8b4beSAndre Guedes 	int err;
22057ba8b4beSAndre Guedes 
22064c87eaabSAndre Guedes 	if (status) {
22074c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
22084c87eaabSAndre Guedes 		return;
22097ba8b4beSAndre Guedes 	}
22107ba8b4beSAndre Guedes 
22114c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
22124c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
22134c87eaabSAndre Guedes 		hci_dev_lock(hdev);
22144c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
22154c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
22164c87eaabSAndre Guedes 		break;
22177dbfac1dSAndre Guedes 
22184c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
22194c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
22207dbfac1dSAndre Guedes 
22217dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
22224c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
22234c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
22244c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
22254c87eaabSAndre Guedes 
22264c87eaabSAndre Guedes 		hci_dev_lock(hdev);
22274c87eaabSAndre Guedes 
22284c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
22294c87eaabSAndre Guedes 
22304c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
22314c87eaabSAndre Guedes 		if (err) {
22324c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
22334c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
22347dbfac1dSAndre Guedes 		}
22357dbfac1dSAndre Guedes 
22364c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
22374c87eaabSAndre Guedes 		break;
22384c87eaabSAndre Guedes 	}
22397dbfac1dSAndre Guedes }
22407dbfac1dSAndre Guedes 
22417ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
22427ba8b4beSAndre Guedes {
22437ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
22447ba8b4beSAndre Guedes 					    le_scan_disable.work);
22457ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
22464c87eaabSAndre Guedes 	struct hci_request req;
22474c87eaabSAndre Guedes 	int err;
22487ba8b4beSAndre Guedes 
22497ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
22507ba8b4beSAndre Guedes 
22514c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
22527ba8b4beSAndre Guedes 
22537ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
22544c87eaabSAndre Guedes 	cp.enable = LE_SCAN_DISABLE;
22554c87eaabSAndre Guedes 	hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
22567ba8b4beSAndre Guedes 
22574c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
22584c87eaabSAndre Guedes 	if (err)
22594c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
226028b75a89SAndre Guedes }
226128b75a89SAndre Guedes 
22629be0dab7SDavid Herrmann /* Alloc HCI device */
22639be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
22649be0dab7SDavid Herrmann {
22659be0dab7SDavid Herrmann 	struct hci_dev *hdev;
22669be0dab7SDavid Herrmann 
22679be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
22689be0dab7SDavid Herrmann 	if (!hdev)
22699be0dab7SDavid Herrmann 		return NULL;
22709be0dab7SDavid Herrmann 
2271b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2272b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
2273b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
2274b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03; /* No Input No Output */
2275bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2276bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2277b1b813d4SDavid Herrmann 
2278b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
2279b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
2280b1b813d4SDavid Herrmann 
2281bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
2282bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
2283bef64738SMarcel Holtmann 
2284b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
2285b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
2286b1b813d4SDavid Herrmann 
2287b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
2288b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
2289b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
2290b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
2291b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
2292b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
22936b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
2294b1b813d4SDavid Herrmann 
2295b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2296b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2297b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2298b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2299b1b813d4SDavid Herrmann 
2300b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2301b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
2302b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
2303b1b813d4SDavid Herrmann 
2304b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2305b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2306b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2307b1b813d4SDavid Herrmann 
2308b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2309b1b813d4SDavid Herrmann 
2310bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
2311b1b813d4SDavid Herrmann 
2312b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2313b1b813d4SDavid Herrmann 	discovery_init(hdev);
23149be0dab7SDavid Herrmann 
23159be0dab7SDavid Herrmann 	return hdev;
23169be0dab7SDavid Herrmann }
23179be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
23189be0dab7SDavid Herrmann 
23199be0dab7SDavid Herrmann /* Free HCI device */
23209be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
23219be0dab7SDavid Herrmann {
23229be0dab7SDavid Herrmann 	/* will free via device release */
23239be0dab7SDavid Herrmann 	put_device(&hdev->dev);
23249be0dab7SDavid Herrmann }
23259be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
23269be0dab7SDavid Herrmann 
23271da177e4SLinus Torvalds /* Register HCI device */
23281da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
23291da177e4SLinus Torvalds {
2330b1b813d4SDavid Herrmann 	int id, error;
23311da177e4SLinus Torvalds 
2332010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
23331da177e4SLinus Torvalds 		return -EINVAL;
23341da177e4SLinus Torvalds 
233508add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
233608add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
233708add513SMat Martineau 	 */
23383df92b31SSasha Levin 	switch (hdev->dev_type) {
23393df92b31SSasha Levin 	case HCI_BREDR:
23403df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
23411da177e4SLinus Torvalds 		break;
23423df92b31SSasha Levin 	case HCI_AMP:
23433df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
23443df92b31SSasha Levin 		break;
23453df92b31SSasha Levin 	default:
23463df92b31SSasha Levin 		return -EINVAL;
23471da177e4SLinus Torvalds 	}
23481da177e4SLinus Torvalds 
23493df92b31SSasha Levin 	if (id < 0)
23503df92b31SSasha Levin 		return id;
23513df92b31SSasha Levin 
23521da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
23531da177e4SLinus Torvalds 	hdev->id = id;
23542d8b3a11SAndrei Emeltchenko 
23552d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
23562d8b3a11SAndrei Emeltchenko 
2357d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
2358d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
235933ca954dSDavid Herrmann 	if (!hdev->workqueue) {
236033ca954dSDavid Herrmann 		error = -ENOMEM;
236133ca954dSDavid Herrmann 		goto err;
236233ca954dSDavid Herrmann 	}
2363f48fd9c8SMarcel Holtmann 
2364d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
2365d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
23666ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
23676ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
23686ead1bbcSJohan Hedberg 		error = -ENOMEM;
23696ead1bbcSJohan Hedberg 		goto err;
23706ead1bbcSJohan Hedberg 	}
23716ead1bbcSJohan Hedberg 
237233ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
237333ca954dSDavid Herrmann 	if (error < 0)
237433ca954dSDavid Herrmann 		goto err_wqueue;
23751da177e4SLinus Torvalds 
2376611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2377a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2378a8c5fb1aSGustavo Padovan 				    hdev);
2379611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2380611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
2381611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
2382611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
2383611b30f7SMarcel Holtmann 		}
2384611b30f7SMarcel Holtmann 	}
2385611b30f7SMarcel Holtmann 
23865e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
23875e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
23885e130367SJohan Hedberg 
2389a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
2390004b0258SMarcel Holtmann 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2391ce2be9acSAndrei Emeltchenko 
239201cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
239356f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
239456f87901SJohan Hedberg 		 * through reading supported features during init.
239556f87901SJohan Hedberg 		 */
239656f87901SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
239756f87901SJohan Hedberg 	}
2398ce2be9acSAndrei Emeltchenko 
2399fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
2400fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
2401fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
2402fcee3377SGustavo Padovan 
24031da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
2404dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
24051da177e4SLinus Torvalds 
240619202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2407fbe96d6fSMarcel Holtmann 
24081da177e4SLinus Torvalds 	return id;
2409f48fd9c8SMarcel Holtmann 
241033ca954dSDavid Herrmann err_wqueue:
241133ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
24126ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
241333ca954dSDavid Herrmann err:
24143df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
2415f48fd9c8SMarcel Holtmann 
241633ca954dSDavid Herrmann 	return error;
24171da177e4SLinus Torvalds }
24181da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
24191da177e4SLinus Torvalds 
24201da177e4SLinus Torvalds /* Unregister HCI device */
242159735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
24221da177e4SLinus Torvalds {
24233df92b31SSasha Levin 	int i, id;
2424ef222013SMarcel Holtmann 
2425c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
24261da177e4SLinus Torvalds 
242794324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
242894324962SJohan Hovold 
24293df92b31SSasha Levin 	id = hdev->id;
24303df92b31SSasha Levin 
2431f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
24321da177e4SLinus Torvalds 	list_del(&hdev->list);
2433f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
24341da177e4SLinus Torvalds 
24351da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
24361da177e4SLinus Torvalds 
2437cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
2438ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
2439ef222013SMarcel Holtmann 
2440b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
2441b9b5ef18SGustavo Padovan 
2442ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2443a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
244409fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2445744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
244609fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
244756e5cb86SJohan Hedberg 	}
2448ab81cbf9SJohan Hedberg 
24492e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
24502e58ef3eSJohan Hedberg 	 * pending list */
24512e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
24522e58ef3eSJohan Hedberg 
24531da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
24541da177e4SLinus Torvalds 
2455611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2456611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2457611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2458611b30f7SMarcel Holtmann 	}
2459611b30f7SMarcel Holtmann 
2460ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
2461147e2d59SDave Young 
2462f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
24636ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2464f48fd9c8SMarcel Holtmann 
246509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
2466e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
24672aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
246855ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2469b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
24702763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
247109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2472e2e0cacbSJohan Hedberg 
2473dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
24743df92b31SSasha Levin 
24753df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
24761da177e4SLinus Torvalds }
24771da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
24781da177e4SLinus Torvalds 
24791da177e4SLinus Torvalds /* Suspend HCI device */
24801da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
24811da177e4SLinus Torvalds {
24821da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
24831da177e4SLinus Torvalds 	return 0;
24841da177e4SLinus Torvalds }
24851da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
24861da177e4SLinus Torvalds 
24871da177e4SLinus Torvalds /* Resume HCI device */
24881da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
24891da177e4SLinus Torvalds {
24901da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
24911da177e4SLinus Torvalds 	return 0;
24921da177e4SLinus Torvalds }
24931da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
24941da177e4SLinus Torvalds 
249576bca880SMarcel Holtmann /* Receive frame from HCI drivers */
2496e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
249776bca880SMarcel Holtmann {
249876bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
249976bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
250076bca880SMarcel Holtmann 		kfree_skb(skb);
250176bca880SMarcel Holtmann 		return -ENXIO;
250276bca880SMarcel Holtmann 	}
250376bca880SMarcel Holtmann 
2504d82603c6SJorrit Schippers 	/* Incoming skb */
250576bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
250676bca880SMarcel Holtmann 
250776bca880SMarcel Holtmann 	/* Time stamp */
250876bca880SMarcel Holtmann 	__net_timestamp(skb);
250976bca880SMarcel Holtmann 
251076bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2511b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2512c78ae283SMarcel Holtmann 
251376bca880SMarcel Holtmann 	return 0;
251476bca880SMarcel Holtmann }
251576bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
251676bca880SMarcel Holtmann 
251733e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
25181e429f38SGustavo F. Padovan 			  int count, __u8 index)
251933e882a5SSuraj Sumangala {
252033e882a5SSuraj Sumangala 	int len = 0;
252133e882a5SSuraj Sumangala 	int hlen = 0;
252233e882a5SSuraj Sumangala 	int remain = count;
252333e882a5SSuraj Sumangala 	struct sk_buff *skb;
252433e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
252533e882a5SSuraj Sumangala 
252633e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
252733e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
252833e882a5SSuraj Sumangala 		return -EILSEQ;
252933e882a5SSuraj Sumangala 
253033e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
253133e882a5SSuraj Sumangala 
253233e882a5SSuraj Sumangala 	if (!skb) {
253333e882a5SSuraj Sumangala 		switch (type) {
253433e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
253533e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
253633e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
253733e882a5SSuraj Sumangala 			break;
253833e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
253933e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
254033e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
254133e882a5SSuraj Sumangala 			break;
254233e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
254333e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
254433e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
254533e882a5SSuraj Sumangala 			break;
254633e882a5SSuraj Sumangala 		}
254733e882a5SSuraj Sumangala 
25481e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
254933e882a5SSuraj Sumangala 		if (!skb)
255033e882a5SSuraj Sumangala 			return -ENOMEM;
255133e882a5SSuraj Sumangala 
255233e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
255333e882a5SSuraj Sumangala 		scb->expect = hlen;
255433e882a5SSuraj Sumangala 		scb->pkt_type = type;
255533e882a5SSuraj Sumangala 
255633e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
255733e882a5SSuraj Sumangala 	}
255833e882a5SSuraj Sumangala 
255933e882a5SSuraj Sumangala 	while (count) {
256033e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
256189bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
256233e882a5SSuraj Sumangala 
256333e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
256433e882a5SSuraj Sumangala 
256533e882a5SSuraj Sumangala 		count -= len;
256633e882a5SSuraj Sumangala 		data += len;
256733e882a5SSuraj Sumangala 		scb->expect -= len;
256833e882a5SSuraj Sumangala 		remain = count;
256933e882a5SSuraj Sumangala 
257033e882a5SSuraj Sumangala 		switch (type) {
257133e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
257233e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
257333e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
257433e882a5SSuraj Sumangala 				scb->expect = h->plen;
257533e882a5SSuraj Sumangala 
257633e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
257733e882a5SSuraj Sumangala 					kfree_skb(skb);
257833e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
257933e882a5SSuraj Sumangala 					return -ENOMEM;
258033e882a5SSuraj Sumangala 				}
258133e882a5SSuraj Sumangala 			}
258233e882a5SSuraj Sumangala 			break;
258333e882a5SSuraj Sumangala 
258433e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
258533e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
258633e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
258733e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
258833e882a5SSuraj Sumangala 
258933e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
259033e882a5SSuraj Sumangala 					kfree_skb(skb);
259133e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
259233e882a5SSuraj Sumangala 					return -ENOMEM;
259333e882a5SSuraj Sumangala 				}
259433e882a5SSuraj Sumangala 			}
259533e882a5SSuraj Sumangala 			break;
259633e882a5SSuraj Sumangala 
259733e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
259833e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
259933e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
260033e882a5SSuraj Sumangala 				scb->expect = h->dlen;
260133e882a5SSuraj Sumangala 
260233e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
260333e882a5SSuraj Sumangala 					kfree_skb(skb);
260433e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
260533e882a5SSuraj Sumangala 					return -ENOMEM;
260633e882a5SSuraj Sumangala 				}
260733e882a5SSuraj Sumangala 			}
260833e882a5SSuraj Sumangala 			break;
260933e882a5SSuraj Sumangala 		}
261033e882a5SSuraj Sumangala 
261133e882a5SSuraj Sumangala 		if (scb->expect == 0) {
261233e882a5SSuraj Sumangala 			/* Complete frame */
261333e882a5SSuraj Sumangala 
261433e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
2615e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
261633e882a5SSuraj Sumangala 
261733e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
261833e882a5SSuraj Sumangala 			return remain;
261933e882a5SSuraj Sumangala 		}
262033e882a5SSuraj Sumangala 	}
262133e882a5SSuraj Sumangala 
262233e882a5SSuraj Sumangala 	return remain;
262333e882a5SSuraj Sumangala }
262433e882a5SSuraj Sumangala 
2625ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
2626ef222013SMarcel Holtmann {
2627f39a3c06SSuraj Sumangala 	int rem = 0;
2628f39a3c06SSuraj Sumangala 
2629ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
2630ef222013SMarcel Holtmann 		return -EILSEQ;
2631ef222013SMarcel Holtmann 
2632da5f6c37SGustavo F. Padovan 	while (count) {
26331e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
2634f39a3c06SSuraj Sumangala 		if (rem < 0)
2635f39a3c06SSuraj Sumangala 			return rem;
2636ef222013SMarcel Holtmann 
2637f39a3c06SSuraj Sumangala 		data += (count - rem);
2638f39a3c06SSuraj Sumangala 		count = rem;
2639f81c6224SJoe Perches 	}
2640ef222013SMarcel Holtmann 
2641f39a3c06SSuraj Sumangala 	return rem;
2642ef222013SMarcel Holtmann }
2643ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
2644ef222013SMarcel Holtmann 
264599811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
264699811510SSuraj Sumangala 
264799811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
264899811510SSuraj Sumangala {
264999811510SSuraj Sumangala 	int type;
265099811510SSuraj Sumangala 	int rem = 0;
265199811510SSuraj Sumangala 
2652da5f6c37SGustavo F. Padovan 	while (count) {
265399811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
265499811510SSuraj Sumangala 
265599811510SSuraj Sumangala 		if (!skb) {
265699811510SSuraj Sumangala 			struct { char type; } *pkt;
265799811510SSuraj Sumangala 
265899811510SSuraj Sumangala 			/* Start of the frame */
265999811510SSuraj Sumangala 			pkt = data;
266099811510SSuraj Sumangala 			type = pkt->type;
266199811510SSuraj Sumangala 
266299811510SSuraj Sumangala 			data++;
266399811510SSuraj Sumangala 			count--;
266499811510SSuraj Sumangala 		} else
266599811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
266699811510SSuraj Sumangala 
26671e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
26681e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
266999811510SSuraj Sumangala 		if (rem < 0)
267099811510SSuraj Sumangala 			return rem;
267199811510SSuraj Sumangala 
267299811510SSuraj Sumangala 		data += (count - rem);
267399811510SSuraj Sumangala 		count = rem;
2674f81c6224SJoe Perches 	}
267599811510SSuraj Sumangala 
267699811510SSuraj Sumangala 	return rem;
267799811510SSuraj Sumangala }
267899811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
267999811510SSuraj Sumangala 
26801da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
26811da177e4SLinus Torvalds 
26821da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
26831da177e4SLinus Torvalds {
26841da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
26851da177e4SLinus Torvalds 
2686f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
26871da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2688f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
26891da177e4SLinus Torvalds 
26901da177e4SLinus Torvalds 	return 0;
26911da177e4SLinus Torvalds }
26921da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
26931da177e4SLinus Torvalds 
26941da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
26951da177e4SLinus Torvalds {
26961da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
26971da177e4SLinus Torvalds 
2698f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
26991da177e4SLinus Torvalds 	list_del(&cb->list);
2700f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
27011da177e4SLinus Torvalds 
27021da177e4SLinus Torvalds 	return 0;
27031da177e4SLinus Torvalds }
27041da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
27051da177e4SLinus Torvalds 
270651086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
27071da177e4SLinus Torvalds {
27080d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
27091da177e4SLinus Torvalds 
27101da177e4SLinus Torvalds 	/* Time stamp */
2711a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
27121da177e4SLinus Torvalds 
2713cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2714cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2715cd82e61cSMarcel Holtmann 
2716cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2717cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2718470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
27191da177e4SLinus Torvalds 	}
27201da177e4SLinus Torvalds 
27211da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
27221da177e4SLinus Torvalds 	skb_orphan(skb);
27231da177e4SLinus Torvalds 
27247bd8f09fSMarcel Holtmann 	if (hdev->send(hdev, skb) < 0)
272551086991SMarcel Holtmann 		BT_ERR("%s sending frame failed", hdev->name);
27261da177e4SLinus Torvalds }
27271da177e4SLinus Torvalds 
27283119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
27293119ae95SJohan Hedberg {
27303119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
27313119ae95SJohan Hedberg 	req->hdev = hdev;
27325d73e034SAndre Guedes 	req->err = 0;
27333119ae95SJohan Hedberg }
27343119ae95SJohan Hedberg 
27353119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
27363119ae95SJohan Hedberg {
27373119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
27383119ae95SJohan Hedberg 	struct sk_buff *skb;
27393119ae95SJohan Hedberg 	unsigned long flags;
27403119ae95SJohan Hedberg 
27413119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
27423119ae95SJohan Hedberg 
27435d73e034SAndre Guedes 	/* If an error occured during request building, remove all HCI
27445d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
27455d73e034SAndre Guedes 	 */
27465d73e034SAndre Guedes 	if (req->err) {
27475d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
27485d73e034SAndre Guedes 		return req->err;
27495d73e034SAndre Guedes 	}
27505d73e034SAndre Guedes 
27513119ae95SJohan Hedberg 	/* Do not allow empty requests */
27523119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
2753382b0c39SAndre Guedes 		return -ENODATA;
27543119ae95SJohan Hedberg 
27553119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
27563119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
27573119ae95SJohan Hedberg 
27583119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
27593119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
27603119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
27613119ae95SJohan Hedberg 
27623119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
27633119ae95SJohan Hedberg 
27643119ae95SJohan Hedberg 	return 0;
27653119ae95SJohan Hedberg }
27663119ae95SJohan Hedberg 
27671ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
276807dc93ddSJohan Hedberg 				       u32 plen, const void *param)
27691da177e4SLinus Torvalds {
27701da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
27711da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
27721da177e4SLinus Torvalds 	struct sk_buff *skb;
27731da177e4SLinus Torvalds 
27741da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
27751ca3a9d0SJohan Hedberg 	if (!skb)
27761ca3a9d0SJohan Hedberg 		return NULL;
27771da177e4SLinus Torvalds 
27781da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2779a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
27801da177e4SLinus Torvalds 	hdr->plen   = plen;
27811da177e4SLinus Torvalds 
27821da177e4SLinus Torvalds 	if (plen)
27831da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
27841da177e4SLinus Torvalds 
27851da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
27861da177e4SLinus Torvalds 
27870d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
2788c78ae283SMarcel Holtmann 
27891ca3a9d0SJohan Hedberg 	return skb;
27901ca3a9d0SJohan Hedberg }
27911ca3a9d0SJohan Hedberg 
27921ca3a9d0SJohan Hedberg /* Send HCI command */
279307dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
279407dc93ddSJohan Hedberg 		 const void *param)
27951ca3a9d0SJohan Hedberg {
27961ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
27971ca3a9d0SJohan Hedberg 
27981ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
27991ca3a9d0SJohan Hedberg 
28001ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
28011ca3a9d0SJohan Hedberg 	if (!skb) {
28021ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
28031ca3a9d0SJohan Hedberg 		return -ENOMEM;
28041ca3a9d0SJohan Hedberg 	}
28051ca3a9d0SJohan Hedberg 
280611714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
280711714b3dSJohan Hedberg 	 * single-command requests.
280811714b3dSJohan Hedberg 	 */
280911714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
281011714b3dSJohan Hedberg 
28111da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2812c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
28131da177e4SLinus Torvalds 
28141da177e4SLinus Torvalds 	return 0;
28151da177e4SLinus Torvalds }
28161da177e4SLinus Torvalds 
281771c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
281807dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
281907dc93ddSJohan Hedberg 		    const void *param, u8 event)
282071c76a17SJohan Hedberg {
282171c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
282271c76a17SJohan Hedberg 	struct sk_buff *skb;
282371c76a17SJohan Hedberg 
282471c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
282571c76a17SJohan Hedberg 
282634739c1eSAndre Guedes 	/* If an error occured during request building, there is no point in
282734739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
282834739c1eSAndre Guedes 	 */
282934739c1eSAndre Guedes 	if (req->err)
283034739c1eSAndre Guedes 		return;
283134739c1eSAndre Guedes 
283271c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
283371c76a17SJohan Hedberg 	if (!skb) {
28345d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
28355d73e034SAndre Guedes 		       hdev->name, opcode);
28365d73e034SAndre Guedes 		req->err = -ENOMEM;
2837e348fe6bSAndre Guedes 		return;
283871c76a17SJohan Hedberg 	}
283971c76a17SJohan Hedberg 
284071c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
284171c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
284271c76a17SJohan Hedberg 
284302350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
284402350a72SJohan Hedberg 
284571c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
284671c76a17SJohan Hedberg }
284771c76a17SJohan Hedberg 
284807dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
284907dc93ddSJohan Hedberg 		 const void *param)
285002350a72SJohan Hedberg {
285102350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
285202350a72SJohan Hedberg }
285302350a72SJohan Hedberg 
28541da177e4SLinus Torvalds /* Get data from the previously sent command */
2855a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
28561da177e4SLinus Torvalds {
28571da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
28581da177e4SLinus Torvalds 
28591da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
28601da177e4SLinus Torvalds 		return NULL;
28611da177e4SLinus Torvalds 
28621da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
28631da177e4SLinus Torvalds 
2864a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
28651da177e4SLinus Torvalds 		return NULL;
28661da177e4SLinus Torvalds 
2867f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
28681da177e4SLinus Torvalds 
28691da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
28701da177e4SLinus Torvalds }
28711da177e4SLinus Torvalds 
28721da177e4SLinus Torvalds /* Send ACL data */
28731da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
28741da177e4SLinus Torvalds {
28751da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
28761da177e4SLinus Torvalds 	int len = skb->len;
28771da177e4SLinus Torvalds 
2878badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2879badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
28809c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2881aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2882aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
28831da177e4SLinus Torvalds }
28841da177e4SLinus Torvalds 
2885ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
288673d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
28871da177e4SLinus Torvalds {
2888ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
28891da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
28901da177e4SLinus Torvalds 	struct sk_buff *list;
28911da177e4SLinus Torvalds 
2892087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
2893087bfd99SGustavo Padovan 	skb->data_len = 0;
2894087bfd99SGustavo Padovan 
2895087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2896204a6e54SAndrei Emeltchenko 
2897204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
2898204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
2899087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
2900204a6e54SAndrei Emeltchenko 		break;
2901204a6e54SAndrei Emeltchenko 	case HCI_AMP:
2902204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
2903204a6e54SAndrei Emeltchenko 		break;
2904204a6e54SAndrei Emeltchenko 	default:
2905204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2906204a6e54SAndrei Emeltchenko 		return;
2907204a6e54SAndrei Emeltchenko 	}
2908087bfd99SGustavo Padovan 
290970f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
291070f23020SAndrei Emeltchenko 	if (!list) {
29111da177e4SLinus Torvalds 		/* Non fragmented */
29121da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
29131da177e4SLinus Torvalds 
291473d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
29151da177e4SLinus Torvalds 	} else {
29161da177e4SLinus Torvalds 		/* Fragmented */
29171da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
29181da177e4SLinus Torvalds 
29191da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
29201da177e4SLinus Torvalds 
29211da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2922af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
29231da177e4SLinus Torvalds 
292473d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2925e702112fSAndrei Emeltchenko 
2926e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2927e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
29281da177e4SLinus Torvalds 		do {
29291da177e4SLinus Torvalds 			skb = list; list = list->next;
29301da177e4SLinus Torvalds 
29310d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2932e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
29331da177e4SLinus Torvalds 
29341da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
29351da177e4SLinus Torvalds 
293673d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
29371da177e4SLinus Torvalds 		} while (list);
29381da177e4SLinus Torvalds 
2939af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
29401da177e4SLinus Torvalds 	}
294173d80debSLuiz Augusto von Dentz }
294273d80debSLuiz Augusto von Dentz 
294373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
294473d80debSLuiz Augusto von Dentz {
2945ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
294673d80debSLuiz Augusto von Dentz 
2947f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
294873d80debSLuiz Augusto von Dentz 
2949ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
29501da177e4SLinus Torvalds 
29513eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
29521da177e4SLinus Torvalds }
29531da177e4SLinus Torvalds 
29541da177e4SLinus Torvalds /* Send SCO data */
29550d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
29561da177e4SLinus Torvalds {
29571da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
29581da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
29591da177e4SLinus Torvalds 
29601da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
29611da177e4SLinus Torvalds 
2962aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
29631da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
29641da177e4SLinus Torvalds 
2965badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2966badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
29679c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
29681da177e4SLinus Torvalds 
29690d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2970c78ae283SMarcel Holtmann 
29711da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
29723eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
29731da177e4SLinus Torvalds }
29741da177e4SLinus Torvalds 
29751da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
29761da177e4SLinus Torvalds 
29771da177e4SLinus Torvalds /* HCI Connection scheduler */
29786039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
2979a8c5fb1aSGustavo Padovan 				     int *quote)
29801da177e4SLinus Torvalds {
29811da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
29828035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
2983abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
29841da177e4SLinus Torvalds 
29851da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
29861da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2987bf4c6325SGustavo F. Padovan 
2988bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2989bf4c6325SGustavo F. Padovan 
2990bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2991769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
29921da177e4SLinus Torvalds 			continue;
2993769be974SMarcel Holtmann 
2994769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2995769be974SMarcel Holtmann 			continue;
2996769be974SMarcel Holtmann 
29971da177e4SLinus Torvalds 		num++;
29981da177e4SLinus Torvalds 
29991da177e4SLinus Torvalds 		if (c->sent < min) {
30001da177e4SLinus Torvalds 			min  = c->sent;
30011da177e4SLinus Torvalds 			conn = c;
30021da177e4SLinus Torvalds 		}
300352087a79SLuiz Augusto von Dentz 
300452087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
300552087a79SLuiz Augusto von Dentz 			break;
30061da177e4SLinus Torvalds 	}
30071da177e4SLinus Torvalds 
3008bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3009bf4c6325SGustavo F. Padovan 
30101da177e4SLinus Torvalds 	if (conn) {
30116ed58ec5SVille Tervo 		int cnt, q;
30126ed58ec5SVille Tervo 
30136ed58ec5SVille Tervo 		switch (conn->type) {
30146ed58ec5SVille Tervo 		case ACL_LINK:
30156ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
30166ed58ec5SVille Tervo 			break;
30176ed58ec5SVille Tervo 		case SCO_LINK:
30186ed58ec5SVille Tervo 		case ESCO_LINK:
30196ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
30206ed58ec5SVille Tervo 			break;
30216ed58ec5SVille Tervo 		case LE_LINK:
30226ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
30236ed58ec5SVille Tervo 			break;
30246ed58ec5SVille Tervo 		default:
30256ed58ec5SVille Tervo 			cnt = 0;
30266ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
30276ed58ec5SVille Tervo 		}
30286ed58ec5SVille Tervo 
30296ed58ec5SVille Tervo 		q = cnt / num;
30301da177e4SLinus Torvalds 		*quote = q ? q : 1;
30311da177e4SLinus Torvalds 	} else
30321da177e4SLinus Torvalds 		*quote = 0;
30331da177e4SLinus Torvalds 
30341da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
30351da177e4SLinus Torvalds 	return conn;
30361da177e4SLinus Torvalds }
30371da177e4SLinus Torvalds 
30386039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
30391da177e4SLinus Torvalds {
30401da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
30411da177e4SLinus Torvalds 	struct hci_conn *c;
30421da177e4SLinus Torvalds 
3043bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
30441da177e4SLinus Torvalds 
3045bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3046bf4c6325SGustavo F. Padovan 
30471da177e4SLinus Torvalds 	/* Kill stalled connections */
3048bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3049bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
30506ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
30516ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
3052bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
30531da177e4SLinus Torvalds 		}
30541da177e4SLinus Torvalds 	}
3055bf4c6325SGustavo F. Padovan 
3056bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
30571da177e4SLinus Torvalds }
30581da177e4SLinus Torvalds 
30596039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
306073d80debSLuiz Augusto von Dentz 				      int *quote)
306173d80debSLuiz Augusto von Dentz {
306273d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
306373d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3064abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
306573d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
306673d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
306773d80debSLuiz Augusto von Dentz 
306873d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
306973d80debSLuiz Augusto von Dentz 
3070bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3071bf4c6325SGustavo F. Padovan 
3072bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
307373d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
307473d80debSLuiz Augusto von Dentz 
307573d80debSLuiz Augusto von Dentz 		if (conn->type != type)
307673d80debSLuiz Augusto von Dentz 			continue;
307773d80debSLuiz Augusto von Dentz 
307873d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
307973d80debSLuiz Augusto von Dentz 			continue;
308073d80debSLuiz Augusto von Dentz 
308173d80debSLuiz Augusto von Dentz 		conn_num++;
308273d80debSLuiz Augusto von Dentz 
30838192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
308473d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
308573d80debSLuiz Augusto von Dentz 
308673d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
308773d80debSLuiz Augusto von Dentz 				continue;
308873d80debSLuiz Augusto von Dentz 
308973d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
309073d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
309173d80debSLuiz Augusto von Dentz 				continue;
309273d80debSLuiz Augusto von Dentz 
309373d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
309473d80debSLuiz Augusto von Dentz 				num = 0;
309573d80debSLuiz Augusto von Dentz 				min = ~0;
309673d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
309773d80debSLuiz Augusto von Dentz 			}
309873d80debSLuiz Augusto von Dentz 
309973d80debSLuiz Augusto von Dentz 			num++;
310073d80debSLuiz Augusto von Dentz 
310173d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
310273d80debSLuiz Augusto von Dentz 				min  = conn->sent;
310373d80debSLuiz Augusto von Dentz 				chan = tmp;
310473d80debSLuiz Augusto von Dentz 			}
310573d80debSLuiz Augusto von Dentz 		}
310673d80debSLuiz Augusto von Dentz 
310773d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
310873d80debSLuiz Augusto von Dentz 			break;
310973d80debSLuiz Augusto von Dentz 	}
311073d80debSLuiz Augusto von Dentz 
3111bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3112bf4c6325SGustavo F. Padovan 
311373d80debSLuiz Augusto von Dentz 	if (!chan)
311473d80debSLuiz Augusto von Dentz 		return NULL;
311573d80debSLuiz Augusto von Dentz 
311673d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
311773d80debSLuiz Augusto von Dentz 	case ACL_LINK:
311873d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
311973d80debSLuiz Augusto von Dentz 		break;
3120bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
3121bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
3122bd1eb66bSAndrei Emeltchenko 		break;
312373d80debSLuiz Augusto von Dentz 	case SCO_LINK:
312473d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
312573d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
312673d80debSLuiz Augusto von Dentz 		break;
312773d80debSLuiz Augusto von Dentz 	case LE_LINK:
312873d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
312973d80debSLuiz Augusto von Dentz 		break;
313073d80debSLuiz Augusto von Dentz 	default:
313173d80debSLuiz Augusto von Dentz 		cnt = 0;
313273d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
313373d80debSLuiz Augusto von Dentz 	}
313473d80debSLuiz Augusto von Dentz 
313573d80debSLuiz Augusto von Dentz 	q = cnt / num;
313673d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
313773d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
313873d80debSLuiz Augusto von Dentz 	return chan;
313973d80debSLuiz Augusto von Dentz }
314073d80debSLuiz Augusto von Dentz 
314102b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
314202b20f0bSLuiz Augusto von Dentz {
314302b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
314402b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
314502b20f0bSLuiz Augusto von Dentz 	int num = 0;
314602b20f0bSLuiz Augusto von Dentz 
314702b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
314802b20f0bSLuiz Augusto von Dentz 
3149bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3150bf4c6325SGustavo F. Padovan 
3151bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
315202b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
315302b20f0bSLuiz Augusto von Dentz 
315402b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
315502b20f0bSLuiz Augusto von Dentz 			continue;
315602b20f0bSLuiz Augusto von Dentz 
315702b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
315802b20f0bSLuiz Augusto von Dentz 			continue;
315902b20f0bSLuiz Augusto von Dentz 
316002b20f0bSLuiz Augusto von Dentz 		num++;
316102b20f0bSLuiz Augusto von Dentz 
31628192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
316302b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
316402b20f0bSLuiz Augusto von Dentz 
316502b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
316602b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
316702b20f0bSLuiz Augusto von Dentz 				continue;
316802b20f0bSLuiz Augusto von Dentz 			}
316902b20f0bSLuiz Augusto von Dentz 
317002b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
317102b20f0bSLuiz Augusto von Dentz 				continue;
317202b20f0bSLuiz Augusto von Dentz 
317302b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
317402b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
317502b20f0bSLuiz Augusto von Dentz 				continue;
317602b20f0bSLuiz Augusto von Dentz 
317702b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
317802b20f0bSLuiz Augusto von Dentz 
317902b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
318002b20f0bSLuiz Augusto von Dentz 			       skb->priority);
318102b20f0bSLuiz Augusto von Dentz 		}
318202b20f0bSLuiz Augusto von Dentz 
318302b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
318402b20f0bSLuiz Augusto von Dentz 			break;
318502b20f0bSLuiz Augusto von Dentz 	}
3186bf4c6325SGustavo F. Padovan 
3187bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3188bf4c6325SGustavo F. Padovan 
318902b20f0bSLuiz Augusto von Dentz }
319002b20f0bSLuiz Augusto von Dentz 
3191b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3192b71d385aSAndrei Emeltchenko {
3193b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3194b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3195b71d385aSAndrei Emeltchenko }
3196b71d385aSAndrei Emeltchenko 
31976039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
31981da177e4SLinus Torvalds {
31991da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
32001da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
32011da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
320263d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
32035f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
3204bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
32051da177e4SLinus Torvalds 	}
320663d2bc1bSAndrei Emeltchenko }
32071da177e4SLinus Torvalds 
32086039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
320963d2bc1bSAndrei Emeltchenko {
321063d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
321163d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
321263d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
321363d2bc1bSAndrei Emeltchenko 	int quote;
321463d2bc1bSAndrei Emeltchenko 
321563d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
321604837f64SMarcel Holtmann 
321773d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
321873d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3219ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3220ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
322173d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
322273d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
322373d80debSLuiz Augusto von Dentz 
3224ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3225ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3226ec1cce24SLuiz Augusto von Dentz 				break;
3227ec1cce24SLuiz Augusto von Dentz 
3228ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3229ec1cce24SLuiz Augusto von Dentz 
323073d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
323173d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
323204837f64SMarcel Holtmann 
323357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
32341da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
32351da177e4SLinus Torvalds 
32361da177e4SLinus Torvalds 			hdev->acl_cnt--;
323773d80debSLuiz Augusto von Dentz 			chan->sent++;
323873d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
32391da177e4SLinus Torvalds 		}
32401da177e4SLinus Torvalds 	}
324102b20f0bSLuiz Augusto von Dentz 
324202b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
324302b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
32441da177e4SLinus Torvalds }
32451da177e4SLinus Torvalds 
32466039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3247b71d385aSAndrei Emeltchenko {
324863d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3249b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3250b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3251b71d385aSAndrei Emeltchenko 	int quote;
3252bd1eb66bSAndrei Emeltchenko 	u8 type;
3253b71d385aSAndrei Emeltchenko 
325463d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
3255b71d385aSAndrei Emeltchenko 
3256bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3257bd1eb66bSAndrei Emeltchenko 
3258bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3259bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3260bd1eb66bSAndrei Emeltchenko 	else
3261bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3262bd1eb66bSAndrei Emeltchenko 
3263b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3264bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3265b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3266b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3267b71d385aSAndrei Emeltchenko 			int blocks;
3268b71d385aSAndrei Emeltchenko 
3269b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3270b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3271b71d385aSAndrei Emeltchenko 
3272b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3273b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3274b71d385aSAndrei Emeltchenko 				break;
3275b71d385aSAndrei Emeltchenko 
3276b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3277b71d385aSAndrei Emeltchenko 
3278b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3279b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3280b71d385aSAndrei Emeltchenko 				return;
3281b71d385aSAndrei Emeltchenko 
3282b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3283b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3284b71d385aSAndrei Emeltchenko 
328557d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3286b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3287b71d385aSAndrei Emeltchenko 
3288b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3289b71d385aSAndrei Emeltchenko 			quote -= blocks;
3290b71d385aSAndrei Emeltchenko 
3291b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3292b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3293b71d385aSAndrei Emeltchenko 		}
3294b71d385aSAndrei Emeltchenko 	}
3295b71d385aSAndrei Emeltchenko 
3296b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3297bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3298b71d385aSAndrei Emeltchenko }
3299b71d385aSAndrei Emeltchenko 
33006039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3301b71d385aSAndrei Emeltchenko {
3302b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3303b71d385aSAndrei Emeltchenko 
3304bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3305bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
3306bd1eb66bSAndrei Emeltchenko 		return;
3307bd1eb66bSAndrei Emeltchenko 
3308bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3309bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3310b71d385aSAndrei Emeltchenko 		return;
3311b71d385aSAndrei Emeltchenko 
3312b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3313b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3314b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3315b71d385aSAndrei Emeltchenko 		break;
3316b71d385aSAndrei Emeltchenko 
3317b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3318b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3319b71d385aSAndrei Emeltchenko 		break;
3320b71d385aSAndrei Emeltchenko 	}
3321b71d385aSAndrei Emeltchenko }
3322b71d385aSAndrei Emeltchenko 
33231da177e4SLinus Torvalds /* Schedule SCO */
33246039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
33251da177e4SLinus Torvalds {
33261da177e4SLinus Torvalds 	struct hci_conn *conn;
33271da177e4SLinus Torvalds 	struct sk_buff *skb;
33281da177e4SLinus Torvalds 	int quote;
33291da177e4SLinus Torvalds 
33301da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
33311da177e4SLinus Torvalds 
333252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
333352087a79SLuiz Augusto von Dentz 		return;
333452087a79SLuiz Augusto von Dentz 
33351da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
33361da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
33371da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
333857d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
33391da177e4SLinus Torvalds 
33401da177e4SLinus Torvalds 			conn->sent++;
33411da177e4SLinus Torvalds 			if (conn->sent == ~0)
33421da177e4SLinus Torvalds 				conn->sent = 0;
33431da177e4SLinus Torvalds 		}
33441da177e4SLinus Torvalds 	}
33451da177e4SLinus Torvalds }
33461da177e4SLinus Torvalds 
33476039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
3348b6a0dc82SMarcel Holtmann {
3349b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
3350b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
3351b6a0dc82SMarcel Holtmann 	int quote;
3352b6a0dc82SMarcel Holtmann 
3353b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
3354b6a0dc82SMarcel Holtmann 
335552087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
335652087a79SLuiz Augusto von Dentz 		return;
335752087a79SLuiz Augusto von Dentz 
33588fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
33598fc9ced3SGustavo Padovan 						     &quote))) {
3360b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
3361b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
336257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3363b6a0dc82SMarcel Holtmann 
3364b6a0dc82SMarcel Holtmann 			conn->sent++;
3365b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
3366b6a0dc82SMarcel Holtmann 				conn->sent = 0;
3367b6a0dc82SMarcel Holtmann 		}
3368b6a0dc82SMarcel Holtmann 	}
3369b6a0dc82SMarcel Holtmann }
3370b6a0dc82SMarcel Holtmann 
33716039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
33726ed58ec5SVille Tervo {
337373d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
33746ed58ec5SVille Tervo 	struct sk_buff *skb;
337502b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
33766ed58ec5SVille Tervo 
33776ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
33786ed58ec5SVille Tervo 
337952087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
338052087a79SLuiz Augusto von Dentz 		return;
338152087a79SLuiz Augusto von Dentz 
33826ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
33836ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
33846ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
3385bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
33866ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
3387bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
33886ed58ec5SVille Tervo 	}
33896ed58ec5SVille Tervo 
33906ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
339102b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
339273d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3393ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3394ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
339573d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
339673d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
33976ed58ec5SVille Tervo 
3398ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3399ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3400ec1cce24SLuiz Augusto von Dentz 				break;
3401ec1cce24SLuiz Augusto von Dentz 
3402ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3403ec1cce24SLuiz Augusto von Dentz 
340457d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
34056ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
34066ed58ec5SVille Tervo 
34076ed58ec5SVille Tervo 			cnt--;
340873d80debSLuiz Augusto von Dentz 			chan->sent++;
340973d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
34106ed58ec5SVille Tervo 		}
34116ed58ec5SVille Tervo 	}
341273d80debSLuiz Augusto von Dentz 
34136ed58ec5SVille Tervo 	if (hdev->le_pkts)
34146ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
34156ed58ec5SVille Tervo 	else
34166ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
341702b20f0bSLuiz Augusto von Dentz 
341802b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
341902b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
34206ed58ec5SVille Tervo }
34216ed58ec5SVille Tervo 
34223eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
34231da177e4SLinus Torvalds {
34243eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
34251da177e4SLinus Torvalds 	struct sk_buff *skb;
34261da177e4SLinus Torvalds 
34276ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
34286ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
34291da177e4SLinus Torvalds 
343052de599eSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
34311da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
34321da177e4SLinus Torvalds 		hci_sched_acl(hdev);
34331da177e4SLinus Torvalds 		hci_sched_sco(hdev);
3434b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
34356ed58ec5SVille Tervo 		hci_sched_le(hdev);
343652de599eSMarcel Holtmann 	}
34376ed58ec5SVille Tervo 
34381da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
34391da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
344057d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
34411da177e4SLinus Torvalds }
34421da177e4SLinus Torvalds 
344325985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
34441da177e4SLinus Torvalds 
34451da177e4SLinus Torvalds /* ACL data packet */
34466039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
34471da177e4SLinus Torvalds {
34481da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
34491da177e4SLinus Torvalds 	struct hci_conn *conn;
34501da177e4SLinus Torvalds 	__u16 handle, flags;
34511da177e4SLinus Torvalds 
34521da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
34531da177e4SLinus Torvalds 
34541da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
34551da177e4SLinus Torvalds 	flags  = hci_flags(handle);
34561da177e4SLinus Torvalds 	handle = hci_handle(handle);
34571da177e4SLinus Torvalds 
3458f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3459a8c5fb1aSGustavo Padovan 	       handle, flags);
34601da177e4SLinus Torvalds 
34611da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
34621da177e4SLinus Torvalds 
34631da177e4SLinus Torvalds 	hci_dev_lock(hdev);
34641da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
34651da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
34661da177e4SLinus Torvalds 
34671da177e4SLinus Torvalds 	if (conn) {
346865983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
346904837f64SMarcel Holtmann 
34701da177e4SLinus Torvalds 		/* Send to upper protocol */
3471686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
34721da177e4SLinus Torvalds 		return;
34731da177e4SLinus Torvalds 	} else {
34741da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
34751da177e4SLinus Torvalds 		       hdev->name, handle);
34761da177e4SLinus Torvalds 	}
34771da177e4SLinus Torvalds 
34781da177e4SLinus Torvalds 	kfree_skb(skb);
34791da177e4SLinus Torvalds }
34801da177e4SLinus Torvalds 
34811da177e4SLinus Torvalds /* SCO data packet */
34826039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
34831da177e4SLinus Torvalds {
34841da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
34851da177e4SLinus Torvalds 	struct hci_conn *conn;
34861da177e4SLinus Torvalds 	__u16 handle;
34871da177e4SLinus Torvalds 
34881da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
34891da177e4SLinus Torvalds 
34901da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
34911da177e4SLinus Torvalds 
3492f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
34931da177e4SLinus Torvalds 
34941da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
34951da177e4SLinus Torvalds 
34961da177e4SLinus Torvalds 	hci_dev_lock(hdev);
34971da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
34981da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
34991da177e4SLinus Torvalds 
35001da177e4SLinus Torvalds 	if (conn) {
35011da177e4SLinus Torvalds 		/* Send to upper protocol */
3502686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
35031da177e4SLinus Torvalds 		return;
35041da177e4SLinus Torvalds 	} else {
35051da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
35061da177e4SLinus Torvalds 		       hdev->name, handle);
35071da177e4SLinus Torvalds 	}
35081da177e4SLinus Torvalds 
35091da177e4SLinus Torvalds 	kfree_skb(skb);
35101da177e4SLinus Torvalds }
35111da177e4SLinus Torvalds 
35129238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
35139238f36aSJohan Hedberg {
35149238f36aSJohan Hedberg 	struct sk_buff *skb;
35159238f36aSJohan Hedberg 
35169238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
35179238f36aSJohan Hedberg 	if (!skb)
35189238f36aSJohan Hedberg 		return true;
35199238f36aSJohan Hedberg 
35209238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
35219238f36aSJohan Hedberg }
35229238f36aSJohan Hedberg 
352342c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
352442c6b129SJohan Hedberg {
352542c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
352642c6b129SJohan Hedberg 	struct sk_buff *skb;
352742c6b129SJohan Hedberg 	u16 opcode;
352842c6b129SJohan Hedberg 
352942c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
353042c6b129SJohan Hedberg 		return;
353142c6b129SJohan Hedberg 
353242c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
353342c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
353442c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
353542c6b129SJohan Hedberg 		return;
353642c6b129SJohan Hedberg 
353742c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
353842c6b129SJohan Hedberg 	if (!skb)
353942c6b129SJohan Hedberg 		return;
354042c6b129SJohan Hedberg 
354142c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
354242c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
354342c6b129SJohan Hedberg }
354442c6b129SJohan Hedberg 
35459238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
35469238f36aSJohan Hedberg {
35479238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
35489238f36aSJohan Hedberg 	struct sk_buff *skb;
35499238f36aSJohan Hedberg 	unsigned long flags;
35509238f36aSJohan Hedberg 
35519238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
35529238f36aSJohan Hedberg 
355342c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
355442c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
35559238f36aSJohan Hedberg 	 */
355642c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
355742c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
355842c6b129SJohan Hedberg 		 * reset complete event during init and any pending
355942c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
356042c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
356142c6b129SJohan Hedberg 		 * command.
356242c6b129SJohan Hedberg 		 */
356342c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
356442c6b129SJohan Hedberg 			hci_resend_last(hdev);
356542c6b129SJohan Hedberg 
35669238f36aSJohan Hedberg 		return;
356742c6b129SJohan Hedberg 	}
35689238f36aSJohan Hedberg 
35699238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
35709238f36aSJohan Hedberg 	 * this request the request is not yet complete.
35719238f36aSJohan Hedberg 	 */
35729238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
35739238f36aSJohan Hedberg 		return;
35749238f36aSJohan Hedberg 
35759238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
35769238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
35779238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
35789238f36aSJohan Hedberg 	 */
35799238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
35809238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
358153e21fbcSJohan Hedberg 
358253e21fbcSJohan Hedberg 		if (req_complete) {
358353e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
358453e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
358553e21fbcSJohan Hedberg 			 * this function gets called again.
358653e21fbcSJohan Hedberg 			 */
358753e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
358853e21fbcSJohan Hedberg 
35899238f36aSJohan Hedberg 			goto call_complete;
35909238f36aSJohan Hedberg 		}
359153e21fbcSJohan Hedberg 	}
35929238f36aSJohan Hedberg 
35939238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
35949238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
35959238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
35969238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
35979238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
35989238f36aSJohan Hedberg 			break;
35999238f36aSJohan Hedberg 		}
36009238f36aSJohan Hedberg 
36019238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
36029238f36aSJohan Hedberg 		kfree_skb(skb);
36039238f36aSJohan Hedberg 	}
36049238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
36059238f36aSJohan Hedberg 
36069238f36aSJohan Hedberg call_complete:
36079238f36aSJohan Hedberg 	if (req_complete)
36089238f36aSJohan Hedberg 		req_complete(hdev, status);
36099238f36aSJohan Hedberg }
36109238f36aSJohan Hedberg 
3611b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
36121da177e4SLinus Torvalds {
3613b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
36141da177e4SLinus Torvalds 	struct sk_buff *skb;
36151da177e4SLinus Torvalds 
36161da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
36171da177e4SLinus Torvalds 
36181da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
3619cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
3620cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
3621cd82e61cSMarcel Holtmann 
36221da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
36231da177e4SLinus Torvalds 			/* Send copy to the sockets */
3624470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
36251da177e4SLinus Torvalds 		}
36261da177e4SLinus Torvalds 
36270736cfa8SMarcel Holtmann 		if (test_bit(HCI_RAW, &hdev->flags) ||
36280736cfa8SMarcel Holtmann 		    test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
36291da177e4SLinus Torvalds 			kfree_skb(skb);
36301da177e4SLinus Torvalds 			continue;
36311da177e4SLinus Torvalds 		}
36321da177e4SLinus Torvalds 
36331da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
36341da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
36350d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
36361da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
36371da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
36381da177e4SLinus Torvalds 				kfree_skb(skb);
36391da177e4SLinus Torvalds 				continue;
36403ff50b79SStephen Hemminger 			}
36411da177e4SLinus Torvalds 		}
36421da177e4SLinus Torvalds 
36431da177e4SLinus Torvalds 		/* Process frame */
36440d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
36451da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
3646b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
36471da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
36481da177e4SLinus Torvalds 			break;
36491da177e4SLinus Torvalds 
36501da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
36511da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
36521da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
36531da177e4SLinus Torvalds 			break;
36541da177e4SLinus Torvalds 
36551da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
36561da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
36571da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
36581da177e4SLinus Torvalds 			break;
36591da177e4SLinus Torvalds 
36601da177e4SLinus Torvalds 		default:
36611da177e4SLinus Torvalds 			kfree_skb(skb);
36621da177e4SLinus Torvalds 			break;
36631da177e4SLinus Torvalds 		}
36641da177e4SLinus Torvalds 	}
36651da177e4SLinus Torvalds }
36661da177e4SLinus Torvalds 
3667c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
36681da177e4SLinus Torvalds {
3669c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
36701da177e4SLinus Torvalds 	struct sk_buff *skb;
36711da177e4SLinus Torvalds 
36722104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
36732104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
36741da177e4SLinus Torvalds 
36751da177e4SLinus Torvalds 	/* Send queued commands */
36765a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
36775a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
36785a08ecceSAndrei Emeltchenko 		if (!skb)
36795a08ecceSAndrei Emeltchenko 			return;
36805a08ecceSAndrei Emeltchenko 
36811da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
36821da177e4SLinus Torvalds 
3683a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
368470f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
36851da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
368657d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
36877bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
36887bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
36897bdb8a5cSSzymon Janc 			else
36906bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
36915f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
36921da177e4SLinus Torvalds 		} else {
36931da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
3694c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
36951da177e4SLinus Torvalds 		}
36961da177e4SLinus Torvalds 	}
36971da177e4SLinus Torvalds }
36982519a1fcSAndre Guedes 
369931f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type)
370031f7956cSAndre Guedes {
370131f7956cSAndre Guedes 	switch (bdaddr_type) {
370231f7956cSAndre Guedes 	case BDADDR_LE_PUBLIC:
370331f7956cSAndre Guedes 		return ADDR_LE_DEV_PUBLIC;
370431f7956cSAndre Guedes 
370531f7956cSAndre Guedes 	default:
370631f7956cSAndre Guedes 		/* Fallback to LE Random address type */
370731f7956cSAndre Guedes 		return ADDR_LE_DEV_RANDOM;
370831f7956cSAndre Guedes 	}
370931f7956cSAndre Guedes }
3710