xref: /openbmc/linux/net/bluetooth/hci_core.c (revision f41c70c4)
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;
31942c6b129SJohan Hedberg 	struct hci_request init_req;
320e61ef499SAndrei Emeltchenko 	struct sk_buff *skb;
321e61ef499SAndrei Emeltchenko 
322e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
323e61ef499SAndrei Emeltchenko 
324e61ef499SAndrei Emeltchenko 	/* Driver initialization */
325e61ef499SAndrei Emeltchenko 
32642c6b129SJohan Hedberg 	hci_req_init(&init_req, hdev);
32742c6b129SJohan Hedberg 
328e61ef499SAndrei Emeltchenko 	/* Special commands */
329e61ef499SAndrei Emeltchenko 	while ((skb = skb_dequeue(&hdev->driver_init))) {
330e61ef499SAndrei Emeltchenko 		bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
331e61ef499SAndrei Emeltchenko 		skb->dev = (void *) hdev;
332e61ef499SAndrei Emeltchenko 
33342c6b129SJohan Hedberg 		if (skb_queue_empty(&init_req.cmd_q))
33442c6b129SJohan Hedberg 			bt_cb(skb)->req.start = true;
33542c6b129SJohan Hedberg 
33642c6b129SJohan Hedberg 		skb_queue_tail(&init_req.cmd_q, skb);
337e61ef499SAndrei Emeltchenko 	}
338e61ef499SAndrei Emeltchenko 	skb_queue_purge(&hdev->driver_init);
339e61ef499SAndrei Emeltchenko 
34042c6b129SJohan Hedberg 	hci_req_run(&init_req, NULL);
34142c6b129SJohan Hedberg 
34211778716SAndrei Emeltchenko 	/* Reset */
34311778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
34442c6b129SJohan Hedberg 		hci_reset_req(req, 0);
34511778716SAndrei Emeltchenko 
346e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
347e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
34842c6b129SJohan Hedberg 		bredr_init(req);
349e61ef499SAndrei Emeltchenko 		break;
350e61ef499SAndrei Emeltchenko 
351e61ef499SAndrei Emeltchenko 	case HCI_AMP:
35242c6b129SJohan Hedberg 		amp_init(req);
353e61ef499SAndrei Emeltchenko 		break;
354e61ef499SAndrei Emeltchenko 
355e61ef499SAndrei Emeltchenko 	default:
356e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
357e61ef499SAndrei Emeltchenko 		break;
358e61ef499SAndrei Emeltchenko 	}
359e61ef499SAndrei Emeltchenko }
360e61ef499SAndrei Emeltchenko 
36142c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
3622177bab5SJohan Hedberg {
3632177bab5SJohan Hedberg 	struct hci_cp_delete_stored_link_key cp;
3642177bab5SJohan Hedberg 	__le16 param;
3652177bab5SJohan Hedberg 	__u8 flt_type;
3662177bab5SJohan Hedberg 
3672177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
36842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
3692177bab5SJohan Hedberg 
3702177bab5SJohan Hedberg 	/* Read Class of Device */
37142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
3722177bab5SJohan Hedberg 
3732177bab5SJohan Hedberg 	/* Read Local Name */
37442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
3752177bab5SJohan Hedberg 
3762177bab5SJohan Hedberg 	/* Read Voice Setting */
37742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
3782177bab5SJohan Hedberg 
3792177bab5SJohan Hedberg 	/* Clear Event Filters */
3802177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
38142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
3822177bab5SJohan Hedberg 
3832177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
3842177bab5SJohan Hedberg 	param = __constant_cpu_to_le16(0x7d00);
38542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
3862177bab5SJohan Hedberg 
3872177bab5SJohan Hedberg 	bacpy(&cp.bdaddr, BDADDR_ANY);
3882177bab5SJohan Hedberg 	cp.delete_all = 0x01;
38942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
390f332ec66SJohan Hedberg 
391f332ec66SJohan Hedberg 	/* Read page scan parameters */
392f332ec66SJohan Hedberg 	if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) {
393f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
394f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
395f332ec66SJohan Hedberg 	}
3962177bab5SJohan Hedberg }
3972177bab5SJohan Hedberg 
39842c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
3992177bab5SJohan Hedberg {
4002177bab5SJohan Hedberg 	/* Read LE Buffer Size */
40142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
4022177bab5SJohan Hedberg 
4032177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
40442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
4052177bab5SJohan Hedberg 
4062177bab5SJohan Hedberg 	/* Read LE Advertising Channel TX Power */
40742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
4082177bab5SJohan Hedberg 
4092177bab5SJohan Hedberg 	/* Read LE White List Size */
41042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
4112177bab5SJohan Hedberg 
4122177bab5SJohan Hedberg 	/* Read LE Supported States */
41342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
4142177bab5SJohan Hedberg }
4152177bab5SJohan Hedberg 
4162177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
4172177bab5SJohan Hedberg {
4182177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
4192177bab5SJohan Hedberg 		return 0x02;
4202177bab5SJohan Hedberg 
4212177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4222177bab5SJohan Hedberg 		return 0x01;
4232177bab5SJohan Hedberg 
4242177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
4252177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
4262177bab5SJohan Hedberg 		return 0x01;
4272177bab5SJohan Hedberg 
4282177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
4292177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
4302177bab5SJohan Hedberg 			return 0x01;
4312177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
4322177bab5SJohan Hedberg 			return 0x01;
4332177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
4342177bab5SJohan Hedberg 			return 0x01;
4352177bab5SJohan Hedberg 	}
4362177bab5SJohan Hedberg 
4372177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
4382177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
4392177bab5SJohan Hedberg 		return 0x01;
4402177bab5SJohan Hedberg 
4412177bab5SJohan Hedberg 	return 0x00;
4422177bab5SJohan Hedberg }
4432177bab5SJohan Hedberg 
44442c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
4452177bab5SJohan Hedberg {
4462177bab5SJohan Hedberg 	u8 mode;
4472177bab5SJohan Hedberg 
44842c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
4492177bab5SJohan Hedberg 
45042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
4512177bab5SJohan Hedberg }
4522177bab5SJohan Hedberg 
45342c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
4542177bab5SJohan Hedberg {
45542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
45642c6b129SJohan Hedberg 
4572177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
4582177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
4592177bab5SJohan Hedberg 	 * command otherwise.
4602177bab5SJohan Hedberg 	 */
4612177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
4622177bab5SJohan Hedberg 
4632177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
4642177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
4652177bab5SJohan Hedberg 	 */
4662177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
4672177bab5SJohan Hedberg 		return;
4682177bab5SJohan Hedberg 
4692177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
4702177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
4712177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4722177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
4732177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
4742177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
4752177bab5SJohan Hedberg 	}
4762177bab5SJohan Hedberg 
4772177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4782177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4792177bab5SJohan Hedberg 
4802177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
4812177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
4822177bab5SJohan Hedberg 
4832177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
4842177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
4852177bab5SJohan Hedberg 
4862177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
4872177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
4882177bab5SJohan Hedberg 
4892177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
4902177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
4912177bab5SJohan Hedberg 
4922177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
4932177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
4942177bab5SJohan Hedberg 
4952177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
4962177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
4972177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
4982177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
4992177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
5002177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
5012177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
5022177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
5032177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
5042177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
5052177bab5SJohan Hedberg 					 * Features Notification
5062177bab5SJohan Hedberg 					 */
5072177bab5SJohan Hedberg 	}
5082177bab5SJohan Hedberg 
5092177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
5102177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
5112177bab5SJohan Hedberg 
51242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
5132177bab5SJohan Hedberg 
5142177bab5SJohan Hedberg 	if (lmp_le_capable(hdev)) {
5152177bab5SJohan Hedberg 		memset(events, 0, sizeof(events));
5162177bab5SJohan Hedberg 		events[0] = 0x1f;
51742c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
5182177bab5SJohan Hedberg 			    sizeof(events), events);
5192177bab5SJohan Hedberg 	}
5202177bab5SJohan Hedberg }
5212177bab5SJohan Hedberg 
52242c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
5232177bab5SJohan Hedberg {
52442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
52542c6b129SJohan Hedberg 
5262177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
52742c6b129SJohan Hedberg 		bredr_setup(req);
5282177bab5SJohan Hedberg 
5292177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
53042c6b129SJohan Hedberg 		le_setup(req);
5312177bab5SJohan Hedberg 
53242c6b129SJohan Hedberg 	hci_setup_event_mask(req);
5332177bab5SJohan Hedberg 
5342177bab5SJohan Hedberg 	if (hdev->hci_ver > BLUETOOTH_VER_1_1)
53542c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
5362177bab5SJohan Hedberg 
5372177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5382177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
5392177bab5SJohan Hedberg 			u8 mode = 0x01;
54042c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
5412177bab5SJohan Hedberg 				    sizeof(mode), &mode);
5422177bab5SJohan Hedberg 		} else {
5432177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
5442177bab5SJohan Hedberg 
5452177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
5462177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
5472177bab5SJohan Hedberg 
54842c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
5492177bab5SJohan Hedberg 		}
5502177bab5SJohan Hedberg 	}
5512177bab5SJohan Hedberg 
5522177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
55342c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
5542177bab5SJohan Hedberg 
5552177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
55642c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
5572177bab5SJohan Hedberg 
5582177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
5592177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
5602177bab5SJohan Hedberg 
5612177bab5SJohan Hedberg 		cp.page = 0x01;
56242c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
56342c6b129SJohan Hedberg 			    sizeof(cp), &cp);
5642177bab5SJohan Hedberg 	}
5652177bab5SJohan Hedberg 
5662177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
5672177bab5SJohan Hedberg 		u8 enable = 1;
56842c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
5692177bab5SJohan Hedberg 			    &enable);
5702177bab5SJohan Hedberg 	}
5712177bab5SJohan Hedberg }
5722177bab5SJohan Hedberg 
57342c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
5742177bab5SJohan Hedberg {
57542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5762177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
5772177bab5SJohan Hedberg 	u16 link_policy = 0;
5782177bab5SJohan Hedberg 
5792177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
5802177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
5812177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
5822177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
5832177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
5842177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
5852177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
5862177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
5872177bab5SJohan Hedberg 
5882177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
58942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
5902177bab5SJohan Hedberg }
5912177bab5SJohan Hedberg 
59242c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
5932177bab5SJohan Hedberg {
59442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5952177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
5962177bab5SJohan Hedberg 
5972177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
5982177bab5SJohan Hedberg 
5992177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
6002177bab5SJohan Hedberg 		cp.le = 0x01;
6012177bab5SJohan Hedberg 		cp.simul = lmp_le_br_capable(hdev);
6022177bab5SJohan Hedberg 	}
6032177bab5SJohan Hedberg 
6042177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
60542c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
6062177bab5SJohan Hedberg 			    &cp);
6072177bab5SJohan Hedberg }
6082177bab5SJohan Hedberg 
60942c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
6102177bab5SJohan Hedberg {
61142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
61242c6b129SJohan Hedberg 
6132177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
61442c6b129SJohan Hedberg 		hci_setup_link_policy(req);
6152177bab5SJohan Hedberg 
61604b4edcbSJohan Hedberg 	if (lmp_le_capable(hdev)) {
61742c6b129SJohan Hedberg 		hci_set_le_support(req);
61804b4edcbSJohan Hedberg 		hci_update_ad(req);
61904b4edcbSJohan Hedberg 	}
6202177bab5SJohan Hedberg }
6212177bab5SJohan Hedberg 
6222177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
6232177bab5SJohan Hedberg {
6242177bab5SJohan Hedberg 	int err;
6252177bab5SJohan Hedberg 
6262177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
6272177bab5SJohan Hedberg 	if (err < 0)
6282177bab5SJohan Hedberg 		return err;
6292177bab5SJohan Hedberg 
6302177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
6312177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
6322177bab5SJohan Hedberg 	 * first stage init.
6332177bab5SJohan Hedberg 	 */
6342177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
6352177bab5SJohan Hedberg 		return 0;
6362177bab5SJohan Hedberg 
6372177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
6382177bab5SJohan Hedberg 	if (err < 0)
6392177bab5SJohan Hedberg 		return err;
6402177bab5SJohan Hedberg 
6412177bab5SJohan Hedberg 	return __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
6422177bab5SJohan Hedberg }
6432177bab5SJohan Hedberg 
64442c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
6451da177e4SLinus Torvalds {
6461da177e4SLinus Torvalds 	__u8 scan = opt;
6471da177e4SLinus Torvalds 
64842c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
6491da177e4SLinus Torvalds 
6501da177e4SLinus Torvalds 	/* Inquiry and Page scans */
65142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
6521da177e4SLinus Torvalds }
6531da177e4SLinus Torvalds 
65442c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
6551da177e4SLinus Torvalds {
6561da177e4SLinus Torvalds 	__u8 auth = opt;
6571da177e4SLinus Torvalds 
65842c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
6591da177e4SLinus Torvalds 
6601da177e4SLinus Torvalds 	/* Authentication */
66142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
6621da177e4SLinus Torvalds }
6631da177e4SLinus Torvalds 
66442c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
6651da177e4SLinus Torvalds {
6661da177e4SLinus Torvalds 	__u8 encrypt = opt;
6671da177e4SLinus Torvalds 
66842c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
6691da177e4SLinus Torvalds 
670e4e8e37cSMarcel Holtmann 	/* Encryption */
67142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
6721da177e4SLinus Torvalds }
6731da177e4SLinus Torvalds 
67442c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
675e4e8e37cSMarcel Holtmann {
676e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
677e4e8e37cSMarcel Holtmann 
67842c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
679e4e8e37cSMarcel Holtmann 
680e4e8e37cSMarcel Holtmann 	/* Default link policy */
68142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
682e4e8e37cSMarcel Holtmann }
683e4e8e37cSMarcel Holtmann 
6841da177e4SLinus Torvalds /* Get HCI device by index.
6851da177e4SLinus Torvalds  * Device is held on return. */
6861da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
6871da177e4SLinus Torvalds {
6888035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
6891da177e4SLinus Torvalds 
6901da177e4SLinus Torvalds 	BT_DBG("%d", index);
6911da177e4SLinus Torvalds 
6921da177e4SLinus Torvalds 	if (index < 0)
6931da177e4SLinus Torvalds 		return NULL;
6941da177e4SLinus Torvalds 
6951da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
6968035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
6971da177e4SLinus Torvalds 		if (d->id == index) {
6981da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
6991da177e4SLinus Torvalds 			break;
7001da177e4SLinus Torvalds 		}
7011da177e4SLinus Torvalds 	}
7021da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
7031da177e4SLinus Torvalds 	return hdev;
7041da177e4SLinus Torvalds }
7051da177e4SLinus Torvalds 
7061da177e4SLinus Torvalds /* ---- Inquiry support ---- */
707ff9ef578SJohan Hedberg 
70830dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
70930dc78e1SJohan Hedberg {
71030dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
71130dc78e1SJohan Hedberg 
7126fbe195dSAndre Guedes 	switch (discov->state) {
713343f935bSAndre Guedes 	case DISCOVERY_FINDING:
7146fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
71530dc78e1SJohan Hedberg 		return true;
71630dc78e1SJohan Hedberg 
7176fbe195dSAndre Guedes 	default:
71830dc78e1SJohan Hedberg 		return false;
71930dc78e1SJohan Hedberg 	}
7206fbe195dSAndre Guedes }
72130dc78e1SJohan Hedberg 
722ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
723ff9ef578SJohan Hedberg {
724ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
725ff9ef578SJohan Hedberg 
726ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
727ff9ef578SJohan Hedberg 		return;
728ff9ef578SJohan Hedberg 
729ff9ef578SJohan Hedberg 	switch (state) {
730ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
7317b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
732ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
733ff9ef578SJohan Hedberg 		break;
734ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
735ff9ef578SJohan Hedberg 		break;
736343f935bSAndre Guedes 	case DISCOVERY_FINDING:
737ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
738ff9ef578SJohan Hedberg 		break;
73930dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
74030dc78e1SJohan Hedberg 		break;
741ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
742ff9ef578SJohan Hedberg 		break;
743ff9ef578SJohan Hedberg 	}
744ff9ef578SJohan Hedberg 
745ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
746ff9ef578SJohan Hedberg }
747ff9ef578SJohan Hedberg 
7481da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
7491da177e4SLinus Torvalds {
75030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
751b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
7521da177e4SLinus Torvalds 
753561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
754561aafbcSJohan Hedberg 		list_del(&p->all);
755b57c1a56SJohan Hedberg 		kfree(p);
7561da177e4SLinus Torvalds 	}
757561aafbcSJohan Hedberg 
758561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
759561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
7601da177e4SLinus Torvalds }
7611da177e4SLinus Torvalds 
762a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
763a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
7641da177e4SLinus Torvalds {
76530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
7661da177e4SLinus Torvalds 	struct inquiry_entry *e;
7671da177e4SLinus Torvalds 
7686ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
7691da177e4SLinus Torvalds 
770561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
7711da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
7721da177e4SLinus Torvalds 			return e;
7731da177e4SLinus Torvalds 	}
7741da177e4SLinus Torvalds 
775b57c1a56SJohan Hedberg 	return NULL;
776b57c1a56SJohan Hedberg }
777b57c1a56SJohan Hedberg 
778561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
779561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
780561aafbcSJohan Hedberg {
78130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
782561aafbcSJohan Hedberg 	struct inquiry_entry *e;
783561aafbcSJohan Hedberg 
7846ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
785561aafbcSJohan Hedberg 
786561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
787561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
788561aafbcSJohan Hedberg 			return e;
789561aafbcSJohan Hedberg 	}
790561aafbcSJohan Hedberg 
791561aafbcSJohan Hedberg 	return NULL;
792561aafbcSJohan Hedberg }
793561aafbcSJohan Hedberg 
79430dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
79530dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
79630dc78e1SJohan Hedberg 						       int state)
79730dc78e1SJohan Hedberg {
79830dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
79930dc78e1SJohan Hedberg 	struct inquiry_entry *e;
80030dc78e1SJohan Hedberg 
8016ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
80230dc78e1SJohan Hedberg 
80330dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
80430dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
80530dc78e1SJohan Hedberg 			return e;
80630dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
80730dc78e1SJohan Hedberg 			return e;
80830dc78e1SJohan Hedberg 	}
80930dc78e1SJohan Hedberg 
81030dc78e1SJohan Hedberg 	return NULL;
81130dc78e1SJohan Hedberg }
81230dc78e1SJohan Hedberg 
813a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
814a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
815a3d4e20aSJohan Hedberg {
816a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
817a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
818a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
819a3d4e20aSJohan Hedberg 
820a3d4e20aSJohan Hedberg 	list_del(&ie->list);
821a3d4e20aSJohan Hedberg 
822a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
823a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
824a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
825a3d4e20aSJohan Hedberg 			break;
826a3d4e20aSJohan Hedberg 		pos = &p->list;
827a3d4e20aSJohan Hedberg 	}
828a3d4e20aSJohan Hedberg 
829a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
830a3d4e20aSJohan Hedberg }
831a3d4e20aSJohan Hedberg 
8323175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
833388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
8341da177e4SLinus Torvalds {
83530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
83670f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
8371da177e4SLinus Torvalds 
8386ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
8391da177e4SLinus Torvalds 
8402b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
8412b2fec4dSSzymon Janc 
842388fc8faSJohan Hedberg 	if (ssp)
843388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
844388fc8faSJohan Hedberg 
84570f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
846a3d4e20aSJohan Hedberg 	if (ie) {
847388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
848388fc8faSJohan Hedberg 			*ssp = true;
849388fc8faSJohan Hedberg 
850a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
851a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
852a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
853a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
854a3d4e20aSJohan Hedberg 		}
855a3d4e20aSJohan Hedberg 
856561aafbcSJohan Hedberg 		goto update;
857a3d4e20aSJohan Hedberg 	}
858561aafbcSJohan Hedberg 
8591da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
86070f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
86170f23020SAndrei Emeltchenko 	if (!ie)
8623175405bSJohan Hedberg 		return false;
86370f23020SAndrei Emeltchenko 
864561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
865561aafbcSJohan Hedberg 
866561aafbcSJohan Hedberg 	if (name_known) {
867561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
868561aafbcSJohan Hedberg 	} else {
869561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
870561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
871561aafbcSJohan Hedberg 	}
872561aafbcSJohan Hedberg 
873561aafbcSJohan Hedberg update:
874561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
875561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
876561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
877561aafbcSJohan Hedberg 		list_del(&ie->list);
8781da177e4SLinus Torvalds 	}
8791da177e4SLinus Torvalds 
88070f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
88170f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
8821da177e4SLinus Torvalds 	cache->timestamp = jiffies;
8833175405bSJohan Hedberg 
8843175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
8853175405bSJohan Hedberg 		return false;
8863175405bSJohan Hedberg 
8873175405bSJohan Hedberg 	return true;
8881da177e4SLinus Torvalds }
8891da177e4SLinus Torvalds 
8901da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
8911da177e4SLinus Torvalds {
89230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
8931da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
8941da177e4SLinus Torvalds 	struct inquiry_entry *e;
8951da177e4SLinus Torvalds 	int copied = 0;
8961da177e4SLinus Torvalds 
897561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
8981da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
899b57c1a56SJohan Hedberg 
900b57c1a56SJohan Hedberg 		if (copied >= num)
901b57c1a56SJohan Hedberg 			break;
902b57c1a56SJohan Hedberg 
9031da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
9041da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
9051da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
9061da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
9071da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
9081da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
909b57c1a56SJohan Hedberg 
9101da177e4SLinus Torvalds 		info++;
911b57c1a56SJohan Hedberg 		copied++;
9121da177e4SLinus Torvalds 	}
9131da177e4SLinus Torvalds 
9141da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
9151da177e4SLinus Torvalds 	return copied;
9161da177e4SLinus Torvalds }
9171da177e4SLinus Torvalds 
91842c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
9191da177e4SLinus Torvalds {
9201da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
92142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
9221da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
9231da177e4SLinus Torvalds 
9241da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
9251da177e4SLinus Torvalds 
9261da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
9271da177e4SLinus Torvalds 		return;
9281da177e4SLinus Torvalds 
9291da177e4SLinus Torvalds 	/* Start Inquiry */
9301da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
9311da177e4SLinus Torvalds 	cp.length  = ir->length;
9321da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
93342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
9341da177e4SLinus Torvalds }
9351da177e4SLinus Torvalds 
9363e13fa1eSAndre Guedes static int wait_inquiry(void *word)
9373e13fa1eSAndre Guedes {
9383e13fa1eSAndre Guedes 	schedule();
9393e13fa1eSAndre Guedes 	return signal_pending(current);
9403e13fa1eSAndre Guedes }
9413e13fa1eSAndre Guedes 
9421da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
9431da177e4SLinus Torvalds {
9441da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
9451da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
9461da177e4SLinus Torvalds 	struct hci_dev *hdev;
9471da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
9481da177e4SLinus Torvalds 	long timeo;
9491da177e4SLinus Torvalds 	__u8 *buf;
9501da177e4SLinus Torvalds 
9511da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
9521da177e4SLinus Torvalds 		return -EFAULT;
9531da177e4SLinus Torvalds 
9545a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
9555a08ecceSAndrei Emeltchenko 	if (!hdev)
9561da177e4SLinus Torvalds 		return -ENODEV;
9571da177e4SLinus Torvalds 
95809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
9591da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
960a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
9611da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
9621da177e4SLinus Torvalds 		do_inquiry = 1;
9631da177e4SLinus Torvalds 	}
96409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
9651da177e4SLinus Torvalds 
96604837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
96770f23020SAndrei Emeltchenko 
96870f23020SAndrei Emeltchenko 	if (do_inquiry) {
96901178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
97001178cd4SJohan Hedberg 				   timeo);
97170f23020SAndrei Emeltchenko 		if (err < 0)
9721da177e4SLinus Torvalds 			goto done;
9733e13fa1eSAndre Guedes 
9743e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
9753e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
9763e13fa1eSAndre Guedes 		 */
9773e13fa1eSAndre Guedes 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry,
9783e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
9793e13fa1eSAndre Guedes 			return -EINTR;
98070f23020SAndrei Emeltchenko 	}
9811da177e4SLinus Torvalds 
9828fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
9838fc9ced3SGustavo Padovan 	 * 255 entries
9848fc9ced3SGustavo Padovan 	 */
9851da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
9861da177e4SLinus Torvalds 
9871da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
9881da177e4SLinus Torvalds 	 * copy it to the user space.
9891da177e4SLinus Torvalds 	 */
99070f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
99170f23020SAndrei Emeltchenko 	if (!buf) {
9921da177e4SLinus Torvalds 		err = -ENOMEM;
9931da177e4SLinus Torvalds 		goto done;
9941da177e4SLinus Torvalds 	}
9951da177e4SLinus Torvalds 
99609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
9971da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
99809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
9991da177e4SLinus Torvalds 
10001da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
10011da177e4SLinus Torvalds 
10021da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
10031da177e4SLinus Torvalds 		ptr += sizeof(ir);
10041da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
10051da177e4SLinus Torvalds 				 ir.num_rsp))
10061da177e4SLinus Torvalds 			err = -EFAULT;
10071da177e4SLinus Torvalds 	} else
10081da177e4SLinus Torvalds 		err = -EFAULT;
10091da177e4SLinus Torvalds 
10101da177e4SLinus Torvalds 	kfree(buf);
10111da177e4SLinus Torvalds 
10121da177e4SLinus Torvalds done:
10131da177e4SLinus Torvalds 	hci_dev_put(hdev);
10141da177e4SLinus Torvalds 	return err;
10151da177e4SLinus Torvalds }
10161da177e4SLinus Torvalds 
10173f0f524bSJohan Hedberg static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
10183f0f524bSJohan Hedberg {
10193f0f524bSJohan Hedberg 	u8 ad_len = 0, flags = 0;
10203f0f524bSJohan Hedberg 	size_t name_len;
10213f0f524bSJohan Hedberg 
10223f0f524bSJohan Hedberg 	if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
10233f0f524bSJohan Hedberg 		flags |= LE_AD_GENERAL;
10243f0f524bSJohan Hedberg 
10253f0f524bSJohan Hedberg 	if (!lmp_bredr_capable(hdev))
10263f0f524bSJohan Hedberg 		flags |= LE_AD_NO_BREDR;
10273f0f524bSJohan Hedberg 
10283f0f524bSJohan Hedberg 	if (lmp_le_br_capable(hdev))
10293f0f524bSJohan Hedberg 		flags |= LE_AD_SIM_LE_BREDR_CTRL;
10303f0f524bSJohan Hedberg 
10313f0f524bSJohan Hedberg 	if (lmp_host_le_br_capable(hdev))
10323f0f524bSJohan Hedberg 		flags |= LE_AD_SIM_LE_BREDR_HOST;
10333f0f524bSJohan Hedberg 
10343f0f524bSJohan Hedberg 	if (flags) {
10353f0f524bSJohan Hedberg 		BT_DBG("adv flags 0x%02x", flags);
10363f0f524bSJohan Hedberg 
10373f0f524bSJohan Hedberg 		ptr[0] = 2;
10383f0f524bSJohan Hedberg 		ptr[1] = EIR_FLAGS;
10393f0f524bSJohan Hedberg 		ptr[2] = flags;
10403f0f524bSJohan Hedberg 
10413f0f524bSJohan Hedberg 		ad_len += 3;
10423f0f524bSJohan Hedberg 		ptr += 3;
10433f0f524bSJohan Hedberg 	}
10443f0f524bSJohan Hedberg 
10453f0f524bSJohan Hedberg 	if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) {
10463f0f524bSJohan Hedberg 		ptr[0] = 2;
10473f0f524bSJohan Hedberg 		ptr[1] = EIR_TX_POWER;
10483f0f524bSJohan Hedberg 		ptr[2] = (u8) hdev->adv_tx_power;
10493f0f524bSJohan Hedberg 
10503f0f524bSJohan Hedberg 		ad_len += 3;
10513f0f524bSJohan Hedberg 		ptr += 3;
10523f0f524bSJohan Hedberg 	}
10533f0f524bSJohan Hedberg 
10543f0f524bSJohan Hedberg 	name_len = strlen(hdev->dev_name);
10553f0f524bSJohan Hedberg 	if (name_len > 0) {
10563f0f524bSJohan Hedberg 		size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
10573f0f524bSJohan Hedberg 
10583f0f524bSJohan Hedberg 		if (name_len > max_len) {
10593f0f524bSJohan Hedberg 			name_len = max_len;
10603f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_SHORT;
10613f0f524bSJohan Hedberg 		} else
10623f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_COMPLETE;
10633f0f524bSJohan Hedberg 
10643f0f524bSJohan Hedberg 		ptr[0] = name_len + 1;
10653f0f524bSJohan Hedberg 
10663f0f524bSJohan Hedberg 		memcpy(ptr + 2, hdev->dev_name, name_len);
10673f0f524bSJohan Hedberg 
10683f0f524bSJohan Hedberg 		ad_len += (name_len + 2);
10693f0f524bSJohan Hedberg 		ptr += (name_len + 2);
10703f0f524bSJohan Hedberg 	}
10713f0f524bSJohan Hedberg 
10723f0f524bSJohan Hedberg 	return ad_len;
10733f0f524bSJohan Hedberg }
10743f0f524bSJohan Hedberg 
107504b4edcbSJohan Hedberg void hci_update_ad(struct hci_request *req)
10763f0f524bSJohan Hedberg {
107704b4edcbSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
10783f0f524bSJohan Hedberg 	struct hci_cp_le_set_adv_data cp;
10793f0f524bSJohan Hedberg 	u8 len;
10803f0f524bSJohan Hedberg 
108104b4edcbSJohan Hedberg 	if (!lmp_le_capable(hdev))
108204b4edcbSJohan Hedberg 		return;
10833f0f524bSJohan Hedberg 
10843f0f524bSJohan Hedberg 	memset(&cp, 0, sizeof(cp));
10853f0f524bSJohan Hedberg 
10863f0f524bSJohan Hedberg 	len = create_ad(hdev, cp.data);
10873f0f524bSJohan Hedberg 
10883f0f524bSJohan Hedberg 	if (hdev->adv_data_len == len &&
108904b4edcbSJohan Hedberg 	    memcmp(cp.data, hdev->adv_data, len) == 0)
109004b4edcbSJohan Hedberg 		return;
10913f0f524bSJohan Hedberg 
10923f0f524bSJohan Hedberg 	memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
10933f0f524bSJohan Hedberg 	hdev->adv_data_len = len;
10943f0f524bSJohan Hedberg 
10953f0f524bSJohan Hedberg 	cp.length = len;
10963f0f524bSJohan Hedberg 
109704b4edcbSJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
10983f0f524bSJohan Hedberg }
10993f0f524bSJohan Hedberg 
11001da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
11011da177e4SLinus Torvalds 
11021da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
11031da177e4SLinus Torvalds {
11041da177e4SLinus Torvalds 	struct hci_dev *hdev;
11051da177e4SLinus Torvalds 	int ret = 0;
11061da177e4SLinus Torvalds 
11075a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
11085a08ecceSAndrei Emeltchenko 	if (!hdev)
11091da177e4SLinus Torvalds 		return -ENODEV;
11101da177e4SLinus Torvalds 
11111da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
11121da177e4SLinus Torvalds 
11131da177e4SLinus Torvalds 	hci_req_lock(hdev);
11141da177e4SLinus Torvalds 
111594324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
111694324962SJohan Hovold 		ret = -ENODEV;
111794324962SJohan Hovold 		goto done;
111894324962SJohan Hovold 	}
111994324962SJohan Hovold 
1120611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
1121611b30f7SMarcel Holtmann 		ret = -ERFKILL;
1122611b30f7SMarcel Holtmann 		goto done;
1123611b30f7SMarcel Holtmann 	}
1124611b30f7SMarcel Holtmann 
11251da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
11261da177e4SLinus Torvalds 		ret = -EALREADY;
11271da177e4SLinus Torvalds 		goto done;
11281da177e4SLinus Torvalds 	}
11291da177e4SLinus Torvalds 
11301da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
11311da177e4SLinus Torvalds 		ret = -EIO;
11321da177e4SLinus Torvalds 		goto done;
11331da177e4SLinus Torvalds 	}
11341da177e4SLinus Torvalds 
11351da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
11361da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1137f41c70c4SMarcel Holtmann 
1138f41c70c4SMarcel Holtmann 	if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
1139f41c70c4SMarcel Holtmann 		ret = hdev->setup(hdev);
1140f41c70c4SMarcel Holtmann 
1141f41c70c4SMarcel Holtmann 	if (!ret) {
1142f41c70c4SMarcel Holtmann 		/* Treat all non BR/EDR controllers as raw devices if
1143f41c70c4SMarcel Holtmann 		 * enable_hs is not set.
1144f41c70c4SMarcel Holtmann 		 */
1145f41c70c4SMarcel Holtmann 		if (hdev->dev_type != HCI_BREDR && !enable_hs)
1146f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
1147f41c70c4SMarcel Holtmann 
1148f41c70c4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1149f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
1150f41c70c4SMarcel Holtmann 
1151f41c70c4SMarcel Holtmann 		if (!test_bit(HCI_RAW, &hdev->flags))
11522177bab5SJohan Hedberg 			ret = __hci_init(hdev);
11531da177e4SLinus Torvalds 	}
11541da177e4SLinus Torvalds 
1155f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1156f41c70c4SMarcel Holtmann 
11571da177e4SLinus Torvalds 	if (!ret) {
11581da177e4SLinus Torvalds 		hci_dev_hold(hdev);
11591da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
11601da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
1161bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
1162bb4b2a9aSAndrei Emeltchenko 		    mgmt_valid_hdev(hdev)) {
116309fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1164744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
116509fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
116656e5cb86SJohan Hedberg 		}
11671da177e4SLinus Torvalds 	} else {
11681da177e4SLinus Torvalds 		/* Init failed, cleanup */
11693eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1170c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1171b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
11721da177e4SLinus Torvalds 
11731da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
11741da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
11751da177e4SLinus Torvalds 
11761da177e4SLinus Torvalds 		if (hdev->flush)
11771da177e4SLinus Torvalds 			hdev->flush(hdev);
11781da177e4SLinus Torvalds 
11791da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
11801da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
11811da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
11821da177e4SLinus Torvalds 		}
11831da177e4SLinus Torvalds 
11841da177e4SLinus Torvalds 		hdev->close(hdev);
11851da177e4SLinus Torvalds 		hdev->flags = 0;
11861da177e4SLinus Torvalds 	}
11871da177e4SLinus Torvalds 
11881da177e4SLinus Torvalds done:
11891da177e4SLinus Torvalds 	hci_req_unlock(hdev);
11901da177e4SLinus Torvalds 	hci_dev_put(hdev);
11911da177e4SLinus Torvalds 	return ret;
11921da177e4SLinus Torvalds }
11931da177e4SLinus Torvalds 
11941da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
11951da177e4SLinus Torvalds {
11961da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
11971da177e4SLinus Torvalds 
119828b75a89SAndre Guedes 	cancel_work_sync(&hdev->le_scan);
119928b75a89SAndre Guedes 
120078c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
120178c04c0bSVinicius Costa Gomes 
12021da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
12031da177e4SLinus Torvalds 	hci_req_lock(hdev);
12041da177e4SLinus Torvalds 
12051da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
1206b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
12071da177e4SLinus Torvalds 		hci_req_unlock(hdev);
12081da177e4SLinus Torvalds 		return 0;
12091da177e4SLinus Torvalds 	}
12101da177e4SLinus Torvalds 
12113eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
12123eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1213b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
12141da177e4SLinus Torvalds 
121516ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
1216e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
121716ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
12185e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
121916ab91abSJohan Hedberg 	}
122016ab91abSJohan Hedberg 
1221a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
12227d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
12237d78525dSJohan Hedberg 
12247ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
12257ba8b4beSAndre Guedes 
122609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
12271da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
12281da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
122909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
12301da177e4SLinus Torvalds 
12311da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
12321da177e4SLinus Torvalds 
12331da177e4SLinus Torvalds 	if (hdev->flush)
12341da177e4SLinus Torvalds 		hdev->flush(hdev);
12351da177e4SLinus Torvalds 
12361da177e4SLinus Torvalds 	/* Reset device */
12371da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
12381da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
12398af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
1240a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
12411da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
124201178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
12431da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
12441da177e4SLinus Torvalds 	}
12451da177e4SLinus Torvalds 
1246c347b765SGustavo F. Padovan 	/* flush cmd  work */
1247c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
12481da177e4SLinus Torvalds 
12491da177e4SLinus Torvalds 	/* Drop queues */
12501da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
12511da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
12521da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
12531da177e4SLinus Torvalds 
12541da177e4SLinus Torvalds 	/* Drop last sent command */
12551da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
1256b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
12571da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
12581da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
12591da177e4SLinus Torvalds 	}
12601da177e4SLinus Torvalds 
1261b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
1262b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
1263b6ddb638SJohan Hedberg 
12641da177e4SLinus Torvalds 	/* After this point our queues are empty
12651da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
12661da177e4SLinus Torvalds 	hdev->close(hdev);
12671da177e4SLinus Torvalds 
126835b973c9SJohan Hedberg 	/* Clear flags */
126935b973c9SJohan Hedberg 	hdev->flags = 0;
127035b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
127135b973c9SJohan Hedberg 
1272bb4b2a9aSAndrei Emeltchenko 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
1273bb4b2a9aSAndrei Emeltchenko 	    mgmt_valid_hdev(hdev)) {
127409fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1275744cf19eSJohan Hedberg 		mgmt_powered(hdev, 0);
127609fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
12778ee56540SMarcel Holtmann 	}
12785add6af8SJohan Hedberg 
1279ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1280ced5c338SAndrei Emeltchenko 	hdev->amp_status = 0;
1281ced5c338SAndrei Emeltchenko 
1282e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
128309b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
1284e59fda8dSJohan Hedberg 
12851da177e4SLinus Torvalds 	hci_req_unlock(hdev);
12861da177e4SLinus Torvalds 
12871da177e4SLinus Torvalds 	hci_dev_put(hdev);
12881da177e4SLinus Torvalds 	return 0;
12891da177e4SLinus Torvalds }
12901da177e4SLinus Torvalds 
12911da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
12921da177e4SLinus Torvalds {
12931da177e4SLinus Torvalds 	struct hci_dev *hdev;
12941da177e4SLinus Torvalds 	int err;
12951da177e4SLinus Torvalds 
129670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
129770f23020SAndrei Emeltchenko 	if (!hdev)
12981da177e4SLinus Torvalds 		return -ENODEV;
12998ee56540SMarcel Holtmann 
13008ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
13018ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
13028ee56540SMarcel Holtmann 
13031da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
13048ee56540SMarcel Holtmann 
13051da177e4SLinus Torvalds 	hci_dev_put(hdev);
13061da177e4SLinus Torvalds 	return err;
13071da177e4SLinus Torvalds }
13081da177e4SLinus Torvalds 
13091da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
13101da177e4SLinus Torvalds {
13111da177e4SLinus Torvalds 	struct hci_dev *hdev;
13121da177e4SLinus Torvalds 	int ret = 0;
13131da177e4SLinus Torvalds 
131470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
131570f23020SAndrei Emeltchenko 	if (!hdev)
13161da177e4SLinus Torvalds 		return -ENODEV;
13171da177e4SLinus Torvalds 
13181da177e4SLinus Torvalds 	hci_req_lock(hdev);
13191da177e4SLinus Torvalds 
13201da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
13211da177e4SLinus Torvalds 		goto done;
13221da177e4SLinus Torvalds 
13231da177e4SLinus Torvalds 	/* Drop queues */
13241da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
13251da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
13261da177e4SLinus Torvalds 
132709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13281da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
13291da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
133009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13311da177e4SLinus Torvalds 
13321da177e4SLinus Torvalds 	if (hdev->flush)
13331da177e4SLinus Torvalds 		hdev->flush(hdev);
13341da177e4SLinus Torvalds 
13351da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
13366ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
13371da177e4SLinus Torvalds 
13381da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
133901178cd4SJohan Hedberg 		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
13401da177e4SLinus Torvalds 
13411da177e4SLinus Torvalds done:
13421da177e4SLinus Torvalds 	hci_req_unlock(hdev);
13431da177e4SLinus Torvalds 	hci_dev_put(hdev);
13441da177e4SLinus Torvalds 	return ret;
13451da177e4SLinus Torvalds }
13461da177e4SLinus Torvalds 
13471da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
13481da177e4SLinus Torvalds {
13491da177e4SLinus Torvalds 	struct hci_dev *hdev;
13501da177e4SLinus Torvalds 	int ret = 0;
13511da177e4SLinus Torvalds 
135270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
135370f23020SAndrei Emeltchenko 	if (!hdev)
13541da177e4SLinus Torvalds 		return -ENODEV;
13551da177e4SLinus Torvalds 
13561da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
13571da177e4SLinus Torvalds 
13581da177e4SLinus Torvalds 	hci_dev_put(hdev);
13591da177e4SLinus Torvalds 
13601da177e4SLinus Torvalds 	return ret;
13611da177e4SLinus Torvalds }
13621da177e4SLinus Torvalds 
13631da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
13641da177e4SLinus Torvalds {
13651da177e4SLinus Torvalds 	struct hci_dev *hdev;
13661da177e4SLinus Torvalds 	struct hci_dev_req dr;
13671da177e4SLinus Torvalds 	int err = 0;
13681da177e4SLinus Torvalds 
13691da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
13701da177e4SLinus Torvalds 		return -EFAULT;
13711da177e4SLinus Torvalds 
137270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
137370f23020SAndrei Emeltchenko 	if (!hdev)
13741da177e4SLinus Torvalds 		return -ENODEV;
13751da177e4SLinus Torvalds 
13761da177e4SLinus Torvalds 	switch (cmd) {
13771da177e4SLinus Torvalds 	case HCISETAUTH:
137801178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
13795f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
13801da177e4SLinus Torvalds 		break;
13811da177e4SLinus Torvalds 
13821da177e4SLinus Torvalds 	case HCISETENCRYPT:
13831da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
13841da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
13851da177e4SLinus Torvalds 			break;
13861da177e4SLinus Torvalds 		}
13871da177e4SLinus Torvalds 
13881da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
13891da177e4SLinus Torvalds 			/* Auth must be enabled first */
139001178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
13915f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
13921da177e4SLinus Torvalds 			if (err)
13931da177e4SLinus Torvalds 				break;
13941da177e4SLinus Torvalds 		}
13951da177e4SLinus Torvalds 
139601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
13975f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
13981da177e4SLinus Torvalds 		break;
13991da177e4SLinus Torvalds 
14001da177e4SLinus Torvalds 	case HCISETSCAN:
140101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
14025f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
14031da177e4SLinus Torvalds 		break;
14041da177e4SLinus Torvalds 
14051da177e4SLinus Torvalds 	case HCISETLINKPOL:
140601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
14075f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
14081da177e4SLinus Torvalds 		break;
14091da177e4SLinus Torvalds 
14101da177e4SLinus Torvalds 	case HCISETLINKMODE:
1411e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
1412e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
1413e4e8e37cSMarcel Holtmann 		break;
1414e4e8e37cSMarcel Holtmann 
1415e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
1416e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
14171da177e4SLinus Torvalds 		break;
14181da177e4SLinus Torvalds 
14191da177e4SLinus Torvalds 	case HCISETACLMTU:
14201da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
14211da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
14221da177e4SLinus Torvalds 		break;
14231da177e4SLinus Torvalds 
14241da177e4SLinus Torvalds 	case HCISETSCOMTU:
14251da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
14261da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
14271da177e4SLinus Torvalds 		break;
14281da177e4SLinus Torvalds 
14291da177e4SLinus Torvalds 	default:
14301da177e4SLinus Torvalds 		err = -EINVAL;
14311da177e4SLinus Torvalds 		break;
14321da177e4SLinus Torvalds 	}
1433e4e8e37cSMarcel Holtmann 
14341da177e4SLinus Torvalds 	hci_dev_put(hdev);
14351da177e4SLinus Torvalds 	return err;
14361da177e4SLinus Torvalds }
14371da177e4SLinus Torvalds 
14381da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
14391da177e4SLinus Torvalds {
14408035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
14411da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
14421da177e4SLinus Torvalds 	struct hci_dev_req *dr;
14431da177e4SLinus Torvalds 	int n = 0, size, err;
14441da177e4SLinus Torvalds 	__u16 dev_num;
14451da177e4SLinus Torvalds 
14461da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
14471da177e4SLinus Torvalds 		return -EFAULT;
14481da177e4SLinus Torvalds 
14491da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
14501da177e4SLinus Torvalds 		return -EINVAL;
14511da177e4SLinus Torvalds 
14521da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
14531da177e4SLinus Torvalds 
145470f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
145570f23020SAndrei Emeltchenko 	if (!dl)
14561da177e4SLinus Torvalds 		return -ENOMEM;
14571da177e4SLinus Torvalds 
14581da177e4SLinus Torvalds 	dr = dl->dev_req;
14591da177e4SLinus Torvalds 
1460f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
14618035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
1462a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1463e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
1464c542a06cSJohan Hedberg 
1465a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1466a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1467c542a06cSJohan Hedberg 
14681da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
14691da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
1470c542a06cSJohan Hedberg 
14711da177e4SLinus Torvalds 		if (++n >= dev_num)
14721da177e4SLinus Torvalds 			break;
14731da177e4SLinus Torvalds 	}
1474f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
14751da177e4SLinus Torvalds 
14761da177e4SLinus Torvalds 	dl->dev_num = n;
14771da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
14781da177e4SLinus Torvalds 
14791da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
14801da177e4SLinus Torvalds 	kfree(dl);
14811da177e4SLinus Torvalds 
14821da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
14831da177e4SLinus Torvalds }
14841da177e4SLinus Torvalds 
14851da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
14861da177e4SLinus Torvalds {
14871da177e4SLinus Torvalds 	struct hci_dev *hdev;
14881da177e4SLinus Torvalds 	struct hci_dev_info di;
14891da177e4SLinus Torvalds 	int err = 0;
14901da177e4SLinus Torvalds 
14911da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
14921da177e4SLinus Torvalds 		return -EFAULT;
14931da177e4SLinus Torvalds 
149470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
149570f23020SAndrei Emeltchenko 	if (!hdev)
14961da177e4SLinus Torvalds 		return -ENODEV;
14971da177e4SLinus Torvalds 
1498a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
14993243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1500ab81cbf9SJohan Hedberg 
1501a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1502a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1503c542a06cSJohan Hedberg 
15041da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
15051da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
1506943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
15071da177e4SLinus Torvalds 	di.flags    = hdev->flags;
15081da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
1509572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
15101da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
15111da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
15121da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
15131da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
1514572c7f84SJohan Hedberg 	} else {
1515572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
1516572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
1517572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
1518572c7f84SJohan Hedberg 		di.sco_pkts = 0;
1519572c7f84SJohan Hedberg 	}
15201da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
15211da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
15221da177e4SLinus Torvalds 
15231da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
15241da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
15251da177e4SLinus Torvalds 
15261da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
15271da177e4SLinus Torvalds 		err = -EFAULT;
15281da177e4SLinus Torvalds 
15291da177e4SLinus Torvalds 	hci_dev_put(hdev);
15301da177e4SLinus Torvalds 
15311da177e4SLinus Torvalds 	return err;
15321da177e4SLinus Torvalds }
15331da177e4SLinus Torvalds 
15341da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
15351da177e4SLinus Torvalds 
1536611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1537611b30f7SMarcel Holtmann {
1538611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1539611b30f7SMarcel Holtmann 
1540611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1541611b30f7SMarcel Holtmann 
1542611b30f7SMarcel Holtmann 	if (!blocked)
1543611b30f7SMarcel Holtmann 		return 0;
1544611b30f7SMarcel Holtmann 
1545611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1546611b30f7SMarcel Holtmann 
1547611b30f7SMarcel Holtmann 	return 0;
1548611b30f7SMarcel Holtmann }
1549611b30f7SMarcel Holtmann 
1550611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1551611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1552611b30f7SMarcel Holtmann };
1553611b30f7SMarcel Holtmann 
1554ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1555ab81cbf9SJohan Hedberg {
1556ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
1557ab81cbf9SJohan Hedberg 
1558ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1559ab81cbf9SJohan Hedberg 
1560ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
1561ab81cbf9SJohan Hedberg 		return;
1562ab81cbf9SJohan Hedberg 
1563a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
156419202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
156519202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
1566ab81cbf9SJohan Hedberg 
1567a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1568744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1569ab81cbf9SJohan Hedberg }
1570ab81cbf9SJohan Hedberg 
1571ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1572ab81cbf9SJohan Hedberg {
15733243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
15743243553fSJohan Hedberg 					    power_off.work);
1575ab81cbf9SJohan Hedberg 
1576ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1577ab81cbf9SJohan Hedberg 
15788ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1579ab81cbf9SJohan Hedberg }
1580ab81cbf9SJohan Hedberg 
158116ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
158216ab91abSJohan Hedberg {
158316ab91abSJohan Hedberg 	struct hci_dev *hdev;
158416ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
158516ab91abSJohan Hedberg 
158616ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
158716ab91abSJohan Hedberg 
158816ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
158916ab91abSJohan Hedberg 
159009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
159116ab91abSJohan Hedberg 
159216ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
159316ab91abSJohan Hedberg 
159416ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
159516ab91abSJohan Hedberg 
159609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
159716ab91abSJohan Hedberg }
159816ab91abSJohan Hedberg 
15992aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
16002aeb9a1aSJohan Hedberg {
16014821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
16022aeb9a1aSJohan Hedberg 
16034821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
16044821002cSJohan Hedberg 		list_del(&uuid->list);
16052aeb9a1aSJohan Hedberg 		kfree(uuid);
16062aeb9a1aSJohan Hedberg 	}
16072aeb9a1aSJohan Hedberg 
16082aeb9a1aSJohan Hedberg 	return 0;
16092aeb9a1aSJohan Hedberg }
16102aeb9a1aSJohan Hedberg 
161155ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
161255ed8ca1SJohan Hedberg {
161355ed8ca1SJohan Hedberg 	struct list_head *p, *n;
161455ed8ca1SJohan Hedberg 
161555ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
161655ed8ca1SJohan Hedberg 		struct link_key *key;
161755ed8ca1SJohan Hedberg 
161855ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
161955ed8ca1SJohan Hedberg 
162055ed8ca1SJohan Hedberg 		list_del(p);
162155ed8ca1SJohan Hedberg 		kfree(key);
162255ed8ca1SJohan Hedberg 	}
162355ed8ca1SJohan Hedberg 
162455ed8ca1SJohan Hedberg 	return 0;
162555ed8ca1SJohan Hedberg }
162655ed8ca1SJohan Hedberg 
1627b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1628b899efafSVinicius Costa Gomes {
1629b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1630b899efafSVinicius Costa Gomes 
1631b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1632b899efafSVinicius Costa Gomes 		list_del(&k->list);
1633b899efafSVinicius Costa Gomes 		kfree(k);
1634b899efafSVinicius Costa Gomes 	}
1635b899efafSVinicius Costa Gomes 
1636b899efafSVinicius Costa Gomes 	return 0;
1637b899efafSVinicius Costa Gomes }
1638b899efafSVinicius Costa Gomes 
163955ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
164055ed8ca1SJohan Hedberg {
164155ed8ca1SJohan Hedberg 	struct link_key *k;
164255ed8ca1SJohan Hedberg 
16438035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
164455ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
164555ed8ca1SJohan Hedberg 			return k;
164655ed8ca1SJohan Hedberg 
164755ed8ca1SJohan Hedberg 	return NULL;
164855ed8ca1SJohan Hedberg }
164955ed8ca1SJohan Hedberg 
1650745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1651d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1652d25e28abSJohan Hedberg {
1653d25e28abSJohan Hedberg 	/* Legacy key */
1654d25e28abSJohan Hedberg 	if (key_type < 0x03)
1655745c0ce3SVishal Agarwal 		return true;
1656d25e28abSJohan Hedberg 
1657d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1658d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1659745c0ce3SVishal Agarwal 		return false;
1660d25e28abSJohan Hedberg 
1661d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1662d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1663745c0ce3SVishal Agarwal 		return false;
1664d25e28abSJohan Hedberg 
1665d25e28abSJohan Hedberg 	/* Security mode 3 case */
1666d25e28abSJohan Hedberg 	if (!conn)
1667745c0ce3SVishal Agarwal 		return true;
1668d25e28abSJohan Hedberg 
1669d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1670d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1671745c0ce3SVishal Agarwal 		return true;
1672d25e28abSJohan Hedberg 
1673d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1674d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1675745c0ce3SVishal Agarwal 		return true;
1676d25e28abSJohan Hedberg 
1677d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1678d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1679745c0ce3SVishal Agarwal 		return true;
1680d25e28abSJohan Hedberg 
1681d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1682d25e28abSJohan Hedberg 	 * persistently */
1683745c0ce3SVishal Agarwal 	return false;
1684d25e28abSJohan Hedberg }
1685d25e28abSJohan Hedberg 
1686c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
168775d262c2SVinicius Costa Gomes {
1688c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
168975d262c2SVinicius Costa Gomes 
1690c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1691c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1692c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
169375d262c2SVinicius Costa Gomes 			continue;
169475d262c2SVinicius Costa Gomes 
169575d262c2SVinicius Costa Gomes 		return k;
169675d262c2SVinicius Costa Gomes 	}
169775d262c2SVinicius Costa Gomes 
169875d262c2SVinicius Costa Gomes 	return NULL;
169975d262c2SVinicius Costa Gomes }
170075d262c2SVinicius Costa Gomes 
1701c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1702c9839a11SVinicius Costa Gomes 				     u8 addr_type)
170375d262c2SVinicius Costa Gomes {
1704c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
170575d262c2SVinicius Costa Gomes 
1706c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1707c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1708c9839a11SVinicius Costa Gomes 		    bacmp(bdaddr, &k->bdaddr) == 0)
170975d262c2SVinicius Costa Gomes 			return k;
171075d262c2SVinicius Costa Gomes 
171175d262c2SVinicius Costa Gomes 	return NULL;
171275d262c2SVinicius Costa Gomes }
171375d262c2SVinicius Costa Gomes 
1714d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1715d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
171655ed8ca1SJohan Hedberg {
171755ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1718745c0ce3SVishal Agarwal 	u8 old_key_type;
1719745c0ce3SVishal Agarwal 	bool persistent;
172055ed8ca1SJohan Hedberg 
172155ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
172255ed8ca1SJohan Hedberg 	if (old_key) {
172355ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
172455ed8ca1SJohan Hedberg 		key = old_key;
172555ed8ca1SJohan Hedberg 	} else {
172612adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
172755ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
172855ed8ca1SJohan Hedberg 		if (!key)
172955ed8ca1SJohan Hedberg 			return -ENOMEM;
173055ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
173155ed8ca1SJohan Hedberg 	}
173255ed8ca1SJohan Hedberg 
17336ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
173455ed8ca1SJohan Hedberg 
1735d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1736d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1737d25e28abSJohan Hedberg 	 * previous key */
1738d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1739a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1740d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1741655fe6ecSJohan Hedberg 		if (conn)
1742655fe6ecSJohan Hedberg 			conn->key_type = type;
1743655fe6ecSJohan Hedberg 	}
1744d25e28abSJohan Hedberg 
174555ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
17469b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
174755ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
174855ed8ca1SJohan Hedberg 
1749b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
175055ed8ca1SJohan Hedberg 		key->type = old_key_type;
17514748fed2SJohan Hedberg 	else
17524748fed2SJohan Hedberg 		key->type = type;
17534748fed2SJohan Hedberg 
17544df378a1SJohan Hedberg 	if (!new_key)
17554df378a1SJohan Hedberg 		return 0;
17564df378a1SJohan Hedberg 
17574df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
17584df378a1SJohan Hedberg 
1759744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
17604df378a1SJohan Hedberg 
17616ec5bcadSVishal Agarwal 	if (conn)
17626ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
176355ed8ca1SJohan Hedberg 
176455ed8ca1SJohan Hedberg 	return 0;
176555ed8ca1SJohan Hedberg }
176655ed8ca1SJohan Hedberg 
1767c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
17689a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
176904124681SGustavo F. Padovan 		ediv, u8 rand[8])
177075d262c2SVinicius Costa Gomes {
1771c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
177275d262c2SVinicius Costa Gomes 
1773c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1774c9839a11SVinicius Costa Gomes 		return 0;
177575d262c2SVinicius Costa Gomes 
1776c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1777c9839a11SVinicius Costa Gomes 	if (old_key)
177875d262c2SVinicius Costa Gomes 		key = old_key;
1779c9839a11SVinicius Costa Gomes 	else {
1780c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
178175d262c2SVinicius Costa Gomes 		if (!key)
178275d262c2SVinicius Costa Gomes 			return -ENOMEM;
1783c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
178475d262c2SVinicius Costa Gomes 	}
178575d262c2SVinicius Costa Gomes 
178675d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1787c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1788c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1789c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1790c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1791c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1792c9839a11SVinicius Costa Gomes 	key->type = type;
1793c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
179475d262c2SVinicius Costa Gomes 
1795c9839a11SVinicius Costa Gomes 	if (!new_key)
1796c9839a11SVinicius Costa Gomes 		return 0;
179775d262c2SVinicius Costa Gomes 
1798261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1799261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1800261cc5aaSVinicius Costa Gomes 
180175d262c2SVinicius Costa Gomes 	return 0;
180275d262c2SVinicius Costa Gomes }
180375d262c2SVinicius Costa Gomes 
180455ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
180555ed8ca1SJohan Hedberg {
180655ed8ca1SJohan Hedberg 	struct link_key *key;
180755ed8ca1SJohan Hedberg 
180855ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
180955ed8ca1SJohan Hedberg 	if (!key)
181055ed8ca1SJohan Hedberg 		return -ENOENT;
181155ed8ca1SJohan Hedberg 
18126ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
181355ed8ca1SJohan Hedberg 
181455ed8ca1SJohan Hedberg 	list_del(&key->list);
181555ed8ca1SJohan Hedberg 	kfree(key);
181655ed8ca1SJohan Hedberg 
181755ed8ca1SJohan Hedberg 	return 0;
181855ed8ca1SJohan Hedberg }
181955ed8ca1SJohan Hedberg 
1820b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1821b899efafSVinicius Costa Gomes {
1822b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1823b899efafSVinicius Costa Gomes 
1824b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1825b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1826b899efafSVinicius Costa Gomes 			continue;
1827b899efafSVinicius Costa Gomes 
18286ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1829b899efafSVinicius Costa Gomes 
1830b899efafSVinicius Costa Gomes 		list_del(&k->list);
1831b899efafSVinicius Costa Gomes 		kfree(k);
1832b899efafSVinicius Costa Gomes 	}
1833b899efafSVinicius Costa Gomes 
1834b899efafSVinicius Costa Gomes 	return 0;
1835b899efafSVinicius Costa Gomes }
1836b899efafSVinicius Costa Gomes 
18376bd32326SVille Tervo /* HCI command timer function */
1838bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
18396bd32326SVille Tervo {
18406bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
18416bd32326SVille Tervo 
1842bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
1843bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
1844bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
1845bda4f23aSAndrei Emeltchenko 
1846bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
1847bda4f23aSAndrei Emeltchenko 	} else {
18486bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
1849bda4f23aSAndrei Emeltchenko 	}
1850bda4f23aSAndrei Emeltchenko 
18516bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1852c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
18536bd32326SVille Tervo }
18546bd32326SVille Tervo 
18552763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
18562763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
18572763eda6SSzymon Janc {
18582763eda6SSzymon Janc 	struct oob_data *data;
18592763eda6SSzymon Janc 
18602763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
18612763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
18622763eda6SSzymon Janc 			return data;
18632763eda6SSzymon Janc 
18642763eda6SSzymon Janc 	return NULL;
18652763eda6SSzymon Janc }
18662763eda6SSzymon Janc 
18672763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
18682763eda6SSzymon Janc {
18692763eda6SSzymon Janc 	struct oob_data *data;
18702763eda6SSzymon Janc 
18712763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
18722763eda6SSzymon Janc 	if (!data)
18732763eda6SSzymon Janc 		return -ENOENT;
18742763eda6SSzymon Janc 
18756ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
18762763eda6SSzymon Janc 
18772763eda6SSzymon Janc 	list_del(&data->list);
18782763eda6SSzymon Janc 	kfree(data);
18792763eda6SSzymon Janc 
18802763eda6SSzymon Janc 	return 0;
18812763eda6SSzymon Janc }
18822763eda6SSzymon Janc 
18832763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
18842763eda6SSzymon Janc {
18852763eda6SSzymon Janc 	struct oob_data *data, *n;
18862763eda6SSzymon Janc 
18872763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
18882763eda6SSzymon Janc 		list_del(&data->list);
18892763eda6SSzymon Janc 		kfree(data);
18902763eda6SSzymon Janc 	}
18912763eda6SSzymon Janc 
18922763eda6SSzymon Janc 	return 0;
18932763eda6SSzymon Janc }
18942763eda6SSzymon Janc 
18952763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
18962763eda6SSzymon Janc 			    u8 *randomizer)
18972763eda6SSzymon Janc {
18982763eda6SSzymon Janc 	struct oob_data *data;
18992763eda6SSzymon Janc 
19002763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
19012763eda6SSzymon Janc 
19022763eda6SSzymon Janc 	if (!data) {
19032763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
19042763eda6SSzymon Janc 		if (!data)
19052763eda6SSzymon Janc 			return -ENOMEM;
19062763eda6SSzymon Janc 
19072763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
19082763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
19092763eda6SSzymon Janc 	}
19102763eda6SSzymon Janc 
19112763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
19122763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
19132763eda6SSzymon Janc 
19146ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
19152763eda6SSzymon Janc 
19162763eda6SSzymon Janc 	return 0;
19172763eda6SSzymon Janc }
19182763eda6SSzymon Janc 
191904124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
1920b2a66aadSAntti Julku {
1921b2a66aadSAntti Julku 	struct bdaddr_list *b;
1922b2a66aadSAntti Julku 
19238035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1924b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1925b2a66aadSAntti Julku 			return b;
1926b2a66aadSAntti Julku 
1927b2a66aadSAntti Julku 	return NULL;
1928b2a66aadSAntti Julku }
1929b2a66aadSAntti Julku 
1930b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1931b2a66aadSAntti Julku {
1932b2a66aadSAntti Julku 	struct list_head *p, *n;
1933b2a66aadSAntti Julku 
1934b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1935b2a66aadSAntti Julku 		struct bdaddr_list *b;
1936b2a66aadSAntti Julku 
1937b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1938b2a66aadSAntti Julku 
1939b2a66aadSAntti Julku 		list_del(p);
1940b2a66aadSAntti Julku 		kfree(b);
1941b2a66aadSAntti Julku 	}
1942b2a66aadSAntti Julku 
1943b2a66aadSAntti Julku 	return 0;
1944b2a66aadSAntti Julku }
1945b2a66aadSAntti Julku 
194688c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1947b2a66aadSAntti Julku {
1948b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1949b2a66aadSAntti Julku 
1950b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1951b2a66aadSAntti Julku 		return -EBADF;
1952b2a66aadSAntti Julku 
19535e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
19545e762444SAntti Julku 		return -EEXIST;
1955b2a66aadSAntti Julku 
1956b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
19575e762444SAntti Julku 	if (!entry)
19585e762444SAntti Julku 		return -ENOMEM;
1959b2a66aadSAntti Julku 
1960b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1961b2a66aadSAntti Julku 
1962b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1963b2a66aadSAntti Julku 
196488c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
1965b2a66aadSAntti Julku }
1966b2a66aadSAntti Julku 
196788c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1968b2a66aadSAntti Julku {
1969b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1970b2a66aadSAntti Julku 
19711ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
19725e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1973b2a66aadSAntti Julku 
1974b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
19751ec918ceSSzymon Janc 	if (!entry)
19765e762444SAntti Julku 		return -ENOENT;
1977b2a66aadSAntti Julku 
1978b2a66aadSAntti Julku 	list_del(&entry->list);
1979b2a66aadSAntti Julku 	kfree(entry);
1980b2a66aadSAntti Julku 
198188c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
1982b2a66aadSAntti Julku }
1983b2a66aadSAntti Julku 
198442c6b129SJohan Hedberg static void le_scan_param_req(struct hci_request *req, unsigned long opt)
19857ba8b4beSAndre Guedes {
19867ba8b4beSAndre Guedes 	struct le_scan_params *param =  (struct le_scan_params *) opt;
19877ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_param cp;
19887ba8b4beSAndre Guedes 
19897ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
19907ba8b4beSAndre Guedes 	cp.type = param->type;
19917ba8b4beSAndre Guedes 	cp.interval = cpu_to_le16(param->interval);
19927ba8b4beSAndre Guedes 	cp.window = cpu_to_le16(param->window);
19937ba8b4beSAndre Guedes 
199442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
19957ba8b4beSAndre Guedes }
19967ba8b4beSAndre Guedes 
199742c6b129SJohan Hedberg static void le_scan_enable_req(struct hci_request *req, unsigned long opt)
19987ba8b4beSAndre Guedes {
19997ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
20007ba8b4beSAndre Guedes 
20017ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
20027ba8b4beSAndre Guedes 	cp.enable = 1;
20030431a43cSAndre Guedes 	cp.filter_dup = 1;
20047ba8b4beSAndre Guedes 
200542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
20067ba8b4beSAndre Guedes }
20077ba8b4beSAndre Guedes 
20087ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
20097ba8b4beSAndre Guedes 			  u16 window, int timeout)
20107ba8b4beSAndre Guedes {
20117ba8b4beSAndre Guedes 	long timeo = msecs_to_jiffies(3000);
20127ba8b4beSAndre Guedes 	struct le_scan_params param;
20137ba8b4beSAndre Guedes 	int err;
20147ba8b4beSAndre Guedes 
20157ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
20167ba8b4beSAndre Guedes 
20177ba8b4beSAndre Guedes 	if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
20187ba8b4beSAndre Guedes 		return -EINPROGRESS;
20197ba8b4beSAndre Guedes 
20207ba8b4beSAndre Guedes 	param.type = type;
20217ba8b4beSAndre Guedes 	param.interval = interval;
20227ba8b4beSAndre Guedes 	param.window = window;
20237ba8b4beSAndre Guedes 
20247ba8b4beSAndre Guedes 	hci_req_lock(hdev);
20257ba8b4beSAndre Guedes 
202601178cd4SJohan Hedberg 	err = __hci_req_sync(hdev, le_scan_param_req, (unsigned long) &param,
20277ba8b4beSAndre Guedes 			     timeo);
20287ba8b4beSAndre Guedes 	if (!err)
202901178cd4SJohan Hedberg 		err = __hci_req_sync(hdev, le_scan_enable_req, 0, timeo);
20307ba8b4beSAndre Guedes 
20317ba8b4beSAndre Guedes 	hci_req_unlock(hdev);
20327ba8b4beSAndre Guedes 
20337ba8b4beSAndre Guedes 	if (err < 0)
20347ba8b4beSAndre Guedes 		return err;
20357ba8b4beSAndre Guedes 
203646818ed5SJohan Hedberg 	queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable,
20377ba8b4beSAndre Guedes 			   msecs_to_jiffies(timeout));
20387ba8b4beSAndre Guedes 
20397ba8b4beSAndre Guedes 	return 0;
20407ba8b4beSAndre Guedes }
20417ba8b4beSAndre Guedes 
20427dbfac1dSAndre Guedes int hci_cancel_le_scan(struct hci_dev *hdev)
20437dbfac1dSAndre Guedes {
20447dbfac1dSAndre Guedes 	BT_DBG("%s", hdev->name);
20457dbfac1dSAndre Guedes 
20467dbfac1dSAndre Guedes 	if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
20477dbfac1dSAndre Guedes 		return -EALREADY;
20487dbfac1dSAndre Guedes 
20497dbfac1dSAndre Guedes 	if (cancel_delayed_work(&hdev->le_scan_disable)) {
20507dbfac1dSAndre Guedes 		struct hci_cp_le_set_scan_enable cp;
20517dbfac1dSAndre Guedes 
20527dbfac1dSAndre Guedes 		/* Send HCI command to disable LE Scan */
20537dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
20547dbfac1dSAndre Guedes 		hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
20557dbfac1dSAndre Guedes 	}
20567dbfac1dSAndre Guedes 
20577dbfac1dSAndre Guedes 	return 0;
20587dbfac1dSAndre Guedes }
20597dbfac1dSAndre Guedes 
20607ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
20617ba8b4beSAndre Guedes {
20627ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
20637ba8b4beSAndre Guedes 					    le_scan_disable.work);
20647ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
20657ba8b4beSAndre Guedes 
20667ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
20677ba8b4beSAndre Guedes 
20687ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
20697ba8b4beSAndre Guedes 
20707ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
20717ba8b4beSAndre Guedes }
20727ba8b4beSAndre Guedes 
207328b75a89SAndre Guedes static void le_scan_work(struct work_struct *work)
207428b75a89SAndre Guedes {
207528b75a89SAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
207628b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
207728b75a89SAndre Guedes 
207828b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
207928b75a89SAndre Guedes 
208004124681SGustavo F. Padovan 	hci_do_le_scan(hdev, param->type, param->interval, param->window,
208104124681SGustavo F. Padovan 		       param->timeout);
208228b75a89SAndre Guedes }
208328b75a89SAndre Guedes 
208428b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
208528b75a89SAndre Guedes 		int timeout)
208628b75a89SAndre Guedes {
208728b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
208828b75a89SAndre Guedes 
208928b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
209028b75a89SAndre Guedes 
2091f1550478SJohan Hedberg 	if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
2092f1550478SJohan Hedberg 		return -ENOTSUPP;
2093f1550478SJohan Hedberg 
209428b75a89SAndre Guedes 	if (work_busy(&hdev->le_scan))
209528b75a89SAndre Guedes 		return -EINPROGRESS;
209628b75a89SAndre Guedes 
209728b75a89SAndre Guedes 	param->type = type;
209828b75a89SAndre Guedes 	param->interval = interval;
209928b75a89SAndre Guedes 	param->window = window;
210028b75a89SAndre Guedes 	param->timeout = timeout;
210128b75a89SAndre Guedes 
210228b75a89SAndre Guedes 	queue_work(system_long_wq, &hdev->le_scan);
210328b75a89SAndre Guedes 
210428b75a89SAndre Guedes 	return 0;
210528b75a89SAndre Guedes }
210628b75a89SAndre Guedes 
21079be0dab7SDavid Herrmann /* Alloc HCI device */
21089be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
21099be0dab7SDavid Herrmann {
21109be0dab7SDavid Herrmann 	struct hci_dev *hdev;
21119be0dab7SDavid Herrmann 
21129be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
21139be0dab7SDavid Herrmann 	if (!hdev)
21149be0dab7SDavid Herrmann 		return NULL;
21159be0dab7SDavid Herrmann 
2116b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2117b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
2118b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
2119b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03; /* No Input No Output */
2120bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2121bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2122b1b813d4SDavid Herrmann 
2123b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
2124b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
2125b1b813d4SDavid Herrmann 
2126b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
2127b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
2128b1b813d4SDavid Herrmann 
2129b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
2130b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
2131b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
2132b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
2133b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
2134b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
21356b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
2136b1b813d4SDavid Herrmann 
2137b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
2138b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2139b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2140b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2141b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->le_scan, le_scan_work);
2142b1b813d4SDavid Herrmann 
2143b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2144b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
2145b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
2146b1b813d4SDavid Herrmann 
21479be0dab7SDavid Herrmann 	skb_queue_head_init(&hdev->driver_init);
2148b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2149b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2150b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2151b1b813d4SDavid Herrmann 
2152b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2153b1b813d4SDavid Herrmann 
2154bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
2155b1b813d4SDavid Herrmann 
2156b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2157b1b813d4SDavid Herrmann 	discovery_init(hdev);
21589be0dab7SDavid Herrmann 
21599be0dab7SDavid Herrmann 	return hdev;
21609be0dab7SDavid Herrmann }
21619be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
21629be0dab7SDavid Herrmann 
21639be0dab7SDavid Herrmann /* Free HCI device */
21649be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
21659be0dab7SDavid Herrmann {
21669be0dab7SDavid Herrmann 	skb_queue_purge(&hdev->driver_init);
21679be0dab7SDavid Herrmann 
21689be0dab7SDavid Herrmann 	/* will free via device release */
21699be0dab7SDavid Herrmann 	put_device(&hdev->dev);
21709be0dab7SDavid Herrmann }
21719be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
21729be0dab7SDavid Herrmann 
21731da177e4SLinus Torvalds /* Register HCI device */
21741da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
21751da177e4SLinus Torvalds {
2176b1b813d4SDavid Herrmann 	int id, error;
21771da177e4SLinus Torvalds 
2178010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
21791da177e4SLinus Torvalds 		return -EINVAL;
21801da177e4SLinus Torvalds 
218108add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
218208add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
218308add513SMat Martineau 	 */
21843df92b31SSasha Levin 	switch (hdev->dev_type) {
21853df92b31SSasha Levin 	case HCI_BREDR:
21863df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
21871da177e4SLinus Torvalds 		break;
21883df92b31SSasha Levin 	case HCI_AMP:
21893df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
21903df92b31SSasha Levin 		break;
21913df92b31SSasha Levin 	default:
21923df92b31SSasha Levin 		return -EINVAL;
21931da177e4SLinus Torvalds 	}
21941da177e4SLinus Torvalds 
21953df92b31SSasha Levin 	if (id < 0)
21963df92b31SSasha Levin 		return id;
21973df92b31SSasha Levin 
21981da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
21991da177e4SLinus Torvalds 	hdev->id = id;
22002d8b3a11SAndrei Emeltchenko 
22012d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
22022d8b3a11SAndrei Emeltchenko 
22033df92b31SSasha Levin 	write_lock(&hci_dev_list_lock);
22043df92b31SSasha Levin 	list_add(&hdev->list, &hci_dev_list);
2205f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
22061da177e4SLinus Torvalds 
220732845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
220832845eb1SGustavo F. Padovan 					  WQ_MEM_RECLAIM, 1);
220933ca954dSDavid Herrmann 	if (!hdev->workqueue) {
221033ca954dSDavid Herrmann 		error = -ENOMEM;
221133ca954dSDavid Herrmann 		goto err;
221233ca954dSDavid Herrmann 	}
2213f48fd9c8SMarcel Holtmann 
22146ead1bbcSJohan Hedberg 	hdev->req_workqueue = alloc_workqueue(hdev->name,
22156ead1bbcSJohan Hedberg 					      WQ_HIGHPRI | WQ_UNBOUND |
22166ead1bbcSJohan Hedberg 					      WQ_MEM_RECLAIM, 1);
22176ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
22186ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
22196ead1bbcSJohan Hedberg 		error = -ENOMEM;
22206ead1bbcSJohan Hedberg 		goto err;
22216ead1bbcSJohan Hedberg 	}
22226ead1bbcSJohan Hedberg 
222333ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
222433ca954dSDavid Herrmann 	if (error < 0)
222533ca954dSDavid Herrmann 		goto err_wqueue;
22261da177e4SLinus Torvalds 
2227611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2228a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2229a8c5fb1aSGustavo Padovan 				    hdev);
2230611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2231611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
2232611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
2233611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
2234611b30f7SMarcel Holtmann 		}
2235611b30f7SMarcel Holtmann 	}
2236611b30f7SMarcel Holtmann 
2237a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
2238ce2be9acSAndrei Emeltchenko 
2239ce2be9acSAndrei Emeltchenko 	if (hdev->dev_type != HCI_AMP)
2240ce2be9acSAndrei Emeltchenko 		set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2241ce2be9acSAndrei Emeltchenko 
22421da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
2243dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
22441da177e4SLinus Torvalds 
224519202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2246fbe96d6fSMarcel Holtmann 
22471da177e4SLinus Torvalds 	return id;
2248f48fd9c8SMarcel Holtmann 
224933ca954dSDavid Herrmann err_wqueue:
225033ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
22516ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
225233ca954dSDavid Herrmann err:
22533df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
2254f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
2255f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
2256f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
2257f48fd9c8SMarcel Holtmann 
225833ca954dSDavid Herrmann 	return error;
22591da177e4SLinus Torvalds }
22601da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
22611da177e4SLinus Torvalds 
22621da177e4SLinus Torvalds /* Unregister HCI device */
226359735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
22641da177e4SLinus Torvalds {
22653df92b31SSasha Levin 	int i, id;
2266ef222013SMarcel Holtmann 
2267c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
22681da177e4SLinus Torvalds 
226994324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
227094324962SJohan Hovold 
22713df92b31SSasha Levin 	id = hdev->id;
22723df92b31SSasha Levin 
2273f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
22741da177e4SLinus Torvalds 	list_del(&hdev->list);
2275f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
22761da177e4SLinus Torvalds 
22771da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
22781da177e4SLinus Torvalds 
2279cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
2280ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
2281ef222013SMarcel Holtmann 
2282b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
2283b9b5ef18SGustavo Padovan 
2284ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2285a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
228609fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2287744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
228809fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
228956e5cb86SJohan Hedberg 	}
2290ab81cbf9SJohan Hedberg 
22912e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
22922e58ef3eSJohan Hedberg 	 * pending list */
22932e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
22942e58ef3eSJohan Hedberg 
22951da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
22961da177e4SLinus Torvalds 
2297611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2298611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2299611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2300611b30f7SMarcel Holtmann 	}
2301611b30f7SMarcel Holtmann 
2302ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
2303147e2d59SDave Young 
2304f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
23056ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2306f48fd9c8SMarcel Holtmann 
230709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
2308e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
23092aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
231055ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2311b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
23122763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
231309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2314e2e0cacbSJohan Hedberg 
2315dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
23163df92b31SSasha Levin 
23173df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
23181da177e4SLinus Torvalds }
23191da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
23201da177e4SLinus Torvalds 
23211da177e4SLinus Torvalds /* Suspend HCI device */
23221da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
23231da177e4SLinus Torvalds {
23241da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
23251da177e4SLinus Torvalds 	return 0;
23261da177e4SLinus Torvalds }
23271da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
23281da177e4SLinus Torvalds 
23291da177e4SLinus Torvalds /* Resume HCI device */
23301da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
23311da177e4SLinus Torvalds {
23321da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
23331da177e4SLinus Torvalds 	return 0;
23341da177e4SLinus Torvalds }
23351da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
23361da177e4SLinus Torvalds 
233776bca880SMarcel Holtmann /* Receive frame from HCI drivers */
233876bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
233976bca880SMarcel Holtmann {
234076bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
234176bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
234276bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
234376bca880SMarcel Holtmann 		kfree_skb(skb);
234476bca880SMarcel Holtmann 		return -ENXIO;
234576bca880SMarcel Holtmann 	}
234676bca880SMarcel Holtmann 
2347d82603c6SJorrit Schippers 	/* Incoming skb */
234876bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
234976bca880SMarcel Holtmann 
235076bca880SMarcel Holtmann 	/* Time stamp */
235176bca880SMarcel Holtmann 	__net_timestamp(skb);
235276bca880SMarcel Holtmann 
235376bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2354b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2355c78ae283SMarcel Holtmann 
235676bca880SMarcel Holtmann 	return 0;
235776bca880SMarcel Holtmann }
235876bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
235976bca880SMarcel Holtmann 
236033e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
23611e429f38SGustavo F. Padovan 			  int count, __u8 index)
236233e882a5SSuraj Sumangala {
236333e882a5SSuraj Sumangala 	int len = 0;
236433e882a5SSuraj Sumangala 	int hlen = 0;
236533e882a5SSuraj Sumangala 	int remain = count;
236633e882a5SSuraj Sumangala 	struct sk_buff *skb;
236733e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
236833e882a5SSuraj Sumangala 
236933e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
237033e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
237133e882a5SSuraj Sumangala 		return -EILSEQ;
237233e882a5SSuraj Sumangala 
237333e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
237433e882a5SSuraj Sumangala 
237533e882a5SSuraj Sumangala 	if (!skb) {
237633e882a5SSuraj Sumangala 		switch (type) {
237733e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
237833e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
237933e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
238033e882a5SSuraj Sumangala 			break;
238133e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
238233e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
238333e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
238433e882a5SSuraj Sumangala 			break;
238533e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
238633e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
238733e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
238833e882a5SSuraj Sumangala 			break;
238933e882a5SSuraj Sumangala 		}
239033e882a5SSuraj Sumangala 
23911e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
239233e882a5SSuraj Sumangala 		if (!skb)
239333e882a5SSuraj Sumangala 			return -ENOMEM;
239433e882a5SSuraj Sumangala 
239533e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
239633e882a5SSuraj Sumangala 		scb->expect = hlen;
239733e882a5SSuraj Sumangala 		scb->pkt_type = type;
239833e882a5SSuraj Sumangala 
239933e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
240033e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
240133e882a5SSuraj Sumangala 	}
240233e882a5SSuraj Sumangala 
240333e882a5SSuraj Sumangala 	while (count) {
240433e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
240589bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
240633e882a5SSuraj Sumangala 
240733e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
240833e882a5SSuraj Sumangala 
240933e882a5SSuraj Sumangala 		count -= len;
241033e882a5SSuraj Sumangala 		data += len;
241133e882a5SSuraj Sumangala 		scb->expect -= len;
241233e882a5SSuraj Sumangala 		remain = count;
241333e882a5SSuraj Sumangala 
241433e882a5SSuraj Sumangala 		switch (type) {
241533e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
241633e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
241733e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
241833e882a5SSuraj Sumangala 				scb->expect = h->plen;
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_ACLDATA_PKT:
242933e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
243033e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
243133e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(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 		case HCI_SCODATA_PKT:
244233e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
244333e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
244433e882a5SSuraj Sumangala 				scb->expect = h->dlen;
244533e882a5SSuraj Sumangala 
244633e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
244733e882a5SSuraj Sumangala 					kfree_skb(skb);
244833e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
244933e882a5SSuraj Sumangala 					return -ENOMEM;
245033e882a5SSuraj Sumangala 				}
245133e882a5SSuraj Sumangala 			}
245233e882a5SSuraj Sumangala 			break;
245333e882a5SSuraj Sumangala 		}
245433e882a5SSuraj Sumangala 
245533e882a5SSuraj Sumangala 		if (scb->expect == 0) {
245633e882a5SSuraj Sumangala 			/* Complete frame */
245733e882a5SSuraj Sumangala 
245833e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
245933e882a5SSuraj Sumangala 			hci_recv_frame(skb);
246033e882a5SSuraj Sumangala 
246133e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
246233e882a5SSuraj Sumangala 			return remain;
246333e882a5SSuraj Sumangala 		}
246433e882a5SSuraj Sumangala 	}
246533e882a5SSuraj Sumangala 
246633e882a5SSuraj Sumangala 	return remain;
246733e882a5SSuraj Sumangala }
246833e882a5SSuraj Sumangala 
2469ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
2470ef222013SMarcel Holtmann {
2471f39a3c06SSuraj Sumangala 	int rem = 0;
2472f39a3c06SSuraj Sumangala 
2473ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
2474ef222013SMarcel Holtmann 		return -EILSEQ;
2475ef222013SMarcel Holtmann 
2476da5f6c37SGustavo F. Padovan 	while (count) {
24771e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
2478f39a3c06SSuraj Sumangala 		if (rem < 0)
2479f39a3c06SSuraj Sumangala 			return rem;
2480ef222013SMarcel Holtmann 
2481f39a3c06SSuraj Sumangala 		data += (count - rem);
2482f39a3c06SSuraj Sumangala 		count = rem;
2483f81c6224SJoe Perches 	}
2484ef222013SMarcel Holtmann 
2485f39a3c06SSuraj Sumangala 	return rem;
2486ef222013SMarcel Holtmann }
2487ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
2488ef222013SMarcel Holtmann 
248999811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
249099811510SSuraj Sumangala 
249199811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
249299811510SSuraj Sumangala {
249399811510SSuraj Sumangala 	int type;
249499811510SSuraj Sumangala 	int rem = 0;
249599811510SSuraj Sumangala 
2496da5f6c37SGustavo F. Padovan 	while (count) {
249799811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
249899811510SSuraj Sumangala 
249999811510SSuraj Sumangala 		if (!skb) {
250099811510SSuraj Sumangala 			struct { char type; } *pkt;
250199811510SSuraj Sumangala 
250299811510SSuraj Sumangala 			/* Start of the frame */
250399811510SSuraj Sumangala 			pkt = data;
250499811510SSuraj Sumangala 			type = pkt->type;
250599811510SSuraj Sumangala 
250699811510SSuraj Sumangala 			data++;
250799811510SSuraj Sumangala 			count--;
250899811510SSuraj Sumangala 		} else
250999811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
251099811510SSuraj Sumangala 
25111e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
25121e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
251399811510SSuraj Sumangala 		if (rem < 0)
251499811510SSuraj Sumangala 			return rem;
251599811510SSuraj Sumangala 
251699811510SSuraj Sumangala 		data += (count - rem);
251799811510SSuraj Sumangala 		count = rem;
2518f81c6224SJoe Perches 	}
251999811510SSuraj Sumangala 
252099811510SSuraj Sumangala 	return rem;
252199811510SSuraj Sumangala }
252299811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
252399811510SSuraj Sumangala 
25241da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
25251da177e4SLinus Torvalds 
25261da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
25271da177e4SLinus Torvalds {
25281da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
25291da177e4SLinus Torvalds 
2530f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
25311da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2532f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
25331da177e4SLinus Torvalds 
25341da177e4SLinus Torvalds 	return 0;
25351da177e4SLinus Torvalds }
25361da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
25371da177e4SLinus Torvalds 
25381da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
25391da177e4SLinus Torvalds {
25401da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
25411da177e4SLinus Torvalds 
2542f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
25431da177e4SLinus Torvalds 	list_del(&cb->list);
2544f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
25451da177e4SLinus Torvalds 
25461da177e4SLinus Torvalds 	return 0;
25471da177e4SLinus Torvalds }
25481da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
25491da177e4SLinus Torvalds 
25501da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
25511da177e4SLinus Torvalds {
25521da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
25531da177e4SLinus Torvalds 
25541da177e4SLinus Torvalds 	if (!hdev) {
25551da177e4SLinus Torvalds 		kfree_skb(skb);
25561da177e4SLinus Torvalds 		return -ENODEV;
25571da177e4SLinus Torvalds 	}
25581da177e4SLinus Torvalds 
25590d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
25601da177e4SLinus Torvalds 
25611da177e4SLinus Torvalds 	/* Time stamp */
2562a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
25631da177e4SLinus Torvalds 
2564cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2565cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2566cd82e61cSMarcel Holtmann 
2567cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2568cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2569470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
25701da177e4SLinus Torvalds 	}
25711da177e4SLinus Torvalds 
25721da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
25731da177e4SLinus Torvalds 	skb_orphan(skb);
25741da177e4SLinus Torvalds 
25751da177e4SLinus Torvalds 	return hdev->send(skb);
25761da177e4SLinus Torvalds }
25771da177e4SLinus Torvalds 
25783119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
25793119ae95SJohan Hedberg {
25803119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
25813119ae95SJohan Hedberg 	req->hdev = hdev;
25825d73e034SAndre Guedes 	req->err = 0;
25833119ae95SJohan Hedberg }
25843119ae95SJohan Hedberg 
25853119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
25863119ae95SJohan Hedberg {
25873119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
25883119ae95SJohan Hedberg 	struct sk_buff *skb;
25893119ae95SJohan Hedberg 	unsigned long flags;
25903119ae95SJohan Hedberg 
25913119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
25923119ae95SJohan Hedberg 
25935d73e034SAndre Guedes 	/* If an error occured during request building, remove all HCI
25945d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
25955d73e034SAndre Guedes 	 */
25965d73e034SAndre Guedes 	if (req->err) {
25975d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
25985d73e034SAndre Guedes 		return req->err;
25995d73e034SAndre Guedes 	}
26005d73e034SAndre Guedes 
26013119ae95SJohan Hedberg 	/* Do not allow empty requests */
26023119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
2603382b0c39SAndre Guedes 		return -ENODATA;
26043119ae95SJohan Hedberg 
26053119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
26063119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
26073119ae95SJohan Hedberg 
26083119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
26093119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
26103119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
26113119ae95SJohan Hedberg 
26123119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
26133119ae95SJohan Hedberg 
26143119ae95SJohan Hedberg 	return 0;
26153119ae95SJohan Hedberg }
26163119ae95SJohan Hedberg 
26171ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
26181ca3a9d0SJohan Hedberg 				       u32 plen, void *param)
26191da177e4SLinus Torvalds {
26201da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
26211da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
26221da177e4SLinus Torvalds 	struct sk_buff *skb;
26231da177e4SLinus Torvalds 
26241da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
26251ca3a9d0SJohan Hedberg 	if (!skb)
26261ca3a9d0SJohan Hedberg 		return NULL;
26271da177e4SLinus Torvalds 
26281da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2629a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
26301da177e4SLinus Torvalds 	hdr->plen   = plen;
26311da177e4SLinus Torvalds 
26321da177e4SLinus Torvalds 	if (plen)
26331da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
26341da177e4SLinus Torvalds 
26351da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
26361da177e4SLinus Torvalds 
26370d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
26381da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2639c78ae283SMarcel Holtmann 
26401ca3a9d0SJohan Hedberg 	return skb;
26411ca3a9d0SJohan Hedberg }
26421ca3a9d0SJohan Hedberg 
26431ca3a9d0SJohan Hedberg /* Send HCI command */
26441ca3a9d0SJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
26451ca3a9d0SJohan Hedberg {
26461ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
26471ca3a9d0SJohan Hedberg 
26481ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
26491ca3a9d0SJohan Hedberg 
26501ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
26511ca3a9d0SJohan Hedberg 	if (!skb) {
26521ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
26531ca3a9d0SJohan Hedberg 		return -ENOMEM;
26541ca3a9d0SJohan Hedberg 	}
26551ca3a9d0SJohan Hedberg 
265611714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
265711714b3dSJohan Hedberg 	 * single-command requests.
265811714b3dSJohan Hedberg 	 */
265911714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
266011714b3dSJohan Hedberg 
26611da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2662c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
26631da177e4SLinus Torvalds 
26641da177e4SLinus Torvalds 	return 0;
26651da177e4SLinus Torvalds }
26661da177e4SLinus Torvalds 
266771c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
266802350a72SJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, void *param,
266902350a72SJohan Hedberg 		    u8 event)
267071c76a17SJohan Hedberg {
267171c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
267271c76a17SJohan Hedberg 	struct sk_buff *skb;
267371c76a17SJohan Hedberg 
267471c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
267571c76a17SJohan Hedberg 
267634739c1eSAndre Guedes 	/* If an error occured during request building, there is no point in
267734739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
267834739c1eSAndre Guedes 	 */
267934739c1eSAndre Guedes 	if (req->err)
268034739c1eSAndre Guedes 		return;
268134739c1eSAndre Guedes 
268271c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
268371c76a17SJohan Hedberg 	if (!skb) {
26845d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
26855d73e034SAndre Guedes 		       hdev->name, opcode);
26865d73e034SAndre Guedes 		req->err = -ENOMEM;
2687e348fe6bSAndre Guedes 		return;
268871c76a17SJohan Hedberg 	}
268971c76a17SJohan Hedberg 
269071c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
269171c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
269271c76a17SJohan Hedberg 
269302350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
269402350a72SJohan Hedberg 
269571c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
269671c76a17SJohan Hedberg }
269771c76a17SJohan Hedberg 
269802350a72SJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param)
269902350a72SJohan Hedberg {
270002350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
270102350a72SJohan Hedberg }
270202350a72SJohan Hedberg 
27031da177e4SLinus Torvalds /* Get data from the previously sent command */
2704a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
27051da177e4SLinus Torvalds {
27061da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
27071da177e4SLinus Torvalds 
27081da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
27091da177e4SLinus Torvalds 		return NULL;
27101da177e4SLinus Torvalds 
27111da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
27121da177e4SLinus Torvalds 
2713a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
27141da177e4SLinus Torvalds 		return NULL;
27151da177e4SLinus Torvalds 
2716f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
27171da177e4SLinus Torvalds 
27181da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
27191da177e4SLinus Torvalds }
27201da177e4SLinus Torvalds 
27211da177e4SLinus Torvalds /* Send ACL data */
27221da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
27231da177e4SLinus Torvalds {
27241da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
27251da177e4SLinus Torvalds 	int len = skb->len;
27261da177e4SLinus Torvalds 
2727badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2728badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
27299c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2730aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2731aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
27321da177e4SLinus Torvalds }
27331da177e4SLinus Torvalds 
2734ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
273573d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
27361da177e4SLinus Torvalds {
2737ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
27381da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
27391da177e4SLinus Torvalds 	struct sk_buff *list;
27401da177e4SLinus Torvalds 
2741087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
2742087bfd99SGustavo Padovan 	skb->data_len = 0;
2743087bfd99SGustavo Padovan 
2744087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2745204a6e54SAndrei Emeltchenko 
2746204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
2747204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
2748087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
2749204a6e54SAndrei Emeltchenko 		break;
2750204a6e54SAndrei Emeltchenko 	case HCI_AMP:
2751204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
2752204a6e54SAndrei Emeltchenko 		break;
2753204a6e54SAndrei Emeltchenko 	default:
2754204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2755204a6e54SAndrei Emeltchenko 		return;
2756204a6e54SAndrei Emeltchenko 	}
2757087bfd99SGustavo Padovan 
275870f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
275970f23020SAndrei Emeltchenko 	if (!list) {
27601da177e4SLinus Torvalds 		/* Non fragmented */
27611da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
27621da177e4SLinus Torvalds 
276373d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
27641da177e4SLinus Torvalds 	} else {
27651da177e4SLinus Torvalds 		/* Fragmented */
27661da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
27671da177e4SLinus Torvalds 
27681da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
27691da177e4SLinus Torvalds 
27701da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2771af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
27721da177e4SLinus Torvalds 
277373d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2774e702112fSAndrei Emeltchenko 
2775e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2776e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
27771da177e4SLinus Torvalds 		do {
27781da177e4SLinus Torvalds 			skb = list; list = list->next;
27791da177e4SLinus Torvalds 
27801da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
27810d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2782e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
27831da177e4SLinus Torvalds 
27841da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
27851da177e4SLinus Torvalds 
278673d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
27871da177e4SLinus Torvalds 		} while (list);
27881da177e4SLinus Torvalds 
2789af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
27901da177e4SLinus Torvalds 	}
279173d80debSLuiz Augusto von Dentz }
279273d80debSLuiz Augusto von Dentz 
279373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
279473d80debSLuiz Augusto von Dentz {
2795ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
279673d80debSLuiz Augusto von Dentz 
2797f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
279873d80debSLuiz Augusto von Dentz 
279973d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
280073d80debSLuiz Augusto von Dentz 
2801ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
28021da177e4SLinus Torvalds 
28033eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
28041da177e4SLinus Torvalds }
28051da177e4SLinus Torvalds 
28061da177e4SLinus Torvalds /* Send SCO data */
28070d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
28081da177e4SLinus Torvalds {
28091da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
28101da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
28111da177e4SLinus Torvalds 
28121da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
28131da177e4SLinus Torvalds 
2814aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
28151da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
28161da177e4SLinus Torvalds 
2817badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2818badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
28199c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
28201da177e4SLinus Torvalds 
28211da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
28220d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2823c78ae283SMarcel Holtmann 
28241da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
28253eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
28261da177e4SLinus Torvalds }
28271da177e4SLinus Torvalds 
28281da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
28291da177e4SLinus Torvalds 
28301da177e4SLinus Torvalds /* HCI Connection scheduler */
28316039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
2832a8c5fb1aSGustavo Padovan 				     int *quote)
28331da177e4SLinus Torvalds {
28341da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
28358035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
2836abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
28371da177e4SLinus Torvalds 
28381da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
28391da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2840bf4c6325SGustavo F. Padovan 
2841bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2842bf4c6325SGustavo F. Padovan 
2843bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2844769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
28451da177e4SLinus Torvalds 			continue;
2846769be974SMarcel Holtmann 
2847769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2848769be974SMarcel Holtmann 			continue;
2849769be974SMarcel Holtmann 
28501da177e4SLinus Torvalds 		num++;
28511da177e4SLinus Torvalds 
28521da177e4SLinus Torvalds 		if (c->sent < min) {
28531da177e4SLinus Torvalds 			min  = c->sent;
28541da177e4SLinus Torvalds 			conn = c;
28551da177e4SLinus Torvalds 		}
285652087a79SLuiz Augusto von Dentz 
285752087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
285852087a79SLuiz Augusto von Dentz 			break;
28591da177e4SLinus Torvalds 	}
28601da177e4SLinus Torvalds 
2861bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2862bf4c6325SGustavo F. Padovan 
28631da177e4SLinus Torvalds 	if (conn) {
28646ed58ec5SVille Tervo 		int cnt, q;
28656ed58ec5SVille Tervo 
28666ed58ec5SVille Tervo 		switch (conn->type) {
28676ed58ec5SVille Tervo 		case ACL_LINK:
28686ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
28696ed58ec5SVille Tervo 			break;
28706ed58ec5SVille Tervo 		case SCO_LINK:
28716ed58ec5SVille Tervo 		case ESCO_LINK:
28726ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
28736ed58ec5SVille Tervo 			break;
28746ed58ec5SVille Tervo 		case LE_LINK:
28756ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
28766ed58ec5SVille Tervo 			break;
28776ed58ec5SVille Tervo 		default:
28786ed58ec5SVille Tervo 			cnt = 0;
28796ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
28806ed58ec5SVille Tervo 		}
28816ed58ec5SVille Tervo 
28826ed58ec5SVille Tervo 		q = cnt / num;
28831da177e4SLinus Torvalds 		*quote = q ? q : 1;
28841da177e4SLinus Torvalds 	} else
28851da177e4SLinus Torvalds 		*quote = 0;
28861da177e4SLinus Torvalds 
28871da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
28881da177e4SLinus Torvalds 	return conn;
28891da177e4SLinus Torvalds }
28901da177e4SLinus Torvalds 
28916039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
28921da177e4SLinus Torvalds {
28931da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
28941da177e4SLinus Torvalds 	struct hci_conn *c;
28951da177e4SLinus Torvalds 
2896bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
28971da177e4SLinus Torvalds 
2898bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2899bf4c6325SGustavo F. Padovan 
29001da177e4SLinus Torvalds 	/* Kill stalled connections */
2901bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2902bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
29036ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
29046ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
2905bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
29061da177e4SLinus Torvalds 		}
29071da177e4SLinus Torvalds 	}
2908bf4c6325SGustavo F. Padovan 
2909bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
29101da177e4SLinus Torvalds }
29111da177e4SLinus Torvalds 
29126039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
291373d80debSLuiz Augusto von Dentz 				      int *quote)
291473d80debSLuiz Augusto von Dentz {
291573d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
291673d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
2917abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
291873d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
291973d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
292073d80debSLuiz Augusto von Dentz 
292173d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
292273d80debSLuiz Augusto von Dentz 
2923bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2924bf4c6325SGustavo F. Padovan 
2925bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
292673d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
292773d80debSLuiz Augusto von Dentz 
292873d80debSLuiz Augusto von Dentz 		if (conn->type != type)
292973d80debSLuiz Augusto von Dentz 			continue;
293073d80debSLuiz Augusto von Dentz 
293173d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
293273d80debSLuiz Augusto von Dentz 			continue;
293373d80debSLuiz Augusto von Dentz 
293473d80debSLuiz Augusto von Dentz 		conn_num++;
293573d80debSLuiz Augusto von Dentz 
29368192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
293773d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
293873d80debSLuiz Augusto von Dentz 
293973d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
294073d80debSLuiz Augusto von Dentz 				continue;
294173d80debSLuiz Augusto von Dentz 
294273d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
294373d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
294473d80debSLuiz Augusto von Dentz 				continue;
294573d80debSLuiz Augusto von Dentz 
294673d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
294773d80debSLuiz Augusto von Dentz 				num = 0;
294873d80debSLuiz Augusto von Dentz 				min = ~0;
294973d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
295073d80debSLuiz Augusto von Dentz 			}
295173d80debSLuiz Augusto von Dentz 
295273d80debSLuiz Augusto von Dentz 			num++;
295373d80debSLuiz Augusto von Dentz 
295473d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
295573d80debSLuiz Augusto von Dentz 				min  = conn->sent;
295673d80debSLuiz Augusto von Dentz 				chan = tmp;
295773d80debSLuiz Augusto von Dentz 			}
295873d80debSLuiz Augusto von Dentz 		}
295973d80debSLuiz Augusto von Dentz 
296073d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
296173d80debSLuiz Augusto von Dentz 			break;
296273d80debSLuiz Augusto von Dentz 	}
296373d80debSLuiz Augusto von Dentz 
2964bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2965bf4c6325SGustavo F. Padovan 
296673d80debSLuiz Augusto von Dentz 	if (!chan)
296773d80debSLuiz Augusto von Dentz 		return NULL;
296873d80debSLuiz Augusto von Dentz 
296973d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
297073d80debSLuiz Augusto von Dentz 	case ACL_LINK:
297173d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
297273d80debSLuiz Augusto von Dentz 		break;
2973bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
2974bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
2975bd1eb66bSAndrei Emeltchenko 		break;
297673d80debSLuiz Augusto von Dentz 	case SCO_LINK:
297773d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
297873d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
297973d80debSLuiz Augusto von Dentz 		break;
298073d80debSLuiz Augusto von Dentz 	case LE_LINK:
298173d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
298273d80debSLuiz Augusto von Dentz 		break;
298373d80debSLuiz Augusto von Dentz 	default:
298473d80debSLuiz Augusto von Dentz 		cnt = 0;
298573d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
298673d80debSLuiz Augusto von Dentz 	}
298773d80debSLuiz Augusto von Dentz 
298873d80debSLuiz Augusto von Dentz 	q = cnt / num;
298973d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
299073d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
299173d80debSLuiz Augusto von Dentz 	return chan;
299273d80debSLuiz Augusto von Dentz }
299373d80debSLuiz Augusto von Dentz 
299402b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
299502b20f0bSLuiz Augusto von Dentz {
299602b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
299702b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
299802b20f0bSLuiz Augusto von Dentz 	int num = 0;
299902b20f0bSLuiz Augusto von Dentz 
300002b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
300102b20f0bSLuiz Augusto von Dentz 
3002bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3003bf4c6325SGustavo F. Padovan 
3004bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
300502b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
300602b20f0bSLuiz Augusto von Dentz 
300702b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
300802b20f0bSLuiz Augusto von Dentz 			continue;
300902b20f0bSLuiz Augusto von Dentz 
301002b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
301102b20f0bSLuiz Augusto von Dentz 			continue;
301202b20f0bSLuiz Augusto von Dentz 
301302b20f0bSLuiz Augusto von Dentz 		num++;
301402b20f0bSLuiz Augusto von Dentz 
30158192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
301602b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
301702b20f0bSLuiz Augusto von Dentz 
301802b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
301902b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
302002b20f0bSLuiz Augusto von Dentz 				continue;
302102b20f0bSLuiz Augusto von Dentz 			}
302202b20f0bSLuiz Augusto von Dentz 
302302b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
302402b20f0bSLuiz Augusto von Dentz 				continue;
302502b20f0bSLuiz Augusto von Dentz 
302602b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
302702b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
302802b20f0bSLuiz Augusto von Dentz 				continue;
302902b20f0bSLuiz Augusto von Dentz 
303002b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
303102b20f0bSLuiz Augusto von Dentz 
303202b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
303302b20f0bSLuiz Augusto von Dentz 			       skb->priority);
303402b20f0bSLuiz Augusto von Dentz 		}
303502b20f0bSLuiz Augusto von Dentz 
303602b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
303702b20f0bSLuiz Augusto von Dentz 			break;
303802b20f0bSLuiz Augusto von Dentz 	}
3039bf4c6325SGustavo F. Padovan 
3040bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3041bf4c6325SGustavo F. Padovan 
304202b20f0bSLuiz Augusto von Dentz }
304302b20f0bSLuiz Augusto von Dentz 
3044b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3045b71d385aSAndrei Emeltchenko {
3046b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3047b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3048b71d385aSAndrei Emeltchenko }
3049b71d385aSAndrei Emeltchenko 
30506039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
30511da177e4SLinus Torvalds {
30521da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
30531da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
30541da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
305563d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
30565f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
3057bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
30581da177e4SLinus Torvalds 	}
305963d2bc1bSAndrei Emeltchenko }
30601da177e4SLinus Torvalds 
30616039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
306263d2bc1bSAndrei Emeltchenko {
306363d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
306463d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
306563d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
306663d2bc1bSAndrei Emeltchenko 	int quote;
306763d2bc1bSAndrei Emeltchenko 
306863d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
306904837f64SMarcel Holtmann 
307073d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
307173d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3072ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3073ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
307473d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
307573d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
307673d80debSLuiz Augusto von Dentz 
3077ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3078ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3079ec1cce24SLuiz Augusto von Dentz 				break;
3080ec1cce24SLuiz Augusto von Dentz 
3081ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3082ec1cce24SLuiz Augusto von Dentz 
308373d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
308473d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
308504837f64SMarcel Holtmann 
30861da177e4SLinus Torvalds 			hci_send_frame(skb);
30871da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
30881da177e4SLinus Torvalds 
30891da177e4SLinus Torvalds 			hdev->acl_cnt--;
309073d80debSLuiz Augusto von Dentz 			chan->sent++;
309173d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
30921da177e4SLinus Torvalds 		}
30931da177e4SLinus Torvalds 	}
309402b20f0bSLuiz Augusto von Dentz 
309502b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
309602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
30971da177e4SLinus Torvalds }
30981da177e4SLinus Torvalds 
30996039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3100b71d385aSAndrei Emeltchenko {
310163d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3102b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3103b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3104b71d385aSAndrei Emeltchenko 	int quote;
3105bd1eb66bSAndrei Emeltchenko 	u8 type;
3106b71d385aSAndrei Emeltchenko 
310763d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
3108b71d385aSAndrei Emeltchenko 
3109bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3110bd1eb66bSAndrei Emeltchenko 
3111bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3112bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3113bd1eb66bSAndrei Emeltchenko 	else
3114bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3115bd1eb66bSAndrei Emeltchenko 
3116b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3117bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3118b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3119b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3120b71d385aSAndrei Emeltchenko 			int blocks;
3121b71d385aSAndrei Emeltchenko 
3122b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3123b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3124b71d385aSAndrei Emeltchenko 
3125b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3126b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3127b71d385aSAndrei Emeltchenko 				break;
3128b71d385aSAndrei Emeltchenko 
3129b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3130b71d385aSAndrei Emeltchenko 
3131b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3132b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3133b71d385aSAndrei Emeltchenko 				return;
3134b71d385aSAndrei Emeltchenko 
3135b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3136b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3137b71d385aSAndrei Emeltchenko 
3138b71d385aSAndrei Emeltchenko 			hci_send_frame(skb);
3139b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3140b71d385aSAndrei Emeltchenko 
3141b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3142b71d385aSAndrei Emeltchenko 			quote -= blocks;
3143b71d385aSAndrei Emeltchenko 
3144b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3145b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3146b71d385aSAndrei Emeltchenko 		}
3147b71d385aSAndrei Emeltchenko 	}
3148b71d385aSAndrei Emeltchenko 
3149b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3150bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3151b71d385aSAndrei Emeltchenko }
3152b71d385aSAndrei Emeltchenko 
31536039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3154b71d385aSAndrei Emeltchenko {
3155b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3156b71d385aSAndrei Emeltchenko 
3157bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3158bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
3159bd1eb66bSAndrei Emeltchenko 		return;
3160bd1eb66bSAndrei Emeltchenko 
3161bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3162bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3163b71d385aSAndrei Emeltchenko 		return;
3164b71d385aSAndrei Emeltchenko 
3165b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3166b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3167b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3168b71d385aSAndrei Emeltchenko 		break;
3169b71d385aSAndrei Emeltchenko 
3170b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3171b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3172b71d385aSAndrei Emeltchenko 		break;
3173b71d385aSAndrei Emeltchenko 	}
3174b71d385aSAndrei Emeltchenko }
3175b71d385aSAndrei Emeltchenko 
31761da177e4SLinus Torvalds /* Schedule SCO */
31776039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
31781da177e4SLinus Torvalds {
31791da177e4SLinus Torvalds 	struct hci_conn *conn;
31801da177e4SLinus Torvalds 	struct sk_buff *skb;
31811da177e4SLinus Torvalds 	int quote;
31821da177e4SLinus Torvalds 
31831da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
31841da177e4SLinus Torvalds 
318552087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
318652087a79SLuiz Augusto von Dentz 		return;
318752087a79SLuiz Augusto von Dentz 
31881da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
31891da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
31901da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
31911da177e4SLinus Torvalds 			hci_send_frame(skb);
31921da177e4SLinus Torvalds 
31931da177e4SLinus Torvalds 			conn->sent++;
31941da177e4SLinus Torvalds 			if (conn->sent == ~0)
31951da177e4SLinus Torvalds 				conn->sent = 0;
31961da177e4SLinus Torvalds 		}
31971da177e4SLinus Torvalds 	}
31981da177e4SLinus Torvalds }
31991da177e4SLinus Torvalds 
32006039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
3201b6a0dc82SMarcel Holtmann {
3202b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
3203b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
3204b6a0dc82SMarcel Holtmann 	int quote;
3205b6a0dc82SMarcel Holtmann 
3206b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
3207b6a0dc82SMarcel Holtmann 
320852087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
320952087a79SLuiz Augusto von Dentz 		return;
321052087a79SLuiz Augusto von Dentz 
32118fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
32128fc9ced3SGustavo Padovan 						     &quote))) {
3213b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
3214b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
3215b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
3216b6a0dc82SMarcel Holtmann 
3217b6a0dc82SMarcel Holtmann 			conn->sent++;
3218b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
3219b6a0dc82SMarcel Holtmann 				conn->sent = 0;
3220b6a0dc82SMarcel Holtmann 		}
3221b6a0dc82SMarcel Holtmann 	}
3222b6a0dc82SMarcel Holtmann }
3223b6a0dc82SMarcel Holtmann 
32246039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
32256ed58ec5SVille Tervo {
322673d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
32276ed58ec5SVille Tervo 	struct sk_buff *skb;
322802b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
32296ed58ec5SVille Tervo 
32306ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
32316ed58ec5SVille Tervo 
323252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
323352087a79SLuiz Augusto von Dentz 		return;
323452087a79SLuiz Augusto von Dentz 
32356ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
32366ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
32376ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
3238bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
32396ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
3240bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
32416ed58ec5SVille Tervo 	}
32426ed58ec5SVille Tervo 
32436ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
324402b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
324573d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3246ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3247ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
324873d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
324973d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
32506ed58ec5SVille Tervo 
3251ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3252ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3253ec1cce24SLuiz Augusto von Dentz 				break;
3254ec1cce24SLuiz Augusto von Dentz 
3255ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3256ec1cce24SLuiz Augusto von Dentz 
32576ed58ec5SVille Tervo 			hci_send_frame(skb);
32586ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
32596ed58ec5SVille Tervo 
32606ed58ec5SVille Tervo 			cnt--;
326173d80debSLuiz Augusto von Dentz 			chan->sent++;
326273d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
32636ed58ec5SVille Tervo 		}
32646ed58ec5SVille Tervo 	}
326573d80debSLuiz Augusto von Dentz 
32666ed58ec5SVille Tervo 	if (hdev->le_pkts)
32676ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
32686ed58ec5SVille Tervo 	else
32696ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
327002b20f0bSLuiz Augusto von Dentz 
327102b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
327202b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
32736ed58ec5SVille Tervo }
32746ed58ec5SVille Tervo 
32753eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
32761da177e4SLinus Torvalds {
32773eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
32781da177e4SLinus Torvalds 	struct sk_buff *skb;
32791da177e4SLinus Torvalds 
32806ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
32816ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
32821da177e4SLinus Torvalds 
32831da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
32841da177e4SLinus Torvalds 
32851da177e4SLinus Torvalds 	hci_sched_acl(hdev);
32861da177e4SLinus Torvalds 
32871da177e4SLinus Torvalds 	hci_sched_sco(hdev);
32881da177e4SLinus Torvalds 
3289b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
3290b6a0dc82SMarcel Holtmann 
32916ed58ec5SVille Tervo 	hci_sched_le(hdev);
32926ed58ec5SVille Tervo 
32931da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
32941da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
32951da177e4SLinus Torvalds 		hci_send_frame(skb);
32961da177e4SLinus Torvalds }
32971da177e4SLinus Torvalds 
329825985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
32991da177e4SLinus Torvalds 
33001da177e4SLinus Torvalds /* ACL data packet */
33016039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
33021da177e4SLinus Torvalds {
33031da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
33041da177e4SLinus Torvalds 	struct hci_conn *conn;
33051da177e4SLinus Torvalds 	__u16 handle, flags;
33061da177e4SLinus Torvalds 
33071da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
33081da177e4SLinus Torvalds 
33091da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
33101da177e4SLinus Torvalds 	flags  = hci_flags(handle);
33111da177e4SLinus Torvalds 	handle = hci_handle(handle);
33121da177e4SLinus Torvalds 
3313f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3314a8c5fb1aSGustavo Padovan 	       handle, flags);
33151da177e4SLinus Torvalds 
33161da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
33171da177e4SLinus Torvalds 
33181da177e4SLinus Torvalds 	hci_dev_lock(hdev);
33191da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
33201da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
33211da177e4SLinus Torvalds 
33221da177e4SLinus Torvalds 	if (conn) {
332365983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
332404837f64SMarcel Holtmann 
33251da177e4SLinus Torvalds 		/* Send to upper protocol */
3326686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
33271da177e4SLinus Torvalds 		return;
33281da177e4SLinus Torvalds 	} else {
33291da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
33301da177e4SLinus Torvalds 		       hdev->name, handle);
33311da177e4SLinus Torvalds 	}
33321da177e4SLinus Torvalds 
33331da177e4SLinus Torvalds 	kfree_skb(skb);
33341da177e4SLinus Torvalds }
33351da177e4SLinus Torvalds 
33361da177e4SLinus Torvalds /* SCO data packet */
33376039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
33381da177e4SLinus Torvalds {
33391da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
33401da177e4SLinus Torvalds 	struct hci_conn *conn;
33411da177e4SLinus Torvalds 	__u16 handle;
33421da177e4SLinus Torvalds 
33431da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
33441da177e4SLinus Torvalds 
33451da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
33461da177e4SLinus Torvalds 
3347f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
33481da177e4SLinus Torvalds 
33491da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
33501da177e4SLinus Torvalds 
33511da177e4SLinus Torvalds 	hci_dev_lock(hdev);
33521da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
33531da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
33541da177e4SLinus Torvalds 
33551da177e4SLinus Torvalds 	if (conn) {
33561da177e4SLinus Torvalds 		/* Send to upper protocol */
3357686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
33581da177e4SLinus Torvalds 		return;
33591da177e4SLinus Torvalds 	} else {
33601da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
33611da177e4SLinus Torvalds 		       hdev->name, handle);
33621da177e4SLinus Torvalds 	}
33631da177e4SLinus Torvalds 
33641da177e4SLinus Torvalds 	kfree_skb(skb);
33651da177e4SLinus Torvalds }
33661da177e4SLinus Torvalds 
33679238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
33689238f36aSJohan Hedberg {
33699238f36aSJohan Hedberg 	struct sk_buff *skb;
33709238f36aSJohan Hedberg 
33719238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
33729238f36aSJohan Hedberg 	if (!skb)
33739238f36aSJohan Hedberg 		return true;
33749238f36aSJohan Hedberg 
33759238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
33769238f36aSJohan Hedberg }
33779238f36aSJohan Hedberg 
337842c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
337942c6b129SJohan Hedberg {
338042c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
338142c6b129SJohan Hedberg 	struct sk_buff *skb;
338242c6b129SJohan Hedberg 	u16 opcode;
338342c6b129SJohan Hedberg 
338442c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
338542c6b129SJohan Hedberg 		return;
338642c6b129SJohan Hedberg 
338742c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
338842c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
338942c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
339042c6b129SJohan Hedberg 		return;
339142c6b129SJohan Hedberg 
339242c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
339342c6b129SJohan Hedberg 	if (!skb)
339442c6b129SJohan Hedberg 		return;
339542c6b129SJohan Hedberg 
339642c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
339742c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
339842c6b129SJohan Hedberg }
339942c6b129SJohan Hedberg 
34009238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
34019238f36aSJohan Hedberg {
34029238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
34039238f36aSJohan Hedberg 	struct sk_buff *skb;
34049238f36aSJohan Hedberg 	unsigned long flags;
34059238f36aSJohan Hedberg 
34069238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
34079238f36aSJohan Hedberg 
340842c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
340942c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
34109238f36aSJohan Hedberg 	 */
341142c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
341242c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
341342c6b129SJohan Hedberg 		 * reset complete event during init and any pending
341442c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
341542c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
341642c6b129SJohan Hedberg 		 * command.
341742c6b129SJohan Hedberg 		 */
341842c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
341942c6b129SJohan Hedberg 			hci_resend_last(hdev);
342042c6b129SJohan Hedberg 
34219238f36aSJohan Hedberg 		return;
342242c6b129SJohan Hedberg 	}
34239238f36aSJohan Hedberg 
34249238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
34259238f36aSJohan Hedberg 	 * this request the request is not yet complete.
34269238f36aSJohan Hedberg 	 */
34279238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
34289238f36aSJohan Hedberg 		return;
34299238f36aSJohan Hedberg 
34309238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
34319238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
34329238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
34339238f36aSJohan Hedberg 	 */
34349238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
34359238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
34369238f36aSJohan Hedberg 		if (req_complete)
34379238f36aSJohan Hedberg 			goto call_complete;
34389238f36aSJohan Hedberg 	}
34399238f36aSJohan Hedberg 
34409238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
34419238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
34429238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
34439238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
34449238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
34459238f36aSJohan Hedberg 			break;
34469238f36aSJohan Hedberg 		}
34479238f36aSJohan Hedberg 
34489238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
34499238f36aSJohan Hedberg 		kfree_skb(skb);
34509238f36aSJohan Hedberg 	}
34519238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
34529238f36aSJohan Hedberg 
34539238f36aSJohan Hedberg call_complete:
34549238f36aSJohan Hedberg 	if (req_complete)
34559238f36aSJohan Hedberg 		req_complete(hdev, status);
34569238f36aSJohan Hedberg }
34579238f36aSJohan Hedberg 
3458b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
34591da177e4SLinus Torvalds {
3460b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
34611da177e4SLinus Torvalds 	struct sk_buff *skb;
34621da177e4SLinus Torvalds 
34631da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
34641da177e4SLinus Torvalds 
34651da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
3466cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
3467cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
3468cd82e61cSMarcel Holtmann 
34691da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
34701da177e4SLinus Torvalds 			/* Send copy to the sockets */
3471470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
34721da177e4SLinus Torvalds 		}
34731da177e4SLinus Torvalds 
34741da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
34751da177e4SLinus Torvalds 			kfree_skb(skb);
34761da177e4SLinus Torvalds 			continue;
34771da177e4SLinus Torvalds 		}
34781da177e4SLinus Torvalds 
34791da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
34801da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
34810d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
34821da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
34831da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
34841da177e4SLinus Torvalds 				kfree_skb(skb);
34851da177e4SLinus Torvalds 				continue;
34863ff50b79SStephen Hemminger 			}
34871da177e4SLinus Torvalds 		}
34881da177e4SLinus Torvalds 
34891da177e4SLinus Torvalds 		/* Process frame */
34900d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
34911da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
3492b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
34931da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
34941da177e4SLinus Torvalds 			break;
34951da177e4SLinus Torvalds 
34961da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
34971da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
34981da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
34991da177e4SLinus Torvalds 			break;
35001da177e4SLinus Torvalds 
35011da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
35021da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
35031da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
35041da177e4SLinus Torvalds 			break;
35051da177e4SLinus Torvalds 
35061da177e4SLinus Torvalds 		default:
35071da177e4SLinus Torvalds 			kfree_skb(skb);
35081da177e4SLinus Torvalds 			break;
35091da177e4SLinus Torvalds 		}
35101da177e4SLinus Torvalds 	}
35111da177e4SLinus Torvalds }
35121da177e4SLinus Torvalds 
3513c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
35141da177e4SLinus Torvalds {
3515c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
35161da177e4SLinus Torvalds 	struct sk_buff *skb;
35171da177e4SLinus Torvalds 
35182104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
35192104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
35201da177e4SLinus Torvalds 
35211da177e4SLinus Torvalds 	/* Send queued commands */
35225a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
35235a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
35245a08ecceSAndrei Emeltchenko 		if (!skb)
35255a08ecceSAndrei Emeltchenko 			return;
35265a08ecceSAndrei Emeltchenko 
35271da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
35281da177e4SLinus Torvalds 
352970f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
353070f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
35311da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
35321da177e4SLinus Torvalds 			hci_send_frame(skb);
35337bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
35347bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
35357bdb8a5cSSzymon Janc 			else
35366bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
35375f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
35381da177e4SLinus Torvalds 		} else {
35391da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
3540c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
35411da177e4SLinus Torvalds 		}
35421da177e4SLinus Torvalds 	}
35431da177e4SLinus Torvalds }
35442519a1fcSAndre Guedes 
35452519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
35462519a1fcSAndre Guedes {
35472519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
35482519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
35492519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
35502519a1fcSAndre Guedes 
35512519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
35522519a1fcSAndre Guedes 
35532519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
35542519a1fcSAndre Guedes 		return -EINPROGRESS;
35552519a1fcSAndre Guedes 
35564663262cSJohan Hedberg 	inquiry_cache_flush(hdev);
35574663262cSJohan Hedberg 
35582519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
35592519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
35602519a1fcSAndre Guedes 	cp.length  = length;
35612519a1fcSAndre Guedes 
35622519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
35632519a1fcSAndre Guedes }
3564023d5049SAndre Guedes 
3565023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
3566023d5049SAndre Guedes {
3567023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
3568023d5049SAndre Guedes 
3569023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
35707537e5c3SAndre Guedes 		return -EALREADY;
3571023d5049SAndre Guedes 
3572023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
3573023d5049SAndre Guedes }
357431f7956cSAndre Guedes 
357531f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type)
357631f7956cSAndre Guedes {
357731f7956cSAndre Guedes 	switch (bdaddr_type) {
357831f7956cSAndre Guedes 	case BDADDR_LE_PUBLIC:
357931f7956cSAndre Guedes 		return ADDR_LE_DEV_PUBLIC;
358031f7956cSAndre Guedes 
358131f7956cSAndre Guedes 	default:
358231f7956cSAndre Guedes 		/* Fallback to LE Random address type */
358331f7956cSAndre Guedes 		return ADDR_LE_DEV_RANDOM;
358431f7956cSAndre Guedes 	}
358531f7956cSAndre Guedes }
3586