xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 4c87eaab)
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 */
4572177bab5SJohan Hedberg 	}
4582177bab5SJohan Hedberg 
4592177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4602177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4612177bab5SJohan Hedberg 
4622177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
4632177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
4642177bab5SJohan Hedberg 
4652177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
4662177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
4672177bab5SJohan Hedberg 
4682177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
4692177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
4702177bab5SJohan Hedberg 
4712177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
4722177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
4732177bab5SJohan Hedberg 
4742177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
4752177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
4762177bab5SJohan Hedberg 
4772177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
4782177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
4792177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
4802177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
4812177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
4822177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
4832177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
4842177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
4852177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
4862177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
4872177bab5SJohan Hedberg 					 * Features Notification
4882177bab5SJohan Hedberg 					 */
4892177bab5SJohan Hedberg 	}
4902177bab5SJohan Hedberg 
4912177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
4922177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
4932177bab5SJohan Hedberg 
49442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
4952177bab5SJohan Hedberg 
4962177bab5SJohan Hedberg 	if (lmp_le_capable(hdev)) {
4972177bab5SJohan Hedberg 		memset(events, 0, sizeof(events));
4982177bab5SJohan Hedberg 		events[0] = 0x1f;
49942c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
5002177bab5SJohan Hedberg 			    sizeof(events), events);
5012177bab5SJohan Hedberg 	}
5022177bab5SJohan Hedberg }
5032177bab5SJohan Hedberg 
50442c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
5052177bab5SJohan Hedberg {
50642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
50742c6b129SJohan Hedberg 
5082177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
50942c6b129SJohan Hedberg 		bredr_setup(req);
5102177bab5SJohan Hedberg 
5112177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
51242c6b129SJohan Hedberg 		le_setup(req);
5132177bab5SJohan Hedberg 
51442c6b129SJohan Hedberg 	hci_setup_event_mask(req);
5152177bab5SJohan Hedberg 
5162177bab5SJohan Hedberg 	if (hdev->hci_ver > BLUETOOTH_VER_1_1)
51742c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
5182177bab5SJohan Hedberg 
5192177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5202177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
5212177bab5SJohan Hedberg 			u8 mode = 0x01;
52242c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
5232177bab5SJohan Hedberg 				    sizeof(mode), &mode);
5242177bab5SJohan Hedberg 		} else {
5252177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
5262177bab5SJohan Hedberg 
5272177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
5282177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
5292177bab5SJohan Hedberg 
53042c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
5312177bab5SJohan Hedberg 		}
5322177bab5SJohan Hedberg 	}
5332177bab5SJohan Hedberg 
5342177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
53542c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
5362177bab5SJohan Hedberg 
5372177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
53842c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
5392177bab5SJohan Hedberg 
5402177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
5412177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
5422177bab5SJohan Hedberg 
5432177bab5SJohan Hedberg 		cp.page = 0x01;
54442c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
54542c6b129SJohan Hedberg 			    sizeof(cp), &cp);
5462177bab5SJohan Hedberg 	}
5472177bab5SJohan Hedberg 
5482177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
5492177bab5SJohan Hedberg 		u8 enable = 1;
55042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
5512177bab5SJohan Hedberg 			    &enable);
5522177bab5SJohan Hedberg 	}
5532177bab5SJohan Hedberg }
5542177bab5SJohan Hedberg 
55542c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
5562177bab5SJohan Hedberg {
55742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5582177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
5592177bab5SJohan Hedberg 	u16 link_policy = 0;
5602177bab5SJohan Hedberg 
5612177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
5622177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
5632177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
5642177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
5652177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
5662177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
5672177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
5682177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
5692177bab5SJohan Hedberg 
5702177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
57142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
5722177bab5SJohan Hedberg }
5732177bab5SJohan Hedberg 
57442c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
5752177bab5SJohan Hedberg {
57642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5772177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
5782177bab5SJohan Hedberg 
579c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
580c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
581c73eee91SJohan Hedberg 		return;
582c73eee91SJohan Hedberg 
5832177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
5842177bab5SJohan Hedberg 
5852177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
5862177bab5SJohan Hedberg 		cp.le = 0x01;
5872177bab5SJohan Hedberg 		cp.simul = lmp_le_br_capable(hdev);
5882177bab5SJohan Hedberg 	}
5892177bab5SJohan Hedberg 
5902177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
59142c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
5922177bab5SJohan Hedberg 			    &cp);
5932177bab5SJohan Hedberg }
5942177bab5SJohan Hedberg 
59542c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
5962177bab5SJohan Hedberg {
59742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
598d2c5d77fSJohan Hedberg 	u8 p;
59942c6b129SJohan Hedberg 
60059f45d57SJohan Hedberg 	/* Only send HCI_Delete_Stored_Link_Key if it is supported */
60159f45d57SJohan Hedberg 	if (hdev->commands[6] & 0x80) {
60259f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
60359f45d57SJohan Hedberg 
60459f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
60559f45d57SJohan Hedberg 		cp.delete_all = 0x01;
60659f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
60759f45d57SJohan Hedberg 			    sizeof(cp), &cp);
60859f45d57SJohan Hedberg 	}
60959f45d57SJohan Hedberg 
6102177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
61142c6b129SJohan Hedberg 		hci_setup_link_policy(req);
6122177bab5SJohan Hedberg 
61304b4edcbSJohan Hedberg 	if (lmp_le_capable(hdev)) {
61442c6b129SJohan Hedberg 		hci_set_le_support(req);
61504b4edcbSJohan Hedberg 		hci_update_ad(req);
61604b4edcbSJohan Hedberg 	}
617d2c5d77fSJohan Hedberg 
618d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
619d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
620d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
621d2c5d77fSJohan Hedberg 
622d2c5d77fSJohan Hedberg 		cp.page = p;
623d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
624d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
625d2c5d77fSJohan Hedberg 	}
6262177bab5SJohan Hedberg }
6272177bab5SJohan Hedberg 
6282177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
6292177bab5SJohan Hedberg {
6302177bab5SJohan Hedberg 	int err;
6312177bab5SJohan Hedberg 
6322177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
6332177bab5SJohan Hedberg 	if (err < 0)
6342177bab5SJohan Hedberg 		return err;
6352177bab5SJohan Hedberg 
6362177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
6372177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
6382177bab5SJohan Hedberg 	 * first stage init.
6392177bab5SJohan Hedberg 	 */
6402177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
6412177bab5SJohan Hedberg 		return 0;
6422177bab5SJohan Hedberg 
6432177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
6442177bab5SJohan Hedberg 	if (err < 0)
6452177bab5SJohan Hedberg 		return err;
6462177bab5SJohan Hedberg 
6472177bab5SJohan Hedberg 	return __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
6482177bab5SJohan Hedberg }
6492177bab5SJohan Hedberg 
65042c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
6511da177e4SLinus Torvalds {
6521da177e4SLinus Torvalds 	__u8 scan = opt;
6531da177e4SLinus Torvalds 
65442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
6551da177e4SLinus Torvalds 
6561da177e4SLinus Torvalds 	/* Inquiry and Page scans */
65742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
6581da177e4SLinus Torvalds }
6591da177e4SLinus Torvalds 
66042c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
6611da177e4SLinus Torvalds {
6621da177e4SLinus Torvalds 	__u8 auth = opt;
6631da177e4SLinus Torvalds 
66442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
6651da177e4SLinus Torvalds 
6661da177e4SLinus Torvalds 	/* Authentication */
66742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
6681da177e4SLinus Torvalds }
6691da177e4SLinus Torvalds 
67042c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
6711da177e4SLinus Torvalds {
6721da177e4SLinus Torvalds 	__u8 encrypt = opt;
6731da177e4SLinus Torvalds 
67442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
6751da177e4SLinus Torvalds 
676e4e8e37cSMarcel Holtmann 	/* Encryption */
67742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
6781da177e4SLinus Torvalds }
6791da177e4SLinus Torvalds 
68042c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
681e4e8e37cSMarcel Holtmann {
682e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
683e4e8e37cSMarcel Holtmann 
68442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
685e4e8e37cSMarcel Holtmann 
686e4e8e37cSMarcel Holtmann 	/* Default link policy */
68742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
688e4e8e37cSMarcel Holtmann }
689e4e8e37cSMarcel Holtmann 
6901da177e4SLinus Torvalds /* Get HCI device by index.
6911da177e4SLinus Torvalds  * Device is held on return. */
6921da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
6931da177e4SLinus Torvalds {
6948035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
6951da177e4SLinus Torvalds 
6961da177e4SLinus Torvalds 	BT_DBG("%d", index);
6971da177e4SLinus Torvalds 
6981da177e4SLinus Torvalds 	if (index < 0)
6991da177e4SLinus Torvalds 		return NULL;
7001da177e4SLinus Torvalds 
7011da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
7028035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
7031da177e4SLinus Torvalds 		if (d->id == index) {
7041da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
7051da177e4SLinus Torvalds 			break;
7061da177e4SLinus Torvalds 		}
7071da177e4SLinus Torvalds 	}
7081da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
7091da177e4SLinus Torvalds 	return hdev;
7101da177e4SLinus Torvalds }
7111da177e4SLinus Torvalds 
7121da177e4SLinus Torvalds /* ---- Inquiry support ---- */
713ff9ef578SJohan Hedberg 
71430dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
71530dc78e1SJohan Hedberg {
71630dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
71730dc78e1SJohan Hedberg 
7186fbe195dSAndre Guedes 	switch (discov->state) {
719343f935bSAndre Guedes 	case DISCOVERY_FINDING:
7206fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
72130dc78e1SJohan Hedberg 		return true;
72230dc78e1SJohan Hedberg 
7236fbe195dSAndre Guedes 	default:
72430dc78e1SJohan Hedberg 		return false;
72530dc78e1SJohan Hedberg 	}
7266fbe195dSAndre Guedes }
72730dc78e1SJohan Hedberg 
728ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
729ff9ef578SJohan Hedberg {
730ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
731ff9ef578SJohan Hedberg 
732ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
733ff9ef578SJohan Hedberg 		return;
734ff9ef578SJohan Hedberg 
735ff9ef578SJohan Hedberg 	switch (state) {
736ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
7377b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
738ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
739ff9ef578SJohan Hedberg 		break;
740ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
741ff9ef578SJohan Hedberg 		break;
742343f935bSAndre Guedes 	case DISCOVERY_FINDING:
743ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
744ff9ef578SJohan Hedberg 		break;
74530dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
74630dc78e1SJohan Hedberg 		break;
747ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
748ff9ef578SJohan Hedberg 		break;
749ff9ef578SJohan Hedberg 	}
750ff9ef578SJohan Hedberg 
751ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
752ff9ef578SJohan Hedberg }
753ff9ef578SJohan Hedberg 
7541f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
7551da177e4SLinus Torvalds {
75630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
757b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
7581da177e4SLinus Torvalds 
759561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
760561aafbcSJohan Hedberg 		list_del(&p->all);
761b57c1a56SJohan Hedberg 		kfree(p);
7621da177e4SLinus Torvalds 	}
763561aafbcSJohan Hedberg 
764561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
765561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
7661da177e4SLinus Torvalds }
7671da177e4SLinus Torvalds 
768a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
769a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
7701da177e4SLinus Torvalds {
77130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
7721da177e4SLinus Torvalds 	struct inquiry_entry *e;
7731da177e4SLinus Torvalds 
7746ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
7751da177e4SLinus Torvalds 
776561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
7771da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
7781da177e4SLinus Torvalds 			return e;
7791da177e4SLinus Torvalds 	}
7801da177e4SLinus Torvalds 
781b57c1a56SJohan Hedberg 	return NULL;
782b57c1a56SJohan Hedberg }
783b57c1a56SJohan Hedberg 
784561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
785561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
786561aafbcSJohan Hedberg {
78730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
788561aafbcSJohan Hedberg 	struct inquiry_entry *e;
789561aafbcSJohan Hedberg 
7906ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
791561aafbcSJohan Hedberg 
792561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
793561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
794561aafbcSJohan Hedberg 			return e;
795561aafbcSJohan Hedberg 	}
796561aafbcSJohan Hedberg 
797561aafbcSJohan Hedberg 	return NULL;
798561aafbcSJohan Hedberg }
799561aafbcSJohan Hedberg 
80030dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
80130dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
80230dc78e1SJohan Hedberg 						       int state)
80330dc78e1SJohan Hedberg {
80430dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
80530dc78e1SJohan Hedberg 	struct inquiry_entry *e;
80630dc78e1SJohan Hedberg 
8076ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
80830dc78e1SJohan Hedberg 
80930dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
81030dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
81130dc78e1SJohan Hedberg 			return e;
81230dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
81330dc78e1SJohan Hedberg 			return e;
81430dc78e1SJohan Hedberg 	}
81530dc78e1SJohan Hedberg 
81630dc78e1SJohan Hedberg 	return NULL;
81730dc78e1SJohan Hedberg }
81830dc78e1SJohan Hedberg 
819a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
820a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
821a3d4e20aSJohan Hedberg {
822a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
823a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
824a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
825a3d4e20aSJohan Hedberg 
826a3d4e20aSJohan Hedberg 	list_del(&ie->list);
827a3d4e20aSJohan Hedberg 
828a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
829a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
830a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
831a3d4e20aSJohan Hedberg 			break;
832a3d4e20aSJohan Hedberg 		pos = &p->list;
833a3d4e20aSJohan Hedberg 	}
834a3d4e20aSJohan Hedberg 
835a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
836a3d4e20aSJohan Hedberg }
837a3d4e20aSJohan Hedberg 
8383175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
839388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
8401da177e4SLinus Torvalds {
84130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
84270f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
8431da177e4SLinus Torvalds 
8446ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
8451da177e4SLinus Torvalds 
8462b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
8472b2fec4dSSzymon Janc 
848388fc8faSJohan Hedberg 	if (ssp)
849388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
850388fc8faSJohan Hedberg 
85170f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
852a3d4e20aSJohan Hedberg 	if (ie) {
853388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
854388fc8faSJohan Hedberg 			*ssp = true;
855388fc8faSJohan Hedberg 
856a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
857a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
858a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
859a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
860a3d4e20aSJohan Hedberg 		}
861a3d4e20aSJohan Hedberg 
862561aafbcSJohan Hedberg 		goto update;
863a3d4e20aSJohan Hedberg 	}
864561aafbcSJohan Hedberg 
8651da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
86670f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
86770f23020SAndrei Emeltchenko 	if (!ie)
8683175405bSJohan Hedberg 		return false;
86970f23020SAndrei Emeltchenko 
870561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
871561aafbcSJohan Hedberg 
872561aafbcSJohan Hedberg 	if (name_known) {
873561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
874561aafbcSJohan Hedberg 	} else {
875561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
876561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
877561aafbcSJohan Hedberg 	}
878561aafbcSJohan Hedberg 
879561aafbcSJohan Hedberg update:
880561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
881561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
882561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
883561aafbcSJohan Hedberg 		list_del(&ie->list);
8841da177e4SLinus Torvalds 	}
8851da177e4SLinus Torvalds 
88670f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
88770f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
8881da177e4SLinus Torvalds 	cache->timestamp = jiffies;
8893175405bSJohan Hedberg 
8903175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
8913175405bSJohan Hedberg 		return false;
8923175405bSJohan Hedberg 
8933175405bSJohan Hedberg 	return true;
8941da177e4SLinus Torvalds }
8951da177e4SLinus Torvalds 
8961da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
8971da177e4SLinus Torvalds {
89830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
8991da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
9001da177e4SLinus Torvalds 	struct inquiry_entry *e;
9011da177e4SLinus Torvalds 	int copied = 0;
9021da177e4SLinus Torvalds 
903561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
9041da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
905b57c1a56SJohan Hedberg 
906b57c1a56SJohan Hedberg 		if (copied >= num)
907b57c1a56SJohan Hedberg 			break;
908b57c1a56SJohan Hedberg 
9091da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
9101da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
9111da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
9121da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
9131da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
9141da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
915b57c1a56SJohan Hedberg 
9161da177e4SLinus Torvalds 		info++;
917b57c1a56SJohan Hedberg 		copied++;
9181da177e4SLinus Torvalds 	}
9191da177e4SLinus Torvalds 
9201da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
9211da177e4SLinus Torvalds 	return copied;
9221da177e4SLinus Torvalds }
9231da177e4SLinus Torvalds 
92442c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
9251da177e4SLinus Torvalds {
9261da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
92742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
9281da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
9291da177e4SLinus Torvalds 
9301da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
9311da177e4SLinus Torvalds 
9321da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
9331da177e4SLinus Torvalds 		return;
9341da177e4SLinus Torvalds 
9351da177e4SLinus Torvalds 	/* Start Inquiry */
9361da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
9371da177e4SLinus Torvalds 	cp.length  = ir->length;
9381da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
93942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
9401da177e4SLinus Torvalds }
9411da177e4SLinus Torvalds 
9423e13fa1eSAndre Guedes static int wait_inquiry(void *word)
9433e13fa1eSAndre Guedes {
9443e13fa1eSAndre Guedes 	schedule();
9453e13fa1eSAndre Guedes 	return signal_pending(current);
9463e13fa1eSAndre Guedes }
9473e13fa1eSAndre Guedes 
9481da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
9491da177e4SLinus Torvalds {
9501da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
9511da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
9521da177e4SLinus Torvalds 	struct hci_dev *hdev;
9531da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
9541da177e4SLinus Torvalds 	long timeo;
9551da177e4SLinus Torvalds 	__u8 *buf;
9561da177e4SLinus Torvalds 
9571da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
9581da177e4SLinus Torvalds 		return -EFAULT;
9591da177e4SLinus Torvalds 
9605a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
9615a08ecceSAndrei Emeltchenko 	if (!hdev)
9621da177e4SLinus Torvalds 		return -ENODEV;
9631da177e4SLinus Torvalds 
96409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
9651da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
966a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
9671f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
9681da177e4SLinus Torvalds 		do_inquiry = 1;
9691da177e4SLinus Torvalds 	}
97009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
9711da177e4SLinus Torvalds 
97204837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
97370f23020SAndrei Emeltchenko 
97470f23020SAndrei Emeltchenko 	if (do_inquiry) {
97501178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
97601178cd4SJohan Hedberg 				   timeo);
97770f23020SAndrei Emeltchenko 		if (err < 0)
9781da177e4SLinus Torvalds 			goto done;
9793e13fa1eSAndre Guedes 
9803e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
9813e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
9823e13fa1eSAndre Guedes 		 */
9833e13fa1eSAndre Guedes 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry,
9843e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
9853e13fa1eSAndre Guedes 			return -EINTR;
98670f23020SAndrei Emeltchenko 	}
9871da177e4SLinus Torvalds 
9888fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
9898fc9ced3SGustavo Padovan 	 * 255 entries
9908fc9ced3SGustavo Padovan 	 */
9911da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
9921da177e4SLinus Torvalds 
9931da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
9941da177e4SLinus Torvalds 	 * copy it to the user space.
9951da177e4SLinus Torvalds 	 */
99670f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
99770f23020SAndrei Emeltchenko 	if (!buf) {
9981da177e4SLinus Torvalds 		err = -ENOMEM;
9991da177e4SLinus Torvalds 		goto done;
10001da177e4SLinus Torvalds 	}
10011da177e4SLinus Torvalds 
100209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
10031da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
100409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
10051da177e4SLinus Torvalds 
10061da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
10071da177e4SLinus Torvalds 
10081da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
10091da177e4SLinus Torvalds 		ptr += sizeof(ir);
10101da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
10111da177e4SLinus Torvalds 				 ir.num_rsp))
10121da177e4SLinus Torvalds 			err = -EFAULT;
10131da177e4SLinus Torvalds 	} else
10141da177e4SLinus Torvalds 		err = -EFAULT;
10151da177e4SLinus Torvalds 
10161da177e4SLinus Torvalds 	kfree(buf);
10171da177e4SLinus Torvalds 
10181da177e4SLinus Torvalds done:
10191da177e4SLinus Torvalds 	hci_dev_put(hdev);
10201da177e4SLinus Torvalds 	return err;
10211da177e4SLinus Torvalds }
10221da177e4SLinus Torvalds 
10233f0f524bSJohan Hedberg static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
10243f0f524bSJohan Hedberg {
10253f0f524bSJohan Hedberg 	u8 ad_len = 0, flags = 0;
10263f0f524bSJohan Hedberg 	size_t name_len;
10273f0f524bSJohan Hedberg 
10283f0f524bSJohan Hedberg 	if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
10293f0f524bSJohan Hedberg 		flags |= LE_AD_GENERAL;
10303f0f524bSJohan Hedberg 
10313f0f524bSJohan Hedberg 	if (!lmp_bredr_capable(hdev))
10323f0f524bSJohan Hedberg 		flags |= LE_AD_NO_BREDR;
10333f0f524bSJohan Hedberg 
10343f0f524bSJohan Hedberg 	if (lmp_le_br_capable(hdev))
10353f0f524bSJohan Hedberg 		flags |= LE_AD_SIM_LE_BREDR_CTRL;
10363f0f524bSJohan Hedberg 
10373f0f524bSJohan Hedberg 	if (lmp_host_le_br_capable(hdev))
10383f0f524bSJohan Hedberg 		flags |= LE_AD_SIM_LE_BREDR_HOST;
10393f0f524bSJohan Hedberg 
10403f0f524bSJohan Hedberg 	if (flags) {
10413f0f524bSJohan Hedberg 		BT_DBG("adv flags 0x%02x", flags);
10423f0f524bSJohan Hedberg 
10433f0f524bSJohan Hedberg 		ptr[0] = 2;
10443f0f524bSJohan Hedberg 		ptr[1] = EIR_FLAGS;
10453f0f524bSJohan Hedberg 		ptr[2] = flags;
10463f0f524bSJohan Hedberg 
10473f0f524bSJohan Hedberg 		ad_len += 3;
10483f0f524bSJohan Hedberg 		ptr += 3;
10493f0f524bSJohan Hedberg 	}
10503f0f524bSJohan Hedberg 
10513f0f524bSJohan Hedberg 	if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) {
10523f0f524bSJohan Hedberg 		ptr[0] = 2;
10533f0f524bSJohan Hedberg 		ptr[1] = EIR_TX_POWER;
10543f0f524bSJohan Hedberg 		ptr[2] = (u8) hdev->adv_tx_power;
10553f0f524bSJohan Hedberg 
10563f0f524bSJohan Hedberg 		ad_len += 3;
10573f0f524bSJohan Hedberg 		ptr += 3;
10583f0f524bSJohan Hedberg 	}
10593f0f524bSJohan Hedberg 
10603f0f524bSJohan Hedberg 	name_len = strlen(hdev->dev_name);
10613f0f524bSJohan Hedberg 	if (name_len > 0) {
10623f0f524bSJohan Hedberg 		size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
10633f0f524bSJohan Hedberg 
10643f0f524bSJohan Hedberg 		if (name_len > max_len) {
10653f0f524bSJohan Hedberg 			name_len = max_len;
10663f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_SHORT;
10673f0f524bSJohan Hedberg 		} else
10683f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_COMPLETE;
10693f0f524bSJohan Hedberg 
10703f0f524bSJohan Hedberg 		ptr[0] = name_len + 1;
10713f0f524bSJohan Hedberg 
10723f0f524bSJohan Hedberg 		memcpy(ptr + 2, hdev->dev_name, name_len);
10733f0f524bSJohan Hedberg 
10743f0f524bSJohan Hedberg 		ad_len += (name_len + 2);
10753f0f524bSJohan Hedberg 		ptr += (name_len + 2);
10763f0f524bSJohan Hedberg 	}
10773f0f524bSJohan Hedberg 
10783f0f524bSJohan Hedberg 	return ad_len;
10793f0f524bSJohan Hedberg }
10803f0f524bSJohan Hedberg 
108104b4edcbSJohan Hedberg void hci_update_ad(struct hci_request *req)
10823f0f524bSJohan Hedberg {
108304b4edcbSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
10843f0f524bSJohan Hedberg 	struct hci_cp_le_set_adv_data cp;
10853f0f524bSJohan Hedberg 	u8 len;
10863f0f524bSJohan Hedberg 
108704b4edcbSJohan Hedberg 	if (!lmp_le_capable(hdev))
108804b4edcbSJohan Hedberg 		return;
10893f0f524bSJohan Hedberg 
10903f0f524bSJohan Hedberg 	memset(&cp, 0, sizeof(cp));
10913f0f524bSJohan Hedberg 
10923f0f524bSJohan Hedberg 	len = create_ad(hdev, cp.data);
10933f0f524bSJohan Hedberg 
10943f0f524bSJohan Hedberg 	if (hdev->adv_data_len == len &&
109504b4edcbSJohan Hedberg 	    memcmp(cp.data, hdev->adv_data, len) == 0)
109604b4edcbSJohan Hedberg 		return;
10973f0f524bSJohan Hedberg 
10983f0f524bSJohan Hedberg 	memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
10993f0f524bSJohan Hedberg 	hdev->adv_data_len = len;
11003f0f524bSJohan Hedberg 
11013f0f524bSJohan Hedberg 	cp.length = len;
11023f0f524bSJohan Hedberg 
110304b4edcbSJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
11043f0f524bSJohan Hedberg }
11053f0f524bSJohan Hedberg 
11061da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
11071da177e4SLinus Torvalds 
11081da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
11091da177e4SLinus Torvalds {
11101da177e4SLinus Torvalds 	struct hci_dev *hdev;
11111da177e4SLinus Torvalds 	int ret = 0;
11121da177e4SLinus Torvalds 
11135a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
11145a08ecceSAndrei Emeltchenko 	if (!hdev)
11151da177e4SLinus Torvalds 		return -ENODEV;
11161da177e4SLinus Torvalds 
11171da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
11181da177e4SLinus Torvalds 
11191da177e4SLinus Torvalds 	hci_req_lock(hdev);
11201da177e4SLinus Torvalds 
112194324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
112294324962SJohan Hovold 		ret = -ENODEV;
112394324962SJohan Hovold 		goto done;
112494324962SJohan Hovold 	}
112594324962SJohan Hovold 
1126611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
1127611b30f7SMarcel Holtmann 		ret = -ERFKILL;
1128611b30f7SMarcel Holtmann 		goto done;
1129611b30f7SMarcel Holtmann 	}
1130611b30f7SMarcel Holtmann 
11311da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
11321da177e4SLinus Torvalds 		ret = -EALREADY;
11331da177e4SLinus Torvalds 		goto done;
11341da177e4SLinus Torvalds 	}
11351da177e4SLinus Torvalds 
11361da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
11371da177e4SLinus Torvalds 		ret = -EIO;
11381da177e4SLinus Torvalds 		goto done;
11391da177e4SLinus Torvalds 	}
11401da177e4SLinus Torvalds 
11411da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
11421da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1143f41c70c4SMarcel Holtmann 
1144f41c70c4SMarcel Holtmann 	if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
1145f41c70c4SMarcel Holtmann 		ret = hdev->setup(hdev);
1146f41c70c4SMarcel Holtmann 
1147f41c70c4SMarcel Holtmann 	if (!ret) {
1148f41c70c4SMarcel Holtmann 		/* Treat all non BR/EDR controllers as raw devices if
1149f41c70c4SMarcel Holtmann 		 * enable_hs is not set.
1150f41c70c4SMarcel Holtmann 		 */
1151f41c70c4SMarcel Holtmann 		if (hdev->dev_type != HCI_BREDR && !enable_hs)
1152f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
1153f41c70c4SMarcel Holtmann 
1154f41c70c4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1155f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
1156f41c70c4SMarcel Holtmann 
1157f41c70c4SMarcel Holtmann 		if (!test_bit(HCI_RAW, &hdev->flags))
11582177bab5SJohan Hedberg 			ret = __hci_init(hdev);
11591da177e4SLinus Torvalds 	}
11601da177e4SLinus Torvalds 
1161f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1162f41c70c4SMarcel Holtmann 
11631da177e4SLinus Torvalds 	if (!ret) {
11641da177e4SLinus Torvalds 		hci_dev_hold(hdev);
11651da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
11661da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
1167bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
1168bb4b2a9aSAndrei Emeltchenko 		    mgmt_valid_hdev(hdev)) {
116909fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1170744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
117109fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
117256e5cb86SJohan Hedberg 		}
11731da177e4SLinus Torvalds 	} else {
11741da177e4SLinus Torvalds 		/* Init failed, cleanup */
11753eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1176c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1177b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
11781da177e4SLinus Torvalds 
11791da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
11801da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
11811da177e4SLinus Torvalds 
11821da177e4SLinus Torvalds 		if (hdev->flush)
11831da177e4SLinus Torvalds 			hdev->flush(hdev);
11841da177e4SLinus Torvalds 
11851da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
11861da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
11871da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
11881da177e4SLinus Torvalds 		}
11891da177e4SLinus Torvalds 
11901da177e4SLinus Torvalds 		hdev->close(hdev);
11911da177e4SLinus Torvalds 		hdev->flags = 0;
11921da177e4SLinus Torvalds 	}
11931da177e4SLinus Torvalds 
11941da177e4SLinus Torvalds done:
11951da177e4SLinus Torvalds 	hci_req_unlock(hdev);
11961da177e4SLinus Torvalds 	hci_dev_put(hdev);
11971da177e4SLinus Torvalds 	return ret;
11981da177e4SLinus Torvalds }
11991da177e4SLinus Torvalds 
12001da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
12011da177e4SLinus Torvalds {
12021da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
12031da177e4SLinus Torvalds 
120428b75a89SAndre Guedes 	cancel_work_sync(&hdev->le_scan);
120528b75a89SAndre Guedes 
120678c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
120778c04c0bSVinicius Costa Gomes 
12081da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
12091da177e4SLinus Torvalds 	hci_req_lock(hdev);
12101da177e4SLinus Torvalds 
12111da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
1212b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
12131da177e4SLinus Torvalds 		hci_req_unlock(hdev);
12141da177e4SLinus Torvalds 		return 0;
12151da177e4SLinus Torvalds 	}
12161da177e4SLinus Torvalds 
12173eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
12183eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1219b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
12201da177e4SLinus Torvalds 
122116ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
1222e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
122316ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
12245e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
122516ab91abSJohan Hedberg 	}
122616ab91abSJohan Hedberg 
1227a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
12287d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
12297d78525dSJohan Hedberg 
12307ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
12317ba8b4beSAndre Guedes 
123209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
12331f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
12341da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
123509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
12361da177e4SLinus Torvalds 
12371da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
12381da177e4SLinus Torvalds 
12391da177e4SLinus Torvalds 	if (hdev->flush)
12401da177e4SLinus Torvalds 		hdev->flush(hdev);
12411da177e4SLinus Torvalds 
12421da177e4SLinus Torvalds 	/* Reset device */
12431da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
12441da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
12458af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
1246a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
12471da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
124801178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
12491da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
12501da177e4SLinus Torvalds 	}
12511da177e4SLinus Torvalds 
1252c347b765SGustavo F. Padovan 	/* flush cmd  work */
1253c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
12541da177e4SLinus Torvalds 
12551da177e4SLinus Torvalds 	/* Drop queues */
12561da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
12571da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
12581da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
12591da177e4SLinus Torvalds 
12601da177e4SLinus Torvalds 	/* Drop last sent command */
12611da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
1262b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
12631da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
12641da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
12651da177e4SLinus Torvalds 	}
12661da177e4SLinus Torvalds 
1267b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
1268b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
1269b6ddb638SJohan Hedberg 
12701da177e4SLinus Torvalds 	/* After this point our queues are empty
12711da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
12721da177e4SLinus Torvalds 	hdev->close(hdev);
12731da177e4SLinus Torvalds 
127435b973c9SJohan Hedberg 	/* Clear flags */
127535b973c9SJohan Hedberg 	hdev->flags = 0;
127635b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
127735b973c9SJohan Hedberg 
1278bb4b2a9aSAndrei Emeltchenko 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
1279bb4b2a9aSAndrei Emeltchenko 	    mgmt_valid_hdev(hdev)) {
128009fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1281744cf19eSJohan Hedberg 		mgmt_powered(hdev, 0);
128209fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
12838ee56540SMarcel Holtmann 	}
12845add6af8SJohan Hedberg 
1285ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1286ced5c338SAndrei Emeltchenko 	hdev->amp_status = 0;
1287ced5c338SAndrei Emeltchenko 
1288e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
128909b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
1290e59fda8dSJohan Hedberg 
12911da177e4SLinus Torvalds 	hci_req_unlock(hdev);
12921da177e4SLinus Torvalds 
12931da177e4SLinus Torvalds 	hci_dev_put(hdev);
12941da177e4SLinus Torvalds 	return 0;
12951da177e4SLinus Torvalds }
12961da177e4SLinus Torvalds 
12971da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
12981da177e4SLinus Torvalds {
12991da177e4SLinus Torvalds 	struct hci_dev *hdev;
13001da177e4SLinus Torvalds 	int err;
13011da177e4SLinus Torvalds 
130270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
130370f23020SAndrei Emeltchenko 	if (!hdev)
13041da177e4SLinus Torvalds 		return -ENODEV;
13058ee56540SMarcel Holtmann 
13068ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
13078ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
13088ee56540SMarcel Holtmann 
13091da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
13108ee56540SMarcel Holtmann 
13111da177e4SLinus Torvalds 	hci_dev_put(hdev);
13121da177e4SLinus Torvalds 	return err;
13131da177e4SLinus Torvalds }
13141da177e4SLinus Torvalds 
13151da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
13161da177e4SLinus Torvalds {
13171da177e4SLinus Torvalds 	struct hci_dev *hdev;
13181da177e4SLinus Torvalds 	int ret = 0;
13191da177e4SLinus Torvalds 
132070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
132170f23020SAndrei Emeltchenko 	if (!hdev)
13221da177e4SLinus Torvalds 		return -ENODEV;
13231da177e4SLinus Torvalds 
13241da177e4SLinus Torvalds 	hci_req_lock(hdev);
13251da177e4SLinus Torvalds 
13261da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
13271da177e4SLinus Torvalds 		goto done;
13281da177e4SLinus Torvalds 
13291da177e4SLinus Torvalds 	/* Drop queues */
13301da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
13311da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
13321da177e4SLinus Torvalds 
133309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13341f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
13351da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
133609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13371da177e4SLinus Torvalds 
13381da177e4SLinus Torvalds 	if (hdev->flush)
13391da177e4SLinus Torvalds 		hdev->flush(hdev);
13401da177e4SLinus Torvalds 
13411da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
13426ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
13431da177e4SLinus Torvalds 
13441da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
134501178cd4SJohan Hedberg 		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
13461da177e4SLinus Torvalds 
13471da177e4SLinus Torvalds done:
13481da177e4SLinus Torvalds 	hci_req_unlock(hdev);
13491da177e4SLinus Torvalds 	hci_dev_put(hdev);
13501da177e4SLinus Torvalds 	return ret;
13511da177e4SLinus Torvalds }
13521da177e4SLinus Torvalds 
13531da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
13541da177e4SLinus Torvalds {
13551da177e4SLinus Torvalds 	struct hci_dev *hdev;
13561da177e4SLinus Torvalds 	int ret = 0;
13571da177e4SLinus Torvalds 
135870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
135970f23020SAndrei Emeltchenko 	if (!hdev)
13601da177e4SLinus Torvalds 		return -ENODEV;
13611da177e4SLinus Torvalds 
13621da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
13631da177e4SLinus Torvalds 
13641da177e4SLinus Torvalds 	hci_dev_put(hdev);
13651da177e4SLinus Torvalds 
13661da177e4SLinus Torvalds 	return ret;
13671da177e4SLinus Torvalds }
13681da177e4SLinus Torvalds 
13691da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
13701da177e4SLinus Torvalds {
13711da177e4SLinus Torvalds 	struct hci_dev *hdev;
13721da177e4SLinus Torvalds 	struct hci_dev_req dr;
13731da177e4SLinus Torvalds 	int err = 0;
13741da177e4SLinus Torvalds 
13751da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
13761da177e4SLinus Torvalds 		return -EFAULT;
13771da177e4SLinus Torvalds 
137870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
137970f23020SAndrei Emeltchenko 	if (!hdev)
13801da177e4SLinus Torvalds 		return -ENODEV;
13811da177e4SLinus Torvalds 
13821da177e4SLinus Torvalds 	switch (cmd) {
13831da177e4SLinus Torvalds 	case HCISETAUTH:
138401178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
13855f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
13861da177e4SLinus Torvalds 		break;
13871da177e4SLinus Torvalds 
13881da177e4SLinus Torvalds 	case HCISETENCRYPT:
13891da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
13901da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
13911da177e4SLinus Torvalds 			break;
13921da177e4SLinus Torvalds 		}
13931da177e4SLinus Torvalds 
13941da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
13951da177e4SLinus Torvalds 			/* Auth must be enabled first */
139601178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
13975f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
13981da177e4SLinus Torvalds 			if (err)
13991da177e4SLinus Torvalds 				break;
14001da177e4SLinus Torvalds 		}
14011da177e4SLinus Torvalds 
140201178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
14035f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
14041da177e4SLinus Torvalds 		break;
14051da177e4SLinus Torvalds 
14061da177e4SLinus Torvalds 	case HCISETSCAN:
140701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
14085f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
14091da177e4SLinus Torvalds 		break;
14101da177e4SLinus Torvalds 
14111da177e4SLinus Torvalds 	case HCISETLINKPOL:
141201178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
14135f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
14141da177e4SLinus Torvalds 		break;
14151da177e4SLinus Torvalds 
14161da177e4SLinus Torvalds 	case HCISETLINKMODE:
1417e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
1418e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
1419e4e8e37cSMarcel Holtmann 		break;
1420e4e8e37cSMarcel Holtmann 
1421e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
1422e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
14231da177e4SLinus Torvalds 		break;
14241da177e4SLinus Torvalds 
14251da177e4SLinus Torvalds 	case HCISETACLMTU:
14261da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
14271da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
14281da177e4SLinus Torvalds 		break;
14291da177e4SLinus Torvalds 
14301da177e4SLinus Torvalds 	case HCISETSCOMTU:
14311da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
14321da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
14331da177e4SLinus Torvalds 		break;
14341da177e4SLinus Torvalds 
14351da177e4SLinus Torvalds 	default:
14361da177e4SLinus Torvalds 		err = -EINVAL;
14371da177e4SLinus Torvalds 		break;
14381da177e4SLinus Torvalds 	}
1439e4e8e37cSMarcel Holtmann 
14401da177e4SLinus Torvalds 	hci_dev_put(hdev);
14411da177e4SLinus Torvalds 	return err;
14421da177e4SLinus Torvalds }
14431da177e4SLinus Torvalds 
14441da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
14451da177e4SLinus Torvalds {
14468035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
14471da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
14481da177e4SLinus Torvalds 	struct hci_dev_req *dr;
14491da177e4SLinus Torvalds 	int n = 0, size, err;
14501da177e4SLinus Torvalds 	__u16 dev_num;
14511da177e4SLinus Torvalds 
14521da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
14531da177e4SLinus Torvalds 		return -EFAULT;
14541da177e4SLinus Torvalds 
14551da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
14561da177e4SLinus Torvalds 		return -EINVAL;
14571da177e4SLinus Torvalds 
14581da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
14591da177e4SLinus Torvalds 
146070f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
146170f23020SAndrei Emeltchenko 	if (!dl)
14621da177e4SLinus Torvalds 		return -ENOMEM;
14631da177e4SLinus Torvalds 
14641da177e4SLinus Torvalds 	dr = dl->dev_req;
14651da177e4SLinus Torvalds 
1466f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
14678035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
1468a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1469e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
1470c542a06cSJohan Hedberg 
1471a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1472a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1473c542a06cSJohan Hedberg 
14741da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
14751da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
1476c542a06cSJohan Hedberg 
14771da177e4SLinus Torvalds 		if (++n >= dev_num)
14781da177e4SLinus Torvalds 			break;
14791da177e4SLinus Torvalds 	}
1480f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
14811da177e4SLinus Torvalds 
14821da177e4SLinus Torvalds 	dl->dev_num = n;
14831da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
14841da177e4SLinus Torvalds 
14851da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
14861da177e4SLinus Torvalds 	kfree(dl);
14871da177e4SLinus Torvalds 
14881da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
14891da177e4SLinus Torvalds }
14901da177e4SLinus Torvalds 
14911da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
14921da177e4SLinus Torvalds {
14931da177e4SLinus Torvalds 	struct hci_dev *hdev;
14941da177e4SLinus Torvalds 	struct hci_dev_info di;
14951da177e4SLinus Torvalds 	int err = 0;
14961da177e4SLinus Torvalds 
14971da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
14981da177e4SLinus Torvalds 		return -EFAULT;
14991da177e4SLinus Torvalds 
150070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
150170f23020SAndrei Emeltchenko 	if (!hdev)
15021da177e4SLinus Torvalds 		return -ENODEV;
15031da177e4SLinus Torvalds 
1504a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
15053243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1506ab81cbf9SJohan Hedberg 
1507a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1508a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1509c542a06cSJohan Hedberg 
15101da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
15111da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
1512943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
15131da177e4SLinus Torvalds 	di.flags    = hdev->flags;
15141da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
1515572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
15161da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
15171da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
15181da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
15191da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
1520572c7f84SJohan Hedberg 	} else {
1521572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
1522572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
1523572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
1524572c7f84SJohan Hedberg 		di.sco_pkts = 0;
1525572c7f84SJohan Hedberg 	}
15261da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
15271da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
15281da177e4SLinus Torvalds 
15291da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
15301da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
15311da177e4SLinus Torvalds 
15321da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
15331da177e4SLinus Torvalds 		err = -EFAULT;
15341da177e4SLinus Torvalds 
15351da177e4SLinus Torvalds 	hci_dev_put(hdev);
15361da177e4SLinus Torvalds 
15371da177e4SLinus Torvalds 	return err;
15381da177e4SLinus Torvalds }
15391da177e4SLinus Torvalds 
15401da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
15411da177e4SLinus Torvalds 
1542611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1543611b30f7SMarcel Holtmann {
1544611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1545611b30f7SMarcel Holtmann 
1546611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1547611b30f7SMarcel Holtmann 
1548611b30f7SMarcel Holtmann 	if (!blocked)
1549611b30f7SMarcel Holtmann 		return 0;
1550611b30f7SMarcel Holtmann 
1551611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1552611b30f7SMarcel Holtmann 
1553611b30f7SMarcel Holtmann 	return 0;
1554611b30f7SMarcel Holtmann }
1555611b30f7SMarcel Holtmann 
1556611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1557611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1558611b30f7SMarcel Holtmann };
1559611b30f7SMarcel Holtmann 
1560ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1561ab81cbf9SJohan Hedberg {
1562ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
156396570ffcSJohan Hedberg 	int err;
1564ab81cbf9SJohan Hedberg 
1565ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1566ab81cbf9SJohan Hedberg 
156796570ffcSJohan Hedberg 	err = hci_dev_open(hdev->id);
156896570ffcSJohan Hedberg 	if (err < 0) {
156996570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
1570ab81cbf9SJohan Hedberg 		return;
157196570ffcSJohan Hedberg 	}
1572ab81cbf9SJohan Hedberg 
1573a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
157419202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
157519202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
1576ab81cbf9SJohan Hedberg 
1577a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1578744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1579ab81cbf9SJohan Hedberg }
1580ab81cbf9SJohan Hedberg 
1581ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1582ab81cbf9SJohan Hedberg {
15833243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
15843243553fSJohan Hedberg 					    power_off.work);
1585ab81cbf9SJohan Hedberg 
1586ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1587ab81cbf9SJohan Hedberg 
15888ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1589ab81cbf9SJohan Hedberg }
1590ab81cbf9SJohan Hedberg 
159116ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
159216ab91abSJohan Hedberg {
159316ab91abSJohan Hedberg 	struct hci_dev *hdev;
159416ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
159516ab91abSJohan Hedberg 
159616ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
159716ab91abSJohan Hedberg 
159816ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
159916ab91abSJohan Hedberg 
160009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
160116ab91abSJohan Hedberg 
160216ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
160316ab91abSJohan Hedberg 
160416ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
160516ab91abSJohan Hedberg 
160609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
160716ab91abSJohan Hedberg }
160816ab91abSJohan Hedberg 
16092aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
16102aeb9a1aSJohan Hedberg {
16114821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
16122aeb9a1aSJohan Hedberg 
16134821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
16144821002cSJohan Hedberg 		list_del(&uuid->list);
16152aeb9a1aSJohan Hedberg 		kfree(uuid);
16162aeb9a1aSJohan Hedberg 	}
16172aeb9a1aSJohan Hedberg 
16182aeb9a1aSJohan Hedberg 	return 0;
16192aeb9a1aSJohan Hedberg }
16202aeb9a1aSJohan Hedberg 
162155ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
162255ed8ca1SJohan Hedberg {
162355ed8ca1SJohan Hedberg 	struct list_head *p, *n;
162455ed8ca1SJohan Hedberg 
162555ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
162655ed8ca1SJohan Hedberg 		struct link_key *key;
162755ed8ca1SJohan Hedberg 
162855ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
162955ed8ca1SJohan Hedberg 
163055ed8ca1SJohan Hedberg 		list_del(p);
163155ed8ca1SJohan Hedberg 		kfree(key);
163255ed8ca1SJohan Hedberg 	}
163355ed8ca1SJohan Hedberg 
163455ed8ca1SJohan Hedberg 	return 0;
163555ed8ca1SJohan Hedberg }
163655ed8ca1SJohan Hedberg 
1637b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1638b899efafSVinicius Costa Gomes {
1639b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1640b899efafSVinicius Costa Gomes 
1641b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1642b899efafSVinicius Costa Gomes 		list_del(&k->list);
1643b899efafSVinicius Costa Gomes 		kfree(k);
1644b899efafSVinicius Costa Gomes 	}
1645b899efafSVinicius Costa Gomes 
1646b899efafSVinicius Costa Gomes 	return 0;
1647b899efafSVinicius Costa Gomes }
1648b899efafSVinicius Costa Gomes 
164955ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
165055ed8ca1SJohan Hedberg {
165155ed8ca1SJohan Hedberg 	struct link_key *k;
165255ed8ca1SJohan Hedberg 
16538035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
165455ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
165555ed8ca1SJohan Hedberg 			return k;
165655ed8ca1SJohan Hedberg 
165755ed8ca1SJohan Hedberg 	return NULL;
165855ed8ca1SJohan Hedberg }
165955ed8ca1SJohan Hedberg 
1660745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1661d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1662d25e28abSJohan Hedberg {
1663d25e28abSJohan Hedberg 	/* Legacy key */
1664d25e28abSJohan Hedberg 	if (key_type < 0x03)
1665745c0ce3SVishal Agarwal 		return true;
1666d25e28abSJohan Hedberg 
1667d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1668d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1669745c0ce3SVishal Agarwal 		return false;
1670d25e28abSJohan Hedberg 
1671d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1672d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1673745c0ce3SVishal Agarwal 		return false;
1674d25e28abSJohan Hedberg 
1675d25e28abSJohan Hedberg 	/* Security mode 3 case */
1676d25e28abSJohan Hedberg 	if (!conn)
1677745c0ce3SVishal Agarwal 		return true;
1678d25e28abSJohan Hedberg 
1679d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1680d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1681745c0ce3SVishal Agarwal 		return true;
1682d25e28abSJohan Hedberg 
1683d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1684d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1685745c0ce3SVishal Agarwal 		return true;
1686d25e28abSJohan Hedberg 
1687d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1688d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1689745c0ce3SVishal Agarwal 		return true;
1690d25e28abSJohan Hedberg 
1691d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1692d25e28abSJohan Hedberg 	 * persistently */
1693745c0ce3SVishal Agarwal 	return false;
1694d25e28abSJohan Hedberg }
1695d25e28abSJohan Hedberg 
1696c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
169775d262c2SVinicius Costa Gomes {
1698c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
169975d262c2SVinicius Costa Gomes 
1700c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1701c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1702c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
170375d262c2SVinicius Costa Gomes 			continue;
170475d262c2SVinicius Costa Gomes 
170575d262c2SVinicius Costa Gomes 		return k;
170675d262c2SVinicius Costa Gomes 	}
170775d262c2SVinicius Costa Gomes 
170875d262c2SVinicius Costa Gomes 	return NULL;
170975d262c2SVinicius Costa Gomes }
171075d262c2SVinicius Costa Gomes 
1711c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1712c9839a11SVinicius Costa Gomes 				     u8 addr_type)
171375d262c2SVinicius Costa Gomes {
1714c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
171575d262c2SVinicius Costa Gomes 
1716c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1717c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1718c9839a11SVinicius Costa Gomes 		    bacmp(bdaddr, &k->bdaddr) == 0)
171975d262c2SVinicius Costa Gomes 			return k;
172075d262c2SVinicius Costa Gomes 
172175d262c2SVinicius Costa Gomes 	return NULL;
172275d262c2SVinicius Costa Gomes }
172375d262c2SVinicius Costa Gomes 
1724d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1725d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
172655ed8ca1SJohan Hedberg {
172755ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1728745c0ce3SVishal Agarwal 	u8 old_key_type;
1729745c0ce3SVishal Agarwal 	bool persistent;
173055ed8ca1SJohan Hedberg 
173155ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
173255ed8ca1SJohan Hedberg 	if (old_key) {
173355ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
173455ed8ca1SJohan Hedberg 		key = old_key;
173555ed8ca1SJohan Hedberg 	} else {
173612adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
173755ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
173855ed8ca1SJohan Hedberg 		if (!key)
173955ed8ca1SJohan Hedberg 			return -ENOMEM;
174055ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
174155ed8ca1SJohan Hedberg 	}
174255ed8ca1SJohan Hedberg 
17436ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
174455ed8ca1SJohan Hedberg 
1745d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1746d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1747d25e28abSJohan Hedberg 	 * previous key */
1748d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1749a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1750d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1751655fe6ecSJohan Hedberg 		if (conn)
1752655fe6ecSJohan Hedberg 			conn->key_type = type;
1753655fe6ecSJohan Hedberg 	}
1754d25e28abSJohan Hedberg 
175555ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
17569b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
175755ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
175855ed8ca1SJohan Hedberg 
1759b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
176055ed8ca1SJohan Hedberg 		key->type = old_key_type;
17614748fed2SJohan Hedberg 	else
17624748fed2SJohan Hedberg 		key->type = type;
17634748fed2SJohan Hedberg 
17644df378a1SJohan Hedberg 	if (!new_key)
17654df378a1SJohan Hedberg 		return 0;
17664df378a1SJohan Hedberg 
17674df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
17684df378a1SJohan Hedberg 
1769744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
17704df378a1SJohan Hedberg 
17716ec5bcadSVishal Agarwal 	if (conn)
17726ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
177355ed8ca1SJohan Hedberg 
177455ed8ca1SJohan Hedberg 	return 0;
177555ed8ca1SJohan Hedberg }
177655ed8ca1SJohan Hedberg 
1777c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
17789a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
177904124681SGustavo F. Padovan 		ediv, u8 rand[8])
178075d262c2SVinicius Costa Gomes {
1781c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
178275d262c2SVinicius Costa Gomes 
1783c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1784c9839a11SVinicius Costa Gomes 		return 0;
178575d262c2SVinicius Costa Gomes 
1786c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1787c9839a11SVinicius Costa Gomes 	if (old_key)
178875d262c2SVinicius Costa Gomes 		key = old_key;
1789c9839a11SVinicius Costa Gomes 	else {
1790c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
179175d262c2SVinicius Costa Gomes 		if (!key)
179275d262c2SVinicius Costa Gomes 			return -ENOMEM;
1793c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
179475d262c2SVinicius Costa Gomes 	}
179575d262c2SVinicius Costa Gomes 
179675d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1797c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1798c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1799c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1800c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1801c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1802c9839a11SVinicius Costa Gomes 	key->type = type;
1803c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
180475d262c2SVinicius Costa Gomes 
1805c9839a11SVinicius Costa Gomes 	if (!new_key)
1806c9839a11SVinicius Costa Gomes 		return 0;
180775d262c2SVinicius Costa Gomes 
1808261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1809261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1810261cc5aaSVinicius Costa Gomes 
181175d262c2SVinicius Costa Gomes 	return 0;
181275d262c2SVinicius Costa Gomes }
181375d262c2SVinicius Costa Gomes 
181455ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
181555ed8ca1SJohan Hedberg {
181655ed8ca1SJohan Hedberg 	struct link_key *key;
181755ed8ca1SJohan Hedberg 
181855ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
181955ed8ca1SJohan Hedberg 	if (!key)
182055ed8ca1SJohan Hedberg 		return -ENOENT;
182155ed8ca1SJohan Hedberg 
18226ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
182355ed8ca1SJohan Hedberg 
182455ed8ca1SJohan Hedberg 	list_del(&key->list);
182555ed8ca1SJohan Hedberg 	kfree(key);
182655ed8ca1SJohan Hedberg 
182755ed8ca1SJohan Hedberg 	return 0;
182855ed8ca1SJohan Hedberg }
182955ed8ca1SJohan Hedberg 
1830b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1831b899efafSVinicius Costa Gomes {
1832b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1833b899efafSVinicius Costa Gomes 
1834b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1835b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1836b899efafSVinicius Costa Gomes 			continue;
1837b899efafSVinicius Costa Gomes 
18386ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1839b899efafSVinicius Costa Gomes 
1840b899efafSVinicius Costa Gomes 		list_del(&k->list);
1841b899efafSVinicius Costa Gomes 		kfree(k);
1842b899efafSVinicius Costa Gomes 	}
1843b899efafSVinicius Costa Gomes 
1844b899efafSVinicius Costa Gomes 	return 0;
1845b899efafSVinicius Costa Gomes }
1846b899efafSVinicius Costa Gomes 
18476bd32326SVille Tervo /* HCI command timer function */
1848bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
18496bd32326SVille Tervo {
18506bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
18516bd32326SVille Tervo 
1852bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
1853bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
1854bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
1855bda4f23aSAndrei Emeltchenko 
1856bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
1857bda4f23aSAndrei Emeltchenko 	} else {
18586bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
1859bda4f23aSAndrei Emeltchenko 	}
1860bda4f23aSAndrei Emeltchenko 
18616bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1862c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
18636bd32326SVille Tervo }
18646bd32326SVille Tervo 
18652763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
18662763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
18672763eda6SSzymon Janc {
18682763eda6SSzymon Janc 	struct oob_data *data;
18692763eda6SSzymon Janc 
18702763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
18712763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
18722763eda6SSzymon Janc 			return data;
18732763eda6SSzymon Janc 
18742763eda6SSzymon Janc 	return NULL;
18752763eda6SSzymon Janc }
18762763eda6SSzymon Janc 
18772763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
18782763eda6SSzymon Janc {
18792763eda6SSzymon Janc 	struct oob_data *data;
18802763eda6SSzymon Janc 
18812763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
18822763eda6SSzymon Janc 	if (!data)
18832763eda6SSzymon Janc 		return -ENOENT;
18842763eda6SSzymon Janc 
18856ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
18862763eda6SSzymon Janc 
18872763eda6SSzymon Janc 	list_del(&data->list);
18882763eda6SSzymon Janc 	kfree(data);
18892763eda6SSzymon Janc 
18902763eda6SSzymon Janc 	return 0;
18912763eda6SSzymon Janc }
18922763eda6SSzymon Janc 
18932763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
18942763eda6SSzymon Janc {
18952763eda6SSzymon Janc 	struct oob_data *data, *n;
18962763eda6SSzymon Janc 
18972763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
18982763eda6SSzymon Janc 		list_del(&data->list);
18992763eda6SSzymon Janc 		kfree(data);
19002763eda6SSzymon Janc 	}
19012763eda6SSzymon Janc 
19022763eda6SSzymon Janc 	return 0;
19032763eda6SSzymon Janc }
19042763eda6SSzymon Janc 
19052763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
19062763eda6SSzymon Janc 			    u8 *randomizer)
19072763eda6SSzymon Janc {
19082763eda6SSzymon Janc 	struct oob_data *data;
19092763eda6SSzymon Janc 
19102763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
19112763eda6SSzymon Janc 
19122763eda6SSzymon Janc 	if (!data) {
19132763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
19142763eda6SSzymon Janc 		if (!data)
19152763eda6SSzymon Janc 			return -ENOMEM;
19162763eda6SSzymon Janc 
19172763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
19182763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
19192763eda6SSzymon Janc 	}
19202763eda6SSzymon Janc 
19212763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
19222763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
19232763eda6SSzymon Janc 
19246ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
19252763eda6SSzymon Janc 
19262763eda6SSzymon Janc 	return 0;
19272763eda6SSzymon Janc }
19282763eda6SSzymon Janc 
192904124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
1930b2a66aadSAntti Julku {
1931b2a66aadSAntti Julku 	struct bdaddr_list *b;
1932b2a66aadSAntti Julku 
19338035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1934b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1935b2a66aadSAntti Julku 			return b;
1936b2a66aadSAntti Julku 
1937b2a66aadSAntti Julku 	return NULL;
1938b2a66aadSAntti Julku }
1939b2a66aadSAntti Julku 
1940b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1941b2a66aadSAntti Julku {
1942b2a66aadSAntti Julku 	struct list_head *p, *n;
1943b2a66aadSAntti Julku 
1944b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1945b2a66aadSAntti Julku 		struct bdaddr_list *b;
1946b2a66aadSAntti Julku 
1947b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1948b2a66aadSAntti Julku 
1949b2a66aadSAntti Julku 		list_del(p);
1950b2a66aadSAntti Julku 		kfree(b);
1951b2a66aadSAntti Julku 	}
1952b2a66aadSAntti Julku 
1953b2a66aadSAntti Julku 	return 0;
1954b2a66aadSAntti Julku }
1955b2a66aadSAntti Julku 
195688c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1957b2a66aadSAntti Julku {
1958b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1959b2a66aadSAntti Julku 
1960b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1961b2a66aadSAntti Julku 		return -EBADF;
1962b2a66aadSAntti Julku 
19635e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
19645e762444SAntti Julku 		return -EEXIST;
1965b2a66aadSAntti Julku 
1966b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
19675e762444SAntti Julku 	if (!entry)
19685e762444SAntti Julku 		return -ENOMEM;
1969b2a66aadSAntti Julku 
1970b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1971b2a66aadSAntti Julku 
1972b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1973b2a66aadSAntti Julku 
197488c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
1975b2a66aadSAntti Julku }
1976b2a66aadSAntti Julku 
197788c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1978b2a66aadSAntti Julku {
1979b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1980b2a66aadSAntti Julku 
19811ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
19825e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1983b2a66aadSAntti Julku 
1984b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
19851ec918ceSSzymon Janc 	if (!entry)
19865e762444SAntti Julku 		return -ENOENT;
1987b2a66aadSAntti Julku 
1988b2a66aadSAntti Julku 	list_del(&entry->list);
1989b2a66aadSAntti Julku 	kfree(entry);
1990b2a66aadSAntti Julku 
199188c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
1992b2a66aadSAntti Julku }
1993b2a66aadSAntti Julku 
199442c6b129SJohan Hedberg static void le_scan_param_req(struct hci_request *req, unsigned long opt)
19957ba8b4beSAndre Guedes {
19967ba8b4beSAndre Guedes 	struct le_scan_params *param =  (struct le_scan_params *) opt;
19977ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_param cp;
19987ba8b4beSAndre Guedes 
19997ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
20007ba8b4beSAndre Guedes 	cp.type = param->type;
20017ba8b4beSAndre Guedes 	cp.interval = cpu_to_le16(param->interval);
20027ba8b4beSAndre Guedes 	cp.window = cpu_to_le16(param->window);
20037ba8b4beSAndre Guedes 
200442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
20057ba8b4beSAndre Guedes }
20067ba8b4beSAndre Guedes 
200742c6b129SJohan Hedberg static void le_scan_enable_req(struct hci_request *req, unsigned long opt)
20087ba8b4beSAndre Guedes {
20097ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
20107ba8b4beSAndre Guedes 
20117ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
201276a388beSAndre Guedes 	cp.enable = LE_SCAN_ENABLE;
2013525e296aSAndre Guedes 	cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
20147ba8b4beSAndre Guedes 
201542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
20167ba8b4beSAndre Guedes }
20177ba8b4beSAndre Guedes 
20187ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
20197ba8b4beSAndre Guedes 			  u16 window, int timeout)
20207ba8b4beSAndre Guedes {
20217ba8b4beSAndre Guedes 	long timeo = msecs_to_jiffies(3000);
20227ba8b4beSAndre Guedes 	struct le_scan_params param;
20237ba8b4beSAndre Guedes 	int err;
20247ba8b4beSAndre Guedes 
20257ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
20267ba8b4beSAndre Guedes 
20277ba8b4beSAndre Guedes 	if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
20287ba8b4beSAndre Guedes 		return -EINPROGRESS;
20297ba8b4beSAndre Guedes 
20307ba8b4beSAndre Guedes 	param.type = type;
20317ba8b4beSAndre Guedes 	param.interval = interval;
20327ba8b4beSAndre Guedes 	param.window = window;
20337ba8b4beSAndre Guedes 
20347ba8b4beSAndre Guedes 	hci_req_lock(hdev);
20357ba8b4beSAndre Guedes 
203601178cd4SJohan Hedberg 	err = __hci_req_sync(hdev, le_scan_param_req, (unsigned long) &param,
20377ba8b4beSAndre Guedes 			     timeo);
20387ba8b4beSAndre Guedes 	if (!err)
203901178cd4SJohan Hedberg 		err = __hci_req_sync(hdev, le_scan_enable_req, 0, timeo);
20407ba8b4beSAndre Guedes 
20417ba8b4beSAndre Guedes 	hci_req_unlock(hdev);
20427ba8b4beSAndre Guedes 
20437ba8b4beSAndre Guedes 	if (err < 0)
20447ba8b4beSAndre Guedes 		return err;
20457ba8b4beSAndre Guedes 
204646818ed5SJohan Hedberg 	queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable,
2047b6c7515aSAndre Guedes 			   timeout);
20487ba8b4beSAndre Guedes 
20497ba8b4beSAndre Guedes 	return 0;
20507ba8b4beSAndre Guedes }
20517ba8b4beSAndre Guedes 
20527dbfac1dSAndre Guedes int hci_cancel_le_scan(struct hci_dev *hdev)
20537dbfac1dSAndre Guedes {
20547dbfac1dSAndre Guedes 	BT_DBG("%s", hdev->name);
20557dbfac1dSAndre Guedes 
20567dbfac1dSAndre Guedes 	if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
20577dbfac1dSAndre Guedes 		return -EALREADY;
20587dbfac1dSAndre Guedes 
20597dbfac1dSAndre Guedes 	if (cancel_delayed_work(&hdev->le_scan_disable)) {
20607dbfac1dSAndre Guedes 		struct hci_cp_le_set_scan_enable cp;
20617dbfac1dSAndre Guedes 
20627dbfac1dSAndre Guedes 		/* Send HCI command to disable LE Scan */
20637dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
20647dbfac1dSAndre Guedes 		hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
20657dbfac1dSAndre Guedes 	}
20667dbfac1dSAndre Guedes 
20677dbfac1dSAndre Guedes 	return 0;
20687dbfac1dSAndre Guedes }
20697dbfac1dSAndre Guedes 
20704c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
20714c87eaabSAndre Guedes {
20724c87eaabSAndre Guedes 	if (status) {
20734c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
20744c87eaabSAndre Guedes 
20754c87eaabSAndre Guedes 		hci_dev_lock(hdev);
20764c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
20774c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
20784c87eaabSAndre Guedes 		return;
20794c87eaabSAndre Guedes 	}
20804c87eaabSAndre Guedes }
20814c87eaabSAndre Guedes 
20824c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
20834c87eaabSAndre Guedes {
20844c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
20854c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
20864c87eaabSAndre Guedes 	struct hci_request req;
20874c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
20884c87eaabSAndre Guedes 	int err;
20894c87eaabSAndre Guedes 
20904c87eaabSAndre Guedes 	if (status) {
20914c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
20924c87eaabSAndre Guedes 		return;
20934c87eaabSAndre Guedes 	}
20944c87eaabSAndre Guedes 
20954c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
20964c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
20974c87eaabSAndre Guedes 		hci_dev_lock(hdev);
20984c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
20994c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
21004c87eaabSAndre Guedes 		break;
21014c87eaabSAndre Guedes 
21024c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
21034c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
21044c87eaabSAndre Guedes 
21054c87eaabSAndre Guedes 		memset(&cp, 0, sizeof(cp));
21064c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
21074c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
21084c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
21094c87eaabSAndre Guedes 
21104c87eaabSAndre Guedes 		hci_dev_lock(hdev);
21114c87eaabSAndre Guedes 
21124c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
21134c87eaabSAndre Guedes 
21144c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
21154c87eaabSAndre Guedes 		if (err) {
21164c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
21174c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
21184c87eaabSAndre Guedes 		}
21194c87eaabSAndre Guedes 
21204c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
21214c87eaabSAndre Guedes 		break;
21224c87eaabSAndre Guedes 	}
21234c87eaabSAndre Guedes }
21244c87eaabSAndre Guedes 
21257ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
21267ba8b4beSAndre Guedes {
21277ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
21287ba8b4beSAndre Guedes 					    le_scan_disable.work);
21297ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
21304c87eaabSAndre Guedes 	struct hci_request req;
21314c87eaabSAndre Guedes 	int err;
21327ba8b4beSAndre Guedes 
21337ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
21347ba8b4beSAndre Guedes 
21354c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
21367ba8b4beSAndre Guedes 
21374c87eaabSAndre Guedes 	memset(&cp, 0, sizeof(cp));
21384c87eaabSAndre Guedes 	cp.enable = LE_SCAN_DISABLE;
21394c87eaabSAndre Guedes 	hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
21404c87eaabSAndre Guedes 
21414c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
21424c87eaabSAndre Guedes 	if (err)
21434c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
21447ba8b4beSAndre Guedes }
21457ba8b4beSAndre Guedes 
214628b75a89SAndre Guedes static void le_scan_work(struct work_struct *work)
214728b75a89SAndre Guedes {
214828b75a89SAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
214928b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
215028b75a89SAndre Guedes 
215128b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
215228b75a89SAndre Guedes 
215304124681SGustavo F. Padovan 	hci_do_le_scan(hdev, param->type, param->interval, param->window,
215404124681SGustavo F. Padovan 		       param->timeout);
215528b75a89SAndre Guedes }
215628b75a89SAndre Guedes 
215728b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
215828b75a89SAndre Guedes 		int timeout)
215928b75a89SAndre Guedes {
216028b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
216128b75a89SAndre Guedes 
216228b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
216328b75a89SAndre Guedes 
2164f1550478SJohan Hedberg 	if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
2165f1550478SJohan Hedberg 		return -ENOTSUPP;
2166f1550478SJohan Hedberg 
216728b75a89SAndre Guedes 	if (work_busy(&hdev->le_scan))
216828b75a89SAndre Guedes 		return -EINPROGRESS;
216928b75a89SAndre Guedes 
217028b75a89SAndre Guedes 	param->type = type;
217128b75a89SAndre Guedes 	param->interval = interval;
217228b75a89SAndre Guedes 	param->window = window;
217328b75a89SAndre Guedes 	param->timeout = timeout;
217428b75a89SAndre Guedes 
217528b75a89SAndre Guedes 	queue_work(system_long_wq, &hdev->le_scan);
217628b75a89SAndre Guedes 
217728b75a89SAndre Guedes 	return 0;
217828b75a89SAndre Guedes }
217928b75a89SAndre Guedes 
21809be0dab7SDavid Herrmann /* Alloc HCI device */
21819be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
21829be0dab7SDavid Herrmann {
21839be0dab7SDavid Herrmann 	struct hci_dev *hdev;
21849be0dab7SDavid Herrmann 
21859be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
21869be0dab7SDavid Herrmann 	if (!hdev)
21879be0dab7SDavid Herrmann 		return NULL;
21889be0dab7SDavid Herrmann 
2189b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2190b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
2191b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
2192b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03; /* No Input No Output */
2193bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2194bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2195b1b813d4SDavid Herrmann 
2196b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
2197b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
2198b1b813d4SDavid Herrmann 
2199b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
2200b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
2201b1b813d4SDavid Herrmann 
2202b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
2203b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
2204b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
2205b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
2206b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
2207b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
22086b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
2209b1b813d4SDavid Herrmann 
2210b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2211b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2212b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2213b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2214b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->le_scan, le_scan_work);
2215b1b813d4SDavid Herrmann 
2216b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2217b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
2218b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
2219b1b813d4SDavid Herrmann 
2220b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2221b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2222b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2223b1b813d4SDavid Herrmann 
2224b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2225b1b813d4SDavid Herrmann 
2226bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
2227b1b813d4SDavid Herrmann 
2228b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2229b1b813d4SDavid Herrmann 	discovery_init(hdev);
22309be0dab7SDavid Herrmann 
22319be0dab7SDavid Herrmann 	return hdev;
22329be0dab7SDavid Herrmann }
22339be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
22349be0dab7SDavid Herrmann 
22359be0dab7SDavid Herrmann /* Free HCI device */
22369be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
22379be0dab7SDavid Herrmann {
22389be0dab7SDavid Herrmann 	/* will free via device release */
22399be0dab7SDavid Herrmann 	put_device(&hdev->dev);
22409be0dab7SDavid Herrmann }
22419be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
22429be0dab7SDavid Herrmann 
22431da177e4SLinus Torvalds /* Register HCI device */
22441da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
22451da177e4SLinus Torvalds {
2246b1b813d4SDavid Herrmann 	int id, error;
22471da177e4SLinus Torvalds 
2248010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
22491da177e4SLinus Torvalds 		return -EINVAL;
22501da177e4SLinus Torvalds 
225108add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
225208add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
225308add513SMat Martineau 	 */
22543df92b31SSasha Levin 	switch (hdev->dev_type) {
22553df92b31SSasha Levin 	case HCI_BREDR:
22563df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
22571da177e4SLinus Torvalds 		break;
22583df92b31SSasha Levin 	case HCI_AMP:
22593df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
22603df92b31SSasha Levin 		break;
22613df92b31SSasha Levin 	default:
22623df92b31SSasha Levin 		return -EINVAL;
22631da177e4SLinus Torvalds 	}
22641da177e4SLinus Torvalds 
22653df92b31SSasha Levin 	if (id < 0)
22663df92b31SSasha Levin 		return id;
22673df92b31SSasha Levin 
22681da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
22691da177e4SLinus Torvalds 	hdev->id = id;
22702d8b3a11SAndrei Emeltchenko 
22712d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
22722d8b3a11SAndrei Emeltchenko 
22733df92b31SSasha Levin 	write_lock(&hci_dev_list_lock);
22743df92b31SSasha Levin 	list_add(&hdev->list, &hci_dev_list);
2275f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
22761da177e4SLinus Torvalds 
227732845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
227832845eb1SGustavo F. Padovan 					  WQ_MEM_RECLAIM, 1);
227933ca954dSDavid Herrmann 	if (!hdev->workqueue) {
228033ca954dSDavid Herrmann 		error = -ENOMEM;
228133ca954dSDavid Herrmann 		goto err;
228233ca954dSDavid Herrmann 	}
2283f48fd9c8SMarcel Holtmann 
22846ead1bbcSJohan Hedberg 	hdev->req_workqueue = alloc_workqueue(hdev->name,
22856ead1bbcSJohan Hedberg 					      WQ_HIGHPRI | WQ_UNBOUND |
22866ead1bbcSJohan Hedberg 					      WQ_MEM_RECLAIM, 1);
22876ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
22886ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
22896ead1bbcSJohan Hedberg 		error = -ENOMEM;
22906ead1bbcSJohan Hedberg 		goto err;
22916ead1bbcSJohan Hedberg 	}
22926ead1bbcSJohan Hedberg 
229333ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
229433ca954dSDavid Herrmann 	if (error < 0)
229533ca954dSDavid Herrmann 		goto err_wqueue;
22961da177e4SLinus Torvalds 
2297611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2298a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2299a8c5fb1aSGustavo Padovan 				    hdev);
2300611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2301611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
2302611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
2303611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
2304611b30f7SMarcel Holtmann 		}
2305611b30f7SMarcel Holtmann 	}
2306611b30f7SMarcel Holtmann 
2307a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
2308ce2be9acSAndrei Emeltchenko 
2309ce2be9acSAndrei Emeltchenko 	if (hdev->dev_type != HCI_AMP)
2310ce2be9acSAndrei Emeltchenko 		set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2311ce2be9acSAndrei Emeltchenko 
23121da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
2313dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
23141da177e4SLinus Torvalds 
231519202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2316fbe96d6fSMarcel Holtmann 
23171da177e4SLinus Torvalds 	return id;
2318f48fd9c8SMarcel Holtmann 
231933ca954dSDavid Herrmann err_wqueue:
232033ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
23216ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
232233ca954dSDavid Herrmann err:
23233df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
2324f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
2325f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
2326f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
2327f48fd9c8SMarcel Holtmann 
232833ca954dSDavid Herrmann 	return error;
23291da177e4SLinus Torvalds }
23301da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
23311da177e4SLinus Torvalds 
23321da177e4SLinus Torvalds /* Unregister HCI device */
233359735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
23341da177e4SLinus Torvalds {
23353df92b31SSasha Levin 	int i, id;
2336ef222013SMarcel Holtmann 
2337c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
23381da177e4SLinus Torvalds 
233994324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
234094324962SJohan Hovold 
23413df92b31SSasha Levin 	id = hdev->id;
23423df92b31SSasha Levin 
2343f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
23441da177e4SLinus Torvalds 	list_del(&hdev->list);
2345f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
23461da177e4SLinus Torvalds 
23471da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
23481da177e4SLinus Torvalds 
2349cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
2350ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
2351ef222013SMarcel Holtmann 
2352b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
2353b9b5ef18SGustavo Padovan 
2354ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2355a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
235609fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2357744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
235809fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
235956e5cb86SJohan Hedberg 	}
2360ab81cbf9SJohan Hedberg 
23612e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
23622e58ef3eSJohan Hedberg 	 * pending list */
23632e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
23642e58ef3eSJohan Hedberg 
23651da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
23661da177e4SLinus Torvalds 
2367611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2368611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2369611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2370611b30f7SMarcel Holtmann 	}
2371611b30f7SMarcel Holtmann 
2372ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
2373147e2d59SDave Young 
2374f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
23756ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2376f48fd9c8SMarcel Holtmann 
237709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
2378e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
23792aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
238055ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2381b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
23822763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
238309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2384e2e0cacbSJohan Hedberg 
2385dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
23863df92b31SSasha Levin 
23873df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
23881da177e4SLinus Torvalds }
23891da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
23901da177e4SLinus Torvalds 
23911da177e4SLinus Torvalds /* Suspend HCI device */
23921da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
23931da177e4SLinus Torvalds {
23941da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
23951da177e4SLinus Torvalds 	return 0;
23961da177e4SLinus Torvalds }
23971da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
23981da177e4SLinus Torvalds 
23991da177e4SLinus Torvalds /* Resume HCI device */
24001da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
24011da177e4SLinus Torvalds {
24021da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
24031da177e4SLinus Torvalds 	return 0;
24041da177e4SLinus Torvalds }
24051da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
24061da177e4SLinus Torvalds 
240776bca880SMarcel Holtmann /* Receive frame from HCI drivers */
240876bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
240976bca880SMarcel Holtmann {
241076bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
241176bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
241276bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
241376bca880SMarcel Holtmann 		kfree_skb(skb);
241476bca880SMarcel Holtmann 		return -ENXIO;
241576bca880SMarcel Holtmann 	}
241676bca880SMarcel Holtmann 
2417d82603c6SJorrit Schippers 	/* Incoming skb */
241876bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
241976bca880SMarcel Holtmann 
242076bca880SMarcel Holtmann 	/* Time stamp */
242176bca880SMarcel Holtmann 	__net_timestamp(skb);
242276bca880SMarcel Holtmann 
242376bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2424b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2425c78ae283SMarcel Holtmann 
242676bca880SMarcel Holtmann 	return 0;
242776bca880SMarcel Holtmann }
242876bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
242976bca880SMarcel Holtmann 
243033e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
24311e429f38SGustavo F. Padovan 			  int count, __u8 index)
243233e882a5SSuraj Sumangala {
243333e882a5SSuraj Sumangala 	int len = 0;
243433e882a5SSuraj Sumangala 	int hlen = 0;
243533e882a5SSuraj Sumangala 	int remain = count;
243633e882a5SSuraj Sumangala 	struct sk_buff *skb;
243733e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
243833e882a5SSuraj Sumangala 
243933e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
244033e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
244133e882a5SSuraj Sumangala 		return -EILSEQ;
244233e882a5SSuraj Sumangala 
244333e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
244433e882a5SSuraj Sumangala 
244533e882a5SSuraj Sumangala 	if (!skb) {
244633e882a5SSuraj Sumangala 		switch (type) {
244733e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
244833e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
244933e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
245033e882a5SSuraj Sumangala 			break;
245133e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
245233e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
245333e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
245433e882a5SSuraj Sumangala 			break;
245533e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
245633e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
245733e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
245833e882a5SSuraj Sumangala 			break;
245933e882a5SSuraj Sumangala 		}
246033e882a5SSuraj Sumangala 
24611e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
246233e882a5SSuraj Sumangala 		if (!skb)
246333e882a5SSuraj Sumangala 			return -ENOMEM;
246433e882a5SSuraj Sumangala 
246533e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
246633e882a5SSuraj Sumangala 		scb->expect = hlen;
246733e882a5SSuraj Sumangala 		scb->pkt_type = type;
246833e882a5SSuraj Sumangala 
246933e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
247033e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
247133e882a5SSuraj Sumangala 	}
247233e882a5SSuraj Sumangala 
247333e882a5SSuraj Sumangala 	while (count) {
247433e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
247589bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
247633e882a5SSuraj Sumangala 
247733e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
247833e882a5SSuraj Sumangala 
247933e882a5SSuraj Sumangala 		count -= len;
248033e882a5SSuraj Sumangala 		data += len;
248133e882a5SSuraj Sumangala 		scb->expect -= len;
248233e882a5SSuraj Sumangala 		remain = count;
248333e882a5SSuraj Sumangala 
248433e882a5SSuraj Sumangala 		switch (type) {
248533e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
248633e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
248733e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
248833e882a5SSuraj Sumangala 				scb->expect = h->plen;
248933e882a5SSuraj Sumangala 
249033e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
249133e882a5SSuraj Sumangala 					kfree_skb(skb);
249233e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
249333e882a5SSuraj Sumangala 					return -ENOMEM;
249433e882a5SSuraj Sumangala 				}
249533e882a5SSuraj Sumangala 			}
249633e882a5SSuraj Sumangala 			break;
249733e882a5SSuraj Sumangala 
249833e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
249933e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
250033e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
250133e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
250233e882a5SSuraj Sumangala 
250333e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
250433e882a5SSuraj Sumangala 					kfree_skb(skb);
250533e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
250633e882a5SSuraj Sumangala 					return -ENOMEM;
250733e882a5SSuraj Sumangala 				}
250833e882a5SSuraj Sumangala 			}
250933e882a5SSuraj Sumangala 			break;
251033e882a5SSuraj Sumangala 
251133e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
251233e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
251333e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
251433e882a5SSuraj Sumangala 				scb->expect = h->dlen;
251533e882a5SSuraj Sumangala 
251633e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
251733e882a5SSuraj Sumangala 					kfree_skb(skb);
251833e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
251933e882a5SSuraj Sumangala 					return -ENOMEM;
252033e882a5SSuraj Sumangala 				}
252133e882a5SSuraj Sumangala 			}
252233e882a5SSuraj Sumangala 			break;
252333e882a5SSuraj Sumangala 		}
252433e882a5SSuraj Sumangala 
252533e882a5SSuraj Sumangala 		if (scb->expect == 0) {
252633e882a5SSuraj Sumangala 			/* Complete frame */
252733e882a5SSuraj Sumangala 
252833e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
252933e882a5SSuraj Sumangala 			hci_recv_frame(skb);
253033e882a5SSuraj Sumangala 
253133e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
253233e882a5SSuraj Sumangala 			return remain;
253333e882a5SSuraj Sumangala 		}
253433e882a5SSuraj Sumangala 	}
253533e882a5SSuraj Sumangala 
253633e882a5SSuraj Sumangala 	return remain;
253733e882a5SSuraj Sumangala }
253833e882a5SSuraj Sumangala 
2539ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
2540ef222013SMarcel Holtmann {
2541f39a3c06SSuraj Sumangala 	int rem = 0;
2542f39a3c06SSuraj Sumangala 
2543ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
2544ef222013SMarcel Holtmann 		return -EILSEQ;
2545ef222013SMarcel Holtmann 
2546da5f6c37SGustavo F. Padovan 	while (count) {
25471e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
2548f39a3c06SSuraj Sumangala 		if (rem < 0)
2549f39a3c06SSuraj Sumangala 			return rem;
2550ef222013SMarcel Holtmann 
2551f39a3c06SSuraj Sumangala 		data += (count - rem);
2552f39a3c06SSuraj Sumangala 		count = rem;
2553f81c6224SJoe Perches 	}
2554ef222013SMarcel Holtmann 
2555f39a3c06SSuraj Sumangala 	return rem;
2556ef222013SMarcel Holtmann }
2557ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
2558ef222013SMarcel Holtmann 
255999811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
256099811510SSuraj Sumangala 
256199811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
256299811510SSuraj Sumangala {
256399811510SSuraj Sumangala 	int type;
256499811510SSuraj Sumangala 	int rem = 0;
256599811510SSuraj Sumangala 
2566da5f6c37SGustavo F. Padovan 	while (count) {
256799811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
256899811510SSuraj Sumangala 
256999811510SSuraj Sumangala 		if (!skb) {
257099811510SSuraj Sumangala 			struct { char type; } *pkt;
257199811510SSuraj Sumangala 
257299811510SSuraj Sumangala 			/* Start of the frame */
257399811510SSuraj Sumangala 			pkt = data;
257499811510SSuraj Sumangala 			type = pkt->type;
257599811510SSuraj Sumangala 
257699811510SSuraj Sumangala 			data++;
257799811510SSuraj Sumangala 			count--;
257899811510SSuraj Sumangala 		} else
257999811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
258099811510SSuraj Sumangala 
25811e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
25821e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
258399811510SSuraj Sumangala 		if (rem < 0)
258499811510SSuraj Sumangala 			return rem;
258599811510SSuraj Sumangala 
258699811510SSuraj Sumangala 		data += (count - rem);
258799811510SSuraj Sumangala 		count = rem;
2588f81c6224SJoe Perches 	}
258999811510SSuraj Sumangala 
259099811510SSuraj Sumangala 	return rem;
259199811510SSuraj Sumangala }
259299811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
259399811510SSuraj Sumangala 
25941da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
25951da177e4SLinus Torvalds 
25961da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
25971da177e4SLinus Torvalds {
25981da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
25991da177e4SLinus Torvalds 
2600f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
26011da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2602f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
26031da177e4SLinus Torvalds 
26041da177e4SLinus Torvalds 	return 0;
26051da177e4SLinus Torvalds }
26061da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
26071da177e4SLinus Torvalds 
26081da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
26091da177e4SLinus Torvalds {
26101da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
26111da177e4SLinus Torvalds 
2612f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
26131da177e4SLinus Torvalds 	list_del(&cb->list);
2614f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
26151da177e4SLinus Torvalds 
26161da177e4SLinus Torvalds 	return 0;
26171da177e4SLinus Torvalds }
26181da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
26191da177e4SLinus Torvalds 
26201da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
26211da177e4SLinus Torvalds {
26221da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
26231da177e4SLinus Torvalds 
26241da177e4SLinus Torvalds 	if (!hdev) {
26251da177e4SLinus Torvalds 		kfree_skb(skb);
26261da177e4SLinus Torvalds 		return -ENODEV;
26271da177e4SLinus Torvalds 	}
26281da177e4SLinus Torvalds 
26290d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
26301da177e4SLinus Torvalds 
26311da177e4SLinus Torvalds 	/* Time stamp */
2632a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
26331da177e4SLinus Torvalds 
2634cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2635cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2636cd82e61cSMarcel Holtmann 
2637cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2638cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2639470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
26401da177e4SLinus Torvalds 	}
26411da177e4SLinus Torvalds 
26421da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
26431da177e4SLinus Torvalds 	skb_orphan(skb);
26441da177e4SLinus Torvalds 
26451da177e4SLinus Torvalds 	return hdev->send(skb);
26461da177e4SLinus Torvalds }
26471da177e4SLinus Torvalds 
26483119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
26493119ae95SJohan Hedberg {
26503119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
26513119ae95SJohan Hedberg 	req->hdev = hdev;
26525d73e034SAndre Guedes 	req->err = 0;
26533119ae95SJohan Hedberg }
26543119ae95SJohan Hedberg 
26553119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
26563119ae95SJohan Hedberg {
26573119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
26583119ae95SJohan Hedberg 	struct sk_buff *skb;
26593119ae95SJohan Hedberg 	unsigned long flags;
26603119ae95SJohan Hedberg 
26613119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
26623119ae95SJohan Hedberg 
26635d73e034SAndre Guedes 	/* If an error occured during request building, remove all HCI
26645d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
26655d73e034SAndre Guedes 	 */
26665d73e034SAndre Guedes 	if (req->err) {
26675d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
26685d73e034SAndre Guedes 		return req->err;
26695d73e034SAndre Guedes 	}
26705d73e034SAndre Guedes 
26713119ae95SJohan Hedberg 	/* Do not allow empty requests */
26723119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
2673382b0c39SAndre Guedes 		return -ENODATA;
26743119ae95SJohan Hedberg 
26753119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
26763119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
26773119ae95SJohan Hedberg 
26783119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
26793119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
26803119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
26813119ae95SJohan Hedberg 
26823119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
26833119ae95SJohan Hedberg 
26843119ae95SJohan Hedberg 	return 0;
26853119ae95SJohan Hedberg }
26863119ae95SJohan Hedberg 
26871ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
268807dc93ddSJohan Hedberg 				       u32 plen, const void *param)
26891da177e4SLinus Torvalds {
26901da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
26911da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
26921da177e4SLinus Torvalds 	struct sk_buff *skb;
26931da177e4SLinus Torvalds 
26941da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
26951ca3a9d0SJohan Hedberg 	if (!skb)
26961ca3a9d0SJohan Hedberg 		return NULL;
26971da177e4SLinus Torvalds 
26981da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2699a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
27001da177e4SLinus Torvalds 	hdr->plen   = plen;
27011da177e4SLinus Torvalds 
27021da177e4SLinus Torvalds 	if (plen)
27031da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
27041da177e4SLinus Torvalds 
27051da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
27061da177e4SLinus Torvalds 
27070d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
27081da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2709c78ae283SMarcel Holtmann 
27101ca3a9d0SJohan Hedberg 	return skb;
27111ca3a9d0SJohan Hedberg }
27121ca3a9d0SJohan Hedberg 
27131ca3a9d0SJohan Hedberg /* Send HCI command */
271407dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
271507dc93ddSJohan Hedberg 		 const void *param)
27161ca3a9d0SJohan Hedberg {
27171ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
27181ca3a9d0SJohan Hedberg 
27191ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
27201ca3a9d0SJohan Hedberg 
27211ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
27221ca3a9d0SJohan Hedberg 	if (!skb) {
27231ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
27241ca3a9d0SJohan Hedberg 		return -ENOMEM;
27251ca3a9d0SJohan Hedberg 	}
27261ca3a9d0SJohan Hedberg 
272711714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
272811714b3dSJohan Hedberg 	 * single-command requests.
272911714b3dSJohan Hedberg 	 */
273011714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
273111714b3dSJohan Hedberg 
27321da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2733c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
27341da177e4SLinus Torvalds 
27351da177e4SLinus Torvalds 	return 0;
27361da177e4SLinus Torvalds }
27371da177e4SLinus Torvalds 
273871c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
273907dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
274007dc93ddSJohan Hedberg 		    const void *param, u8 event)
274171c76a17SJohan Hedberg {
274271c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
274371c76a17SJohan Hedberg 	struct sk_buff *skb;
274471c76a17SJohan Hedberg 
274571c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
274671c76a17SJohan Hedberg 
274734739c1eSAndre Guedes 	/* If an error occured during request building, there is no point in
274834739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
274934739c1eSAndre Guedes 	 */
275034739c1eSAndre Guedes 	if (req->err)
275134739c1eSAndre Guedes 		return;
275234739c1eSAndre Guedes 
275371c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
275471c76a17SJohan Hedberg 	if (!skb) {
27555d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
27565d73e034SAndre Guedes 		       hdev->name, opcode);
27575d73e034SAndre Guedes 		req->err = -ENOMEM;
2758e348fe6bSAndre Guedes 		return;
275971c76a17SJohan Hedberg 	}
276071c76a17SJohan Hedberg 
276171c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
276271c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
276371c76a17SJohan Hedberg 
276402350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
276502350a72SJohan Hedberg 
276671c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
276771c76a17SJohan Hedberg }
276871c76a17SJohan Hedberg 
276907dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
277007dc93ddSJohan Hedberg 		 const void *param)
277102350a72SJohan Hedberg {
277202350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
277302350a72SJohan Hedberg }
277402350a72SJohan Hedberg 
27751da177e4SLinus Torvalds /* Get data from the previously sent command */
2776a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
27771da177e4SLinus Torvalds {
27781da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
27791da177e4SLinus Torvalds 
27801da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
27811da177e4SLinus Torvalds 		return NULL;
27821da177e4SLinus Torvalds 
27831da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
27841da177e4SLinus Torvalds 
2785a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
27861da177e4SLinus Torvalds 		return NULL;
27871da177e4SLinus Torvalds 
2788f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
27891da177e4SLinus Torvalds 
27901da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
27911da177e4SLinus Torvalds }
27921da177e4SLinus Torvalds 
27931da177e4SLinus Torvalds /* Send ACL data */
27941da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
27951da177e4SLinus Torvalds {
27961da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
27971da177e4SLinus Torvalds 	int len = skb->len;
27981da177e4SLinus Torvalds 
2799badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2800badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
28019c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2802aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2803aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
28041da177e4SLinus Torvalds }
28051da177e4SLinus Torvalds 
2806ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
280773d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
28081da177e4SLinus Torvalds {
2809ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
28101da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
28111da177e4SLinus Torvalds 	struct sk_buff *list;
28121da177e4SLinus Torvalds 
2813087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
2814087bfd99SGustavo Padovan 	skb->data_len = 0;
2815087bfd99SGustavo Padovan 
2816087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2817204a6e54SAndrei Emeltchenko 
2818204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
2819204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
2820087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
2821204a6e54SAndrei Emeltchenko 		break;
2822204a6e54SAndrei Emeltchenko 	case HCI_AMP:
2823204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
2824204a6e54SAndrei Emeltchenko 		break;
2825204a6e54SAndrei Emeltchenko 	default:
2826204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2827204a6e54SAndrei Emeltchenko 		return;
2828204a6e54SAndrei Emeltchenko 	}
2829087bfd99SGustavo Padovan 
283070f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
283170f23020SAndrei Emeltchenko 	if (!list) {
28321da177e4SLinus Torvalds 		/* Non fragmented */
28331da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
28341da177e4SLinus Torvalds 
283573d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
28361da177e4SLinus Torvalds 	} else {
28371da177e4SLinus Torvalds 		/* Fragmented */
28381da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
28391da177e4SLinus Torvalds 
28401da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
28411da177e4SLinus Torvalds 
28421da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2843af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
28441da177e4SLinus Torvalds 
284573d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2846e702112fSAndrei Emeltchenko 
2847e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2848e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
28491da177e4SLinus Torvalds 		do {
28501da177e4SLinus Torvalds 			skb = list; list = list->next;
28511da177e4SLinus Torvalds 
28521da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
28530d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2854e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
28551da177e4SLinus Torvalds 
28561da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
28571da177e4SLinus Torvalds 
285873d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
28591da177e4SLinus Torvalds 		} while (list);
28601da177e4SLinus Torvalds 
2861af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
28621da177e4SLinus Torvalds 	}
286373d80debSLuiz Augusto von Dentz }
286473d80debSLuiz Augusto von Dentz 
286573d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
286673d80debSLuiz Augusto von Dentz {
2867ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
286873d80debSLuiz Augusto von Dentz 
2869f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
287073d80debSLuiz Augusto von Dentz 
287173d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
287273d80debSLuiz Augusto von Dentz 
2873ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
28741da177e4SLinus Torvalds 
28753eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
28761da177e4SLinus Torvalds }
28771da177e4SLinus Torvalds 
28781da177e4SLinus Torvalds /* Send SCO data */
28790d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
28801da177e4SLinus Torvalds {
28811da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
28821da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
28831da177e4SLinus Torvalds 
28841da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
28851da177e4SLinus Torvalds 
2886aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
28871da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
28881da177e4SLinus Torvalds 
2889badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2890badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
28919c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
28921da177e4SLinus Torvalds 
28931da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
28940d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2895c78ae283SMarcel Holtmann 
28961da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
28973eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
28981da177e4SLinus Torvalds }
28991da177e4SLinus Torvalds 
29001da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
29011da177e4SLinus Torvalds 
29021da177e4SLinus Torvalds /* HCI Connection scheduler */
29036039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
2904a8c5fb1aSGustavo Padovan 				     int *quote)
29051da177e4SLinus Torvalds {
29061da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
29078035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
2908abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
29091da177e4SLinus Torvalds 
29101da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
29111da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2912bf4c6325SGustavo F. Padovan 
2913bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2914bf4c6325SGustavo F. Padovan 
2915bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2916769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
29171da177e4SLinus Torvalds 			continue;
2918769be974SMarcel Holtmann 
2919769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2920769be974SMarcel Holtmann 			continue;
2921769be974SMarcel Holtmann 
29221da177e4SLinus Torvalds 		num++;
29231da177e4SLinus Torvalds 
29241da177e4SLinus Torvalds 		if (c->sent < min) {
29251da177e4SLinus Torvalds 			min  = c->sent;
29261da177e4SLinus Torvalds 			conn = c;
29271da177e4SLinus Torvalds 		}
292852087a79SLuiz Augusto von Dentz 
292952087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
293052087a79SLuiz Augusto von Dentz 			break;
29311da177e4SLinus Torvalds 	}
29321da177e4SLinus Torvalds 
2933bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2934bf4c6325SGustavo F. Padovan 
29351da177e4SLinus Torvalds 	if (conn) {
29366ed58ec5SVille Tervo 		int cnt, q;
29376ed58ec5SVille Tervo 
29386ed58ec5SVille Tervo 		switch (conn->type) {
29396ed58ec5SVille Tervo 		case ACL_LINK:
29406ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
29416ed58ec5SVille Tervo 			break;
29426ed58ec5SVille Tervo 		case SCO_LINK:
29436ed58ec5SVille Tervo 		case ESCO_LINK:
29446ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
29456ed58ec5SVille Tervo 			break;
29466ed58ec5SVille Tervo 		case LE_LINK:
29476ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
29486ed58ec5SVille Tervo 			break;
29496ed58ec5SVille Tervo 		default:
29506ed58ec5SVille Tervo 			cnt = 0;
29516ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
29526ed58ec5SVille Tervo 		}
29536ed58ec5SVille Tervo 
29546ed58ec5SVille Tervo 		q = cnt / num;
29551da177e4SLinus Torvalds 		*quote = q ? q : 1;
29561da177e4SLinus Torvalds 	} else
29571da177e4SLinus Torvalds 		*quote = 0;
29581da177e4SLinus Torvalds 
29591da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
29601da177e4SLinus Torvalds 	return conn;
29611da177e4SLinus Torvalds }
29621da177e4SLinus Torvalds 
29636039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
29641da177e4SLinus Torvalds {
29651da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
29661da177e4SLinus Torvalds 	struct hci_conn *c;
29671da177e4SLinus Torvalds 
2968bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
29691da177e4SLinus Torvalds 
2970bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2971bf4c6325SGustavo F. Padovan 
29721da177e4SLinus Torvalds 	/* Kill stalled connections */
2973bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2974bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
29756ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
29766ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
2977bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
29781da177e4SLinus Torvalds 		}
29791da177e4SLinus Torvalds 	}
2980bf4c6325SGustavo F. Padovan 
2981bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
29821da177e4SLinus Torvalds }
29831da177e4SLinus Torvalds 
29846039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
298573d80debSLuiz Augusto von Dentz 				      int *quote)
298673d80debSLuiz Augusto von Dentz {
298773d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
298873d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
2989abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
299073d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
299173d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
299273d80debSLuiz Augusto von Dentz 
299373d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
299473d80debSLuiz Augusto von Dentz 
2995bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2996bf4c6325SGustavo F. Padovan 
2997bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
299873d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
299973d80debSLuiz Augusto von Dentz 
300073d80debSLuiz Augusto von Dentz 		if (conn->type != type)
300173d80debSLuiz Augusto von Dentz 			continue;
300273d80debSLuiz Augusto von Dentz 
300373d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
300473d80debSLuiz Augusto von Dentz 			continue;
300573d80debSLuiz Augusto von Dentz 
300673d80debSLuiz Augusto von Dentz 		conn_num++;
300773d80debSLuiz Augusto von Dentz 
30088192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
300973d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
301073d80debSLuiz Augusto von Dentz 
301173d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
301273d80debSLuiz Augusto von Dentz 				continue;
301373d80debSLuiz Augusto von Dentz 
301473d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
301573d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
301673d80debSLuiz Augusto von Dentz 				continue;
301773d80debSLuiz Augusto von Dentz 
301873d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
301973d80debSLuiz Augusto von Dentz 				num = 0;
302073d80debSLuiz Augusto von Dentz 				min = ~0;
302173d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
302273d80debSLuiz Augusto von Dentz 			}
302373d80debSLuiz Augusto von Dentz 
302473d80debSLuiz Augusto von Dentz 			num++;
302573d80debSLuiz Augusto von Dentz 
302673d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
302773d80debSLuiz Augusto von Dentz 				min  = conn->sent;
302873d80debSLuiz Augusto von Dentz 				chan = tmp;
302973d80debSLuiz Augusto von Dentz 			}
303073d80debSLuiz Augusto von Dentz 		}
303173d80debSLuiz Augusto von Dentz 
303273d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
303373d80debSLuiz Augusto von Dentz 			break;
303473d80debSLuiz Augusto von Dentz 	}
303573d80debSLuiz Augusto von Dentz 
3036bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3037bf4c6325SGustavo F. Padovan 
303873d80debSLuiz Augusto von Dentz 	if (!chan)
303973d80debSLuiz Augusto von Dentz 		return NULL;
304073d80debSLuiz Augusto von Dentz 
304173d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
304273d80debSLuiz Augusto von Dentz 	case ACL_LINK:
304373d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
304473d80debSLuiz Augusto von Dentz 		break;
3045bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
3046bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
3047bd1eb66bSAndrei Emeltchenko 		break;
304873d80debSLuiz Augusto von Dentz 	case SCO_LINK:
304973d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
305073d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
305173d80debSLuiz Augusto von Dentz 		break;
305273d80debSLuiz Augusto von Dentz 	case LE_LINK:
305373d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
305473d80debSLuiz Augusto von Dentz 		break;
305573d80debSLuiz Augusto von Dentz 	default:
305673d80debSLuiz Augusto von Dentz 		cnt = 0;
305773d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
305873d80debSLuiz Augusto von Dentz 	}
305973d80debSLuiz Augusto von Dentz 
306073d80debSLuiz Augusto von Dentz 	q = cnt / num;
306173d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
306273d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
306373d80debSLuiz Augusto von Dentz 	return chan;
306473d80debSLuiz Augusto von Dentz }
306573d80debSLuiz Augusto von Dentz 
306602b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
306702b20f0bSLuiz Augusto von Dentz {
306802b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
306902b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
307002b20f0bSLuiz Augusto von Dentz 	int num = 0;
307102b20f0bSLuiz Augusto von Dentz 
307202b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
307302b20f0bSLuiz Augusto von Dentz 
3074bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3075bf4c6325SGustavo F. Padovan 
3076bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
307702b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
307802b20f0bSLuiz Augusto von Dentz 
307902b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
308002b20f0bSLuiz Augusto von Dentz 			continue;
308102b20f0bSLuiz Augusto von Dentz 
308202b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
308302b20f0bSLuiz Augusto von Dentz 			continue;
308402b20f0bSLuiz Augusto von Dentz 
308502b20f0bSLuiz Augusto von Dentz 		num++;
308602b20f0bSLuiz Augusto von Dentz 
30878192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
308802b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
308902b20f0bSLuiz Augusto von Dentz 
309002b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
309102b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
309202b20f0bSLuiz Augusto von Dentz 				continue;
309302b20f0bSLuiz Augusto von Dentz 			}
309402b20f0bSLuiz Augusto von Dentz 
309502b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
309602b20f0bSLuiz Augusto von Dentz 				continue;
309702b20f0bSLuiz Augusto von Dentz 
309802b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
309902b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
310002b20f0bSLuiz Augusto von Dentz 				continue;
310102b20f0bSLuiz Augusto von Dentz 
310202b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
310302b20f0bSLuiz Augusto von Dentz 
310402b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
310502b20f0bSLuiz Augusto von Dentz 			       skb->priority);
310602b20f0bSLuiz Augusto von Dentz 		}
310702b20f0bSLuiz Augusto von Dentz 
310802b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
310902b20f0bSLuiz Augusto von Dentz 			break;
311002b20f0bSLuiz Augusto von Dentz 	}
3111bf4c6325SGustavo F. Padovan 
3112bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3113bf4c6325SGustavo F. Padovan 
311402b20f0bSLuiz Augusto von Dentz }
311502b20f0bSLuiz Augusto von Dentz 
3116b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3117b71d385aSAndrei Emeltchenko {
3118b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3119b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3120b71d385aSAndrei Emeltchenko }
3121b71d385aSAndrei Emeltchenko 
31226039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
31231da177e4SLinus Torvalds {
31241da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
31251da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
31261da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
312763d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
31285f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
3129bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
31301da177e4SLinus Torvalds 	}
313163d2bc1bSAndrei Emeltchenko }
31321da177e4SLinus Torvalds 
31336039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
313463d2bc1bSAndrei Emeltchenko {
313563d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
313663d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
313763d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
313863d2bc1bSAndrei Emeltchenko 	int quote;
313963d2bc1bSAndrei Emeltchenko 
314063d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
314104837f64SMarcel Holtmann 
314273d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
314373d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3144ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3145ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
314673d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
314773d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
314873d80debSLuiz Augusto von Dentz 
3149ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3150ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3151ec1cce24SLuiz Augusto von Dentz 				break;
3152ec1cce24SLuiz Augusto von Dentz 
3153ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3154ec1cce24SLuiz Augusto von Dentz 
315573d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
315673d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
315704837f64SMarcel Holtmann 
31581da177e4SLinus Torvalds 			hci_send_frame(skb);
31591da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
31601da177e4SLinus Torvalds 
31611da177e4SLinus Torvalds 			hdev->acl_cnt--;
316273d80debSLuiz Augusto von Dentz 			chan->sent++;
316373d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
31641da177e4SLinus Torvalds 		}
31651da177e4SLinus Torvalds 	}
316602b20f0bSLuiz Augusto von Dentz 
316702b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
316802b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
31691da177e4SLinus Torvalds }
31701da177e4SLinus Torvalds 
31716039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3172b71d385aSAndrei Emeltchenko {
317363d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3174b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3175b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3176b71d385aSAndrei Emeltchenko 	int quote;
3177bd1eb66bSAndrei Emeltchenko 	u8 type;
3178b71d385aSAndrei Emeltchenko 
317963d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
3180b71d385aSAndrei Emeltchenko 
3181bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3182bd1eb66bSAndrei Emeltchenko 
3183bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3184bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3185bd1eb66bSAndrei Emeltchenko 	else
3186bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3187bd1eb66bSAndrei Emeltchenko 
3188b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3189bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3190b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3191b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3192b71d385aSAndrei Emeltchenko 			int blocks;
3193b71d385aSAndrei Emeltchenko 
3194b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3195b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3196b71d385aSAndrei Emeltchenko 
3197b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3198b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3199b71d385aSAndrei Emeltchenko 				break;
3200b71d385aSAndrei Emeltchenko 
3201b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3202b71d385aSAndrei Emeltchenko 
3203b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3204b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3205b71d385aSAndrei Emeltchenko 				return;
3206b71d385aSAndrei Emeltchenko 
3207b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3208b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3209b71d385aSAndrei Emeltchenko 
3210b71d385aSAndrei Emeltchenko 			hci_send_frame(skb);
3211b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3212b71d385aSAndrei Emeltchenko 
3213b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3214b71d385aSAndrei Emeltchenko 			quote -= blocks;
3215b71d385aSAndrei Emeltchenko 
3216b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3217b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3218b71d385aSAndrei Emeltchenko 		}
3219b71d385aSAndrei Emeltchenko 	}
3220b71d385aSAndrei Emeltchenko 
3221b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3222bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3223b71d385aSAndrei Emeltchenko }
3224b71d385aSAndrei Emeltchenko 
32256039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3226b71d385aSAndrei Emeltchenko {
3227b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3228b71d385aSAndrei Emeltchenko 
3229bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3230bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
3231bd1eb66bSAndrei Emeltchenko 		return;
3232bd1eb66bSAndrei Emeltchenko 
3233bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3234bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3235b71d385aSAndrei Emeltchenko 		return;
3236b71d385aSAndrei Emeltchenko 
3237b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3238b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3239b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3240b71d385aSAndrei Emeltchenko 		break;
3241b71d385aSAndrei Emeltchenko 
3242b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3243b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3244b71d385aSAndrei Emeltchenko 		break;
3245b71d385aSAndrei Emeltchenko 	}
3246b71d385aSAndrei Emeltchenko }
3247b71d385aSAndrei Emeltchenko 
32481da177e4SLinus Torvalds /* Schedule SCO */
32496039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
32501da177e4SLinus Torvalds {
32511da177e4SLinus Torvalds 	struct hci_conn *conn;
32521da177e4SLinus Torvalds 	struct sk_buff *skb;
32531da177e4SLinus Torvalds 	int quote;
32541da177e4SLinus Torvalds 
32551da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
32561da177e4SLinus Torvalds 
325752087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
325852087a79SLuiz Augusto von Dentz 		return;
325952087a79SLuiz Augusto von Dentz 
32601da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
32611da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
32621da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
32631da177e4SLinus Torvalds 			hci_send_frame(skb);
32641da177e4SLinus Torvalds 
32651da177e4SLinus Torvalds 			conn->sent++;
32661da177e4SLinus Torvalds 			if (conn->sent == ~0)
32671da177e4SLinus Torvalds 				conn->sent = 0;
32681da177e4SLinus Torvalds 		}
32691da177e4SLinus Torvalds 	}
32701da177e4SLinus Torvalds }
32711da177e4SLinus Torvalds 
32726039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
3273b6a0dc82SMarcel Holtmann {
3274b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
3275b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
3276b6a0dc82SMarcel Holtmann 	int quote;
3277b6a0dc82SMarcel Holtmann 
3278b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
3279b6a0dc82SMarcel Holtmann 
328052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
328152087a79SLuiz Augusto von Dentz 		return;
328252087a79SLuiz Augusto von Dentz 
32838fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
32848fc9ced3SGustavo Padovan 						     &quote))) {
3285b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
3286b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
3287b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
3288b6a0dc82SMarcel Holtmann 
3289b6a0dc82SMarcel Holtmann 			conn->sent++;
3290b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
3291b6a0dc82SMarcel Holtmann 				conn->sent = 0;
3292b6a0dc82SMarcel Holtmann 		}
3293b6a0dc82SMarcel Holtmann 	}
3294b6a0dc82SMarcel Holtmann }
3295b6a0dc82SMarcel Holtmann 
32966039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
32976ed58ec5SVille Tervo {
329873d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
32996ed58ec5SVille Tervo 	struct sk_buff *skb;
330002b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
33016ed58ec5SVille Tervo 
33026ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
33036ed58ec5SVille Tervo 
330452087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
330552087a79SLuiz Augusto von Dentz 		return;
330652087a79SLuiz Augusto von Dentz 
33076ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
33086ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
33096ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
3310bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
33116ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
3312bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
33136ed58ec5SVille Tervo 	}
33146ed58ec5SVille Tervo 
33156ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
331602b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
331773d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3318ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3319ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
332073d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
332173d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
33226ed58ec5SVille Tervo 
3323ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3324ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3325ec1cce24SLuiz Augusto von Dentz 				break;
3326ec1cce24SLuiz Augusto von Dentz 
3327ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3328ec1cce24SLuiz Augusto von Dentz 
33296ed58ec5SVille Tervo 			hci_send_frame(skb);
33306ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
33316ed58ec5SVille Tervo 
33326ed58ec5SVille Tervo 			cnt--;
333373d80debSLuiz Augusto von Dentz 			chan->sent++;
333473d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
33356ed58ec5SVille Tervo 		}
33366ed58ec5SVille Tervo 	}
333773d80debSLuiz Augusto von Dentz 
33386ed58ec5SVille Tervo 	if (hdev->le_pkts)
33396ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
33406ed58ec5SVille Tervo 	else
33416ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
334202b20f0bSLuiz Augusto von Dentz 
334302b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
334402b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
33456ed58ec5SVille Tervo }
33466ed58ec5SVille Tervo 
33473eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
33481da177e4SLinus Torvalds {
33493eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
33501da177e4SLinus Torvalds 	struct sk_buff *skb;
33511da177e4SLinus Torvalds 
33526ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
33536ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
33541da177e4SLinus Torvalds 
33551da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
33561da177e4SLinus Torvalds 
33571da177e4SLinus Torvalds 	hci_sched_acl(hdev);
33581da177e4SLinus Torvalds 
33591da177e4SLinus Torvalds 	hci_sched_sco(hdev);
33601da177e4SLinus Torvalds 
3361b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
3362b6a0dc82SMarcel Holtmann 
33636ed58ec5SVille Tervo 	hci_sched_le(hdev);
33646ed58ec5SVille Tervo 
33651da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
33661da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
33671da177e4SLinus Torvalds 		hci_send_frame(skb);
33681da177e4SLinus Torvalds }
33691da177e4SLinus Torvalds 
337025985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
33711da177e4SLinus Torvalds 
33721da177e4SLinus Torvalds /* ACL data packet */
33736039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
33741da177e4SLinus Torvalds {
33751da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
33761da177e4SLinus Torvalds 	struct hci_conn *conn;
33771da177e4SLinus Torvalds 	__u16 handle, flags;
33781da177e4SLinus Torvalds 
33791da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
33801da177e4SLinus Torvalds 
33811da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
33821da177e4SLinus Torvalds 	flags  = hci_flags(handle);
33831da177e4SLinus Torvalds 	handle = hci_handle(handle);
33841da177e4SLinus Torvalds 
3385f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3386a8c5fb1aSGustavo Padovan 	       handle, flags);
33871da177e4SLinus Torvalds 
33881da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
33891da177e4SLinus Torvalds 
33901da177e4SLinus Torvalds 	hci_dev_lock(hdev);
33911da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
33921da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
33931da177e4SLinus Torvalds 
33941da177e4SLinus Torvalds 	if (conn) {
339565983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
339604837f64SMarcel Holtmann 
33971da177e4SLinus Torvalds 		/* Send to upper protocol */
3398686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
33991da177e4SLinus Torvalds 		return;
34001da177e4SLinus Torvalds 	} else {
34011da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
34021da177e4SLinus Torvalds 		       hdev->name, handle);
34031da177e4SLinus Torvalds 	}
34041da177e4SLinus Torvalds 
34051da177e4SLinus Torvalds 	kfree_skb(skb);
34061da177e4SLinus Torvalds }
34071da177e4SLinus Torvalds 
34081da177e4SLinus Torvalds /* SCO data packet */
34096039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
34101da177e4SLinus Torvalds {
34111da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
34121da177e4SLinus Torvalds 	struct hci_conn *conn;
34131da177e4SLinus Torvalds 	__u16 handle;
34141da177e4SLinus Torvalds 
34151da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
34161da177e4SLinus Torvalds 
34171da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
34181da177e4SLinus Torvalds 
3419f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
34201da177e4SLinus Torvalds 
34211da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
34221da177e4SLinus Torvalds 
34231da177e4SLinus Torvalds 	hci_dev_lock(hdev);
34241da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
34251da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
34261da177e4SLinus Torvalds 
34271da177e4SLinus Torvalds 	if (conn) {
34281da177e4SLinus Torvalds 		/* Send to upper protocol */
3429686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
34301da177e4SLinus Torvalds 		return;
34311da177e4SLinus Torvalds 	} else {
34321da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
34331da177e4SLinus Torvalds 		       hdev->name, handle);
34341da177e4SLinus Torvalds 	}
34351da177e4SLinus Torvalds 
34361da177e4SLinus Torvalds 	kfree_skb(skb);
34371da177e4SLinus Torvalds }
34381da177e4SLinus Torvalds 
34399238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
34409238f36aSJohan Hedberg {
34419238f36aSJohan Hedberg 	struct sk_buff *skb;
34429238f36aSJohan Hedberg 
34439238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
34449238f36aSJohan Hedberg 	if (!skb)
34459238f36aSJohan Hedberg 		return true;
34469238f36aSJohan Hedberg 
34479238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
34489238f36aSJohan Hedberg }
34499238f36aSJohan Hedberg 
345042c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
345142c6b129SJohan Hedberg {
345242c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
345342c6b129SJohan Hedberg 	struct sk_buff *skb;
345442c6b129SJohan Hedberg 	u16 opcode;
345542c6b129SJohan Hedberg 
345642c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
345742c6b129SJohan Hedberg 		return;
345842c6b129SJohan Hedberg 
345942c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
346042c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
346142c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
346242c6b129SJohan Hedberg 		return;
346342c6b129SJohan Hedberg 
346442c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
346542c6b129SJohan Hedberg 	if (!skb)
346642c6b129SJohan Hedberg 		return;
346742c6b129SJohan Hedberg 
346842c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
346942c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
347042c6b129SJohan Hedberg }
347142c6b129SJohan Hedberg 
34729238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
34739238f36aSJohan Hedberg {
34749238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
34759238f36aSJohan Hedberg 	struct sk_buff *skb;
34769238f36aSJohan Hedberg 	unsigned long flags;
34779238f36aSJohan Hedberg 
34789238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
34799238f36aSJohan Hedberg 
348042c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
348142c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
34829238f36aSJohan Hedberg 	 */
348342c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
348442c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
348542c6b129SJohan Hedberg 		 * reset complete event during init and any pending
348642c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
348742c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
348842c6b129SJohan Hedberg 		 * command.
348942c6b129SJohan Hedberg 		 */
349042c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
349142c6b129SJohan Hedberg 			hci_resend_last(hdev);
349242c6b129SJohan Hedberg 
34939238f36aSJohan Hedberg 		return;
349442c6b129SJohan Hedberg 	}
34959238f36aSJohan Hedberg 
34969238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
34979238f36aSJohan Hedberg 	 * this request the request is not yet complete.
34989238f36aSJohan Hedberg 	 */
34999238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
35009238f36aSJohan Hedberg 		return;
35019238f36aSJohan Hedberg 
35029238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
35039238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
35049238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
35059238f36aSJohan Hedberg 	 */
35069238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
35079238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
35089238f36aSJohan Hedberg 		if (req_complete)
35099238f36aSJohan Hedberg 			goto call_complete;
35109238f36aSJohan Hedberg 	}
35119238f36aSJohan Hedberg 
35129238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
35139238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
35149238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
35159238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
35169238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
35179238f36aSJohan Hedberg 			break;
35189238f36aSJohan Hedberg 		}
35199238f36aSJohan Hedberg 
35209238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
35219238f36aSJohan Hedberg 		kfree_skb(skb);
35229238f36aSJohan Hedberg 	}
35239238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
35249238f36aSJohan Hedberg 
35259238f36aSJohan Hedberg call_complete:
35269238f36aSJohan Hedberg 	if (req_complete)
35279238f36aSJohan Hedberg 		req_complete(hdev, status);
35289238f36aSJohan Hedberg }
35299238f36aSJohan Hedberg 
3530b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
35311da177e4SLinus Torvalds {
3532b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
35331da177e4SLinus Torvalds 	struct sk_buff *skb;
35341da177e4SLinus Torvalds 
35351da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
35361da177e4SLinus Torvalds 
35371da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
3538cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
3539cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
3540cd82e61cSMarcel Holtmann 
35411da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
35421da177e4SLinus Torvalds 			/* Send copy to the sockets */
3543470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
35441da177e4SLinus Torvalds 		}
35451da177e4SLinus Torvalds 
35461da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
35471da177e4SLinus Torvalds 			kfree_skb(skb);
35481da177e4SLinus Torvalds 			continue;
35491da177e4SLinus Torvalds 		}
35501da177e4SLinus Torvalds 
35511da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
35521da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
35530d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
35541da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
35551da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
35561da177e4SLinus Torvalds 				kfree_skb(skb);
35571da177e4SLinus Torvalds 				continue;
35583ff50b79SStephen Hemminger 			}
35591da177e4SLinus Torvalds 		}
35601da177e4SLinus Torvalds 
35611da177e4SLinus Torvalds 		/* Process frame */
35620d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
35631da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
3564b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
35651da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
35661da177e4SLinus Torvalds 			break;
35671da177e4SLinus Torvalds 
35681da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
35691da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
35701da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
35711da177e4SLinus Torvalds 			break;
35721da177e4SLinus Torvalds 
35731da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
35741da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
35751da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
35761da177e4SLinus Torvalds 			break;
35771da177e4SLinus Torvalds 
35781da177e4SLinus Torvalds 		default:
35791da177e4SLinus Torvalds 			kfree_skb(skb);
35801da177e4SLinus Torvalds 			break;
35811da177e4SLinus Torvalds 		}
35821da177e4SLinus Torvalds 	}
35831da177e4SLinus Torvalds }
35841da177e4SLinus Torvalds 
3585c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
35861da177e4SLinus Torvalds {
3587c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
35881da177e4SLinus Torvalds 	struct sk_buff *skb;
35891da177e4SLinus Torvalds 
35902104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
35912104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
35921da177e4SLinus Torvalds 
35931da177e4SLinus Torvalds 	/* Send queued commands */
35945a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
35955a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
35965a08ecceSAndrei Emeltchenko 		if (!skb)
35975a08ecceSAndrei Emeltchenko 			return;
35985a08ecceSAndrei Emeltchenko 
35991da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
36001da177e4SLinus Torvalds 
360170f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
360270f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
36031da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
36041da177e4SLinus Torvalds 			hci_send_frame(skb);
36057bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
36067bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
36077bdb8a5cSSzymon Janc 			else
36086bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
36095f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
36101da177e4SLinus Torvalds 		} else {
36111da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
3612c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
36131da177e4SLinus Torvalds 		}
36141da177e4SLinus Torvalds 	}
36151da177e4SLinus Torvalds }
36162519a1fcSAndre Guedes 
36172519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
36182519a1fcSAndre Guedes {
36192519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
36202519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
36212519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
36222519a1fcSAndre Guedes 
36232519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
36242519a1fcSAndre Guedes 
36252519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
36262519a1fcSAndre Guedes 		return -EINPROGRESS;
36272519a1fcSAndre Guedes 
36281f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
36294663262cSJohan Hedberg 
36302519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
36312519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
36322519a1fcSAndre Guedes 	cp.length  = length;
36332519a1fcSAndre Guedes 
36342519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
36352519a1fcSAndre Guedes }
3636023d5049SAndre Guedes 
3637023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
3638023d5049SAndre Guedes {
3639023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
3640023d5049SAndre Guedes 
3641023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
36427537e5c3SAndre Guedes 		return -EALREADY;
3643023d5049SAndre Guedes 
3644023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
3645023d5049SAndre Guedes }
364631f7956cSAndre Guedes 
364731f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type)
364831f7956cSAndre Guedes {
364931f7956cSAndre Guedes 	switch (bdaddr_type) {
365031f7956cSAndre Guedes 	case BDADDR_LE_PUBLIC:
365131f7956cSAndre Guedes 		return ADDR_LE_DEV_PUBLIC;
365231f7956cSAndre Guedes 
365331f7956cSAndre Guedes 	default:
365431f7956cSAndre Guedes 		/* Fallback to LE Random address type */
365531f7956cSAndre Guedes 		return ADDR_LE_DEV_RANDOM;
365631f7956cSAndre Guedes 	}
365731f7956cSAndre Guedes }
3658