xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 0736cfa8)
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 
3106bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
31142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
312e71dfabaSAndrei Emeltchenko 
313e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
31442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
315e61ef499SAndrei Emeltchenko }
316e61ef499SAndrei Emeltchenko 
31742c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
318e61ef499SAndrei Emeltchenko {
31942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
320e61ef499SAndrei Emeltchenko 
321e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
322e61ef499SAndrei Emeltchenko 
32311778716SAndrei Emeltchenko 	/* Reset */
32411778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
32542c6b129SJohan Hedberg 		hci_reset_req(req, 0);
32611778716SAndrei Emeltchenko 
327e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
328e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
32942c6b129SJohan Hedberg 		bredr_init(req);
330e61ef499SAndrei Emeltchenko 		break;
331e61ef499SAndrei Emeltchenko 
332e61ef499SAndrei Emeltchenko 	case HCI_AMP:
33342c6b129SJohan Hedberg 		amp_init(req);
334e61ef499SAndrei Emeltchenko 		break;
335e61ef499SAndrei Emeltchenko 
336e61ef499SAndrei Emeltchenko 	default:
337e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
338e61ef499SAndrei Emeltchenko 		break;
339e61ef499SAndrei Emeltchenko 	}
340e61ef499SAndrei Emeltchenko }
341e61ef499SAndrei Emeltchenko 
34242c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
3432177bab5SJohan Hedberg {
3442177bab5SJohan Hedberg 	__le16 param;
3452177bab5SJohan Hedberg 	__u8 flt_type;
3462177bab5SJohan Hedberg 
3472177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
34842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
3492177bab5SJohan Hedberg 
3502177bab5SJohan Hedberg 	/* Read Class of Device */
35142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
3522177bab5SJohan Hedberg 
3532177bab5SJohan Hedberg 	/* Read Local Name */
35442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
3552177bab5SJohan Hedberg 
3562177bab5SJohan Hedberg 	/* Read Voice Setting */
35742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
3582177bab5SJohan Hedberg 
3592177bab5SJohan Hedberg 	/* Clear Event Filters */
3602177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
36142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
3622177bab5SJohan Hedberg 
3632177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
3642177bab5SJohan Hedberg 	param = __constant_cpu_to_le16(0x7d00);
36542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
3662177bab5SJohan Hedberg 
367f332ec66SJohan Hedberg 	/* Read page scan parameters */
368f332ec66SJohan Hedberg 	if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) {
369f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
370f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
371f332ec66SJohan Hedberg 	}
3722177bab5SJohan Hedberg }
3732177bab5SJohan Hedberg 
37442c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
3752177bab5SJohan Hedberg {
376c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
377c73eee91SJohan Hedberg 
3782177bab5SJohan Hedberg 	/* Read LE Buffer Size */
37942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
3802177bab5SJohan Hedberg 
3812177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
38242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
3832177bab5SJohan Hedberg 
3842177bab5SJohan Hedberg 	/* Read LE Advertising Channel TX Power */
38542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
3862177bab5SJohan Hedberg 
3872177bab5SJohan Hedberg 	/* Read LE White List Size */
38842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
3892177bab5SJohan Hedberg 
3902177bab5SJohan Hedberg 	/* Read LE Supported States */
39142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
392c73eee91SJohan Hedberg 
393c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
394c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
395c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
3962177bab5SJohan Hedberg }
3972177bab5SJohan Hedberg 
3982177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
3992177bab5SJohan Hedberg {
4002177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
4012177bab5SJohan Hedberg 		return 0x02;
4022177bab5SJohan Hedberg 
4032177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4042177bab5SJohan Hedberg 		return 0x01;
4052177bab5SJohan Hedberg 
4062177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
4072177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
4082177bab5SJohan Hedberg 		return 0x01;
4092177bab5SJohan Hedberg 
4102177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
4112177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
4122177bab5SJohan Hedberg 			return 0x01;
4132177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
4142177bab5SJohan Hedberg 			return 0x01;
4152177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
4162177bab5SJohan Hedberg 			return 0x01;
4172177bab5SJohan Hedberg 	}
4182177bab5SJohan Hedberg 
4192177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
4202177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
4212177bab5SJohan Hedberg 		return 0x01;
4222177bab5SJohan Hedberg 
4232177bab5SJohan Hedberg 	return 0x00;
4242177bab5SJohan Hedberg }
4252177bab5SJohan Hedberg 
42642c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
4272177bab5SJohan Hedberg {
4282177bab5SJohan Hedberg 	u8 mode;
4292177bab5SJohan Hedberg 
43042c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
4312177bab5SJohan Hedberg 
43242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
4332177bab5SJohan Hedberg }
4342177bab5SJohan Hedberg 
43542c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
4362177bab5SJohan Hedberg {
43742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
43842c6b129SJohan Hedberg 
4392177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
4402177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
4412177bab5SJohan Hedberg 	 * command otherwise.
4422177bab5SJohan Hedberg 	 */
4432177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
4442177bab5SJohan Hedberg 
4452177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
4462177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
4472177bab5SJohan Hedberg 	 */
4482177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
4492177bab5SJohan Hedberg 		return;
4502177bab5SJohan Hedberg 
4512177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
4522177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
4532177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4542177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
4552177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
4562177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
457c7882cbdSMarcel Holtmann 	} else {
458c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
459c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
460c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
461c7882cbdSMarcel Holtmann 		events[0] |= 0x80; /* Encryption Change */
462c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
463c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
464c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
465c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
466c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
467c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
468c7882cbdSMarcel Holtmann 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
4692177bab5SJohan Hedberg 	}
4702177bab5SJohan Hedberg 
4712177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4722177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4732177bab5SJohan Hedberg 
4742177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
4752177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
4762177bab5SJohan Hedberg 
4772177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
4782177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
4792177bab5SJohan Hedberg 
4802177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
4812177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
4822177bab5SJohan Hedberg 
4832177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
4842177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
4852177bab5SJohan Hedberg 
4862177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
4872177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
4882177bab5SJohan Hedberg 
4892177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
4902177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
4912177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
4922177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
4932177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
4942177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
4952177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
4962177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
4972177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
4982177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
4992177bab5SJohan Hedberg 					 * Features Notification
5002177bab5SJohan Hedberg 					 */
5012177bab5SJohan Hedberg 	}
5022177bab5SJohan Hedberg 
5032177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
5042177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
5052177bab5SJohan Hedberg 
50642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
5072177bab5SJohan Hedberg 
5082177bab5SJohan Hedberg 	if (lmp_le_capable(hdev)) {
5092177bab5SJohan Hedberg 		memset(events, 0, sizeof(events));
5102177bab5SJohan Hedberg 		events[0] = 0x1f;
51142c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
5122177bab5SJohan Hedberg 			    sizeof(events), events);
5132177bab5SJohan Hedberg 	}
5142177bab5SJohan Hedberg }
5152177bab5SJohan Hedberg 
51642c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
5172177bab5SJohan Hedberg {
51842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
51942c6b129SJohan Hedberg 
5202177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
52142c6b129SJohan Hedberg 		bredr_setup(req);
5222177bab5SJohan Hedberg 
5232177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
52442c6b129SJohan Hedberg 		le_setup(req);
5252177bab5SJohan Hedberg 
52642c6b129SJohan Hedberg 	hci_setup_event_mask(req);
5272177bab5SJohan Hedberg 
5283f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
5293f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
5303f8e2d75SJohan Hedberg 	 */
5313f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
53242c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
5332177bab5SJohan Hedberg 
5342177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5352177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
5362177bab5SJohan Hedberg 			u8 mode = 0x01;
53742c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
5382177bab5SJohan Hedberg 				    sizeof(mode), &mode);
5392177bab5SJohan Hedberg 		} else {
5402177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
5412177bab5SJohan Hedberg 
5422177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
5432177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
5442177bab5SJohan Hedberg 
54542c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
5462177bab5SJohan Hedberg 		}
5472177bab5SJohan Hedberg 	}
5482177bab5SJohan Hedberg 
5492177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
55042c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
5512177bab5SJohan Hedberg 
5522177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
55342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
5542177bab5SJohan Hedberg 
5552177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
5562177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
5572177bab5SJohan Hedberg 
5582177bab5SJohan Hedberg 		cp.page = 0x01;
55942c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
56042c6b129SJohan Hedberg 			    sizeof(cp), &cp);
5612177bab5SJohan Hedberg 	}
5622177bab5SJohan Hedberg 
5632177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
5642177bab5SJohan Hedberg 		u8 enable = 1;
56542c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
5662177bab5SJohan Hedberg 			    &enable);
5672177bab5SJohan Hedberg 	}
5682177bab5SJohan Hedberg }
5692177bab5SJohan Hedberg 
57042c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
5712177bab5SJohan Hedberg {
57242c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5732177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
5742177bab5SJohan Hedberg 	u16 link_policy = 0;
5752177bab5SJohan Hedberg 
5762177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
5772177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
5782177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
5792177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
5802177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
5812177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
5822177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
5832177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
5842177bab5SJohan Hedberg 
5852177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
58642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
5872177bab5SJohan Hedberg }
5882177bab5SJohan Hedberg 
58942c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
5902177bab5SJohan Hedberg {
59142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5922177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
5932177bab5SJohan Hedberg 
594c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
595c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
596c73eee91SJohan Hedberg 		return;
597c73eee91SJohan Hedberg 
5982177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
5992177bab5SJohan Hedberg 
6002177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
6012177bab5SJohan Hedberg 		cp.le = 0x01;
6022177bab5SJohan Hedberg 		cp.simul = lmp_le_br_capable(hdev);
6032177bab5SJohan Hedberg 	}
6042177bab5SJohan Hedberg 
6052177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
60642c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
6072177bab5SJohan Hedberg 			    &cp);
6082177bab5SJohan Hedberg }
6092177bab5SJohan Hedberg 
61042c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
6112177bab5SJohan Hedberg {
61242c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
613d2c5d77fSJohan Hedberg 	u8 p;
61442c6b129SJohan Hedberg 
615b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
616b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
617b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
618b8f4e068SGustavo Padovan 	 *
619b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
620b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
621b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
622b8f4e068SGustavo Padovan 	 * command redundant anyway.
623b8f4e068SGustavo Padovan 	 */
62459f45d57SJohan Hedberg 	if (hdev->commands[6] & 0x80) {
62559f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
62659f45d57SJohan Hedberg 
62759f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
62859f45d57SJohan Hedberg 		cp.delete_all = 0x01;
62959f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
63059f45d57SJohan Hedberg 			    sizeof(cp), &cp);
63159f45d57SJohan Hedberg 	}
63259f45d57SJohan Hedberg 
6332177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
63442c6b129SJohan Hedberg 		hci_setup_link_policy(req);
6352177bab5SJohan Hedberg 
63604b4edcbSJohan Hedberg 	if (lmp_le_capable(hdev)) {
63742c6b129SJohan Hedberg 		hci_set_le_support(req);
63804b4edcbSJohan Hedberg 		hci_update_ad(req);
63904b4edcbSJohan Hedberg 	}
640d2c5d77fSJohan Hedberg 
641d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
642d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
643d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
644d2c5d77fSJohan Hedberg 
645d2c5d77fSJohan Hedberg 		cp.page = p;
646d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
647d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
648d2c5d77fSJohan Hedberg 	}
6492177bab5SJohan Hedberg }
6502177bab5SJohan Hedberg 
6512177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
6522177bab5SJohan Hedberg {
6532177bab5SJohan Hedberg 	int err;
6542177bab5SJohan Hedberg 
6552177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
6562177bab5SJohan Hedberg 	if (err < 0)
6572177bab5SJohan Hedberg 		return err;
6582177bab5SJohan Hedberg 
6592177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
6602177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
6612177bab5SJohan Hedberg 	 * first stage init.
6622177bab5SJohan Hedberg 	 */
6632177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
6642177bab5SJohan Hedberg 		return 0;
6652177bab5SJohan Hedberg 
6662177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
6672177bab5SJohan Hedberg 	if (err < 0)
6682177bab5SJohan Hedberg 		return err;
6692177bab5SJohan Hedberg 
6702177bab5SJohan Hedberg 	return __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
6712177bab5SJohan Hedberg }
6722177bab5SJohan Hedberg 
67342c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
6741da177e4SLinus Torvalds {
6751da177e4SLinus Torvalds 	__u8 scan = opt;
6761da177e4SLinus Torvalds 
67742c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
6781da177e4SLinus Torvalds 
6791da177e4SLinus Torvalds 	/* Inquiry and Page scans */
68042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
6811da177e4SLinus Torvalds }
6821da177e4SLinus Torvalds 
68342c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
6841da177e4SLinus Torvalds {
6851da177e4SLinus Torvalds 	__u8 auth = opt;
6861da177e4SLinus Torvalds 
68742c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
6881da177e4SLinus Torvalds 
6891da177e4SLinus Torvalds 	/* Authentication */
69042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
6911da177e4SLinus Torvalds }
6921da177e4SLinus Torvalds 
69342c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
6941da177e4SLinus Torvalds {
6951da177e4SLinus Torvalds 	__u8 encrypt = opt;
6961da177e4SLinus Torvalds 
69742c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
6981da177e4SLinus Torvalds 
699e4e8e37cSMarcel Holtmann 	/* Encryption */
70042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
7011da177e4SLinus Torvalds }
7021da177e4SLinus Torvalds 
70342c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
704e4e8e37cSMarcel Holtmann {
705e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
706e4e8e37cSMarcel Holtmann 
70742c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
708e4e8e37cSMarcel Holtmann 
709e4e8e37cSMarcel Holtmann 	/* Default link policy */
71042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
711e4e8e37cSMarcel Holtmann }
712e4e8e37cSMarcel Holtmann 
7131da177e4SLinus Torvalds /* Get HCI device by index.
7141da177e4SLinus Torvalds  * Device is held on return. */
7151da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
7161da177e4SLinus Torvalds {
7178035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
7181da177e4SLinus Torvalds 
7191da177e4SLinus Torvalds 	BT_DBG("%d", index);
7201da177e4SLinus Torvalds 
7211da177e4SLinus Torvalds 	if (index < 0)
7221da177e4SLinus Torvalds 		return NULL;
7231da177e4SLinus Torvalds 
7241da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
7258035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
7261da177e4SLinus Torvalds 		if (d->id == index) {
7271da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
7281da177e4SLinus Torvalds 			break;
7291da177e4SLinus Torvalds 		}
7301da177e4SLinus Torvalds 	}
7311da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
7321da177e4SLinus Torvalds 	return hdev;
7331da177e4SLinus Torvalds }
7341da177e4SLinus Torvalds 
7351da177e4SLinus Torvalds /* ---- Inquiry support ---- */
736ff9ef578SJohan Hedberg 
73730dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
73830dc78e1SJohan Hedberg {
73930dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
74030dc78e1SJohan Hedberg 
7416fbe195dSAndre Guedes 	switch (discov->state) {
742343f935bSAndre Guedes 	case DISCOVERY_FINDING:
7436fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
74430dc78e1SJohan Hedberg 		return true;
74530dc78e1SJohan Hedberg 
7466fbe195dSAndre Guedes 	default:
74730dc78e1SJohan Hedberg 		return false;
74830dc78e1SJohan Hedberg 	}
7496fbe195dSAndre Guedes }
75030dc78e1SJohan Hedberg 
751ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
752ff9ef578SJohan Hedberg {
753ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
754ff9ef578SJohan Hedberg 
755ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
756ff9ef578SJohan Hedberg 		return;
757ff9ef578SJohan Hedberg 
758ff9ef578SJohan Hedberg 	switch (state) {
759ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
7607b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
761ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
762ff9ef578SJohan Hedberg 		break;
763ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
764ff9ef578SJohan Hedberg 		break;
765343f935bSAndre Guedes 	case DISCOVERY_FINDING:
766ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
767ff9ef578SJohan Hedberg 		break;
76830dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
76930dc78e1SJohan Hedberg 		break;
770ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
771ff9ef578SJohan Hedberg 		break;
772ff9ef578SJohan Hedberg 	}
773ff9ef578SJohan Hedberg 
774ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
775ff9ef578SJohan Hedberg }
776ff9ef578SJohan Hedberg 
7771f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
7781da177e4SLinus Torvalds {
77930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
780b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
7811da177e4SLinus Torvalds 
782561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
783561aafbcSJohan Hedberg 		list_del(&p->all);
784b57c1a56SJohan Hedberg 		kfree(p);
7851da177e4SLinus Torvalds 	}
786561aafbcSJohan Hedberg 
787561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
788561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
7891da177e4SLinus Torvalds }
7901da177e4SLinus Torvalds 
791a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
792a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
7931da177e4SLinus Torvalds {
79430883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
7951da177e4SLinus Torvalds 	struct inquiry_entry *e;
7961da177e4SLinus Torvalds 
7976ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
7981da177e4SLinus Torvalds 
799561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
8001da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
8011da177e4SLinus Torvalds 			return e;
8021da177e4SLinus Torvalds 	}
8031da177e4SLinus Torvalds 
804b57c1a56SJohan Hedberg 	return NULL;
805b57c1a56SJohan Hedberg }
806b57c1a56SJohan Hedberg 
807561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
808561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
809561aafbcSJohan Hedberg {
81030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
811561aafbcSJohan Hedberg 	struct inquiry_entry *e;
812561aafbcSJohan Hedberg 
8136ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
814561aafbcSJohan Hedberg 
815561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
816561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
817561aafbcSJohan Hedberg 			return e;
818561aafbcSJohan Hedberg 	}
819561aafbcSJohan Hedberg 
820561aafbcSJohan Hedberg 	return NULL;
821561aafbcSJohan Hedberg }
822561aafbcSJohan Hedberg 
82330dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
82430dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
82530dc78e1SJohan Hedberg 						       int state)
82630dc78e1SJohan Hedberg {
82730dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
82830dc78e1SJohan Hedberg 	struct inquiry_entry *e;
82930dc78e1SJohan Hedberg 
8306ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
83130dc78e1SJohan Hedberg 
83230dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
83330dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
83430dc78e1SJohan Hedberg 			return e;
83530dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
83630dc78e1SJohan Hedberg 			return e;
83730dc78e1SJohan Hedberg 	}
83830dc78e1SJohan Hedberg 
83930dc78e1SJohan Hedberg 	return NULL;
84030dc78e1SJohan Hedberg }
84130dc78e1SJohan Hedberg 
842a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
843a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
844a3d4e20aSJohan Hedberg {
845a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
846a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
847a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
848a3d4e20aSJohan Hedberg 
849a3d4e20aSJohan Hedberg 	list_del(&ie->list);
850a3d4e20aSJohan Hedberg 
851a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
852a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
853a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
854a3d4e20aSJohan Hedberg 			break;
855a3d4e20aSJohan Hedberg 		pos = &p->list;
856a3d4e20aSJohan Hedberg 	}
857a3d4e20aSJohan Hedberg 
858a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
859a3d4e20aSJohan Hedberg }
860a3d4e20aSJohan Hedberg 
8613175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
862388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
8631da177e4SLinus Torvalds {
86430883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
86570f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
8661da177e4SLinus Torvalds 
8676ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
8681da177e4SLinus Torvalds 
8692b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
8702b2fec4dSSzymon Janc 
871388fc8faSJohan Hedberg 	if (ssp)
872388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
873388fc8faSJohan Hedberg 
87470f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
875a3d4e20aSJohan Hedberg 	if (ie) {
876388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
877388fc8faSJohan Hedberg 			*ssp = true;
878388fc8faSJohan Hedberg 
879a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
880a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
881a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
882a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
883a3d4e20aSJohan Hedberg 		}
884a3d4e20aSJohan Hedberg 
885561aafbcSJohan Hedberg 		goto update;
886a3d4e20aSJohan Hedberg 	}
887561aafbcSJohan Hedberg 
8881da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
88970f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
89070f23020SAndrei Emeltchenko 	if (!ie)
8913175405bSJohan Hedberg 		return false;
89270f23020SAndrei Emeltchenko 
893561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
894561aafbcSJohan Hedberg 
895561aafbcSJohan Hedberg 	if (name_known) {
896561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
897561aafbcSJohan Hedberg 	} else {
898561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
899561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
900561aafbcSJohan Hedberg 	}
901561aafbcSJohan Hedberg 
902561aafbcSJohan Hedberg update:
903561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
904561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
905561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
906561aafbcSJohan Hedberg 		list_del(&ie->list);
9071da177e4SLinus Torvalds 	}
9081da177e4SLinus Torvalds 
90970f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
91070f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
9111da177e4SLinus Torvalds 	cache->timestamp = jiffies;
9123175405bSJohan Hedberg 
9133175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
9143175405bSJohan Hedberg 		return false;
9153175405bSJohan Hedberg 
9163175405bSJohan Hedberg 	return true;
9171da177e4SLinus Torvalds }
9181da177e4SLinus Torvalds 
9191da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
9201da177e4SLinus Torvalds {
92130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
9221da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
9231da177e4SLinus Torvalds 	struct inquiry_entry *e;
9241da177e4SLinus Torvalds 	int copied = 0;
9251da177e4SLinus Torvalds 
926561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
9271da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
928b57c1a56SJohan Hedberg 
929b57c1a56SJohan Hedberg 		if (copied >= num)
930b57c1a56SJohan Hedberg 			break;
931b57c1a56SJohan Hedberg 
9321da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
9331da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
9341da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
9351da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
9361da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
9371da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
938b57c1a56SJohan Hedberg 
9391da177e4SLinus Torvalds 		info++;
940b57c1a56SJohan Hedberg 		copied++;
9411da177e4SLinus Torvalds 	}
9421da177e4SLinus Torvalds 
9431da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
9441da177e4SLinus Torvalds 	return copied;
9451da177e4SLinus Torvalds }
9461da177e4SLinus Torvalds 
94742c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
9481da177e4SLinus Torvalds {
9491da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
95042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
9511da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
9521da177e4SLinus Torvalds 
9531da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
9541da177e4SLinus Torvalds 
9551da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
9561da177e4SLinus Torvalds 		return;
9571da177e4SLinus Torvalds 
9581da177e4SLinus Torvalds 	/* Start Inquiry */
9591da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
9601da177e4SLinus Torvalds 	cp.length  = ir->length;
9611da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
96242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
9631da177e4SLinus Torvalds }
9641da177e4SLinus Torvalds 
9653e13fa1eSAndre Guedes static int wait_inquiry(void *word)
9663e13fa1eSAndre Guedes {
9673e13fa1eSAndre Guedes 	schedule();
9683e13fa1eSAndre Guedes 	return signal_pending(current);
9693e13fa1eSAndre Guedes }
9703e13fa1eSAndre Guedes 
9711da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
9721da177e4SLinus Torvalds {
9731da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
9741da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
9751da177e4SLinus Torvalds 	struct hci_dev *hdev;
9761da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
9771da177e4SLinus Torvalds 	long timeo;
9781da177e4SLinus Torvalds 	__u8 *buf;
9791da177e4SLinus Torvalds 
9801da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
9811da177e4SLinus Torvalds 		return -EFAULT;
9821da177e4SLinus Torvalds 
9835a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
9845a08ecceSAndrei Emeltchenko 	if (!hdev)
9851da177e4SLinus Torvalds 		return -ENODEV;
9861da177e4SLinus Torvalds 
9870736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
9880736cfa8SMarcel Holtmann 		err = -EBUSY;
9890736cfa8SMarcel Holtmann 		goto done;
9900736cfa8SMarcel Holtmann 	}
9910736cfa8SMarcel Holtmann 
99209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
9931da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
994a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
9951f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
9961da177e4SLinus Torvalds 		do_inquiry = 1;
9971da177e4SLinus Torvalds 	}
99809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
9991da177e4SLinus Torvalds 
100004837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
100170f23020SAndrei Emeltchenko 
100270f23020SAndrei Emeltchenko 	if (do_inquiry) {
100301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
100401178cd4SJohan Hedberg 				   timeo);
100570f23020SAndrei Emeltchenko 		if (err < 0)
10061da177e4SLinus Torvalds 			goto done;
10073e13fa1eSAndre Guedes 
10083e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
10093e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
10103e13fa1eSAndre Guedes 		 */
10113e13fa1eSAndre Guedes 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry,
10123e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
10133e13fa1eSAndre Guedes 			return -EINTR;
101470f23020SAndrei Emeltchenko 	}
10151da177e4SLinus Torvalds 
10168fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
10178fc9ced3SGustavo Padovan 	 * 255 entries
10188fc9ced3SGustavo Padovan 	 */
10191da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
10201da177e4SLinus Torvalds 
10211da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
10221da177e4SLinus Torvalds 	 * copy it to the user space.
10231da177e4SLinus Torvalds 	 */
102470f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
102570f23020SAndrei Emeltchenko 	if (!buf) {
10261da177e4SLinus Torvalds 		err = -ENOMEM;
10271da177e4SLinus Torvalds 		goto done;
10281da177e4SLinus Torvalds 	}
10291da177e4SLinus Torvalds 
103009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
10311da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
103209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
10331da177e4SLinus Torvalds 
10341da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
10351da177e4SLinus Torvalds 
10361da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
10371da177e4SLinus Torvalds 		ptr += sizeof(ir);
10381da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
10391da177e4SLinus Torvalds 				 ir.num_rsp))
10401da177e4SLinus Torvalds 			err = -EFAULT;
10411da177e4SLinus Torvalds 	} else
10421da177e4SLinus Torvalds 		err = -EFAULT;
10431da177e4SLinus Torvalds 
10441da177e4SLinus Torvalds 	kfree(buf);
10451da177e4SLinus Torvalds 
10461da177e4SLinus Torvalds done:
10471da177e4SLinus Torvalds 	hci_dev_put(hdev);
10481da177e4SLinus Torvalds 	return err;
10491da177e4SLinus Torvalds }
10501da177e4SLinus Torvalds 
10513f0f524bSJohan Hedberg static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
10523f0f524bSJohan Hedberg {
10533f0f524bSJohan Hedberg 	u8 ad_len = 0, flags = 0;
10543f0f524bSJohan Hedberg 	size_t name_len;
10553f0f524bSJohan Hedberg 
10563f0f524bSJohan Hedberg 	if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
10573f0f524bSJohan Hedberg 		flags |= LE_AD_GENERAL;
10583f0f524bSJohan Hedberg 
10593f0f524bSJohan Hedberg 	if (!lmp_bredr_capable(hdev))
10603f0f524bSJohan Hedberg 		flags |= LE_AD_NO_BREDR;
10613f0f524bSJohan Hedberg 
10623f0f524bSJohan Hedberg 	if (lmp_le_br_capable(hdev))
10633f0f524bSJohan Hedberg 		flags |= LE_AD_SIM_LE_BREDR_CTRL;
10643f0f524bSJohan Hedberg 
10653f0f524bSJohan Hedberg 	if (lmp_host_le_br_capable(hdev))
10663f0f524bSJohan Hedberg 		flags |= LE_AD_SIM_LE_BREDR_HOST;
10673f0f524bSJohan Hedberg 
10683f0f524bSJohan Hedberg 	if (flags) {
10693f0f524bSJohan Hedberg 		BT_DBG("adv flags 0x%02x", flags);
10703f0f524bSJohan Hedberg 
10713f0f524bSJohan Hedberg 		ptr[0] = 2;
10723f0f524bSJohan Hedberg 		ptr[1] = EIR_FLAGS;
10733f0f524bSJohan Hedberg 		ptr[2] = flags;
10743f0f524bSJohan Hedberg 
10753f0f524bSJohan Hedberg 		ad_len += 3;
10763f0f524bSJohan Hedberg 		ptr += 3;
10773f0f524bSJohan Hedberg 	}
10783f0f524bSJohan Hedberg 
10793f0f524bSJohan Hedberg 	if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) {
10803f0f524bSJohan Hedberg 		ptr[0] = 2;
10813f0f524bSJohan Hedberg 		ptr[1] = EIR_TX_POWER;
10823f0f524bSJohan Hedberg 		ptr[2] = (u8) hdev->adv_tx_power;
10833f0f524bSJohan Hedberg 
10843f0f524bSJohan Hedberg 		ad_len += 3;
10853f0f524bSJohan Hedberg 		ptr += 3;
10863f0f524bSJohan Hedberg 	}
10873f0f524bSJohan Hedberg 
10883f0f524bSJohan Hedberg 	name_len = strlen(hdev->dev_name);
10893f0f524bSJohan Hedberg 	if (name_len > 0) {
10903f0f524bSJohan Hedberg 		size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
10913f0f524bSJohan Hedberg 
10923f0f524bSJohan Hedberg 		if (name_len > max_len) {
10933f0f524bSJohan Hedberg 			name_len = max_len;
10943f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_SHORT;
10953f0f524bSJohan Hedberg 		} else
10963f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_COMPLETE;
10973f0f524bSJohan Hedberg 
10983f0f524bSJohan Hedberg 		ptr[0] = name_len + 1;
10993f0f524bSJohan Hedberg 
11003f0f524bSJohan Hedberg 		memcpy(ptr + 2, hdev->dev_name, name_len);
11013f0f524bSJohan Hedberg 
11023f0f524bSJohan Hedberg 		ad_len += (name_len + 2);
11033f0f524bSJohan Hedberg 		ptr += (name_len + 2);
11043f0f524bSJohan Hedberg 	}
11053f0f524bSJohan Hedberg 
11063f0f524bSJohan Hedberg 	return ad_len;
11073f0f524bSJohan Hedberg }
11083f0f524bSJohan Hedberg 
110904b4edcbSJohan Hedberg void hci_update_ad(struct hci_request *req)
11103f0f524bSJohan Hedberg {
111104b4edcbSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
11123f0f524bSJohan Hedberg 	struct hci_cp_le_set_adv_data cp;
11133f0f524bSJohan Hedberg 	u8 len;
11143f0f524bSJohan Hedberg 
111504b4edcbSJohan Hedberg 	if (!lmp_le_capable(hdev))
111604b4edcbSJohan Hedberg 		return;
11173f0f524bSJohan Hedberg 
11183f0f524bSJohan Hedberg 	memset(&cp, 0, sizeof(cp));
11193f0f524bSJohan Hedberg 
11203f0f524bSJohan Hedberg 	len = create_ad(hdev, cp.data);
11213f0f524bSJohan Hedberg 
11223f0f524bSJohan Hedberg 	if (hdev->adv_data_len == len &&
112304b4edcbSJohan Hedberg 	    memcmp(cp.data, hdev->adv_data, len) == 0)
112404b4edcbSJohan Hedberg 		return;
11253f0f524bSJohan Hedberg 
11263f0f524bSJohan Hedberg 	memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
11273f0f524bSJohan Hedberg 	hdev->adv_data_len = len;
11283f0f524bSJohan Hedberg 
11293f0f524bSJohan Hedberg 	cp.length = len;
11303f0f524bSJohan Hedberg 
113104b4edcbSJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
11323f0f524bSJohan Hedberg }
11333f0f524bSJohan Hedberg 
11341da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
11351da177e4SLinus Torvalds 
11361da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
11371da177e4SLinus Torvalds {
11381da177e4SLinus Torvalds 	struct hci_dev *hdev;
11391da177e4SLinus Torvalds 	int ret = 0;
11401da177e4SLinus Torvalds 
11415a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
11425a08ecceSAndrei Emeltchenko 	if (!hdev)
11431da177e4SLinus Torvalds 		return -ENODEV;
11441da177e4SLinus Torvalds 
11451da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
11461da177e4SLinus Torvalds 
11471da177e4SLinus Torvalds 	hci_req_lock(hdev);
11481da177e4SLinus Torvalds 
114994324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
115094324962SJohan Hovold 		ret = -ENODEV;
115194324962SJohan Hovold 		goto done;
115294324962SJohan Hovold 	}
115394324962SJohan Hovold 
1154611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
1155611b30f7SMarcel Holtmann 		ret = -ERFKILL;
1156611b30f7SMarcel Holtmann 		goto done;
1157611b30f7SMarcel Holtmann 	}
1158611b30f7SMarcel Holtmann 
11591da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
11601da177e4SLinus Torvalds 		ret = -EALREADY;
11611da177e4SLinus Torvalds 		goto done;
11621da177e4SLinus Torvalds 	}
11631da177e4SLinus Torvalds 
11641da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
11651da177e4SLinus Torvalds 		ret = -EIO;
11661da177e4SLinus Torvalds 		goto done;
11671da177e4SLinus Torvalds 	}
11681da177e4SLinus Torvalds 
11691da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
11701da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1171f41c70c4SMarcel Holtmann 
1172f41c70c4SMarcel Holtmann 	if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
1173f41c70c4SMarcel Holtmann 		ret = hdev->setup(hdev);
1174f41c70c4SMarcel Holtmann 
1175f41c70c4SMarcel Holtmann 	if (!ret) {
1176f41c70c4SMarcel Holtmann 		/* Treat all non BR/EDR controllers as raw devices if
1177f41c70c4SMarcel Holtmann 		 * enable_hs is not set.
1178f41c70c4SMarcel Holtmann 		 */
1179f41c70c4SMarcel Holtmann 		if (hdev->dev_type != HCI_BREDR && !enable_hs)
1180f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
1181f41c70c4SMarcel Holtmann 
1182f41c70c4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1183f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
1184f41c70c4SMarcel Holtmann 
11850736cfa8SMarcel Holtmann 		if (!test_bit(HCI_RAW, &hdev->flags) &&
11860736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
11872177bab5SJohan Hedberg 			ret = __hci_init(hdev);
11881da177e4SLinus Torvalds 	}
11891da177e4SLinus Torvalds 
1190f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1191f41c70c4SMarcel Holtmann 
11921da177e4SLinus Torvalds 	if (!ret) {
11931da177e4SLinus Torvalds 		hci_dev_hold(hdev);
11941da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
11951da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
1196bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
11970736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
1198bb4b2a9aSAndrei Emeltchenko 		    mgmt_valid_hdev(hdev)) {
119909fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1200744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
120109fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
120256e5cb86SJohan Hedberg 		}
12031da177e4SLinus Torvalds 	} else {
12041da177e4SLinus Torvalds 		/* Init failed, cleanup */
12053eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1206c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1207b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
12081da177e4SLinus Torvalds 
12091da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
12101da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
12111da177e4SLinus Torvalds 
12121da177e4SLinus Torvalds 		if (hdev->flush)
12131da177e4SLinus Torvalds 			hdev->flush(hdev);
12141da177e4SLinus Torvalds 
12151da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
12161da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
12171da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
12181da177e4SLinus Torvalds 		}
12191da177e4SLinus Torvalds 
12201da177e4SLinus Torvalds 		hdev->close(hdev);
12211da177e4SLinus Torvalds 		hdev->flags = 0;
12221da177e4SLinus Torvalds 	}
12231da177e4SLinus Torvalds 
12241da177e4SLinus Torvalds done:
12251da177e4SLinus Torvalds 	hci_req_unlock(hdev);
12261da177e4SLinus Torvalds 	hci_dev_put(hdev);
12271da177e4SLinus Torvalds 	return ret;
12281da177e4SLinus Torvalds }
12291da177e4SLinus Torvalds 
12301da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
12311da177e4SLinus Torvalds {
12321da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
12331da177e4SLinus Torvalds 
123478c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
123578c04c0bSVinicius Costa Gomes 
12361da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
12371da177e4SLinus Torvalds 	hci_req_lock(hdev);
12381da177e4SLinus Torvalds 
12391da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
1240b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
12411da177e4SLinus Torvalds 		hci_req_unlock(hdev);
12421da177e4SLinus Torvalds 		return 0;
12431da177e4SLinus Torvalds 	}
12441da177e4SLinus Torvalds 
12453eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
12463eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1247b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
12481da177e4SLinus Torvalds 
124916ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
1250e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
125116ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
12525e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
125316ab91abSJohan Hedberg 	}
125416ab91abSJohan Hedberg 
1255a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
12567d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
12577d78525dSJohan Hedberg 
12587ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
12597ba8b4beSAndre Guedes 
126009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
12611f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
12621da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
126309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
12641da177e4SLinus Torvalds 
12651da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
12661da177e4SLinus Torvalds 
12671da177e4SLinus Torvalds 	if (hdev->flush)
12681da177e4SLinus Torvalds 		hdev->flush(hdev);
12691da177e4SLinus Torvalds 
12701da177e4SLinus Torvalds 	/* Reset device */
12711da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
12721da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
12738af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
1274a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
12751da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
127601178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
12771da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
12781da177e4SLinus Torvalds 	}
12791da177e4SLinus Torvalds 
1280c347b765SGustavo F. Padovan 	/* flush cmd  work */
1281c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
12821da177e4SLinus Torvalds 
12831da177e4SLinus Torvalds 	/* Drop queues */
12841da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
12851da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
12861da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
12871da177e4SLinus Torvalds 
12881da177e4SLinus Torvalds 	/* Drop last sent command */
12891da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
1290b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
12911da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
12921da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
12931da177e4SLinus Torvalds 	}
12941da177e4SLinus Torvalds 
1295b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
1296b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
1297b6ddb638SJohan Hedberg 
12981da177e4SLinus Torvalds 	/* After this point our queues are empty
12991da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
13001da177e4SLinus Torvalds 	hdev->close(hdev);
13011da177e4SLinus Torvalds 
130235b973c9SJohan Hedberg 	/* Clear flags */
130335b973c9SJohan Hedberg 	hdev->flags = 0;
130435b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
130535b973c9SJohan Hedberg 
1306bb4b2a9aSAndrei Emeltchenko 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
1307bb4b2a9aSAndrei Emeltchenko 	    mgmt_valid_hdev(hdev)) {
130809fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1309744cf19eSJohan Hedberg 		mgmt_powered(hdev, 0);
131009fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
13118ee56540SMarcel Holtmann 	}
13125add6af8SJohan Hedberg 
1313ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1314ced5c338SAndrei Emeltchenko 	hdev->amp_status = 0;
1315ced5c338SAndrei Emeltchenko 
1316e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
131709b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
1318e59fda8dSJohan Hedberg 
13191da177e4SLinus Torvalds 	hci_req_unlock(hdev);
13201da177e4SLinus Torvalds 
13211da177e4SLinus Torvalds 	hci_dev_put(hdev);
13221da177e4SLinus Torvalds 	return 0;
13231da177e4SLinus Torvalds }
13241da177e4SLinus Torvalds 
13251da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
13261da177e4SLinus Torvalds {
13271da177e4SLinus Torvalds 	struct hci_dev *hdev;
13281da177e4SLinus Torvalds 	int err;
13291da177e4SLinus Torvalds 
133070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
133170f23020SAndrei Emeltchenko 	if (!hdev)
13321da177e4SLinus Torvalds 		return -ENODEV;
13338ee56540SMarcel Holtmann 
13340736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
13350736cfa8SMarcel Holtmann 		err = -EBUSY;
13360736cfa8SMarcel Holtmann 		goto done;
13370736cfa8SMarcel Holtmann 	}
13380736cfa8SMarcel Holtmann 
13398ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
13408ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
13418ee56540SMarcel Holtmann 
13421da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
13438ee56540SMarcel Holtmann 
13440736cfa8SMarcel Holtmann done:
13451da177e4SLinus Torvalds 	hci_dev_put(hdev);
13461da177e4SLinus Torvalds 	return err;
13471da177e4SLinus Torvalds }
13481da177e4SLinus Torvalds 
13491da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
13501da177e4SLinus Torvalds {
13511da177e4SLinus Torvalds 	struct hci_dev *hdev;
13521da177e4SLinus Torvalds 	int ret = 0;
13531da177e4SLinus Torvalds 
135470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
135570f23020SAndrei Emeltchenko 	if (!hdev)
13561da177e4SLinus Torvalds 		return -ENODEV;
13571da177e4SLinus Torvalds 
13581da177e4SLinus Torvalds 	hci_req_lock(hdev);
13591da177e4SLinus Torvalds 
1360808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
1361808a049eSMarcel Holtmann 		ret = -ENETDOWN;
13621da177e4SLinus Torvalds 		goto done;
1363808a049eSMarcel Holtmann 	}
13641da177e4SLinus Torvalds 
13650736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
13660736cfa8SMarcel Holtmann 		ret = -EBUSY;
13670736cfa8SMarcel Holtmann 		goto done;
13680736cfa8SMarcel Holtmann 	}
13690736cfa8SMarcel Holtmann 
13701da177e4SLinus Torvalds 	/* Drop queues */
13711da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
13721da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
13731da177e4SLinus Torvalds 
137409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13751f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
13761da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
137709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13781da177e4SLinus Torvalds 
13791da177e4SLinus Torvalds 	if (hdev->flush)
13801da177e4SLinus Torvalds 		hdev->flush(hdev);
13811da177e4SLinus Torvalds 
13821da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
13836ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
13841da177e4SLinus Torvalds 
13851da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
138601178cd4SJohan Hedberg 		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
13871da177e4SLinus Torvalds 
13881da177e4SLinus Torvalds done:
13891da177e4SLinus Torvalds 	hci_req_unlock(hdev);
13901da177e4SLinus Torvalds 	hci_dev_put(hdev);
13911da177e4SLinus Torvalds 	return ret;
13921da177e4SLinus Torvalds }
13931da177e4SLinus Torvalds 
13941da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
13951da177e4SLinus Torvalds {
13961da177e4SLinus Torvalds 	struct hci_dev *hdev;
13971da177e4SLinus Torvalds 	int ret = 0;
13981da177e4SLinus Torvalds 
139970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
140070f23020SAndrei Emeltchenko 	if (!hdev)
14011da177e4SLinus Torvalds 		return -ENODEV;
14021da177e4SLinus Torvalds 
14030736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
14040736cfa8SMarcel Holtmann 		ret = -EBUSY;
14050736cfa8SMarcel Holtmann 		goto done;
14060736cfa8SMarcel Holtmann 	}
14070736cfa8SMarcel Holtmann 
14081da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
14091da177e4SLinus Torvalds 
14100736cfa8SMarcel Holtmann done:
14111da177e4SLinus Torvalds 	hci_dev_put(hdev);
14121da177e4SLinus Torvalds 	return ret;
14131da177e4SLinus Torvalds }
14141da177e4SLinus Torvalds 
14151da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
14161da177e4SLinus Torvalds {
14171da177e4SLinus Torvalds 	struct hci_dev *hdev;
14181da177e4SLinus Torvalds 	struct hci_dev_req dr;
14191da177e4SLinus Torvalds 	int err = 0;
14201da177e4SLinus Torvalds 
14211da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
14221da177e4SLinus Torvalds 		return -EFAULT;
14231da177e4SLinus Torvalds 
142470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
142570f23020SAndrei Emeltchenko 	if (!hdev)
14261da177e4SLinus Torvalds 		return -ENODEV;
14271da177e4SLinus Torvalds 
14280736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
14290736cfa8SMarcel Holtmann 		err = -EBUSY;
14300736cfa8SMarcel Holtmann 		goto done;
14310736cfa8SMarcel Holtmann 	}
14320736cfa8SMarcel Holtmann 
14331da177e4SLinus Torvalds 	switch (cmd) {
14341da177e4SLinus Torvalds 	case HCISETAUTH:
143501178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
14365f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
14371da177e4SLinus Torvalds 		break;
14381da177e4SLinus Torvalds 
14391da177e4SLinus Torvalds 	case HCISETENCRYPT:
14401da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
14411da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
14421da177e4SLinus Torvalds 			break;
14431da177e4SLinus Torvalds 		}
14441da177e4SLinus Torvalds 
14451da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
14461da177e4SLinus Torvalds 			/* Auth must be enabled first */
144701178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
14485f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
14491da177e4SLinus Torvalds 			if (err)
14501da177e4SLinus Torvalds 				break;
14511da177e4SLinus Torvalds 		}
14521da177e4SLinus Torvalds 
145301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
14545f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
14551da177e4SLinus Torvalds 		break;
14561da177e4SLinus Torvalds 
14571da177e4SLinus Torvalds 	case HCISETSCAN:
145801178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
14595f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
14601da177e4SLinus Torvalds 		break;
14611da177e4SLinus Torvalds 
14621da177e4SLinus Torvalds 	case HCISETLINKPOL:
146301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
14645f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
14651da177e4SLinus Torvalds 		break;
14661da177e4SLinus Torvalds 
14671da177e4SLinus Torvalds 	case HCISETLINKMODE:
1468e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
1469e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
1470e4e8e37cSMarcel Holtmann 		break;
1471e4e8e37cSMarcel Holtmann 
1472e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
1473e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
14741da177e4SLinus Torvalds 		break;
14751da177e4SLinus Torvalds 
14761da177e4SLinus Torvalds 	case HCISETACLMTU:
14771da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
14781da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
14791da177e4SLinus Torvalds 		break;
14801da177e4SLinus Torvalds 
14811da177e4SLinus Torvalds 	case HCISETSCOMTU:
14821da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
14831da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
14841da177e4SLinus Torvalds 		break;
14851da177e4SLinus Torvalds 
14861da177e4SLinus Torvalds 	default:
14871da177e4SLinus Torvalds 		err = -EINVAL;
14881da177e4SLinus Torvalds 		break;
14891da177e4SLinus Torvalds 	}
1490e4e8e37cSMarcel Holtmann 
14910736cfa8SMarcel Holtmann done:
14921da177e4SLinus Torvalds 	hci_dev_put(hdev);
14931da177e4SLinus Torvalds 	return err;
14941da177e4SLinus Torvalds }
14951da177e4SLinus Torvalds 
14961da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
14971da177e4SLinus Torvalds {
14988035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
14991da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
15001da177e4SLinus Torvalds 	struct hci_dev_req *dr;
15011da177e4SLinus Torvalds 	int n = 0, size, err;
15021da177e4SLinus Torvalds 	__u16 dev_num;
15031da177e4SLinus Torvalds 
15041da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
15051da177e4SLinus Torvalds 		return -EFAULT;
15061da177e4SLinus Torvalds 
15071da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
15081da177e4SLinus Torvalds 		return -EINVAL;
15091da177e4SLinus Torvalds 
15101da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
15111da177e4SLinus Torvalds 
151270f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
151370f23020SAndrei Emeltchenko 	if (!dl)
15141da177e4SLinus Torvalds 		return -ENOMEM;
15151da177e4SLinus Torvalds 
15161da177e4SLinus Torvalds 	dr = dl->dev_req;
15171da177e4SLinus Torvalds 
1518f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
15198035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
1520a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1521e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
1522c542a06cSJohan Hedberg 
1523a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1524a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1525c542a06cSJohan Hedberg 
15261da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
15271da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
1528c542a06cSJohan Hedberg 
15291da177e4SLinus Torvalds 		if (++n >= dev_num)
15301da177e4SLinus Torvalds 			break;
15311da177e4SLinus Torvalds 	}
1532f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
15331da177e4SLinus Torvalds 
15341da177e4SLinus Torvalds 	dl->dev_num = n;
15351da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
15361da177e4SLinus Torvalds 
15371da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
15381da177e4SLinus Torvalds 	kfree(dl);
15391da177e4SLinus Torvalds 
15401da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
15411da177e4SLinus Torvalds }
15421da177e4SLinus Torvalds 
15431da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
15441da177e4SLinus Torvalds {
15451da177e4SLinus Torvalds 	struct hci_dev *hdev;
15461da177e4SLinus Torvalds 	struct hci_dev_info di;
15471da177e4SLinus Torvalds 	int err = 0;
15481da177e4SLinus Torvalds 
15491da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
15501da177e4SLinus Torvalds 		return -EFAULT;
15511da177e4SLinus Torvalds 
155270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
155370f23020SAndrei Emeltchenko 	if (!hdev)
15541da177e4SLinus Torvalds 		return -ENODEV;
15551da177e4SLinus Torvalds 
1556a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
15573243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1558ab81cbf9SJohan Hedberg 
1559a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1560a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1561c542a06cSJohan Hedberg 
15621da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
15631da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
1564943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
15651da177e4SLinus Torvalds 	di.flags    = hdev->flags;
15661da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
1567572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
15681da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
15691da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
15701da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
15711da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
1572572c7f84SJohan Hedberg 	} else {
1573572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
1574572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
1575572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
1576572c7f84SJohan Hedberg 		di.sco_pkts = 0;
1577572c7f84SJohan Hedberg 	}
15781da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
15791da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
15801da177e4SLinus Torvalds 
15811da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
15821da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
15831da177e4SLinus Torvalds 
15841da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
15851da177e4SLinus Torvalds 		err = -EFAULT;
15861da177e4SLinus Torvalds 
15871da177e4SLinus Torvalds 	hci_dev_put(hdev);
15881da177e4SLinus Torvalds 
15891da177e4SLinus Torvalds 	return err;
15901da177e4SLinus Torvalds }
15911da177e4SLinus Torvalds 
15921da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
15931da177e4SLinus Torvalds 
1594611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1595611b30f7SMarcel Holtmann {
1596611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1597611b30f7SMarcel Holtmann 
1598611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1599611b30f7SMarcel Holtmann 
16000736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
16010736cfa8SMarcel Holtmann 		return -EBUSY;
16020736cfa8SMarcel Holtmann 
1603611b30f7SMarcel Holtmann 	if (!blocked)
1604611b30f7SMarcel Holtmann 		return 0;
1605611b30f7SMarcel Holtmann 
1606611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1607611b30f7SMarcel Holtmann 
1608611b30f7SMarcel Holtmann 	return 0;
1609611b30f7SMarcel Holtmann }
1610611b30f7SMarcel Holtmann 
1611611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1612611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1613611b30f7SMarcel Holtmann };
1614611b30f7SMarcel Holtmann 
1615ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1616ab81cbf9SJohan Hedberg {
1617ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
161896570ffcSJohan Hedberg 	int err;
1619ab81cbf9SJohan Hedberg 
1620ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1621ab81cbf9SJohan Hedberg 
162296570ffcSJohan Hedberg 	err = hci_dev_open(hdev->id);
162396570ffcSJohan Hedberg 	if (err < 0) {
162496570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
1625ab81cbf9SJohan Hedberg 		return;
162696570ffcSJohan Hedberg 	}
1627ab81cbf9SJohan Hedberg 
1628a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
162919202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
163019202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
1631ab81cbf9SJohan Hedberg 
1632a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1633744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1634ab81cbf9SJohan Hedberg }
1635ab81cbf9SJohan Hedberg 
1636ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1637ab81cbf9SJohan Hedberg {
16383243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
16393243553fSJohan Hedberg 					    power_off.work);
1640ab81cbf9SJohan Hedberg 
1641ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1642ab81cbf9SJohan Hedberg 
16438ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1644ab81cbf9SJohan Hedberg }
1645ab81cbf9SJohan Hedberg 
164616ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
164716ab91abSJohan Hedberg {
164816ab91abSJohan Hedberg 	struct hci_dev *hdev;
164916ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
165016ab91abSJohan Hedberg 
165116ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
165216ab91abSJohan Hedberg 
165316ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
165416ab91abSJohan Hedberg 
165509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
165616ab91abSJohan Hedberg 
165716ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
165816ab91abSJohan Hedberg 
165916ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
166016ab91abSJohan Hedberg 
166109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
166216ab91abSJohan Hedberg }
166316ab91abSJohan Hedberg 
16642aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
16652aeb9a1aSJohan Hedberg {
16664821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
16672aeb9a1aSJohan Hedberg 
16684821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
16694821002cSJohan Hedberg 		list_del(&uuid->list);
16702aeb9a1aSJohan Hedberg 		kfree(uuid);
16712aeb9a1aSJohan Hedberg 	}
16722aeb9a1aSJohan Hedberg 
16732aeb9a1aSJohan Hedberg 	return 0;
16742aeb9a1aSJohan Hedberg }
16752aeb9a1aSJohan Hedberg 
167655ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
167755ed8ca1SJohan Hedberg {
167855ed8ca1SJohan Hedberg 	struct list_head *p, *n;
167955ed8ca1SJohan Hedberg 
168055ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
168155ed8ca1SJohan Hedberg 		struct link_key *key;
168255ed8ca1SJohan Hedberg 
168355ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
168455ed8ca1SJohan Hedberg 
168555ed8ca1SJohan Hedberg 		list_del(p);
168655ed8ca1SJohan Hedberg 		kfree(key);
168755ed8ca1SJohan Hedberg 	}
168855ed8ca1SJohan Hedberg 
168955ed8ca1SJohan Hedberg 	return 0;
169055ed8ca1SJohan Hedberg }
169155ed8ca1SJohan Hedberg 
1692b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1693b899efafSVinicius Costa Gomes {
1694b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1695b899efafSVinicius Costa Gomes 
1696b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1697b899efafSVinicius Costa Gomes 		list_del(&k->list);
1698b899efafSVinicius Costa Gomes 		kfree(k);
1699b899efafSVinicius Costa Gomes 	}
1700b899efafSVinicius Costa Gomes 
1701b899efafSVinicius Costa Gomes 	return 0;
1702b899efafSVinicius Costa Gomes }
1703b899efafSVinicius Costa Gomes 
170455ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
170555ed8ca1SJohan Hedberg {
170655ed8ca1SJohan Hedberg 	struct link_key *k;
170755ed8ca1SJohan Hedberg 
17088035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
170955ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
171055ed8ca1SJohan Hedberg 			return k;
171155ed8ca1SJohan Hedberg 
171255ed8ca1SJohan Hedberg 	return NULL;
171355ed8ca1SJohan Hedberg }
171455ed8ca1SJohan Hedberg 
1715745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1716d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1717d25e28abSJohan Hedberg {
1718d25e28abSJohan Hedberg 	/* Legacy key */
1719d25e28abSJohan Hedberg 	if (key_type < 0x03)
1720745c0ce3SVishal Agarwal 		return true;
1721d25e28abSJohan Hedberg 
1722d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1723d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1724745c0ce3SVishal Agarwal 		return false;
1725d25e28abSJohan Hedberg 
1726d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1727d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1728745c0ce3SVishal Agarwal 		return false;
1729d25e28abSJohan Hedberg 
1730d25e28abSJohan Hedberg 	/* Security mode 3 case */
1731d25e28abSJohan Hedberg 	if (!conn)
1732745c0ce3SVishal Agarwal 		return true;
1733d25e28abSJohan Hedberg 
1734d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1735d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1736745c0ce3SVishal Agarwal 		return true;
1737d25e28abSJohan Hedberg 
1738d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1739d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1740745c0ce3SVishal Agarwal 		return true;
1741d25e28abSJohan Hedberg 
1742d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1743d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1744745c0ce3SVishal Agarwal 		return true;
1745d25e28abSJohan Hedberg 
1746d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1747d25e28abSJohan Hedberg 	 * persistently */
1748745c0ce3SVishal Agarwal 	return false;
1749d25e28abSJohan Hedberg }
1750d25e28abSJohan Hedberg 
1751c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
175275d262c2SVinicius Costa Gomes {
1753c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
175475d262c2SVinicius Costa Gomes 
1755c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1756c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1757c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
175875d262c2SVinicius Costa Gomes 			continue;
175975d262c2SVinicius Costa Gomes 
176075d262c2SVinicius Costa Gomes 		return k;
176175d262c2SVinicius Costa Gomes 	}
176275d262c2SVinicius Costa Gomes 
176375d262c2SVinicius Costa Gomes 	return NULL;
176475d262c2SVinicius Costa Gomes }
176575d262c2SVinicius Costa Gomes 
1766c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1767c9839a11SVinicius Costa Gomes 				     u8 addr_type)
176875d262c2SVinicius Costa Gomes {
1769c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
177075d262c2SVinicius Costa Gomes 
1771c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1772c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1773c9839a11SVinicius Costa Gomes 		    bacmp(bdaddr, &k->bdaddr) == 0)
177475d262c2SVinicius Costa Gomes 			return k;
177575d262c2SVinicius Costa Gomes 
177675d262c2SVinicius Costa Gomes 	return NULL;
177775d262c2SVinicius Costa Gomes }
177875d262c2SVinicius Costa Gomes 
1779d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1780d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
178155ed8ca1SJohan Hedberg {
178255ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1783745c0ce3SVishal Agarwal 	u8 old_key_type;
1784745c0ce3SVishal Agarwal 	bool persistent;
178555ed8ca1SJohan Hedberg 
178655ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
178755ed8ca1SJohan Hedberg 	if (old_key) {
178855ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
178955ed8ca1SJohan Hedberg 		key = old_key;
179055ed8ca1SJohan Hedberg 	} else {
179112adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
179255ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
179355ed8ca1SJohan Hedberg 		if (!key)
179455ed8ca1SJohan Hedberg 			return -ENOMEM;
179555ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
179655ed8ca1SJohan Hedberg 	}
179755ed8ca1SJohan Hedberg 
17986ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
179955ed8ca1SJohan Hedberg 
1800d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1801d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1802d25e28abSJohan Hedberg 	 * previous key */
1803d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1804a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1805d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1806655fe6ecSJohan Hedberg 		if (conn)
1807655fe6ecSJohan Hedberg 			conn->key_type = type;
1808655fe6ecSJohan Hedberg 	}
1809d25e28abSJohan Hedberg 
181055ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
18119b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
181255ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
181355ed8ca1SJohan Hedberg 
1814b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
181555ed8ca1SJohan Hedberg 		key->type = old_key_type;
18164748fed2SJohan Hedberg 	else
18174748fed2SJohan Hedberg 		key->type = type;
18184748fed2SJohan Hedberg 
18194df378a1SJohan Hedberg 	if (!new_key)
18204df378a1SJohan Hedberg 		return 0;
18214df378a1SJohan Hedberg 
18224df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
18234df378a1SJohan Hedberg 
1824744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
18254df378a1SJohan Hedberg 
18266ec5bcadSVishal Agarwal 	if (conn)
18276ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
182855ed8ca1SJohan Hedberg 
182955ed8ca1SJohan Hedberg 	return 0;
183055ed8ca1SJohan Hedberg }
183155ed8ca1SJohan Hedberg 
1832c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
18339a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
183404124681SGustavo F. Padovan 		ediv, u8 rand[8])
183575d262c2SVinicius Costa Gomes {
1836c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
183775d262c2SVinicius Costa Gomes 
1838c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1839c9839a11SVinicius Costa Gomes 		return 0;
184075d262c2SVinicius Costa Gomes 
1841c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1842c9839a11SVinicius Costa Gomes 	if (old_key)
184375d262c2SVinicius Costa Gomes 		key = old_key;
1844c9839a11SVinicius Costa Gomes 	else {
1845c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
184675d262c2SVinicius Costa Gomes 		if (!key)
184775d262c2SVinicius Costa Gomes 			return -ENOMEM;
1848c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
184975d262c2SVinicius Costa Gomes 	}
185075d262c2SVinicius Costa Gomes 
185175d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1852c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1853c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1854c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1855c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1856c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1857c9839a11SVinicius Costa Gomes 	key->type = type;
1858c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
185975d262c2SVinicius Costa Gomes 
1860c9839a11SVinicius Costa Gomes 	if (!new_key)
1861c9839a11SVinicius Costa Gomes 		return 0;
186275d262c2SVinicius Costa Gomes 
1863261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1864261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1865261cc5aaSVinicius Costa Gomes 
186675d262c2SVinicius Costa Gomes 	return 0;
186775d262c2SVinicius Costa Gomes }
186875d262c2SVinicius Costa Gomes 
186955ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
187055ed8ca1SJohan Hedberg {
187155ed8ca1SJohan Hedberg 	struct link_key *key;
187255ed8ca1SJohan Hedberg 
187355ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
187455ed8ca1SJohan Hedberg 	if (!key)
187555ed8ca1SJohan Hedberg 		return -ENOENT;
187655ed8ca1SJohan Hedberg 
18776ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
187855ed8ca1SJohan Hedberg 
187955ed8ca1SJohan Hedberg 	list_del(&key->list);
188055ed8ca1SJohan Hedberg 	kfree(key);
188155ed8ca1SJohan Hedberg 
188255ed8ca1SJohan Hedberg 	return 0;
188355ed8ca1SJohan Hedberg }
188455ed8ca1SJohan Hedberg 
1885b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1886b899efafSVinicius Costa Gomes {
1887b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1888b899efafSVinicius Costa Gomes 
1889b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1890b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1891b899efafSVinicius Costa Gomes 			continue;
1892b899efafSVinicius Costa Gomes 
18936ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1894b899efafSVinicius Costa Gomes 
1895b899efafSVinicius Costa Gomes 		list_del(&k->list);
1896b899efafSVinicius Costa Gomes 		kfree(k);
1897b899efafSVinicius Costa Gomes 	}
1898b899efafSVinicius Costa Gomes 
1899b899efafSVinicius Costa Gomes 	return 0;
1900b899efafSVinicius Costa Gomes }
1901b899efafSVinicius Costa Gomes 
19026bd32326SVille Tervo /* HCI command timer function */
1903bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
19046bd32326SVille Tervo {
19056bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
19066bd32326SVille Tervo 
1907bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
1908bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
1909bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
1910bda4f23aSAndrei Emeltchenko 
1911bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
1912bda4f23aSAndrei Emeltchenko 	} else {
19136bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
1914bda4f23aSAndrei Emeltchenko 	}
1915bda4f23aSAndrei Emeltchenko 
19166bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1917c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
19186bd32326SVille Tervo }
19196bd32326SVille Tervo 
19202763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
19212763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
19222763eda6SSzymon Janc {
19232763eda6SSzymon Janc 	struct oob_data *data;
19242763eda6SSzymon Janc 
19252763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
19262763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
19272763eda6SSzymon Janc 			return data;
19282763eda6SSzymon Janc 
19292763eda6SSzymon Janc 	return NULL;
19302763eda6SSzymon Janc }
19312763eda6SSzymon Janc 
19322763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
19332763eda6SSzymon Janc {
19342763eda6SSzymon Janc 	struct oob_data *data;
19352763eda6SSzymon Janc 
19362763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
19372763eda6SSzymon Janc 	if (!data)
19382763eda6SSzymon Janc 		return -ENOENT;
19392763eda6SSzymon Janc 
19406ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
19412763eda6SSzymon Janc 
19422763eda6SSzymon Janc 	list_del(&data->list);
19432763eda6SSzymon Janc 	kfree(data);
19442763eda6SSzymon Janc 
19452763eda6SSzymon Janc 	return 0;
19462763eda6SSzymon Janc }
19472763eda6SSzymon Janc 
19482763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
19492763eda6SSzymon Janc {
19502763eda6SSzymon Janc 	struct oob_data *data, *n;
19512763eda6SSzymon Janc 
19522763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
19532763eda6SSzymon Janc 		list_del(&data->list);
19542763eda6SSzymon Janc 		kfree(data);
19552763eda6SSzymon Janc 	}
19562763eda6SSzymon Janc 
19572763eda6SSzymon Janc 	return 0;
19582763eda6SSzymon Janc }
19592763eda6SSzymon Janc 
19602763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
19612763eda6SSzymon Janc 			    u8 *randomizer)
19622763eda6SSzymon Janc {
19632763eda6SSzymon Janc 	struct oob_data *data;
19642763eda6SSzymon Janc 
19652763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
19662763eda6SSzymon Janc 
19672763eda6SSzymon Janc 	if (!data) {
19682763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
19692763eda6SSzymon Janc 		if (!data)
19702763eda6SSzymon Janc 			return -ENOMEM;
19712763eda6SSzymon Janc 
19722763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
19732763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
19742763eda6SSzymon Janc 	}
19752763eda6SSzymon Janc 
19762763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
19772763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
19782763eda6SSzymon Janc 
19796ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
19802763eda6SSzymon Janc 
19812763eda6SSzymon Janc 	return 0;
19822763eda6SSzymon Janc }
19832763eda6SSzymon Janc 
198404124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
1985b2a66aadSAntti Julku {
1986b2a66aadSAntti Julku 	struct bdaddr_list *b;
1987b2a66aadSAntti Julku 
19888035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1989b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1990b2a66aadSAntti Julku 			return b;
1991b2a66aadSAntti Julku 
1992b2a66aadSAntti Julku 	return NULL;
1993b2a66aadSAntti Julku }
1994b2a66aadSAntti Julku 
1995b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1996b2a66aadSAntti Julku {
1997b2a66aadSAntti Julku 	struct list_head *p, *n;
1998b2a66aadSAntti Julku 
1999b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
2000b2a66aadSAntti Julku 		struct bdaddr_list *b;
2001b2a66aadSAntti Julku 
2002b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
2003b2a66aadSAntti Julku 
2004b2a66aadSAntti Julku 		list_del(p);
2005b2a66aadSAntti Julku 		kfree(b);
2006b2a66aadSAntti Julku 	}
2007b2a66aadSAntti Julku 
2008b2a66aadSAntti Julku 	return 0;
2009b2a66aadSAntti Julku }
2010b2a66aadSAntti Julku 
201188c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2012b2a66aadSAntti Julku {
2013b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2014b2a66aadSAntti Julku 
2015b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
2016b2a66aadSAntti Julku 		return -EBADF;
2017b2a66aadSAntti Julku 
20185e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
20195e762444SAntti Julku 		return -EEXIST;
2020b2a66aadSAntti Julku 
2021b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
20225e762444SAntti Julku 	if (!entry)
20235e762444SAntti Julku 		return -ENOMEM;
2024b2a66aadSAntti Julku 
2025b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2026b2a66aadSAntti Julku 
2027b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
2028b2a66aadSAntti Julku 
202988c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
2030b2a66aadSAntti Julku }
2031b2a66aadSAntti Julku 
203288c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2033b2a66aadSAntti Julku {
2034b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2035b2a66aadSAntti Julku 
20361ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
20375e762444SAntti Julku 		return hci_blacklist_clear(hdev);
2038b2a66aadSAntti Julku 
2039b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
20401ec918ceSSzymon Janc 	if (!entry)
20415e762444SAntti Julku 		return -ENOENT;
2042b2a66aadSAntti Julku 
2043b2a66aadSAntti Julku 	list_del(&entry->list);
2044b2a66aadSAntti Julku 	kfree(entry);
2045b2a66aadSAntti Julku 
204688c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
2047b2a66aadSAntti Julku }
2048b2a66aadSAntti Julku 
20494c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
20507ba8b4beSAndre Guedes {
20514c87eaabSAndre Guedes 	if (status) {
20524c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
20537ba8b4beSAndre Guedes 
20544c87eaabSAndre Guedes 		hci_dev_lock(hdev);
20554c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
20564c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
20574c87eaabSAndre Guedes 		return;
20584c87eaabSAndre Guedes 	}
20597ba8b4beSAndre Guedes }
20607ba8b4beSAndre Guedes 
20614c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
20627ba8b4beSAndre Guedes {
20634c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
20644c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
20654c87eaabSAndre Guedes 	struct hci_request req;
20664c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
20677ba8b4beSAndre Guedes 	int err;
20687ba8b4beSAndre Guedes 
20694c87eaabSAndre Guedes 	if (status) {
20704c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
20714c87eaabSAndre Guedes 		return;
20727ba8b4beSAndre Guedes 	}
20737ba8b4beSAndre Guedes 
20744c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
20754c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
20764c87eaabSAndre Guedes 		hci_dev_lock(hdev);
20774c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
20784c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
20794c87eaabSAndre Guedes 		break;
20807dbfac1dSAndre Guedes 
20814c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
20824c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
20837dbfac1dSAndre Guedes 
20847dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
20854c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
20864c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
20874c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
20884c87eaabSAndre Guedes 
20894c87eaabSAndre Guedes 		hci_dev_lock(hdev);
20904c87eaabSAndre Guedes 
20914c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
20924c87eaabSAndre Guedes 
20934c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
20944c87eaabSAndre Guedes 		if (err) {
20954c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
20964c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
20977dbfac1dSAndre Guedes 		}
20987dbfac1dSAndre Guedes 
20994c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
21004c87eaabSAndre Guedes 		break;
21014c87eaabSAndre Guedes 	}
21027dbfac1dSAndre Guedes }
21037dbfac1dSAndre Guedes 
21047ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
21057ba8b4beSAndre Guedes {
21067ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
21077ba8b4beSAndre Guedes 					    le_scan_disable.work);
21087ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
21094c87eaabSAndre Guedes 	struct hci_request req;
21104c87eaabSAndre Guedes 	int err;
21117ba8b4beSAndre Guedes 
21127ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
21137ba8b4beSAndre Guedes 
21144c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
21157ba8b4beSAndre Guedes 
21167ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
21174c87eaabSAndre Guedes 	cp.enable = LE_SCAN_DISABLE;
21184c87eaabSAndre Guedes 	hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
21197ba8b4beSAndre Guedes 
21204c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
21214c87eaabSAndre Guedes 	if (err)
21224c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
212328b75a89SAndre Guedes }
212428b75a89SAndre Guedes 
21259be0dab7SDavid Herrmann /* Alloc HCI device */
21269be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
21279be0dab7SDavid Herrmann {
21289be0dab7SDavid Herrmann 	struct hci_dev *hdev;
21299be0dab7SDavid Herrmann 
21309be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
21319be0dab7SDavid Herrmann 	if (!hdev)
21329be0dab7SDavid Herrmann 		return NULL;
21339be0dab7SDavid Herrmann 
2134b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2135b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
2136b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
2137b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03; /* No Input No Output */
2138bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2139bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2140b1b813d4SDavid Herrmann 
2141b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
2142b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
2143b1b813d4SDavid Herrmann 
2144b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
2145b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
2146b1b813d4SDavid Herrmann 
2147b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
2148b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
2149b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
2150b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
2151b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
2152b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
21536b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
2154b1b813d4SDavid Herrmann 
2155b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2156b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2157b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2158b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2159b1b813d4SDavid Herrmann 
2160b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2161b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
2162b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
2163b1b813d4SDavid Herrmann 
2164b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2165b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2166b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2167b1b813d4SDavid Herrmann 
2168b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2169b1b813d4SDavid Herrmann 
2170bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
2171b1b813d4SDavid Herrmann 
2172b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2173b1b813d4SDavid Herrmann 	discovery_init(hdev);
21749be0dab7SDavid Herrmann 
21759be0dab7SDavid Herrmann 	return hdev;
21769be0dab7SDavid Herrmann }
21779be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
21789be0dab7SDavid Herrmann 
21799be0dab7SDavid Herrmann /* Free HCI device */
21809be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
21819be0dab7SDavid Herrmann {
21829be0dab7SDavid Herrmann 	/* will free via device release */
21839be0dab7SDavid Herrmann 	put_device(&hdev->dev);
21849be0dab7SDavid Herrmann }
21859be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
21869be0dab7SDavid Herrmann 
21871da177e4SLinus Torvalds /* Register HCI device */
21881da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
21891da177e4SLinus Torvalds {
2190b1b813d4SDavid Herrmann 	int id, error;
21911da177e4SLinus Torvalds 
2192010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
21931da177e4SLinus Torvalds 		return -EINVAL;
21941da177e4SLinus Torvalds 
219508add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
219608add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
219708add513SMat Martineau 	 */
21983df92b31SSasha Levin 	switch (hdev->dev_type) {
21993df92b31SSasha Levin 	case HCI_BREDR:
22003df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
22011da177e4SLinus Torvalds 		break;
22023df92b31SSasha Levin 	case HCI_AMP:
22033df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
22043df92b31SSasha Levin 		break;
22053df92b31SSasha Levin 	default:
22063df92b31SSasha Levin 		return -EINVAL;
22071da177e4SLinus Torvalds 	}
22081da177e4SLinus Torvalds 
22093df92b31SSasha Levin 	if (id < 0)
22103df92b31SSasha Levin 		return id;
22113df92b31SSasha Levin 
22121da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
22131da177e4SLinus Torvalds 	hdev->id = id;
22142d8b3a11SAndrei Emeltchenko 
22152d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
22162d8b3a11SAndrei Emeltchenko 
2217d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
2218d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
221933ca954dSDavid Herrmann 	if (!hdev->workqueue) {
222033ca954dSDavid Herrmann 		error = -ENOMEM;
222133ca954dSDavid Herrmann 		goto err;
222233ca954dSDavid Herrmann 	}
2223f48fd9c8SMarcel Holtmann 
2224d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
2225d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
22266ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
22276ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
22286ead1bbcSJohan Hedberg 		error = -ENOMEM;
22296ead1bbcSJohan Hedberg 		goto err;
22306ead1bbcSJohan Hedberg 	}
22316ead1bbcSJohan Hedberg 
223233ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
223333ca954dSDavid Herrmann 	if (error < 0)
223433ca954dSDavid Herrmann 		goto err_wqueue;
22351da177e4SLinus Torvalds 
2236611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2237a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2238a8c5fb1aSGustavo Padovan 				    hdev);
2239611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2240611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
2241611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
2242611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
2243611b30f7SMarcel Holtmann 		}
2244611b30f7SMarcel Holtmann 	}
2245611b30f7SMarcel Holtmann 
2246a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
2247ce2be9acSAndrei Emeltchenko 
2248ce2be9acSAndrei Emeltchenko 	if (hdev->dev_type != HCI_AMP)
2249ce2be9acSAndrei Emeltchenko 		set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2250ce2be9acSAndrei Emeltchenko 
2251fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
2252fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
2253fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
2254fcee3377SGustavo Padovan 
22551da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
2256dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
22571da177e4SLinus Torvalds 
225819202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2259fbe96d6fSMarcel Holtmann 
22601da177e4SLinus Torvalds 	return id;
2261f48fd9c8SMarcel Holtmann 
226233ca954dSDavid Herrmann err_wqueue:
226333ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
22646ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
226533ca954dSDavid Herrmann err:
22663df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
2267f48fd9c8SMarcel Holtmann 
226833ca954dSDavid Herrmann 	return error;
22691da177e4SLinus Torvalds }
22701da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
22711da177e4SLinus Torvalds 
22721da177e4SLinus Torvalds /* Unregister HCI device */
227359735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
22741da177e4SLinus Torvalds {
22753df92b31SSasha Levin 	int i, id;
2276ef222013SMarcel Holtmann 
2277c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
22781da177e4SLinus Torvalds 
227994324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
228094324962SJohan Hovold 
22813df92b31SSasha Levin 	id = hdev->id;
22823df92b31SSasha Levin 
2283f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
22841da177e4SLinus Torvalds 	list_del(&hdev->list);
2285f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
22861da177e4SLinus Torvalds 
22871da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
22881da177e4SLinus Torvalds 
2289cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
2290ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
2291ef222013SMarcel Holtmann 
2292b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
2293b9b5ef18SGustavo Padovan 
2294ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2295a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
229609fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2297744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
229809fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
229956e5cb86SJohan Hedberg 	}
2300ab81cbf9SJohan Hedberg 
23012e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
23022e58ef3eSJohan Hedberg 	 * pending list */
23032e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
23042e58ef3eSJohan Hedberg 
23051da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
23061da177e4SLinus Torvalds 
2307611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2308611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2309611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2310611b30f7SMarcel Holtmann 	}
2311611b30f7SMarcel Holtmann 
2312ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
2313147e2d59SDave Young 
2314f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
23156ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2316f48fd9c8SMarcel Holtmann 
231709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
2318e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
23192aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
232055ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2321b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
23222763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
232309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2324e2e0cacbSJohan Hedberg 
2325dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
23263df92b31SSasha Levin 
23273df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
23281da177e4SLinus Torvalds }
23291da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
23301da177e4SLinus Torvalds 
23311da177e4SLinus Torvalds /* Suspend HCI device */
23321da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
23331da177e4SLinus Torvalds {
23341da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
23351da177e4SLinus Torvalds 	return 0;
23361da177e4SLinus Torvalds }
23371da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
23381da177e4SLinus Torvalds 
23391da177e4SLinus Torvalds /* Resume HCI device */
23401da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
23411da177e4SLinus Torvalds {
23421da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
23431da177e4SLinus Torvalds 	return 0;
23441da177e4SLinus Torvalds }
23451da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
23461da177e4SLinus Torvalds 
234776bca880SMarcel Holtmann /* Receive frame from HCI drivers */
234876bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
234976bca880SMarcel Holtmann {
235076bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
235176bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
235276bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
235376bca880SMarcel Holtmann 		kfree_skb(skb);
235476bca880SMarcel Holtmann 		return -ENXIO;
235576bca880SMarcel Holtmann 	}
235676bca880SMarcel Holtmann 
2357d82603c6SJorrit Schippers 	/* Incoming skb */
235876bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
235976bca880SMarcel Holtmann 
236076bca880SMarcel Holtmann 	/* Time stamp */
236176bca880SMarcel Holtmann 	__net_timestamp(skb);
236276bca880SMarcel Holtmann 
236376bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2364b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2365c78ae283SMarcel Holtmann 
236676bca880SMarcel Holtmann 	return 0;
236776bca880SMarcel Holtmann }
236876bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
236976bca880SMarcel Holtmann 
237033e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
23711e429f38SGustavo F. Padovan 			  int count, __u8 index)
237233e882a5SSuraj Sumangala {
237333e882a5SSuraj Sumangala 	int len = 0;
237433e882a5SSuraj Sumangala 	int hlen = 0;
237533e882a5SSuraj Sumangala 	int remain = count;
237633e882a5SSuraj Sumangala 	struct sk_buff *skb;
237733e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
237833e882a5SSuraj Sumangala 
237933e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
238033e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
238133e882a5SSuraj Sumangala 		return -EILSEQ;
238233e882a5SSuraj Sumangala 
238333e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
238433e882a5SSuraj Sumangala 
238533e882a5SSuraj Sumangala 	if (!skb) {
238633e882a5SSuraj Sumangala 		switch (type) {
238733e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
238833e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
238933e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
239033e882a5SSuraj Sumangala 			break;
239133e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
239233e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
239333e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
239433e882a5SSuraj Sumangala 			break;
239533e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
239633e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
239733e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
239833e882a5SSuraj Sumangala 			break;
239933e882a5SSuraj Sumangala 		}
240033e882a5SSuraj Sumangala 
24011e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
240233e882a5SSuraj Sumangala 		if (!skb)
240333e882a5SSuraj Sumangala 			return -ENOMEM;
240433e882a5SSuraj Sumangala 
240533e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
240633e882a5SSuraj Sumangala 		scb->expect = hlen;
240733e882a5SSuraj Sumangala 		scb->pkt_type = type;
240833e882a5SSuraj Sumangala 
240933e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
241033e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
241133e882a5SSuraj Sumangala 	}
241233e882a5SSuraj Sumangala 
241333e882a5SSuraj Sumangala 	while (count) {
241433e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
241589bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
241633e882a5SSuraj Sumangala 
241733e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
241833e882a5SSuraj Sumangala 
241933e882a5SSuraj Sumangala 		count -= len;
242033e882a5SSuraj Sumangala 		data += len;
242133e882a5SSuraj Sumangala 		scb->expect -= len;
242233e882a5SSuraj Sumangala 		remain = count;
242333e882a5SSuraj Sumangala 
242433e882a5SSuraj Sumangala 		switch (type) {
242533e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
242633e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
242733e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
242833e882a5SSuraj Sumangala 				scb->expect = h->plen;
242933e882a5SSuraj Sumangala 
243033e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
243133e882a5SSuraj Sumangala 					kfree_skb(skb);
243233e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
243333e882a5SSuraj Sumangala 					return -ENOMEM;
243433e882a5SSuraj Sumangala 				}
243533e882a5SSuraj Sumangala 			}
243633e882a5SSuraj Sumangala 			break;
243733e882a5SSuraj Sumangala 
243833e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
243933e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
244033e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
244133e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
244233e882a5SSuraj Sumangala 
244333e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
244433e882a5SSuraj Sumangala 					kfree_skb(skb);
244533e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
244633e882a5SSuraj Sumangala 					return -ENOMEM;
244733e882a5SSuraj Sumangala 				}
244833e882a5SSuraj Sumangala 			}
244933e882a5SSuraj Sumangala 			break;
245033e882a5SSuraj Sumangala 
245133e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
245233e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
245333e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
245433e882a5SSuraj Sumangala 				scb->expect = h->dlen;
245533e882a5SSuraj Sumangala 
245633e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
245733e882a5SSuraj Sumangala 					kfree_skb(skb);
245833e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
245933e882a5SSuraj Sumangala 					return -ENOMEM;
246033e882a5SSuraj Sumangala 				}
246133e882a5SSuraj Sumangala 			}
246233e882a5SSuraj Sumangala 			break;
246333e882a5SSuraj Sumangala 		}
246433e882a5SSuraj Sumangala 
246533e882a5SSuraj Sumangala 		if (scb->expect == 0) {
246633e882a5SSuraj Sumangala 			/* Complete frame */
246733e882a5SSuraj Sumangala 
246833e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
246933e882a5SSuraj Sumangala 			hci_recv_frame(skb);
247033e882a5SSuraj Sumangala 
247133e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
247233e882a5SSuraj Sumangala 			return remain;
247333e882a5SSuraj Sumangala 		}
247433e882a5SSuraj Sumangala 	}
247533e882a5SSuraj Sumangala 
247633e882a5SSuraj Sumangala 	return remain;
247733e882a5SSuraj Sumangala }
247833e882a5SSuraj Sumangala 
2479ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
2480ef222013SMarcel Holtmann {
2481f39a3c06SSuraj Sumangala 	int rem = 0;
2482f39a3c06SSuraj Sumangala 
2483ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
2484ef222013SMarcel Holtmann 		return -EILSEQ;
2485ef222013SMarcel Holtmann 
2486da5f6c37SGustavo F. Padovan 	while (count) {
24871e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
2488f39a3c06SSuraj Sumangala 		if (rem < 0)
2489f39a3c06SSuraj Sumangala 			return rem;
2490ef222013SMarcel Holtmann 
2491f39a3c06SSuraj Sumangala 		data += (count - rem);
2492f39a3c06SSuraj Sumangala 		count = rem;
2493f81c6224SJoe Perches 	}
2494ef222013SMarcel Holtmann 
2495f39a3c06SSuraj Sumangala 	return rem;
2496ef222013SMarcel Holtmann }
2497ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
2498ef222013SMarcel Holtmann 
249999811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
250099811510SSuraj Sumangala 
250199811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
250299811510SSuraj Sumangala {
250399811510SSuraj Sumangala 	int type;
250499811510SSuraj Sumangala 	int rem = 0;
250599811510SSuraj Sumangala 
2506da5f6c37SGustavo F. Padovan 	while (count) {
250799811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
250899811510SSuraj Sumangala 
250999811510SSuraj Sumangala 		if (!skb) {
251099811510SSuraj Sumangala 			struct { char type; } *pkt;
251199811510SSuraj Sumangala 
251299811510SSuraj Sumangala 			/* Start of the frame */
251399811510SSuraj Sumangala 			pkt = data;
251499811510SSuraj Sumangala 			type = pkt->type;
251599811510SSuraj Sumangala 
251699811510SSuraj Sumangala 			data++;
251799811510SSuraj Sumangala 			count--;
251899811510SSuraj Sumangala 		} else
251999811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
252099811510SSuraj Sumangala 
25211e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
25221e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
252399811510SSuraj Sumangala 		if (rem < 0)
252499811510SSuraj Sumangala 			return rem;
252599811510SSuraj Sumangala 
252699811510SSuraj Sumangala 		data += (count - rem);
252799811510SSuraj Sumangala 		count = rem;
2528f81c6224SJoe Perches 	}
252999811510SSuraj Sumangala 
253099811510SSuraj Sumangala 	return rem;
253199811510SSuraj Sumangala }
253299811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
253399811510SSuraj Sumangala 
25341da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
25351da177e4SLinus Torvalds 
25361da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
25371da177e4SLinus Torvalds {
25381da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
25391da177e4SLinus Torvalds 
2540f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
25411da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2542f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
25431da177e4SLinus Torvalds 
25441da177e4SLinus Torvalds 	return 0;
25451da177e4SLinus Torvalds }
25461da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
25471da177e4SLinus Torvalds 
25481da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
25491da177e4SLinus Torvalds {
25501da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
25511da177e4SLinus Torvalds 
2552f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
25531da177e4SLinus Torvalds 	list_del(&cb->list);
2554f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
25551da177e4SLinus Torvalds 
25561da177e4SLinus Torvalds 	return 0;
25571da177e4SLinus Torvalds }
25581da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
25591da177e4SLinus Torvalds 
25601da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
25611da177e4SLinus Torvalds {
25621da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
25631da177e4SLinus Torvalds 
25641da177e4SLinus Torvalds 	if (!hdev) {
25651da177e4SLinus Torvalds 		kfree_skb(skb);
25661da177e4SLinus Torvalds 		return -ENODEV;
25671da177e4SLinus Torvalds 	}
25681da177e4SLinus Torvalds 
25690d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
25701da177e4SLinus Torvalds 
25711da177e4SLinus Torvalds 	/* Time stamp */
2572a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
25731da177e4SLinus Torvalds 
2574cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2575cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2576cd82e61cSMarcel Holtmann 
2577cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2578cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2579470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
25801da177e4SLinus Torvalds 	}
25811da177e4SLinus Torvalds 
25821da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
25831da177e4SLinus Torvalds 	skb_orphan(skb);
25841da177e4SLinus Torvalds 
25851da177e4SLinus Torvalds 	return hdev->send(skb);
25861da177e4SLinus Torvalds }
25871da177e4SLinus Torvalds 
25883119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
25893119ae95SJohan Hedberg {
25903119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
25913119ae95SJohan Hedberg 	req->hdev = hdev;
25925d73e034SAndre Guedes 	req->err = 0;
25933119ae95SJohan Hedberg }
25943119ae95SJohan Hedberg 
25953119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
25963119ae95SJohan Hedberg {
25973119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
25983119ae95SJohan Hedberg 	struct sk_buff *skb;
25993119ae95SJohan Hedberg 	unsigned long flags;
26003119ae95SJohan Hedberg 
26013119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
26023119ae95SJohan Hedberg 
26035d73e034SAndre Guedes 	/* If an error occured during request building, remove all HCI
26045d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
26055d73e034SAndre Guedes 	 */
26065d73e034SAndre Guedes 	if (req->err) {
26075d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
26085d73e034SAndre Guedes 		return req->err;
26095d73e034SAndre Guedes 	}
26105d73e034SAndre Guedes 
26113119ae95SJohan Hedberg 	/* Do not allow empty requests */
26123119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
2613382b0c39SAndre Guedes 		return -ENODATA;
26143119ae95SJohan Hedberg 
26153119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
26163119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
26173119ae95SJohan Hedberg 
26183119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
26193119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
26203119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
26213119ae95SJohan Hedberg 
26223119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
26233119ae95SJohan Hedberg 
26243119ae95SJohan Hedberg 	return 0;
26253119ae95SJohan Hedberg }
26263119ae95SJohan Hedberg 
26271ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
262807dc93ddSJohan Hedberg 				       u32 plen, const void *param)
26291da177e4SLinus Torvalds {
26301da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
26311da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
26321da177e4SLinus Torvalds 	struct sk_buff *skb;
26331da177e4SLinus Torvalds 
26341da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
26351ca3a9d0SJohan Hedberg 	if (!skb)
26361ca3a9d0SJohan Hedberg 		return NULL;
26371da177e4SLinus Torvalds 
26381da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2639a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
26401da177e4SLinus Torvalds 	hdr->plen   = plen;
26411da177e4SLinus Torvalds 
26421da177e4SLinus Torvalds 	if (plen)
26431da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
26441da177e4SLinus Torvalds 
26451da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
26461da177e4SLinus Torvalds 
26470d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
26481da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2649c78ae283SMarcel Holtmann 
26501ca3a9d0SJohan Hedberg 	return skb;
26511ca3a9d0SJohan Hedberg }
26521ca3a9d0SJohan Hedberg 
26531ca3a9d0SJohan Hedberg /* Send HCI command */
265407dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
265507dc93ddSJohan Hedberg 		 const void *param)
26561ca3a9d0SJohan Hedberg {
26571ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
26581ca3a9d0SJohan Hedberg 
26591ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
26601ca3a9d0SJohan Hedberg 
26611ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
26621ca3a9d0SJohan Hedberg 	if (!skb) {
26631ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
26641ca3a9d0SJohan Hedberg 		return -ENOMEM;
26651ca3a9d0SJohan Hedberg 	}
26661ca3a9d0SJohan Hedberg 
266711714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
266811714b3dSJohan Hedberg 	 * single-command requests.
266911714b3dSJohan Hedberg 	 */
267011714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
267111714b3dSJohan Hedberg 
26721da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2673c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
26741da177e4SLinus Torvalds 
26751da177e4SLinus Torvalds 	return 0;
26761da177e4SLinus Torvalds }
26771da177e4SLinus Torvalds 
267871c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
267907dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
268007dc93ddSJohan Hedberg 		    const void *param, u8 event)
268171c76a17SJohan Hedberg {
268271c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
268371c76a17SJohan Hedberg 	struct sk_buff *skb;
268471c76a17SJohan Hedberg 
268571c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
268671c76a17SJohan Hedberg 
268734739c1eSAndre Guedes 	/* If an error occured during request building, there is no point in
268834739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
268934739c1eSAndre Guedes 	 */
269034739c1eSAndre Guedes 	if (req->err)
269134739c1eSAndre Guedes 		return;
269234739c1eSAndre Guedes 
269371c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
269471c76a17SJohan Hedberg 	if (!skb) {
26955d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
26965d73e034SAndre Guedes 		       hdev->name, opcode);
26975d73e034SAndre Guedes 		req->err = -ENOMEM;
2698e348fe6bSAndre Guedes 		return;
269971c76a17SJohan Hedberg 	}
270071c76a17SJohan Hedberg 
270171c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
270271c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
270371c76a17SJohan Hedberg 
270402350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
270502350a72SJohan Hedberg 
270671c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
270771c76a17SJohan Hedberg }
270871c76a17SJohan Hedberg 
270907dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
271007dc93ddSJohan Hedberg 		 const void *param)
271102350a72SJohan Hedberg {
271202350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
271302350a72SJohan Hedberg }
271402350a72SJohan Hedberg 
27151da177e4SLinus Torvalds /* Get data from the previously sent command */
2716a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
27171da177e4SLinus Torvalds {
27181da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
27191da177e4SLinus Torvalds 
27201da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
27211da177e4SLinus Torvalds 		return NULL;
27221da177e4SLinus Torvalds 
27231da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
27241da177e4SLinus Torvalds 
2725a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
27261da177e4SLinus Torvalds 		return NULL;
27271da177e4SLinus Torvalds 
2728f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
27291da177e4SLinus Torvalds 
27301da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
27311da177e4SLinus Torvalds }
27321da177e4SLinus Torvalds 
27331da177e4SLinus Torvalds /* Send ACL data */
27341da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
27351da177e4SLinus Torvalds {
27361da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
27371da177e4SLinus Torvalds 	int len = skb->len;
27381da177e4SLinus Torvalds 
2739badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2740badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
27419c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2742aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2743aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
27441da177e4SLinus Torvalds }
27451da177e4SLinus Torvalds 
2746ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
274773d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
27481da177e4SLinus Torvalds {
2749ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
27501da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
27511da177e4SLinus Torvalds 	struct sk_buff *list;
27521da177e4SLinus Torvalds 
2753087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
2754087bfd99SGustavo Padovan 	skb->data_len = 0;
2755087bfd99SGustavo Padovan 
2756087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2757204a6e54SAndrei Emeltchenko 
2758204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
2759204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
2760087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
2761204a6e54SAndrei Emeltchenko 		break;
2762204a6e54SAndrei Emeltchenko 	case HCI_AMP:
2763204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
2764204a6e54SAndrei Emeltchenko 		break;
2765204a6e54SAndrei Emeltchenko 	default:
2766204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2767204a6e54SAndrei Emeltchenko 		return;
2768204a6e54SAndrei Emeltchenko 	}
2769087bfd99SGustavo Padovan 
277070f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
277170f23020SAndrei Emeltchenko 	if (!list) {
27721da177e4SLinus Torvalds 		/* Non fragmented */
27731da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
27741da177e4SLinus Torvalds 
277573d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
27761da177e4SLinus Torvalds 	} else {
27771da177e4SLinus Torvalds 		/* Fragmented */
27781da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
27791da177e4SLinus Torvalds 
27801da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
27811da177e4SLinus Torvalds 
27821da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2783af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
27841da177e4SLinus Torvalds 
278573d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2786e702112fSAndrei Emeltchenko 
2787e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2788e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
27891da177e4SLinus Torvalds 		do {
27901da177e4SLinus Torvalds 			skb = list; list = list->next;
27911da177e4SLinus Torvalds 
27921da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
27930d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2794e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
27951da177e4SLinus Torvalds 
27961da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
27971da177e4SLinus Torvalds 
279873d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
27991da177e4SLinus Torvalds 		} while (list);
28001da177e4SLinus Torvalds 
2801af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
28021da177e4SLinus Torvalds 	}
280373d80debSLuiz Augusto von Dentz }
280473d80debSLuiz Augusto von Dentz 
280573d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
280673d80debSLuiz Augusto von Dentz {
2807ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
280873d80debSLuiz Augusto von Dentz 
2809f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
281073d80debSLuiz Augusto von Dentz 
281173d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
281273d80debSLuiz Augusto von Dentz 
2813ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
28141da177e4SLinus Torvalds 
28153eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
28161da177e4SLinus Torvalds }
28171da177e4SLinus Torvalds 
28181da177e4SLinus Torvalds /* Send SCO data */
28190d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
28201da177e4SLinus Torvalds {
28211da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
28221da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
28231da177e4SLinus Torvalds 
28241da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
28251da177e4SLinus Torvalds 
2826aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
28271da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
28281da177e4SLinus Torvalds 
2829badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2830badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
28319c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
28321da177e4SLinus Torvalds 
28331da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
28340d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2835c78ae283SMarcel Holtmann 
28361da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
28373eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
28381da177e4SLinus Torvalds }
28391da177e4SLinus Torvalds 
28401da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
28411da177e4SLinus Torvalds 
28421da177e4SLinus Torvalds /* HCI Connection scheduler */
28436039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
2844a8c5fb1aSGustavo Padovan 				     int *quote)
28451da177e4SLinus Torvalds {
28461da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
28478035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
2848abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
28491da177e4SLinus Torvalds 
28501da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
28511da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2852bf4c6325SGustavo F. Padovan 
2853bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2854bf4c6325SGustavo F. Padovan 
2855bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2856769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
28571da177e4SLinus Torvalds 			continue;
2858769be974SMarcel Holtmann 
2859769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2860769be974SMarcel Holtmann 			continue;
2861769be974SMarcel Holtmann 
28621da177e4SLinus Torvalds 		num++;
28631da177e4SLinus Torvalds 
28641da177e4SLinus Torvalds 		if (c->sent < min) {
28651da177e4SLinus Torvalds 			min  = c->sent;
28661da177e4SLinus Torvalds 			conn = c;
28671da177e4SLinus Torvalds 		}
286852087a79SLuiz Augusto von Dentz 
286952087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
287052087a79SLuiz Augusto von Dentz 			break;
28711da177e4SLinus Torvalds 	}
28721da177e4SLinus Torvalds 
2873bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2874bf4c6325SGustavo F. Padovan 
28751da177e4SLinus Torvalds 	if (conn) {
28766ed58ec5SVille Tervo 		int cnt, q;
28776ed58ec5SVille Tervo 
28786ed58ec5SVille Tervo 		switch (conn->type) {
28796ed58ec5SVille Tervo 		case ACL_LINK:
28806ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
28816ed58ec5SVille Tervo 			break;
28826ed58ec5SVille Tervo 		case SCO_LINK:
28836ed58ec5SVille Tervo 		case ESCO_LINK:
28846ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
28856ed58ec5SVille Tervo 			break;
28866ed58ec5SVille Tervo 		case LE_LINK:
28876ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
28886ed58ec5SVille Tervo 			break;
28896ed58ec5SVille Tervo 		default:
28906ed58ec5SVille Tervo 			cnt = 0;
28916ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
28926ed58ec5SVille Tervo 		}
28936ed58ec5SVille Tervo 
28946ed58ec5SVille Tervo 		q = cnt / num;
28951da177e4SLinus Torvalds 		*quote = q ? q : 1;
28961da177e4SLinus Torvalds 	} else
28971da177e4SLinus Torvalds 		*quote = 0;
28981da177e4SLinus Torvalds 
28991da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
29001da177e4SLinus Torvalds 	return conn;
29011da177e4SLinus Torvalds }
29021da177e4SLinus Torvalds 
29036039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
29041da177e4SLinus Torvalds {
29051da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
29061da177e4SLinus Torvalds 	struct hci_conn *c;
29071da177e4SLinus Torvalds 
2908bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
29091da177e4SLinus Torvalds 
2910bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2911bf4c6325SGustavo F. Padovan 
29121da177e4SLinus Torvalds 	/* Kill stalled connections */
2913bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2914bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
29156ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
29166ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
2917bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
29181da177e4SLinus Torvalds 		}
29191da177e4SLinus Torvalds 	}
2920bf4c6325SGustavo F. Padovan 
2921bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
29221da177e4SLinus Torvalds }
29231da177e4SLinus Torvalds 
29246039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
292573d80debSLuiz Augusto von Dentz 				      int *quote)
292673d80debSLuiz Augusto von Dentz {
292773d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
292873d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
2929abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
293073d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
293173d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
293273d80debSLuiz Augusto von Dentz 
293373d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
293473d80debSLuiz Augusto von Dentz 
2935bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2936bf4c6325SGustavo F. Padovan 
2937bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
293873d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
293973d80debSLuiz Augusto von Dentz 
294073d80debSLuiz Augusto von Dentz 		if (conn->type != type)
294173d80debSLuiz Augusto von Dentz 			continue;
294273d80debSLuiz Augusto von Dentz 
294373d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
294473d80debSLuiz Augusto von Dentz 			continue;
294573d80debSLuiz Augusto von Dentz 
294673d80debSLuiz Augusto von Dentz 		conn_num++;
294773d80debSLuiz Augusto von Dentz 
29488192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
294973d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
295073d80debSLuiz Augusto von Dentz 
295173d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
295273d80debSLuiz Augusto von Dentz 				continue;
295373d80debSLuiz Augusto von Dentz 
295473d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
295573d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
295673d80debSLuiz Augusto von Dentz 				continue;
295773d80debSLuiz Augusto von Dentz 
295873d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
295973d80debSLuiz Augusto von Dentz 				num = 0;
296073d80debSLuiz Augusto von Dentz 				min = ~0;
296173d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
296273d80debSLuiz Augusto von Dentz 			}
296373d80debSLuiz Augusto von Dentz 
296473d80debSLuiz Augusto von Dentz 			num++;
296573d80debSLuiz Augusto von Dentz 
296673d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
296773d80debSLuiz Augusto von Dentz 				min  = conn->sent;
296873d80debSLuiz Augusto von Dentz 				chan = tmp;
296973d80debSLuiz Augusto von Dentz 			}
297073d80debSLuiz Augusto von Dentz 		}
297173d80debSLuiz Augusto von Dentz 
297273d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
297373d80debSLuiz Augusto von Dentz 			break;
297473d80debSLuiz Augusto von Dentz 	}
297573d80debSLuiz Augusto von Dentz 
2976bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2977bf4c6325SGustavo F. Padovan 
297873d80debSLuiz Augusto von Dentz 	if (!chan)
297973d80debSLuiz Augusto von Dentz 		return NULL;
298073d80debSLuiz Augusto von Dentz 
298173d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
298273d80debSLuiz Augusto von Dentz 	case ACL_LINK:
298373d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
298473d80debSLuiz Augusto von Dentz 		break;
2985bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
2986bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
2987bd1eb66bSAndrei Emeltchenko 		break;
298873d80debSLuiz Augusto von Dentz 	case SCO_LINK:
298973d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
299073d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
299173d80debSLuiz Augusto von Dentz 		break;
299273d80debSLuiz Augusto von Dentz 	case LE_LINK:
299373d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
299473d80debSLuiz Augusto von Dentz 		break;
299573d80debSLuiz Augusto von Dentz 	default:
299673d80debSLuiz Augusto von Dentz 		cnt = 0;
299773d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
299873d80debSLuiz Augusto von Dentz 	}
299973d80debSLuiz Augusto von Dentz 
300073d80debSLuiz Augusto von Dentz 	q = cnt / num;
300173d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
300273d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
300373d80debSLuiz Augusto von Dentz 	return chan;
300473d80debSLuiz Augusto von Dentz }
300573d80debSLuiz Augusto von Dentz 
300602b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
300702b20f0bSLuiz Augusto von Dentz {
300802b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
300902b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
301002b20f0bSLuiz Augusto von Dentz 	int num = 0;
301102b20f0bSLuiz Augusto von Dentz 
301202b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
301302b20f0bSLuiz Augusto von Dentz 
3014bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3015bf4c6325SGustavo F. Padovan 
3016bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
301702b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
301802b20f0bSLuiz Augusto von Dentz 
301902b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
302002b20f0bSLuiz Augusto von Dentz 			continue;
302102b20f0bSLuiz Augusto von Dentz 
302202b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
302302b20f0bSLuiz Augusto von Dentz 			continue;
302402b20f0bSLuiz Augusto von Dentz 
302502b20f0bSLuiz Augusto von Dentz 		num++;
302602b20f0bSLuiz Augusto von Dentz 
30278192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
302802b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
302902b20f0bSLuiz Augusto von Dentz 
303002b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
303102b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
303202b20f0bSLuiz Augusto von Dentz 				continue;
303302b20f0bSLuiz Augusto von Dentz 			}
303402b20f0bSLuiz Augusto von Dentz 
303502b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
303602b20f0bSLuiz Augusto von Dentz 				continue;
303702b20f0bSLuiz Augusto von Dentz 
303802b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
303902b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
304002b20f0bSLuiz Augusto von Dentz 				continue;
304102b20f0bSLuiz Augusto von Dentz 
304202b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
304302b20f0bSLuiz Augusto von Dentz 
304402b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
304502b20f0bSLuiz Augusto von Dentz 			       skb->priority);
304602b20f0bSLuiz Augusto von Dentz 		}
304702b20f0bSLuiz Augusto von Dentz 
304802b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
304902b20f0bSLuiz Augusto von Dentz 			break;
305002b20f0bSLuiz Augusto von Dentz 	}
3051bf4c6325SGustavo F. Padovan 
3052bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3053bf4c6325SGustavo F. Padovan 
305402b20f0bSLuiz Augusto von Dentz }
305502b20f0bSLuiz Augusto von Dentz 
3056b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3057b71d385aSAndrei Emeltchenko {
3058b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3059b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3060b71d385aSAndrei Emeltchenko }
3061b71d385aSAndrei Emeltchenko 
30626039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
30631da177e4SLinus Torvalds {
30641da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
30651da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
30661da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
306763d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
30685f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
3069bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
30701da177e4SLinus Torvalds 	}
307163d2bc1bSAndrei Emeltchenko }
30721da177e4SLinus Torvalds 
30736039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
307463d2bc1bSAndrei Emeltchenko {
307563d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
307663d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
307763d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
307863d2bc1bSAndrei Emeltchenko 	int quote;
307963d2bc1bSAndrei Emeltchenko 
308063d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
308104837f64SMarcel Holtmann 
308273d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
308373d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3084ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3085ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
308673d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
308773d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
308873d80debSLuiz Augusto von Dentz 
3089ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3090ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3091ec1cce24SLuiz Augusto von Dentz 				break;
3092ec1cce24SLuiz Augusto von Dentz 
3093ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3094ec1cce24SLuiz Augusto von Dentz 
309573d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
309673d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
309704837f64SMarcel Holtmann 
30981da177e4SLinus Torvalds 			hci_send_frame(skb);
30991da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
31001da177e4SLinus Torvalds 
31011da177e4SLinus Torvalds 			hdev->acl_cnt--;
310273d80debSLuiz Augusto von Dentz 			chan->sent++;
310373d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
31041da177e4SLinus Torvalds 		}
31051da177e4SLinus Torvalds 	}
310602b20f0bSLuiz Augusto von Dentz 
310702b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
310802b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
31091da177e4SLinus Torvalds }
31101da177e4SLinus Torvalds 
31116039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3112b71d385aSAndrei Emeltchenko {
311363d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3114b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3115b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3116b71d385aSAndrei Emeltchenko 	int quote;
3117bd1eb66bSAndrei Emeltchenko 	u8 type;
3118b71d385aSAndrei Emeltchenko 
311963d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
3120b71d385aSAndrei Emeltchenko 
3121bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3122bd1eb66bSAndrei Emeltchenko 
3123bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3124bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3125bd1eb66bSAndrei Emeltchenko 	else
3126bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3127bd1eb66bSAndrei Emeltchenko 
3128b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3129bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3130b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3131b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3132b71d385aSAndrei Emeltchenko 			int blocks;
3133b71d385aSAndrei Emeltchenko 
3134b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3135b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3136b71d385aSAndrei Emeltchenko 
3137b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3138b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3139b71d385aSAndrei Emeltchenko 				break;
3140b71d385aSAndrei Emeltchenko 
3141b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3142b71d385aSAndrei Emeltchenko 
3143b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3144b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3145b71d385aSAndrei Emeltchenko 				return;
3146b71d385aSAndrei Emeltchenko 
3147b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3148b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3149b71d385aSAndrei Emeltchenko 
3150b71d385aSAndrei Emeltchenko 			hci_send_frame(skb);
3151b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3152b71d385aSAndrei Emeltchenko 
3153b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3154b71d385aSAndrei Emeltchenko 			quote -= blocks;
3155b71d385aSAndrei Emeltchenko 
3156b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3157b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3158b71d385aSAndrei Emeltchenko 		}
3159b71d385aSAndrei Emeltchenko 	}
3160b71d385aSAndrei Emeltchenko 
3161b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3162bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3163b71d385aSAndrei Emeltchenko }
3164b71d385aSAndrei Emeltchenko 
31656039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3166b71d385aSAndrei Emeltchenko {
3167b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3168b71d385aSAndrei Emeltchenko 
3169bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3170bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
3171bd1eb66bSAndrei Emeltchenko 		return;
3172bd1eb66bSAndrei Emeltchenko 
3173bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3174bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3175b71d385aSAndrei Emeltchenko 		return;
3176b71d385aSAndrei Emeltchenko 
3177b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3178b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3179b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3180b71d385aSAndrei Emeltchenko 		break;
3181b71d385aSAndrei Emeltchenko 
3182b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3183b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3184b71d385aSAndrei Emeltchenko 		break;
3185b71d385aSAndrei Emeltchenko 	}
3186b71d385aSAndrei Emeltchenko }
3187b71d385aSAndrei Emeltchenko 
31881da177e4SLinus Torvalds /* Schedule SCO */
31896039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
31901da177e4SLinus Torvalds {
31911da177e4SLinus Torvalds 	struct hci_conn *conn;
31921da177e4SLinus Torvalds 	struct sk_buff *skb;
31931da177e4SLinus Torvalds 	int quote;
31941da177e4SLinus Torvalds 
31951da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
31961da177e4SLinus Torvalds 
319752087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
319852087a79SLuiz Augusto von Dentz 		return;
319952087a79SLuiz Augusto von Dentz 
32001da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
32011da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
32021da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
32031da177e4SLinus Torvalds 			hci_send_frame(skb);
32041da177e4SLinus Torvalds 
32051da177e4SLinus Torvalds 			conn->sent++;
32061da177e4SLinus Torvalds 			if (conn->sent == ~0)
32071da177e4SLinus Torvalds 				conn->sent = 0;
32081da177e4SLinus Torvalds 		}
32091da177e4SLinus Torvalds 	}
32101da177e4SLinus Torvalds }
32111da177e4SLinus Torvalds 
32126039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
3213b6a0dc82SMarcel Holtmann {
3214b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
3215b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
3216b6a0dc82SMarcel Holtmann 	int quote;
3217b6a0dc82SMarcel Holtmann 
3218b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
3219b6a0dc82SMarcel Holtmann 
322052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
322152087a79SLuiz Augusto von Dentz 		return;
322252087a79SLuiz Augusto von Dentz 
32238fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
32248fc9ced3SGustavo Padovan 						     &quote))) {
3225b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
3226b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
3227b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
3228b6a0dc82SMarcel Holtmann 
3229b6a0dc82SMarcel Holtmann 			conn->sent++;
3230b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
3231b6a0dc82SMarcel Holtmann 				conn->sent = 0;
3232b6a0dc82SMarcel Holtmann 		}
3233b6a0dc82SMarcel Holtmann 	}
3234b6a0dc82SMarcel Holtmann }
3235b6a0dc82SMarcel Holtmann 
32366039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
32376ed58ec5SVille Tervo {
323873d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
32396ed58ec5SVille Tervo 	struct sk_buff *skb;
324002b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
32416ed58ec5SVille Tervo 
32426ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
32436ed58ec5SVille Tervo 
324452087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
324552087a79SLuiz Augusto von Dentz 		return;
324652087a79SLuiz Augusto von Dentz 
32476ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
32486ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
32496ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
3250bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
32516ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
3252bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
32536ed58ec5SVille Tervo 	}
32546ed58ec5SVille Tervo 
32556ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
325602b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
325773d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3258ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3259ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
326073d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
326173d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
32626ed58ec5SVille Tervo 
3263ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3264ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3265ec1cce24SLuiz Augusto von Dentz 				break;
3266ec1cce24SLuiz Augusto von Dentz 
3267ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3268ec1cce24SLuiz Augusto von Dentz 
32696ed58ec5SVille Tervo 			hci_send_frame(skb);
32706ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
32716ed58ec5SVille Tervo 
32726ed58ec5SVille Tervo 			cnt--;
327373d80debSLuiz Augusto von Dentz 			chan->sent++;
327473d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
32756ed58ec5SVille Tervo 		}
32766ed58ec5SVille Tervo 	}
327773d80debSLuiz Augusto von Dentz 
32786ed58ec5SVille Tervo 	if (hdev->le_pkts)
32796ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
32806ed58ec5SVille Tervo 	else
32816ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
328202b20f0bSLuiz Augusto von Dentz 
328302b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
328402b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
32856ed58ec5SVille Tervo }
32866ed58ec5SVille Tervo 
32873eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
32881da177e4SLinus Torvalds {
32893eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
32901da177e4SLinus Torvalds 	struct sk_buff *skb;
32911da177e4SLinus Torvalds 
32926ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
32936ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
32941da177e4SLinus Torvalds 
32951da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
32961da177e4SLinus Torvalds 
32971da177e4SLinus Torvalds 	hci_sched_acl(hdev);
32981da177e4SLinus Torvalds 
32991da177e4SLinus Torvalds 	hci_sched_sco(hdev);
33001da177e4SLinus Torvalds 
3301b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
3302b6a0dc82SMarcel Holtmann 
33036ed58ec5SVille Tervo 	hci_sched_le(hdev);
33046ed58ec5SVille Tervo 
33051da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
33061da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
33071da177e4SLinus Torvalds 		hci_send_frame(skb);
33081da177e4SLinus Torvalds }
33091da177e4SLinus Torvalds 
331025985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
33111da177e4SLinus Torvalds 
33121da177e4SLinus Torvalds /* ACL data packet */
33136039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
33141da177e4SLinus Torvalds {
33151da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
33161da177e4SLinus Torvalds 	struct hci_conn *conn;
33171da177e4SLinus Torvalds 	__u16 handle, flags;
33181da177e4SLinus Torvalds 
33191da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
33201da177e4SLinus Torvalds 
33211da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
33221da177e4SLinus Torvalds 	flags  = hci_flags(handle);
33231da177e4SLinus Torvalds 	handle = hci_handle(handle);
33241da177e4SLinus Torvalds 
3325f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3326a8c5fb1aSGustavo Padovan 	       handle, flags);
33271da177e4SLinus Torvalds 
33281da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
33291da177e4SLinus Torvalds 
33301da177e4SLinus Torvalds 	hci_dev_lock(hdev);
33311da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
33321da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
33331da177e4SLinus Torvalds 
33341da177e4SLinus Torvalds 	if (conn) {
333565983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
333604837f64SMarcel Holtmann 
33371da177e4SLinus Torvalds 		/* Send to upper protocol */
3338686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
33391da177e4SLinus Torvalds 		return;
33401da177e4SLinus Torvalds 	} else {
33411da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
33421da177e4SLinus Torvalds 		       hdev->name, handle);
33431da177e4SLinus Torvalds 	}
33441da177e4SLinus Torvalds 
33451da177e4SLinus Torvalds 	kfree_skb(skb);
33461da177e4SLinus Torvalds }
33471da177e4SLinus Torvalds 
33481da177e4SLinus Torvalds /* SCO data packet */
33496039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
33501da177e4SLinus Torvalds {
33511da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
33521da177e4SLinus Torvalds 	struct hci_conn *conn;
33531da177e4SLinus Torvalds 	__u16 handle;
33541da177e4SLinus Torvalds 
33551da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
33561da177e4SLinus Torvalds 
33571da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
33581da177e4SLinus Torvalds 
3359f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
33601da177e4SLinus Torvalds 
33611da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
33621da177e4SLinus Torvalds 
33631da177e4SLinus Torvalds 	hci_dev_lock(hdev);
33641da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
33651da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
33661da177e4SLinus Torvalds 
33671da177e4SLinus Torvalds 	if (conn) {
33681da177e4SLinus Torvalds 		/* Send to upper protocol */
3369686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
33701da177e4SLinus Torvalds 		return;
33711da177e4SLinus Torvalds 	} else {
33721da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
33731da177e4SLinus Torvalds 		       hdev->name, handle);
33741da177e4SLinus Torvalds 	}
33751da177e4SLinus Torvalds 
33761da177e4SLinus Torvalds 	kfree_skb(skb);
33771da177e4SLinus Torvalds }
33781da177e4SLinus Torvalds 
33799238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
33809238f36aSJohan Hedberg {
33819238f36aSJohan Hedberg 	struct sk_buff *skb;
33829238f36aSJohan Hedberg 
33839238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
33849238f36aSJohan Hedberg 	if (!skb)
33859238f36aSJohan Hedberg 		return true;
33869238f36aSJohan Hedberg 
33879238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
33889238f36aSJohan Hedberg }
33899238f36aSJohan Hedberg 
339042c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
339142c6b129SJohan Hedberg {
339242c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
339342c6b129SJohan Hedberg 	struct sk_buff *skb;
339442c6b129SJohan Hedberg 	u16 opcode;
339542c6b129SJohan Hedberg 
339642c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
339742c6b129SJohan Hedberg 		return;
339842c6b129SJohan Hedberg 
339942c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
340042c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
340142c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
340242c6b129SJohan Hedberg 		return;
340342c6b129SJohan Hedberg 
340442c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
340542c6b129SJohan Hedberg 	if (!skb)
340642c6b129SJohan Hedberg 		return;
340742c6b129SJohan Hedberg 
340842c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
340942c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
341042c6b129SJohan Hedberg }
341142c6b129SJohan Hedberg 
34129238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
34139238f36aSJohan Hedberg {
34149238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
34159238f36aSJohan Hedberg 	struct sk_buff *skb;
34169238f36aSJohan Hedberg 	unsigned long flags;
34179238f36aSJohan Hedberg 
34189238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
34199238f36aSJohan Hedberg 
342042c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
342142c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
34229238f36aSJohan Hedberg 	 */
342342c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
342442c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
342542c6b129SJohan Hedberg 		 * reset complete event during init and any pending
342642c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
342742c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
342842c6b129SJohan Hedberg 		 * command.
342942c6b129SJohan Hedberg 		 */
343042c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
343142c6b129SJohan Hedberg 			hci_resend_last(hdev);
343242c6b129SJohan Hedberg 
34339238f36aSJohan Hedberg 		return;
343442c6b129SJohan Hedberg 	}
34359238f36aSJohan Hedberg 
34369238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
34379238f36aSJohan Hedberg 	 * this request the request is not yet complete.
34389238f36aSJohan Hedberg 	 */
34399238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
34409238f36aSJohan Hedberg 		return;
34419238f36aSJohan Hedberg 
34429238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
34439238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
34449238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
34459238f36aSJohan Hedberg 	 */
34469238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
34479238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
344853e21fbcSJohan Hedberg 
344953e21fbcSJohan Hedberg 		if (req_complete) {
345053e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
345153e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
345253e21fbcSJohan Hedberg 			 * this function gets called again.
345353e21fbcSJohan Hedberg 			 */
345453e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
345553e21fbcSJohan Hedberg 
34569238f36aSJohan Hedberg 			goto call_complete;
34579238f36aSJohan Hedberg 		}
345853e21fbcSJohan Hedberg 	}
34599238f36aSJohan Hedberg 
34609238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
34619238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
34629238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
34639238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
34649238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
34659238f36aSJohan Hedberg 			break;
34669238f36aSJohan Hedberg 		}
34679238f36aSJohan Hedberg 
34689238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
34699238f36aSJohan Hedberg 		kfree_skb(skb);
34709238f36aSJohan Hedberg 	}
34719238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
34729238f36aSJohan Hedberg 
34739238f36aSJohan Hedberg call_complete:
34749238f36aSJohan Hedberg 	if (req_complete)
34759238f36aSJohan Hedberg 		req_complete(hdev, status);
34769238f36aSJohan Hedberg }
34779238f36aSJohan Hedberg 
3478b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
34791da177e4SLinus Torvalds {
3480b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
34811da177e4SLinus Torvalds 	struct sk_buff *skb;
34821da177e4SLinus Torvalds 
34831da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
34841da177e4SLinus Torvalds 
34851da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
3486cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
3487cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
3488cd82e61cSMarcel Holtmann 
34891da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
34901da177e4SLinus Torvalds 			/* Send copy to the sockets */
3491470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
34921da177e4SLinus Torvalds 		}
34931da177e4SLinus Torvalds 
34940736cfa8SMarcel Holtmann 		if (test_bit(HCI_RAW, &hdev->flags) ||
34950736cfa8SMarcel Holtmann 		    test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
34961da177e4SLinus Torvalds 			kfree_skb(skb);
34971da177e4SLinus Torvalds 			continue;
34981da177e4SLinus Torvalds 		}
34991da177e4SLinus Torvalds 
35001da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
35011da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
35020d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
35031da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
35041da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
35051da177e4SLinus Torvalds 				kfree_skb(skb);
35061da177e4SLinus Torvalds 				continue;
35073ff50b79SStephen Hemminger 			}
35081da177e4SLinus Torvalds 		}
35091da177e4SLinus Torvalds 
35101da177e4SLinus Torvalds 		/* Process frame */
35110d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
35121da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
3513b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
35141da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
35151da177e4SLinus Torvalds 			break;
35161da177e4SLinus Torvalds 
35171da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
35181da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
35191da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
35201da177e4SLinus Torvalds 			break;
35211da177e4SLinus Torvalds 
35221da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
35231da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
35241da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
35251da177e4SLinus Torvalds 			break;
35261da177e4SLinus Torvalds 
35271da177e4SLinus Torvalds 		default:
35281da177e4SLinus Torvalds 			kfree_skb(skb);
35291da177e4SLinus Torvalds 			break;
35301da177e4SLinus Torvalds 		}
35311da177e4SLinus Torvalds 	}
35321da177e4SLinus Torvalds }
35331da177e4SLinus Torvalds 
3534c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
35351da177e4SLinus Torvalds {
3536c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
35371da177e4SLinus Torvalds 	struct sk_buff *skb;
35381da177e4SLinus Torvalds 
35392104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
35402104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
35411da177e4SLinus Torvalds 
35421da177e4SLinus Torvalds 	/* Send queued commands */
35435a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
35445a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
35455a08ecceSAndrei Emeltchenko 		if (!skb)
35465a08ecceSAndrei Emeltchenko 			return;
35475a08ecceSAndrei Emeltchenko 
35481da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
35491da177e4SLinus Torvalds 
355070f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
355170f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
35521da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
35531da177e4SLinus Torvalds 			hci_send_frame(skb);
35547bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
35557bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
35567bdb8a5cSSzymon Janc 			else
35576bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
35585f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
35591da177e4SLinus Torvalds 		} else {
35601da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
3561c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
35621da177e4SLinus Torvalds 		}
35631da177e4SLinus Torvalds 	}
35641da177e4SLinus Torvalds }
35652519a1fcSAndre Guedes 
356631f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type)
356731f7956cSAndre Guedes {
356831f7956cSAndre Guedes 	switch (bdaddr_type) {
356931f7956cSAndre Guedes 	case BDADDR_LE_PUBLIC:
357031f7956cSAndre Guedes 		return ADDR_LE_DEV_PUBLIC;
357131f7956cSAndre Guedes 
357231f7956cSAndre Guedes 	default:
357331f7956cSAndre Guedes 		/* Fallback to LE Random address type */
357431f7956cSAndre Guedes 		return ADDR_LE_DEV_RANDOM;
357531f7956cSAndre Guedes 	}
357631f7956cSAndre Guedes }
3577