xref: /openbmc/linux/net/bluetooth/hci_core.c (revision b1e73124)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
4590051deSGustavo F. Padovan    Copyright (C) 2011 ProFUSION Embedded Systems
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds    published by the Free Software Foundation;
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds /* Bluetooth HCI core. */
271da177e4SLinus Torvalds 
288c520a59SGustavo Padovan #include <linux/export.h>
293df92b31SSasha Levin #include <linux/idr.h>
301da177e4SLinus Torvalds 
31611b30f7SMarcel Holtmann #include <linux/rfkill.h>
321da177e4SLinus Torvalds 
331da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
341da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
351da177e4SLinus Torvalds 
36b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
37c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
383eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
391da177e4SLinus Torvalds 
401da177e4SLinus Torvalds /* HCI device list */
411da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
421da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
431da177e4SLinus Torvalds 
441da177e4SLinus Torvalds /* HCI callback list */
451da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
461da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
471da177e4SLinus Torvalds 
483df92b31SSasha Levin /* HCI ID Numbering */
493df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
503df92b31SSasha Levin 
511da177e4SLinus Torvalds /* ---- HCI notifications ---- */
521da177e4SLinus Torvalds 
536516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
541da177e4SLinus Torvalds {
55040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
561da177e4SLinus Torvalds }
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds /* ---- HCI requests ---- */
591da177e4SLinus Torvalds 
6042c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
611da177e4SLinus Torvalds {
6242c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
6375fb0e32SJohan Hedberg 
641da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
651da177e4SLinus Torvalds 		hdev->req_result = result;
661da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
671da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
681da177e4SLinus Torvalds 	}
691da177e4SLinus Torvalds }
701da177e4SLinus Torvalds 
711da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
721da177e4SLinus Torvalds {
731da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
741da177e4SLinus Torvalds 
751da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
761da177e4SLinus Torvalds 		hdev->req_result = err;
771da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
781da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
791da177e4SLinus Torvalds 	}
801da177e4SLinus Torvalds }
811da177e4SLinus Torvalds 
8277a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
8377a63e0aSFengguang Wu 					    u8 event)
8475e84b7cSJohan Hedberg {
8575e84b7cSJohan Hedberg 	struct hci_ev_cmd_complete *ev;
8675e84b7cSJohan Hedberg 	struct hci_event_hdr *hdr;
8775e84b7cSJohan Hedberg 	struct sk_buff *skb;
8875e84b7cSJohan Hedberg 
8975e84b7cSJohan Hedberg 	hci_dev_lock(hdev);
9075e84b7cSJohan Hedberg 
9175e84b7cSJohan Hedberg 	skb = hdev->recv_evt;
9275e84b7cSJohan Hedberg 	hdev->recv_evt = NULL;
9375e84b7cSJohan Hedberg 
9475e84b7cSJohan Hedberg 	hci_dev_unlock(hdev);
9575e84b7cSJohan Hedberg 
9675e84b7cSJohan Hedberg 	if (!skb)
9775e84b7cSJohan Hedberg 		return ERR_PTR(-ENODATA);
9875e84b7cSJohan Hedberg 
9975e84b7cSJohan Hedberg 	if (skb->len < sizeof(*hdr)) {
10075e84b7cSJohan Hedberg 		BT_ERR("Too short HCI event");
10175e84b7cSJohan Hedberg 		goto failed;
10275e84b7cSJohan Hedberg 	}
10375e84b7cSJohan Hedberg 
10475e84b7cSJohan Hedberg 	hdr = (void *) skb->data;
10575e84b7cSJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
10675e84b7cSJohan Hedberg 
1077b1abbbeSJohan Hedberg 	if (event) {
1087b1abbbeSJohan Hedberg 		if (hdr->evt != event)
1097b1abbbeSJohan Hedberg 			goto failed;
1107b1abbbeSJohan Hedberg 		return skb;
1117b1abbbeSJohan Hedberg 	}
1127b1abbbeSJohan Hedberg 
11375e84b7cSJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
11475e84b7cSJohan Hedberg 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
11575e84b7cSJohan Hedberg 		goto failed;
11675e84b7cSJohan Hedberg 	}
11775e84b7cSJohan Hedberg 
11875e84b7cSJohan Hedberg 	if (skb->len < sizeof(*ev)) {
11975e84b7cSJohan Hedberg 		BT_ERR("Too short cmd_complete event");
12075e84b7cSJohan Hedberg 		goto failed;
12175e84b7cSJohan Hedberg 	}
12275e84b7cSJohan Hedberg 
12375e84b7cSJohan Hedberg 	ev = (void *) skb->data;
12475e84b7cSJohan Hedberg 	skb_pull(skb, sizeof(*ev));
12575e84b7cSJohan Hedberg 
12675e84b7cSJohan Hedberg 	if (opcode == __le16_to_cpu(ev->opcode))
12775e84b7cSJohan Hedberg 		return skb;
12875e84b7cSJohan Hedberg 
12975e84b7cSJohan Hedberg 	BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
13075e84b7cSJohan Hedberg 	       __le16_to_cpu(ev->opcode));
13175e84b7cSJohan Hedberg 
13275e84b7cSJohan Hedberg failed:
13375e84b7cSJohan Hedberg 	kfree_skb(skb);
13475e84b7cSJohan Hedberg 	return ERR_PTR(-ENODATA);
13575e84b7cSJohan Hedberg }
13675e84b7cSJohan Hedberg 
1377b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
13807dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
13975e84b7cSJohan Hedberg {
14075e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
14175e84b7cSJohan Hedberg 	struct hci_request req;
14275e84b7cSJohan Hedberg 	int err = 0;
14375e84b7cSJohan Hedberg 
14475e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
14575e84b7cSJohan Hedberg 
14675e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
14775e84b7cSJohan Hedberg 
1487b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
14975e84b7cSJohan Hedberg 
15075e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
15175e84b7cSJohan Hedberg 
15275e84b7cSJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
15375e84b7cSJohan Hedberg 	if (err < 0)
15475e84b7cSJohan Hedberg 		return ERR_PTR(err);
15575e84b7cSJohan Hedberg 
15675e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
15775e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
15875e84b7cSJohan Hedberg 
15975e84b7cSJohan Hedberg 	schedule_timeout(timeout);
16075e84b7cSJohan Hedberg 
16175e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
16275e84b7cSJohan Hedberg 
16375e84b7cSJohan Hedberg 	if (signal_pending(current))
16475e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
16575e84b7cSJohan Hedberg 
16675e84b7cSJohan Hedberg 	switch (hdev->req_status) {
16775e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
16875e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
16975e84b7cSJohan Hedberg 		break;
17075e84b7cSJohan Hedberg 
17175e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
17275e84b7cSJohan Hedberg 		err = -hdev->req_result;
17375e84b7cSJohan Hedberg 		break;
17475e84b7cSJohan Hedberg 
17575e84b7cSJohan Hedberg 	default:
17675e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
17775e84b7cSJohan Hedberg 		break;
17875e84b7cSJohan Hedberg 	}
17975e84b7cSJohan Hedberg 
18075e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
18175e84b7cSJohan Hedberg 
18275e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
18375e84b7cSJohan Hedberg 
18475e84b7cSJohan Hedberg 	if (err < 0)
18575e84b7cSJohan Hedberg 		return ERR_PTR(err);
18675e84b7cSJohan Hedberg 
1877b1abbbeSJohan Hedberg 	return hci_get_cmd_complete(hdev, opcode, event);
1887b1abbbeSJohan Hedberg }
1897b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
1907b1abbbeSJohan Hedberg 
1917b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
19207dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
1937b1abbbeSJohan Hedberg {
1947b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
19575e84b7cSJohan Hedberg }
19675e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
19775e84b7cSJohan Hedberg 
1981da177e4SLinus Torvalds /* Execute request and wait for completion. */
19901178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
20042c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
20142c6b129SJohan Hedberg 				      unsigned long opt),
2021da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
2031da177e4SLinus Torvalds {
20442c6b129SJohan Hedberg 	struct hci_request req;
2051da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
2061da177e4SLinus Torvalds 	int err = 0;
2071da177e4SLinus Torvalds 
2081da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
2091da177e4SLinus Torvalds 
21042c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
21142c6b129SJohan Hedberg 
2121da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
2131da177e4SLinus Torvalds 
21442c6b129SJohan Hedberg 	func(&req, opt);
21553cce22dSJohan Hedberg 
21642c6b129SJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
21742c6b129SJohan Hedberg 	if (err < 0) {
21853cce22dSJohan Hedberg 		hdev->req_status = 0;
219920c8300SAndre Guedes 
220920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
221920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
222920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
223920c8300SAndre Guedes 		 * and should not trigger an error return.
22442c6b129SJohan Hedberg 		 */
225920c8300SAndre Guedes 		if (err == -ENODATA)
22642c6b129SJohan Hedberg 			return 0;
227920c8300SAndre Guedes 
228920c8300SAndre Guedes 		return err;
22953cce22dSJohan Hedberg 	}
23053cce22dSJohan Hedberg 
231bc4445c7SAndre Guedes 	add_wait_queue(&hdev->req_wait_q, &wait);
232bc4445c7SAndre Guedes 	set_current_state(TASK_INTERRUPTIBLE);
233bc4445c7SAndre Guedes 
2341da177e4SLinus Torvalds 	schedule_timeout(timeout);
2351da177e4SLinus Torvalds 
2361da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
2371da177e4SLinus Torvalds 
2381da177e4SLinus Torvalds 	if (signal_pending(current))
2391da177e4SLinus Torvalds 		return -EINTR;
2401da177e4SLinus Torvalds 
2411da177e4SLinus Torvalds 	switch (hdev->req_status) {
2421da177e4SLinus Torvalds 	case HCI_REQ_DONE:
243e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
2441da177e4SLinus Torvalds 		break;
2451da177e4SLinus Torvalds 
2461da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
2471da177e4SLinus Torvalds 		err = -hdev->req_result;
2481da177e4SLinus Torvalds 		break;
2491da177e4SLinus Torvalds 
2501da177e4SLinus Torvalds 	default:
2511da177e4SLinus Torvalds 		err = -ETIMEDOUT;
2521da177e4SLinus Torvalds 		break;
2533ff50b79SStephen Hemminger 	}
2541da177e4SLinus Torvalds 
255a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
2561da177e4SLinus Torvalds 
2571da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
2581da177e4SLinus Torvalds 
2591da177e4SLinus Torvalds 	return err;
2601da177e4SLinus Torvalds }
2611da177e4SLinus Torvalds 
26201178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
26342c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
26442c6b129SJohan Hedberg 				    unsigned long opt),
2651da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
2661da177e4SLinus Torvalds {
2671da177e4SLinus Torvalds 	int ret;
2681da177e4SLinus Torvalds 
2697c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
2707c6a329eSMarcel Holtmann 		return -ENETDOWN;
2717c6a329eSMarcel Holtmann 
2721da177e4SLinus Torvalds 	/* Serialize all requests */
2731da177e4SLinus Torvalds 	hci_req_lock(hdev);
27401178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
2751da177e4SLinus Torvalds 	hci_req_unlock(hdev);
2761da177e4SLinus Torvalds 
2771da177e4SLinus Torvalds 	return ret;
2781da177e4SLinus Torvalds }
2791da177e4SLinus Torvalds 
28042c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
2811da177e4SLinus Torvalds {
28242c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
2831da177e4SLinus Torvalds 
2841da177e4SLinus Torvalds 	/* Reset device */
28542c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
28642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
2871da177e4SLinus Torvalds }
2881da177e4SLinus Torvalds 
28942c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
2901da177e4SLinus Torvalds {
29142c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
2922455a3eaSAndrei Emeltchenko 
2931da177e4SLinus Torvalds 	/* Read Local Supported Features */
29442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
2951da177e4SLinus Torvalds 
2961143e5a6SMarcel Holtmann 	/* Read Local Version */
29742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2982177bab5SJohan Hedberg 
2992177bab5SJohan Hedberg 	/* Read BD Address */
30042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
3011da177e4SLinus Torvalds }
3021da177e4SLinus Torvalds 
30342c6b129SJohan Hedberg static void amp_init(struct hci_request *req)
304e61ef499SAndrei Emeltchenko {
30542c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
3062455a3eaSAndrei Emeltchenko 
307e61ef499SAndrei Emeltchenko 	/* Read Local Version */
30842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
3096bcbc489SAndrei Emeltchenko 
310f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
311f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
312f6996cfeSMarcel Holtmann 
313f6996cfeSMarcel Holtmann 	/* Read Local Supported Features */
314f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
315f6996cfeSMarcel Holtmann 
3166bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
31742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
318e71dfabaSAndrei Emeltchenko 
319e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
32042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
3217528ca1cSMarcel Holtmann 
322f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
323f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
324f38ba941SMarcel Holtmann 
3257528ca1cSMarcel Holtmann 	/* Read Location Data */
3267528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
327e61ef499SAndrei Emeltchenko }
328e61ef499SAndrei Emeltchenko 
32942c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
330e61ef499SAndrei Emeltchenko {
33142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
332e61ef499SAndrei Emeltchenko 
333e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
334e61ef499SAndrei Emeltchenko 
33511778716SAndrei Emeltchenko 	/* Reset */
33611778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
33742c6b129SJohan Hedberg 		hci_reset_req(req, 0);
33811778716SAndrei Emeltchenko 
339e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
340e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
34142c6b129SJohan Hedberg 		bredr_init(req);
342e61ef499SAndrei Emeltchenko 		break;
343e61ef499SAndrei Emeltchenko 
344e61ef499SAndrei Emeltchenko 	case HCI_AMP:
34542c6b129SJohan Hedberg 		amp_init(req);
346e61ef499SAndrei Emeltchenko 		break;
347e61ef499SAndrei Emeltchenko 
348e61ef499SAndrei Emeltchenko 	default:
349e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
350e61ef499SAndrei Emeltchenko 		break;
351e61ef499SAndrei Emeltchenko 	}
352e61ef499SAndrei Emeltchenko }
353e61ef499SAndrei Emeltchenko 
35442c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
3552177bab5SJohan Hedberg {
3564ca048e3SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
3574ca048e3SMarcel Holtmann 
3582177bab5SJohan Hedberg 	__le16 param;
3592177bab5SJohan Hedberg 	__u8 flt_type;
3602177bab5SJohan Hedberg 
3612177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
36242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
3632177bab5SJohan Hedberg 
3642177bab5SJohan Hedberg 	/* Read Class of Device */
36542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
3662177bab5SJohan Hedberg 
3672177bab5SJohan Hedberg 	/* Read Local Name */
36842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
3692177bab5SJohan Hedberg 
3702177bab5SJohan Hedberg 	/* Read Voice Setting */
37142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
3722177bab5SJohan Hedberg 
373b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
374b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
375b4cb9fb2SMarcel Holtmann 
3764b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
3774b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
3784b836f39SMarcel Holtmann 
3792177bab5SJohan Hedberg 	/* Clear Event Filters */
3802177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
38142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
3822177bab5SJohan Hedberg 
3832177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
3842177bab5SJohan Hedberg 	param = __constant_cpu_to_le16(0x7d00);
38542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
3862177bab5SJohan Hedberg 
3874ca048e3SMarcel Holtmann 	/* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2,
3884ca048e3SMarcel Holtmann 	 * but it does not support page scan related HCI commands.
3894ca048e3SMarcel Holtmann 	 */
3904ca048e3SMarcel Holtmann 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) {
391f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
392f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
393f332ec66SJohan Hedberg 	}
3942177bab5SJohan Hedberg }
3952177bab5SJohan Hedberg 
39642c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
3972177bab5SJohan Hedberg {
398c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
399c73eee91SJohan Hedberg 
4002177bab5SJohan Hedberg 	/* Read LE Buffer Size */
40142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
4022177bab5SJohan Hedberg 
4032177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
40442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
4052177bab5SJohan Hedberg 
4062177bab5SJohan Hedberg 	/* Read LE Advertising Channel TX Power */
40742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
4082177bab5SJohan Hedberg 
4092177bab5SJohan Hedberg 	/* Read LE White List Size */
41042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
4112177bab5SJohan Hedberg 
4122177bab5SJohan Hedberg 	/* Read LE Supported States */
41342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
414c73eee91SJohan Hedberg 
415c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
416c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
417c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
4182177bab5SJohan Hedberg }
4192177bab5SJohan Hedberg 
4202177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
4212177bab5SJohan Hedberg {
4222177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
4232177bab5SJohan Hedberg 		return 0x02;
4242177bab5SJohan Hedberg 
4252177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4262177bab5SJohan Hedberg 		return 0x01;
4272177bab5SJohan Hedberg 
4282177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
4292177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
4302177bab5SJohan Hedberg 		return 0x01;
4312177bab5SJohan Hedberg 
4322177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
4332177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
4342177bab5SJohan Hedberg 			return 0x01;
4352177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
4362177bab5SJohan Hedberg 			return 0x01;
4372177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
4382177bab5SJohan Hedberg 			return 0x01;
4392177bab5SJohan Hedberg 	}
4402177bab5SJohan Hedberg 
4412177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
4422177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
4432177bab5SJohan Hedberg 		return 0x01;
4442177bab5SJohan Hedberg 
4452177bab5SJohan Hedberg 	return 0x00;
4462177bab5SJohan Hedberg }
4472177bab5SJohan Hedberg 
44842c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
4492177bab5SJohan Hedberg {
4502177bab5SJohan Hedberg 	u8 mode;
4512177bab5SJohan Hedberg 
45242c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
4532177bab5SJohan Hedberg 
45442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
4552177bab5SJohan Hedberg }
4562177bab5SJohan Hedberg 
45742c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
4582177bab5SJohan Hedberg {
45942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
46042c6b129SJohan Hedberg 
4612177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
4622177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
4632177bab5SJohan Hedberg 	 * command otherwise.
4642177bab5SJohan Hedberg 	 */
4652177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
4662177bab5SJohan Hedberg 
4672177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
4682177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
4692177bab5SJohan Hedberg 	 */
4702177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
4712177bab5SJohan Hedberg 		return;
4722177bab5SJohan Hedberg 
4732177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
4742177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
4752177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4762177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
4772177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
4782177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
479c7882cbdSMarcel Holtmann 	} else {
480c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
481c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
482c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
483c7882cbdSMarcel Holtmann 		events[0] |= 0x80; /* Encryption Change */
484c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
485c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
486c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
487c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
488c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
489c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
490c7882cbdSMarcel Holtmann 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
4912177bab5SJohan Hedberg 	}
4922177bab5SJohan Hedberg 
4932177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4942177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4952177bab5SJohan Hedberg 
4962177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
4972177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
4982177bab5SJohan Hedberg 
4992177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
5002177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
5012177bab5SJohan Hedberg 
5022177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
5032177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
5042177bab5SJohan Hedberg 
5052177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
5062177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
5072177bab5SJohan Hedberg 
5082177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
5092177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
5102177bab5SJohan Hedberg 
5112177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5122177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
5132177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
5142177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
5152177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
5162177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
5172177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
5182177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
5192177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
5202177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
5212177bab5SJohan Hedberg 					 * Features Notification
5222177bab5SJohan Hedberg 					 */
5232177bab5SJohan Hedberg 	}
5242177bab5SJohan Hedberg 
5252177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
5262177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
5272177bab5SJohan Hedberg 
52842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
5292177bab5SJohan Hedberg 
5302177bab5SJohan Hedberg 	if (lmp_le_capable(hdev)) {
5312177bab5SJohan Hedberg 		memset(events, 0, sizeof(events));
5322177bab5SJohan Hedberg 		events[0] = 0x1f;
53342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
5342177bab5SJohan Hedberg 			    sizeof(events), events);
5352177bab5SJohan Hedberg 	}
5362177bab5SJohan Hedberg }
5372177bab5SJohan Hedberg 
53842c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
5392177bab5SJohan Hedberg {
54042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
54142c6b129SJohan Hedberg 
5422177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
54342c6b129SJohan Hedberg 		bredr_setup(req);
54456f87901SJohan Hedberg 	else
54556f87901SJohan Hedberg 		clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
5462177bab5SJohan Hedberg 
5472177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
54842c6b129SJohan Hedberg 		le_setup(req);
5492177bab5SJohan Hedberg 
55042c6b129SJohan Hedberg 	hci_setup_event_mask(req);
5512177bab5SJohan Hedberg 
5523f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
5533f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
5543f8e2d75SJohan Hedberg 	 */
5553f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
55642c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
5572177bab5SJohan Hedberg 
5582177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5592177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
5602177bab5SJohan Hedberg 			u8 mode = 0x01;
56142c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
5622177bab5SJohan Hedberg 				    sizeof(mode), &mode);
5632177bab5SJohan Hedberg 		} else {
5642177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
5652177bab5SJohan Hedberg 
5662177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
5672177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
5682177bab5SJohan Hedberg 
56942c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
5702177bab5SJohan Hedberg 		}
5712177bab5SJohan Hedberg 	}
5722177bab5SJohan Hedberg 
5732177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
57442c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
5752177bab5SJohan Hedberg 
5762177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
57742c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
5782177bab5SJohan Hedberg 
5792177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
5802177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
5812177bab5SJohan Hedberg 
5822177bab5SJohan Hedberg 		cp.page = 0x01;
58342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
58442c6b129SJohan Hedberg 			    sizeof(cp), &cp);
5852177bab5SJohan Hedberg 	}
5862177bab5SJohan Hedberg 
5872177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
5882177bab5SJohan Hedberg 		u8 enable = 1;
58942c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
5902177bab5SJohan Hedberg 			    &enable);
5912177bab5SJohan Hedberg 	}
5922177bab5SJohan Hedberg }
5932177bab5SJohan Hedberg 
59442c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
5952177bab5SJohan Hedberg {
59642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5972177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
5982177bab5SJohan Hedberg 	u16 link_policy = 0;
5992177bab5SJohan Hedberg 
6002177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
6012177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
6022177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
6032177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
6042177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
6052177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
6062177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
6072177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
6082177bab5SJohan Hedberg 
6092177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
61042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
6112177bab5SJohan Hedberg }
6122177bab5SJohan Hedberg 
61342c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
6142177bab5SJohan Hedberg {
61542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
6162177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
6172177bab5SJohan Hedberg 
618c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
619c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
620c73eee91SJohan Hedberg 		return;
621c73eee91SJohan Hedberg 
6222177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
6232177bab5SJohan Hedberg 
6242177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
6252177bab5SJohan Hedberg 		cp.le = 0x01;
6262177bab5SJohan Hedberg 		cp.simul = lmp_le_br_capable(hdev);
6272177bab5SJohan Hedberg 	}
6282177bab5SJohan Hedberg 
6292177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
63042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
6312177bab5SJohan Hedberg 			    &cp);
6322177bab5SJohan Hedberg }
6332177bab5SJohan Hedberg 
634d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
635d62e6d67SJohan Hedberg {
636d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
637d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
638d62e6d67SJohan Hedberg 
639d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
640d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
641d62e6d67SJohan Hedberg 	 */
642d62e6d67SJohan Hedberg 	if (hdev->features[2][0] & 0x01) {
643d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
644d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
645d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
646d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
647d62e6d67SJohan Hedberg 	}
648d62e6d67SJohan Hedberg 
649d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
650d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
651d62e6d67SJohan Hedberg 	 */
652d62e6d67SJohan Hedberg 	if (hdev->features[2][0] & 0x02) {
653d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
654d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
655d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
656d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
657d62e6d67SJohan Hedberg 	}
658d62e6d67SJohan Hedberg 
659d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
660d62e6d67SJohan Hedberg }
661d62e6d67SJohan Hedberg 
66242c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
6632177bab5SJohan Hedberg {
66442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
665d2c5d77fSJohan Hedberg 	u8 p;
66642c6b129SJohan Hedberg 
667b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
668b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
669b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
670b8f4e068SGustavo Padovan 	 *
671b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
672b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
673b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
674b8f4e068SGustavo Padovan 	 * command redundant anyway.
675b8f4e068SGustavo Padovan 	 */
67659f45d57SJohan Hedberg 	if (hdev->commands[6] & 0x80) {
67759f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
67859f45d57SJohan Hedberg 
67959f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
68059f45d57SJohan Hedberg 		cp.delete_all = 0x01;
68159f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
68259f45d57SJohan Hedberg 			    sizeof(cp), &cp);
68359f45d57SJohan Hedberg 	}
68459f45d57SJohan Hedberg 
6852177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
68642c6b129SJohan Hedberg 		hci_setup_link_policy(req);
6872177bab5SJohan Hedberg 
68804b4edcbSJohan Hedberg 	if (lmp_le_capable(hdev)) {
68942c6b129SJohan Hedberg 		hci_set_le_support(req);
69004b4edcbSJohan Hedberg 		hci_update_ad(req);
69104b4edcbSJohan Hedberg 	}
692d2c5d77fSJohan Hedberg 
693d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
694d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
695d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
696d2c5d77fSJohan Hedberg 
697d2c5d77fSJohan Hedberg 		cp.page = p;
698d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
699d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
700d2c5d77fSJohan Hedberg 	}
7012177bab5SJohan Hedberg }
7022177bab5SJohan Hedberg 
7035d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
7045d4e7e8dSJohan Hedberg {
7055d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
7065d4e7e8dSJohan Hedberg 
707d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
708d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
709d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
710d62e6d67SJohan Hedberg 
7115d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
7125d4e7e8dSJohan Hedberg 	if (hdev->features[2][0] & 0x04)
7135d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
7145d4e7e8dSJohan Hedberg }
7155d4e7e8dSJohan Hedberg 
7162177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
7172177bab5SJohan Hedberg {
7182177bab5SJohan Hedberg 	int err;
7192177bab5SJohan Hedberg 
7202177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
7212177bab5SJohan Hedberg 	if (err < 0)
7222177bab5SJohan Hedberg 		return err;
7232177bab5SJohan Hedberg 
7242177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
7252177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
7262177bab5SJohan Hedberg 	 * first stage init.
7272177bab5SJohan Hedberg 	 */
7282177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
7292177bab5SJohan Hedberg 		return 0;
7302177bab5SJohan Hedberg 
7312177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
7322177bab5SJohan Hedberg 	if (err < 0)
7332177bab5SJohan Hedberg 		return err;
7342177bab5SJohan Hedberg 
7355d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
7365d4e7e8dSJohan Hedberg 	if (err < 0)
7375d4e7e8dSJohan Hedberg 		return err;
7385d4e7e8dSJohan Hedberg 
7395d4e7e8dSJohan Hedberg 	return __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
7402177bab5SJohan Hedberg }
7412177bab5SJohan Hedberg 
74242c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
7431da177e4SLinus Torvalds {
7441da177e4SLinus Torvalds 	__u8 scan = opt;
7451da177e4SLinus Torvalds 
74642c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
7471da177e4SLinus Torvalds 
7481da177e4SLinus Torvalds 	/* Inquiry and Page scans */
74942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
7501da177e4SLinus Torvalds }
7511da177e4SLinus Torvalds 
75242c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
7531da177e4SLinus Torvalds {
7541da177e4SLinus Torvalds 	__u8 auth = opt;
7551da177e4SLinus Torvalds 
75642c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
7571da177e4SLinus Torvalds 
7581da177e4SLinus Torvalds 	/* Authentication */
75942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
7601da177e4SLinus Torvalds }
7611da177e4SLinus Torvalds 
76242c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
7631da177e4SLinus Torvalds {
7641da177e4SLinus Torvalds 	__u8 encrypt = opt;
7651da177e4SLinus Torvalds 
76642c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
7671da177e4SLinus Torvalds 
768e4e8e37cSMarcel Holtmann 	/* Encryption */
76942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
7701da177e4SLinus Torvalds }
7711da177e4SLinus Torvalds 
77242c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
773e4e8e37cSMarcel Holtmann {
774e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
775e4e8e37cSMarcel Holtmann 
77642c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
777e4e8e37cSMarcel Holtmann 
778e4e8e37cSMarcel Holtmann 	/* Default link policy */
77942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
780e4e8e37cSMarcel Holtmann }
781e4e8e37cSMarcel Holtmann 
7821da177e4SLinus Torvalds /* Get HCI device by index.
7831da177e4SLinus Torvalds  * Device is held on return. */
7841da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
7851da177e4SLinus Torvalds {
7868035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
7871da177e4SLinus Torvalds 
7881da177e4SLinus Torvalds 	BT_DBG("%d", index);
7891da177e4SLinus Torvalds 
7901da177e4SLinus Torvalds 	if (index < 0)
7911da177e4SLinus Torvalds 		return NULL;
7921da177e4SLinus Torvalds 
7931da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
7948035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
7951da177e4SLinus Torvalds 		if (d->id == index) {
7961da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
7971da177e4SLinus Torvalds 			break;
7981da177e4SLinus Torvalds 		}
7991da177e4SLinus Torvalds 	}
8001da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
8011da177e4SLinus Torvalds 	return hdev;
8021da177e4SLinus Torvalds }
8031da177e4SLinus Torvalds 
8041da177e4SLinus Torvalds /* ---- Inquiry support ---- */
805ff9ef578SJohan Hedberg 
80630dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
80730dc78e1SJohan Hedberg {
80830dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
80930dc78e1SJohan Hedberg 
8106fbe195dSAndre Guedes 	switch (discov->state) {
811343f935bSAndre Guedes 	case DISCOVERY_FINDING:
8126fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
81330dc78e1SJohan Hedberg 		return true;
81430dc78e1SJohan Hedberg 
8156fbe195dSAndre Guedes 	default:
81630dc78e1SJohan Hedberg 		return false;
81730dc78e1SJohan Hedberg 	}
8186fbe195dSAndre Guedes }
81930dc78e1SJohan Hedberg 
820ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
821ff9ef578SJohan Hedberg {
822ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
823ff9ef578SJohan Hedberg 
824ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
825ff9ef578SJohan Hedberg 		return;
826ff9ef578SJohan Hedberg 
827ff9ef578SJohan Hedberg 	switch (state) {
828ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
8297b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
830ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
831ff9ef578SJohan Hedberg 		break;
832ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
833ff9ef578SJohan Hedberg 		break;
834343f935bSAndre Guedes 	case DISCOVERY_FINDING:
835ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
836ff9ef578SJohan Hedberg 		break;
83730dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
83830dc78e1SJohan Hedberg 		break;
839ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
840ff9ef578SJohan Hedberg 		break;
841ff9ef578SJohan Hedberg 	}
842ff9ef578SJohan Hedberg 
843ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
844ff9ef578SJohan Hedberg }
845ff9ef578SJohan Hedberg 
8461f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
8471da177e4SLinus Torvalds {
84830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
849b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
8501da177e4SLinus Torvalds 
851561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
852561aafbcSJohan Hedberg 		list_del(&p->all);
853b57c1a56SJohan Hedberg 		kfree(p);
8541da177e4SLinus Torvalds 	}
855561aafbcSJohan Hedberg 
856561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
857561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
8581da177e4SLinus Torvalds }
8591da177e4SLinus Torvalds 
860a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
861a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
8621da177e4SLinus Torvalds {
86330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
8641da177e4SLinus Torvalds 	struct inquiry_entry *e;
8651da177e4SLinus Torvalds 
8666ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
8671da177e4SLinus Torvalds 
868561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
8691da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
8701da177e4SLinus Torvalds 			return e;
8711da177e4SLinus Torvalds 	}
8721da177e4SLinus Torvalds 
873b57c1a56SJohan Hedberg 	return NULL;
874b57c1a56SJohan Hedberg }
875b57c1a56SJohan Hedberg 
876561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
877561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
878561aafbcSJohan Hedberg {
87930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
880561aafbcSJohan Hedberg 	struct inquiry_entry *e;
881561aafbcSJohan Hedberg 
8826ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
883561aafbcSJohan Hedberg 
884561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
885561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
886561aafbcSJohan Hedberg 			return e;
887561aafbcSJohan Hedberg 	}
888561aafbcSJohan Hedberg 
889561aafbcSJohan Hedberg 	return NULL;
890561aafbcSJohan Hedberg }
891561aafbcSJohan Hedberg 
89230dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
89330dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
89430dc78e1SJohan Hedberg 						       int state)
89530dc78e1SJohan Hedberg {
89630dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
89730dc78e1SJohan Hedberg 	struct inquiry_entry *e;
89830dc78e1SJohan Hedberg 
8996ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
90030dc78e1SJohan Hedberg 
90130dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
90230dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
90330dc78e1SJohan Hedberg 			return e;
90430dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
90530dc78e1SJohan Hedberg 			return e;
90630dc78e1SJohan Hedberg 	}
90730dc78e1SJohan Hedberg 
90830dc78e1SJohan Hedberg 	return NULL;
90930dc78e1SJohan Hedberg }
91030dc78e1SJohan Hedberg 
911a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
912a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
913a3d4e20aSJohan Hedberg {
914a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
915a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
916a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
917a3d4e20aSJohan Hedberg 
918a3d4e20aSJohan Hedberg 	list_del(&ie->list);
919a3d4e20aSJohan Hedberg 
920a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
921a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
922a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
923a3d4e20aSJohan Hedberg 			break;
924a3d4e20aSJohan Hedberg 		pos = &p->list;
925a3d4e20aSJohan Hedberg 	}
926a3d4e20aSJohan Hedberg 
927a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
928a3d4e20aSJohan Hedberg }
929a3d4e20aSJohan Hedberg 
9303175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
931388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
9321da177e4SLinus Torvalds {
93330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
93470f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
9351da177e4SLinus Torvalds 
9366ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
9371da177e4SLinus Torvalds 
9382b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
9392b2fec4dSSzymon Janc 
940388fc8faSJohan Hedberg 	if (ssp)
941388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
942388fc8faSJohan Hedberg 
94370f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
944a3d4e20aSJohan Hedberg 	if (ie) {
945388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
946388fc8faSJohan Hedberg 			*ssp = true;
947388fc8faSJohan Hedberg 
948a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
949a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
950a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
951a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
952a3d4e20aSJohan Hedberg 		}
953a3d4e20aSJohan Hedberg 
954561aafbcSJohan Hedberg 		goto update;
955a3d4e20aSJohan Hedberg 	}
956561aafbcSJohan Hedberg 
9571da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
95870f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
95970f23020SAndrei Emeltchenko 	if (!ie)
9603175405bSJohan Hedberg 		return false;
96170f23020SAndrei Emeltchenko 
962561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
963561aafbcSJohan Hedberg 
964561aafbcSJohan Hedberg 	if (name_known) {
965561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
966561aafbcSJohan Hedberg 	} else {
967561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
968561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
969561aafbcSJohan Hedberg 	}
970561aafbcSJohan Hedberg 
971561aafbcSJohan Hedberg update:
972561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
973561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
974561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
975561aafbcSJohan Hedberg 		list_del(&ie->list);
9761da177e4SLinus Torvalds 	}
9771da177e4SLinus Torvalds 
97870f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
97970f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
9801da177e4SLinus Torvalds 	cache->timestamp = jiffies;
9813175405bSJohan Hedberg 
9823175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
9833175405bSJohan Hedberg 		return false;
9843175405bSJohan Hedberg 
9853175405bSJohan Hedberg 	return true;
9861da177e4SLinus Torvalds }
9871da177e4SLinus Torvalds 
9881da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
9891da177e4SLinus Torvalds {
99030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
9911da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
9921da177e4SLinus Torvalds 	struct inquiry_entry *e;
9931da177e4SLinus Torvalds 	int copied = 0;
9941da177e4SLinus Torvalds 
995561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
9961da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
997b57c1a56SJohan Hedberg 
998b57c1a56SJohan Hedberg 		if (copied >= num)
999b57c1a56SJohan Hedberg 			break;
1000b57c1a56SJohan Hedberg 
10011da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
10021da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
10031da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
10041da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
10051da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
10061da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
1007b57c1a56SJohan Hedberg 
10081da177e4SLinus Torvalds 		info++;
1009b57c1a56SJohan Hedberg 		copied++;
10101da177e4SLinus Torvalds 	}
10111da177e4SLinus Torvalds 
10121da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
10131da177e4SLinus Torvalds 	return copied;
10141da177e4SLinus Torvalds }
10151da177e4SLinus Torvalds 
101642c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
10171da177e4SLinus Torvalds {
10181da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
101942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
10201da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
10211da177e4SLinus Torvalds 
10221da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
10231da177e4SLinus Torvalds 
10241da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
10251da177e4SLinus Torvalds 		return;
10261da177e4SLinus Torvalds 
10271da177e4SLinus Torvalds 	/* Start Inquiry */
10281da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
10291da177e4SLinus Torvalds 	cp.length  = ir->length;
10301da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
103142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
10321da177e4SLinus Torvalds }
10331da177e4SLinus Torvalds 
10343e13fa1eSAndre Guedes static int wait_inquiry(void *word)
10353e13fa1eSAndre Guedes {
10363e13fa1eSAndre Guedes 	schedule();
10373e13fa1eSAndre Guedes 	return signal_pending(current);
10383e13fa1eSAndre Guedes }
10393e13fa1eSAndre Guedes 
10401da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
10411da177e4SLinus Torvalds {
10421da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
10431da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
10441da177e4SLinus Torvalds 	struct hci_dev *hdev;
10451da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
10461da177e4SLinus Torvalds 	long timeo;
10471da177e4SLinus Torvalds 	__u8 *buf;
10481da177e4SLinus Torvalds 
10491da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
10501da177e4SLinus Torvalds 		return -EFAULT;
10511da177e4SLinus Torvalds 
10525a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
10535a08ecceSAndrei Emeltchenko 	if (!hdev)
10541da177e4SLinus Torvalds 		return -ENODEV;
10551da177e4SLinus Torvalds 
10560736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
10570736cfa8SMarcel Holtmann 		err = -EBUSY;
10580736cfa8SMarcel Holtmann 		goto done;
10590736cfa8SMarcel Holtmann 	}
10600736cfa8SMarcel Holtmann 
10615b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
10625b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
10635b69bef5SMarcel Holtmann 		goto done;
10645b69bef5SMarcel Holtmann 	}
10655b69bef5SMarcel Holtmann 
106656f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
106756f87901SJohan Hedberg 		err = -EOPNOTSUPP;
106856f87901SJohan Hedberg 		goto done;
106956f87901SJohan Hedberg 	}
107056f87901SJohan Hedberg 
107109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
10721da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1073a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
10741f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
10751da177e4SLinus Torvalds 		do_inquiry = 1;
10761da177e4SLinus Torvalds 	}
107709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
10781da177e4SLinus Torvalds 
107904837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
108070f23020SAndrei Emeltchenko 
108170f23020SAndrei Emeltchenko 	if (do_inquiry) {
108201178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
108301178cd4SJohan Hedberg 				   timeo);
108470f23020SAndrei Emeltchenko 		if (err < 0)
10851da177e4SLinus Torvalds 			goto done;
10863e13fa1eSAndre Guedes 
10873e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
10883e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
10893e13fa1eSAndre Guedes 		 */
10903e13fa1eSAndre Guedes 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry,
10913e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
10923e13fa1eSAndre Guedes 			return -EINTR;
109370f23020SAndrei Emeltchenko 	}
10941da177e4SLinus Torvalds 
10958fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
10968fc9ced3SGustavo Padovan 	 * 255 entries
10978fc9ced3SGustavo Padovan 	 */
10981da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
10991da177e4SLinus Torvalds 
11001da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
11011da177e4SLinus Torvalds 	 * copy it to the user space.
11021da177e4SLinus Torvalds 	 */
110370f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
110470f23020SAndrei Emeltchenko 	if (!buf) {
11051da177e4SLinus Torvalds 		err = -ENOMEM;
11061da177e4SLinus Torvalds 		goto done;
11071da177e4SLinus Torvalds 	}
11081da177e4SLinus Torvalds 
110909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
11101da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
111109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
11121da177e4SLinus Torvalds 
11131da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
11141da177e4SLinus Torvalds 
11151da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
11161da177e4SLinus Torvalds 		ptr += sizeof(ir);
11171da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
11181da177e4SLinus Torvalds 				 ir.num_rsp))
11191da177e4SLinus Torvalds 			err = -EFAULT;
11201da177e4SLinus Torvalds 	} else
11211da177e4SLinus Torvalds 		err = -EFAULT;
11221da177e4SLinus Torvalds 
11231da177e4SLinus Torvalds 	kfree(buf);
11241da177e4SLinus Torvalds 
11251da177e4SLinus Torvalds done:
11261da177e4SLinus Torvalds 	hci_dev_put(hdev);
11271da177e4SLinus Torvalds 	return err;
11281da177e4SLinus Torvalds }
11291da177e4SLinus Torvalds 
11303f0f524bSJohan Hedberg static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
11313f0f524bSJohan Hedberg {
11323f0f524bSJohan Hedberg 	u8 ad_len = 0, flags = 0;
11333f0f524bSJohan Hedberg 	size_t name_len;
11343f0f524bSJohan Hedberg 
1135f3d3444aSJohan Hedberg 	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
11363f0f524bSJohan Hedberg 		flags |= LE_AD_GENERAL;
11373f0f524bSJohan Hedberg 
113811802b29SJohan Hedberg 	if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
11393f0f524bSJohan Hedberg 		if (lmp_le_br_capable(hdev))
11403f0f524bSJohan Hedberg 			flags |= LE_AD_SIM_LE_BREDR_CTRL;
11413f0f524bSJohan Hedberg 		if (lmp_host_le_br_capable(hdev))
11423f0f524bSJohan Hedberg 			flags |= LE_AD_SIM_LE_BREDR_HOST;
114311802b29SJohan Hedberg 	} else {
114411802b29SJohan Hedberg 		flags |= LE_AD_NO_BREDR;
114511802b29SJohan Hedberg 	}
11463f0f524bSJohan Hedberg 
11473f0f524bSJohan Hedberg 	if (flags) {
11483f0f524bSJohan Hedberg 		BT_DBG("adv flags 0x%02x", flags);
11493f0f524bSJohan Hedberg 
11503f0f524bSJohan Hedberg 		ptr[0] = 2;
11513f0f524bSJohan Hedberg 		ptr[1] = EIR_FLAGS;
11523f0f524bSJohan Hedberg 		ptr[2] = flags;
11533f0f524bSJohan Hedberg 
11543f0f524bSJohan Hedberg 		ad_len += 3;
11553f0f524bSJohan Hedberg 		ptr += 3;
11563f0f524bSJohan Hedberg 	}
11573f0f524bSJohan Hedberg 
11583f0f524bSJohan Hedberg 	if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) {
11593f0f524bSJohan Hedberg 		ptr[0] = 2;
11603f0f524bSJohan Hedberg 		ptr[1] = EIR_TX_POWER;
11613f0f524bSJohan Hedberg 		ptr[2] = (u8) hdev->adv_tx_power;
11623f0f524bSJohan Hedberg 
11633f0f524bSJohan Hedberg 		ad_len += 3;
11643f0f524bSJohan Hedberg 		ptr += 3;
11653f0f524bSJohan Hedberg 	}
11663f0f524bSJohan Hedberg 
11673f0f524bSJohan Hedberg 	name_len = strlen(hdev->dev_name);
11683f0f524bSJohan Hedberg 	if (name_len > 0) {
11693f0f524bSJohan Hedberg 		size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
11703f0f524bSJohan Hedberg 
11713f0f524bSJohan Hedberg 		if (name_len > max_len) {
11723f0f524bSJohan Hedberg 			name_len = max_len;
11733f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_SHORT;
11743f0f524bSJohan Hedberg 		} else
11753f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_COMPLETE;
11763f0f524bSJohan Hedberg 
11773f0f524bSJohan Hedberg 		ptr[0] = name_len + 1;
11783f0f524bSJohan Hedberg 
11793f0f524bSJohan Hedberg 		memcpy(ptr + 2, hdev->dev_name, name_len);
11803f0f524bSJohan Hedberg 
11813f0f524bSJohan Hedberg 		ad_len += (name_len + 2);
11823f0f524bSJohan Hedberg 		ptr += (name_len + 2);
11833f0f524bSJohan Hedberg 	}
11843f0f524bSJohan Hedberg 
11853f0f524bSJohan Hedberg 	return ad_len;
11863f0f524bSJohan Hedberg }
11873f0f524bSJohan Hedberg 
118804b4edcbSJohan Hedberg void hci_update_ad(struct hci_request *req)
11893f0f524bSJohan Hedberg {
119004b4edcbSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
11913f0f524bSJohan Hedberg 	struct hci_cp_le_set_adv_data cp;
11923f0f524bSJohan Hedberg 	u8 len;
11933f0f524bSJohan Hedberg 
119404b4edcbSJohan Hedberg 	if (!lmp_le_capable(hdev))
119504b4edcbSJohan Hedberg 		return;
11963f0f524bSJohan Hedberg 
11973f0f524bSJohan Hedberg 	memset(&cp, 0, sizeof(cp));
11983f0f524bSJohan Hedberg 
11993f0f524bSJohan Hedberg 	len = create_ad(hdev, cp.data);
12003f0f524bSJohan Hedberg 
12013f0f524bSJohan Hedberg 	if (hdev->adv_data_len == len &&
120204b4edcbSJohan Hedberg 	    memcmp(cp.data, hdev->adv_data, len) == 0)
120304b4edcbSJohan Hedberg 		return;
12043f0f524bSJohan Hedberg 
12053f0f524bSJohan Hedberg 	memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
12063f0f524bSJohan Hedberg 	hdev->adv_data_len = len;
12073f0f524bSJohan Hedberg 
12083f0f524bSJohan Hedberg 	cp.length = len;
12093f0f524bSJohan Hedberg 
121004b4edcbSJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
12113f0f524bSJohan Hedberg }
12123f0f524bSJohan Hedberg 
1213cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
12141da177e4SLinus Torvalds {
12151da177e4SLinus Torvalds 	int ret = 0;
12161da177e4SLinus Torvalds 
12171da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
12181da177e4SLinus Torvalds 
12191da177e4SLinus Torvalds 	hci_req_lock(hdev);
12201da177e4SLinus Torvalds 
122194324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
122294324962SJohan Hovold 		ret = -ENODEV;
122394324962SJohan Hovold 		goto done;
122494324962SJohan Hovold 	}
122594324962SJohan Hovold 
1226a5c8f270SMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
1227a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1228a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1229bf543036SJohan Hedberg 		 */
1230a5c8f270SMarcel Holtmann 		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
1231611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1232611b30f7SMarcel Holtmann 			goto done;
1233611b30f7SMarcel Holtmann 		}
1234611b30f7SMarcel Holtmann 
1235a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
1236a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
1237a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1238a5c8f270SMarcel Holtmann 		 * or not.
1239a5c8f270SMarcel Holtmann 		 *
1240a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1241a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1242a5c8f270SMarcel Holtmann 		 */
1243a5c8f270SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR &&
1244a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1245a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1246a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1247a5c8f270SMarcel Holtmann 			goto done;
1248a5c8f270SMarcel Holtmann 		}
1249a5c8f270SMarcel Holtmann 	}
1250a5c8f270SMarcel Holtmann 
12511da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
12521da177e4SLinus Torvalds 		ret = -EALREADY;
12531da177e4SLinus Torvalds 		goto done;
12541da177e4SLinus Torvalds 	}
12551da177e4SLinus Torvalds 
12561da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
12571da177e4SLinus Torvalds 		ret = -EIO;
12581da177e4SLinus Torvalds 		goto done;
12591da177e4SLinus Torvalds 	}
12601da177e4SLinus Torvalds 
12611da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
12621da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1263f41c70c4SMarcel Holtmann 
1264f41c70c4SMarcel Holtmann 	if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
1265f41c70c4SMarcel Holtmann 		ret = hdev->setup(hdev);
1266f41c70c4SMarcel Holtmann 
1267f41c70c4SMarcel Holtmann 	if (!ret) {
1268f41c70c4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1269f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
1270f41c70c4SMarcel Holtmann 
12710736cfa8SMarcel Holtmann 		if (!test_bit(HCI_RAW, &hdev->flags) &&
12720736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
12732177bab5SJohan Hedberg 			ret = __hci_init(hdev);
12741da177e4SLinus Torvalds 	}
12751da177e4SLinus Torvalds 
1276f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1277f41c70c4SMarcel Holtmann 
12781da177e4SLinus Torvalds 	if (!ret) {
12791da177e4SLinus Torvalds 		hci_dev_hold(hdev);
12801da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
12811da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
1282bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
12830736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
12841514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
128509fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1286744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
128709fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
128856e5cb86SJohan Hedberg 		}
12891da177e4SLinus Torvalds 	} else {
12901da177e4SLinus Torvalds 		/* Init failed, cleanup */
12913eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1292c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1293b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
12941da177e4SLinus Torvalds 
12951da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
12961da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
12971da177e4SLinus Torvalds 
12981da177e4SLinus Torvalds 		if (hdev->flush)
12991da177e4SLinus Torvalds 			hdev->flush(hdev);
13001da177e4SLinus Torvalds 
13011da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
13021da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
13031da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
13041da177e4SLinus Torvalds 		}
13051da177e4SLinus Torvalds 
13061da177e4SLinus Torvalds 		hdev->close(hdev);
13071da177e4SLinus Torvalds 		hdev->flags = 0;
13081da177e4SLinus Torvalds 	}
13091da177e4SLinus Torvalds 
13101da177e4SLinus Torvalds done:
13111da177e4SLinus Torvalds 	hci_req_unlock(hdev);
13121da177e4SLinus Torvalds 	return ret;
13131da177e4SLinus Torvalds }
13141da177e4SLinus Torvalds 
1315cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
1316cbed0ca1SJohan Hedberg 
1317cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
1318cbed0ca1SJohan Hedberg {
1319cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
1320cbed0ca1SJohan Hedberg 	int err;
1321cbed0ca1SJohan Hedberg 
1322cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
1323cbed0ca1SJohan Hedberg 	if (!hdev)
1324cbed0ca1SJohan Hedberg 		return -ENODEV;
1325cbed0ca1SJohan Hedberg 
1326e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
1327e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
1328e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
1329e1d08f40SJohan Hedberg 	 * completed.
1330e1d08f40SJohan Hedberg 	 */
1331e1d08f40SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1332e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
1333e1d08f40SJohan Hedberg 
1334a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
1335a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
1336a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
1337a5c8f270SMarcel Holtmann 	 */
1338e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
1339e1d08f40SJohan Hedberg 
1340cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
1341cbed0ca1SJohan Hedberg 
1342cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
1343cbed0ca1SJohan Hedberg 
1344cbed0ca1SJohan Hedberg 	return err;
1345cbed0ca1SJohan Hedberg }
1346cbed0ca1SJohan Hedberg 
13471da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
13481da177e4SLinus Torvalds {
13491da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
13501da177e4SLinus Torvalds 
135178c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
135278c04c0bSVinicius Costa Gomes 
13531da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
13541da177e4SLinus Torvalds 	hci_req_lock(hdev);
13551da177e4SLinus Torvalds 
13561da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
1357b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
13581da177e4SLinus Torvalds 		hci_req_unlock(hdev);
13591da177e4SLinus Torvalds 		return 0;
13601da177e4SLinus Torvalds 	}
13611da177e4SLinus Torvalds 
13623eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
13633eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1364b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
13651da177e4SLinus Torvalds 
136616ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
1367e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
136816ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
13695e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
137016ab91abSJohan Hedberg 	}
137116ab91abSJohan Hedberg 
1372a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
13737d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
13747d78525dSJohan Hedberg 
13757ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
13767ba8b4beSAndre Guedes 
137709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13781f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
13791da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
138009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13811da177e4SLinus Torvalds 
13821da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
13831da177e4SLinus Torvalds 
13841da177e4SLinus Torvalds 	if (hdev->flush)
13851da177e4SLinus Torvalds 		hdev->flush(hdev);
13861da177e4SLinus Torvalds 
13871da177e4SLinus Torvalds 	/* Reset device */
13881da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
13891da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
13908af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
13913a6afbd2SMarcel Holtmann 	    !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
1392a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
13931da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
139401178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
13951da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
13961da177e4SLinus Torvalds 	}
13971da177e4SLinus Torvalds 
1398c347b765SGustavo F. Padovan 	/* flush cmd  work */
1399c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
14001da177e4SLinus Torvalds 
14011da177e4SLinus Torvalds 	/* Drop queues */
14021da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
14031da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
14041da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
14051da177e4SLinus Torvalds 
14061da177e4SLinus Torvalds 	/* Drop last sent command */
14071da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
1408b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
14091da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
14101da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
14111da177e4SLinus Torvalds 	}
14121da177e4SLinus Torvalds 
1413b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
1414b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
1415b6ddb638SJohan Hedberg 
14161da177e4SLinus Torvalds 	/* After this point our queues are empty
14171da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
14181da177e4SLinus Torvalds 	hdev->close(hdev);
14191da177e4SLinus Torvalds 
142035b973c9SJohan Hedberg 	/* Clear flags */
142135b973c9SJohan Hedberg 	hdev->flags = 0;
142235b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
142335b973c9SJohan Hedberg 
142493c311a0SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
142593c311a0SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR) {
142609fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1427744cf19eSJohan Hedberg 			mgmt_powered(hdev, 0);
142809fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
14298ee56540SMarcel Holtmann 		}
143093c311a0SMarcel Holtmann 	}
14315add6af8SJohan Hedberg 
1432ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1433536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
1434ced5c338SAndrei Emeltchenko 
1435e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
143609b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
1437e59fda8dSJohan Hedberg 
14381da177e4SLinus Torvalds 	hci_req_unlock(hdev);
14391da177e4SLinus Torvalds 
14401da177e4SLinus Torvalds 	hci_dev_put(hdev);
14411da177e4SLinus Torvalds 	return 0;
14421da177e4SLinus Torvalds }
14431da177e4SLinus Torvalds 
14441da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
14451da177e4SLinus Torvalds {
14461da177e4SLinus Torvalds 	struct hci_dev *hdev;
14471da177e4SLinus Torvalds 	int err;
14481da177e4SLinus Torvalds 
144970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
145070f23020SAndrei Emeltchenko 	if (!hdev)
14511da177e4SLinus Torvalds 		return -ENODEV;
14528ee56540SMarcel Holtmann 
14530736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
14540736cfa8SMarcel Holtmann 		err = -EBUSY;
14550736cfa8SMarcel Holtmann 		goto done;
14560736cfa8SMarcel Holtmann 	}
14570736cfa8SMarcel Holtmann 
14588ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
14598ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
14608ee56540SMarcel Holtmann 
14611da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
14628ee56540SMarcel Holtmann 
14630736cfa8SMarcel Holtmann done:
14641da177e4SLinus Torvalds 	hci_dev_put(hdev);
14651da177e4SLinus Torvalds 	return err;
14661da177e4SLinus Torvalds }
14671da177e4SLinus Torvalds 
14681da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
14691da177e4SLinus Torvalds {
14701da177e4SLinus Torvalds 	struct hci_dev *hdev;
14711da177e4SLinus Torvalds 	int ret = 0;
14721da177e4SLinus Torvalds 
147370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
147470f23020SAndrei Emeltchenko 	if (!hdev)
14751da177e4SLinus Torvalds 		return -ENODEV;
14761da177e4SLinus Torvalds 
14771da177e4SLinus Torvalds 	hci_req_lock(hdev);
14781da177e4SLinus Torvalds 
1479808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
1480808a049eSMarcel Holtmann 		ret = -ENETDOWN;
14811da177e4SLinus Torvalds 		goto done;
1482808a049eSMarcel Holtmann 	}
14831da177e4SLinus Torvalds 
14840736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
14850736cfa8SMarcel Holtmann 		ret = -EBUSY;
14860736cfa8SMarcel Holtmann 		goto done;
14870736cfa8SMarcel Holtmann 	}
14880736cfa8SMarcel Holtmann 
14891da177e4SLinus Torvalds 	/* Drop queues */
14901da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
14911da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
14921da177e4SLinus Torvalds 
149309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
14941f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
14951da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
149609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
14971da177e4SLinus Torvalds 
14981da177e4SLinus Torvalds 	if (hdev->flush)
14991da177e4SLinus Torvalds 		hdev->flush(hdev);
15001da177e4SLinus Torvalds 
15011da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
15026ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
15031da177e4SLinus Torvalds 
15041da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
150501178cd4SJohan Hedberg 		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
15061da177e4SLinus Torvalds 
15071da177e4SLinus Torvalds done:
15081da177e4SLinus Torvalds 	hci_req_unlock(hdev);
15091da177e4SLinus Torvalds 	hci_dev_put(hdev);
15101da177e4SLinus Torvalds 	return ret;
15111da177e4SLinus Torvalds }
15121da177e4SLinus Torvalds 
15131da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
15141da177e4SLinus Torvalds {
15151da177e4SLinus Torvalds 	struct hci_dev *hdev;
15161da177e4SLinus Torvalds 	int ret = 0;
15171da177e4SLinus Torvalds 
151870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
151970f23020SAndrei Emeltchenko 	if (!hdev)
15201da177e4SLinus Torvalds 		return -ENODEV;
15211da177e4SLinus Torvalds 
15220736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
15230736cfa8SMarcel Holtmann 		ret = -EBUSY;
15240736cfa8SMarcel Holtmann 		goto done;
15250736cfa8SMarcel Holtmann 	}
15260736cfa8SMarcel Holtmann 
15271da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
15281da177e4SLinus Torvalds 
15290736cfa8SMarcel Holtmann done:
15301da177e4SLinus Torvalds 	hci_dev_put(hdev);
15311da177e4SLinus Torvalds 	return ret;
15321da177e4SLinus Torvalds }
15331da177e4SLinus Torvalds 
15341da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
15351da177e4SLinus Torvalds {
15361da177e4SLinus Torvalds 	struct hci_dev *hdev;
15371da177e4SLinus Torvalds 	struct hci_dev_req dr;
15381da177e4SLinus Torvalds 	int err = 0;
15391da177e4SLinus Torvalds 
15401da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
15411da177e4SLinus Torvalds 		return -EFAULT;
15421da177e4SLinus Torvalds 
154370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
154470f23020SAndrei Emeltchenko 	if (!hdev)
15451da177e4SLinus Torvalds 		return -ENODEV;
15461da177e4SLinus Torvalds 
15470736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
15480736cfa8SMarcel Holtmann 		err = -EBUSY;
15490736cfa8SMarcel Holtmann 		goto done;
15500736cfa8SMarcel Holtmann 	}
15510736cfa8SMarcel Holtmann 
15525b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
15535b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
15545b69bef5SMarcel Holtmann 		goto done;
15555b69bef5SMarcel Holtmann 	}
15565b69bef5SMarcel Holtmann 
155756f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
155856f87901SJohan Hedberg 		err = -EOPNOTSUPP;
155956f87901SJohan Hedberg 		goto done;
156056f87901SJohan Hedberg 	}
156156f87901SJohan Hedberg 
15621da177e4SLinus Torvalds 	switch (cmd) {
15631da177e4SLinus Torvalds 	case HCISETAUTH:
156401178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
15655f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15661da177e4SLinus Torvalds 		break;
15671da177e4SLinus Torvalds 
15681da177e4SLinus Torvalds 	case HCISETENCRYPT:
15691da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
15701da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
15711da177e4SLinus Torvalds 			break;
15721da177e4SLinus Torvalds 		}
15731da177e4SLinus Torvalds 
15741da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
15751da177e4SLinus Torvalds 			/* Auth must be enabled first */
157601178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
15775f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
15781da177e4SLinus Torvalds 			if (err)
15791da177e4SLinus Torvalds 				break;
15801da177e4SLinus Torvalds 		}
15811da177e4SLinus Torvalds 
158201178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
15835f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15841da177e4SLinus Torvalds 		break;
15851da177e4SLinus Torvalds 
15861da177e4SLinus Torvalds 	case HCISETSCAN:
158701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
15885f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15891da177e4SLinus Torvalds 		break;
15901da177e4SLinus Torvalds 
15911da177e4SLinus Torvalds 	case HCISETLINKPOL:
159201178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
15935f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15941da177e4SLinus Torvalds 		break;
15951da177e4SLinus Torvalds 
15961da177e4SLinus Torvalds 	case HCISETLINKMODE:
1597e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
1598e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
1599e4e8e37cSMarcel Holtmann 		break;
1600e4e8e37cSMarcel Holtmann 
1601e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
1602e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
16031da177e4SLinus Torvalds 		break;
16041da177e4SLinus Torvalds 
16051da177e4SLinus Torvalds 	case HCISETACLMTU:
16061da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
16071da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
16081da177e4SLinus Torvalds 		break;
16091da177e4SLinus Torvalds 
16101da177e4SLinus Torvalds 	case HCISETSCOMTU:
16111da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
16121da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
16131da177e4SLinus Torvalds 		break;
16141da177e4SLinus Torvalds 
16151da177e4SLinus Torvalds 	default:
16161da177e4SLinus Torvalds 		err = -EINVAL;
16171da177e4SLinus Torvalds 		break;
16181da177e4SLinus Torvalds 	}
1619e4e8e37cSMarcel Holtmann 
16200736cfa8SMarcel Holtmann done:
16211da177e4SLinus Torvalds 	hci_dev_put(hdev);
16221da177e4SLinus Torvalds 	return err;
16231da177e4SLinus Torvalds }
16241da177e4SLinus Torvalds 
16251da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
16261da177e4SLinus Torvalds {
16278035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
16281da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
16291da177e4SLinus Torvalds 	struct hci_dev_req *dr;
16301da177e4SLinus Torvalds 	int n = 0, size, err;
16311da177e4SLinus Torvalds 	__u16 dev_num;
16321da177e4SLinus Torvalds 
16331da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
16341da177e4SLinus Torvalds 		return -EFAULT;
16351da177e4SLinus Torvalds 
16361da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
16371da177e4SLinus Torvalds 		return -EINVAL;
16381da177e4SLinus Torvalds 
16391da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
16401da177e4SLinus Torvalds 
164170f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
164270f23020SAndrei Emeltchenko 	if (!dl)
16431da177e4SLinus Torvalds 		return -ENOMEM;
16441da177e4SLinus Torvalds 
16451da177e4SLinus Torvalds 	dr = dl->dev_req;
16461da177e4SLinus Torvalds 
1647f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
16488035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
1649a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1650e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
1651c542a06cSJohan Hedberg 
1652a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1653a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1654c542a06cSJohan Hedberg 
16551da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
16561da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
1657c542a06cSJohan Hedberg 
16581da177e4SLinus Torvalds 		if (++n >= dev_num)
16591da177e4SLinus Torvalds 			break;
16601da177e4SLinus Torvalds 	}
1661f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
16621da177e4SLinus Torvalds 
16631da177e4SLinus Torvalds 	dl->dev_num = n;
16641da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
16651da177e4SLinus Torvalds 
16661da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
16671da177e4SLinus Torvalds 	kfree(dl);
16681da177e4SLinus Torvalds 
16691da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
16701da177e4SLinus Torvalds }
16711da177e4SLinus Torvalds 
16721da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
16731da177e4SLinus Torvalds {
16741da177e4SLinus Torvalds 	struct hci_dev *hdev;
16751da177e4SLinus Torvalds 	struct hci_dev_info di;
16761da177e4SLinus Torvalds 	int err = 0;
16771da177e4SLinus Torvalds 
16781da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
16791da177e4SLinus Torvalds 		return -EFAULT;
16801da177e4SLinus Torvalds 
168170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
168270f23020SAndrei Emeltchenko 	if (!hdev)
16831da177e4SLinus Torvalds 		return -ENODEV;
16841da177e4SLinus Torvalds 
1685a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
16863243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1687ab81cbf9SJohan Hedberg 
1688a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1689a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1690c542a06cSJohan Hedberg 
16911da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
16921da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
169360f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
16941da177e4SLinus Torvalds 	di.flags    = hdev->flags;
16951da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
1696572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
16971da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
16981da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
16991da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
17001da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
1701572c7f84SJohan Hedberg 	} else {
1702572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
1703572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
1704572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
1705572c7f84SJohan Hedberg 		di.sco_pkts = 0;
1706572c7f84SJohan Hedberg 	}
17071da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
17081da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
17091da177e4SLinus Torvalds 
17101da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
17111da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
17121da177e4SLinus Torvalds 
17131da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
17141da177e4SLinus Torvalds 		err = -EFAULT;
17151da177e4SLinus Torvalds 
17161da177e4SLinus Torvalds 	hci_dev_put(hdev);
17171da177e4SLinus Torvalds 
17181da177e4SLinus Torvalds 	return err;
17191da177e4SLinus Torvalds }
17201da177e4SLinus Torvalds 
17211da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
17221da177e4SLinus Torvalds 
1723611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1724611b30f7SMarcel Holtmann {
1725611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1726611b30f7SMarcel Holtmann 
1727611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1728611b30f7SMarcel Holtmann 
17290736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
17300736cfa8SMarcel Holtmann 		return -EBUSY;
17310736cfa8SMarcel Holtmann 
17325e130367SJohan Hedberg 	if (blocked) {
17335e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
1734bf543036SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags))
1735611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
17365e130367SJohan Hedberg 	} else {
17375e130367SJohan Hedberg 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
17385e130367SJohan Hedberg 	}
1739611b30f7SMarcel Holtmann 
1740611b30f7SMarcel Holtmann 	return 0;
1741611b30f7SMarcel Holtmann }
1742611b30f7SMarcel Holtmann 
1743611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1744611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1745611b30f7SMarcel Holtmann };
1746611b30f7SMarcel Holtmann 
1747ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1748ab81cbf9SJohan Hedberg {
1749ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
175096570ffcSJohan Hedberg 	int err;
1751ab81cbf9SJohan Hedberg 
1752ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1753ab81cbf9SJohan Hedberg 
1754cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
175596570ffcSJohan Hedberg 	if (err < 0) {
175696570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
1757ab81cbf9SJohan Hedberg 		return;
175896570ffcSJohan Hedberg 	}
1759ab81cbf9SJohan Hedberg 
1760a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
1761a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
1762a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
1763a5c8f270SMarcel Holtmann 	 */
1764a5c8f270SMarcel Holtmann 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
1765a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
1766a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1767a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
1768bf543036SJohan Hedberg 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
1769bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
1770bf543036SJohan Hedberg 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
177119202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
177219202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
1773bf543036SJohan Hedberg 	}
1774ab81cbf9SJohan Hedberg 
1775a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1776744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1777ab81cbf9SJohan Hedberg }
1778ab81cbf9SJohan Hedberg 
1779ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1780ab81cbf9SJohan Hedberg {
17813243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
17823243553fSJohan Hedberg 					    power_off.work);
1783ab81cbf9SJohan Hedberg 
1784ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1785ab81cbf9SJohan Hedberg 
17868ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1787ab81cbf9SJohan Hedberg }
1788ab81cbf9SJohan Hedberg 
178916ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
179016ab91abSJohan Hedberg {
179116ab91abSJohan Hedberg 	struct hci_dev *hdev;
1792b1e73124SMarcel Holtmann 	struct hci_request req;
179316ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
179416ab91abSJohan Hedberg 
179516ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
179616ab91abSJohan Hedberg 
179716ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
179816ab91abSJohan Hedberg 
179909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
180016ab91abSJohan Hedberg 
1801b1e73124SMarcel Holtmann 	hci_req_init(&req, hdev);
1802b1e73124SMarcel Holtmann 	hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
1803b1e73124SMarcel Holtmann 	hci_req_run(&req, NULL);
180416ab91abSJohan Hedberg 
180516ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
180616ab91abSJohan Hedberg 
180709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
180816ab91abSJohan Hedberg }
180916ab91abSJohan Hedberg 
18102aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
18112aeb9a1aSJohan Hedberg {
18124821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
18132aeb9a1aSJohan Hedberg 
18144821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
18154821002cSJohan Hedberg 		list_del(&uuid->list);
18162aeb9a1aSJohan Hedberg 		kfree(uuid);
18172aeb9a1aSJohan Hedberg 	}
18182aeb9a1aSJohan Hedberg 
18192aeb9a1aSJohan Hedberg 	return 0;
18202aeb9a1aSJohan Hedberg }
18212aeb9a1aSJohan Hedberg 
182255ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
182355ed8ca1SJohan Hedberg {
182455ed8ca1SJohan Hedberg 	struct list_head *p, *n;
182555ed8ca1SJohan Hedberg 
182655ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
182755ed8ca1SJohan Hedberg 		struct link_key *key;
182855ed8ca1SJohan Hedberg 
182955ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
183055ed8ca1SJohan Hedberg 
183155ed8ca1SJohan Hedberg 		list_del(p);
183255ed8ca1SJohan Hedberg 		kfree(key);
183355ed8ca1SJohan Hedberg 	}
183455ed8ca1SJohan Hedberg 
183555ed8ca1SJohan Hedberg 	return 0;
183655ed8ca1SJohan Hedberg }
183755ed8ca1SJohan Hedberg 
1838b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1839b899efafSVinicius Costa Gomes {
1840b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1841b899efafSVinicius Costa Gomes 
1842b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1843b899efafSVinicius Costa Gomes 		list_del(&k->list);
1844b899efafSVinicius Costa Gomes 		kfree(k);
1845b899efafSVinicius Costa Gomes 	}
1846b899efafSVinicius Costa Gomes 
1847b899efafSVinicius Costa Gomes 	return 0;
1848b899efafSVinicius Costa Gomes }
1849b899efafSVinicius Costa Gomes 
185055ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
185155ed8ca1SJohan Hedberg {
185255ed8ca1SJohan Hedberg 	struct link_key *k;
185355ed8ca1SJohan Hedberg 
18548035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
185555ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
185655ed8ca1SJohan Hedberg 			return k;
185755ed8ca1SJohan Hedberg 
185855ed8ca1SJohan Hedberg 	return NULL;
185955ed8ca1SJohan Hedberg }
186055ed8ca1SJohan Hedberg 
1861745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1862d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1863d25e28abSJohan Hedberg {
1864d25e28abSJohan Hedberg 	/* Legacy key */
1865d25e28abSJohan Hedberg 	if (key_type < 0x03)
1866745c0ce3SVishal Agarwal 		return true;
1867d25e28abSJohan Hedberg 
1868d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1869d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1870745c0ce3SVishal Agarwal 		return false;
1871d25e28abSJohan Hedberg 
1872d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1873d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1874745c0ce3SVishal Agarwal 		return false;
1875d25e28abSJohan Hedberg 
1876d25e28abSJohan Hedberg 	/* Security mode 3 case */
1877d25e28abSJohan Hedberg 	if (!conn)
1878745c0ce3SVishal Agarwal 		return true;
1879d25e28abSJohan Hedberg 
1880d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1881d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1882745c0ce3SVishal Agarwal 		return true;
1883d25e28abSJohan Hedberg 
1884d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1885d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1886745c0ce3SVishal Agarwal 		return true;
1887d25e28abSJohan Hedberg 
1888d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1889d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1890745c0ce3SVishal Agarwal 		return true;
1891d25e28abSJohan Hedberg 
1892d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1893d25e28abSJohan Hedberg 	 * persistently */
1894745c0ce3SVishal Agarwal 	return false;
1895d25e28abSJohan Hedberg }
1896d25e28abSJohan Hedberg 
1897c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
189875d262c2SVinicius Costa Gomes {
1899c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
190075d262c2SVinicius Costa Gomes 
1901c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1902c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1903c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
190475d262c2SVinicius Costa Gomes 			continue;
190575d262c2SVinicius Costa Gomes 
190675d262c2SVinicius Costa Gomes 		return k;
190775d262c2SVinicius Costa Gomes 	}
190875d262c2SVinicius Costa Gomes 
190975d262c2SVinicius Costa Gomes 	return NULL;
191075d262c2SVinicius Costa Gomes }
191175d262c2SVinicius Costa Gomes 
1912c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1913c9839a11SVinicius Costa Gomes 				     u8 addr_type)
191475d262c2SVinicius Costa Gomes {
1915c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
191675d262c2SVinicius Costa Gomes 
1917c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1918c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1919c9839a11SVinicius Costa Gomes 		    bacmp(bdaddr, &k->bdaddr) == 0)
192075d262c2SVinicius Costa Gomes 			return k;
192175d262c2SVinicius Costa Gomes 
192275d262c2SVinicius Costa Gomes 	return NULL;
192375d262c2SVinicius Costa Gomes }
192475d262c2SVinicius Costa Gomes 
1925d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1926d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
192755ed8ca1SJohan Hedberg {
192855ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1929745c0ce3SVishal Agarwal 	u8 old_key_type;
1930745c0ce3SVishal Agarwal 	bool persistent;
193155ed8ca1SJohan Hedberg 
193255ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
193355ed8ca1SJohan Hedberg 	if (old_key) {
193455ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
193555ed8ca1SJohan Hedberg 		key = old_key;
193655ed8ca1SJohan Hedberg 	} else {
193712adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
193855ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
193955ed8ca1SJohan Hedberg 		if (!key)
194055ed8ca1SJohan Hedberg 			return -ENOMEM;
194155ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
194255ed8ca1SJohan Hedberg 	}
194355ed8ca1SJohan Hedberg 
19446ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
194555ed8ca1SJohan Hedberg 
1946d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1947d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1948d25e28abSJohan Hedberg 	 * previous key */
1949d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1950a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1951d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1952655fe6ecSJohan Hedberg 		if (conn)
1953655fe6ecSJohan Hedberg 			conn->key_type = type;
1954655fe6ecSJohan Hedberg 	}
1955d25e28abSJohan Hedberg 
195655ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
19579b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
195855ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
195955ed8ca1SJohan Hedberg 
1960b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
196155ed8ca1SJohan Hedberg 		key->type = old_key_type;
19624748fed2SJohan Hedberg 	else
19634748fed2SJohan Hedberg 		key->type = type;
19644748fed2SJohan Hedberg 
19654df378a1SJohan Hedberg 	if (!new_key)
19664df378a1SJohan Hedberg 		return 0;
19674df378a1SJohan Hedberg 
19684df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
19694df378a1SJohan Hedberg 
1970744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
19714df378a1SJohan Hedberg 
19726ec5bcadSVishal Agarwal 	if (conn)
19736ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
197455ed8ca1SJohan Hedberg 
197555ed8ca1SJohan Hedberg 	return 0;
197655ed8ca1SJohan Hedberg }
197755ed8ca1SJohan Hedberg 
1978c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
19799a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
198004124681SGustavo F. Padovan 		ediv, u8 rand[8])
198175d262c2SVinicius Costa Gomes {
1982c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
198375d262c2SVinicius Costa Gomes 
1984c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1985c9839a11SVinicius Costa Gomes 		return 0;
198675d262c2SVinicius Costa Gomes 
1987c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1988c9839a11SVinicius Costa Gomes 	if (old_key)
198975d262c2SVinicius Costa Gomes 		key = old_key;
1990c9839a11SVinicius Costa Gomes 	else {
1991c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
199275d262c2SVinicius Costa Gomes 		if (!key)
199375d262c2SVinicius Costa Gomes 			return -ENOMEM;
1994c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
199575d262c2SVinicius Costa Gomes 	}
199675d262c2SVinicius Costa Gomes 
199775d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1998c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1999c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
2000c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
2001c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
2002c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
2003c9839a11SVinicius Costa Gomes 	key->type = type;
2004c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
200575d262c2SVinicius Costa Gomes 
2006c9839a11SVinicius Costa Gomes 	if (!new_key)
2007c9839a11SVinicius Costa Gomes 		return 0;
200875d262c2SVinicius Costa Gomes 
2009261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
2010261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
2011261cc5aaSVinicius Costa Gomes 
201275d262c2SVinicius Costa Gomes 	return 0;
201375d262c2SVinicius Costa Gomes }
201475d262c2SVinicius Costa Gomes 
201555ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
201655ed8ca1SJohan Hedberg {
201755ed8ca1SJohan Hedberg 	struct link_key *key;
201855ed8ca1SJohan Hedberg 
201955ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
202055ed8ca1SJohan Hedberg 	if (!key)
202155ed8ca1SJohan Hedberg 		return -ENOENT;
202255ed8ca1SJohan Hedberg 
20236ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
202455ed8ca1SJohan Hedberg 
202555ed8ca1SJohan Hedberg 	list_del(&key->list);
202655ed8ca1SJohan Hedberg 	kfree(key);
202755ed8ca1SJohan Hedberg 
202855ed8ca1SJohan Hedberg 	return 0;
202955ed8ca1SJohan Hedberg }
203055ed8ca1SJohan Hedberg 
2031b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
2032b899efafSVinicius Costa Gomes {
2033b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
2034b899efafSVinicius Costa Gomes 
2035b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2036b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
2037b899efafSVinicius Costa Gomes 			continue;
2038b899efafSVinicius Costa Gomes 
20396ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2040b899efafSVinicius Costa Gomes 
2041b899efafSVinicius Costa Gomes 		list_del(&k->list);
2042b899efafSVinicius Costa Gomes 		kfree(k);
2043b899efafSVinicius Costa Gomes 	}
2044b899efafSVinicius Costa Gomes 
2045b899efafSVinicius Costa Gomes 	return 0;
2046b899efafSVinicius Costa Gomes }
2047b899efafSVinicius Costa Gomes 
20486bd32326SVille Tervo /* HCI command timer function */
2049bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
20506bd32326SVille Tervo {
20516bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
20526bd32326SVille Tervo 
2053bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2054bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2055bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2056bda4f23aSAndrei Emeltchenko 
2057bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
2058bda4f23aSAndrei Emeltchenko 	} else {
20596bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
2060bda4f23aSAndrei Emeltchenko 	}
2061bda4f23aSAndrei Emeltchenko 
20626bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2063c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
20646bd32326SVille Tervo }
20656bd32326SVille Tervo 
20662763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
20672763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
20682763eda6SSzymon Janc {
20692763eda6SSzymon Janc 	struct oob_data *data;
20702763eda6SSzymon Janc 
20712763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
20722763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
20732763eda6SSzymon Janc 			return data;
20742763eda6SSzymon Janc 
20752763eda6SSzymon Janc 	return NULL;
20762763eda6SSzymon Janc }
20772763eda6SSzymon Janc 
20782763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
20792763eda6SSzymon Janc {
20802763eda6SSzymon Janc 	struct oob_data *data;
20812763eda6SSzymon Janc 
20822763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
20832763eda6SSzymon Janc 	if (!data)
20842763eda6SSzymon Janc 		return -ENOENT;
20852763eda6SSzymon Janc 
20866ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
20872763eda6SSzymon Janc 
20882763eda6SSzymon Janc 	list_del(&data->list);
20892763eda6SSzymon Janc 	kfree(data);
20902763eda6SSzymon Janc 
20912763eda6SSzymon Janc 	return 0;
20922763eda6SSzymon Janc }
20932763eda6SSzymon Janc 
20942763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
20952763eda6SSzymon Janc {
20962763eda6SSzymon Janc 	struct oob_data *data, *n;
20972763eda6SSzymon Janc 
20982763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
20992763eda6SSzymon Janc 		list_del(&data->list);
21002763eda6SSzymon Janc 		kfree(data);
21012763eda6SSzymon Janc 	}
21022763eda6SSzymon Janc 
21032763eda6SSzymon Janc 	return 0;
21042763eda6SSzymon Janc }
21052763eda6SSzymon Janc 
21062763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
21072763eda6SSzymon Janc 			    u8 *randomizer)
21082763eda6SSzymon Janc {
21092763eda6SSzymon Janc 	struct oob_data *data;
21102763eda6SSzymon Janc 
21112763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
21122763eda6SSzymon Janc 
21132763eda6SSzymon Janc 	if (!data) {
21142763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
21152763eda6SSzymon Janc 		if (!data)
21162763eda6SSzymon Janc 			return -ENOMEM;
21172763eda6SSzymon Janc 
21182763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
21192763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
21202763eda6SSzymon Janc 	}
21212763eda6SSzymon Janc 
21222763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
21232763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
21242763eda6SSzymon Janc 
21256ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
21262763eda6SSzymon Janc 
21272763eda6SSzymon Janc 	return 0;
21282763eda6SSzymon Janc }
21292763eda6SSzymon Janc 
213004124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
2131b2a66aadSAntti Julku {
2132b2a66aadSAntti Julku 	struct bdaddr_list *b;
2133b2a66aadSAntti Julku 
21348035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
2135b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
2136b2a66aadSAntti Julku 			return b;
2137b2a66aadSAntti Julku 
2138b2a66aadSAntti Julku 	return NULL;
2139b2a66aadSAntti Julku }
2140b2a66aadSAntti Julku 
2141b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
2142b2a66aadSAntti Julku {
2143b2a66aadSAntti Julku 	struct list_head *p, *n;
2144b2a66aadSAntti Julku 
2145b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
2146b2a66aadSAntti Julku 		struct bdaddr_list *b;
2147b2a66aadSAntti Julku 
2148b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
2149b2a66aadSAntti Julku 
2150b2a66aadSAntti Julku 		list_del(p);
2151b2a66aadSAntti Julku 		kfree(b);
2152b2a66aadSAntti Julku 	}
2153b2a66aadSAntti Julku 
2154b2a66aadSAntti Julku 	return 0;
2155b2a66aadSAntti Julku }
2156b2a66aadSAntti Julku 
215788c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2158b2a66aadSAntti Julku {
2159b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2160b2a66aadSAntti Julku 
2161b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
2162b2a66aadSAntti Julku 		return -EBADF;
2163b2a66aadSAntti Julku 
21645e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
21655e762444SAntti Julku 		return -EEXIST;
2166b2a66aadSAntti Julku 
2167b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
21685e762444SAntti Julku 	if (!entry)
21695e762444SAntti Julku 		return -ENOMEM;
2170b2a66aadSAntti Julku 
2171b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2172b2a66aadSAntti Julku 
2173b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
2174b2a66aadSAntti Julku 
217588c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
2176b2a66aadSAntti Julku }
2177b2a66aadSAntti Julku 
217888c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2179b2a66aadSAntti Julku {
2180b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2181b2a66aadSAntti Julku 
21821ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
21835e762444SAntti Julku 		return hci_blacklist_clear(hdev);
2184b2a66aadSAntti Julku 
2185b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
21861ec918ceSSzymon Janc 	if (!entry)
21875e762444SAntti Julku 		return -ENOENT;
2188b2a66aadSAntti Julku 
2189b2a66aadSAntti Julku 	list_del(&entry->list);
2190b2a66aadSAntti Julku 	kfree(entry);
2191b2a66aadSAntti Julku 
219288c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
2193b2a66aadSAntti Julku }
2194b2a66aadSAntti Julku 
21954c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
21967ba8b4beSAndre Guedes {
21974c87eaabSAndre Guedes 	if (status) {
21984c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
21997ba8b4beSAndre Guedes 
22004c87eaabSAndre Guedes 		hci_dev_lock(hdev);
22014c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
22024c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
22034c87eaabSAndre Guedes 		return;
22044c87eaabSAndre Guedes 	}
22057ba8b4beSAndre Guedes }
22067ba8b4beSAndre Guedes 
22074c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
22087ba8b4beSAndre Guedes {
22094c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
22104c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
22114c87eaabSAndre Guedes 	struct hci_request req;
22124c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
22137ba8b4beSAndre Guedes 	int err;
22147ba8b4beSAndre Guedes 
22154c87eaabSAndre Guedes 	if (status) {
22164c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
22174c87eaabSAndre Guedes 		return;
22187ba8b4beSAndre Guedes 	}
22197ba8b4beSAndre Guedes 
22204c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
22214c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
22224c87eaabSAndre Guedes 		hci_dev_lock(hdev);
22234c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
22244c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
22254c87eaabSAndre Guedes 		break;
22267dbfac1dSAndre Guedes 
22274c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
22284c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
22297dbfac1dSAndre Guedes 
22307dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
22314c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
22324c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
22334c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
22344c87eaabSAndre Guedes 
22354c87eaabSAndre Guedes 		hci_dev_lock(hdev);
22364c87eaabSAndre Guedes 
22374c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
22384c87eaabSAndre Guedes 
22394c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
22404c87eaabSAndre Guedes 		if (err) {
22414c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
22424c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
22437dbfac1dSAndre Guedes 		}
22447dbfac1dSAndre Guedes 
22454c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
22464c87eaabSAndre Guedes 		break;
22474c87eaabSAndre Guedes 	}
22487dbfac1dSAndre Guedes }
22497dbfac1dSAndre Guedes 
22507ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
22517ba8b4beSAndre Guedes {
22527ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
22537ba8b4beSAndre Guedes 					    le_scan_disable.work);
22547ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
22554c87eaabSAndre Guedes 	struct hci_request req;
22564c87eaabSAndre Guedes 	int err;
22577ba8b4beSAndre Guedes 
22587ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
22597ba8b4beSAndre Guedes 
22604c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
22617ba8b4beSAndre Guedes 
22627ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
22634c87eaabSAndre Guedes 	cp.enable = LE_SCAN_DISABLE;
22644c87eaabSAndre Guedes 	hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
22657ba8b4beSAndre Guedes 
22664c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
22674c87eaabSAndre Guedes 	if (err)
22684c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
226928b75a89SAndre Guedes }
227028b75a89SAndre Guedes 
22719be0dab7SDavid Herrmann /* Alloc HCI device */
22729be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
22739be0dab7SDavid Herrmann {
22749be0dab7SDavid Herrmann 	struct hci_dev *hdev;
22759be0dab7SDavid Herrmann 
22769be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
22779be0dab7SDavid Herrmann 	if (!hdev)
22789be0dab7SDavid Herrmann 		return NULL;
22799be0dab7SDavid Herrmann 
2280b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2281b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
2282b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
2283b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
2284b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
2285bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2286bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2287b1b813d4SDavid Herrmann 
2288b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
2289b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
2290b1b813d4SDavid Herrmann 
2291bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
2292bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
2293bef64738SMarcel Holtmann 
2294b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
2295b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
2296b1b813d4SDavid Herrmann 
2297b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
2298b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
2299b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
2300b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
2301b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
2302b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
23036b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
2304b1b813d4SDavid Herrmann 
2305b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2306b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2307b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2308b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2309b1b813d4SDavid Herrmann 
2310b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2311b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
2312b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
2313b1b813d4SDavid Herrmann 
2314b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2315b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2316b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2317b1b813d4SDavid Herrmann 
2318b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2319b1b813d4SDavid Herrmann 
2320bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
2321b1b813d4SDavid Herrmann 
2322b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2323b1b813d4SDavid Herrmann 	discovery_init(hdev);
23249be0dab7SDavid Herrmann 
23259be0dab7SDavid Herrmann 	return hdev;
23269be0dab7SDavid Herrmann }
23279be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
23289be0dab7SDavid Herrmann 
23299be0dab7SDavid Herrmann /* Free HCI device */
23309be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
23319be0dab7SDavid Herrmann {
23329be0dab7SDavid Herrmann 	/* will free via device release */
23339be0dab7SDavid Herrmann 	put_device(&hdev->dev);
23349be0dab7SDavid Herrmann }
23359be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
23369be0dab7SDavid Herrmann 
23371da177e4SLinus Torvalds /* Register HCI device */
23381da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
23391da177e4SLinus Torvalds {
2340b1b813d4SDavid Herrmann 	int id, error;
23411da177e4SLinus Torvalds 
2342010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
23431da177e4SLinus Torvalds 		return -EINVAL;
23441da177e4SLinus Torvalds 
234508add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
234608add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
234708add513SMat Martineau 	 */
23483df92b31SSasha Levin 	switch (hdev->dev_type) {
23493df92b31SSasha Levin 	case HCI_BREDR:
23503df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
23511da177e4SLinus Torvalds 		break;
23523df92b31SSasha Levin 	case HCI_AMP:
23533df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
23543df92b31SSasha Levin 		break;
23553df92b31SSasha Levin 	default:
23563df92b31SSasha Levin 		return -EINVAL;
23571da177e4SLinus Torvalds 	}
23581da177e4SLinus Torvalds 
23593df92b31SSasha Levin 	if (id < 0)
23603df92b31SSasha Levin 		return id;
23613df92b31SSasha Levin 
23621da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
23631da177e4SLinus Torvalds 	hdev->id = id;
23642d8b3a11SAndrei Emeltchenko 
23652d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
23662d8b3a11SAndrei Emeltchenko 
2367d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
2368d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
236933ca954dSDavid Herrmann 	if (!hdev->workqueue) {
237033ca954dSDavid Herrmann 		error = -ENOMEM;
237133ca954dSDavid Herrmann 		goto err;
237233ca954dSDavid Herrmann 	}
2373f48fd9c8SMarcel Holtmann 
2374d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
2375d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
23766ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
23776ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
23786ead1bbcSJohan Hedberg 		error = -ENOMEM;
23796ead1bbcSJohan Hedberg 		goto err;
23806ead1bbcSJohan Hedberg 	}
23816ead1bbcSJohan Hedberg 
238233ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
238333ca954dSDavid Herrmann 	if (error < 0)
238433ca954dSDavid Herrmann 		goto err_wqueue;
23851da177e4SLinus Torvalds 
2386611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2387a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2388a8c5fb1aSGustavo Padovan 				    hdev);
2389611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2390611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
2391611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
2392611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
2393611b30f7SMarcel Holtmann 		}
2394611b30f7SMarcel Holtmann 	}
2395611b30f7SMarcel Holtmann 
23965e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
23975e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
23985e130367SJohan Hedberg 
2399a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
2400004b0258SMarcel Holtmann 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2401ce2be9acSAndrei Emeltchenko 
240201cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
240356f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
240456f87901SJohan Hedberg 		 * through reading supported features during init.
240556f87901SJohan Hedberg 		 */
240656f87901SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
240756f87901SJohan Hedberg 	}
2408ce2be9acSAndrei Emeltchenko 
2409fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
2410fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
2411fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
2412fcee3377SGustavo Padovan 
24131da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
2414dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
24151da177e4SLinus Torvalds 
241619202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2417fbe96d6fSMarcel Holtmann 
24181da177e4SLinus Torvalds 	return id;
2419f48fd9c8SMarcel Holtmann 
242033ca954dSDavid Herrmann err_wqueue:
242133ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
24226ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
242333ca954dSDavid Herrmann err:
24243df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
2425f48fd9c8SMarcel Holtmann 
242633ca954dSDavid Herrmann 	return error;
24271da177e4SLinus Torvalds }
24281da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
24291da177e4SLinus Torvalds 
24301da177e4SLinus Torvalds /* Unregister HCI device */
243159735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
24321da177e4SLinus Torvalds {
24333df92b31SSasha Levin 	int i, id;
2434ef222013SMarcel Holtmann 
2435c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
24361da177e4SLinus Torvalds 
243794324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
243894324962SJohan Hovold 
24393df92b31SSasha Levin 	id = hdev->id;
24403df92b31SSasha Levin 
2441f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
24421da177e4SLinus Torvalds 	list_del(&hdev->list);
2443f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
24441da177e4SLinus Torvalds 
24451da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
24461da177e4SLinus Torvalds 
2447cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
2448ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
2449ef222013SMarcel Holtmann 
2450b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
2451b9b5ef18SGustavo Padovan 
2452ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2453a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
245409fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2455744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
245609fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
245756e5cb86SJohan Hedberg 	}
2458ab81cbf9SJohan Hedberg 
24592e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
24602e58ef3eSJohan Hedberg 	 * pending list */
24612e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
24622e58ef3eSJohan Hedberg 
24631da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
24641da177e4SLinus Torvalds 
2465611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2466611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2467611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2468611b30f7SMarcel Holtmann 	}
2469611b30f7SMarcel Holtmann 
2470ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
2471147e2d59SDave Young 
2472f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
24736ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2474f48fd9c8SMarcel Holtmann 
247509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
2476e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
24772aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
247855ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2479b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
24802763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
248109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2482e2e0cacbSJohan Hedberg 
2483dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
24843df92b31SSasha Levin 
24853df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
24861da177e4SLinus Torvalds }
24871da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
24881da177e4SLinus Torvalds 
24891da177e4SLinus Torvalds /* Suspend HCI device */
24901da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
24911da177e4SLinus Torvalds {
24921da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
24931da177e4SLinus Torvalds 	return 0;
24941da177e4SLinus Torvalds }
24951da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
24961da177e4SLinus Torvalds 
24971da177e4SLinus Torvalds /* Resume HCI device */
24981da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
24991da177e4SLinus Torvalds {
25001da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
25011da177e4SLinus Torvalds 	return 0;
25021da177e4SLinus Torvalds }
25031da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
25041da177e4SLinus Torvalds 
250576bca880SMarcel Holtmann /* Receive frame from HCI drivers */
2506e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
250776bca880SMarcel Holtmann {
250876bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
250976bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
251076bca880SMarcel Holtmann 		kfree_skb(skb);
251176bca880SMarcel Holtmann 		return -ENXIO;
251276bca880SMarcel Holtmann 	}
251376bca880SMarcel Holtmann 
2514d82603c6SJorrit Schippers 	/* Incoming skb */
251576bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
251676bca880SMarcel Holtmann 
251776bca880SMarcel Holtmann 	/* Time stamp */
251876bca880SMarcel Holtmann 	__net_timestamp(skb);
251976bca880SMarcel Holtmann 
252076bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2521b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2522c78ae283SMarcel Holtmann 
252376bca880SMarcel Holtmann 	return 0;
252476bca880SMarcel Holtmann }
252576bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
252676bca880SMarcel Holtmann 
252733e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
25281e429f38SGustavo F. Padovan 			  int count, __u8 index)
252933e882a5SSuraj Sumangala {
253033e882a5SSuraj Sumangala 	int len = 0;
253133e882a5SSuraj Sumangala 	int hlen = 0;
253233e882a5SSuraj Sumangala 	int remain = count;
253333e882a5SSuraj Sumangala 	struct sk_buff *skb;
253433e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
253533e882a5SSuraj Sumangala 
253633e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
253733e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
253833e882a5SSuraj Sumangala 		return -EILSEQ;
253933e882a5SSuraj Sumangala 
254033e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
254133e882a5SSuraj Sumangala 
254233e882a5SSuraj Sumangala 	if (!skb) {
254333e882a5SSuraj Sumangala 		switch (type) {
254433e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
254533e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
254633e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
254733e882a5SSuraj Sumangala 			break;
254833e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
254933e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
255033e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
255133e882a5SSuraj Sumangala 			break;
255233e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
255333e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
255433e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
255533e882a5SSuraj Sumangala 			break;
255633e882a5SSuraj Sumangala 		}
255733e882a5SSuraj Sumangala 
25581e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
255933e882a5SSuraj Sumangala 		if (!skb)
256033e882a5SSuraj Sumangala 			return -ENOMEM;
256133e882a5SSuraj Sumangala 
256233e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
256333e882a5SSuraj Sumangala 		scb->expect = hlen;
256433e882a5SSuraj Sumangala 		scb->pkt_type = type;
256533e882a5SSuraj Sumangala 
256633e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
256733e882a5SSuraj Sumangala 	}
256833e882a5SSuraj Sumangala 
256933e882a5SSuraj Sumangala 	while (count) {
257033e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
257189bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
257233e882a5SSuraj Sumangala 
257333e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
257433e882a5SSuraj Sumangala 
257533e882a5SSuraj Sumangala 		count -= len;
257633e882a5SSuraj Sumangala 		data += len;
257733e882a5SSuraj Sumangala 		scb->expect -= len;
257833e882a5SSuraj Sumangala 		remain = count;
257933e882a5SSuraj Sumangala 
258033e882a5SSuraj Sumangala 		switch (type) {
258133e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
258233e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
258333e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
258433e882a5SSuraj Sumangala 				scb->expect = h->plen;
258533e882a5SSuraj Sumangala 
258633e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
258733e882a5SSuraj Sumangala 					kfree_skb(skb);
258833e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
258933e882a5SSuraj Sumangala 					return -ENOMEM;
259033e882a5SSuraj Sumangala 				}
259133e882a5SSuraj Sumangala 			}
259233e882a5SSuraj Sumangala 			break;
259333e882a5SSuraj Sumangala 
259433e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
259533e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
259633e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
259733e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
259833e882a5SSuraj Sumangala 
259933e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
260033e882a5SSuraj Sumangala 					kfree_skb(skb);
260133e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
260233e882a5SSuraj Sumangala 					return -ENOMEM;
260333e882a5SSuraj Sumangala 				}
260433e882a5SSuraj Sumangala 			}
260533e882a5SSuraj Sumangala 			break;
260633e882a5SSuraj Sumangala 
260733e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
260833e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
260933e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
261033e882a5SSuraj Sumangala 				scb->expect = h->dlen;
261133e882a5SSuraj Sumangala 
261233e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
261333e882a5SSuraj Sumangala 					kfree_skb(skb);
261433e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
261533e882a5SSuraj Sumangala 					return -ENOMEM;
261633e882a5SSuraj Sumangala 				}
261733e882a5SSuraj Sumangala 			}
261833e882a5SSuraj Sumangala 			break;
261933e882a5SSuraj Sumangala 		}
262033e882a5SSuraj Sumangala 
262133e882a5SSuraj Sumangala 		if (scb->expect == 0) {
262233e882a5SSuraj Sumangala 			/* Complete frame */
262333e882a5SSuraj Sumangala 
262433e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
2625e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
262633e882a5SSuraj Sumangala 
262733e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
262833e882a5SSuraj Sumangala 			return remain;
262933e882a5SSuraj Sumangala 		}
263033e882a5SSuraj Sumangala 	}
263133e882a5SSuraj Sumangala 
263233e882a5SSuraj Sumangala 	return remain;
263333e882a5SSuraj Sumangala }
263433e882a5SSuraj Sumangala 
2635ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
2636ef222013SMarcel Holtmann {
2637f39a3c06SSuraj Sumangala 	int rem = 0;
2638f39a3c06SSuraj Sumangala 
2639ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
2640ef222013SMarcel Holtmann 		return -EILSEQ;
2641ef222013SMarcel Holtmann 
2642da5f6c37SGustavo F. Padovan 	while (count) {
26431e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
2644f39a3c06SSuraj Sumangala 		if (rem < 0)
2645f39a3c06SSuraj Sumangala 			return rem;
2646ef222013SMarcel Holtmann 
2647f39a3c06SSuraj Sumangala 		data += (count - rem);
2648f39a3c06SSuraj Sumangala 		count = rem;
2649f81c6224SJoe Perches 	}
2650ef222013SMarcel Holtmann 
2651f39a3c06SSuraj Sumangala 	return rem;
2652ef222013SMarcel Holtmann }
2653ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
2654ef222013SMarcel Holtmann 
265599811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
265699811510SSuraj Sumangala 
265799811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
265899811510SSuraj Sumangala {
265999811510SSuraj Sumangala 	int type;
266099811510SSuraj Sumangala 	int rem = 0;
266199811510SSuraj Sumangala 
2662da5f6c37SGustavo F. Padovan 	while (count) {
266399811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
266499811510SSuraj Sumangala 
266599811510SSuraj Sumangala 		if (!skb) {
266699811510SSuraj Sumangala 			struct { char type; } *pkt;
266799811510SSuraj Sumangala 
266899811510SSuraj Sumangala 			/* Start of the frame */
266999811510SSuraj Sumangala 			pkt = data;
267099811510SSuraj Sumangala 			type = pkt->type;
267199811510SSuraj Sumangala 
267299811510SSuraj Sumangala 			data++;
267399811510SSuraj Sumangala 			count--;
267499811510SSuraj Sumangala 		} else
267599811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
267699811510SSuraj Sumangala 
26771e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
26781e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
267999811510SSuraj Sumangala 		if (rem < 0)
268099811510SSuraj Sumangala 			return rem;
268199811510SSuraj Sumangala 
268299811510SSuraj Sumangala 		data += (count - rem);
268399811510SSuraj Sumangala 		count = rem;
2684f81c6224SJoe Perches 	}
268599811510SSuraj Sumangala 
268699811510SSuraj Sumangala 	return rem;
268799811510SSuraj Sumangala }
268899811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
268999811510SSuraj Sumangala 
26901da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
26911da177e4SLinus Torvalds 
26921da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
26931da177e4SLinus Torvalds {
26941da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
26951da177e4SLinus Torvalds 
2696f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
26971da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2698f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
26991da177e4SLinus Torvalds 
27001da177e4SLinus Torvalds 	return 0;
27011da177e4SLinus Torvalds }
27021da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
27031da177e4SLinus Torvalds 
27041da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
27051da177e4SLinus Torvalds {
27061da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
27071da177e4SLinus Torvalds 
2708f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
27091da177e4SLinus Torvalds 	list_del(&cb->list);
2710f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
27111da177e4SLinus Torvalds 
27121da177e4SLinus Torvalds 	return 0;
27131da177e4SLinus Torvalds }
27141da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
27151da177e4SLinus Torvalds 
271651086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
27171da177e4SLinus Torvalds {
27180d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
27191da177e4SLinus Torvalds 
27201da177e4SLinus Torvalds 	/* Time stamp */
2721a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
27221da177e4SLinus Torvalds 
2723cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2724cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2725cd82e61cSMarcel Holtmann 
2726cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2727cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2728470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
27291da177e4SLinus Torvalds 	}
27301da177e4SLinus Torvalds 
27311da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
27321da177e4SLinus Torvalds 	skb_orphan(skb);
27331da177e4SLinus Torvalds 
27347bd8f09fSMarcel Holtmann 	if (hdev->send(hdev, skb) < 0)
273551086991SMarcel Holtmann 		BT_ERR("%s sending frame failed", hdev->name);
27361da177e4SLinus Torvalds }
27371da177e4SLinus Torvalds 
27383119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
27393119ae95SJohan Hedberg {
27403119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
27413119ae95SJohan Hedberg 	req->hdev = hdev;
27425d73e034SAndre Guedes 	req->err = 0;
27433119ae95SJohan Hedberg }
27443119ae95SJohan Hedberg 
27453119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
27463119ae95SJohan Hedberg {
27473119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
27483119ae95SJohan Hedberg 	struct sk_buff *skb;
27493119ae95SJohan Hedberg 	unsigned long flags;
27503119ae95SJohan Hedberg 
27513119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
27523119ae95SJohan Hedberg 
27535d73e034SAndre Guedes 	/* If an error occured during request building, remove all HCI
27545d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
27555d73e034SAndre Guedes 	 */
27565d73e034SAndre Guedes 	if (req->err) {
27575d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
27585d73e034SAndre Guedes 		return req->err;
27595d73e034SAndre Guedes 	}
27605d73e034SAndre Guedes 
27613119ae95SJohan Hedberg 	/* Do not allow empty requests */
27623119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
2763382b0c39SAndre Guedes 		return -ENODATA;
27643119ae95SJohan Hedberg 
27653119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
27663119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
27673119ae95SJohan Hedberg 
27683119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
27693119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
27703119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
27713119ae95SJohan Hedberg 
27723119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
27733119ae95SJohan Hedberg 
27743119ae95SJohan Hedberg 	return 0;
27753119ae95SJohan Hedberg }
27763119ae95SJohan Hedberg 
27771ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
277807dc93ddSJohan Hedberg 				       u32 plen, const void *param)
27791da177e4SLinus Torvalds {
27801da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
27811da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
27821da177e4SLinus Torvalds 	struct sk_buff *skb;
27831da177e4SLinus Torvalds 
27841da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
27851ca3a9d0SJohan Hedberg 	if (!skb)
27861ca3a9d0SJohan Hedberg 		return NULL;
27871da177e4SLinus Torvalds 
27881da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2789a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
27901da177e4SLinus Torvalds 	hdr->plen   = plen;
27911da177e4SLinus Torvalds 
27921da177e4SLinus Torvalds 	if (plen)
27931da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
27941da177e4SLinus Torvalds 
27951da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
27961da177e4SLinus Torvalds 
27970d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
2798c78ae283SMarcel Holtmann 
27991ca3a9d0SJohan Hedberg 	return skb;
28001ca3a9d0SJohan Hedberg }
28011ca3a9d0SJohan Hedberg 
28021ca3a9d0SJohan Hedberg /* Send HCI command */
280307dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
280407dc93ddSJohan Hedberg 		 const void *param)
28051ca3a9d0SJohan Hedberg {
28061ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
28071ca3a9d0SJohan Hedberg 
28081ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
28091ca3a9d0SJohan Hedberg 
28101ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
28111ca3a9d0SJohan Hedberg 	if (!skb) {
28121ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
28131ca3a9d0SJohan Hedberg 		return -ENOMEM;
28141ca3a9d0SJohan Hedberg 	}
28151ca3a9d0SJohan Hedberg 
281611714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
281711714b3dSJohan Hedberg 	 * single-command requests.
281811714b3dSJohan Hedberg 	 */
281911714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
282011714b3dSJohan Hedberg 
28211da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2822c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
28231da177e4SLinus Torvalds 
28241da177e4SLinus Torvalds 	return 0;
28251da177e4SLinus Torvalds }
28261da177e4SLinus Torvalds 
282771c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
282807dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
282907dc93ddSJohan Hedberg 		    const void *param, u8 event)
283071c76a17SJohan Hedberg {
283171c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
283271c76a17SJohan Hedberg 	struct sk_buff *skb;
283371c76a17SJohan Hedberg 
283471c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
283571c76a17SJohan Hedberg 
283634739c1eSAndre Guedes 	/* If an error occured during request building, there is no point in
283734739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
283834739c1eSAndre Guedes 	 */
283934739c1eSAndre Guedes 	if (req->err)
284034739c1eSAndre Guedes 		return;
284134739c1eSAndre Guedes 
284271c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
284371c76a17SJohan Hedberg 	if (!skb) {
28445d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
28455d73e034SAndre Guedes 		       hdev->name, opcode);
28465d73e034SAndre Guedes 		req->err = -ENOMEM;
2847e348fe6bSAndre Guedes 		return;
284871c76a17SJohan Hedberg 	}
284971c76a17SJohan Hedberg 
285071c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
285171c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
285271c76a17SJohan Hedberg 
285302350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
285402350a72SJohan Hedberg 
285571c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
285671c76a17SJohan Hedberg }
285771c76a17SJohan Hedberg 
285807dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
285907dc93ddSJohan Hedberg 		 const void *param)
286002350a72SJohan Hedberg {
286102350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
286202350a72SJohan Hedberg }
286302350a72SJohan Hedberg 
28641da177e4SLinus Torvalds /* Get data from the previously sent command */
2865a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
28661da177e4SLinus Torvalds {
28671da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
28681da177e4SLinus Torvalds 
28691da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
28701da177e4SLinus Torvalds 		return NULL;
28711da177e4SLinus Torvalds 
28721da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
28731da177e4SLinus Torvalds 
2874a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
28751da177e4SLinus Torvalds 		return NULL;
28761da177e4SLinus Torvalds 
2877f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
28781da177e4SLinus Torvalds 
28791da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
28801da177e4SLinus Torvalds }
28811da177e4SLinus Torvalds 
28821da177e4SLinus Torvalds /* Send ACL data */
28831da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
28841da177e4SLinus Torvalds {
28851da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
28861da177e4SLinus Torvalds 	int len = skb->len;
28871da177e4SLinus Torvalds 
2888badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2889badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
28909c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2891aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2892aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
28931da177e4SLinus Torvalds }
28941da177e4SLinus Torvalds 
2895ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
289673d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
28971da177e4SLinus Torvalds {
2898ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
28991da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
29001da177e4SLinus Torvalds 	struct sk_buff *list;
29011da177e4SLinus Torvalds 
2902087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
2903087bfd99SGustavo Padovan 	skb->data_len = 0;
2904087bfd99SGustavo Padovan 
2905087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2906204a6e54SAndrei Emeltchenko 
2907204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
2908204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
2909087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
2910204a6e54SAndrei Emeltchenko 		break;
2911204a6e54SAndrei Emeltchenko 	case HCI_AMP:
2912204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
2913204a6e54SAndrei Emeltchenko 		break;
2914204a6e54SAndrei Emeltchenko 	default:
2915204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2916204a6e54SAndrei Emeltchenko 		return;
2917204a6e54SAndrei Emeltchenko 	}
2918087bfd99SGustavo Padovan 
291970f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
292070f23020SAndrei Emeltchenko 	if (!list) {
29211da177e4SLinus Torvalds 		/* Non fragmented */
29221da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
29231da177e4SLinus Torvalds 
292473d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
29251da177e4SLinus Torvalds 	} else {
29261da177e4SLinus Torvalds 		/* Fragmented */
29271da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
29281da177e4SLinus Torvalds 
29291da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
29301da177e4SLinus Torvalds 
29311da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2932af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
29331da177e4SLinus Torvalds 
293473d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2935e702112fSAndrei Emeltchenko 
2936e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2937e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
29381da177e4SLinus Torvalds 		do {
29391da177e4SLinus Torvalds 			skb = list; list = list->next;
29401da177e4SLinus Torvalds 
29410d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2942e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
29431da177e4SLinus Torvalds 
29441da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
29451da177e4SLinus Torvalds 
294673d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
29471da177e4SLinus Torvalds 		} while (list);
29481da177e4SLinus Torvalds 
2949af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
29501da177e4SLinus Torvalds 	}
295173d80debSLuiz Augusto von Dentz }
295273d80debSLuiz Augusto von Dentz 
295373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
295473d80debSLuiz Augusto von Dentz {
2955ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
295673d80debSLuiz Augusto von Dentz 
2957f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
295873d80debSLuiz Augusto von Dentz 
2959ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
29601da177e4SLinus Torvalds 
29613eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
29621da177e4SLinus Torvalds }
29631da177e4SLinus Torvalds 
29641da177e4SLinus Torvalds /* Send SCO data */
29650d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
29661da177e4SLinus Torvalds {
29671da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
29681da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
29691da177e4SLinus Torvalds 
29701da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
29711da177e4SLinus Torvalds 
2972aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
29731da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
29741da177e4SLinus Torvalds 
2975badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2976badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
29779c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
29781da177e4SLinus Torvalds 
29790d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2980c78ae283SMarcel Holtmann 
29811da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
29823eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
29831da177e4SLinus Torvalds }
29841da177e4SLinus Torvalds 
29851da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
29861da177e4SLinus Torvalds 
29871da177e4SLinus Torvalds /* HCI Connection scheduler */
29886039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
2989a8c5fb1aSGustavo Padovan 				     int *quote)
29901da177e4SLinus Torvalds {
29911da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
29928035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
2993abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
29941da177e4SLinus Torvalds 
29951da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
29961da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2997bf4c6325SGustavo F. Padovan 
2998bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2999bf4c6325SGustavo F. Padovan 
3000bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3001769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
30021da177e4SLinus Torvalds 			continue;
3003769be974SMarcel Holtmann 
3004769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3005769be974SMarcel Holtmann 			continue;
3006769be974SMarcel Holtmann 
30071da177e4SLinus Torvalds 		num++;
30081da177e4SLinus Torvalds 
30091da177e4SLinus Torvalds 		if (c->sent < min) {
30101da177e4SLinus Torvalds 			min  = c->sent;
30111da177e4SLinus Torvalds 			conn = c;
30121da177e4SLinus Torvalds 		}
301352087a79SLuiz Augusto von Dentz 
301452087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
301552087a79SLuiz Augusto von Dentz 			break;
30161da177e4SLinus Torvalds 	}
30171da177e4SLinus Torvalds 
3018bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3019bf4c6325SGustavo F. Padovan 
30201da177e4SLinus Torvalds 	if (conn) {
30216ed58ec5SVille Tervo 		int cnt, q;
30226ed58ec5SVille Tervo 
30236ed58ec5SVille Tervo 		switch (conn->type) {
30246ed58ec5SVille Tervo 		case ACL_LINK:
30256ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
30266ed58ec5SVille Tervo 			break;
30276ed58ec5SVille Tervo 		case SCO_LINK:
30286ed58ec5SVille Tervo 		case ESCO_LINK:
30296ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
30306ed58ec5SVille Tervo 			break;
30316ed58ec5SVille Tervo 		case LE_LINK:
30326ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
30336ed58ec5SVille Tervo 			break;
30346ed58ec5SVille Tervo 		default:
30356ed58ec5SVille Tervo 			cnt = 0;
30366ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
30376ed58ec5SVille Tervo 		}
30386ed58ec5SVille Tervo 
30396ed58ec5SVille Tervo 		q = cnt / num;
30401da177e4SLinus Torvalds 		*quote = q ? q : 1;
30411da177e4SLinus Torvalds 	} else
30421da177e4SLinus Torvalds 		*quote = 0;
30431da177e4SLinus Torvalds 
30441da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
30451da177e4SLinus Torvalds 	return conn;
30461da177e4SLinus Torvalds }
30471da177e4SLinus Torvalds 
30486039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
30491da177e4SLinus Torvalds {
30501da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
30511da177e4SLinus Torvalds 	struct hci_conn *c;
30521da177e4SLinus Torvalds 
3053bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
30541da177e4SLinus Torvalds 
3055bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3056bf4c6325SGustavo F. Padovan 
30571da177e4SLinus Torvalds 	/* Kill stalled connections */
3058bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3059bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
30606ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
30616ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
3062bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
30631da177e4SLinus Torvalds 		}
30641da177e4SLinus Torvalds 	}
3065bf4c6325SGustavo F. Padovan 
3066bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
30671da177e4SLinus Torvalds }
30681da177e4SLinus Torvalds 
30696039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
307073d80debSLuiz Augusto von Dentz 				      int *quote)
307173d80debSLuiz Augusto von Dentz {
307273d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
307373d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3074abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
307573d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
307673d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
307773d80debSLuiz Augusto von Dentz 
307873d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
307973d80debSLuiz Augusto von Dentz 
3080bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3081bf4c6325SGustavo F. Padovan 
3082bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
308373d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
308473d80debSLuiz Augusto von Dentz 
308573d80debSLuiz Augusto von Dentz 		if (conn->type != type)
308673d80debSLuiz Augusto von Dentz 			continue;
308773d80debSLuiz Augusto von Dentz 
308873d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
308973d80debSLuiz Augusto von Dentz 			continue;
309073d80debSLuiz Augusto von Dentz 
309173d80debSLuiz Augusto von Dentz 		conn_num++;
309273d80debSLuiz Augusto von Dentz 
30938192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
309473d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
309573d80debSLuiz Augusto von Dentz 
309673d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
309773d80debSLuiz Augusto von Dentz 				continue;
309873d80debSLuiz Augusto von Dentz 
309973d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
310073d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
310173d80debSLuiz Augusto von Dentz 				continue;
310273d80debSLuiz Augusto von Dentz 
310373d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
310473d80debSLuiz Augusto von Dentz 				num = 0;
310573d80debSLuiz Augusto von Dentz 				min = ~0;
310673d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
310773d80debSLuiz Augusto von Dentz 			}
310873d80debSLuiz Augusto von Dentz 
310973d80debSLuiz Augusto von Dentz 			num++;
311073d80debSLuiz Augusto von Dentz 
311173d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
311273d80debSLuiz Augusto von Dentz 				min  = conn->sent;
311373d80debSLuiz Augusto von Dentz 				chan = tmp;
311473d80debSLuiz Augusto von Dentz 			}
311573d80debSLuiz Augusto von Dentz 		}
311673d80debSLuiz Augusto von Dentz 
311773d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
311873d80debSLuiz Augusto von Dentz 			break;
311973d80debSLuiz Augusto von Dentz 	}
312073d80debSLuiz Augusto von Dentz 
3121bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3122bf4c6325SGustavo F. Padovan 
312373d80debSLuiz Augusto von Dentz 	if (!chan)
312473d80debSLuiz Augusto von Dentz 		return NULL;
312573d80debSLuiz Augusto von Dentz 
312673d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
312773d80debSLuiz Augusto von Dentz 	case ACL_LINK:
312873d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
312973d80debSLuiz Augusto von Dentz 		break;
3130bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
3131bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
3132bd1eb66bSAndrei Emeltchenko 		break;
313373d80debSLuiz Augusto von Dentz 	case SCO_LINK:
313473d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
313573d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
313673d80debSLuiz Augusto von Dentz 		break;
313773d80debSLuiz Augusto von Dentz 	case LE_LINK:
313873d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
313973d80debSLuiz Augusto von Dentz 		break;
314073d80debSLuiz Augusto von Dentz 	default:
314173d80debSLuiz Augusto von Dentz 		cnt = 0;
314273d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
314373d80debSLuiz Augusto von Dentz 	}
314473d80debSLuiz Augusto von Dentz 
314573d80debSLuiz Augusto von Dentz 	q = cnt / num;
314673d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
314773d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
314873d80debSLuiz Augusto von Dentz 	return chan;
314973d80debSLuiz Augusto von Dentz }
315073d80debSLuiz Augusto von Dentz 
315102b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
315202b20f0bSLuiz Augusto von Dentz {
315302b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
315402b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
315502b20f0bSLuiz Augusto von Dentz 	int num = 0;
315602b20f0bSLuiz Augusto von Dentz 
315702b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
315802b20f0bSLuiz Augusto von Dentz 
3159bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3160bf4c6325SGustavo F. Padovan 
3161bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
316202b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
316302b20f0bSLuiz Augusto von Dentz 
316402b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
316502b20f0bSLuiz Augusto von Dentz 			continue;
316602b20f0bSLuiz Augusto von Dentz 
316702b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
316802b20f0bSLuiz Augusto von Dentz 			continue;
316902b20f0bSLuiz Augusto von Dentz 
317002b20f0bSLuiz Augusto von Dentz 		num++;
317102b20f0bSLuiz Augusto von Dentz 
31728192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
317302b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
317402b20f0bSLuiz Augusto von Dentz 
317502b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
317602b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
317702b20f0bSLuiz Augusto von Dentz 				continue;
317802b20f0bSLuiz Augusto von Dentz 			}
317902b20f0bSLuiz Augusto von Dentz 
318002b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
318102b20f0bSLuiz Augusto von Dentz 				continue;
318202b20f0bSLuiz Augusto von Dentz 
318302b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
318402b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
318502b20f0bSLuiz Augusto von Dentz 				continue;
318602b20f0bSLuiz Augusto von Dentz 
318702b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
318802b20f0bSLuiz Augusto von Dentz 
318902b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
319002b20f0bSLuiz Augusto von Dentz 			       skb->priority);
319102b20f0bSLuiz Augusto von Dentz 		}
319202b20f0bSLuiz Augusto von Dentz 
319302b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
319402b20f0bSLuiz Augusto von Dentz 			break;
319502b20f0bSLuiz Augusto von Dentz 	}
3196bf4c6325SGustavo F. Padovan 
3197bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3198bf4c6325SGustavo F. Padovan 
319902b20f0bSLuiz Augusto von Dentz }
320002b20f0bSLuiz Augusto von Dentz 
3201b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3202b71d385aSAndrei Emeltchenko {
3203b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3204b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3205b71d385aSAndrei Emeltchenko }
3206b71d385aSAndrei Emeltchenko 
32076039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
32081da177e4SLinus Torvalds {
32091da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
32101da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
32111da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
321263d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
32135f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
3214bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
32151da177e4SLinus Torvalds 	}
321663d2bc1bSAndrei Emeltchenko }
32171da177e4SLinus Torvalds 
32186039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
321963d2bc1bSAndrei Emeltchenko {
322063d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
322163d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
322263d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
322363d2bc1bSAndrei Emeltchenko 	int quote;
322463d2bc1bSAndrei Emeltchenko 
322563d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
322604837f64SMarcel Holtmann 
322773d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
322873d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3229ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3230ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
323173d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
323273d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
323373d80debSLuiz Augusto von Dentz 
3234ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3235ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3236ec1cce24SLuiz Augusto von Dentz 				break;
3237ec1cce24SLuiz Augusto von Dentz 
3238ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3239ec1cce24SLuiz Augusto von Dentz 
324073d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
324173d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
324204837f64SMarcel Holtmann 
324357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
32441da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
32451da177e4SLinus Torvalds 
32461da177e4SLinus Torvalds 			hdev->acl_cnt--;
324773d80debSLuiz Augusto von Dentz 			chan->sent++;
324873d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
32491da177e4SLinus Torvalds 		}
32501da177e4SLinus Torvalds 	}
325102b20f0bSLuiz Augusto von Dentz 
325202b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
325302b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
32541da177e4SLinus Torvalds }
32551da177e4SLinus Torvalds 
32566039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3257b71d385aSAndrei Emeltchenko {
325863d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3259b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3260b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3261b71d385aSAndrei Emeltchenko 	int quote;
3262bd1eb66bSAndrei Emeltchenko 	u8 type;
3263b71d385aSAndrei Emeltchenko 
326463d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
3265b71d385aSAndrei Emeltchenko 
3266bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3267bd1eb66bSAndrei Emeltchenko 
3268bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3269bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3270bd1eb66bSAndrei Emeltchenko 	else
3271bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3272bd1eb66bSAndrei Emeltchenko 
3273b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3274bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3275b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3276b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3277b71d385aSAndrei Emeltchenko 			int blocks;
3278b71d385aSAndrei Emeltchenko 
3279b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3280b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3281b71d385aSAndrei Emeltchenko 
3282b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3283b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3284b71d385aSAndrei Emeltchenko 				break;
3285b71d385aSAndrei Emeltchenko 
3286b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3287b71d385aSAndrei Emeltchenko 
3288b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3289b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3290b71d385aSAndrei Emeltchenko 				return;
3291b71d385aSAndrei Emeltchenko 
3292b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3293b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3294b71d385aSAndrei Emeltchenko 
329557d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3296b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3297b71d385aSAndrei Emeltchenko 
3298b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3299b71d385aSAndrei Emeltchenko 			quote -= blocks;
3300b71d385aSAndrei Emeltchenko 
3301b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3302b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3303b71d385aSAndrei Emeltchenko 		}
3304b71d385aSAndrei Emeltchenko 	}
3305b71d385aSAndrei Emeltchenko 
3306b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3307bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3308b71d385aSAndrei Emeltchenko }
3309b71d385aSAndrei Emeltchenko 
33106039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3311b71d385aSAndrei Emeltchenko {
3312b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3313b71d385aSAndrei Emeltchenko 
3314bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3315bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
3316bd1eb66bSAndrei Emeltchenko 		return;
3317bd1eb66bSAndrei Emeltchenko 
3318bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3319bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3320b71d385aSAndrei Emeltchenko 		return;
3321b71d385aSAndrei Emeltchenko 
3322b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3323b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3324b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3325b71d385aSAndrei Emeltchenko 		break;
3326b71d385aSAndrei Emeltchenko 
3327b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3328b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3329b71d385aSAndrei Emeltchenko 		break;
3330b71d385aSAndrei Emeltchenko 	}
3331b71d385aSAndrei Emeltchenko }
3332b71d385aSAndrei Emeltchenko 
33331da177e4SLinus Torvalds /* Schedule SCO */
33346039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
33351da177e4SLinus Torvalds {
33361da177e4SLinus Torvalds 	struct hci_conn *conn;
33371da177e4SLinus Torvalds 	struct sk_buff *skb;
33381da177e4SLinus Torvalds 	int quote;
33391da177e4SLinus Torvalds 
33401da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
33411da177e4SLinus Torvalds 
334252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
334352087a79SLuiz Augusto von Dentz 		return;
334452087a79SLuiz Augusto von Dentz 
33451da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
33461da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
33471da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
334857d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
33491da177e4SLinus Torvalds 
33501da177e4SLinus Torvalds 			conn->sent++;
33511da177e4SLinus Torvalds 			if (conn->sent == ~0)
33521da177e4SLinus Torvalds 				conn->sent = 0;
33531da177e4SLinus Torvalds 		}
33541da177e4SLinus Torvalds 	}
33551da177e4SLinus Torvalds }
33561da177e4SLinus Torvalds 
33576039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
3358b6a0dc82SMarcel Holtmann {
3359b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
3360b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
3361b6a0dc82SMarcel Holtmann 	int quote;
3362b6a0dc82SMarcel Holtmann 
3363b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
3364b6a0dc82SMarcel Holtmann 
336552087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
336652087a79SLuiz Augusto von Dentz 		return;
336752087a79SLuiz Augusto von Dentz 
33688fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
33698fc9ced3SGustavo Padovan 						     &quote))) {
3370b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
3371b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
337257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3373b6a0dc82SMarcel Holtmann 
3374b6a0dc82SMarcel Holtmann 			conn->sent++;
3375b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
3376b6a0dc82SMarcel Holtmann 				conn->sent = 0;
3377b6a0dc82SMarcel Holtmann 		}
3378b6a0dc82SMarcel Holtmann 	}
3379b6a0dc82SMarcel Holtmann }
3380b6a0dc82SMarcel Holtmann 
33816039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
33826ed58ec5SVille Tervo {
338373d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
33846ed58ec5SVille Tervo 	struct sk_buff *skb;
338502b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
33866ed58ec5SVille Tervo 
33876ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
33886ed58ec5SVille Tervo 
338952087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
339052087a79SLuiz Augusto von Dentz 		return;
339152087a79SLuiz Augusto von Dentz 
33926ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
33936ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
33946ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
3395bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
33966ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
3397bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
33986ed58ec5SVille Tervo 	}
33996ed58ec5SVille Tervo 
34006ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
340102b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
340273d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3403ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3404ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
340573d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
340673d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
34076ed58ec5SVille Tervo 
3408ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3409ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3410ec1cce24SLuiz Augusto von Dentz 				break;
3411ec1cce24SLuiz Augusto von Dentz 
3412ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3413ec1cce24SLuiz Augusto von Dentz 
341457d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
34156ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
34166ed58ec5SVille Tervo 
34176ed58ec5SVille Tervo 			cnt--;
341873d80debSLuiz Augusto von Dentz 			chan->sent++;
341973d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
34206ed58ec5SVille Tervo 		}
34216ed58ec5SVille Tervo 	}
342273d80debSLuiz Augusto von Dentz 
34236ed58ec5SVille Tervo 	if (hdev->le_pkts)
34246ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
34256ed58ec5SVille Tervo 	else
34266ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
342702b20f0bSLuiz Augusto von Dentz 
342802b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
342902b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
34306ed58ec5SVille Tervo }
34316ed58ec5SVille Tervo 
34323eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
34331da177e4SLinus Torvalds {
34343eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
34351da177e4SLinus Torvalds 	struct sk_buff *skb;
34361da177e4SLinus Torvalds 
34376ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
34386ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
34391da177e4SLinus Torvalds 
344052de599eSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
34411da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
34421da177e4SLinus Torvalds 		hci_sched_acl(hdev);
34431da177e4SLinus Torvalds 		hci_sched_sco(hdev);
3444b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
34456ed58ec5SVille Tervo 		hci_sched_le(hdev);
344652de599eSMarcel Holtmann 	}
34476ed58ec5SVille Tervo 
34481da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
34491da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
345057d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
34511da177e4SLinus Torvalds }
34521da177e4SLinus Torvalds 
345325985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
34541da177e4SLinus Torvalds 
34551da177e4SLinus Torvalds /* ACL data packet */
34566039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
34571da177e4SLinus Torvalds {
34581da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
34591da177e4SLinus Torvalds 	struct hci_conn *conn;
34601da177e4SLinus Torvalds 	__u16 handle, flags;
34611da177e4SLinus Torvalds 
34621da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
34631da177e4SLinus Torvalds 
34641da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
34651da177e4SLinus Torvalds 	flags  = hci_flags(handle);
34661da177e4SLinus Torvalds 	handle = hci_handle(handle);
34671da177e4SLinus Torvalds 
3468f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3469a8c5fb1aSGustavo Padovan 	       handle, flags);
34701da177e4SLinus Torvalds 
34711da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
34721da177e4SLinus Torvalds 
34731da177e4SLinus Torvalds 	hci_dev_lock(hdev);
34741da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
34751da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
34761da177e4SLinus Torvalds 
34771da177e4SLinus Torvalds 	if (conn) {
347865983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
347904837f64SMarcel Holtmann 
34801da177e4SLinus Torvalds 		/* Send to upper protocol */
3481686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
34821da177e4SLinus Torvalds 		return;
34831da177e4SLinus Torvalds 	} else {
34841da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
34851da177e4SLinus Torvalds 		       hdev->name, handle);
34861da177e4SLinus Torvalds 	}
34871da177e4SLinus Torvalds 
34881da177e4SLinus Torvalds 	kfree_skb(skb);
34891da177e4SLinus Torvalds }
34901da177e4SLinus Torvalds 
34911da177e4SLinus Torvalds /* SCO data packet */
34926039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
34931da177e4SLinus Torvalds {
34941da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
34951da177e4SLinus Torvalds 	struct hci_conn *conn;
34961da177e4SLinus Torvalds 	__u16 handle;
34971da177e4SLinus Torvalds 
34981da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
34991da177e4SLinus Torvalds 
35001da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
35011da177e4SLinus Torvalds 
3502f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
35031da177e4SLinus Torvalds 
35041da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
35051da177e4SLinus Torvalds 
35061da177e4SLinus Torvalds 	hci_dev_lock(hdev);
35071da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
35081da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
35091da177e4SLinus Torvalds 
35101da177e4SLinus Torvalds 	if (conn) {
35111da177e4SLinus Torvalds 		/* Send to upper protocol */
3512686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
35131da177e4SLinus Torvalds 		return;
35141da177e4SLinus Torvalds 	} else {
35151da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
35161da177e4SLinus Torvalds 		       hdev->name, handle);
35171da177e4SLinus Torvalds 	}
35181da177e4SLinus Torvalds 
35191da177e4SLinus Torvalds 	kfree_skb(skb);
35201da177e4SLinus Torvalds }
35211da177e4SLinus Torvalds 
35229238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
35239238f36aSJohan Hedberg {
35249238f36aSJohan Hedberg 	struct sk_buff *skb;
35259238f36aSJohan Hedberg 
35269238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
35279238f36aSJohan Hedberg 	if (!skb)
35289238f36aSJohan Hedberg 		return true;
35299238f36aSJohan Hedberg 
35309238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
35319238f36aSJohan Hedberg }
35329238f36aSJohan Hedberg 
353342c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
353442c6b129SJohan Hedberg {
353542c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
353642c6b129SJohan Hedberg 	struct sk_buff *skb;
353742c6b129SJohan Hedberg 	u16 opcode;
353842c6b129SJohan Hedberg 
353942c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
354042c6b129SJohan Hedberg 		return;
354142c6b129SJohan Hedberg 
354242c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
354342c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
354442c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
354542c6b129SJohan Hedberg 		return;
354642c6b129SJohan Hedberg 
354742c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
354842c6b129SJohan Hedberg 	if (!skb)
354942c6b129SJohan Hedberg 		return;
355042c6b129SJohan Hedberg 
355142c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
355242c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
355342c6b129SJohan Hedberg }
355442c6b129SJohan Hedberg 
35559238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
35569238f36aSJohan Hedberg {
35579238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
35589238f36aSJohan Hedberg 	struct sk_buff *skb;
35599238f36aSJohan Hedberg 	unsigned long flags;
35609238f36aSJohan Hedberg 
35619238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
35629238f36aSJohan Hedberg 
356342c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
356442c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
35659238f36aSJohan Hedberg 	 */
356642c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
356742c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
356842c6b129SJohan Hedberg 		 * reset complete event during init and any pending
356942c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
357042c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
357142c6b129SJohan Hedberg 		 * command.
357242c6b129SJohan Hedberg 		 */
357342c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
357442c6b129SJohan Hedberg 			hci_resend_last(hdev);
357542c6b129SJohan Hedberg 
35769238f36aSJohan Hedberg 		return;
357742c6b129SJohan Hedberg 	}
35789238f36aSJohan Hedberg 
35799238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
35809238f36aSJohan Hedberg 	 * this request the request is not yet complete.
35819238f36aSJohan Hedberg 	 */
35829238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
35839238f36aSJohan Hedberg 		return;
35849238f36aSJohan Hedberg 
35859238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
35869238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
35879238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
35889238f36aSJohan Hedberg 	 */
35899238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
35909238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
359153e21fbcSJohan Hedberg 
359253e21fbcSJohan Hedberg 		if (req_complete) {
359353e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
359453e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
359553e21fbcSJohan Hedberg 			 * this function gets called again.
359653e21fbcSJohan Hedberg 			 */
359753e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
359853e21fbcSJohan Hedberg 
35999238f36aSJohan Hedberg 			goto call_complete;
36009238f36aSJohan Hedberg 		}
360153e21fbcSJohan Hedberg 	}
36029238f36aSJohan Hedberg 
36039238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
36049238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
36059238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
36069238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
36079238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
36089238f36aSJohan Hedberg 			break;
36099238f36aSJohan Hedberg 		}
36109238f36aSJohan Hedberg 
36119238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
36129238f36aSJohan Hedberg 		kfree_skb(skb);
36139238f36aSJohan Hedberg 	}
36149238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
36159238f36aSJohan Hedberg 
36169238f36aSJohan Hedberg call_complete:
36179238f36aSJohan Hedberg 	if (req_complete)
36189238f36aSJohan Hedberg 		req_complete(hdev, status);
36199238f36aSJohan Hedberg }
36209238f36aSJohan Hedberg 
3621b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
36221da177e4SLinus Torvalds {
3623b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
36241da177e4SLinus Torvalds 	struct sk_buff *skb;
36251da177e4SLinus Torvalds 
36261da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
36271da177e4SLinus Torvalds 
36281da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
3629cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
3630cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
3631cd82e61cSMarcel Holtmann 
36321da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
36331da177e4SLinus Torvalds 			/* Send copy to the sockets */
3634470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
36351da177e4SLinus Torvalds 		}
36361da177e4SLinus Torvalds 
36370736cfa8SMarcel Holtmann 		if (test_bit(HCI_RAW, &hdev->flags) ||
36380736cfa8SMarcel Holtmann 		    test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
36391da177e4SLinus Torvalds 			kfree_skb(skb);
36401da177e4SLinus Torvalds 			continue;
36411da177e4SLinus Torvalds 		}
36421da177e4SLinus Torvalds 
36431da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
36441da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
36450d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
36461da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
36471da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
36481da177e4SLinus Torvalds 				kfree_skb(skb);
36491da177e4SLinus Torvalds 				continue;
36503ff50b79SStephen Hemminger 			}
36511da177e4SLinus Torvalds 		}
36521da177e4SLinus Torvalds 
36531da177e4SLinus Torvalds 		/* Process frame */
36540d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
36551da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
3656b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
36571da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
36581da177e4SLinus Torvalds 			break;
36591da177e4SLinus Torvalds 
36601da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
36611da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
36621da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
36631da177e4SLinus Torvalds 			break;
36641da177e4SLinus Torvalds 
36651da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
36661da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
36671da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
36681da177e4SLinus Torvalds 			break;
36691da177e4SLinus Torvalds 
36701da177e4SLinus Torvalds 		default:
36711da177e4SLinus Torvalds 			kfree_skb(skb);
36721da177e4SLinus Torvalds 			break;
36731da177e4SLinus Torvalds 		}
36741da177e4SLinus Torvalds 	}
36751da177e4SLinus Torvalds }
36761da177e4SLinus Torvalds 
3677c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
36781da177e4SLinus Torvalds {
3679c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
36801da177e4SLinus Torvalds 	struct sk_buff *skb;
36811da177e4SLinus Torvalds 
36822104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
36832104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
36841da177e4SLinus Torvalds 
36851da177e4SLinus Torvalds 	/* Send queued commands */
36865a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
36875a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
36885a08ecceSAndrei Emeltchenko 		if (!skb)
36895a08ecceSAndrei Emeltchenko 			return;
36905a08ecceSAndrei Emeltchenko 
36911da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
36921da177e4SLinus Torvalds 
3693a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
369470f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
36951da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
369657d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
36977bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
36987bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
36997bdb8a5cSSzymon Janc 			else
37006bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
37015f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
37021da177e4SLinus Torvalds 		} else {
37031da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
3704c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
37051da177e4SLinus Torvalds 		}
37061da177e4SLinus Torvalds 	}
37071da177e4SLinus Torvalds }
3708