xref: /openbmc/linux/net/bluetooth/hci_core.c (revision e1a26170)
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 {
3562177bab5SJohan Hedberg 	__le16 param;
3572177bab5SJohan Hedberg 	__u8 flt_type;
3582177bab5SJohan Hedberg 
3592177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
36042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
3612177bab5SJohan Hedberg 
3622177bab5SJohan Hedberg 	/* Read Class of Device */
36342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
3642177bab5SJohan Hedberg 
3652177bab5SJohan Hedberg 	/* Read Local Name */
36642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
3672177bab5SJohan Hedberg 
3682177bab5SJohan Hedberg 	/* Read Voice Setting */
36942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
3702177bab5SJohan Hedberg 
3712177bab5SJohan Hedberg 	/* Clear Event Filters */
3722177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
37342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
3742177bab5SJohan Hedberg 
3752177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
3762177bab5SJohan Hedberg 	param = __constant_cpu_to_le16(0x7d00);
37742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
3782177bab5SJohan Hedberg 
379f332ec66SJohan Hedberg 	/* Read page scan parameters */
380f332ec66SJohan Hedberg 	if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) {
381f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
382f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
383f332ec66SJohan Hedberg 	}
3842177bab5SJohan Hedberg }
3852177bab5SJohan Hedberg 
38642c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
3872177bab5SJohan Hedberg {
388c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
389c73eee91SJohan Hedberg 
3902177bab5SJohan Hedberg 	/* Read LE Buffer Size */
39142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
3922177bab5SJohan Hedberg 
3932177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
39442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
3952177bab5SJohan Hedberg 
3962177bab5SJohan Hedberg 	/* Read LE Advertising Channel TX Power */
39742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
3982177bab5SJohan Hedberg 
3992177bab5SJohan Hedberg 	/* Read LE White List Size */
40042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
4012177bab5SJohan Hedberg 
4022177bab5SJohan Hedberg 	/* Read LE Supported States */
40342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
404c73eee91SJohan Hedberg 
405c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
406c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
407c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
4082177bab5SJohan Hedberg }
4092177bab5SJohan Hedberg 
4102177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
4112177bab5SJohan Hedberg {
4122177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
4132177bab5SJohan Hedberg 		return 0x02;
4142177bab5SJohan Hedberg 
4152177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4162177bab5SJohan Hedberg 		return 0x01;
4172177bab5SJohan Hedberg 
4182177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
4192177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
4202177bab5SJohan Hedberg 		return 0x01;
4212177bab5SJohan Hedberg 
4222177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
4232177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
4242177bab5SJohan Hedberg 			return 0x01;
4252177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
4262177bab5SJohan Hedberg 			return 0x01;
4272177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
4282177bab5SJohan Hedberg 			return 0x01;
4292177bab5SJohan Hedberg 	}
4302177bab5SJohan Hedberg 
4312177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
4322177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
4332177bab5SJohan Hedberg 		return 0x01;
4342177bab5SJohan Hedberg 
4352177bab5SJohan Hedberg 	return 0x00;
4362177bab5SJohan Hedberg }
4372177bab5SJohan Hedberg 
43842c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
4392177bab5SJohan Hedberg {
4402177bab5SJohan Hedberg 	u8 mode;
4412177bab5SJohan Hedberg 
44242c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
4432177bab5SJohan Hedberg 
44442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
4452177bab5SJohan Hedberg }
4462177bab5SJohan Hedberg 
44742c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
4482177bab5SJohan Hedberg {
44942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
45042c6b129SJohan Hedberg 
4512177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
4522177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
4532177bab5SJohan Hedberg 	 * command otherwise.
4542177bab5SJohan Hedberg 	 */
4552177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
4562177bab5SJohan Hedberg 
4572177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
4582177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
4592177bab5SJohan Hedberg 	 */
4602177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
4612177bab5SJohan Hedberg 		return;
4622177bab5SJohan Hedberg 
4632177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
4642177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
4652177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4662177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
4672177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
4682177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
469c7882cbdSMarcel Holtmann 	} else {
470c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
471c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
472c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
473c7882cbdSMarcel Holtmann 		events[0] |= 0x80; /* Encryption Change */
474c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
475c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
476c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
477c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
478c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
479c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
480c7882cbdSMarcel Holtmann 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
4812177bab5SJohan Hedberg 	}
4822177bab5SJohan Hedberg 
4832177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4842177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4852177bab5SJohan Hedberg 
4862177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
4872177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
4882177bab5SJohan Hedberg 
4892177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
4902177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
4912177bab5SJohan Hedberg 
4922177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
4932177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
4942177bab5SJohan Hedberg 
4952177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
4962177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
4972177bab5SJohan Hedberg 
4982177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
4992177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
5002177bab5SJohan Hedberg 
5012177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5022177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
5032177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
5042177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
5052177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
5062177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
5072177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
5082177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
5092177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
5102177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
5112177bab5SJohan Hedberg 					 * Features Notification
5122177bab5SJohan Hedberg 					 */
5132177bab5SJohan Hedberg 	}
5142177bab5SJohan Hedberg 
5152177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
5162177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
5172177bab5SJohan Hedberg 
51842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
5192177bab5SJohan Hedberg 
5202177bab5SJohan Hedberg 	if (lmp_le_capable(hdev)) {
5212177bab5SJohan Hedberg 		memset(events, 0, sizeof(events));
5222177bab5SJohan Hedberg 		events[0] = 0x1f;
52342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
5242177bab5SJohan Hedberg 			    sizeof(events), events);
5252177bab5SJohan Hedberg 	}
5262177bab5SJohan Hedberg }
5272177bab5SJohan Hedberg 
52842c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
5292177bab5SJohan Hedberg {
53042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
53142c6b129SJohan Hedberg 
5322177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
53342c6b129SJohan Hedberg 		bredr_setup(req);
53456f87901SJohan Hedberg 	else
53556f87901SJohan Hedberg 		clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
5362177bab5SJohan Hedberg 
5372177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
53842c6b129SJohan Hedberg 		le_setup(req);
5392177bab5SJohan Hedberg 
54042c6b129SJohan Hedberg 	hci_setup_event_mask(req);
5412177bab5SJohan Hedberg 
5423f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
5433f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
5443f8e2d75SJohan Hedberg 	 */
5453f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
54642c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
5472177bab5SJohan Hedberg 
5482177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5492177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
5502177bab5SJohan Hedberg 			u8 mode = 0x01;
55142c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
5522177bab5SJohan Hedberg 				    sizeof(mode), &mode);
5532177bab5SJohan Hedberg 		} else {
5542177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
5552177bab5SJohan Hedberg 
5562177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
5572177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
5582177bab5SJohan Hedberg 
55942c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
5602177bab5SJohan Hedberg 		}
5612177bab5SJohan Hedberg 	}
5622177bab5SJohan Hedberg 
5632177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
56442c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
5652177bab5SJohan Hedberg 
5662177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
56742c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
5682177bab5SJohan Hedberg 
5692177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
5702177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
5712177bab5SJohan Hedberg 
5722177bab5SJohan Hedberg 		cp.page = 0x01;
57342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
57442c6b129SJohan Hedberg 			    sizeof(cp), &cp);
5752177bab5SJohan Hedberg 	}
5762177bab5SJohan Hedberg 
5772177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
5782177bab5SJohan Hedberg 		u8 enable = 1;
57942c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
5802177bab5SJohan Hedberg 			    &enable);
5812177bab5SJohan Hedberg 	}
5822177bab5SJohan Hedberg }
5832177bab5SJohan Hedberg 
58442c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
5852177bab5SJohan Hedberg {
58642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5872177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
5882177bab5SJohan Hedberg 	u16 link_policy = 0;
5892177bab5SJohan Hedberg 
5902177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
5912177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
5922177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
5932177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
5942177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
5952177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
5962177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
5972177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
5982177bab5SJohan Hedberg 
5992177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
60042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
6012177bab5SJohan Hedberg }
6022177bab5SJohan Hedberg 
60342c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
6042177bab5SJohan Hedberg {
60542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
6062177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
6072177bab5SJohan Hedberg 
608c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
609c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
610c73eee91SJohan Hedberg 		return;
611c73eee91SJohan Hedberg 
6122177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
6132177bab5SJohan Hedberg 
6142177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
6152177bab5SJohan Hedberg 		cp.le = 0x01;
6162177bab5SJohan Hedberg 		cp.simul = lmp_le_br_capable(hdev);
6172177bab5SJohan Hedberg 	}
6182177bab5SJohan Hedberg 
6192177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
62042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
6212177bab5SJohan Hedberg 			    &cp);
6222177bab5SJohan Hedberg }
6232177bab5SJohan Hedberg 
624d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
625d62e6d67SJohan Hedberg {
626d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
627d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
628d62e6d67SJohan Hedberg 
629d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
630d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
631d62e6d67SJohan Hedberg 	 */
632d62e6d67SJohan Hedberg 	if (hdev->features[2][0] & 0x01) {
633d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
634d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
635d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
636d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
637d62e6d67SJohan Hedberg 	}
638d62e6d67SJohan Hedberg 
639d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
640d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
641d62e6d67SJohan Hedberg 	 */
642d62e6d67SJohan Hedberg 	if (hdev->features[2][0] & 0x02) {
643d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
644d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
645d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
646d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
647d62e6d67SJohan Hedberg 	}
648d62e6d67SJohan Hedberg 
649d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
650d62e6d67SJohan Hedberg }
651d62e6d67SJohan Hedberg 
65242c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
6532177bab5SJohan Hedberg {
65442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
655d2c5d77fSJohan Hedberg 	u8 p;
65642c6b129SJohan Hedberg 
657b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
658b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
659b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
660b8f4e068SGustavo Padovan 	 *
661b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
662b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
663b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
664b8f4e068SGustavo Padovan 	 * command redundant anyway.
665b8f4e068SGustavo Padovan 	 */
66659f45d57SJohan Hedberg 	if (hdev->commands[6] & 0x80) {
66759f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
66859f45d57SJohan Hedberg 
66959f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
67059f45d57SJohan Hedberg 		cp.delete_all = 0x01;
67159f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
67259f45d57SJohan Hedberg 			    sizeof(cp), &cp);
67359f45d57SJohan Hedberg 	}
67459f45d57SJohan Hedberg 
6752177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
67642c6b129SJohan Hedberg 		hci_setup_link_policy(req);
6772177bab5SJohan Hedberg 
67804b4edcbSJohan Hedberg 	if (lmp_le_capable(hdev)) {
67942c6b129SJohan Hedberg 		hci_set_le_support(req);
68004b4edcbSJohan Hedberg 		hci_update_ad(req);
68104b4edcbSJohan Hedberg 	}
682d2c5d77fSJohan Hedberg 
683d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
684d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
685d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
686d2c5d77fSJohan Hedberg 
687d2c5d77fSJohan Hedberg 		cp.page = p;
688d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
689d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
690d2c5d77fSJohan Hedberg 	}
6912177bab5SJohan Hedberg }
6922177bab5SJohan Hedberg 
6935d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
6945d4e7e8dSJohan Hedberg {
6955d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
6965d4e7e8dSJohan Hedberg 
697d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
698d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
699d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
700d62e6d67SJohan Hedberg 
7015d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
7025d4e7e8dSJohan Hedberg 	if (hdev->features[2][0] & 0x04)
7035d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
7045d4e7e8dSJohan Hedberg }
7055d4e7e8dSJohan Hedberg 
7062177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
7072177bab5SJohan Hedberg {
7082177bab5SJohan Hedberg 	int err;
7092177bab5SJohan Hedberg 
7102177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
7112177bab5SJohan Hedberg 	if (err < 0)
7122177bab5SJohan Hedberg 		return err;
7132177bab5SJohan Hedberg 
7142177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
7152177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
7162177bab5SJohan Hedberg 	 * first stage init.
7172177bab5SJohan Hedberg 	 */
7182177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
7192177bab5SJohan Hedberg 		return 0;
7202177bab5SJohan Hedberg 
7212177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
7222177bab5SJohan Hedberg 	if (err < 0)
7232177bab5SJohan Hedberg 		return err;
7242177bab5SJohan Hedberg 
7255d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
7265d4e7e8dSJohan Hedberg 	if (err < 0)
7275d4e7e8dSJohan Hedberg 		return err;
7285d4e7e8dSJohan Hedberg 
7295d4e7e8dSJohan Hedberg 	return __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
7302177bab5SJohan Hedberg }
7312177bab5SJohan Hedberg 
73242c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
7331da177e4SLinus Torvalds {
7341da177e4SLinus Torvalds 	__u8 scan = opt;
7351da177e4SLinus Torvalds 
73642c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
7371da177e4SLinus Torvalds 
7381da177e4SLinus Torvalds 	/* Inquiry and Page scans */
73942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
7401da177e4SLinus Torvalds }
7411da177e4SLinus Torvalds 
74242c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
7431da177e4SLinus Torvalds {
7441da177e4SLinus Torvalds 	__u8 auth = opt;
7451da177e4SLinus Torvalds 
74642c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
7471da177e4SLinus Torvalds 
7481da177e4SLinus Torvalds 	/* Authentication */
74942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
7501da177e4SLinus Torvalds }
7511da177e4SLinus Torvalds 
75242c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
7531da177e4SLinus Torvalds {
7541da177e4SLinus Torvalds 	__u8 encrypt = opt;
7551da177e4SLinus Torvalds 
75642c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
7571da177e4SLinus Torvalds 
758e4e8e37cSMarcel Holtmann 	/* Encryption */
75942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
7601da177e4SLinus Torvalds }
7611da177e4SLinus Torvalds 
76242c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
763e4e8e37cSMarcel Holtmann {
764e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
765e4e8e37cSMarcel Holtmann 
76642c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
767e4e8e37cSMarcel Holtmann 
768e4e8e37cSMarcel Holtmann 	/* Default link policy */
76942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
770e4e8e37cSMarcel Holtmann }
771e4e8e37cSMarcel Holtmann 
7721da177e4SLinus Torvalds /* Get HCI device by index.
7731da177e4SLinus Torvalds  * Device is held on return. */
7741da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
7751da177e4SLinus Torvalds {
7768035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
7771da177e4SLinus Torvalds 
7781da177e4SLinus Torvalds 	BT_DBG("%d", index);
7791da177e4SLinus Torvalds 
7801da177e4SLinus Torvalds 	if (index < 0)
7811da177e4SLinus Torvalds 		return NULL;
7821da177e4SLinus Torvalds 
7831da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
7848035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
7851da177e4SLinus Torvalds 		if (d->id == index) {
7861da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
7871da177e4SLinus Torvalds 			break;
7881da177e4SLinus Torvalds 		}
7891da177e4SLinus Torvalds 	}
7901da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
7911da177e4SLinus Torvalds 	return hdev;
7921da177e4SLinus Torvalds }
7931da177e4SLinus Torvalds 
7941da177e4SLinus Torvalds /* ---- Inquiry support ---- */
795ff9ef578SJohan Hedberg 
79630dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
79730dc78e1SJohan Hedberg {
79830dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
79930dc78e1SJohan Hedberg 
8006fbe195dSAndre Guedes 	switch (discov->state) {
801343f935bSAndre Guedes 	case DISCOVERY_FINDING:
8026fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
80330dc78e1SJohan Hedberg 		return true;
80430dc78e1SJohan Hedberg 
8056fbe195dSAndre Guedes 	default:
80630dc78e1SJohan Hedberg 		return false;
80730dc78e1SJohan Hedberg 	}
8086fbe195dSAndre Guedes }
80930dc78e1SJohan Hedberg 
810ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
811ff9ef578SJohan Hedberg {
812ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
813ff9ef578SJohan Hedberg 
814ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
815ff9ef578SJohan Hedberg 		return;
816ff9ef578SJohan Hedberg 
817ff9ef578SJohan Hedberg 	switch (state) {
818ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
8197b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
820ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
821ff9ef578SJohan Hedberg 		break;
822ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
823ff9ef578SJohan Hedberg 		break;
824343f935bSAndre Guedes 	case DISCOVERY_FINDING:
825ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
826ff9ef578SJohan Hedberg 		break;
82730dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
82830dc78e1SJohan Hedberg 		break;
829ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
830ff9ef578SJohan Hedberg 		break;
831ff9ef578SJohan Hedberg 	}
832ff9ef578SJohan Hedberg 
833ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
834ff9ef578SJohan Hedberg }
835ff9ef578SJohan Hedberg 
8361f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
8371da177e4SLinus Torvalds {
83830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
839b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
8401da177e4SLinus Torvalds 
841561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
842561aafbcSJohan Hedberg 		list_del(&p->all);
843b57c1a56SJohan Hedberg 		kfree(p);
8441da177e4SLinus Torvalds 	}
845561aafbcSJohan Hedberg 
846561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
847561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
8481da177e4SLinus Torvalds }
8491da177e4SLinus Torvalds 
850a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
851a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
8521da177e4SLinus Torvalds {
85330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
8541da177e4SLinus Torvalds 	struct inquiry_entry *e;
8551da177e4SLinus Torvalds 
8566ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
8571da177e4SLinus Torvalds 
858561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
8591da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
8601da177e4SLinus Torvalds 			return e;
8611da177e4SLinus Torvalds 	}
8621da177e4SLinus Torvalds 
863b57c1a56SJohan Hedberg 	return NULL;
864b57c1a56SJohan Hedberg }
865b57c1a56SJohan Hedberg 
866561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
867561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
868561aafbcSJohan Hedberg {
86930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
870561aafbcSJohan Hedberg 	struct inquiry_entry *e;
871561aafbcSJohan Hedberg 
8726ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
873561aafbcSJohan Hedberg 
874561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
875561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
876561aafbcSJohan Hedberg 			return e;
877561aafbcSJohan Hedberg 	}
878561aafbcSJohan Hedberg 
879561aafbcSJohan Hedberg 	return NULL;
880561aafbcSJohan Hedberg }
881561aafbcSJohan Hedberg 
88230dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
88330dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
88430dc78e1SJohan Hedberg 						       int state)
88530dc78e1SJohan Hedberg {
88630dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
88730dc78e1SJohan Hedberg 	struct inquiry_entry *e;
88830dc78e1SJohan Hedberg 
8896ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
89030dc78e1SJohan Hedberg 
89130dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
89230dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
89330dc78e1SJohan Hedberg 			return e;
89430dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
89530dc78e1SJohan Hedberg 			return e;
89630dc78e1SJohan Hedberg 	}
89730dc78e1SJohan Hedberg 
89830dc78e1SJohan Hedberg 	return NULL;
89930dc78e1SJohan Hedberg }
90030dc78e1SJohan Hedberg 
901a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
902a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
903a3d4e20aSJohan Hedberg {
904a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
905a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
906a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
907a3d4e20aSJohan Hedberg 
908a3d4e20aSJohan Hedberg 	list_del(&ie->list);
909a3d4e20aSJohan Hedberg 
910a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
911a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
912a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
913a3d4e20aSJohan Hedberg 			break;
914a3d4e20aSJohan Hedberg 		pos = &p->list;
915a3d4e20aSJohan Hedberg 	}
916a3d4e20aSJohan Hedberg 
917a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
918a3d4e20aSJohan Hedberg }
919a3d4e20aSJohan Hedberg 
9203175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
921388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
9221da177e4SLinus Torvalds {
92330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
92470f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
9251da177e4SLinus Torvalds 
9266ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
9271da177e4SLinus Torvalds 
9282b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
9292b2fec4dSSzymon Janc 
930388fc8faSJohan Hedberg 	if (ssp)
931388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
932388fc8faSJohan Hedberg 
93370f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
934a3d4e20aSJohan Hedberg 	if (ie) {
935388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
936388fc8faSJohan Hedberg 			*ssp = true;
937388fc8faSJohan Hedberg 
938a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
939a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
940a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
941a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
942a3d4e20aSJohan Hedberg 		}
943a3d4e20aSJohan Hedberg 
944561aafbcSJohan Hedberg 		goto update;
945a3d4e20aSJohan Hedberg 	}
946561aafbcSJohan Hedberg 
9471da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
94870f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
94970f23020SAndrei Emeltchenko 	if (!ie)
9503175405bSJohan Hedberg 		return false;
95170f23020SAndrei Emeltchenko 
952561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
953561aafbcSJohan Hedberg 
954561aafbcSJohan Hedberg 	if (name_known) {
955561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
956561aafbcSJohan Hedberg 	} else {
957561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
958561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
959561aafbcSJohan Hedberg 	}
960561aafbcSJohan Hedberg 
961561aafbcSJohan Hedberg update:
962561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
963561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
964561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
965561aafbcSJohan Hedberg 		list_del(&ie->list);
9661da177e4SLinus Torvalds 	}
9671da177e4SLinus Torvalds 
96870f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
96970f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
9701da177e4SLinus Torvalds 	cache->timestamp = jiffies;
9713175405bSJohan Hedberg 
9723175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
9733175405bSJohan Hedberg 		return false;
9743175405bSJohan Hedberg 
9753175405bSJohan Hedberg 	return true;
9761da177e4SLinus Torvalds }
9771da177e4SLinus Torvalds 
9781da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
9791da177e4SLinus Torvalds {
98030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
9811da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
9821da177e4SLinus Torvalds 	struct inquiry_entry *e;
9831da177e4SLinus Torvalds 	int copied = 0;
9841da177e4SLinus Torvalds 
985561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
9861da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
987b57c1a56SJohan Hedberg 
988b57c1a56SJohan Hedberg 		if (copied >= num)
989b57c1a56SJohan Hedberg 			break;
990b57c1a56SJohan Hedberg 
9911da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
9921da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
9931da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
9941da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
9951da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
9961da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
997b57c1a56SJohan Hedberg 
9981da177e4SLinus Torvalds 		info++;
999b57c1a56SJohan Hedberg 		copied++;
10001da177e4SLinus Torvalds 	}
10011da177e4SLinus Torvalds 
10021da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
10031da177e4SLinus Torvalds 	return copied;
10041da177e4SLinus Torvalds }
10051da177e4SLinus Torvalds 
100642c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
10071da177e4SLinus Torvalds {
10081da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
100942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
10101da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
10111da177e4SLinus Torvalds 
10121da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
10131da177e4SLinus Torvalds 
10141da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
10151da177e4SLinus Torvalds 		return;
10161da177e4SLinus Torvalds 
10171da177e4SLinus Torvalds 	/* Start Inquiry */
10181da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
10191da177e4SLinus Torvalds 	cp.length  = ir->length;
10201da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
102142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
10221da177e4SLinus Torvalds }
10231da177e4SLinus Torvalds 
10243e13fa1eSAndre Guedes static int wait_inquiry(void *word)
10253e13fa1eSAndre Guedes {
10263e13fa1eSAndre Guedes 	schedule();
10273e13fa1eSAndre Guedes 	return signal_pending(current);
10283e13fa1eSAndre Guedes }
10293e13fa1eSAndre Guedes 
10301da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
10311da177e4SLinus Torvalds {
10321da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
10331da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
10341da177e4SLinus Torvalds 	struct hci_dev *hdev;
10351da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
10361da177e4SLinus Torvalds 	long timeo;
10371da177e4SLinus Torvalds 	__u8 *buf;
10381da177e4SLinus Torvalds 
10391da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
10401da177e4SLinus Torvalds 		return -EFAULT;
10411da177e4SLinus Torvalds 
10425a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
10435a08ecceSAndrei Emeltchenko 	if (!hdev)
10441da177e4SLinus Torvalds 		return -ENODEV;
10451da177e4SLinus Torvalds 
10460736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
10470736cfa8SMarcel Holtmann 		err = -EBUSY;
10480736cfa8SMarcel Holtmann 		goto done;
10490736cfa8SMarcel Holtmann 	}
10500736cfa8SMarcel Holtmann 
10515b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
10525b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
10535b69bef5SMarcel Holtmann 		goto done;
10545b69bef5SMarcel Holtmann 	}
10555b69bef5SMarcel Holtmann 
105656f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
105756f87901SJohan Hedberg 		err = -EOPNOTSUPP;
105856f87901SJohan Hedberg 		goto done;
105956f87901SJohan Hedberg 	}
106056f87901SJohan Hedberg 
106109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
10621da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1063a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
10641f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
10651da177e4SLinus Torvalds 		do_inquiry = 1;
10661da177e4SLinus Torvalds 	}
106709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
10681da177e4SLinus Torvalds 
106904837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
107070f23020SAndrei Emeltchenko 
107170f23020SAndrei Emeltchenko 	if (do_inquiry) {
107201178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
107301178cd4SJohan Hedberg 				   timeo);
107470f23020SAndrei Emeltchenko 		if (err < 0)
10751da177e4SLinus Torvalds 			goto done;
10763e13fa1eSAndre Guedes 
10773e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
10783e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
10793e13fa1eSAndre Guedes 		 */
10803e13fa1eSAndre Guedes 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry,
10813e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
10823e13fa1eSAndre Guedes 			return -EINTR;
108370f23020SAndrei Emeltchenko 	}
10841da177e4SLinus Torvalds 
10858fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
10868fc9ced3SGustavo Padovan 	 * 255 entries
10878fc9ced3SGustavo Padovan 	 */
10881da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
10891da177e4SLinus Torvalds 
10901da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
10911da177e4SLinus Torvalds 	 * copy it to the user space.
10921da177e4SLinus Torvalds 	 */
109370f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
109470f23020SAndrei Emeltchenko 	if (!buf) {
10951da177e4SLinus Torvalds 		err = -ENOMEM;
10961da177e4SLinus Torvalds 		goto done;
10971da177e4SLinus Torvalds 	}
10981da177e4SLinus Torvalds 
109909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
11001da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
110109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
11021da177e4SLinus Torvalds 
11031da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
11041da177e4SLinus Torvalds 
11051da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
11061da177e4SLinus Torvalds 		ptr += sizeof(ir);
11071da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
11081da177e4SLinus Torvalds 				 ir.num_rsp))
11091da177e4SLinus Torvalds 			err = -EFAULT;
11101da177e4SLinus Torvalds 	} else
11111da177e4SLinus Torvalds 		err = -EFAULT;
11121da177e4SLinus Torvalds 
11131da177e4SLinus Torvalds 	kfree(buf);
11141da177e4SLinus Torvalds 
11151da177e4SLinus Torvalds done:
11161da177e4SLinus Torvalds 	hci_dev_put(hdev);
11171da177e4SLinus Torvalds 	return err;
11181da177e4SLinus Torvalds }
11191da177e4SLinus Torvalds 
11203f0f524bSJohan Hedberg static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
11213f0f524bSJohan Hedberg {
11223f0f524bSJohan Hedberg 	u8 ad_len = 0, flags = 0;
11233f0f524bSJohan Hedberg 	size_t name_len;
11243f0f524bSJohan Hedberg 
1125f3d3444aSJohan Hedberg 	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
11263f0f524bSJohan Hedberg 		flags |= LE_AD_GENERAL;
11273f0f524bSJohan Hedberg 
112811802b29SJohan Hedberg 	if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
11293f0f524bSJohan Hedberg 		if (lmp_le_br_capable(hdev))
11303f0f524bSJohan Hedberg 			flags |= LE_AD_SIM_LE_BREDR_CTRL;
11313f0f524bSJohan Hedberg 		if (lmp_host_le_br_capable(hdev))
11323f0f524bSJohan Hedberg 			flags |= LE_AD_SIM_LE_BREDR_HOST;
113311802b29SJohan Hedberg 	} else {
113411802b29SJohan Hedberg 		flags |= LE_AD_NO_BREDR;
113511802b29SJohan Hedberg 	}
11363f0f524bSJohan Hedberg 
11373f0f524bSJohan Hedberg 	if (flags) {
11383f0f524bSJohan Hedberg 		BT_DBG("adv flags 0x%02x", flags);
11393f0f524bSJohan Hedberg 
11403f0f524bSJohan Hedberg 		ptr[0] = 2;
11413f0f524bSJohan Hedberg 		ptr[1] = EIR_FLAGS;
11423f0f524bSJohan Hedberg 		ptr[2] = flags;
11433f0f524bSJohan Hedberg 
11443f0f524bSJohan Hedberg 		ad_len += 3;
11453f0f524bSJohan Hedberg 		ptr += 3;
11463f0f524bSJohan Hedberg 	}
11473f0f524bSJohan Hedberg 
11483f0f524bSJohan Hedberg 	if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) {
11493f0f524bSJohan Hedberg 		ptr[0] = 2;
11503f0f524bSJohan Hedberg 		ptr[1] = EIR_TX_POWER;
11513f0f524bSJohan Hedberg 		ptr[2] = (u8) hdev->adv_tx_power;
11523f0f524bSJohan Hedberg 
11533f0f524bSJohan Hedberg 		ad_len += 3;
11543f0f524bSJohan Hedberg 		ptr += 3;
11553f0f524bSJohan Hedberg 	}
11563f0f524bSJohan Hedberg 
11573f0f524bSJohan Hedberg 	name_len = strlen(hdev->dev_name);
11583f0f524bSJohan Hedberg 	if (name_len > 0) {
11593f0f524bSJohan Hedberg 		size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
11603f0f524bSJohan Hedberg 
11613f0f524bSJohan Hedberg 		if (name_len > max_len) {
11623f0f524bSJohan Hedberg 			name_len = max_len;
11633f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_SHORT;
11643f0f524bSJohan Hedberg 		} else
11653f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_COMPLETE;
11663f0f524bSJohan Hedberg 
11673f0f524bSJohan Hedberg 		ptr[0] = name_len + 1;
11683f0f524bSJohan Hedberg 
11693f0f524bSJohan Hedberg 		memcpy(ptr + 2, hdev->dev_name, name_len);
11703f0f524bSJohan Hedberg 
11713f0f524bSJohan Hedberg 		ad_len += (name_len + 2);
11723f0f524bSJohan Hedberg 		ptr += (name_len + 2);
11733f0f524bSJohan Hedberg 	}
11743f0f524bSJohan Hedberg 
11753f0f524bSJohan Hedberg 	return ad_len;
11763f0f524bSJohan Hedberg }
11773f0f524bSJohan Hedberg 
117804b4edcbSJohan Hedberg void hci_update_ad(struct hci_request *req)
11793f0f524bSJohan Hedberg {
118004b4edcbSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
11813f0f524bSJohan Hedberg 	struct hci_cp_le_set_adv_data cp;
11823f0f524bSJohan Hedberg 	u8 len;
11833f0f524bSJohan Hedberg 
118404b4edcbSJohan Hedberg 	if (!lmp_le_capable(hdev))
118504b4edcbSJohan Hedberg 		return;
11863f0f524bSJohan Hedberg 
11873f0f524bSJohan Hedberg 	memset(&cp, 0, sizeof(cp));
11883f0f524bSJohan Hedberg 
11893f0f524bSJohan Hedberg 	len = create_ad(hdev, cp.data);
11903f0f524bSJohan Hedberg 
11913f0f524bSJohan Hedberg 	if (hdev->adv_data_len == len &&
119204b4edcbSJohan Hedberg 	    memcmp(cp.data, hdev->adv_data, len) == 0)
119304b4edcbSJohan Hedberg 		return;
11943f0f524bSJohan Hedberg 
11953f0f524bSJohan Hedberg 	memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
11963f0f524bSJohan Hedberg 	hdev->adv_data_len = len;
11973f0f524bSJohan Hedberg 
11983f0f524bSJohan Hedberg 	cp.length = len;
11993f0f524bSJohan Hedberg 
120004b4edcbSJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
12013f0f524bSJohan Hedberg }
12023f0f524bSJohan Hedberg 
1203cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
12041da177e4SLinus Torvalds {
12051da177e4SLinus Torvalds 	int ret = 0;
12061da177e4SLinus Torvalds 
12071da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
12081da177e4SLinus Torvalds 
12091da177e4SLinus Torvalds 	hci_req_lock(hdev);
12101da177e4SLinus Torvalds 
121194324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
121294324962SJohan Hovold 		ret = -ENODEV;
121394324962SJohan Hovold 		goto done;
121494324962SJohan Hovold 	}
121594324962SJohan Hovold 
1216a5c8f270SMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
1217a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1218a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1219bf543036SJohan Hedberg 		 */
1220a5c8f270SMarcel Holtmann 		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
1221611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1222611b30f7SMarcel Holtmann 			goto done;
1223611b30f7SMarcel Holtmann 		}
1224611b30f7SMarcel Holtmann 
1225a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
1226a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
1227a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1228a5c8f270SMarcel Holtmann 		 * or not.
1229a5c8f270SMarcel Holtmann 		 *
1230a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1231a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1232a5c8f270SMarcel Holtmann 		 */
1233a5c8f270SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR &&
1234a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1235a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1236a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1237a5c8f270SMarcel Holtmann 			goto done;
1238a5c8f270SMarcel Holtmann 		}
1239a5c8f270SMarcel Holtmann 	}
1240a5c8f270SMarcel Holtmann 
12411da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
12421da177e4SLinus Torvalds 		ret = -EALREADY;
12431da177e4SLinus Torvalds 		goto done;
12441da177e4SLinus Torvalds 	}
12451da177e4SLinus Torvalds 
12461da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
12471da177e4SLinus Torvalds 		ret = -EIO;
12481da177e4SLinus Torvalds 		goto done;
12491da177e4SLinus Torvalds 	}
12501da177e4SLinus Torvalds 
12511da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
12521da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1253f41c70c4SMarcel Holtmann 
1254f41c70c4SMarcel Holtmann 	if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
1255f41c70c4SMarcel Holtmann 		ret = hdev->setup(hdev);
1256f41c70c4SMarcel Holtmann 
1257f41c70c4SMarcel Holtmann 	if (!ret) {
1258f41c70c4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1259f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
1260f41c70c4SMarcel Holtmann 
12610736cfa8SMarcel Holtmann 		if (!test_bit(HCI_RAW, &hdev->flags) &&
12620736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
12632177bab5SJohan Hedberg 			ret = __hci_init(hdev);
12641da177e4SLinus Torvalds 	}
12651da177e4SLinus Torvalds 
1266f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1267f41c70c4SMarcel Holtmann 
12681da177e4SLinus Torvalds 	if (!ret) {
12691da177e4SLinus Torvalds 		hci_dev_hold(hdev);
12701da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
12711da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
1272bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
12730736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
12741514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
127509fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1276744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
127709fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
127856e5cb86SJohan Hedberg 		}
12791da177e4SLinus Torvalds 	} else {
12801da177e4SLinus Torvalds 		/* Init failed, cleanup */
12813eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1282c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1283b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
12841da177e4SLinus Torvalds 
12851da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
12861da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
12871da177e4SLinus Torvalds 
12881da177e4SLinus Torvalds 		if (hdev->flush)
12891da177e4SLinus Torvalds 			hdev->flush(hdev);
12901da177e4SLinus Torvalds 
12911da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
12921da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
12931da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
12941da177e4SLinus Torvalds 		}
12951da177e4SLinus Torvalds 
12961da177e4SLinus Torvalds 		hdev->close(hdev);
12971da177e4SLinus Torvalds 		hdev->flags = 0;
12981da177e4SLinus Torvalds 	}
12991da177e4SLinus Torvalds 
13001da177e4SLinus Torvalds done:
13011da177e4SLinus Torvalds 	hci_req_unlock(hdev);
13021da177e4SLinus Torvalds 	return ret;
13031da177e4SLinus Torvalds }
13041da177e4SLinus Torvalds 
1305cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
1306cbed0ca1SJohan Hedberg 
1307cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
1308cbed0ca1SJohan Hedberg {
1309cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
1310cbed0ca1SJohan Hedberg 	int err;
1311cbed0ca1SJohan Hedberg 
1312cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
1313cbed0ca1SJohan Hedberg 	if (!hdev)
1314cbed0ca1SJohan Hedberg 		return -ENODEV;
1315cbed0ca1SJohan Hedberg 
1316e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
1317e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
1318e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
1319e1d08f40SJohan Hedberg 	 * completed.
1320e1d08f40SJohan Hedberg 	 */
1321e1d08f40SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1322e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
1323e1d08f40SJohan Hedberg 
1324a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
1325a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
1326a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
1327a5c8f270SMarcel Holtmann 	 */
1328e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
1329e1d08f40SJohan Hedberg 
1330cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
1331cbed0ca1SJohan Hedberg 
1332cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
1333cbed0ca1SJohan Hedberg 
1334cbed0ca1SJohan Hedberg 	return err;
1335cbed0ca1SJohan Hedberg }
1336cbed0ca1SJohan Hedberg 
13371da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
13381da177e4SLinus Torvalds {
13391da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
13401da177e4SLinus Torvalds 
134178c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
134278c04c0bSVinicius Costa Gomes 
13431da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
13441da177e4SLinus Torvalds 	hci_req_lock(hdev);
13451da177e4SLinus Torvalds 
13461da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
1347b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
13481da177e4SLinus Torvalds 		hci_req_unlock(hdev);
13491da177e4SLinus Torvalds 		return 0;
13501da177e4SLinus Torvalds 	}
13511da177e4SLinus Torvalds 
13523eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
13533eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1354b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
13551da177e4SLinus Torvalds 
135616ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
1357e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
135816ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
13595e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
136016ab91abSJohan Hedberg 	}
136116ab91abSJohan Hedberg 
1362a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
13637d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
13647d78525dSJohan Hedberg 
13657ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
13667ba8b4beSAndre Guedes 
136709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13681f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
13691da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
137009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13711da177e4SLinus Torvalds 
13721da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
13731da177e4SLinus Torvalds 
13741da177e4SLinus Torvalds 	if (hdev->flush)
13751da177e4SLinus Torvalds 		hdev->flush(hdev);
13761da177e4SLinus Torvalds 
13771da177e4SLinus Torvalds 	/* Reset device */
13781da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
13791da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
13808af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
1381a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
13821da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
138301178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
13841da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
13851da177e4SLinus Torvalds 	}
13861da177e4SLinus Torvalds 
1387c347b765SGustavo F. Padovan 	/* flush cmd  work */
1388c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
13891da177e4SLinus Torvalds 
13901da177e4SLinus Torvalds 	/* Drop queues */
13911da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
13921da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
13931da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
13941da177e4SLinus Torvalds 
13951da177e4SLinus Torvalds 	/* Drop last sent command */
13961da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
1397b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
13981da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
13991da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
14001da177e4SLinus Torvalds 	}
14011da177e4SLinus Torvalds 
1402b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
1403b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
1404b6ddb638SJohan Hedberg 
14051da177e4SLinus Torvalds 	/* After this point our queues are empty
14061da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
14071da177e4SLinus Torvalds 	hdev->close(hdev);
14081da177e4SLinus Torvalds 
140935b973c9SJohan Hedberg 	/* Clear flags */
141035b973c9SJohan Hedberg 	hdev->flags = 0;
141135b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
141235b973c9SJohan Hedberg 
141393c311a0SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
141493c311a0SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR) {
141509fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1416744cf19eSJohan Hedberg 			mgmt_powered(hdev, 0);
141709fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
14188ee56540SMarcel Holtmann 		}
141993c311a0SMarcel Holtmann 	}
14205add6af8SJohan Hedberg 
1421ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1422536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
1423ced5c338SAndrei Emeltchenko 
1424e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
142509b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
1426e59fda8dSJohan Hedberg 
14271da177e4SLinus Torvalds 	hci_req_unlock(hdev);
14281da177e4SLinus Torvalds 
14291da177e4SLinus Torvalds 	hci_dev_put(hdev);
14301da177e4SLinus Torvalds 	return 0;
14311da177e4SLinus Torvalds }
14321da177e4SLinus Torvalds 
14331da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
14341da177e4SLinus Torvalds {
14351da177e4SLinus Torvalds 	struct hci_dev *hdev;
14361da177e4SLinus Torvalds 	int err;
14371da177e4SLinus Torvalds 
143870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
143970f23020SAndrei Emeltchenko 	if (!hdev)
14401da177e4SLinus Torvalds 		return -ENODEV;
14418ee56540SMarcel Holtmann 
14420736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
14430736cfa8SMarcel Holtmann 		err = -EBUSY;
14440736cfa8SMarcel Holtmann 		goto done;
14450736cfa8SMarcel Holtmann 	}
14460736cfa8SMarcel Holtmann 
14478ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
14488ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
14498ee56540SMarcel Holtmann 
14501da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
14518ee56540SMarcel Holtmann 
14520736cfa8SMarcel Holtmann done:
14531da177e4SLinus Torvalds 	hci_dev_put(hdev);
14541da177e4SLinus Torvalds 	return err;
14551da177e4SLinus Torvalds }
14561da177e4SLinus Torvalds 
14571da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
14581da177e4SLinus Torvalds {
14591da177e4SLinus Torvalds 	struct hci_dev *hdev;
14601da177e4SLinus Torvalds 	int ret = 0;
14611da177e4SLinus Torvalds 
146270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
146370f23020SAndrei Emeltchenko 	if (!hdev)
14641da177e4SLinus Torvalds 		return -ENODEV;
14651da177e4SLinus Torvalds 
14661da177e4SLinus Torvalds 	hci_req_lock(hdev);
14671da177e4SLinus Torvalds 
1468808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
1469808a049eSMarcel Holtmann 		ret = -ENETDOWN;
14701da177e4SLinus Torvalds 		goto done;
1471808a049eSMarcel Holtmann 	}
14721da177e4SLinus Torvalds 
14730736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
14740736cfa8SMarcel Holtmann 		ret = -EBUSY;
14750736cfa8SMarcel Holtmann 		goto done;
14760736cfa8SMarcel Holtmann 	}
14770736cfa8SMarcel Holtmann 
14781da177e4SLinus Torvalds 	/* Drop queues */
14791da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
14801da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
14811da177e4SLinus Torvalds 
148209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
14831f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
14841da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
148509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
14861da177e4SLinus Torvalds 
14871da177e4SLinus Torvalds 	if (hdev->flush)
14881da177e4SLinus Torvalds 		hdev->flush(hdev);
14891da177e4SLinus Torvalds 
14901da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
14916ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
14921da177e4SLinus Torvalds 
14931da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
149401178cd4SJohan Hedberg 		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
14951da177e4SLinus Torvalds 
14961da177e4SLinus Torvalds done:
14971da177e4SLinus Torvalds 	hci_req_unlock(hdev);
14981da177e4SLinus Torvalds 	hci_dev_put(hdev);
14991da177e4SLinus Torvalds 	return ret;
15001da177e4SLinus Torvalds }
15011da177e4SLinus Torvalds 
15021da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
15031da177e4SLinus Torvalds {
15041da177e4SLinus Torvalds 	struct hci_dev *hdev;
15051da177e4SLinus Torvalds 	int ret = 0;
15061da177e4SLinus Torvalds 
150770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
150870f23020SAndrei Emeltchenko 	if (!hdev)
15091da177e4SLinus Torvalds 		return -ENODEV;
15101da177e4SLinus Torvalds 
15110736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
15120736cfa8SMarcel Holtmann 		ret = -EBUSY;
15130736cfa8SMarcel Holtmann 		goto done;
15140736cfa8SMarcel Holtmann 	}
15150736cfa8SMarcel Holtmann 
15161da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
15171da177e4SLinus Torvalds 
15180736cfa8SMarcel Holtmann done:
15191da177e4SLinus Torvalds 	hci_dev_put(hdev);
15201da177e4SLinus Torvalds 	return ret;
15211da177e4SLinus Torvalds }
15221da177e4SLinus Torvalds 
15231da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
15241da177e4SLinus Torvalds {
15251da177e4SLinus Torvalds 	struct hci_dev *hdev;
15261da177e4SLinus Torvalds 	struct hci_dev_req dr;
15271da177e4SLinus Torvalds 	int err = 0;
15281da177e4SLinus Torvalds 
15291da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
15301da177e4SLinus Torvalds 		return -EFAULT;
15311da177e4SLinus Torvalds 
153270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
153370f23020SAndrei Emeltchenko 	if (!hdev)
15341da177e4SLinus Torvalds 		return -ENODEV;
15351da177e4SLinus Torvalds 
15360736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
15370736cfa8SMarcel Holtmann 		err = -EBUSY;
15380736cfa8SMarcel Holtmann 		goto done;
15390736cfa8SMarcel Holtmann 	}
15400736cfa8SMarcel Holtmann 
15415b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
15425b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
15435b69bef5SMarcel Holtmann 		goto done;
15445b69bef5SMarcel Holtmann 	}
15455b69bef5SMarcel Holtmann 
154656f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
154756f87901SJohan Hedberg 		err = -EOPNOTSUPP;
154856f87901SJohan Hedberg 		goto done;
154956f87901SJohan Hedberg 	}
155056f87901SJohan Hedberg 
15511da177e4SLinus Torvalds 	switch (cmd) {
15521da177e4SLinus Torvalds 	case HCISETAUTH:
155301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
15545f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15551da177e4SLinus Torvalds 		break;
15561da177e4SLinus Torvalds 
15571da177e4SLinus Torvalds 	case HCISETENCRYPT:
15581da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
15591da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
15601da177e4SLinus Torvalds 			break;
15611da177e4SLinus Torvalds 		}
15621da177e4SLinus Torvalds 
15631da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
15641da177e4SLinus Torvalds 			/* Auth must be enabled first */
156501178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
15665f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
15671da177e4SLinus Torvalds 			if (err)
15681da177e4SLinus Torvalds 				break;
15691da177e4SLinus Torvalds 		}
15701da177e4SLinus Torvalds 
157101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
15725f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15731da177e4SLinus Torvalds 		break;
15741da177e4SLinus Torvalds 
15751da177e4SLinus Torvalds 	case HCISETSCAN:
157601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
15775f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15781da177e4SLinus Torvalds 		break;
15791da177e4SLinus Torvalds 
15801da177e4SLinus Torvalds 	case HCISETLINKPOL:
158101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
15825f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
15831da177e4SLinus Torvalds 		break;
15841da177e4SLinus Torvalds 
15851da177e4SLinus Torvalds 	case HCISETLINKMODE:
1586e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
1587e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
1588e4e8e37cSMarcel Holtmann 		break;
1589e4e8e37cSMarcel Holtmann 
1590e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
1591e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
15921da177e4SLinus Torvalds 		break;
15931da177e4SLinus Torvalds 
15941da177e4SLinus Torvalds 	case HCISETACLMTU:
15951da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
15961da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
15971da177e4SLinus Torvalds 		break;
15981da177e4SLinus Torvalds 
15991da177e4SLinus Torvalds 	case HCISETSCOMTU:
16001da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
16011da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
16021da177e4SLinus Torvalds 		break;
16031da177e4SLinus Torvalds 
16041da177e4SLinus Torvalds 	default:
16051da177e4SLinus Torvalds 		err = -EINVAL;
16061da177e4SLinus Torvalds 		break;
16071da177e4SLinus Torvalds 	}
1608e4e8e37cSMarcel Holtmann 
16090736cfa8SMarcel Holtmann done:
16101da177e4SLinus Torvalds 	hci_dev_put(hdev);
16111da177e4SLinus Torvalds 	return err;
16121da177e4SLinus Torvalds }
16131da177e4SLinus Torvalds 
16141da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
16151da177e4SLinus Torvalds {
16168035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
16171da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
16181da177e4SLinus Torvalds 	struct hci_dev_req *dr;
16191da177e4SLinus Torvalds 	int n = 0, size, err;
16201da177e4SLinus Torvalds 	__u16 dev_num;
16211da177e4SLinus Torvalds 
16221da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
16231da177e4SLinus Torvalds 		return -EFAULT;
16241da177e4SLinus Torvalds 
16251da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
16261da177e4SLinus Torvalds 		return -EINVAL;
16271da177e4SLinus Torvalds 
16281da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
16291da177e4SLinus Torvalds 
163070f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
163170f23020SAndrei Emeltchenko 	if (!dl)
16321da177e4SLinus Torvalds 		return -ENOMEM;
16331da177e4SLinus Torvalds 
16341da177e4SLinus Torvalds 	dr = dl->dev_req;
16351da177e4SLinus Torvalds 
1636f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
16378035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
1638a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1639e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
1640c542a06cSJohan Hedberg 
1641a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1642a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1643c542a06cSJohan Hedberg 
16441da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
16451da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
1646c542a06cSJohan Hedberg 
16471da177e4SLinus Torvalds 		if (++n >= dev_num)
16481da177e4SLinus Torvalds 			break;
16491da177e4SLinus Torvalds 	}
1650f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
16511da177e4SLinus Torvalds 
16521da177e4SLinus Torvalds 	dl->dev_num = n;
16531da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
16541da177e4SLinus Torvalds 
16551da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
16561da177e4SLinus Torvalds 	kfree(dl);
16571da177e4SLinus Torvalds 
16581da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
16591da177e4SLinus Torvalds }
16601da177e4SLinus Torvalds 
16611da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
16621da177e4SLinus Torvalds {
16631da177e4SLinus Torvalds 	struct hci_dev *hdev;
16641da177e4SLinus Torvalds 	struct hci_dev_info di;
16651da177e4SLinus Torvalds 	int err = 0;
16661da177e4SLinus Torvalds 
16671da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
16681da177e4SLinus Torvalds 		return -EFAULT;
16691da177e4SLinus Torvalds 
167070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
167170f23020SAndrei Emeltchenko 	if (!hdev)
16721da177e4SLinus Torvalds 		return -ENODEV;
16731da177e4SLinus Torvalds 
1674a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
16753243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1676ab81cbf9SJohan Hedberg 
1677a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1678a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1679c542a06cSJohan Hedberg 
16801da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
16811da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
168260f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
16831da177e4SLinus Torvalds 	di.flags    = hdev->flags;
16841da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
1685572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
16861da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
16871da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
16881da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
16891da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
1690572c7f84SJohan Hedberg 	} else {
1691572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
1692572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
1693572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
1694572c7f84SJohan Hedberg 		di.sco_pkts = 0;
1695572c7f84SJohan Hedberg 	}
16961da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
16971da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
16981da177e4SLinus Torvalds 
16991da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
17001da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
17011da177e4SLinus Torvalds 
17021da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
17031da177e4SLinus Torvalds 		err = -EFAULT;
17041da177e4SLinus Torvalds 
17051da177e4SLinus Torvalds 	hci_dev_put(hdev);
17061da177e4SLinus Torvalds 
17071da177e4SLinus Torvalds 	return err;
17081da177e4SLinus Torvalds }
17091da177e4SLinus Torvalds 
17101da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
17111da177e4SLinus Torvalds 
1712611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1713611b30f7SMarcel Holtmann {
1714611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1715611b30f7SMarcel Holtmann 
1716611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1717611b30f7SMarcel Holtmann 
17180736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
17190736cfa8SMarcel Holtmann 		return -EBUSY;
17200736cfa8SMarcel Holtmann 
17215e130367SJohan Hedberg 	if (blocked) {
17225e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
1723bf543036SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags))
1724611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
17255e130367SJohan Hedberg 	} else {
17265e130367SJohan Hedberg 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
17275e130367SJohan Hedberg 	}
1728611b30f7SMarcel Holtmann 
1729611b30f7SMarcel Holtmann 	return 0;
1730611b30f7SMarcel Holtmann }
1731611b30f7SMarcel Holtmann 
1732611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1733611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1734611b30f7SMarcel Holtmann };
1735611b30f7SMarcel Holtmann 
1736ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1737ab81cbf9SJohan Hedberg {
1738ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
173996570ffcSJohan Hedberg 	int err;
1740ab81cbf9SJohan Hedberg 
1741ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1742ab81cbf9SJohan Hedberg 
1743cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
174496570ffcSJohan Hedberg 	if (err < 0) {
174596570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
1746ab81cbf9SJohan Hedberg 		return;
174796570ffcSJohan Hedberg 	}
1748ab81cbf9SJohan Hedberg 
1749a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
1750a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
1751a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
1752a5c8f270SMarcel Holtmann 	 */
1753a5c8f270SMarcel Holtmann 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
1754a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
1755a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1756a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
1757bf543036SJohan Hedberg 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
1758bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
1759bf543036SJohan Hedberg 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
176019202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
176119202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
1762bf543036SJohan Hedberg 	}
1763ab81cbf9SJohan Hedberg 
1764a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1765744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1766ab81cbf9SJohan Hedberg }
1767ab81cbf9SJohan Hedberg 
1768ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1769ab81cbf9SJohan Hedberg {
17703243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
17713243553fSJohan Hedberg 					    power_off.work);
1772ab81cbf9SJohan Hedberg 
1773ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1774ab81cbf9SJohan Hedberg 
17758ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1776ab81cbf9SJohan Hedberg }
1777ab81cbf9SJohan Hedberg 
177816ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
177916ab91abSJohan Hedberg {
178016ab91abSJohan Hedberg 	struct hci_dev *hdev;
178116ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
178216ab91abSJohan Hedberg 
178316ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
178416ab91abSJohan Hedberg 
178516ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
178616ab91abSJohan Hedberg 
178709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
178816ab91abSJohan Hedberg 
178916ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
179016ab91abSJohan Hedberg 
179116ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
179216ab91abSJohan Hedberg 
179309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
179416ab91abSJohan Hedberg }
179516ab91abSJohan Hedberg 
17962aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
17972aeb9a1aSJohan Hedberg {
17984821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
17992aeb9a1aSJohan Hedberg 
18004821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
18014821002cSJohan Hedberg 		list_del(&uuid->list);
18022aeb9a1aSJohan Hedberg 		kfree(uuid);
18032aeb9a1aSJohan Hedberg 	}
18042aeb9a1aSJohan Hedberg 
18052aeb9a1aSJohan Hedberg 	return 0;
18062aeb9a1aSJohan Hedberg }
18072aeb9a1aSJohan Hedberg 
180855ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
180955ed8ca1SJohan Hedberg {
181055ed8ca1SJohan Hedberg 	struct list_head *p, *n;
181155ed8ca1SJohan Hedberg 
181255ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
181355ed8ca1SJohan Hedberg 		struct link_key *key;
181455ed8ca1SJohan Hedberg 
181555ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
181655ed8ca1SJohan Hedberg 
181755ed8ca1SJohan Hedberg 		list_del(p);
181855ed8ca1SJohan Hedberg 		kfree(key);
181955ed8ca1SJohan Hedberg 	}
182055ed8ca1SJohan Hedberg 
182155ed8ca1SJohan Hedberg 	return 0;
182255ed8ca1SJohan Hedberg }
182355ed8ca1SJohan Hedberg 
1824b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1825b899efafSVinicius Costa Gomes {
1826b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1827b899efafSVinicius Costa Gomes 
1828b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1829b899efafSVinicius Costa Gomes 		list_del(&k->list);
1830b899efafSVinicius Costa Gomes 		kfree(k);
1831b899efafSVinicius Costa Gomes 	}
1832b899efafSVinicius Costa Gomes 
1833b899efafSVinicius Costa Gomes 	return 0;
1834b899efafSVinicius Costa Gomes }
1835b899efafSVinicius Costa Gomes 
183655ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
183755ed8ca1SJohan Hedberg {
183855ed8ca1SJohan Hedberg 	struct link_key *k;
183955ed8ca1SJohan Hedberg 
18408035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
184155ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
184255ed8ca1SJohan Hedberg 			return k;
184355ed8ca1SJohan Hedberg 
184455ed8ca1SJohan Hedberg 	return NULL;
184555ed8ca1SJohan Hedberg }
184655ed8ca1SJohan Hedberg 
1847745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1848d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1849d25e28abSJohan Hedberg {
1850d25e28abSJohan Hedberg 	/* Legacy key */
1851d25e28abSJohan Hedberg 	if (key_type < 0x03)
1852745c0ce3SVishal Agarwal 		return true;
1853d25e28abSJohan Hedberg 
1854d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1855d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1856745c0ce3SVishal Agarwal 		return false;
1857d25e28abSJohan Hedberg 
1858d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1859d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1860745c0ce3SVishal Agarwal 		return false;
1861d25e28abSJohan Hedberg 
1862d25e28abSJohan Hedberg 	/* Security mode 3 case */
1863d25e28abSJohan Hedberg 	if (!conn)
1864745c0ce3SVishal Agarwal 		return true;
1865d25e28abSJohan Hedberg 
1866d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1867d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1868745c0ce3SVishal Agarwal 		return true;
1869d25e28abSJohan Hedberg 
1870d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1871d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1872745c0ce3SVishal Agarwal 		return true;
1873d25e28abSJohan Hedberg 
1874d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1875d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1876745c0ce3SVishal Agarwal 		return true;
1877d25e28abSJohan Hedberg 
1878d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1879d25e28abSJohan Hedberg 	 * persistently */
1880745c0ce3SVishal Agarwal 	return false;
1881d25e28abSJohan Hedberg }
1882d25e28abSJohan Hedberg 
1883c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
188475d262c2SVinicius Costa Gomes {
1885c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
188675d262c2SVinicius Costa Gomes 
1887c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1888c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1889c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
189075d262c2SVinicius Costa Gomes 			continue;
189175d262c2SVinicius Costa Gomes 
189275d262c2SVinicius Costa Gomes 		return k;
189375d262c2SVinicius Costa Gomes 	}
189475d262c2SVinicius Costa Gomes 
189575d262c2SVinicius Costa Gomes 	return NULL;
189675d262c2SVinicius Costa Gomes }
189775d262c2SVinicius Costa Gomes 
1898c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1899c9839a11SVinicius Costa Gomes 				     u8 addr_type)
190075d262c2SVinicius Costa Gomes {
1901c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
190275d262c2SVinicius Costa Gomes 
1903c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1904c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1905c9839a11SVinicius Costa Gomes 		    bacmp(bdaddr, &k->bdaddr) == 0)
190675d262c2SVinicius Costa Gomes 			return k;
190775d262c2SVinicius Costa Gomes 
190875d262c2SVinicius Costa Gomes 	return NULL;
190975d262c2SVinicius Costa Gomes }
191075d262c2SVinicius Costa Gomes 
1911d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1912d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
191355ed8ca1SJohan Hedberg {
191455ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1915745c0ce3SVishal Agarwal 	u8 old_key_type;
1916745c0ce3SVishal Agarwal 	bool persistent;
191755ed8ca1SJohan Hedberg 
191855ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
191955ed8ca1SJohan Hedberg 	if (old_key) {
192055ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
192155ed8ca1SJohan Hedberg 		key = old_key;
192255ed8ca1SJohan Hedberg 	} else {
192312adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
192455ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
192555ed8ca1SJohan Hedberg 		if (!key)
192655ed8ca1SJohan Hedberg 			return -ENOMEM;
192755ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
192855ed8ca1SJohan Hedberg 	}
192955ed8ca1SJohan Hedberg 
19306ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
193155ed8ca1SJohan Hedberg 
1932d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1933d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1934d25e28abSJohan Hedberg 	 * previous key */
1935d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1936a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1937d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1938655fe6ecSJohan Hedberg 		if (conn)
1939655fe6ecSJohan Hedberg 			conn->key_type = type;
1940655fe6ecSJohan Hedberg 	}
1941d25e28abSJohan Hedberg 
194255ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
19439b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
194455ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
194555ed8ca1SJohan Hedberg 
1946b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
194755ed8ca1SJohan Hedberg 		key->type = old_key_type;
19484748fed2SJohan Hedberg 	else
19494748fed2SJohan Hedberg 		key->type = type;
19504748fed2SJohan Hedberg 
19514df378a1SJohan Hedberg 	if (!new_key)
19524df378a1SJohan Hedberg 		return 0;
19534df378a1SJohan Hedberg 
19544df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
19554df378a1SJohan Hedberg 
1956744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
19574df378a1SJohan Hedberg 
19586ec5bcadSVishal Agarwal 	if (conn)
19596ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
196055ed8ca1SJohan Hedberg 
196155ed8ca1SJohan Hedberg 	return 0;
196255ed8ca1SJohan Hedberg }
196355ed8ca1SJohan Hedberg 
1964c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
19659a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
196604124681SGustavo F. Padovan 		ediv, u8 rand[8])
196775d262c2SVinicius Costa Gomes {
1968c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
196975d262c2SVinicius Costa Gomes 
1970c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1971c9839a11SVinicius Costa Gomes 		return 0;
197275d262c2SVinicius Costa Gomes 
1973c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1974c9839a11SVinicius Costa Gomes 	if (old_key)
197575d262c2SVinicius Costa Gomes 		key = old_key;
1976c9839a11SVinicius Costa Gomes 	else {
1977c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
197875d262c2SVinicius Costa Gomes 		if (!key)
197975d262c2SVinicius Costa Gomes 			return -ENOMEM;
1980c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
198175d262c2SVinicius Costa Gomes 	}
198275d262c2SVinicius Costa Gomes 
198375d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1984c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1985c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1986c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1987c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1988c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1989c9839a11SVinicius Costa Gomes 	key->type = type;
1990c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
199175d262c2SVinicius Costa Gomes 
1992c9839a11SVinicius Costa Gomes 	if (!new_key)
1993c9839a11SVinicius Costa Gomes 		return 0;
199475d262c2SVinicius Costa Gomes 
1995261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1996261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1997261cc5aaSVinicius Costa Gomes 
199875d262c2SVinicius Costa Gomes 	return 0;
199975d262c2SVinicius Costa Gomes }
200075d262c2SVinicius Costa Gomes 
200155ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
200255ed8ca1SJohan Hedberg {
200355ed8ca1SJohan Hedberg 	struct link_key *key;
200455ed8ca1SJohan Hedberg 
200555ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
200655ed8ca1SJohan Hedberg 	if (!key)
200755ed8ca1SJohan Hedberg 		return -ENOENT;
200855ed8ca1SJohan Hedberg 
20096ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
201055ed8ca1SJohan Hedberg 
201155ed8ca1SJohan Hedberg 	list_del(&key->list);
201255ed8ca1SJohan Hedberg 	kfree(key);
201355ed8ca1SJohan Hedberg 
201455ed8ca1SJohan Hedberg 	return 0;
201555ed8ca1SJohan Hedberg }
201655ed8ca1SJohan Hedberg 
2017b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
2018b899efafSVinicius Costa Gomes {
2019b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
2020b899efafSVinicius Costa Gomes 
2021b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2022b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
2023b899efafSVinicius Costa Gomes 			continue;
2024b899efafSVinicius Costa Gomes 
20256ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2026b899efafSVinicius Costa Gomes 
2027b899efafSVinicius Costa Gomes 		list_del(&k->list);
2028b899efafSVinicius Costa Gomes 		kfree(k);
2029b899efafSVinicius Costa Gomes 	}
2030b899efafSVinicius Costa Gomes 
2031b899efafSVinicius Costa Gomes 	return 0;
2032b899efafSVinicius Costa Gomes }
2033b899efafSVinicius Costa Gomes 
20346bd32326SVille Tervo /* HCI command timer function */
2035bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
20366bd32326SVille Tervo {
20376bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
20386bd32326SVille Tervo 
2039bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2040bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2041bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2042bda4f23aSAndrei Emeltchenko 
2043bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
2044bda4f23aSAndrei Emeltchenko 	} else {
20456bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
2046bda4f23aSAndrei Emeltchenko 	}
2047bda4f23aSAndrei Emeltchenko 
20486bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2049c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
20506bd32326SVille Tervo }
20516bd32326SVille Tervo 
20522763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
20532763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
20542763eda6SSzymon Janc {
20552763eda6SSzymon Janc 	struct oob_data *data;
20562763eda6SSzymon Janc 
20572763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
20582763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
20592763eda6SSzymon Janc 			return data;
20602763eda6SSzymon Janc 
20612763eda6SSzymon Janc 	return NULL;
20622763eda6SSzymon Janc }
20632763eda6SSzymon Janc 
20642763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
20652763eda6SSzymon Janc {
20662763eda6SSzymon Janc 	struct oob_data *data;
20672763eda6SSzymon Janc 
20682763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
20692763eda6SSzymon Janc 	if (!data)
20702763eda6SSzymon Janc 		return -ENOENT;
20712763eda6SSzymon Janc 
20726ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
20732763eda6SSzymon Janc 
20742763eda6SSzymon Janc 	list_del(&data->list);
20752763eda6SSzymon Janc 	kfree(data);
20762763eda6SSzymon Janc 
20772763eda6SSzymon Janc 	return 0;
20782763eda6SSzymon Janc }
20792763eda6SSzymon Janc 
20802763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
20812763eda6SSzymon Janc {
20822763eda6SSzymon Janc 	struct oob_data *data, *n;
20832763eda6SSzymon Janc 
20842763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
20852763eda6SSzymon Janc 		list_del(&data->list);
20862763eda6SSzymon Janc 		kfree(data);
20872763eda6SSzymon Janc 	}
20882763eda6SSzymon Janc 
20892763eda6SSzymon Janc 	return 0;
20902763eda6SSzymon Janc }
20912763eda6SSzymon Janc 
20922763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
20932763eda6SSzymon Janc 			    u8 *randomizer)
20942763eda6SSzymon Janc {
20952763eda6SSzymon Janc 	struct oob_data *data;
20962763eda6SSzymon Janc 
20972763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
20982763eda6SSzymon Janc 
20992763eda6SSzymon Janc 	if (!data) {
21002763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
21012763eda6SSzymon Janc 		if (!data)
21022763eda6SSzymon Janc 			return -ENOMEM;
21032763eda6SSzymon Janc 
21042763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
21052763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
21062763eda6SSzymon Janc 	}
21072763eda6SSzymon Janc 
21082763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
21092763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
21102763eda6SSzymon Janc 
21116ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
21122763eda6SSzymon Janc 
21132763eda6SSzymon Janc 	return 0;
21142763eda6SSzymon Janc }
21152763eda6SSzymon Janc 
211604124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
2117b2a66aadSAntti Julku {
2118b2a66aadSAntti Julku 	struct bdaddr_list *b;
2119b2a66aadSAntti Julku 
21208035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
2121b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
2122b2a66aadSAntti Julku 			return b;
2123b2a66aadSAntti Julku 
2124b2a66aadSAntti Julku 	return NULL;
2125b2a66aadSAntti Julku }
2126b2a66aadSAntti Julku 
2127b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
2128b2a66aadSAntti Julku {
2129b2a66aadSAntti Julku 	struct list_head *p, *n;
2130b2a66aadSAntti Julku 
2131b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
2132b2a66aadSAntti Julku 		struct bdaddr_list *b;
2133b2a66aadSAntti Julku 
2134b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
2135b2a66aadSAntti Julku 
2136b2a66aadSAntti Julku 		list_del(p);
2137b2a66aadSAntti Julku 		kfree(b);
2138b2a66aadSAntti Julku 	}
2139b2a66aadSAntti Julku 
2140b2a66aadSAntti Julku 	return 0;
2141b2a66aadSAntti Julku }
2142b2a66aadSAntti Julku 
214388c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2144b2a66aadSAntti Julku {
2145b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2146b2a66aadSAntti Julku 
2147b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
2148b2a66aadSAntti Julku 		return -EBADF;
2149b2a66aadSAntti Julku 
21505e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
21515e762444SAntti Julku 		return -EEXIST;
2152b2a66aadSAntti Julku 
2153b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
21545e762444SAntti Julku 	if (!entry)
21555e762444SAntti Julku 		return -ENOMEM;
2156b2a66aadSAntti Julku 
2157b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2158b2a66aadSAntti Julku 
2159b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
2160b2a66aadSAntti Julku 
216188c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
2162b2a66aadSAntti Julku }
2163b2a66aadSAntti Julku 
216488c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2165b2a66aadSAntti Julku {
2166b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2167b2a66aadSAntti Julku 
21681ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
21695e762444SAntti Julku 		return hci_blacklist_clear(hdev);
2170b2a66aadSAntti Julku 
2171b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
21721ec918ceSSzymon Janc 	if (!entry)
21735e762444SAntti Julku 		return -ENOENT;
2174b2a66aadSAntti Julku 
2175b2a66aadSAntti Julku 	list_del(&entry->list);
2176b2a66aadSAntti Julku 	kfree(entry);
2177b2a66aadSAntti Julku 
217888c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
2179b2a66aadSAntti Julku }
2180b2a66aadSAntti Julku 
21814c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
21827ba8b4beSAndre Guedes {
21834c87eaabSAndre Guedes 	if (status) {
21844c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
21857ba8b4beSAndre Guedes 
21864c87eaabSAndre Guedes 		hci_dev_lock(hdev);
21874c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
21884c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
21894c87eaabSAndre Guedes 		return;
21904c87eaabSAndre Guedes 	}
21917ba8b4beSAndre Guedes }
21927ba8b4beSAndre Guedes 
21934c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
21947ba8b4beSAndre Guedes {
21954c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
21964c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
21974c87eaabSAndre Guedes 	struct hci_request req;
21984c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
21997ba8b4beSAndre Guedes 	int err;
22007ba8b4beSAndre Guedes 
22014c87eaabSAndre Guedes 	if (status) {
22024c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
22034c87eaabSAndre Guedes 		return;
22047ba8b4beSAndre Guedes 	}
22057ba8b4beSAndre Guedes 
22064c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
22074c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
22084c87eaabSAndre Guedes 		hci_dev_lock(hdev);
22094c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
22104c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
22114c87eaabSAndre Guedes 		break;
22127dbfac1dSAndre Guedes 
22134c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
22144c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
22157dbfac1dSAndre Guedes 
22167dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
22174c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
22184c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
22194c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
22204c87eaabSAndre Guedes 
22214c87eaabSAndre Guedes 		hci_dev_lock(hdev);
22224c87eaabSAndre Guedes 
22234c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
22244c87eaabSAndre Guedes 
22254c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
22264c87eaabSAndre Guedes 		if (err) {
22274c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
22284c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
22297dbfac1dSAndre Guedes 		}
22307dbfac1dSAndre Guedes 
22314c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
22324c87eaabSAndre Guedes 		break;
22334c87eaabSAndre Guedes 	}
22347dbfac1dSAndre Guedes }
22357dbfac1dSAndre Guedes 
22367ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
22377ba8b4beSAndre Guedes {
22387ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
22397ba8b4beSAndre Guedes 					    le_scan_disable.work);
22407ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
22414c87eaabSAndre Guedes 	struct hci_request req;
22424c87eaabSAndre Guedes 	int err;
22437ba8b4beSAndre Guedes 
22447ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
22457ba8b4beSAndre Guedes 
22464c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
22477ba8b4beSAndre Guedes 
22487ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
22494c87eaabSAndre Guedes 	cp.enable = LE_SCAN_DISABLE;
22504c87eaabSAndre Guedes 	hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
22517ba8b4beSAndre Guedes 
22524c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
22534c87eaabSAndre Guedes 	if (err)
22544c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
225528b75a89SAndre Guedes }
225628b75a89SAndre Guedes 
22579be0dab7SDavid Herrmann /* Alloc HCI device */
22589be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
22599be0dab7SDavid Herrmann {
22609be0dab7SDavid Herrmann 	struct hci_dev *hdev;
22619be0dab7SDavid Herrmann 
22629be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
22639be0dab7SDavid Herrmann 	if (!hdev)
22649be0dab7SDavid Herrmann 		return NULL;
22659be0dab7SDavid Herrmann 
2266b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2267b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
2268b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
2269b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03; /* No Input No Output */
2270bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2271bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2272b1b813d4SDavid Herrmann 
2273b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
2274b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
2275b1b813d4SDavid Herrmann 
2276b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
2277b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
2278b1b813d4SDavid Herrmann 
2279b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
2280b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
2281b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
2282b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
2283b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
2284b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
22856b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
2286b1b813d4SDavid Herrmann 
2287b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2288b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2289b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2290b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2291b1b813d4SDavid Herrmann 
2292b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2293b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
2294b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
2295b1b813d4SDavid Herrmann 
2296b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2297b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2298b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2299b1b813d4SDavid Herrmann 
2300b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2301b1b813d4SDavid Herrmann 
2302bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
2303b1b813d4SDavid Herrmann 
2304b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2305b1b813d4SDavid Herrmann 	discovery_init(hdev);
23069be0dab7SDavid Herrmann 
23079be0dab7SDavid Herrmann 	return hdev;
23089be0dab7SDavid Herrmann }
23099be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
23109be0dab7SDavid Herrmann 
23119be0dab7SDavid Herrmann /* Free HCI device */
23129be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
23139be0dab7SDavid Herrmann {
23149be0dab7SDavid Herrmann 	/* will free via device release */
23159be0dab7SDavid Herrmann 	put_device(&hdev->dev);
23169be0dab7SDavid Herrmann }
23179be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
23189be0dab7SDavid Herrmann 
23191da177e4SLinus Torvalds /* Register HCI device */
23201da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
23211da177e4SLinus Torvalds {
2322b1b813d4SDavid Herrmann 	int id, error;
23231da177e4SLinus Torvalds 
2324010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
23251da177e4SLinus Torvalds 		return -EINVAL;
23261da177e4SLinus Torvalds 
232708add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
232808add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
232908add513SMat Martineau 	 */
23303df92b31SSasha Levin 	switch (hdev->dev_type) {
23313df92b31SSasha Levin 	case HCI_BREDR:
23323df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
23331da177e4SLinus Torvalds 		break;
23343df92b31SSasha Levin 	case HCI_AMP:
23353df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
23363df92b31SSasha Levin 		break;
23373df92b31SSasha Levin 	default:
23383df92b31SSasha Levin 		return -EINVAL;
23391da177e4SLinus Torvalds 	}
23401da177e4SLinus Torvalds 
23413df92b31SSasha Levin 	if (id < 0)
23423df92b31SSasha Levin 		return id;
23433df92b31SSasha Levin 
23441da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
23451da177e4SLinus Torvalds 	hdev->id = id;
23462d8b3a11SAndrei Emeltchenko 
23472d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
23482d8b3a11SAndrei Emeltchenko 
2349d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
2350d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
235133ca954dSDavid Herrmann 	if (!hdev->workqueue) {
235233ca954dSDavid Herrmann 		error = -ENOMEM;
235333ca954dSDavid Herrmann 		goto err;
235433ca954dSDavid Herrmann 	}
2355f48fd9c8SMarcel Holtmann 
2356d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
2357d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
23586ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
23596ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
23606ead1bbcSJohan Hedberg 		error = -ENOMEM;
23616ead1bbcSJohan Hedberg 		goto err;
23626ead1bbcSJohan Hedberg 	}
23636ead1bbcSJohan Hedberg 
236433ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
236533ca954dSDavid Herrmann 	if (error < 0)
236633ca954dSDavid Herrmann 		goto err_wqueue;
23671da177e4SLinus Torvalds 
2368611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2369a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2370a8c5fb1aSGustavo Padovan 				    hdev);
2371611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2372611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
2373611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
2374611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
2375611b30f7SMarcel Holtmann 		}
2376611b30f7SMarcel Holtmann 	}
2377611b30f7SMarcel Holtmann 
23785e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
23795e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
23805e130367SJohan Hedberg 
2381a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
2382004b0258SMarcel Holtmann 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2383ce2be9acSAndrei Emeltchenko 
238401cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
238556f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
238656f87901SJohan Hedberg 		 * through reading supported features during init.
238756f87901SJohan Hedberg 		 */
238856f87901SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
238956f87901SJohan Hedberg 	}
2390ce2be9acSAndrei Emeltchenko 
2391fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
2392fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
2393fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
2394fcee3377SGustavo Padovan 
23951da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
2396dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
23971da177e4SLinus Torvalds 
239819202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2399fbe96d6fSMarcel Holtmann 
24001da177e4SLinus Torvalds 	return id;
2401f48fd9c8SMarcel Holtmann 
240233ca954dSDavid Herrmann err_wqueue:
240333ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
24046ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
240533ca954dSDavid Herrmann err:
24063df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
2407f48fd9c8SMarcel Holtmann 
240833ca954dSDavid Herrmann 	return error;
24091da177e4SLinus Torvalds }
24101da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
24111da177e4SLinus Torvalds 
24121da177e4SLinus Torvalds /* Unregister HCI device */
241359735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
24141da177e4SLinus Torvalds {
24153df92b31SSasha Levin 	int i, id;
2416ef222013SMarcel Holtmann 
2417c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
24181da177e4SLinus Torvalds 
241994324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
242094324962SJohan Hovold 
24213df92b31SSasha Levin 	id = hdev->id;
24223df92b31SSasha Levin 
2423f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
24241da177e4SLinus Torvalds 	list_del(&hdev->list);
2425f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
24261da177e4SLinus Torvalds 
24271da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
24281da177e4SLinus Torvalds 
2429cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
2430ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
2431ef222013SMarcel Holtmann 
2432b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
2433b9b5ef18SGustavo Padovan 
2434ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2435a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
243609fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2437744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
243809fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
243956e5cb86SJohan Hedberg 	}
2440ab81cbf9SJohan Hedberg 
24412e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
24422e58ef3eSJohan Hedberg 	 * pending list */
24432e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
24442e58ef3eSJohan Hedberg 
24451da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
24461da177e4SLinus Torvalds 
2447611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2448611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2449611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2450611b30f7SMarcel Holtmann 	}
2451611b30f7SMarcel Holtmann 
2452ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
2453147e2d59SDave Young 
2454f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
24556ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2456f48fd9c8SMarcel Holtmann 
245709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
2458e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
24592aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
246055ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2461b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
24622763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
246309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2464e2e0cacbSJohan Hedberg 
2465dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
24663df92b31SSasha Levin 
24673df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
24681da177e4SLinus Torvalds }
24691da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
24701da177e4SLinus Torvalds 
24711da177e4SLinus Torvalds /* Suspend HCI device */
24721da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
24731da177e4SLinus Torvalds {
24741da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
24751da177e4SLinus Torvalds 	return 0;
24761da177e4SLinus Torvalds }
24771da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
24781da177e4SLinus Torvalds 
24791da177e4SLinus Torvalds /* Resume HCI device */
24801da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
24811da177e4SLinus Torvalds {
24821da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
24831da177e4SLinus Torvalds 	return 0;
24841da177e4SLinus Torvalds }
24851da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
24861da177e4SLinus Torvalds 
248776bca880SMarcel Holtmann /* Receive frame from HCI drivers */
2488e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
248976bca880SMarcel Holtmann {
249076bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
249176bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
249276bca880SMarcel Holtmann 		kfree_skb(skb);
249376bca880SMarcel Holtmann 		return -ENXIO;
249476bca880SMarcel Holtmann 	}
249576bca880SMarcel Holtmann 
2496d82603c6SJorrit Schippers 	/* Incoming skb */
249776bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
249876bca880SMarcel Holtmann 
249976bca880SMarcel Holtmann 	/* Time stamp */
250076bca880SMarcel Holtmann 	__net_timestamp(skb);
250176bca880SMarcel Holtmann 
250276bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2503b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2504c78ae283SMarcel Holtmann 
250576bca880SMarcel Holtmann 	return 0;
250676bca880SMarcel Holtmann }
250776bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
250876bca880SMarcel Holtmann 
250933e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
25101e429f38SGustavo F. Padovan 			  int count, __u8 index)
251133e882a5SSuraj Sumangala {
251233e882a5SSuraj Sumangala 	int len = 0;
251333e882a5SSuraj Sumangala 	int hlen = 0;
251433e882a5SSuraj Sumangala 	int remain = count;
251533e882a5SSuraj Sumangala 	struct sk_buff *skb;
251633e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
251733e882a5SSuraj Sumangala 
251833e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
251933e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
252033e882a5SSuraj Sumangala 		return -EILSEQ;
252133e882a5SSuraj Sumangala 
252233e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
252333e882a5SSuraj Sumangala 
252433e882a5SSuraj Sumangala 	if (!skb) {
252533e882a5SSuraj Sumangala 		switch (type) {
252633e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
252733e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
252833e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
252933e882a5SSuraj Sumangala 			break;
253033e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
253133e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
253233e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
253333e882a5SSuraj Sumangala 			break;
253433e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
253533e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
253633e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
253733e882a5SSuraj Sumangala 			break;
253833e882a5SSuraj Sumangala 		}
253933e882a5SSuraj Sumangala 
25401e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
254133e882a5SSuraj Sumangala 		if (!skb)
254233e882a5SSuraj Sumangala 			return -ENOMEM;
254333e882a5SSuraj Sumangala 
254433e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
254533e882a5SSuraj Sumangala 		scb->expect = hlen;
254633e882a5SSuraj Sumangala 		scb->pkt_type = type;
254733e882a5SSuraj Sumangala 
254833e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
254933e882a5SSuraj Sumangala 	}
255033e882a5SSuraj Sumangala 
255133e882a5SSuraj Sumangala 	while (count) {
255233e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
255389bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
255433e882a5SSuraj Sumangala 
255533e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
255633e882a5SSuraj Sumangala 
255733e882a5SSuraj Sumangala 		count -= len;
255833e882a5SSuraj Sumangala 		data += len;
255933e882a5SSuraj Sumangala 		scb->expect -= len;
256033e882a5SSuraj Sumangala 		remain = count;
256133e882a5SSuraj Sumangala 
256233e882a5SSuraj Sumangala 		switch (type) {
256333e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
256433e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
256533e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
256633e882a5SSuraj Sumangala 				scb->expect = h->plen;
256733e882a5SSuraj Sumangala 
256833e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
256933e882a5SSuraj Sumangala 					kfree_skb(skb);
257033e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
257133e882a5SSuraj Sumangala 					return -ENOMEM;
257233e882a5SSuraj Sumangala 				}
257333e882a5SSuraj Sumangala 			}
257433e882a5SSuraj Sumangala 			break;
257533e882a5SSuraj Sumangala 
257633e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
257733e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
257833e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
257933e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
258033e882a5SSuraj Sumangala 
258133e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
258233e882a5SSuraj Sumangala 					kfree_skb(skb);
258333e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
258433e882a5SSuraj Sumangala 					return -ENOMEM;
258533e882a5SSuraj Sumangala 				}
258633e882a5SSuraj Sumangala 			}
258733e882a5SSuraj Sumangala 			break;
258833e882a5SSuraj Sumangala 
258933e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
259033e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
259133e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
259233e882a5SSuraj Sumangala 				scb->expect = h->dlen;
259333e882a5SSuraj Sumangala 
259433e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
259533e882a5SSuraj Sumangala 					kfree_skb(skb);
259633e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
259733e882a5SSuraj Sumangala 					return -ENOMEM;
259833e882a5SSuraj Sumangala 				}
259933e882a5SSuraj Sumangala 			}
260033e882a5SSuraj Sumangala 			break;
260133e882a5SSuraj Sumangala 		}
260233e882a5SSuraj Sumangala 
260333e882a5SSuraj Sumangala 		if (scb->expect == 0) {
260433e882a5SSuraj Sumangala 			/* Complete frame */
260533e882a5SSuraj Sumangala 
260633e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
2607e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
260833e882a5SSuraj Sumangala 
260933e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
261033e882a5SSuraj Sumangala 			return remain;
261133e882a5SSuraj Sumangala 		}
261233e882a5SSuraj Sumangala 	}
261333e882a5SSuraj Sumangala 
261433e882a5SSuraj Sumangala 	return remain;
261533e882a5SSuraj Sumangala }
261633e882a5SSuraj Sumangala 
2617ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
2618ef222013SMarcel Holtmann {
2619f39a3c06SSuraj Sumangala 	int rem = 0;
2620f39a3c06SSuraj Sumangala 
2621ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
2622ef222013SMarcel Holtmann 		return -EILSEQ;
2623ef222013SMarcel Holtmann 
2624da5f6c37SGustavo F. Padovan 	while (count) {
26251e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
2626f39a3c06SSuraj Sumangala 		if (rem < 0)
2627f39a3c06SSuraj Sumangala 			return rem;
2628ef222013SMarcel Holtmann 
2629f39a3c06SSuraj Sumangala 		data += (count - rem);
2630f39a3c06SSuraj Sumangala 		count = rem;
2631f81c6224SJoe Perches 	}
2632ef222013SMarcel Holtmann 
2633f39a3c06SSuraj Sumangala 	return rem;
2634ef222013SMarcel Holtmann }
2635ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
2636ef222013SMarcel Holtmann 
263799811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
263899811510SSuraj Sumangala 
263999811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
264099811510SSuraj Sumangala {
264199811510SSuraj Sumangala 	int type;
264299811510SSuraj Sumangala 	int rem = 0;
264399811510SSuraj Sumangala 
2644da5f6c37SGustavo F. Padovan 	while (count) {
264599811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
264699811510SSuraj Sumangala 
264799811510SSuraj Sumangala 		if (!skb) {
264899811510SSuraj Sumangala 			struct { char type; } *pkt;
264999811510SSuraj Sumangala 
265099811510SSuraj Sumangala 			/* Start of the frame */
265199811510SSuraj Sumangala 			pkt = data;
265299811510SSuraj Sumangala 			type = pkt->type;
265399811510SSuraj Sumangala 
265499811510SSuraj Sumangala 			data++;
265599811510SSuraj Sumangala 			count--;
265699811510SSuraj Sumangala 		} else
265799811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
265899811510SSuraj Sumangala 
26591e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
26601e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
266199811510SSuraj Sumangala 		if (rem < 0)
266299811510SSuraj Sumangala 			return rem;
266399811510SSuraj Sumangala 
266499811510SSuraj Sumangala 		data += (count - rem);
266599811510SSuraj Sumangala 		count = rem;
2666f81c6224SJoe Perches 	}
266799811510SSuraj Sumangala 
266899811510SSuraj Sumangala 	return rem;
266999811510SSuraj Sumangala }
267099811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
267199811510SSuraj Sumangala 
26721da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
26731da177e4SLinus Torvalds 
26741da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
26751da177e4SLinus Torvalds {
26761da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
26771da177e4SLinus Torvalds 
2678f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
26791da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2680f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
26811da177e4SLinus Torvalds 
26821da177e4SLinus Torvalds 	return 0;
26831da177e4SLinus Torvalds }
26841da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
26851da177e4SLinus Torvalds 
26861da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
26871da177e4SLinus Torvalds {
26881da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
26891da177e4SLinus Torvalds 
2690f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
26911da177e4SLinus Torvalds 	list_del(&cb->list);
2692f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
26931da177e4SLinus Torvalds 
26941da177e4SLinus Torvalds 	return 0;
26951da177e4SLinus Torvalds }
26961da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
26971da177e4SLinus Torvalds 
269851086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
26991da177e4SLinus Torvalds {
27000d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
27011da177e4SLinus Torvalds 
27021da177e4SLinus Torvalds 	/* Time stamp */
2703a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
27041da177e4SLinus Torvalds 
2705cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2706cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2707cd82e61cSMarcel Holtmann 
2708cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2709cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2710470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
27111da177e4SLinus Torvalds 	}
27121da177e4SLinus Torvalds 
27131da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
27141da177e4SLinus Torvalds 	skb_orphan(skb);
27151da177e4SLinus Torvalds 
271657d17d70SMarcel Holtmann 	skb->dev = (void *) hdev;
271757d17d70SMarcel Holtmann 
271851086991SMarcel Holtmann 	if (hdev->send(skb) < 0)
271951086991SMarcel Holtmann 		BT_ERR("%s sending frame failed", hdev->name);
27201da177e4SLinus Torvalds }
27211da177e4SLinus Torvalds 
27223119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
27233119ae95SJohan Hedberg {
27243119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
27253119ae95SJohan Hedberg 	req->hdev = hdev;
27265d73e034SAndre Guedes 	req->err = 0;
27273119ae95SJohan Hedberg }
27283119ae95SJohan Hedberg 
27293119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
27303119ae95SJohan Hedberg {
27313119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
27323119ae95SJohan Hedberg 	struct sk_buff *skb;
27333119ae95SJohan Hedberg 	unsigned long flags;
27343119ae95SJohan Hedberg 
27353119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
27363119ae95SJohan Hedberg 
27375d73e034SAndre Guedes 	/* If an error occured during request building, remove all HCI
27385d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
27395d73e034SAndre Guedes 	 */
27405d73e034SAndre Guedes 	if (req->err) {
27415d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
27425d73e034SAndre Guedes 		return req->err;
27435d73e034SAndre Guedes 	}
27445d73e034SAndre Guedes 
27453119ae95SJohan Hedberg 	/* Do not allow empty requests */
27463119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
2747382b0c39SAndre Guedes 		return -ENODATA;
27483119ae95SJohan Hedberg 
27493119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
27503119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
27513119ae95SJohan Hedberg 
27523119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
27533119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
27543119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
27553119ae95SJohan Hedberg 
27563119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
27573119ae95SJohan Hedberg 
27583119ae95SJohan Hedberg 	return 0;
27593119ae95SJohan Hedberg }
27603119ae95SJohan Hedberg 
27611ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
276207dc93ddSJohan Hedberg 				       u32 plen, const void *param)
27631da177e4SLinus Torvalds {
27641da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
27651da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
27661da177e4SLinus Torvalds 	struct sk_buff *skb;
27671da177e4SLinus Torvalds 
27681da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
27691ca3a9d0SJohan Hedberg 	if (!skb)
27701ca3a9d0SJohan Hedberg 		return NULL;
27711da177e4SLinus Torvalds 
27721da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2773a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
27741da177e4SLinus Torvalds 	hdr->plen   = plen;
27751da177e4SLinus Torvalds 
27761da177e4SLinus Torvalds 	if (plen)
27771da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
27781da177e4SLinus Torvalds 
27791da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
27801da177e4SLinus Torvalds 
27810d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
2782c78ae283SMarcel Holtmann 
27831ca3a9d0SJohan Hedberg 	return skb;
27841ca3a9d0SJohan Hedberg }
27851ca3a9d0SJohan Hedberg 
27861ca3a9d0SJohan Hedberg /* Send HCI command */
278707dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
278807dc93ddSJohan Hedberg 		 const void *param)
27891ca3a9d0SJohan Hedberg {
27901ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
27911ca3a9d0SJohan Hedberg 
27921ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
27931ca3a9d0SJohan Hedberg 
27941ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
27951ca3a9d0SJohan Hedberg 	if (!skb) {
27961ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
27971ca3a9d0SJohan Hedberg 		return -ENOMEM;
27981ca3a9d0SJohan Hedberg 	}
27991ca3a9d0SJohan Hedberg 
280011714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
280111714b3dSJohan Hedberg 	 * single-command requests.
280211714b3dSJohan Hedberg 	 */
280311714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
280411714b3dSJohan Hedberg 
28051da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2806c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
28071da177e4SLinus Torvalds 
28081da177e4SLinus Torvalds 	return 0;
28091da177e4SLinus Torvalds }
28101da177e4SLinus Torvalds 
281171c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
281207dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
281307dc93ddSJohan Hedberg 		    const void *param, u8 event)
281471c76a17SJohan Hedberg {
281571c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
281671c76a17SJohan Hedberg 	struct sk_buff *skb;
281771c76a17SJohan Hedberg 
281871c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
281971c76a17SJohan Hedberg 
282034739c1eSAndre Guedes 	/* If an error occured during request building, there is no point in
282134739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
282234739c1eSAndre Guedes 	 */
282334739c1eSAndre Guedes 	if (req->err)
282434739c1eSAndre Guedes 		return;
282534739c1eSAndre Guedes 
282671c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
282771c76a17SJohan Hedberg 	if (!skb) {
28285d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
28295d73e034SAndre Guedes 		       hdev->name, opcode);
28305d73e034SAndre Guedes 		req->err = -ENOMEM;
2831e348fe6bSAndre Guedes 		return;
283271c76a17SJohan Hedberg 	}
283371c76a17SJohan Hedberg 
283471c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
283571c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
283671c76a17SJohan Hedberg 
283702350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
283802350a72SJohan Hedberg 
283971c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
284071c76a17SJohan Hedberg }
284171c76a17SJohan Hedberg 
284207dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
284307dc93ddSJohan Hedberg 		 const void *param)
284402350a72SJohan Hedberg {
284502350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
284602350a72SJohan Hedberg }
284702350a72SJohan Hedberg 
28481da177e4SLinus Torvalds /* Get data from the previously sent command */
2849a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
28501da177e4SLinus Torvalds {
28511da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
28521da177e4SLinus Torvalds 
28531da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
28541da177e4SLinus Torvalds 		return NULL;
28551da177e4SLinus Torvalds 
28561da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
28571da177e4SLinus Torvalds 
2858a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
28591da177e4SLinus Torvalds 		return NULL;
28601da177e4SLinus Torvalds 
2861f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
28621da177e4SLinus Torvalds 
28631da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
28641da177e4SLinus Torvalds }
28651da177e4SLinus Torvalds 
28661da177e4SLinus Torvalds /* Send ACL data */
28671da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
28681da177e4SLinus Torvalds {
28691da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
28701da177e4SLinus Torvalds 	int len = skb->len;
28711da177e4SLinus Torvalds 
2872badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2873badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
28749c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2875aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2876aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
28771da177e4SLinus Torvalds }
28781da177e4SLinus Torvalds 
2879ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
288073d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
28811da177e4SLinus Torvalds {
2882ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
28831da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
28841da177e4SLinus Torvalds 	struct sk_buff *list;
28851da177e4SLinus Torvalds 
2886087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
2887087bfd99SGustavo Padovan 	skb->data_len = 0;
2888087bfd99SGustavo Padovan 
2889087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2890204a6e54SAndrei Emeltchenko 
2891204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
2892204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
2893087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
2894204a6e54SAndrei Emeltchenko 		break;
2895204a6e54SAndrei Emeltchenko 	case HCI_AMP:
2896204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
2897204a6e54SAndrei Emeltchenko 		break;
2898204a6e54SAndrei Emeltchenko 	default:
2899204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2900204a6e54SAndrei Emeltchenko 		return;
2901204a6e54SAndrei Emeltchenko 	}
2902087bfd99SGustavo Padovan 
290370f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
290470f23020SAndrei Emeltchenko 	if (!list) {
29051da177e4SLinus Torvalds 		/* Non fragmented */
29061da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
29071da177e4SLinus Torvalds 
290873d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
29091da177e4SLinus Torvalds 	} else {
29101da177e4SLinus Torvalds 		/* Fragmented */
29111da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
29121da177e4SLinus Torvalds 
29131da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
29141da177e4SLinus Torvalds 
29151da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2916af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
29171da177e4SLinus Torvalds 
291873d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2919e702112fSAndrei Emeltchenko 
2920e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2921e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
29221da177e4SLinus Torvalds 		do {
29231da177e4SLinus Torvalds 			skb = list; list = list->next;
29241da177e4SLinus Torvalds 
29250d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2926e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
29271da177e4SLinus Torvalds 
29281da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
29291da177e4SLinus Torvalds 
293073d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
29311da177e4SLinus Torvalds 		} while (list);
29321da177e4SLinus Torvalds 
2933af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
29341da177e4SLinus Torvalds 	}
293573d80debSLuiz Augusto von Dentz }
293673d80debSLuiz Augusto von Dentz 
293773d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
293873d80debSLuiz Augusto von Dentz {
2939ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
294073d80debSLuiz Augusto von Dentz 
2941f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
294273d80debSLuiz Augusto von Dentz 
2943ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
29441da177e4SLinus Torvalds 
29453eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
29461da177e4SLinus Torvalds }
29471da177e4SLinus Torvalds 
29481da177e4SLinus Torvalds /* Send SCO data */
29490d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
29501da177e4SLinus Torvalds {
29511da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
29521da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
29531da177e4SLinus Torvalds 
29541da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
29551da177e4SLinus Torvalds 
2956aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
29571da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
29581da177e4SLinus Torvalds 
2959badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2960badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
29619c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
29621da177e4SLinus Torvalds 
29630d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2964c78ae283SMarcel Holtmann 
29651da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
29663eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
29671da177e4SLinus Torvalds }
29681da177e4SLinus Torvalds 
29691da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
29701da177e4SLinus Torvalds 
29711da177e4SLinus Torvalds /* HCI Connection scheduler */
29726039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
2973a8c5fb1aSGustavo Padovan 				     int *quote)
29741da177e4SLinus Torvalds {
29751da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
29768035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
2977abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
29781da177e4SLinus Torvalds 
29791da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
29801da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2981bf4c6325SGustavo F. Padovan 
2982bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2983bf4c6325SGustavo F. Padovan 
2984bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2985769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
29861da177e4SLinus Torvalds 			continue;
2987769be974SMarcel Holtmann 
2988769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2989769be974SMarcel Holtmann 			continue;
2990769be974SMarcel Holtmann 
29911da177e4SLinus Torvalds 		num++;
29921da177e4SLinus Torvalds 
29931da177e4SLinus Torvalds 		if (c->sent < min) {
29941da177e4SLinus Torvalds 			min  = c->sent;
29951da177e4SLinus Torvalds 			conn = c;
29961da177e4SLinus Torvalds 		}
299752087a79SLuiz Augusto von Dentz 
299852087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
299952087a79SLuiz Augusto von Dentz 			break;
30001da177e4SLinus Torvalds 	}
30011da177e4SLinus Torvalds 
3002bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3003bf4c6325SGustavo F. Padovan 
30041da177e4SLinus Torvalds 	if (conn) {
30056ed58ec5SVille Tervo 		int cnt, q;
30066ed58ec5SVille Tervo 
30076ed58ec5SVille Tervo 		switch (conn->type) {
30086ed58ec5SVille Tervo 		case ACL_LINK:
30096ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
30106ed58ec5SVille Tervo 			break;
30116ed58ec5SVille Tervo 		case SCO_LINK:
30126ed58ec5SVille Tervo 		case ESCO_LINK:
30136ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
30146ed58ec5SVille Tervo 			break;
30156ed58ec5SVille Tervo 		case LE_LINK:
30166ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
30176ed58ec5SVille Tervo 			break;
30186ed58ec5SVille Tervo 		default:
30196ed58ec5SVille Tervo 			cnt = 0;
30206ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
30216ed58ec5SVille Tervo 		}
30226ed58ec5SVille Tervo 
30236ed58ec5SVille Tervo 		q = cnt / num;
30241da177e4SLinus Torvalds 		*quote = q ? q : 1;
30251da177e4SLinus Torvalds 	} else
30261da177e4SLinus Torvalds 		*quote = 0;
30271da177e4SLinus Torvalds 
30281da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
30291da177e4SLinus Torvalds 	return conn;
30301da177e4SLinus Torvalds }
30311da177e4SLinus Torvalds 
30326039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
30331da177e4SLinus Torvalds {
30341da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
30351da177e4SLinus Torvalds 	struct hci_conn *c;
30361da177e4SLinus Torvalds 
3037bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
30381da177e4SLinus Torvalds 
3039bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3040bf4c6325SGustavo F. Padovan 
30411da177e4SLinus Torvalds 	/* Kill stalled connections */
3042bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3043bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
30446ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
30456ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
3046bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
30471da177e4SLinus Torvalds 		}
30481da177e4SLinus Torvalds 	}
3049bf4c6325SGustavo F. Padovan 
3050bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
30511da177e4SLinus Torvalds }
30521da177e4SLinus Torvalds 
30536039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
305473d80debSLuiz Augusto von Dentz 				      int *quote)
305573d80debSLuiz Augusto von Dentz {
305673d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
305773d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3058abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
305973d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
306073d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
306173d80debSLuiz Augusto von Dentz 
306273d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
306373d80debSLuiz Augusto von Dentz 
3064bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3065bf4c6325SGustavo F. Padovan 
3066bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
306773d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
306873d80debSLuiz Augusto von Dentz 
306973d80debSLuiz Augusto von Dentz 		if (conn->type != type)
307073d80debSLuiz Augusto von Dentz 			continue;
307173d80debSLuiz Augusto von Dentz 
307273d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
307373d80debSLuiz Augusto von Dentz 			continue;
307473d80debSLuiz Augusto von Dentz 
307573d80debSLuiz Augusto von Dentz 		conn_num++;
307673d80debSLuiz Augusto von Dentz 
30778192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
307873d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
307973d80debSLuiz Augusto von Dentz 
308073d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
308173d80debSLuiz Augusto von Dentz 				continue;
308273d80debSLuiz Augusto von Dentz 
308373d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
308473d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
308573d80debSLuiz Augusto von Dentz 				continue;
308673d80debSLuiz Augusto von Dentz 
308773d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
308873d80debSLuiz Augusto von Dentz 				num = 0;
308973d80debSLuiz Augusto von Dentz 				min = ~0;
309073d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
309173d80debSLuiz Augusto von Dentz 			}
309273d80debSLuiz Augusto von Dentz 
309373d80debSLuiz Augusto von Dentz 			num++;
309473d80debSLuiz Augusto von Dentz 
309573d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
309673d80debSLuiz Augusto von Dentz 				min  = conn->sent;
309773d80debSLuiz Augusto von Dentz 				chan = tmp;
309873d80debSLuiz Augusto von Dentz 			}
309973d80debSLuiz Augusto von Dentz 		}
310073d80debSLuiz Augusto von Dentz 
310173d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
310273d80debSLuiz Augusto von Dentz 			break;
310373d80debSLuiz Augusto von Dentz 	}
310473d80debSLuiz Augusto von Dentz 
3105bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3106bf4c6325SGustavo F. Padovan 
310773d80debSLuiz Augusto von Dentz 	if (!chan)
310873d80debSLuiz Augusto von Dentz 		return NULL;
310973d80debSLuiz Augusto von Dentz 
311073d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
311173d80debSLuiz Augusto von Dentz 	case ACL_LINK:
311273d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
311373d80debSLuiz Augusto von Dentz 		break;
3114bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
3115bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
3116bd1eb66bSAndrei Emeltchenko 		break;
311773d80debSLuiz Augusto von Dentz 	case SCO_LINK:
311873d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
311973d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
312073d80debSLuiz Augusto von Dentz 		break;
312173d80debSLuiz Augusto von Dentz 	case LE_LINK:
312273d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
312373d80debSLuiz Augusto von Dentz 		break;
312473d80debSLuiz Augusto von Dentz 	default:
312573d80debSLuiz Augusto von Dentz 		cnt = 0;
312673d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
312773d80debSLuiz Augusto von Dentz 	}
312873d80debSLuiz Augusto von Dentz 
312973d80debSLuiz Augusto von Dentz 	q = cnt / num;
313073d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
313173d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
313273d80debSLuiz Augusto von Dentz 	return chan;
313373d80debSLuiz Augusto von Dentz }
313473d80debSLuiz Augusto von Dentz 
313502b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
313602b20f0bSLuiz Augusto von Dentz {
313702b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
313802b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
313902b20f0bSLuiz Augusto von Dentz 	int num = 0;
314002b20f0bSLuiz Augusto von Dentz 
314102b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
314202b20f0bSLuiz Augusto von Dentz 
3143bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3144bf4c6325SGustavo F. Padovan 
3145bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
314602b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
314702b20f0bSLuiz Augusto von Dentz 
314802b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
314902b20f0bSLuiz Augusto von Dentz 			continue;
315002b20f0bSLuiz Augusto von Dentz 
315102b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
315202b20f0bSLuiz Augusto von Dentz 			continue;
315302b20f0bSLuiz Augusto von Dentz 
315402b20f0bSLuiz Augusto von Dentz 		num++;
315502b20f0bSLuiz Augusto von Dentz 
31568192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
315702b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
315802b20f0bSLuiz Augusto von Dentz 
315902b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
316002b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
316102b20f0bSLuiz Augusto von Dentz 				continue;
316202b20f0bSLuiz Augusto von Dentz 			}
316302b20f0bSLuiz Augusto von Dentz 
316402b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
316502b20f0bSLuiz Augusto von Dentz 				continue;
316602b20f0bSLuiz Augusto von Dentz 
316702b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
316802b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
316902b20f0bSLuiz Augusto von Dentz 				continue;
317002b20f0bSLuiz Augusto von Dentz 
317102b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
317202b20f0bSLuiz Augusto von Dentz 
317302b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
317402b20f0bSLuiz Augusto von Dentz 			       skb->priority);
317502b20f0bSLuiz Augusto von Dentz 		}
317602b20f0bSLuiz Augusto von Dentz 
317702b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
317802b20f0bSLuiz Augusto von Dentz 			break;
317902b20f0bSLuiz Augusto von Dentz 	}
3180bf4c6325SGustavo F. Padovan 
3181bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3182bf4c6325SGustavo F. Padovan 
318302b20f0bSLuiz Augusto von Dentz }
318402b20f0bSLuiz Augusto von Dentz 
3185b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3186b71d385aSAndrei Emeltchenko {
3187b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3188b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3189b71d385aSAndrei Emeltchenko }
3190b71d385aSAndrei Emeltchenko 
31916039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
31921da177e4SLinus Torvalds {
31931da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
31941da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
31951da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
319663d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
31975f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
3198bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
31991da177e4SLinus Torvalds 	}
320063d2bc1bSAndrei Emeltchenko }
32011da177e4SLinus Torvalds 
32026039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
320363d2bc1bSAndrei Emeltchenko {
320463d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
320563d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
320663d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
320763d2bc1bSAndrei Emeltchenko 	int quote;
320863d2bc1bSAndrei Emeltchenko 
320963d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
321004837f64SMarcel Holtmann 
321173d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
321273d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3213ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3214ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
321573d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
321673d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
321773d80debSLuiz Augusto von Dentz 
3218ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3219ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3220ec1cce24SLuiz Augusto von Dentz 				break;
3221ec1cce24SLuiz Augusto von Dentz 
3222ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3223ec1cce24SLuiz Augusto von Dentz 
322473d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
322573d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
322604837f64SMarcel Holtmann 
322757d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
32281da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
32291da177e4SLinus Torvalds 
32301da177e4SLinus Torvalds 			hdev->acl_cnt--;
323173d80debSLuiz Augusto von Dentz 			chan->sent++;
323273d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
32331da177e4SLinus Torvalds 		}
32341da177e4SLinus Torvalds 	}
323502b20f0bSLuiz Augusto von Dentz 
323602b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
323702b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
32381da177e4SLinus Torvalds }
32391da177e4SLinus Torvalds 
32406039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3241b71d385aSAndrei Emeltchenko {
324263d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3243b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3244b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3245b71d385aSAndrei Emeltchenko 	int quote;
3246bd1eb66bSAndrei Emeltchenko 	u8 type;
3247b71d385aSAndrei Emeltchenko 
324863d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
3249b71d385aSAndrei Emeltchenko 
3250bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3251bd1eb66bSAndrei Emeltchenko 
3252bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3253bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3254bd1eb66bSAndrei Emeltchenko 	else
3255bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3256bd1eb66bSAndrei Emeltchenko 
3257b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3258bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3259b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3260b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3261b71d385aSAndrei Emeltchenko 			int blocks;
3262b71d385aSAndrei Emeltchenko 
3263b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3264b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3265b71d385aSAndrei Emeltchenko 
3266b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3267b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3268b71d385aSAndrei Emeltchenko 				break;
3269b71d385aSAndrei Emeltchenko 
3270b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3271b71d385aSAndrei Emeltchenko 
3272b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3273b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3274b71d385aSAndrei Emeltchenko 				return;
3275b71d385aSAndrei Emeltchenko 
3276b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3277b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3278b71d385aSAndrei Emeltchenko 
327957d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3280b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3281b71d385aSAndrei Emeltchenko 
3282b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3283b71d385aSAndrei Emeltchenko 			quote -= blocks;
3284b71d385aSAndrei Emeltchenko 
3285b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3286b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3287b71d385aSAndrei Emeltchenko 		}
3288b71d385aSAndrei Emeltchenko 	}
3289b71d385aSAndrei Emeltchenko 
3290b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3291bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3292b71d385aSAndrei Emeltchenko }
3293b71d385aSAndrei Emeltchenko 
32946039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3295b71d385aSAndrei Emeltchenko {
3296b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3297b71d385aSAndrei Emeltchenko 
3298bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3299bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
3300bd1eb66bSAndrei Emeltchenko 		return;
3301bd1eb66bSAndrei Emeltchenko 
3302bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3303bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3304b71d385aSAndrei Emeltchenko 		return;
3305b71d385aSAndrei Emeltchenko 
3306b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3307b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3308b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3309b71d385aSAndrei Emeltchenko 		break;
3310b71d385aSAndrei Emeltchenko 
3311b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3312b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3313b71d385aSAndrei Emeltchenko 		break;
3314b71d385aSAndrei Emeltchenko 	}
3315b71d385aSAndrei Emeltchenko }
3316b71d385aSAndrei Emeltchenko 
33171da177e4SLinus Torvalds /* Schedule SCO */
33186039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
33191da177e4SLinus Torvalds {
33201da177e4SLinus Torvalds 	struct hci_conn *conn;
33211da177e4SLinus Torvalds 	struct sk_buff *skb;
33221da177e4SLinus Torvalds 	int quote;
33231da177e4SLinus Torvalds 
33241da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
33251da177e4SLinus Torvalds 
332652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
332752087a79SLuiz Augusto von Dentz 		return;
332852087a79SLuiz Augusto von Dentz 
33291da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
33301da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
33311da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
333257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
33331da177e4SLinus Torvalds 
33341da177e4SLinus Torvalds 			conn->sent++;
33351da177e4SLinus Torvalds 			if (conn->sent == ~0)
33361da177e4SLinus Torvalds 				conn->sent = 0;
33371da177e4SLinus Torvalds 		}
33381da177e4SLinus Torvalds 	}
33391da177e4SLinus Torvalds }
33401da177e4SLinus Torvalds 
33416039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
3342b6a0dc82SMarcel Holtmann {
3343b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
3344b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
3345b6a0dc82SMarcel Holtmann 	int quote;
3346b6a0dc82SMarcel Holtmann 
3347b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
3348b6a0dc82SMarcel Holtmann 
334952087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
335052087a79SLuiz Augusto von Dentz 		return;
335152087a79SLuiz Augusto von Dentz 
33528fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
33538fc9ced3SGustavo Padovan 						     &quote))) {
3354b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
3355b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
335657d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3357b6a0dc82SMarcel Holtmann 
3358b6a0dc82SMarcel Holtmann 			conn->sent++;
3359b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
3360b6a0dc82SMarcel Holtmann 				conn->sent = 0;
3361b6a0dc82SMarcel Holtmann 		}
3362b6a0dc82SMarcel Holtmann 	}
3363b6a0dc82SMarcel Holtmann }
3364b6a0dc82SMarcel Holtmann 
33656039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
33666ed58ec5SVille Tervo {
336773d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
33686ed58ec5SVille Tervo 	struct sk_buff *skb;
336902b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
33706ed58ec5SVille Tervo 
33716ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
33726ed58ec5SVille Tervo 
337352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
337452087a79SLuiz Augusto von Dentz 		return;
337552087a79SLuiz Augusto von Dentz 
33766ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
33776ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
33786ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
3379bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
33806ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
3381bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
33826ed58ec5SVille Tervo 	}
33836ed58ec5SVille Tervo 
33846ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
338502b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
338673d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3387ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3388ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
338973d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
339073d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
33916ed58ec5SVille Tervo 
3392ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3393ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3394ec1cce24SLuiz Augusto von Dentz 				break;
3395ec1cce24SLuiz Augusto von Dentz 
3396ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3397ec1cce24SLuiz Augusto von Dentz 
339857d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
33996ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
34006ed58ec5SVille Tervo 
34016ed58ec5SVille Tervo 			cnt--;
340273d80debSLuiz Augusto von Dentz 			chan->sent++;
340373d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
34046ed58ec5SVille Tervo 		}
34056ed58ec5SVille Tervo 	}
340673d80debSLuiz Augusto von Dentz 
34076ed58ec5SVille Tervo 	if (hdev->le_pkts)
34086ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
34096ed58ec5SVille Tervo 	else
34106ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
341102b20f0bSLuiz Augusto von Dentz 
341202b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
341302b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
34146ed58ec5SVille Tervo }
34156ed58ec5SVille Tervo 
34163eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
34171da177e4SLinus Torvalds {
34183eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
34191da177e4SLinus Torvalds 	struct sk_buff *skb;
34201da177e4SLinus Torvalds 
34216ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
34226ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
34231da177e4SLinus Torvalds 
342452de599eSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
34251da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
34261da177e4SLinus Torvalds 		hci_sched_acl(hdev);
34271da177e4SLinus Torvalds 		hci_sched_sco(hdev);
3428b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
34296ed58ec5SVille Tervo 		hci_sched_le(hdev);
343052de599eSMarcel Holtmann 	}
34316ed58ec5SVille Tervo 
34321da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
34331da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
343457d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
34351da177e4SLinus Torvalds }
34361da177e4SLinus Torvalds 
343725985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
34381da177e4SLinus Torvalds 
34391da177e4SLinus Torvalds /* ACL data packet */
34406039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
34411da177e4SLinus Torvalds {
34421da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
34431da177e4SLinus Torvalds 	struct hci_conn *conn;
34441da177e4SLinus Torvalds 	__u16 handle, flags;
34451da177e4SLinus Torvalds 
34461da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
34471da177e4SLinus Torvalds 
34481da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
34491da177e4SLinus Torvalds 	flags  = hci_flags(handle);
34501da177e4SLinus Torvalds 	handle = hci_handle(handle);
34511da177e4SLinus Torvalds 
3452f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3453a8c5fb1aSGustavo Padovan 	       handle, flags);
34541da177e4SLinus Torvalds 
34551da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
34561da177e4SLinus Torvalds 
34571da177e4SLinus Torvalds 	hci_dev_lock(hdev);
34581da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
34591da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
34601da177e4SLinus Torvalds 
34611da177e4SLinus Torvalds 	if (conn) {
346265983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
346304837f64SMarcel Holtmann 
34641da177e4SLinus Torvalds 		/* Send to upper protocol */
3465686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
34661da177e4SLinus Torvalds 		return;
34671da177e4SLinus Torvalds 	} else {
34681da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
34691da177e4SLinus Torvalds 		       hdev->name, handle);
34701da177e4SLinus Torvalds 	}
34711da177e4SLinus Torvalds 
34721da177e4SLinus Torvalds 	kfree_skb(skb);
34731da177e4SLinus Torvalds }
34741da177e4SLinus Torvalds 
34751da177e4SLinus Torvalds /* SCO data packet */
34766039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
34771da177e4SLinus Torvalds {
34781da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
34791da177e4SLinus Torvalds 	struct hci_conn *conn;
34801da177e4SLinus Torvalds 	__u16 handle;
34811da177e4SLinus Torvalds 
34821da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
34831da177e4SLinus Torvalds 
34841da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
34851da177e4SLinus Torvalds 
3486f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
34871da177e4SLinus Torvalds 
34881da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
34891da177e4SLinus Torvalds 
34901da177e4SLinus Torvalds 	hci_dev_lock(hdev);
34911da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
34921da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
34931da177e4SLinus Torvalds 
34941da177e4SLinus Torvalds 	if (conn) {
34951da177e4SLinus Torvalds 		/* Send to upper protocol */
3496686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
34971da177e4SLinus Torvalds 		return;
34981da177e4SLinus Torvalds 	} else {
34991da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
35001da177e4SLinus Torvalds 		       hdev->name, handle);
35011da177e4SLinus Torvalds 	}
35021da177e4SLinus Torvalds 
35031da177e4SLinus Torvalds 	kfree_skb(skb);
35041da177e4SLinus Torvalds }
35051da177e4SLinus Torvalds 
35069238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
35079238f36aSJohan Hedberg {
35089238f36aSJohan Hedberg 	struct sk_buff *skb;
35099238f36aSJohan Hedberg 
35109238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
35119238f36aSJohan Hedberg 	if (!skb)
35129238f36aSJohan Hedberg 		return true;
35139238f36aSJohan Hedberg 
35149238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
35159238f36aSJohan Hedberg }
35169238f36aSJohan Hedberg 
351742c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
351842c6b129SJohan Hedberg {
351942c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
352042c6b129SJohan Hedberg 	struct sk_buff *skb;
352142c6b129SJohan Hedberg 	u16 opcode;
352242c6b129SJohan Hedberg 
352342c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
352442c6b129SJohan Hedberg 		return;
352542c6b129SJohan Hedberg 
352642c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
352742c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
352842c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
352942c6b129SJohan Hedberg 		return;
353042c6b129SJohan Hedberg 
353142c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
353242c6b129SJohan Hedberg 	if (!skb)
353342c6b129SJohan Hedberg 		return;
353442c6b129SJohan Hedberg 
353542c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
353642c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
353742c6b129SJohan Hedberg }
353842c6b129SJohan Hedberg 
35399238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
35409238f36aSJohan Hedberg {
35419238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
35429238f36aSJohan Hedberg 	struct sk_buff *skb;
35439238f36aSJohan Hedberg 	unsigned long flags;
35449238f36aSJohan Hedberg 
35459238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
35469238f36aSJohan Hedberg 
354742c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
354842c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
35499238f36aSJohan Hedberg 	 */
355042c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
355142c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
355242c6b129SJohan Hedberg 		 * reset complete event during init and any pending
355342c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
355442c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
355542c6b129SJohan Hedberg 		 * command.
355642c6b129SJohan Hedberg 		 */
355742c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
355842c6b129SJohan Hedberg 			hci_resend_last(hdev);
355942c6b129SJohan Hedberg 
35609238f36aSJohan Hedberg 		return;
356142c6b129SJohan Hedberg 	}
35629238f36aSJohan Hedberg 
35639238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
35649238f36aSJohan Hedberg 	 * this request the request is not yet complete.
35659238f36aSJohan Hedberg 	 */
35669238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
35679238f36aSJohan Hedberg 		return;
35689238f36aSJohan Hedberg 
35699238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
35709238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
35719238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
35729238f36aSJohan Hedberg 	 */
35739238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
35749238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
357553e21fbcSJohan Hedberg 
357653e21fbcSJohan Hedberg 		if (req_complete) {
357753e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
357853e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
357953e21fbcSJohan Hedberg 			 * this function gets called again.
358053e21fbcSJohan Hedberg 			 */
358153e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
358253e21fbcSJohan Hedberg 
35839238f36aSJohan Hedberg 			goto call_complete;
35849238f36aSJohan Hedberg 		}
358553e21fbcSJohan Hedberg 	}
35869238f36aSJohan Hedberg 
35879238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
35889238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
35899238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
35909238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
35919238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
35929238f36aSJohan Hedberg 			break;
35939238f36aSJohan Hedberg 		}
35949238f36aSJohan Hedberg 
35959238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
35969238f36aSJohan Hedberg 		kfree_skb(skb);
35979238f36aSJohan Hedberg 	}
35989238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
35999238f36aSJohan Hedberg 
36009238f36aSJohan Hedberg call_complete:
36019238f36aSJohan Hedberg 	if (req_complete)
36029238f36aSJohan Hedberg 		req_complete(hdev, status);
36039238f36aSJohan Hedberg }
36049238f36aSJohan Hedberg 
3605b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
36061da177e4SLinus Torvalds {
3607b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
36081da177e4SLinus Torvalds 	struct sk_buff *skb;
36091da177e4SLinus Torvalds 
36101da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
36111da177e4SLinus Torvalds 
36121da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
3613cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
3614cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
3615cd82e61cSMarcel Holtmann 
36161da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
36171da177e4SLinus Torvalds 			/* Send copy to the sockets */
3618470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
36191da177e4SLinus Torvalds 		}
36201da177e4SLinus Torvalds 
36210736cfa8SMarcel Holtmann 		if (test_bit(HCI_RAW, &hdev->flags) ||
36220736cfa8SMarcel Holtmann 		    test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
36231da177e4SLinus Torvalds 			kfree_skb(skb);
36241da177e4SLinus Torvalds 			continue;
36251da177e4SLinus Torvalds 		}
36261da177e4SLinus Torvalds 
36271da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
36281da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
36290d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
36301da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
36311da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
36321da177e4SLinus Torvalds 				kfree_skb(skb);
36331da177e4SLinus Torvalds 				continue;
36343ff50b79SStephen Hemminger 			}
36351da177e4SLinus Torvalds 		}
36361da177e4SLinus Torvalds 
36371da177e4SLinus Torvalds 		/* Process frame */
36380d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
36391da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
3640b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
36411da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
36421da177e4SLinus Torvalds 			break;
36431da177e4SLinus Torvalds 
36441da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
36451da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
36461da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
36471da177e4SLinus Torvalds 			break;
36481da177e4SLinus Torvalds 
36491da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
36501da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
36511da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
36521da177e4SLinus Torvalds 			break;
36531da177e4SLinus Torvalds 
36541da177e4SLinus Torvalds 		default:
36551da177e4SLinus Torvalds 			kfree_skb(skb);
36561da177e4SLinus Torvalds 			break;
36571da177e4SLinus Torvalds 		}
36581da177e4SLinus Torvalds 	}
36591da177e4SLinus Torvalds }
36601da177e4SLinus Torvalds 
3661c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
36621da177e4SLinus Torvalds {
3663c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
36641da177e4SLinus Torvalds 	struct sk_buff *skb;
36651da177e4SLinus Torvalds 
36662104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
36672104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
36681da177e4SLinus Torvalds 
36691da177e4SLinus Torvalds 	/* Send queued commands */
36705a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
36715a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
36725a08ecceSAndrei Emeltchenko 		if (!skb)
36735a08ecceSAndrei Emeltchenko 			return;
36745a08ecceSAndrei Emeltchenko 
36751da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
36761da177e4SLinus Torvalds 
3677a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
367870f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
36791da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
368057d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
36817bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
36827bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
36837bdb8a5cSSzymon Janc 			else
36846bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
36855f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
36861da177e4SLinus Torvalds 		} else {
36871da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
3688c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
36891da177e4SLinus Torvalds 		}
36901da177e4SLinus Torvalds 	}
36911da177e4SLinus Torvalds }
36922519a1fcSAndre Guedes 
369331f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type)
369431f7956cSAndre Guedes {
369531f7956cSAndre Guedes 	switch (bdaddr_type) {
369631f7956cSAndre Guedes 	case BDADDR_LE_PUBLIC:
369731f7956cSAndre Guedes 		return ADDR_LE_DEV_PUBLIC;
369831f7956cSAndre Guedes 
369931f7956cSAndre Guedes 	default:
370031f7956cSAndre Guedes 		/* Fallback to LE Random address type */
370131f7956cSAndre Guedes 		return ADDR_LE_DEV_RANDOM;
370231f7956cSAndre Guedes 	}
370331f7956cSAndre Guedes }
3704