xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 76a388be)
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 
827b1abbbeSJohan Hedberg struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 event)
8375e84b7cSJohan Hedberg {
8475e84b7cSJohan Hedberg 	struct hci_ev_cmd_complete *ev;
8575e84b7cSJohan Hedberg 	struct hci_event_hdr *hdr;
8675e84b7cSJohan Hedberg 	struct sk_buff *skb;
8775e84b7cSJohan Hedberg 
8875e84b7cSJohan Hedberg 	hci_dev_lock(hdev);
8975e84b7cSJohan Hedberg 
9075e84b7cSJohan Hedberg 	skb = hdev->recv_evt;
9175e84b7cSJohan Hedberg 	hdev->recv_evt = NULL;
9275e84b7cSJohan Hedberg 
9375e84b7cSJohan Hedberg 	hci_dev_unlock(hdev);
9475e84b7cSJohan Hedberg 
9575e84b7cSJohan Hedberg 	if (!skb)
9675e84b7cSJohan Hedberg 		return ERR_PTR(-ENODATA);
9775e84b7cSJohan Hedberg 
9875e84b7cSJohan Hedberg 	if (skb->len < sizeof(*hdr)) {
9975e84b7cSJohan Hedberg 		BT_ERR("Too short HCI event");
10075e84b7cSJohan Hedberg 		goto failed;
10175e84b7cSJohan Hedberg 	}
10275e84b7cSJohan Hedberg 
10375e84b7cSJohan Hedberg 	hdr = (void *) skb->data;
10475e84b7cSJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
10575e84b7cSJohan Hedberg 
1067b1abbbeSJohan Hedberg 	if (event) {
1077b1abbbeSJohan Hedberg 		if (hdr->evt != event)
1087b1abbbeSJohan Hedberg 			goto failed;
1097b1abbbeSJohan Hedberg 		return skb;
1107b1abbbeSJohan Hedberg 	}
1117b1abbbeSJohan Hedberg 
11275e84b7cSJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
11375e84b7cSJohan Hedberg 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
11475e84b7cSJohan Hedberg 		goto failed;
11575e84b7cSJohan Hedberg 	}
11675e84b7cSJohan Hedberg 
11775e84b7cSJohan Hedberg 	if (skb->len < sizeof(*ev)) {
11875e84b7cSJohan Hedberg 		BT_ERR("Too short cmd_complete event");
11975e84b7cSJohan Hedberg 		goto failed;
12075e84b7cSJohan Hedberg 	}
12175e84b7cSJohan Hedberg 
12275e84b7cSJohan Hedberg 	ev = (void *) skb->data;
12375e84b7cSJohan Hedberg 	skb_pull(skb, sizeof(*ev));
12475e84b7cSJohan Hedberg 
12575e84b7cSJohan Hedberg 	if (opcode == __le16_to_cpu(ev->opcode))
12675e84b7cSJohan Hedberg 		return skb;
12775e84b7cSJohan Hedberg 
12875e84b7cSJohan Hedberg 	BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
12975e84b7cSJohan Hedberg 	       __le16_to_cpu(ev->opcode));
13075e84b7cSJohan Hedberg 
13175e84b7cSJohan Hedberg failed:
13275e84b7cSJohan Hedberg 	kfree_skb(skb);
13375e84b7cSJohan Hedberg 	return ERR_PTR(-ENODATA);
13475e84b7cSJohan Hedberg }
13575e84b7cSJohan Hedberg 
1367b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
1377b1abbbeSJohan Hedberg 				  void *param, u8 event, u32 timeout)
13875e84b7cSJohan Hedberg {
13975e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
14075e84b7cSJohan Hedberg 	struct hci_request req;
14175e84b7cSJohan Hedberg 	int err = 0;
14275e84b7cSJohan Hedberg 
14375e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
14475e84b7cSJohan Hedberg 
14575e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
14675e84b7cSJohan Hedberg 
1477b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
14875e84b7cSJohan Hedberg 
14975e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
15075e84b7cSJohan Hedberg 
15175e84b7cSJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
15275e84b7cSJohan Hedberg 	if (err < 0)
15375e84b7cSJohan Hedberg 		return ERR_PTR(err);
15475e84b7cSJohan Hedberg 
15575e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
15675e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
15775e84b7cSJohan Hedberg 
15875e84b7cSJohan Hedberg 	schedule_timeout(timeout);
15975e84b7cSJohan Hedberg 
16075e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
16175e84b7cSJohan Hedberg 
16275e84b7cSJohan Hedberg 	if (signal_pending(current))
16375e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
16475e84b7cSJohan Hedberg 
16575e84b7cSJohan Hedberg 	switch (hdev->req_status) {
16675e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
16775e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
16875e84b7cSJohan Hedberg 		break;
16975e84b7cSJohan Hedberg 
17075e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
17175e84b7cSJohan Hedberg 		err = -hdev->req_result;
17275e84b7cSJohan Hedberg 		break;
17375e84b7cSJohan Hedberg 
17475e84b7cSJohan Hedberg 	default:
17575e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
17675e84b7cSJohan Hedberg 		break;
17775e84b7cSJohan Hedberg 	}
17875e84b7cSJohan Hedberg 
17975e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
18075e84b7cSJohan Hedberg 
18175e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
18275e84b7cSJohan Hedberg 
18375e84b7cSJohan Hedberg 	if (err < 0)
18475e84b7cSJohan Hedberg 		return ERR_PTR(err);
18575e84b7cSJohan Hedberg 
1867b1abbbeSJohan Hedberg 	return hci_get_cmd_complete(hdev, opcode, event);
1877b1abbbeSJohan Hedberg }
1887b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
1897b1abbbeSJohan Hedberg 
1907b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
1917b1abbbeSJohan Hedberg 			       void *param, u32 timeout)
1927b1abbbeSJohan Hedberg {
1937b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
19475e84b7cSJohan Hedberg }
19575e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
19675e84b7cSJohan Hedberg 
1971da177e4SLinus Torvalds /* Execute request and wait for completion. */
19801178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
19942c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
20042c6b129SJohan Hedberg 				      unsigned long opt),
2011da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
2021da177e4SLinus Torvalds {
20342c6b129SJohan Hedberg 	struct hci_request req;
2041da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
2051da177e4SLinus Torvalds 	int err = 0;
2061da177e4SLinus Torvalds 
2071da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
2081da177e4SLinus Torvalds 
20942c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
21042c6b129SJohan Hedberg 
2111da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
2121da177e4SLinus Torvalds 
21342c6b129SJohan Hedberg 	func(&req, opt);
21453cce22dSJohan Hedberg 
21542c6b129SJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
21642c6b129SJohan Hedberg 	if (err < 0) {
21753cce22dSJohan Hedberg 		hdev->req_status = 0;
218920c8300SAndre Guedes 
219920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
220920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
221920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
222920c8300SAndre Guedes 		 * and should not trigger an error return.
22342c6b129SJohan Hedberg 		 */
224920c8300SAndre Guedes 		if (err == -ENODATA)
22542c6b129SJohan Hedberg 			return 0;
226920c8300SAndre Guedes 
227920c8300SAndre Guedes 		return err;
22853cce22dSJohan Hedberg 	}
22953cce22dSJohan Hedberg 
230bc4445c7SAndre Guedes 	add_wait_queue(&hdev->req_wait_q, &wait);
231bc4445c7SAndre Guedes 	set_current_state(TASK_INTERRUPTIBLE);
232bc4445c7SAndre Guedes 
2331da177e4SLinus Torvalds 	schedule_timeout(timeout);
2341da177e4SLinus Torvalds 
2351da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
2361da177e4SLinus Torvalds 
2371da177e4SLinus Torvalds 	if (signal_pending(current))
2381da177e4SLinus Torvalds 		return -EINTR;
2391da177e4SLinus Torvalds 
2401da177e4SLinus Torvalds 	switch (hdev->req_status) {
2411da177e4SLinus Torvalds 	case HCI_REQ_DONE:
242e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
2431da177e4SLinus Torvalds 		break;
2441da177e4SLinus Torvalds 
2451da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
2461da177e4SLinus Torvalds 		err = -hdev->req_result;
2471da177e4SLinus Torvalds 		break;
2481da177e4SLinus Torvalds 
2491da177e4SLinus Torvalds 	default:
2501da177e4SLinus Torvalds 		err = -ETIMEDOUT;
2511da177e4SLinus Torvalds 		break;
2523ff50b79SStephen Hemminger 	}
2531da177e4SLinus Torvalds 
254a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
2551da177e4SLinus Torvalds 
2561da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
2571da177e4SLinus Torvalds 
2581da177e4SLinus Torvalds 	return err;
2591da177e4SLinus Torvalds }
2601da177e4SLinus Torvalds 
26101178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
26242c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
26342c6b129SJohan Hedberg 				    unsigned long opt),
2641da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
2651da177e4SLinus Torvalds {
2661da177e4SLinus Torvalds 	int ret;
2671da177e4SLinus Torvalds 
2687c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
2697c6a329eSMarcel Holtmann 		return -ENETDOWN;
2707c6a329eSMarcel Holtmann 
2711da177e4SLinus Torvalds 	/* Serialize all requests */
2721da177e4SLinus Torvalds 	hci_req_lock(hdev);
27301178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
2741da177e4SLinus Torvalds 	hci_req_unlock(hdev);
2751da177e4SLinus Torvalds 
2761da177e4SLinus Torvalds 	return ret;
2771da177e4SLinus Torvalds }
2781da177e4SLinus Torvalds 
27942c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
2801da177e4SLinus Torvalds {
28142c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
2821da177e4SLinus Torvalds 
2831da177e4SLinus Torvalds 	/* Reset device */
28442c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
28542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
2861da177e4SLinus Torvalds }
2871da177e4SLinus Torvalds 
28842c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
2891da177e4SLinus Torvalds {
29042c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
2912455a3eaSAndrei Emeltchenko 
2921da177e4SLinus Torvalds 	/* Read Local Supported Features */
29342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
2941da177e4SLinus Torvalds 
2951143e5a6SMarcel Holtmann 	/* Read Local Version */
29642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2972177bab5SJohan Hedberg 
2982177bab5SJohan Hedberg 	/* Read BD Address */
29942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
3001da177e4SLinus Torvalds }
3011da177e4SLinus Torvalds 
30242c6b129SJohan Hedberg static void amp_init(struct hci_request *req)
303e61ef499SAndrei Emeltchenko {
30442c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
3052455a3eaSAndrei Emeltchenko 
306e61ef499SAndrei Emeltchenko 	/* Read Local Version */
30742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
3086bcbc489SAndrei Emeltchenko 
3096bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
31042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
311e71dfabaSAndrei Emeltchenko 
312e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
31342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
314e61ef499SAndrei Emeltchenko }
315e61ef499SAndrei Emeltchenko 
31642c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
317e61ef499SAndrei Emeltchenko {
31842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
319e61ef499SAndrei Emeltchenko 
320e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
321e61ef499SAndrei Emeltchenko 
32211778716SAndrei Emeltchenko 	/* Reset */
32311778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
32442c6b129SJohan Hedberg 		hci_reset_req(req, 0);
32511778716SAndrei Emeltchenko 
326e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
327e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
32842c6b129SJohan Hedberg 		bredr_init(req);
329e61ef499SAndrei Emeltchenko 		break;
330e61ef499SAndrei Emeltchenko 
331e61ef499SAndrei Emeltchenko 	case HCI_AMP:
33242c6b129SJohan Hedberg 		amp_init(req);
333e61ef499SAndrei Emeltchenko 		break;
334e61ef499SAndrei Emeltchenko 
335e61ef499SAndrei Emeltchenko 	default:
336e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
337e61ef499SAndrei Emeltchenko 		break;
338e61ef499SAndrei Emeltchenko 	}
339e61ef499SAndrei Emeltchenko }
340e61ef499SAndrei Emeltchenko 
34142c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
3422177bab5SJohan Hedberg {
3432177bab5SJohan Hedberg 	struct hci_cp_delete_stored_link_key cp;
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 
3672177bab5SJohan Hedberg 	bacpy(&cp.bdaddr, BDADDR_ANY);
3682177bab5SJohan Hedberg 	cp.delete_all = 0x01;
36942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
370f332ec66SJohan Hedberg 
371f332ec66SJohan Hedberg 	/* Read page scan parameters */
372f332ec66SJohan Hedberg 	if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) {
373f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
374f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
375f332ec66SJohan Hedberg 	}
3762177bab5SJohan Hedberg }
3772177bab5SJohan Hedberg 
37842c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
3792177bab5SJohan Hedberg {
3802177bab5SJohan Hedberg 	/* Read LE Buffer Size */
38142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
3822177bab5SJohan Hedberg 
3832177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
38442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
3852177bab5SJohan Hedberg 
3862177bab5SJohan Hedberg 	/* Read LE Advertising Channel TX Power */
38742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
3882177bab5SJohan Hedberg 
3892177bab5SJohan Hedberg 	/* Read LE White List Size */
39042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
3912177bab5SJohan Hedberg 
3922177bab5SJohan Hedberg 	/* Read LE Supported States */
39342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
3942177bab5SJohan Hedberg }
3952177bab5SJohan Hedberg 
3962177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
3972177bab5SJohan Hedberg {
3982177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
3992177bab5SJohan Hedberg 		return 0x02;
4002177bab5SJohan Hedberg 
4012177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4022177bab5SJohan Hedberg 		return 0x01;
4032177bab5SJohan Hedberg 
4042177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
4052177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
4062177bab5SJohan Hedberg 		return 0x01;
4072177bab5SJohan Hedberg 
4082177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
4092177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
4102177bab5SJohan Hedberg 			return 0x01;
4112177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
4122177bab5SJohan Hedberg 			return 0x01;
4132177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
4142177bab5SJohan Hedberg 			return 0x01;
4152177bab5SJohan Hedberg 	}
4162177bab5SJohan Hedberg 
4172177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
4182177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
4192177bab5SJohan Hedberg 		return 0x01;
4202177bab5SJohan Hedberg 
4212177bab5SJohan Hedberg 	return 0x00;
4222177bab5SJohan Hedberg }
4232177bab5SJohan Hedberg 
42442c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
4252177bab5SJohan Hedberg {
4262177bab5SJohan Hedberg 	u8 mode;
4272177bab5SJohan Hedberg 
42842c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
4292177bab5SJohan Hedberg 
43042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
4312177bab5SJohan Hedberg }
4322177bab5SJohan Hedberg 
43342c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
4342177bab5SJohan Hedberg {
43542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
43642c6b129SJohan Hedberg 
4372177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
4382177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
4392177bab5SJohan Hedberg 	 * command otherwise.
4402177bab5SJohan Hedberg 	 */
4412177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
4422177bab5SJohan Hedberg 
4432177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
4442177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
4452177bab5SJohan Hedberg 	 */
4462177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
4472177bab5SJohan Hedberg 		return;
4482177bab5SJohan Hedberg 
4492177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
4502177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
4512177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4522177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
4532177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
4542177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
4552177bab5SJohan Hedberg 	}
4562177bab5SJohan Hedberg 
4572177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4582177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4592177bab5SJohan Hedberg 
4602177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
4612177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
4622177bab5SJohan Hedberg 
4632177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
4642177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
4652177bab5SJohan Hedberg 
4662177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
4672177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
4682177bab5SJohan Hedberg 
4692177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
4702177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
4712177bab5SJohan Hedberg 
4722177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
4732177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
4742177bab5SJohan Hedberg 
4752177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
4762177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
4772177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
4782177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
4792177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
4802177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
4812177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
4822177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
4832177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
4842177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
4852177bab5SJohan Hedberg 					 * Features Notification
4862177bab5SJohan Hedberg 					 */
4872177bab5SJohan Hedberg 	}
4882177bab5SJohan Hedberg 
4892177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
4902177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
4912177bab5SJohan Hedberg 
49242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
4932177bab5SJohan Hedberg 
4942177bab5SJohan Hedberg 	if (lmp_le_capable(hdev)) {
4952177bab5SJohan Hedberg 		memset(events, 0, sizeof(events));
4962177bab5SJohan Hedberg 		events[0] = 0x1f;
49742c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
4982177bab5SJohan Hedberg 			    sizeof(events), events);
4992177bab5SJohan Hedberg 	}
5002177bab5SJohan Hedberg }
5012177bab5SJohan Hedberg 
50242c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
5032177bab5SJohan Hedberg {
50442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
50542c6b129SJohan Hedberg 
5062177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
50742c6b129SJohan Hedberg 		bredr_setup(req);
5082177bab5SJohan Hedberg 
5092177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
51042c6b129SJohan Hedberg 		le_setup(req);
5112177bab5SJohan Hedberg 
51242c6b129SJohan Hedberg 	hci_setup_event_mask(req);
5132177bab5SJohan Hedberg 
5142177bab5SJohan Hedberg 	if (hdev->hci_ver > BLUETOOTH_VER_1_1)
51542c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
5162177bab5SJohan Hedberg 
5172177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5182177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
5192177bab5SJohan Hedberg 			u8 mode = 0x01;
52042c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
5212177bab5SJohan Hedberg 				    sizeof(mode), &mode);
5222177bab5SJohan Hedberg 		} else {
5232177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
5242177bab5SJohan Hedberg 
5252177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
5262177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
5272177bab5SJohan Hedberg 
52842c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
5292177bab5SJohan Hedberg 		}
5302177bab5SJohan Hedberg 	}
5312177bab5SJohan Hedberg 
5322177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
53342c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
5342177bab5SJohan Hedberg 
5352177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
53642c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
5372177bab5SJohan Hedberg 
5382177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
5392177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
5402177bab5SJohan Hedberg 
5412177bab5SJohan Hedberg 		cp.page = 0x01;
54242c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
54342c6b129SJohan Hedberg 			    sizeof(cp), &cp);
5442177bab5SJohan Hedberg 	}
5452177bab5SJohan Hedberg 
5462177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
5472177bab5SJohan Hedberg 		u8 enable = 1;
54842c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
5492177bab5SJohan Hedberg 			    &enable);
5502177bab5SJohan Hedberg 	}
5512177bab5SJohan Hedberg }
5522177bab5SJohan Hedberg 
55342c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
5542177bab5SJohan Hedberg {
55542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5562177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
5572177bab5SJohan Hedberg 	u16 link_policy = 0;
5582177bab5SJohan Hedberg 
5592177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
5602177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
5612177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
5622177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
5632177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
5642177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
5652177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
5662177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
5672177bab5SJohan Hedberg 
5682177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
56942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
5702177bab5SJohan Hedberg }
5712177bab5SJohan Hedberg 
57242c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
5732177bab5SJohan Hedberg {
57442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5752177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
5762177bab5SJohan Hedberg 
5772177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
5782177bab5SJohan Hedberg 
5792177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
5802177bab5SJohan Hedberg 		cp.le = 0x01;
5812177bab5SJohan Hedberg 		cp.simul = lmp_le_br_capable(hdev);
5822177bab5SJohan Hedberg 	}
5832177bab5SJohan Hedberg 
5842177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
58542c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
5862177bab5SJohan Hedberg 			    &cp);
5872177bab5SJohan Hedberg }
5882177bab5SJohan Hedberg 
58942c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
5902177bab5SJohan Hedberg {
59142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
592d2c5d77fSJohan Hedberg 	u8 p;
59342c6b129SJohan Hedberg 
5942177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
59542c6b129SJohan Hedberg 		hci_setup_link_policy(req);
5962177bab5SJohan Hedberg 
59704b4edcbSJohan Hedberg 	if (lmp_le_capable(hdev)) {
59842c6b129SJohan Hedberg 		hci_set_le_support(req);
59904b4edcbSJohan Hedberg 		hci_update_ad(req);
60004b4edcbSJohan Hedberg 	}
601d2c5d77fSJohan Hedberg 
602d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
603d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
604d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
605d2c5d77fSJohan Hedberg 
606d2c5d77fSJohan Hedberg 		cp.page = p;
607d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
608d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
609d2c5d77fSJohan Hedberg 	}
6102177bab5SJohan Hedberg }
6112177bab5SJohan Hedberg 
6122177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
6132177bab5SJohan Hedberg {
6142177bab5SJohan Hedberg 	int err;
6152177bab5SJohan Hedberg 
6162177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
6172177bab5SJohan Hedberg 	if (err < 0)
6182177bab5SJohan Hedberg 		return err;
6192177bab5SJohan Hedberg 
6202177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
6212177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
6222177bab5SJohan Hedberg 	 * first stage init.
6232177bab5SJohan Hedberg 	 */
6242177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
6252177bab5SJohan Hedberg 		return 0;
6262177bab5SJohan Hedberg 
6272177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
6282177bab5SJohan Hedberg 	if (err < 0)
6292177bab5SJohan Hedberg 		return err;
6302177bab5SJohan Hedberg 
6312177bab5SJohan Hedberg 	return __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
6322177bab5SJohan Hedberg }
6332177bab5SJohan Hedberg 
63442c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
6351da177e4SLinus Torvalds {
6361da177e4SLinus Torvalds 	__u8 scan = opt;
6371da177e4SLinus Torvalds 
63842c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
6391da177e4SLinus Torvalds 
6401da177e4SLinus Torvalds 	/* Inquiry and Page scans */
64142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
6421da177e4SLinus Torvalds }
6431da177e4SLinus Torvalds 
64442c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
6451da177e4SLinus Torvalds {
6461da177e4SLinus Torvalds 	__u8 auth = opt;
6471da177e4SLinus Torvalds 
64842c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
6491da177e4SLinus Torvalds 
6501da177e4SLinus Torvalds 	/* Authentication */
65142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
6521da177e4SLinus Torvalds }
6531da177e4SLinus Torvalds 
65442c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
6551da177e4SLinus Torvalds {
6561da177e4SLinus Torvalds 	__u8 encrypt = opt;
6571da177e4SLinus Torvalds 
65842c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
6591da177e4SLinus Torvalds 
660e4e8e37cSMarcel Holtmann 	/* Encryption */
66142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
6621da177e4SLinus Torvalds }
6631da177e4SLinus Torvalds 
66442c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
665e4e8e37cSMarcel Holtmann {
666e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
667e4e8e37cSMarcel Holtmann 
66842c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
669e4e8e37cSMarcel Holtmann 
670e4e8e37cSMarcel Holtmann 	/* Default link policy */
67142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
672e4e8e37cSMarcel Holtmann }
673e4e8e37cSMarcel Holtmann 
6741da177e4SLinus Torvalds /* Get HCI device by index.
6751da177e4SLinus Torvalds  * Device is held on return. */
6761da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
6771da177e4SLinus Torvalds {
6788035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
6791da177e4SLinus Torvalds 
6801da177e4SLinus Torvalds 	BT_DBG("%d", index);
6811da177e4SLinus Torvalds 
6821da177e4SLinus Torvalds 	if (index < 0)
6831da177e4SLinus Torvalds 		return NULL;
6841da177e4SLinus Torvalds 
6851da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
6868035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
6871da177e4SLinus Torvalds 		if (d->id == index) {
6881da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
6891da177e4SLinus Torvalds 			break;
6901da177e4SLinus Torvalds 		}
6911da177e4SLinus Torvalds 	}
6921da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
6931da177e4SLinus Torvalds 	return hdev;
6941da177e4SLinus Torvalds }
6951da177e4SLinus Torvalds 
6961da177e4SLinus Torvalds /* ---- Inquiry support ---- */
697ff9ef578SJohan Hedberg 
69830dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
69930dc78e1SJohan Hedberg {
70030dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
70130dc78e1SJohan Hedberg 
7026fbe195dSAndre Guedes 	switch (discov->state) {
703343f935bSAndre Guedes 	case DISCOVERY_FINDING:
7046fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
70530dc78e1SJohan Hedberg 		return true;
70630dc78e1SJohan Hedberg 
7076fbe195dSAndre Guedes 	default:
70830dc78e1SJohan Hedberg 		return false;
70930dc78e1SJohan Hedberg 	}
7106fbe195dSAndre Guedes }
71130dc78e1SJohan Hedberg 
712ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
713ff9ef578SJohan Hedberg {
714ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
715ff9ef578SJohan Hedberg 
716ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
717ff9ef578SJohan Hedberg 		return;
718ff9ef578SJohan Hedberg 
719ff9ef578SJohan Hedberg 	switch (state) {
720ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
7217b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
722ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
723ff9ef578SJohan Hedberg 		break;
724ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
725ff9ef578SJohan Hedberg 		break;
726343f935bSAndre Guedes 	case DISCOVERY_FINDING:
727ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
728ff9ef578SJohan Hedberg 		break;
72930dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
73030dc78e1SJohan Hedberg 		break;
731ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
732ff9ef578SJohan Hedberg 		break;
733ff9ef578SJohan Hedberg 	}
734ff9ef578SJohan Hedberg 
735ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
736ff9ef578SJohan Hedberg }
737ff9ef578SJohan Hedberg 
7381da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
7391da177e4SLinus Torvalds {
74030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
741b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
7421da177e4SLinus Torvalds 
743561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
744561aafbcSJohan Hedberg 		list_del(&p->all);
745b57c1a56SJohan Hedberg 		kfree(p);
7461da177e4SLinus Torvalds 	}
747561aafbcSJohan Hedberg 
748561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
749561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
7501da177e4SLinus Torvalds }
7511da177e4SLinus Torvalds 
752a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
753a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
7541da177e4SLinus Torvalds {
75530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
7561da177e4SLinus Torvalds 	struct inquiry_entry *e;
7571da177e4SLinus Torvalds 
7586ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
7591da177e4SLinus Torvalds 
760561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
7611da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
7621da177e4SLinus Torvalds 			return e;
7631da177e4SLinus Torvalds 	}
7641da177e4SLinus Torvalds 
765b57c1a56SJohan Hedberg 	return NULL;
766b57c1a56SJohan Hedberg }
767b57c1a56SJohan Hedberg 
768561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
769561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
770561aafbcSJohan Hedberg {
77130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
772561aafbcSJohan Hedberg 	struct inquiry_entry *e;
773561aafbcSJohan Hedberg 
7746ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
775561aafbcSJohan Hedberg 
776561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
777561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
778561aafbcSJohan Hedberg 			return e;
779561aafbcSJohan Hedberg 	}
780561aafbcSJohan Hedberg 
781561aafbcSJohan Hedberg 	return NULL;
782561aafbcSJohan Hedberg }
783561aafbcSJohan Hedberg 
78430dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
78530dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
78630dc78e1SJohan Hedberg 						       int state)
78730dc78e1SJohan Hedberg {
78830dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
78930dc78e1SJohan Hedberg 	struct inquiry_entry *e;
79030dc78e1SJohan Hedberg 
7916ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
79230dc78e1SJohan Hedberg 
79330dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
79430dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
79530dc78e1SJohan Hedberg 			return e;
79630dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
79730dc78e1SJohan Hedberg 			return e;
79830dc78e1SJohan Hedberg 	}
79930dc78e1SJohan Hedberg 
80030dc78e1SJohan Hedberg 	return NULL;
80130dc78e1SJohan Hedberg }
80230dc78e1SJohan Hedberg 
803a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
804a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
805a3d4e20aSJohan Hedberg {
806a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
807a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
808a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
809a3d4e20aSJohan Hedberg 
810a3d4e20aSJohan Hedberg 	list_del(&ie->list);
811a3d4e20aSJohan Hedberg 
812a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
813a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
814a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
815a3d4e20aSJohan Hedberg 			break;
816a3d4e20aSJohan Hedberg 		pos = &p->list;
817a3d4e20aSJohan Hedberg 	}
818a3d4e20aSJohan Hedberg 
819a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
820a3d4e20aSJohan Hedberg }
821a3d4e20aSJohan Hedberg 
8223175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
823388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
8241da177e4SLinus Torvalds {
82530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
82670f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
8271da177e4SLinus Torvalds 
8286ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
8291da177e4SLinus Torvalds 
8302b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
8312b2fec4dSSzymon Janc 
832388fc8faSJohan Hedberg 	if (ssp)
833388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
834388fc8faSJohan Hedberg 
83570f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
836a3d4e20aSJohan Hedberg 	if (ie) {
837388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
838388fc8faSJohan Hedberg 			*ssp = true;
839388fc8faSJohan Hedberg 
840a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
841a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
842a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
843a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
844a3d4e20aSJohan Hedberg 		}
845a3d4e20aSJohan Hedberg 
846561aafbcSJohan Hedberg 		goto update;
847a3d4e20aSJohan Hedberg 	}
848561aafbcSJohan Hedberg 
8491da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
85070f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
85170f23020SAndrei Emeltchenko 	if (!ie)
8523175405bSJohan Hedberg 		return false;
85370f23020SAndrei Emeltchenko 
854561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
855561aafbcSJohan Hedberg 
856561aafbcSJohan Hedberg 	if (name_known) {
857561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
858561aafbcSJohan Hedberg 	} else {
859561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
860561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
861561aafbcSJohan Hedberg 	}
862561aafbcSJohan Hedberg 
863561aafbcSJohan Hedberg update:
864561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
865561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
866561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
867561aafbcSJohan Hedberg 		list_del(&ie->list);
8681da177e4SLinus Torvalds 	}
8691da177e4SLinus Torvalds 
87070f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
87170f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
8721da177e4SLinus Torvalds 	cache->timestamp = jiffies;
8733175405bSJohan Hedberg 
8743175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
8753175405bSJohan Hedberg 		return false;
8763175405bSJohan Hedberg 
8773175405bSJohan Hedberg 	return true;
8781da177e4SLinus Torvalds }
8791da177e4SLinus Torvalds 
8801da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
8811da177e4SLinus Torvalds {
88230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
8831da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
8841da177e4SLinus Torvalds 	struct inquiry_entry *e;
8851da177e4SLinus Torvalds 	int copied = 0;
8861da177e4SLinus Torvalds 
887561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
8881da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
889b57c1a56SJohan Hedberg 
890b57c1a56SJohan Hedberg 		if (copied >= num)
891b57c1a56SJohan Hedberg 			break;
892b57c1a56SJohan Hedberg 
8931da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
8941da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
8951da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
8961da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
8971da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
8981da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
899b57c1a56SJohan Hedberg 
9001da177e4SLinus Torvalds 		info++;
901b57c1a56SJohan Hedberg 		copied++;
9021da177e4SLinus Torvalds 	}
9031da177e4SLinus Torvalds 
9041da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
9051da177e4SLinus Torvalds 	return copied;
9061da177e4SLinus Torvalds }
9071da177e4SLinus Torvalds 
90842c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
9091da177e4SLinus Torvalds {
9101da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
91142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
9121da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
9131da177e4SLinus Torvalds 
9141da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
9151da177e4SLinus Torvalds 
9161da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
9171da177e4SLinus Torvalds 		return;
9181da177e4SLinus Torvalds 
9191da177e4SLinus Torvalds 	/* Start Inquiry */
9201da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
9211da177e4SLinus Torvalds 	cp.length  = ir->length;
9221da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
92342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
9241da177e4SLinus Torvalds }
9251da177e4SLinus Torvalds 
9263e13fa1eSAndre Guedes static int wait_inquiry(void *word)
9273e13fa1eSAndre Guedes {
9283e13fa1eSAndre Guedes 	schedule();
9293e13fa1eSAndre Guedes 	return signal_pending(current);
9303e13fa1eSAndre Guedes }
9313e13fa1eSAndre Guedes 
9321da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
9331da177e4SLinus Torvalds {
9341da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
9351da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
9361da177e4SLinus Torvalds 	struct hci_dev *hdev;
9371da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
9381da177e4SLinus Torvalds 	long timeo;
9391da177e4SLinus Torvalds 	__u8 *buf;
9401da177e4SLinus Torvalds 
9411da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
9421da177e4SLinus Torvalds 		return -EFAULT;
9431da177e4SLinus Torvalds 
9445a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
9455a08ecceSAndrei Emeltchenko 	if (!hdev)
9461da177e4SLinus Torvalds 		return -ENODEV;
9471da177e4SLinus Torvalds 
94809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
9491da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
950a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
9511da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
9521da177e4SLinus Torvalds 		do_inquiry = 1;
9531da177e4SLinus Torvalds 	}
95409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
9551da177e4SLinus Torvalds 
95604837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
95770f23020SAndrei Emeltchenko 
95870f23020SAndrei Emeltchenko 	if (do_inquiry) {
95901178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
96001178cd4SJohan Hedberg 				   timeo);
96170f23020SAndrei Emeltchenko 		if (err < 0)
9621da177e4SLinus Torvalds 			goto done;
9633e13fa1eSAndre Guedes 
9643e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
9653e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
9663e13fa1eSAndre Guedes 		 */
9673e13fa1eSAndre Guedes 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry,
9683e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
9693e13fa1eSAndre Guedes 			return -EINTR;
97070f23020SAndrei Emeltchenko 	}
9711da177e4SLinus Torvalds 
9728fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
9738fc9ced3SGustavo Padovan 	 * 255 entries
9748fc9ced3SGustavo Padovan 	 */
9751da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
9761da177e4SLinus Torvalds 
9771da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
9781da177e4SLinus Torvalds 	 * copy it to the user space.
9791da177e4SLinus Torvalds 	 */
98070f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
98170f23020SAndrei Emeltchenko 	if (!buf) {
9821da177e4SLinus Torvalds 		err = -ENOMEM;
9831da177e4SLinus Torvalds 		goto done;
9841da177e4SLinus Torvalds 	}
9851da177e4SLinus Torvalds 
98609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
9871da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
98809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
9891da177e4SLinus Torvalds 
9901da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
9911da177e4SLinus Torvalds 
9921da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
9931da177e4SLinus Torvalds 		ptr += sizeof(ir);
9941da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
9951da177e4SLinus Torvalds 				 ir.num_rsp))
9961da177e4SLinus Torvalds 			err = -EFAULT;
9971da177e4SLinus Torvalds 	} else
9981da177e4SLinus Torvalds 		err = -EFAULT;
9991da177e4SLinus Torvalds 
10001da177e4SLinus Torvalds 	kfree(buf);
10011da177e4SLinus Torvalds 
10021da177e4SLinus Torvalds done:
10031da177e4SLinus Torvalds 	hci_dev_put(hdev);
10041da177e4SLinus Torvalds 	return err;
10051da177e4SLinus Torvalds }
10061da177e4SLinus Torvalds 
10073f0f524bSJohan Hedberg static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
10083f0f524bSJohan Hedberg {
10093f0f524bSJohan Hedberg 	u8 ad_len = 0, flags = 0;
10103f0f524bSJohan Hedberg 	size_t name_len;
10113f0f524bSJohan Hedberg 
10123f0f524bSJohan Hedberg 	if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
10133f0f524bSJohan Hedberg 		flags |= LE_AD_GENERAL;
10143f0f524bSJohan Hedberg 
10153f0f524bSJohan Hedberg 	if (!lmp_bredr_capable(hdev))
10163f0f524bSJohan Hedberg 		flags |= LE_AD_NO_BREDR;
10173f0f524bSJohan Hedberg 
10183f0f524bSJohan Hedberg 	if (lmp_le_br_capable(hdev))
10193f0f524bSJohan Hedberg 		flags |= LE_AD_SIM_LE_BREDR_CTRL;
10203f0f524bSJohan Hedberg 
10213f0f524bSJohan Hedberg 	if (lmp_host_le_br_capable(hdev))
10223f0f524bSJohan Hedberg 		flags |= LE_AD_SIM_LE_BREDR_HOST;
10233f0f524bSJohan Hedberg 
10243f0f524bSJohan Hedberg 	if (flags) {
10253f0f524bSJohan Hedberg 		BT_DBG("adv flags 0x%02x", flags);
10263f0f524bSJohan Hedberg 
10273f0f524bSJohan Hedberg 		ptr[0] = 2;
10283f0f524bSJohan Hedberg 		ptr[1] = EIR_FLAGS;
10293f0f524bSJohan Hedberg 		ptr[2] = flags;
10303f0f524bSJohan Hedberg 
10313f0f524bSJohan Hedberg 		ad_len += 3;
10323f0f524bSJohan Hedberg 		ptr += 3;
10333f0f524bSJohan Hedberg 	}
10343f0f524bSJohan Hedberg 
10353f0f524bSJohan Hedberg 	if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) {
10363f0f524bSJohan Hedberg 		ptr[0] = 2;
10373f0f524bSJohan Hedberg 		ptr[1] = EIR_TX_POWER;
10383f0f524bSJohan Hedberg 		ptr[2] = (u8) hdev->adv_tx_power;
10393f0f524bSJohan Hedberg 
10403f0f524bSJohan Hedberg 		ad_len += 3;
10413f0f524bSJohan Hedberg 		ptr += 3;
10423f0f524bSJohan Hedberg 	}
10433f0f524bSJohan Hedberg 
10443f0f524bSJohan Hedberg 	name_len = strlen(hdev->dev_name);
10453f0f524bSJohan Hedberg 	if (name_len > 0) {
10463f0f524bSJohan Hedberg 		size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
10473f0f524bSJohan Hedberg 
10483f0f524bSJohan Hedberg 		if (name_len > max_len) {
10493f0f524bSJohan Hedberg 			name_len = max_len;
10503f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_SHORT;
10513f0f524bSJohan Hedberg 		} else
10523f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_COMPLETE;
10533f0f524bSJohan Hedberg 
10543f0f524bSJohan Hedberg 		ptr[0] = name_len + 1;
10553f0f524bSJohan Hedberg 
10563f0f524bSJohan Hedberg 		memcpy(ptr + 2, hdev->dev_name, name_len);
10573f0f524bSJohan Hedberg 
10583f0f524bSJohan Hedberg 		ad_len += (name_len + 2);
10593f0f524bSJohan Hedberg 		ptr += (name_len + 2);
10603f0f524bSJohan Hedberg 	}
10613f0f524bSJohan Hedberg 
10623f0f524bSJohan Hedberg 	return ad_len;
10633f0f524bSJohan Hedberg }
10643f0f524bSJohan Hedberg 
106504b4edcbSJohan Hedberg void hci_update_ad(struct hci_request *req)
10663f0f524bSJohan Hedberg {
106704b4edcbSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
10683f0f524bSJohan Hedberg 	struct hci_cp_le_set_adv_data cp;
10693f0f524bSJohan Hedberg 	u8 len;
10703f0f524bSJohan Hedberg 
107104b4edcbSJohan Hedberg 	if (!lmp_le_capable(hdev))
107204b4edcbSJohan Hedberg 		return;
10733f0f524bSJohan Hedberg 
10743f0f524bSJohan Hedberg 	memset(&cp, 0, sizeof(cp));
10753f0f524bSJohan Hedberg 
10763f0f524bSJohan Hedberg 	len = create_ad(hdev, cp.data);
10773f0f524bSJohan Hedberg 
10783f0f524bSJohan Hedberg 	if (hdev->adv_data_len == len &&
107904b4edcbSJohan Hedberg 	    memcmp(cp.data, hdev->adv_data, len) == 0)
108004b4edcbSJohan Hedberg 		return;
10813f0f524bSJohan Hedberg 
10823f0f524bSJohan Hedberg 	memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
10833f0f524bSJohan Hedberg 	hdev->adv_data_len = len;
10843f0f524bSJohan Hedberg 
10853f0f524bSJohan Hedberg 	cp.length = len;
10863f0f524bSJohan Hedberg 
108704b4edcbSJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
10883f0f524bSJohan Hedberg }
10893f0f524bSJohan Hedberg 
10901da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
10911da177e4SLinus Torvalds 
10921da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
10931da177e4SLinus Torvalds {
10941da177e4SLinus Torvalds 	struct hci_dev *hdev;
10951da177e4SLinus Torvalds 	int ret = 0;
10961da177e4SLinus Torvalds 
10975a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
10985a08ecceSAndrei Emeltchenko 	if (!hdev)
10991da177e4SLinus Torvalds 		return -ENODEV;
11001da177e4SLinus Torvalds 
11011da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
11021da177e4SLinus Torvalds 
11031da177e4SLinus Torvalds 	hci_req_lock(hdev);
11041da177e4SLinus Torvalds 
110594324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
110694324962SJohan Hovold 		ret = -ENODEV;
110794324962SJohan Hovold 		goto done;
110894324962SJohan Hovold 	}
110994324962SJohan Hovold 
1110611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
1111611b30f7SMarcel Holtmann 		ret = -ERFKILL;
1112611b30f7SMarcel Holtmann 		goto done;
1113611b30f7SMarcel Holtmann 	}
1114611b30f7SMarcel Holtmann 
11151da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
11161da177e4SLinus Torvalds 		ret = -EALREADY;
11171da177e4SLinus Torvalds 		goto done;
11181da177e4SLinus Torvalds 	}
11191da177e4SLinus Torvalds 
11201da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
11211da177e4SLinus Torvalds 		ret = -EIO;
11221da177e4SLinus Torvalds 		goto done;
11231da177e4SLinus Torvalds 	}
11241da177e4SLinus Torvalds 
11251da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
11261da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1127f41c70c4SMarcel Holtmann 
1128f41c70c4SMarcel Holtmann 	if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
1129f41c70c4SMarcel Holtmann 		ret = hdev->setup(hdev);
1130f41c70c4SMarcel Holtmann 
1131f41c70c4SMarcel Holtmann 	if (!ret) {
1132f41c70c4SMarcel Holtmann 		/* Treat all non BR/EDR controllers as raw devices if
1133f41c70c4SMarcel Holtmann 		 * enable_hs is not set.
1134f41c70c4SMarcel Holtmann 		 */
1135f41c70c4SMarcel Holtmann 		if (hdev->dev_type != HCI_BREDR && !enable_hs)
1136f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
1137f41c70c4SMarcel Holtmann 
1138f41c70c4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1139f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
1140f41c70c4SMarcel Holtmann 
1141f41c70c4SMarcel Holtmann 		if (!test_bit(HCI_RAW, &hdev->flags))
11422177bab5SJohan Hedberg 			ret = __hci_init(hdev);
11431da177e4SLinus Torvalds 	}
11441da177e4SLinus Torvalds 
1145f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1146f41c70c4SMarcel Holtmann 
11471da177e4SLinus Torvalds 	if (!ret) {
11481da177e4SLinus Torvalds 		hci_dev_hold(hdev);
11491da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
11501da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
1151bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
1152bb4b2a9aSAndrei Emeltchenko 		    mgmt_valid_hdev(hdev)) {
115309fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1154744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
115509fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
115656e5cb86SJohan Hedberg 		}
11571da177e4SLinus Torvalds 	} else {
11581da177e4SLinus Torvalds 		/* Init failed, cleanup */
11593eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1160c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1161b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
11621da177e4SLinus Torvalds 
11631da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
11641da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
11651da177e4SLinus Torvalds 
11661da177e4SLinus Torvalds 		if (hdev->flush)
11671da177e4SLinus Torvalds 			hdev->flush(hdev);
11681da177e4SLinus Torvalds 
11691da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
11701da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
11711da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
11721da177e4SLinus Torvalds 		}
11731da177e4SLinus Torvalds 
11741da177e4SLinus Torvalds 		hdev->close(hdev);
11751da177e4SLinus Torvalds 		hdev->flags = 0;
11761da177e4SLinus Torvalds 	}
11771da177e4SLinus Torvalds 
11781da177e4SLinus Torvalds done:
11791da177e4SLinus Torvalds 	hci_req_unlock(hdev);
11801da177e4SLinus Torvalds 	hci_dev_put(hdev);
11811da177e4SLinus Torvalds 	return ret;
11821da177e4SLinus Torvalds }
11831da177e4SLinus Torvalds 
11841da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
11851da177e4SLinus Torvalds {
11861da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
11871da177e4SLinus Torvalds 
118828b75a89SAndre Guedes 	cancel_work_sync(&hdev->le_scan);
118928b75a89SAndre Guedes 
119078c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
119178c04c0bSVinicius Costa Gomes 
11921da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
11931da177e4SLinus Torvalds 	hci_req_lock(hdev);
11941da177e4SLinus Torvalds 
11951da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
1196b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
11971da177e4SLinus Torvalds 		hci_req_unlock(hdev);
11981da177e4SLinus Torvalds 		return 0;
11991da177e4SLinus Torvalds 	}
12001da177e4SLinus Torvalds 
12013eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
12023eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1203b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
12041da177e4SLinus Torvalds 
120516ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
1206e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
120716ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
12085e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
120916ab91abSJohan Hedberg 	}
121016ab91abSJohan Hedberg 
1211a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
12127d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
12137d78525dSJohan Hedberg 
12147ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
12157ba8b4beSAndre Guedes 
121609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
12171da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
12181da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
121909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
12201da177e4SLinus Torvalds 
12211da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
12221da177e4SLinus Torvalds 
12231da177e4SLinus Torvalds 	if (hdev->flush)
12241da177e4SLinus Torvalds 		hdev->flush(hdev);
12251da177e4SLinus Torvalds 
12261da177e4SLinus Torvalds 	/* Reset device */
12271da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
12281da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
12298af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
1230a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
12311da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
123201178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
12331da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
12341da177e4SLinus Torvalds 	}
12351da177e4SLinus Torvalds 
1236c347b765SGustavo F. Padovan 	/* flush cmd  work */
1237c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
12381da177e4SLinus Torvalds 
12391da177e4SLinus Torvalds 	/* Drop queues */
12401da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
12411da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
12421da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
12431da177e4SLinus Torvalds 
12441da177e4SLinus Torvalds 	/* Drop last sent command */
12451da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
1246b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
12471da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
12481da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
12491da177e4SLinus Torvalds 	}
12501da177e4SLinus Torvalds 
1251b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
1252b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
1253b6ddb638SJohan Hedberg 
12541da177e4SLinus Torvalds 	/* After this point our queues are empty
12551da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
12561da177e4SLinus Torvalds 	hdev->close(hdev);
12571da177e4SLinus Torvalds 
125835b973c9SJohan Hedberg 	/* Clear flags */
125935b973c9SJohan Hedberg 	hdev->flags = 0;
126035b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
126135b973c9SJohan Hedberg 
1262bb4b2a9aSAndrei Emeltchenko 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
1263bb4b2a9aSAndrei Emeltchenko 	    mgmt_valid_hdev(hdev)) {
126409fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1265744cf19eSJohan Hedberg 		mgmt_powered(hdev, 0);
126609fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
12678ee56540SMarcel Holtmann 	}
12685add6af8SJohan Hedberg 
1269ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1270ced5c338SAndrei Emeltchenko 	hdev->amp_status = 0;
1271ced5c338SAndrei Emeltchenko 
1272e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
127309b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
1274e59fda8dSJohan Hedberg 
12751da177e4SLinus Torvalds 	hci_req_unlock(hdev);
12761da177e4SLinus Torvalds 
12771da177e4SLinus Torvalds 	hci_dev_put(hdev);
12781da177e4SLinus Torvalds 	return 0;
12791da177e4SLinus Torvalds }
12801da177e4SLinus Torvalds 
12811da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
12821da177e4SLinus Torvalds {
12831da177e4SLinus Torvalds 	struct hci_dev *hdev;
12841da177e4SLinus Torvalds 	int err;
12851da177e4SLinus Torvalds 
128670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
128770f23020SAndrei Emeltchenko 	if (!hdev)
12881da177e4SLinus Torvalds 		return -ENODEV;
12898ee56540SMarcel Holtmann 
12908ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
12918ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
12928ee56540SMarcel Holtmann 
12931da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
12948ee56540SMarcel Holtmann 
12951da177e4SLinus Torvalds 	hci_dev_put(hdev);
12961da177e4SLinus Torvalds 	return err;
12971da177e4SLinus Torvalds }
12981da177e4SLinus Torvalds 
12991da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
13001da177e4SLinus Torvalds {
13011da177e4SLinus Torvalds 	struct hci_dev *hdev;
13021da177e4SLinus Torvalds 	int ret = 0;
13031da177e4SLinus Torvalds 
130470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
130570f23020SAndrei Emeltchenko 	if (!hdev)
13061da177e4SLinus Torvalds 		return -ENODEV;
13071da177e4SLinus Torvalds 
13081da177e4SLinus Torvalds 	hci_req_lock(hdev);
13091da177e4SLinus Torvalds 
13101da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
13111da177e4SLinus Torvalds 		goto done;
13121da177e4SLinus Torvalds 
13131da177e4SLinus Torvalds 	/* Drop queues */
13141da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
13151da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
13161da177e4SLinus Torvalds 
131709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13181da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
13191da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
132009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13211da177e4SLinus Torvalds 
13221da177e4SLinus Torvalds 	if (hdev->flush)
13231da177e4SLinus Torvalds 		hdev->flush(hdev);
13241da177e4SLinus Torvalds 
13251da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
13266ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
13271da177e4SLinus Torvalds 
13281da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
132901178cd4SJohan Hedberg 		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
13301da177e4SLinus Torvalds 
13311da177e4SLinus Torvalds done:
13321da177e4SLinus Torvalds 	hci_req_unlock(hdev);
13331da177e4SLinus Torvalds 	hci_dev_put(hdev);
13341da177e4SLinus Torvalds 	return ret;
13351da177e4SLinus Torvalds }
13361da177e4SLinus Torvalds 
13371da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
13381da177e4SLinus Torvalds {
13391da177e4SLinus Torvalds 	struct hci_dev *hdev;
13401da177e4SLinus Torvalds 	int ret = 0;
13411da177e4SLinus Torvalds 
134270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
134370f23020SAndrei Emeltchenko 	if (!hdev)
13441da177e4SLinus Torvalds 		return -ENODEV;
13451da177e4SLinus Torvalds 
13461da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
13471da177e4SLinus Torvalds 
13481da177e4SLinus Torvalds 	hci_dev_put(hdev);
13491da177e4SLinus Torvalds 
13501da177e4SLinus Torvalds 	return ret;
13511da177e4SLinus Torvalds }
13521da177e4SLinus Torvalds 
13531da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
13541da177e4SLinus Torvalds {
13551da177e4SLinus Torvalds 	struct hci_dev *hdev;
13561da177e4SLinus Torvalds 	struct hci_dev_req dr;
13571da177e4SLinus Torvalds 	int err = 0;
13581da177e4SLinus Torvalds 
13591da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
13601da177e4SLinus Torvalds 		return -EFAULT;
13611da177e4SLinus Torvalds 
136270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
136370f23020SAndrei Emeltchenko 	if (!hdev)
13641da177e4SLinus Torvalds 		return -ENODEV;
13651da177e4SLinus Torvalds 
13661da177e4SLinus Torvalds 	switch (cmd) {
13671da177e4SLinus Torvalds 	case HCISETAUTH:
136801178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
13695f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
13701da177e4SLinus Torvalds 		break;
13711da177e4SLinus Torvalds 
13721da177e4SLinus Torvalds 	case HCISETENCRYPT:
13731da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
13741da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
13751da177e4SLinus Torvalds 			break;
13761da177e4SLinus Torvalds 		}
13771da177e4SLinus Torvalds 
13781da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
13791da177e4SLinus Torvalds 			/* Auth must be enabled first */
138001178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
13815f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
13821da177e4SLinus Torvalds 			if (err)
13831da177e4SLinus Torvalds 				break;
13841da177e4SLinus Torvalds 		}
13851da177e4SLinus Torvalds 
138601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
13875f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
13881da177e4SLinus Torvalds 		break;
13891da177e4SLinus Torvalds 
13901da177e4SLinus Torvalds 	case HCISETSCAN:
139101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
13925f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
13931da177e4SLinus Torvalds 		break;
13941da177e4SLinus Torvalds 
13951da177e4SLinus Torvalds 	case HCISETLINKPOL:
139601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
13975f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
13981da177e4SLinus Torvalds 		break;
13991da177e4SLinus Torvalds 
14001da177e4SLinus Torvalds 	case HCISETLINKMODE:
1401e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
1402e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
1403e4e8e37cSMarcel Holtmann 		break;
1404e4e8e37cSMarcel Holtmann 
1405e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
1406e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
14071da177e4SLinus Torvalds 		break;
14081da177e4SLinus Torvalds 
14091da177e4SLinus Torvalds 	case HCISETACLMTU:
14101da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
14111da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
14121da177e4SLinus Torvalds 		break;
14131da177e4SLinus Torvalds 
14141da177e4SLinus Torvalds 	case HCISETSCOMTU:
14151da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
14161da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
14171da177e4SLinus Torvalds 		break;
14181da177e4SLinus Torvalds 
14191da177e4SLinus Torvalds 	default:
14201da177e4SLinus Torvalds 		err = -EINVAL;
14211da177e4SLinus Torvalds 		break;
14221da177e4SLinus Torvalds 	}
1423e4e8e37cSMarcel Holtmann 
14241da177e4SLinus Torvalds 	hci_dev_put(hdev);
14251da177e4SLinus Torvalds 	return err;
14261da177e4SLinus Torvalds }
14271da177e4SLinus Torvalds 
14281da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
14291da177e4SLinus Torvalds {
14308035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
14311da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
14321da177e4SLinus Torvalds 	struct hci_dev_req *dr;
14331da177e4SLinus Torvalds 	int n = 0, size, err;
14341da177e4SLinus Torvalds 	__u16 dev_num;
14351da177e4SLinus Torvalds 
14361da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
14371da177e4SLinus Torvalds 		return -EFAULT;
14381da177e4SLinus Torvalds 
14391da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
14401da177e4SLinus Torvalds 		return -EINVAL;
14411da177e4SLinus Torvalds 
14421da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
14431da177e4SLinus Torvalds 
144470f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
144570f23020SAndrei Emeltchenko 	if (!dl)
14461da177e4SLinus Torvalds 		return -ENOMEM;
14471da177e4SLinus Torvalds 
14481da177e4SLinus Torvalds 	dr = dl->dev_req;
14491da177e4SLinus Torvalds 
1450f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
14518035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
1452a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1453e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
1454c542a06cSJohan Hedberg 
1455a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1456a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1457c542a06cSJohan Hedberg 
14581da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
14591da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
1460c542a06cSJohan Hedberg 
14611da177e4SLinus Torvalds 		if (++n >= dev_num)
14621da177e4SLinus Torvalds 			break;
14631da177e4SLinus Torvalds 	}
1464f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
14651da177e4SLinus Torvalds 
14661da177e4SLinus Torvalds 	dl->dev_num = n;
14671da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
14681da177e4SLinus Torvalds 
14691da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
14701da177e4SLinus Torvalds 	kfree(dl);
14711da177e4SLinus Torvalds 
14721da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
14731da177e4SLinus Torvalds }
14741da177e4SLinus Torvalds 
14751da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
14761da177e4SLinus Torvalds {
14771da177e4SLinus Torvalds 	struct hci_dev *hdev;
14781da177e4SLinus Torvalds 	struct hci_dev_info di;
14791da177e4SLinus Torvalds 	int err = 0;
14801da177e4SLinus Torvalds 
14811da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
14821da177e4SLinus Torvalds 		return -EFAULT;
14831da177e4SLinus Torvalds 
148470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
148570f23020SAndrei Emeltchenko 	if (!hdev)
14861da177e4SLinus Torvalds 		return -ENODEV;
14871da177e4SLinus Torvalds 
1488a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
14893243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1490ab81cbf9SJohan Hedberg 
1491a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1492a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1493c542a06cSJohan Hedberg 
14941da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
14951da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
1496943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
14971da177e4SLinus Torvalds 	di.flags    = hdev->flags;
14981da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
1499572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
15001da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
15011da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
15021da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
15031da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
1504572c7f84SJohan Hedberg 	} else {
1505572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
1506572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
1507572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
1508572c7f84SJohan Hedberg 		di.sco_pkts = 0;
1509572c7f84SJohan Hedberg 	}
15101da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
15111da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
15121da177e4SLinus Torvalds 
15131da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
15141da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
15151da177e4SLinus Torvalds 
15161da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
15171da177e4SLinus Torvalds 		err = -EFAULT;
15181da177e4SLinus Torvalds 
15191da177e4SLinus Torvalds 	hci_dev_put(hdev);
15201da177e4SLinus Torvalds 
15211da177e4SLinus Torvalds 	return err;
15221da177e4SLinus Torvalds }
15231da177e4SLinus Torvalds 
15241da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
15251da177e4SLinus Torvalds 
1526611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1527611b30f7SMarcel Holtmann {
1528611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1529611b30f7SMarcel Holtmann 
1530611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1531611b30f7SMarcel Holtmann 
1532611b30f7SMarcel Holtmann 	if (!blocked)
1533611b30f7SMarcel Holtmann 		return 0;
1534611b30f7SMarcel Holtmann 
1535611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1536611b30f7SMarcel Holtmann 
1537611b30f7SMarcel Holtmann 	return 0;
1538611b30f7SMarcel Holtmann }
1539611b30f7SMarcel Holtmann 
1540611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1541611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1542611b30f7SMarcel Holtmann };
1543611b30f7SMarcel Holtmann 
1544ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1545ab81cbf9SJohan Hedberg {
1546ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
1547ab81cbf9SJohan Hedberg 
1548ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1549ab81cbf9SJohan Hedberg 
1550ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
1551ab81cbf9SJohan Hedberg 		return;
1552ab81cbf9SJohan Hedberg 
1553a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
155419202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
155519202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
1556ab81cbf9SJohan Hedberg 
1557a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1558744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1559ab81cbf9SJohan Hedberg }
1560ab81cbf9SJohan Hedberg 
1561ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1562ab81cbf9SJohan Hedberg {
15633243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
15643243553fSJohan Hedberg 					    power_off.work);
1565ab81cbf9SJohan Hedberg 
1566ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1567ab81cbf9SJohan Hedberg 
15688ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1569ab81cbf9SJohan Hedberg }
1570ab81cbf9SJohan Hedberg 
157116ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
157216ab91abSJohan Hedberg {
157316ab91abSJohan Hedberg 	struct hci_dev *hdev;
157416ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
157516ab91abSJohan Hedberg 
157616ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
157716ab91abSJohan Hedberg 
157816ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
157916ab91abSJohan Hedberg 
158009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
158116ab91abSJohan Hedberg 
158216ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
158316ab91abSJohan Hedberg 
158416ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
158516ab91abSJohan Hedberg 
158609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
158716ab91abSJohan Hedberg }
158816ab91abSJohan Hedberg 
15892aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
15902aeb9a1aSJohan Hedberg {
15914821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
15922aeb9a1aSJohan Hedberg 
15934821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
15944821002cSJohan Hedberg 		list_del(&uuid->list);
15952aeb9a1aSJohan Hedberg 		kfree(uuid);
15962aeb9a1aSJohan Hedberg 	}
15972aeb9a1aSJohan Hedberg 
15982aeb9a1aSJohan Hedberg 	return 0;
15992aeb9a1aSJohan Hedberg }
16002aeb9a1aSJohan Hedberg 
160155ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
160255ed8ca1SJohan Hedberg {
160355ed8ca1SJohan Hedberg 	struct list_head *p, *n;
160455ed8ca1SJohan Hedberg 
160555ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
160655ed8ca1SJohan Hedberg 		struct link_key *key;
160755ed8ca1SJohan Hedberg 
160855ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
160955ed8ca1SJohan Hedberg 
161055ed8ca1SJohan Hedberg 		list_del(p);
161155ed8ca1SJohan Hedberg 		kfree(key);
161255ed8ca1SJohan Hedberg 	}
161355ed8ca1SJohan Hedberg 
161455ed8ca1SJohan Hedberg 	return 0;
161555ed8ca1SJohan Hedberg }
161655ed8ca1SJohan Hedberg 
1617b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1618b899efafSVinicius Costa Gomes {
1619b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1620b899efafSVinicius Costa Gomes 
1621b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1622b899efafSVinicius Costa Gomes 		list_del(&k->list);
1623b899efafSVinicius Costa Gomes 		kfree(k);
1624b899efafSVinicius Costa Gomes 	}
1625b899efafSVinicius Costa Gomes 
1626b899efafSVinicius Costa Gomes 	return 0;
1627b899efafSVinicius Costa Gomes }
1628b899efafSVinicius Costa Gomes 
162955ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
163055ed8ca1SJohan Hedberg {
163155ed8ca1SJohan Hedberg 	struct link_key *k;
163255ed8ca1SJohan Hedberg 
16338035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
163455ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
163555ed8ca1SJohan Hedberg 			return k;
163655ed8ca1SJohan Hedberg 
163755ed8ca1SJohan Hedberg 	return NULL;
163855ed8ca1SJohan Hedberg }
163955ed8ca1SJohan Hedberg 
1640745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1641d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1642d25e28abSJohan Hedberg {
1643d25e28abSJohan Hedberg 	/* Legacy key */
1644d25e28abSJohan Hedberg 	if (key_type < 0x03)
1645745c0ce3SVishal Agarwal 		return true;
1646d25e28abSJohan Hedberg 
1647d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1648d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1649745c0ce3SVishal Agarwal 		return false;
1650d25e28abSJohan Hedberg 
1651d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1652d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1653745c0ce3SVishal Agarwal 		return false;
1654d25e28abSJohan Hedberg 
1655d25e28abSJohan Hedberg 	/* Security mode 3 case */
1656d25e28abSJohan Hedberg 	if (!conn)
1657745c0ce3SVishal Agarwal 		return true;
1658d25e28abSJohan Hedberg 
1659d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1660d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1661745c0ce3SVishal Agarwal 		return true;
1662d25e28abSJohan Hedberg 
1663d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1664d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1665745c0ce3SVishal Agarwal 		return true;
1666d25e28abSJohan Hedberg 
1667d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1668d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1669745c0ce3SVishal Agarwal 		return true;
1670d25e28abSJohan Hedberg 
1671d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1672d25e28abSJohan Hedberg 	 * persistently */
1673745c0ce3SVishal Agarwal 	return false;
1674d25e28abSJohan Hedberg }
1675d25e28abSJohan Hedberg 
1676c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
167775d262c2SVinicius Costa Gomes {
1678c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
167975d262c2SVinicius Costa Gomes 
1680c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1681c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1682c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
168375d262c2SVinicius Costa Gomes 			continue;
168475d262c2SVinicius Costa Gomes 
168575d262c2SVinicius Costa Gomes 		return k;
168675d262c2SVinicius Costa Gomes 	}
168775d262c2SVinicius Costa Gomes 
168875d262c2SVinicius Costa Gomes 	return NULL;
168975d262c2SVinicius Costa Gomes }
169075d262c2SVinicius Costa Gomes 
1691c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1692c9839a11SVinicius Costa Gomes 				     u8 addr_type)
169375d262c2SVinicius Costa Gomes {
1694c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
169575d262c2SVinicius Costa Gomes 
1696c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1697c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1698c9839a11SVinicius Costa Gomes 		    bacmp(bdaddr, &k->bdaddr) == 0)
169975d262c2SVinicius Costa Gomes 			return k;
170075d262c2SVinicius Costa Gomes 
170175d262c2SVinicius Costa Gomes 	return NULL;
170275d262c2SVinicius Costa Gomes }
170375d262c2SVinicius Costa Gomes 
1704d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1705d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
170655ed8ca1SJohan Hedberg {
170755ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1708745c0ce3SVishal Agarwal 	u8 old_key_type;
1709745c0ce3SVishal Agarwal 	bool persistent;
171055ed8ca1SJohan Hedberg 
171155ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
171255ed8ca1SJohan Hedberg 	if (old_key) {
171355ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
171455ed8ca1SJohan Hedberg 		key = old_key;
171555ed8ca1SJohan Hedberg 	} else {
171612adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
171755ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
171855ed8ca1SJohan Hedberg 		if (!key)
171955ed8ca1SJohan Hedberg 			return -ENOMEM;
172055ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
172155ed8ca1SJohan Hedberg 	}
172255ed8ca1SJohan Hedberg 
17236ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
172455ed8ca1SJohan Hedberg 
1725d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1726d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1727d25e28abSJohan Hedberg 	 * previous key */
1728d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1729a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1730d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1731655fe6ecSJohan Hedberg 		if (conn)
1732655fe6ecSJohan Hedberg 			conn->key_type = type;
1733655fe6ecSJohan Hedberg 	}
1734d25e28abSJohan Hedberg 
173555ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
17369b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
173755ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
173855ed8ca1SJohan Hedberg 
1739b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
174055ed8ca1SJohan Hedberg 		key->type = old_key_type;
17414748fed2SJohan Hedberg 	else
17424748fed2SJohan Hedberg 		key->type = type;
17434748fed2SJohan Hedberg 
17444df378a1SJohan Hedberg 	if (!new_key)
17454df378a1SJohan Hedberg 		return 0;
17464df378a1SJohan Hedberg 
17474df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
17484df378a1SJohan Hedberg 
1749744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
17504df378a1SJohan Hedberg 
17516ec5bcadSVishal Agarwal 	if (conn)
17526ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
175355ed8ca1SJohan Hedberg 
175455ed8ca1SJohan Hedberg 	return 0;
175555ed8ca1SJohan Hedberg }
175655ed8ca1SJohan Hedberg 
1757c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
17589a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
175904124681SGustavo F. Padovan 		ediv, u8 rand[8])
176075d262c2SVinicius Costa Gomes {
1761c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
176275d262c2SVinicius Costa Gomes 
1763c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1764c9839a11SVinicius Costa Gomes 		return 0;
176575d262c2SVinicius Costa Gomes 
1766c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1767c9839a11SVinicius Costa Gomes 	if (old_key)
176875d262c2SVinicius Costa Gomes 		key = old_key;
1769c9839a11SVinicius Costa Gomes 	else {
1770c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
177175d262c2SVinicius Costa Gomes 		if (!key)
177275d262c2SVinicius Costa Gomes 			return -ENOMEM;
1773c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
177475d262c2SVinicius Costa Gomes 	}
177575d262c2SVinicius Costa Gomes 
177675d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1777c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1778c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1779c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1780c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1781c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1782c9839a11SVinicius Costa Gomes 	key->type = type;
1783c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
178475d262c2SVinicius Costa Gomes 
1785c9839a11SVinicius Costa Gomes 	if (!new_key)
1786c9839a11SVinicius Costa Gomes 		return 0;
178775d262c2SVinicius Costa Gomes 
1788261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1789261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1790261cc5aaSVinicius Costa Gomes 
179175d262c2SVinicius Costa Gomes 	return 0;
179275d262c2SVinicius Costa Gomes }
179375d262c2SVinicius Costa Gomes 
179455ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
179555ed8ca1SJohan Hedberg {
179655ed8ca1SJohan Hedberg 	struct link_key *key;
179755ed8ca1SJohan Hedberg 
179855ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
179955ed8ca1SJohan Hedberg 	if (!key)
180055ed8ca1SJohan Hedberg 		return -ENOENT;
180155ed8ca1SJohan Hedberg 
18026ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
180355ed8ca1SJohan Hedberg 
180455ed8ca1SJohan Hedberg 	list_del(&key->list);
180555ed8ca1SJohan Hedberg 	kfree(key);
180655ed8ca1SJohan Hedberg 
180755ed8ca1SJohan Hedberg 	return 0;
180855ed8ca1SJohan Hedberg }
180955ed8ca1SJohan Hedberg 
1810b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1811b899efafSVinicius Costa Gomes {
1812b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1813b899efafSVinicius Costa Gomes 
1814b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1815b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1816b899efafSVinicius Costa Gomes 			continue;
1817b899efafSVinicius Costa Gomes 
18186ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1819b899efafSVinicius Costa Gomes 
1820b899efafSVinicius Costa Gomes 		list_del(&k->list);
1821b899efafSVinicius Costa Gomes 		kfree(k);
1822b899efafSVinicius Costa Gomes 	}
1823b899efafSVinicius Costa Gomes 
1824b899efafSVinicius Costa Gomes 	return 0;
1825b899efafSVinicius Costa Gomes }
1826b899efafSVinicius Costa Gomes 
18276bd32326SVille Tervo /* HCI command timer function */
1828bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
18296bd32326SVille Tervo {
18306bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
18316bd32326SVille Tervo 
1832bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
1833bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
1834bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
1835bda4f23aSAndrei Emeltchenko 
1836bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
1837bda4f23aSAndrei Emeltchenko 	} else {
18386bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
1839bda4f23aSAndrei Emeltchenko 	}
1840bda4f23aSAndrei Emeltchenko 
18416bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1842c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
18436bd32326SVille Tervo }
18446bd32326SVille Tervo 
18452763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
18462763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
18472763eda6SSzymon Janc {
18482763eda6SSzymon Janc 	struct oob_data *data;
18492763eda6SSzymon Janc 
18502763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
18512763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
18522763eda6SSzymon Janc 			return data;
18532763eda6SSzymon Janc 
18542763eda6SSzymon Janc 	return NULL;
18552763eda6SSzymon Janc }
18562763eda6SSzymon Janc 
18572763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
18582763eda6SSzymon Janc {
18592763eda6SSzymon Janc 	struct oob_data *data;
18602763eda6SSzymon Janc 
18612763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
18622763eda6SSzymon Janc 	if (!data)
18632763eda6SSzymon Janc 		return -ENOENT;
18642763eda6SSzymon Janc 
18656ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
18662763eda6SSzymon Janc 
18672763eda6SSzymon Janc 	list_del(&data->list);
18682763eda6SSzymon Janc 	kfree(data);
18692763eda6SSzymon Janc 
18702763eda6SSzymon Janc 	return 0;
18712763eda6SSzymon Janc }
18722763eda6SSzymon Janc 
18732763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
18742763eda6SSzymon Janc {
18752763eda6SSzymon Janc 	struct oob_data *data, *n;
18762763eda6SSzymon Janc 
18772763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
18782763eda6SSzymon Janc 		list_del(&data->list);
18792763eda6SSzymon Janc 		kfree(data);
18802763eda6SSzymon Janc 	}
18812763eda6SSzymon Janc 
18822763eda6SSzymon Janc 	return 0;
18832763eda6SSzymon Janc }
18842763eda6SSzymon Janc 
18852763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
18862763eda6SSzymon Janc 			    u8 *randomizer)
18872763eda6SSzymon Janc {
18882763eda6SSzymon Janc 	struct oob_data *data;
18892763eda6SSzymon Janc 
18902763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
18912763eda6SSzymon Janc 
18922763eda6SSzymon Janc 	if (!data) {
18932763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
18942763eda6SSzymon Janc 		if (!data)
18952763eda6SSzymon Janc 			return -ENOMEM;
18962763eda6SSzymon Janc 
18972763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
18982763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
18992763eda6SSzymon Janc 	}
19002763eda6SSzymon Janc 
19012763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
19022763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
19032763eda6SSzymon Janc 
19046ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
19052763eda6SSzymon Janc 
19062763eda6SSzymon Janc 	return 0;
19072763eda6SSzymon Janc }
19082763eda6SSzymon Janc 
190904124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
1910b2a66aadSAntti Julku {
1911b2a66aadSAntti Julku 	struct bdaddr_list *b;
1912b2a66aadSAntti Julku 
19138035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1914b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1915b2a66aadSAntti Julku 			return b;
1916b2a66aadSAntti Julku 
1917b2a66aadSAntti Julku 	return NULL;
1918b2a66aadSAntti Julku }
1919b2a66aadSAntti Julku 
1920b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1921b2a66aadSAntti Julku {
1922b2a66aadSAntti Julku 	struct list_head *p, *n;
1923b2a66aadSAntti Julku 
1924b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1925b2a66aadSAntti Julku 		struct bdaddr_list *b;
1926b2a66aadSAntti Julku 
1927b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1928b2a66aadSAntti Julku 
1929b2a66aadSAntti Julku 		list_del(p);
1930b2a66aadSAntti Julku 		kfree(b);
1931b2a66aadSAntti Julku 	}
1932b2a66aadSAntti Julku 
1933b2a66aadSAntti Julku 	return 0;
1934b2a66aadSAntti Julku }
1935b2a66aadSAntti Julku 
193688c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1937b2a66aadSAntti Julku {
1938b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1939b2a66aadSAntti Julku 
1940b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1941b2a66aadSAntti Julku 		return -EBADF;
1942b2a66aadSAntti Julku 
19435e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
19445e762444SAntti Julku 		return -EEXIST;
1945b2a66aadSAntti Julku 
1946b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
19475e762444SAntti Julku 	if (!entry)
19485e762444SAntti Julku 		return -ENOMEM;
1949b2a66aadSAntti Julku 
1950b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1951b2a66aadSAntti Julku 
1952b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1953b2a66aadSAntti Julku 
195488c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
1955b2a66aadSAntti Julku }
1956b2a66aadSAntti Julku 
195788c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1958b2a66aadSAntti Julku {
1959b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1960b2a66aadSAntti Julku 
19611ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
19625e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1963b2a66aadSAntti Julku 
1964b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
19651ec918ceSSzymon Janc 	if (!entry)
19665e762444SAntti Julku 		return -ENOENT;
1967b2a66aadSAntti Julku 
1968b2a66aadSAntti Julku 	list_del(&entry->list);
1969b2a66aadSAntti Julku 	kfree(entry);
1970b2a66aadSAntti Julku 
197188c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
1972b2a66aadSAntti Julku }
1973b2a66aadSAntti Julku 
197442c6b129SJohan Hedberg static void le_scan_param_req(struct hci_request *req, unsigned long opt)
19757ba8b4beSAndre Guedes {
19767ba8b4beSAndre Guedes 	struct le_scan_params *param =  (struct le_scan_params *) opt;
19777ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_param cp;
19787ba8b4beSAndre Guedes 
19797ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
19807ba8b4beSAndre Guedes 	cp.type = param->type;
19817ba8b4beSAndre Guedes 	cp.interval = cpu_to_le16(param->interval);
19827ba8b4beSAndre Guedes 	cp.window = cpu_to_le16(param->window);
19837ba8b4beSAndre Guedes 
198442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
19857ba8b4beSAndre Guedes }
19867ba8b4beSAndre Guedes 
198742c6b129SJohan Hedberg static void le_scan_enable_req(struct hci_request *req, unsigned long opt)
19887ba8b4beSAndre Guedes {
19897ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
19907ba8b4beSAndre Guedes 
19917ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
199276a388beSAndre Guedes 	cp.enable = LE_SCAN_ENABLE;
1993525e296aSAndre Guedes 	cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
19947ba8b4beSAndre Guedes 
199542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
19967ba8b4beSAndre Guedes }
19977ba8b4beSAndre Guedes 
19987ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
19997ba8b4beSAndre Guedes 			  u16 window, int timeout)
20007ba8b4beSAndre Guedes {
20017ba8b4beSAndre Guedes 	long timeo = msecs_to_jiffies(3000);
20027ba8b4beSAndre Guedes 	struct le_scan_params param;
20037ba8b4beSAndre Guedes 	int err;
20047ba8b4beSAndre Guedes 
20057ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
20067ba8b4beSAndre Guedes 
20077ba8b4beSAndre Guedes 	if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
20087ba8b4beSAndre Guedes 		return -EINPROGRESS;
20097ba8b4beSAndre Guedes 
20107ba8b4beSAndre Guedes 	param.type = type;
20117ba8b4beSAndre Guedes 	param.interval = interval;
20127ba8b4beSAndre Guedes 	param.window = window;
20137ba8b4beSAndre Guedes 
20147ba8b4beSAndre Guedes 	hci_req_lock(hdev);
20157ba8b4beSAndre Guedes 
201601178cd4SJohan Hedberg 	err = __hci_req_sync(hdev, le_scan_param_req, (unsigned long) &param,
20177ba8b4beSAndre Guedes 			     timeo);
20187ba8b4beSAndre Guedes 	if (!err)
201901178cd4SJohan Hedberg 		err = __hci_req_sync(hdev, le_scan_enable_req, 0, timeo);
20207ba8b4beSAndre Guedes 
20217ba8b4beSAndre Guedes 	hci_req_unlock(hdev);
20227ba8b4beSAndre Guedes 
20237ba8b4beSAndre Guedes 	if (err < 0)
20247ba8b4beSAndre Guedes 		return err;
20257ba8b4beSAndre Guedes 
202646818ed5SJohan Hedberg 	queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable,
2027b6c7515aSAndre Guedes 			   timeout);
20287ba8b4beSAndre Guedes 
20297ba8b4beSAndre Guedes 	return 0;
20307ba8b4beSAndre Guedes }
20317ba8b4beSAndre Guedes 
20327dbfac1dSAndre Guedes int hci_cancel_le_scan(struct hci_dev *hdev)
20337dbfac1dSAndre Guedes {
20347dbfac1dSAndre Guedes 	BT_DBG("%s", hdev->name);
20357dbfac1dSAndre Guedes 
20367dbfac1dSAndre Guedes 	if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
20377dbfac1dSAndre Guedes 		return -EALREADY;
20387dbfac1dSAndre Guedes 
20397dbfac1dSAndre Guedes 	if (cancel_delayed_work(&hdev->le_scan_disable)) {
20407dbfac1dSAndre Guedes 		struct hci_cp_le_set_scan_enable cp;
20417dbfac1dSAndre Guedes 
20427dbfac1dSAndre Guedes 		/* Send HCI command to disable LE Scan */
20437dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
20447dbfac1dSAndre Guedes 		hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
20457dbfac1dSAndre Guedes 	}
20467dbfac1dSAndre Guedes 
20477dbfac1dSAndre Guedes 	return 0;
20487dbfac1dSAndre Guedes }
20497dbfac1dSAndre Guedes 
20507ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
20517ba8b4beSAndre Guedes {
20527ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
20537ba8b4beSAndre Guedes 					    le_scan_disable.work);
20547ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
20557ba8b4beSAndre Guedes 
20567ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
20577ba8b4beSAndre Guedes 
20587ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
20597ba8b4beSAndre Guedes 
20607ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
20617ba8b4beSAndre Guedes }
20627ba8b4beSAndre Guedes 
206328b75a89SAndre Guedes static void le_scan_work(struct work_struct *work)
206428b75a89SAndre Guedes {
206528b75a89SAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
206628b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
206728b75a89SAndre Guedes 
206828b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
206928b75a89SAndre Guedes 
207004124681SGustavo F. Padovan 	hci_do_le_scan(hdev, param->type, param->interval, param->window,
207104124681SGustavo F. Padovan 		       param->timeout);
207228b75a89SAndre Guedes }
207328b75a89SAndre Guedes 
207428b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
207528b75a89SAndre Guedes 		int timeout)
207628b75a89SAndre Guedes {
207728b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
207828b75a89SAndre Guedes 
207928b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
208028b75a89SAndre Guedes 
2081f1550478SJohan Hedberg 	if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
2082f1550478SJohan Hedberg 		return -ENOTSUPP;
2083f1550478SJohan Hedberg 
208428b75a89SAndre Guedes 	if (work_busy(&hdev->le_scan))
208528b75a89SAndre Guedes 		return -EINPROGRESS;
208628b75a89SAndre Guedes 
208728b75a89SAndre Guedes 	param->type = type;
208828b75a89SAndre Guedes 	param->interval = interval;
208928b75a89SAndre Guedes 	param->window = window;
209028b75a89SAndre Guedes 	param->timeout = timeout;
209128b75a89SAndre Guedes 
209228b75a89SAndre Guedes 	queue_work(system_long_wq, &hdev->le_scan);
209328b75a89SAndre Guedes 
209428b75a89SAndre Guedes 	return 0;
209528b75a89SAndre Guedes }
209628b75a89SAndre Guedes 
20979be0dab7SDavid Herrmann /* Alloc HCI device */
20989be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
20999be0dab7SDavid Herrmann {
21009be0dab7SDavid Herrmann 	struct hci_dev *hdev;
21019be0dab7SDavid Herrmann 
21029be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
21039be0dab7SDavid Herrmann 	if (!hdev)
21049be0dab7SDavid Herrmann 		return NULL;
21059be0dab7SDavid Herrmann 
2106b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2107b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
2108b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
2109b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03; /* No Input No Output */
2110bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2111bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2112b1b813d4SDavid Herrmann 
2113b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
2114b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
2115b1b813d4SDavid Herrmann 
2116b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
2117b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
2118b1b813d4SDavid Herrmann 
2119b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
2120b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
2121b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
2122b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
2123b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
2124b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
21256b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
2126b1b813d4SDavid Herrmann 
2127b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2128b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2129b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2130b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2131b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->le_scan, le_scan_work);
2132b1b813d4SDavid Herrmann 
2133b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2134b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
2135b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
2136b1b813d4SDavid Herrmann 
2137b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2138b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2139b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2140b1b813d4SDavid Herrmann 
2141b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2142b1b813d4SDavid Herrmann 
2143bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
2144b1b813d4SDavid Herrmann 
2145b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2146b1b813d4SDavid Herrmann 	discovery_init(hdev);
21479be0dab7SDavid Herrmann 
21489be0dab7SDavid Herrmann 	return hdev;
21499be0dab7SDavid Herrmann }
21509be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
21519be0dab7SDavid Herrmann 
21529be0dab7SDavid Herrmann /* Free HCI device */
21539be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
21549be0dab7SDavid Herrmann {
21559be0dab7SDavid Herrmann 	/* will free via device release */
21569be0dab7SDavid Herrmann 	put_device(&hdev->dev);
21579be0dab7SDavid Herrmann }
21589be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
21599be0dab7SDavid Herrmann 
21601da177e4SLinus Torvalds /* Register HCI device */
21611da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
21621da177e4SLinus Torvalds {
2163b1b813d4SDavid Herrmann 	int id, error;
21641da177e4SLinus Torvalds 
2165010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
21661da177e4SLinus Torvalds 		return -EINVAL;
21671da177e4SLinus Torvalds 
216808add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
216908add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
217008add513SMat Martineau 	 */
21713df92b31SSasha Levin 	switch (hdev->dev_type) {
21723df92b31SSasha Levin 	case HCI_BREDR:
21733df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
21741da177e4SLinus Torvalds 		break;
21753df92b31SSasha Levin 	case HCI_AMP:
21763df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
21773df92b31SSasha Levin 		break;
21783df92b31SSasha Levin 	default:
21793df92b31SSasha Levin 		return -EINVAL;
21801da177e4SLinus Torvalds 	}
21811da177e4SLinus Torvalds 
21823df92b31SSasha Levin 	if (id < 0)
21833df92b31SSasha Levin 		return id;
21843df92b31SSasha Levin 
21851da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
21861da177e4SLinus Torvalds 	hdev->id = id;
21872d8b3a11SAndrei Emeltchenko 
21882d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
21892d8b3a11SAndrei Emeltchenko 
21903df92b31SSasha Levin 	write_lock(&hci_dev_list_lock);
21913df92b31SSasha Levin 	list_add(&hdev->list, &hci_dev_list);
2192f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
21931da177e4SLinus Torvalds 
219432845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
219532845eb1SGustavo F. Padovan 					  WQ_MEM_RECLAIM, 1);
219633ca954dSDavid Herrmann 	if (!hdev->workqueue) {
219733ca954dSDavid Herrmann 		error = -ENOMEM;
219833ca954dSDavid Herrmann 		goto err;
219933ca954dSDavid Herrmann 	}
2200f48fd9c8SMarcel Holtmann 
22016ead1bbcSJohan Hedberg 	hdev->req_workqueue = alloc_workqueue(hdev->name,
22026ead1bbcSJohan Hedberg 					      WQ_HIGHPRI | WQ_UNBOUND |
22036ead1bbcSJohan Hedberg 					      WQ_MEM_RECLAIM, 1);
22046ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
22056ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
22066ead1bbcSJohan Hedberg 		error = -ENOMEM;
22076ead1bbcSJohan Hedberg 		goto err;
22086ead1bbcSJohan Hedberg 	}
22096ead1bbcSJohan Hedberg 
221033ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
221133ca954dSDavid Herrmann 	if (error < 0)
221233ca954dSDavid Herrmann 		goto err_wqueue;
22131da177e4SLinus Torvalds 
2214611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2215a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2216a8c5fb1aSGustavo Padovan 				    hdev);
2217611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2218611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
2219611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
2220611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
2221611b30f7SMarcel Holtmann 		}
2222611b30f7SMarcel Holtmann 	}
2223611b30f7SMarcel Holtmann 
2224a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
2225ce2be9acSAndrei Emeltchenko 
2226ce2be9acSAndrei Emeltchenko 	if (hdev->dev_type != HCI_AMP)
2227ce2be9acSAndrei Emeltchenko 		set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2228ce2be9acSAndrei Emeltchenko 
22291da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
2230dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
22311da177e4SLinus Torvalds 
223219202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2233fbe96d6fSMarcel Holtmann 
22341da177e4SLinus Torvalds 	return id;
2235f48fd9c8SMarcel Holtmann 
223633ca954dSDavid Herrmann err_wqueue:
223733ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
22386ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
223933ca954dSDavid Herrmann err:
22403df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
2241f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
2242f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
2243f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
2244f48fd9c8SMarcel Holtmann 
224533ca954dSDavid Herrmann 	return error;
22461da177e4SLinus Torvalds }
22471da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
22481da177e4SLinus Torvalds 
22491da177e4SLinus Torvalds /* Unregister HCI device */
225059735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
22511da177e4SLinus Torvalds {
22523df92b31SSasha Levin 	int i, id;
2253ef222013SMarcel Holtmann 
2254c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
22551da177e4SLinus Torvalds 
225694324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
225794324962SJohan Hovold 
22583df92b31SSasha Levin 	id = hdev->id;
22593df92b31SSasha Levin 
2260f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
22611da177e4SLinus Torvalds 	list_del(&hdev->list);
2262f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
22631da177e4SLinus Torvalds 
22641da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
22651da177e4SLinus Torvalds 
2266cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
2267ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
2268ef222013SMarcel Holtmann 
2269b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
2270b9b5ef18SGustavo Padovan 
2271ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2272a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
227309fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2274744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
227509fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
227656e5cb86SJohan Hedberg 	}
2277ab81cbf9SJohan Hedberg 
22782e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
22792e58ef3eSJohan Hedberg 	 * pending list */
22802e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
22812e58ef3eSJohan Hedberg 
22821da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
22831da177e4SLinus Torvalds 
2284611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2285611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2286611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2287611b30f7SMarcel Holtmann 	}
2288611b30f7SMarcel Holtmann 
2289ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
2290147e2d59SDave Young 
2291f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
22926ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2293f48fd9c8SMarcel Holtmann 
229409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
2295e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
22962aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
229755ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2298b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
22992763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
230009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2301e2e0cacbSJohan Hedberg 
2302dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
23033df92b31SSasha Levin 
23043df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
23051da177e4SLinus Torvalds }
23061da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
23071da177e4SLinus Torvalds 
23081da177e4SLinus Torvalds /* Suspend HCI device */
23091da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
23101da177e4SLinus Torvalds {
23111da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
23121da177e4SLinus Torvalds 	return 0;
23131da177e4SLinus Torvalds }
23141da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
23151da177e4SLinus Torvalds 
23161da177e4SLinus Torvalds /* Resume HCI device */
23171da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
23181da177e4SLinus Torvalds {
23191da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
23201da177e4SLinus Torvalds 	return 0;
23211da177e4SLinus Torvalds }
23221da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
23231da177e4SLinus Torvalds 
232476bca880SMarcel Holtmann /* Receive frame from HCI drivers */
232576bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
232676bca880SMarcel Holtmann {
232776bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
232876bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
232976bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
233076bca880SMarcel Holtmann 		kfree_skb(skb);
233176bca880SMarcel Holtmann 		return -ENXIO;
233276bca880SMarcel Holtmann 	}
233376bca880SMarcel Holtmann 
2334d82603c6SJorrit Schippers 	/* Incoming skb */
233576bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
233676bca880SMarcel Holtmann 
233776bca880SMarcel Holtmann 	/* Time stamp */
233876bca880SMarcel Holtmann 	__net_timestamp(skb);
233976bca880SMarcel Holtmann 
234076bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2341b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2342c78ae283SMarcel Holtmann 
234376bca880SMarcel Holtmann 	return 0;
234476bca880SMarcel Holtmann }
234576bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
234676bca880SMarcel Holtmann 
234733e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
23481e429f38SGustavo F. Padovan 			  int count, __u8 index)
234933e882a5SSuraj Sumangala {
235033e882a5SSuraj Sumangala 	int len = 0;
235133e882a5SSuraj Sumangala 	int hlen = 0;
235233e882a5SSuraj Sumangala 	int remain = count;
235333e882a5SSuraj Sumangala 	struct sk_buff *skb;
235433e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
235533e882a5SSuraj Sumangala 
235633e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
235733e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
235833e882a5SSuraj Sumangala 		return -EILSEQ;
235933e882a5SSuraj Sumangala 
236033e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
236133e882a5SSuraj Sumangala 
236233e882a5SSuraj Sumangala 	if (!skb) {
236333e882a5SSuraj Sumangala 		switch (type) {
236433e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
236533e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
236633e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
236733e882a5SSuraj Sumangala 			break;
236833e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
236933e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
237033e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
237133e882a5SSuraj Sumangala 			break;
237233e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
237333e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
237433e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
237533e882a5SSuraj Sumangala 			break;
237633e882a5SSuraj Sumangala 		}
237733e882a5SSuraj Sumangala 
23781e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
237933e882a5SSuraj Sumangala 		if (!skb)
238033e882a5SSuraj Sumangala 			return -ENOMEM;
238133e882a5SSuraj Sumangala 
238233e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
238333e882a5SSuraj Sumangala 		scb->expect = hlen;
238433e882a5SSuraj Sumangala 		scb->pkt_type = type;
238533e882a5SSuraj Sumangala 
238633e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
238733e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
238833e882a5SSuraj Sumangala 	}
238933e882a5SSuraj Sumangala 
239033e882a5SSuraj Sumangala 	while (count) {
239133e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
239289bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
239333e882a5SSuraj Sumangala 
239433e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
239533e882a5SSuraj Sumangala 
239633e882a5SSuraj Sumangala 		count -= len;
239733e882a5SSuraj Sumangala 		data += len;
239833e882a5SSuraj Sumangala 		scb->expect -= len;
239933e882a5SSuraj Sumangala 		remain = count;
240033e882a5SSuraj Sumangala 
240133e882a5SSuraj Sumangala 		switch (type) {
240233e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
240333e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
240433e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
240533e882a5SSuraj Sumangala 				scb->expect = h->plen;
240633e882a5SSuraj Sumangala 
240733e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
240833e882a5SSuraj Sumangala 					kfree_skb(skb);
240933e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
241033e882a5SSuraj Sumangala 					return -ENOMEM;
241133e882a5SSuraj Sumangala 				}
241233e882a5SSuraj Sumangala 			}
241333e882a5SSuraj Sumangala 			break;
241433e882a5SSuraj Sumangala 
241533e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
241633e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
241733e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
241833e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
241933e882a5SSuraj Sumangala 
242033e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
242133e882a5SSuraj Sumangala 					kfree_skb(skb);
242233e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
242333e882a5SSuraj Sumangala 					return -ENOMEM;
242433e882a5SSuraj Sumangala 				}
242533e882a5SSuraj Sumangala 			}
242633e882a5SSuraj Sumangala 			break;
242733e882a5SSuraj Sumangala 
242833e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
242933e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
243033e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
243133e882a5SSuraj Sumangala 				scb->expect = h->dlen;
243233e882a5SSuraj Sumangala 
243333e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
243433e882a5SSuraj Sumangala 					kfree_skb(skb);
243533e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
243633e882a5SSuraj Sumangala 					return -ENOMEM;
243733e882a5SSuraj Sumangala 				}
243833e882a5SSuraj Sumangala 			}
243933e882a5SSuraj Sumangala 			break;
244033e882a5SSuraj Sumangala 		}
244133e882a5SSuraj Sumangala 
244233e882a5SSuraj Sumangala 		if (scb->expect == 0) {
244333e882a5SSuraj Sumangala 			/* Complete frame */
244433e882a5SSuraj Sumangala 
244533e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
244633e882a5SSuraj Sumangala 			hci_recv_frame(skb);
244733e882a5SSuraj Sumangala 
244833e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
244933e882a5SSuraj Sumangala 			return remain;
245033e882a5SSuraj Sumangala 		}
245133e882a5SSuraj Sumangala 	}
245233e882a5SSuraj Sumangala 
245333e882a5SSuraj Sumangala 	return remain;
245433e882a5SSuraj Sumangala }
245533e882a5SSuraj Sumangala 
2456ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
2457ef222013SMarcel Holtmann {
2458f39a3c06SSuraj Sumangala 	int rem = 0;
2459f39a3c06SSuraj Sumangala 
2460ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
2461ef222013SMarcel Holtmann 		return -EILSEQ;
2462ef222013SMarcel Holtmann 
2463da5f6c37SGustavo F. Padovan 	while (count) {
24641e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
2465f39a3c06SSuraj Sumangala 		if (rem < 0)
2466f39a3c06SSuraj Sumangala 			return rem;
2467ef222013SMarcel Holtmann 
2468f39a3c06SSuraj Sumangala 		data += (count - rem);
2469f39a3c06SSuraj Sumangala 		count = rem;
2470f81c6224SJoe Perches 	}
2471ef222013SMarcel Holtmann 
2472f39a3c06SSuraj Sumangala 	return rem;
2473ef222013SMarcel Holtmann }
2474ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
2475ef222013SMarcel Holtmann 
247699811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
247799811510SSuraj Sumangala 
247899811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
247999811510SSuraj Sumangala {
248099811510SSuraj Sumangala 	int type;
248199811510SSuraj Sumangala 	int rem = 0;
248299811510SSuraj Sumangala 
2483da5f6c37SGustavo F. Padovan 	while (count) {
248499811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
248599811510SSuraj Sumangala 
248699811510SSuraj Sumangala 		if (!skb) {
248799811510SSuraj Sumangala 			struct { char type; } *pkt;
248899811510SSuraj Sumangala 
248999811510SSuraj Sumangala 			/* Start of the frame */
249099811510SSuraj Sumangala 			pkt = data;
249199811510SSuraj Sumangala 			type = pkt->type;
249299811510SSuraj Sumangala 
249399811510SSuraj Sumangala 			data++;
249499811510SSuraj Sumangala 			count--;
249599811510SSuraj Sumangala 		} else
249699811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
249799811510SSuraj Sumangala 
24981e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
24991e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
250099811510SSuraj Sumangala 		if (rem < 0)
250199811510SSuraj Sumangala 			return rem;
250299811510SSuraj Sumangala 
250399811510SSuraj Sumangala 		data += (count - rem);
250499811510SSuraj Sumangala 		count = rem;
2505f81c6224SJoe Perches 	}
250699811510SSuraj Sumangala 
250799811510SSuraj Sumangala 	return rem;
250899811510SSuraj Sumangala }
250999811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
251099811510SSuraj Sumangala 
25111da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
25121da177e4SLinus Torvalds 
25131da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
25141da177e4SLinus Torvalds {
25151da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
25161da177e4SLinus Torvalds 
2517f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
25181da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2519f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
25201da177e4SLinus Torvalds 
25211da177e4SLinus Torvalds 	return 0;
25221da177e4SLinus Torvalds }
25231da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
25241da177e4SLinus Torvalds 
25251da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
25261da177e4SLinus Torvalds {
25271da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
25281da177e4SLinus Torvalds 
2529f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
25301da177e4SLinus Torvalds 	list_del(&cb->list);
2531f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
25321da177e4SLinus Torvalds 
25331da177e4SLinus Torvalds 	return 0;
25341da177e4SLinus Torvalds }
25351da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
25361da177e4SLinus Torvalds 
25371da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
25381da177e4SLinus Torvalds {
25391da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
25401da177e4SLinus Torvalds 
25411da177e4SLinus Torvalds 	if (!hdev) {
25421da177e4SLinus Torvalds 		kfree_skb(skb);
25431da177e4SLinus Torvalds 		return -ENODEV;
25441da177e4SLinus Torvalds 	}
25451da177e4SLinus Torvalds 
25460d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
25471da177e4SLinus Torvalds 
25481da177e4SLinus Torvalds 	/* Time stamp */
2549a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
25501da177e4SLinus Torvalds 
2551cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2552cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2553cd82e61cSMarcel Holtmann 
2554cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2555cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2556470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
25571da177e4SLinus Torvalds 	}
25581da177e4SLinus Torvalds 
25591da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
25601da177e4SLinus Torvalds 	skb_orphan(skb);
25611da177e4SLinus Torvalds 
25621da177e4SLinus Torvalds 	return hdev->send(skb);
25631da177e4SLinus Torvalds }
25641da177e4SLinus Torvalds 
25653119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
25663119ae95SJohan Hedberg {
25673119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
25683119ae95SJohan Hedberg 	req->hdev = hdev;
25695d73e034SAndre Guedes 	req->err = 0;
25703119ae95SJohan Hedberg }
25713119ae95SJohan Hedberg 
25723119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
25733119ae95SJohan Hedberg {
25743119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
25753119ae95SJohan Hedberg 	struct sk_buff *skb;
25763119ae95SJohan Hedberg 	unsigned long flags;
25773119ae95SJohan Hedberg 
25783119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
25793119ae95SJohan Hedberg 
25805d73e034SAndre Guedes 	/* If an error occured during request building, remove all HCI
25815d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
25825d73e034SAndre Guedes 	 */
25835d73e034SAndre Guedes 	if (req->err) {
25845d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
25855d73e034SAndre Guedes 		return req->err;
25865d73e034SAndre Guedes 	}
25875d73e034SAndre Guedes 
25883119ae95SJohan Hedberg 	/* Do not allow empty requests */
25893119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
2590382b0c39SAndre Guedes 		return -ENODATA;
25913119ae95SJohan Hedberg 
25923119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
25933119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
25943119ae95SJohan Hedberg 
25953119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
25963119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
25973119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
25983119ae95SJohan Hedberg 
25993119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
26003119ae95SJohan Hedberg 
26013119ae95SJohan Hedberg 	return 0;
26023119ae95SJohan Hedberg }
26033119ae95SJohan Hedberg 
26041ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
26051ca3a9d0SJohan Hedberg 				       u32 plen, void *param)
26061da177e4SLinus Torvalds {
26071da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
26081da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
26091da177e4SLinus Torvalds 	struct sk_buff *skb;
26101da177e4SLinus Torvalds 
26111da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
26121ca3a9d0SJohan Hedberg 	if (!skb)
26131ca3a9d0SJohan Hedberg 		return NULL;
26141da177e4SLinus Torvalds 
26151da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2616a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
26171da177e4SLinus Torvalds 	hdr->plen   = plen;
26181da177e4SLinus Torvalds 
26191da177e4SLinus Torvalds 	if (plen)
26201da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
26211da177e4SLinus Torvalds 
26221da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
26231da177e4SLinus Torvalds 
26240d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
26251da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2626c78ae283SMarcel Holtmann 
26271ca3a9d0SJohan Hedberg 	return skb;
26281ca3a9d0SJohan Hedberg }
26291ca3a9d0SJohan Hedberg 
26301ca3a9d0SJohan Hedberg /* Send HCI command */
26311ca3a9d0SJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
26321ca3a9d0SJohan Hedberg {
26331ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
26341ca3a9d0SJohan Hedberg 
26351ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
26361ca3a9d0SJohan Hedberg 
26371ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
26381ca3a9d0SJohan Hedberg 	if (!skb) {
26391ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
26401ca3a9d0SJohan Hedberg 		return -ENOMEM;
26411ca3a9d0SJohan Hedberg 	}
26421ca3a9d0SJohan Hedberg 
264311714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
264411714b3dSJohan Hedberg 	 * single-command requests.
264511714b3dSJohan Hedberg 	 */
264611714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
264711714b3dSJohan Hedberg 
26481da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2649c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
26501da177e4SLinus Torvalds 
26511da177e4SLinus Torvalds 	return 0;
26521da177e4SLinus Torvalds }
26531da177e4SLinus Torvalds 
265471c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
265502350a72SJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, void *param,
265602350a72SJohan Hedberg 		    u8 event)
265771c76a17SJohan Hedberg {
265871c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
265971c76a17SJohan Hedberg 	struct sk_buff *skb;
266071c76a17SJohan Hedberg 
266171c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
266271c76a17SJohan Hedberg 
266334739c1eSAndre Guedes 	/* If an error occured during request building, there is no point in
266434739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
266534739c1eSAndre Guedes 	 */
266634739c1eSAndre Guedes 	if (req->err)
266734739c1eSAndre Guedes 		return;
266834739c1eSAndre Guedes 
266971c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
267071c76a17SJohan Hedberg 	if (!skb) {
26715d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
26725d73e034SAndre Guedes 		       hdev->name, opcode);
26735d73e034SAndre Guedes 		req->err = -ENOMEM;
2674e348fe6bSAndre Guedes 		return;
267571c76a17SJohan Hedberg 	}
267671c76a17SJohan Hedberg 
267771c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
267871c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
267971c76a17SJohan Hedberg 
268002350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
268102350a72SJohan Hedberg 
268271c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
268371c76a17SJohan Hedberg }
268471c76a17SJohan Hedberg 
268502350a72SJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param)
268602350a72SJohan Hedberg {
268702350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
268802350a72SJohan Hedberg }
268902350a72SJohan Hedberg 
26901da177e4SLinus Torvalds /* Get data from the previously sent command */
2691a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
26921da177e4SLinus Torvalds {
26931da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
26941da177e4SLinus Torvalds 
26951da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
26961da177e4SLinus Torvalds 		return NULL;
26971da177e4SLinus Torvalds 
26981da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
26991da177e4SLinus Torvalds 
2700a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
27011da177e4SLinus Torvalds 		return NULL;
27021da177e4SLinus Torvalds 
2703f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
27041da177e4SLinus Torvalds 
27051da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
27061da177e4SLinus Torvalds }
27071da177e4SLinus Torvalds 
27081da177e4SLinus Torvalds /* Send ACL data */
27091da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
27101da177e4SLinus Torvalds {
27111da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
27121da177e4SLinus Torvalds 	int len = skb->len;
27131da177e4SLinus Torvalds 
2714badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2715badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
27169c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2717aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2718aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
27191da177e4SLinus Torvalds }
27201da177e4SLinus Torvalds 
2721ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
272273d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
27231da177e4SLinus Torvalds {
2724ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
27251da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
27261da177e4SLinus Torvalds 	struct sk_buff *list;
27271da177e4SLinus Torvalds 
2728087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
2729087bfd99SGustavo Padovan 	skb->data_len = 0;
2730087bfd99SGustavo Padovan 
2731087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2732204a6e54SAndrei Emeltchenko 
2733204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
2734204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
2735087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
2736204a6e54SAndrei Emeltchenko 		break;
2737204a6e54SAndrei Emeltchenko 	case HCI_AMP:
2738204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
2739204a6e54SAndrei Emeltchenko 		break;
2740204a6e54SAndrei Emeltchenko 	default:
2741204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2742204a6e54SAndrei Emeltchenko 		return;
2743204a6e54SAndrei Emeltchenko 	}
2744087bfd99SGustavo Padovan 
274570f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
274670f23020SAndrei Emeltchenko 	if (!list) {
27471da177e4SLinus Torvalds 		/* Non fragmented */
27481da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
27491da177e4SLinus Torvalds 
275073d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
27511da177e4SLinus Torvalds 	} else {
27521da177e4SLinus Torvalds 		/* Fragmented */
27531da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
27541da177e4SLinus Torvalds 
27551da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
27561da177e4SLinus Torvalds 
27571da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2758af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
27591da177e4SLinus Torvalds 
276073d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2761e702112fSAndrei Emeltchenko 
2762e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2763e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
27641da177e4SLinus Torvalds 		do {
27651da177e4SLinus Torvalds 			skb = list; list = list->next;
27661da177e4SLinus Torvalds 
27671da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
27680d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2769e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
27701da177e4SLinus Torvalds 
27711da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
27721da177e4SLinus Torvalds 
277373d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
27741da177e4SLinus Torvalds 		} while (list);
27751da177e4SLinus Torvalds 
2776af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
27771da177e4SLinus Torvalds 	}
277873d80debSLuiz Augusto von Dentz }
277973d80debSLuiz Augusto von Dentz 
278073d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
278173d80debSLuiz Augusto von Dentz {
2782ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
278373d80debSLuiz Augusto von Dentz 
2784f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
278573d80debSLuiz Augusto von Dentz 
278673d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
278773d80debSLuiz Augusto von Dentz 
2788ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
27891da177e4SLinus Torvalds 
27903eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
27911da177e4SLinus Torvalds }
27921da177e4SLinus Torvalds 
27931da177e4SLinus Torvalds /* Send SCO data */
27940d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
27951da177e4SLinus Torvalds {
27961da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
27971da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
27981da177e4SLinus Torvalds 
27991da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
28001da177e4SLinus Torvalds 
2801aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
28021da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
28031da177e4SLinus Torvalds 
2804badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2805badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
28069c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
28071da177e4SLinus Torvalds 
28081da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
28090d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2810c78ae283SMarcel Holtmann 
28111da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
28123eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
28131da177e4SLinus Torvalds }
28141da177e4SLinus Torvalds 
28151da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
28161da177e4SLinus Torvalds 
28171da177e4SLinus Torvalds /* HCI Connection scheduler */
28186039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
2819a8c5fb1aSGustavo Padovan 				     int *quote)
28201da177e4SLinus Torvalds {
28211da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
28228035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
2823abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
28241da177e4SLinus Torvalds 
28251da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
28261da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2827bf4c6325SGustavo F. Padovan 
2828bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2829bf4c6325SGustavo F. Padovan 
2830bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2831769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
28321da177e4SLinus Torvalds 			continue;
2833769be974SMarcel Holtmann 
2834769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2835769be974SMarcel Holtmann 			continue;
2836769be974SMarcel Holtmann 
28371da177e4SLinus Torvalds 		num++;
28381da177e4SLinus Torvalds 
28391da177e4SLinus Torvalds 		if (c->sent < min) {
28401da177e4SLinus Torvalds 			min  = c->sent;
28411da177e4SLinus Torvalds 			conn = c;
28421da177e4SLinus Torvalds 		}
284352087a79SLuiz Augusto von Dentz 
284452087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
284552087a79SLuiz Augusto von Dentz 			break;
28461da177e4SLinus Torvalds 	}
28471da177e4SLinus Torvalds 
2848bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2849bf4c6325SGustavo F. Padovan 
28501da177e4SLinus Torvalds 	if (conn) {
28516ed58ec5SVille Tervo 		int cnt, q;
28526ed58ec5SVille Tervo 
28536ed58ec5SVille Tervo 		switch (conn->type) {
28546ed58ec5SVille Tervo 		case ACL_LINK:
28556ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
28566ed58ec5SVille Tervo 			break;
28576ed58ec5SVille Tervo 		case SCO_LINK:
28586ed58ec5SVille Tervo 		case ESCO_LINK:
28596ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
28606ed58ec5SVille Tervo 			break;
28616ed58ec5SVille Tervo 		case LE_LINK:
28626ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
28636ed58ec5SVille Tervo 			break;
28646ed58ec5SVille Tervo 		default:
28656ed58ec5SVille Tervo 			cnt = 0;
28666ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
28676ed58ec5SVille Tervo 		}
28686ed58ec5SVille Tervo 
28696ed58ec5SVille Tervo 		q = cnt / num;
28701da177e4SLinus Torvalds 		*quote = q ? q : 1;
28711da177e4SLinus Torvalds 	} else
28721da177e4SLinus Torvalds 		*quote = 0;
28731da177e4SLinus Torvalds 
28741da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
28751da177e4SLinus Torvalds 	return conn;
28761da177e4SLinus Torvalds }
28771da177e4SLinus Torvalds 
28786039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
28791da177e4SLinus Torvalds {
28801da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
28811da177e4SLinus Torvalds 	struct hci_conn *c;
28821da177e4SLinus Torvalds 
2883bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
28841da177e4SLinus Torvalds 
2885bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2886bf4c6325SGustavo F. Padovan 
28871da177e4SLinus Torvalds 	/* Kill stalled connections */
2888bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2889bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
28906ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
28916ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
2892bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
28931da177e4SLinus Torvalds 		}
28941da177e4SLinus Torvalds 	}
2895bf4c6325SGustavo F. Padovan 
2896bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
28971da177e4SLinus Torvalds }
28981da177e4SLinus Torvalds 
28996039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
290073d80debSLuiz Augusto von Dentz 				      int *quote)
290173d80debSLuiz Augusto von Dentz {
290273d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
290373d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
2904abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
290573d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
290673d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
290773d80debSLuiz Augusto von Dentz 
290873d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
290973d80debSLuiz Augusto von Dentz 
2910bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2911bf4c6325SGustavo F. Padovan 
2912bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
291373d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
291473d80debSLuiz Augusto von Dentz 
291573d80debSLuiz Augusto von Dentz 		if (conn->type != type)
291673d80debSLuiz Augusto von Dentz 			continue;
291773d80debSLuiz Augusto von Dentz 
291873d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
291973d80debSLuiz Augusto von Dentz 			continue;
292073d80debSLuiz Augusto von Dentz 
292173d80debSLuiz Augusto von Dentz 		conn_num++;
292273d80debSLuiz Augusto von Dentz 
29238192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
292473d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
292573d80debSLuiz Augusto von Dentz 
292673d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
292773d80debSLuiz Augusto von Dentz 				continue;
292873d80debSLuiz Augusto von Dentz 
292973d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
293073d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
293173d80debSLuiz Augusto von Dentz 				continue;
293273d80debSLuiz Augusto von Dentz 
293373d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
293473d80debSLuiz Augusto von Dentz 				num = 0;
293573d80debSLuiz Augusto von Dentz 				min = ~0;
293673d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
293773d80debSLuiz Augusto von Dentz 			}
293873d80debSLuiz Augusto von Dentz 
293973d80debSLuiz Augusto von Dentz 			num++;
294073d80debSLuiz Augusto von Dentz 
294173d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
294273d80debSLuiz Augusto von Dentz 				min  = conn->sent;
294373d80debSLuiz Augusto von Dentz 				chan = tmp;
294473d80debSLuiz Augusto von Dentz 			}
294573d80debSLuiz Augusto von Dentz 		}
294673d80debSLuiz Augusto von Dentz 
294773d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
294873d80debSLuiz Augusto von Dentz 			break;
294973d80debSLuiz Augusto von Dentz 	}
295073d80debSLuiz Augusto von Dentz 
2951bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2952bf4c6325SGustavo F. Padovan 
295373d80debSLuiz Augusto von Dentz 	if (!chan)
295473d80debSLuiz Augusto von Dentz 		return NULL;
295573d80debSLuiz Augusto von Dentz 
295673d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
295773d80debSLuiz Augusto von Dentz 	case ACL_LINK:
295873d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
295973d80debSLuiz Augusto von Dentz 		break;
2960bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
2961bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
2962bd1eb66bSAndrei Emeltchenko 		break;
296373d80debSLuiz Augusto von Dentz 	case SCO_LINK:
296473d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
296573d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
296673d80debSLuiz Augusto von Dentz 		break;
296773d80debSLuiz Augusto von Dentz 	case LE_LINK:
296873d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
296973d80debSLuiz Augusto von Dentz 		break;
297073d80debSLuiz Augusto von Dentz 	default:
297173d80debSLuiz Augusto von Dentz 		cnt = 0;
297273d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
297373d80debSLuiz Augusto von Dentz 	}
297473d80debSLuiz Augusto von Dentz 
297573d80debSLuiz Augusto von Dentz 	q = cnt / num;
297673d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
297773d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
297873d80debSLuiz Augusto von Dentz 	return chan;
297973d80debSLuiz Augusto von Dentz }
298073d80debSLuiz Augusto von Dentz 
298102b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
298202b20f0bSLuiz Augusto von Dentz {
298302b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
298402b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
298502b20f0bSLuiz Augusto von Dentz 	int num = 0;
298602b20f0bSLuiz Augusto von Dentz 
298702b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
298802b20f0bSLuiz Augusto von Dentz 
2989bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2990bf4c6325SGustavo F. Padovan 
2991bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
299202b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
299302b20f0bSLuiz Augusto von Dentz 
299402b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
299502b20f0bSLuiz Augusto von Dentz 			continue;
299602b20f0bSLuiz Augusto von Dentz 
299702b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
299802b20f0bSLuiz Augusto von Dentz 			continue;
299902b20f0bSLuiz Augusto von Dentz 
300002b20f0bSLuiz Augusto von Dentz 		num++;
300102b20f0bSLuiz Augusto von Dentz 
30028192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
300302b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
300402b20f0bSLuiz Augusto von Dentz 
300502b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
300602b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
300702b20f0bSLuiz Augusto von Dentz 				continue;
300802b20f0bSLuiz Augusto von Dentz 			}
300902b20f0bSLuiz Augusto von Dentz 
301002b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
301102b20f0bSLuiz Augusto von Dentz 				continue;
301202b20f0bSLuiz Augusto von Dentz 
301302b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
301402b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
301502b20f0bSLuiz Augusto von Dentz 				continue;
301602b20f0bSLuiz Augusto von Dentz 
301702b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
301802b20f0bSLuiz Augusto von Dentz 
301902b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
302002b20f0bSLuiz Augusto von Dentz 			       skb->priority);
302102b20f0bSLuiz Augusto von Dentz 		}
302202b20f0bSLuiz Augusto von Dentz 
302302b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
302402b20f0bSLuiz Augusto von Dentz 			break;
302502b20f0bSLuiz Augusto von Dentz 	}
3026bf4c6325SGustavo F. Padovan 
3027bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3028bf4c6325SGustavo F. Padovan 
302902b20f0bSLuiz Augusto von Dentz }
303002b20f0bSLuiz Augusto von Dentz 
3031b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3032b71d385aSAndrei Emeltchenko {
3033b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3034b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3035b71d385aSAndrei Emeltchenko }
3036b71d385aSAndrei Emeltchenko 
30376039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
30381da177e4SLinus Torvalds {
30391da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
30401da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
30411da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
304263d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
30435f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
3044bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
30451da177e4SLinus Torvalds 	}
304663d2bc1bSAndrei Emeltchenko }
30471da177e4SLinus Torvalds 
30486039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
304963d2bc1bSAndrei Emeltchenko {
305063d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
305163d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
305263d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
305363d2bc1bSAndrei Emeltchenko 	int quote;
305463d2bc1bSAndrei Emeltchenko 
305563d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
305604837f64SMarcel Holtmann 
305773d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
305873d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3059ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3060ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
306173d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
306273d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
306373d80debSLuiz Augusto von Dentz 
3064ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3065ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3066ec1cce24SLuiz Augusto von Dentz 				break;
3067ec1cce24SLuiz Augusto von Dentz 
3068ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3069ec1cce24SLuiz Augusto von Dentz 
307073d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
307173d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
307204837f64SMarcel Holtmann 
30731da177e4SLinus Torvalds 			hci_send_frame(skb);
30741da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
30751da177e4SLinus Torvalds 
30761da177e4SLinus Torvalds 			hdev->acl_cnt--;
307773d80debSLuiz Augusto von Dentz 			chan->sent++;
307873d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
30791da177e4SLinus Torvalds 		}
30801da177e4SLinus Torvalds 	}
308102b20f0bSLuiz Augusto von Dentz 
308202b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
308302b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
30841da177e4SLinus Torvalds }
30851da177e4SLinus Torvalds 
30866039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3087b71d385aSAndrei Emeltchenko {
308863d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3089b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3090b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3091b71d385aSAndrei Emeltchenko 	int quote;
3092bd1eb66bSAndrei Emeltchenko 	u8 type;
3093b71d385aSAndrei Emeltchenko 
309463d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
3095b71d385aSAndrei Emeltchenko 
3096bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3097bd1eb66bSAndrei Emeltchenko 
3098bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3099bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3100bd1eb66bSAndrei Emeltchenko 	else
3101bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3102bd1eb66bSAndrei Emeltchenko 
3103b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3104bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3105b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3106b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3107b71d385aSAndrei Emeltchenko 			int blocks;
3108b71d385aSAndrei Emeltchenko 
3109b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3110b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3111b71d385aSAndrei Emeltchenko 
3112b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3113b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3114b71d385aSAndrei Emeltchenko 				break;
3115b71d385aSAndrei Emeltchenko 
3116b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3117b71d385aSAndrei Emeltchenko 
3118b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3119b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3120b71d385aSAndrei Emeltchenko 				return;
3121b71d385aSAndrei Emeltchenko 
3122b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3123b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3124b71d385aSAndrei Emeltchenko 
3125b71d385aSAndrei Emeltchenko 			hci_send_frame(skb);
3126b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3127b71d385aSAndrei Emeltchenko 
3128b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3129b71d385aSAndrei Emeltchenko 			quote -= blocks;
3130b71d385aSAndrei Emeltchenko 
3131b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3132b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3133b71d385aSAndrei Emeltchenko 		}
3134b71d385aSAndrei Emeltchenko 	}
3135b71d385aSAndrei Emeltchenko 
3136b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3137bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3138b71d385aSAndrei Emeltchenko }
3139b71d385aSAndrei Emeltchenko 
31406039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3141b71d385aSAndrei Emeltchenko {
3142b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3143b71d385aSAndrei Emeltchenko 
3144bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3145bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
3146bd1eb66bSAndrei Emeltchenko 		return;
3147bd1eb66bSAndrei Emeltchenko 
3148bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3149bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3150b71d385aSAndrei Emeltchenko 		return;
3151b71d385aSAndrei Emeltchenko 
3152b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3153b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3154b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3155b71d385aSAndrei Emeltchenko 		break;
3156b71d385aSAndrei Emeltchenko 
3157b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3158b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3159b71d385aSAndrei Emeltchenko 		break;
3160b71d385aSAndrei Emeltchenko 	}
3161b71d385aSAndrei Emeltchenko }
3162b71d385aSAndrei Emeltchenko 
31631da177e4SLinus Torvalds /* Schedule SCO */
31646039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
31651da177e4SLinus Torvalds {
31661da177e4SLinus Torvalds 	struct hci_conn *conn;
31671da177e4SLinus Torvalds 	struct sk_buff *skb;
31681da177e4SLinus Torvalds 	int quote;
31691da177e4SLinus Torvalds 
31701da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
31711da177e4SLinus Torvalds 
317252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
317352087a79SLuiz Augusto von Dentz 		return;
317452087a79SLuiz Augusto von Dentz 
31751da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
31761da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
31771da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
31781da177e4SLinus Torvalds 			hci_send_frame(skb);
31791da177e4SLinus Torvalds 
31801da177e4SLinus Torvalds 			conn->sent++;
31811da177e4SLinus Torvalds 			if (conn->sent == ~0)
31821da177e4SLinus Torvalds 				conn->sent = 0;
31831da177e4SLinus Torvalds 		}
31841da177e4SLinus Torvalds 	}
31851da177e4SLinus Torvalds }
31861da177e4SLinus Torvalds 
31876039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
3188b6a0dc82SMarcel Holtmann {
3189b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
3190b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
3191b6a0dc82SMarcel Holtmann 	int quote;
3192b6a0dc82SMarcel Holtmann 
3193b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
3194b6a0dc82SMarcel Holtmann 
319552087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
319652087a79SLuiz Augusto von Dentz 		return;
319752087a79SLuiz Augusto von Dentz 
31988fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
31998fc9ced3SGustavo Padovan 						     &quote))) {
3200b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
3201b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
3202b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
3203b6a0dc82SMarcel Holtmann 
3204b6a0dc82SMarcel Holtmann 			conn->sent++;
3205b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
3206b6a0dc82SMarcel Holtmann 				conn->sent = 0;
3207b6a0dc82SMarcel Holtmann 		}
3208b6a0dc82SMarcel Holtmann 	}
3209b6a0dc82SMarcel Holtmann }
3210b6a0dc82SMarcel Holtmann 
32116039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
32126ed58ec5SVille Tervo {
321373d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
32146ed58ec5SVille Tervo 	struct sk_buff *skb;
321502b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
32166ed58ec5SVille Tervo 
32176ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
32186ed58ec5SVille Tervo 
321952087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
322052087a79SLuiz Augusto von Dentz 		return;
322152087a79SLuiz Augusto von Dentz 
32226ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
32236ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
32246ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
3225bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
32266ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
3227bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
32286ed58ec5SVille Tervo 	}
32296ed58ec5SVille Tervo 
32306ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
323102b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
323273d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3233ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3234ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
323573d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
323673d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
32376ed58ec5SVille Tervo 
3238ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3239ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3240ec1cce24SLuiz Augusto von Dentz 				break;
3241ec1cce24SLuiz Augusto von Dentz 
3242ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3243ec1cce24SLuiz Augusto von Dentz 
32446ed58ec5SVille Tervo 			hci_send_frame(skb);
32456ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
32466ed58ec5SVille Tervo 
32476ed58ec5SVille Tervo 			cnt--;
324873d80debSLuiz Augusto von Dentz 			chan->sent++;
324973d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
32506ed58ec5SVille Tervo 		}
32516ed58ec5SVille Tervo 	}
325273d80debSLuiz Augusto von Dentz 
32536ed58ec5SVille Tervo 	if (hdev->le_pkts)
32546ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
32556ed58ec5SVille Tervo 	else
32566ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
325702b20f0bSLuiz Augusto von Dentz 
325802b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
325902b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
32606ed58ec5SVille Tervo }
32616ed58ec5SVille Tervo 
32623eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
32631da177e4SLinus Torvalds {
32643eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
32651da177e4SLinus Torvalds 	struct sk_buff *skb;
32661da177e4SLinus Torvalds 
32676ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
32686ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
32691da177e4SLinus Torvalds 
32701da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
32711da177e4SLinus Torvalds 
32721da177e4SLinus Torvalds 	hci_sched_acl(hdev);
32731da177e4SLinus Torvalds 
32741da177e4SLinus Torvalds 	hci_sched_sco(hdev);
32751da177e4SLinus Torvalds 
3276b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
3277b6a0dc82SMarcel Holtmann 
32786ed58ec5SVille Tervo 	hci_sched_le(hdev);
32796ed58ec5SVille Tervo 
32801da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
32811da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
32821da177e4SLinus Torvalds 		hci_send_frame(skb);
32831da177e4SLinus Torvalds }
32841da177e4SLinus Torvalds 
328525985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
32861da177e4SLinus Torvalds 
32871da177e4SLinus Torvalds /* ACL data packet */
32886039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
32891da177e4SLinus Torvalds {
32901da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
32911da177e4SLinus Torvalds 	struct hci_conn *conn;
32921da177e4SLinus Torvalds 	__u16 handle, flags;
32931da177e4SLinus Torvalds 
32941da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
32951da177e4SLinus Torvalds 
32961da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
32971da177e4SLinus Torvalds 	flags  = hci_flags(handle);
32981da177e4SLinus Torvalds 	handle = hci_handle(handle);
32991da177e4SLinus Torvalds 
3300f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3301a8c5fb1aSGustavo Padovan 	       handle, flags);
33021da177e4SLinus Torvalds 
33031da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
33041da177e4SLinus Torvalds 
33051da177e4SLinus Torvalds 	hci_dev_lock(hdev);
33061da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
33071da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
33081da177e4SLinus Torvalds 
33091da177e4SLinus Torvalds 	if (conn) {
331065983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
331104837f64SMarcel Holtmann 
33121da177e4SLinus Torvalds 		/* Send to upper protocol */
3313686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
33141da177e4SLinus Torvalds 		return;
33151da177e4SLinus Torvalds 	} else {
33161da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
33171da177e4SLinus Torvalds 		       hdev->name, handle);
33181da177e4SLinus Torvalds 	}
33191da177e4SLinus Torvalds 
33201da177e4SLinus Torvalds 	kfree_skb(skb);
33211da177e4SLinus Torvalds }
33221da177e4SLinus Torvalds 
33231da177e4SLinus Torvalds /* SCO data packet */
33246039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
33251da177e4SLinus Torvalds {
33261da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
33271da177e4SLinus Torvalds 	struct hci_conn *conn;
33281da177e4SLinus Torvalds 	__u16 handle;
33291da177e4SLinus Torvalds 
33301da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
33311da177e4SLinus Torvalds 
33321da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
33331da177e4SLinus Torvalds 
3334f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
33351da177e4SLinus Torvalds 
33361da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
33371da177e4SLinus Torvalds 
33381da177e4SLinus Torvalds 	hci_dev_lock(hdev);
33391da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
33401da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
33411da177e4SLinus Torvalds 
33421da177e4SLinus Torvalds 	if (conn) {
33431da177e4SLinus Torvalds 		/* Send to upper protocol */
3344686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
33451da177e4SLinus Torvalds 		return;
33461da177e4SLinus Torvalds 	} else {
33471da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
33481da177e4SLinus Torvalds 		       hdev->name, handle);
33491da177e4SLinus Torvalds 	}
33501da177e4SLinus Torvalds 
33511da177e4SLinus Torvalds 	kfree_skb(skb);
33521da177e4SLinus Torvalds }
33531da177e4SLinus Torvalds 
33549238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
33559238f36aSJohan Hedberg {
33569238f36aSJohan Hedberg 	struct sk_buff *skb;
33579238f36aSJohan Hedberg 
33589238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
33599238f36aSJohan Hedberg 	if (!skb)
33609238f36aSJohan Hedberg 		return true;
33619238f36aSJohan Hedberg 
33629238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
33639238f36aSJohan Hedberg }
33649238f36aSJohan Hedberg 
336542c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
336642c6b129SJohan Hedberg {
336742c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
336842c6b129SJohan Hedberg 	struct sk_buff *skb;
336942c6b129SJohan Hedberg 	u16 opcode;
337042c6b129SJohan Hedberg 
337142c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
337242c6b129SJohan Hedberg 		return;
337342c6b129SJohan Hedberg 
337442c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
337542c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
337642c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
337742c6b129SJohan Hedberg 		return;
337842c6b129SJohan Hedberg 
337942c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
338042c6b129SJohan Hedberg 	if (!skb)
338142c6b129SJohan Hedberg 		return;
338242c6b129SJohan Hedberg 
338342c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
338442c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
338542c6b129SJohan Hedberg }
338642c6b129SJohan Hedberg 
33879238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
33889238f36aSJohan Hedberg {
33899238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
33909238f36aSJohan Hedberg 	struct sk_buff *skb;
33919238f36aSJohan Hedberg 	unsigned long flags;
33929238f36aSJohan Hedberg 
33939238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
33949238f36aSJohan Hedberg 
339542c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
339642c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
33979238f36aSJohan Hedberg 	 */
339842c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
339942c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
340042c6b129SJohan Hedberg 		 * reset complete event during init and any pending
340142c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
340242c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
340342c6b129SJohan Hedberg 		 * command.
340442c6b129SJohan Hedberg 		 */
340542c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
340642c6b129SJohan Hedberg 			hci_resend_last(hdev);
340742c6b129SJohan Hedberg 
34089238f36aSJohan Hedberg 		return;
340942c6b129SJohan Hedberg 	}
34109238f36aSJohan Hedberg 
34119238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
34129238f36aSJohan Hedberg 	 * this request the request is not yet complete.
34139238f36aSJohan Hedberg 	 */
34149238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
34159238f36aSJohan Hedberg 		return;
34169238f36aSJohan Hedberg 
34179238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
34189238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
34199238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
34209238f36aSJohan Hedberg 	 */
34219238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
34229238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
34239238f36aSJohan Hedberg 		if (req_complete)
34249238f36aSJohan Hedberg 			goto call_complete;
34259238f36aSJohan Hedberg 	}
34269238f36aSJohan Hedberg 
34279238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
34289238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
34299238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
34309238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
34319238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
34329238f36aSJohan Hedberg 			break;
34339238f36aSJohan Hedberg 		}
34349238f36aSJohan Hedberg 
34359238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
34369238f36aSJohan Hedberg 		kfree_skb(skb);
34379238f36aSJohan Hedberg 	}
34389238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
34399238f36aSJohan Hedberg 
34409238f36aSJohan Hedberg call_complete:
34419238f36aSJohan Hedberg 	if (req_complete)
34429238f36aSJohan Hedberg 		req_complete(hdev, status);
34439238f36aSJohan Hedberg }
34449238f36aSJohan Hedberg 
3445b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
34461da177e4SLinus Torvalds {
3447b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
34481da177e4SLinus Torvalds 	struct sk_buff *skb;
34491da177e4SLinus Torvalds 
34501da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
34511da177e4SLinus Torvalds 
34521da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
3453cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
3454cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
3455cd82e61cSMarcel Holtmann 
34561da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
34571da177e4SLinus Torvalds 			/* Send copy to the sockets */
3458470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
34591da177e4SLinus Torvalds 		}
34601da177e4SLinus Torvalds 
34611da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
34621da177e4SLinus Torvalds 			kfree_skb(skb);
34631da177e4SLinus Torvalds 			continue;
34641da177e4SLinus Torvalds 		}
34651da177e4SLinus Torvalds 
34661da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
34671da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
34680d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
34691da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
34701da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
34711da177e4SLinus Torvalds 				kfree_skb(skb);
34721da177e4SLinus Torvalds 				continue;
34733ff50b79SStephen Hemminger 			}
34741da177e4SLinus Torvalds 		}
34751da177e4SLinus Torvalds 
34761da177e4SLinus Torvalds 		/* Process frame */
34770d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
34781da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
3479b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
34801da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
34811da177e4SLinus Torvalds 			break;
34821da177e4SLinus Torvalds 
34831da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
34841da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
34851da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
34861da177e4SLinus Torvalds 			break;
34871da177e4SLinus Torvalds 
34881da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
34891da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
34901da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
34911da177e4SLinus Torvalds 			break;
34921da177e4SLinus Torvalds 
34931da177e4SLinus Torvalds 		default:
34941da177e4SLinus Torvalds 			kfree_skb(skb);
34951da177e4SLinus Torvalds 			break;
34961da177e4SLinus Torvalds 		}
34971da177e4SLinus Torvalds 	}
34981da177e4SLinus Torvalds }
34991da177e4SLinus Torvalds 
3500c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
35011da177e4SLinus Torvalds {
3502c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
35031da177e4SLinus Torvalds 	struct sk_buff *skb;
35041da177e4SLinus Torvalds 
35052104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
35062104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
35071da177e4SLinus Torvalds 
35081da177e4SLinus Torvalds 	/* Send queued commands */
35095a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
35105a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
35115a08ecceSAndrei Emeltchenko 		if (!skb)
35125a08ecceSAndrei Emeltchenko 			return;
35135a08ecceSAndrei Emeltchenko 
35141da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
35151da177e4SLinus Torvalds 
351670f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
351770f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
35181da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
35191da177e4SLinus Torvalds 			hci_send_frame(skb);
35207bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
35217bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
35227bdb8a5cSSzymon Janc 			else
35236bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
35245f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
35251da177e4SLinus Torvalds 		} else {
35261da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
3527c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
35281da177e4SLinus Torvalds 		}
35291da177e4SLinus Torvalds 	}
35301da177e4SLinus Torvalds }
35312519a1fcSAndre Guedes 
35322519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
35332519a1fcSAndre Guedes {
35342519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
35352519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
35362519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
35372519a1fcSAndre Guedes 
35382519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
35392519a1fcSAndre Guedes 
35402519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
35412519a1fcSAndre Guedes 		return -EINPROGRESS;
35422519a1fcSAndre Guedes 
35434663262cSJohan Hedberg 	inquiry_cache_flush(hdev);
35444663262cSJohan Hedberg 
35452519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
35462519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
35472519a1fcSAndre Guedes 	cp.length  = length;
35482519a1fcSAndre Guedes 
35492519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
35502519a1fcSAndre Guedes }
3551023d5049SAndre Guedes 
3552023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
3553023d5049SAndre Guedes {
3554023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
3555023d5049SAndre Guedes 
3556023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
35577537e5c3SAndre Guedes 		return -EALREADY;
3558023d5049SAndre Guedes 
3559023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
3560023d5049SAndre Guedes }
356131f7956cSAndre Guedes 
356231f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type)
356331f7956cSAndre Guedes {
356431f7956cSAndre Guedes 	switch (bdaddr_type) {
356531f7956cSAndre Guedes 	case BDADDR_LE_PUBLIC:
356631f7956cSAndre Guedes 		return ADDR_LE_DEV_PUBLIC;
356731f7956cSAndre Guedes 
356831f7956cSAndre Guedes 	default:
356931f7956cSAndre Guedes 		/* Fallback to LE Random address type */
357031f7956cSAndre Guedes 		return ADDR_LE_DEV_RANDOM;
357131f7956cSAndre Guedes 	}
357231f7956cSAndre Guedes }
3573