xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 382b0c39)
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 
821da177e4SLinus Torvalds /* Execute request and wait for completion. */
8301178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
8442c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
8542c6b129SJohan Hedberg 				      unsigned long opt),
861da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
871da177e4SLinus Torvalds {
8842c6b129SJohan Hedberg 	struct hci_request req;
891da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
901da177e4SLinus Torvalds 	int err = 0;
911da177e4SLinus Torvalds 
921da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
931da177e4SLinus Torvalds 
9442c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
9542c6b129SJohan Hedberg 
961da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
971da177e4SLinus Torvalds 
9842c6b129SJohan Hedberg 	func(&req, opt);
9953cce22dSJohan Hedberg 
10042c6b129SJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
10142c6b129SJohan Hedberg 	if (err < 0) {
10253cce22dSJohan Hedberg 		hdev->req_status = 0;
10342c6b129SJohan Hedberg 		/* req_run will fail if the request did not add any
10442c6b129SJohan Hedberg 		 * commands to the queue, something that can happen when
10542c6b129SJohan Hedberg 		 * a request with conditionals doesn't trigger any
10642c6b129SJohan Hedberg 		 * commands to be sent. This is normal behavior and
10742c6b129SJohan Hedberg 		 * should not trigger an error return.
10842c6b129SJohan Hedberg 		 */
10942c6b129SJohan Hedberg 		return 0;
11053cce22dSJohan Hedberg 	}
11153cce22dSJohan Hedberg 
112bc4445c7SAndre Guedes 	add_wait_queue(&hdev->req_wait_q, &wait);
113bc4445c7SAndre Guedes 	set_current_state(TASK_INTERRUPTIBLE);
114bc4445c7SAndre Guedes 
1151da177e4SLinus Torvalds 	schedule_timeout(timeout);
1161da177e4SLinus Torvalds 
1171da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
1181da177e4SLinus Torvalds 
1191da177e4SLinus Torvalds 	if (signal_pending(current))
1201da177e4SLinus Torvalds 		return -EINTR;
1211da177e4SLinus Torvalds 
1221da177e4SLinus Torvalds 	switch (hdev->req_status) {
1231da177e4SLinus Torvalds 	case HCI_REQ_DONE:
124e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
1251da177e4SLinus Torvalds 		break;
1261da177e4SLinus Torvalds 
1271da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
1281da177e4SLinus Torvalds 		err = -hdev->req_result;
1291da177e4SLinus Torvalds 		break;
1301da177e4SLinus Torvalds 
1311da177e4SLinus Torvalds 	default:
1321da177e4SLinus Torvalds 		err = -ETIMEDOUT;
1331da177e4SLinus Torvalds 		break;
1343ff50b79SStephen Hemminger 	}
1351da177e4SLinus Torvalds 
136a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
1371da177e4SLinus Torvalds 
1381da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
1391da177e4SLinus Torvalds 
1401da177e4SLinus Torvalds 	return err;
1411da177e4SLinus Torvalds }
1421da177e4SLinus Torvalds 
14301178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
14442c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
14542c6b129SJohan Hedberg 				    unsigned long opt),
1461da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
1471da177e4SLinus Torvalds {
1481da177e4SLinus Torvalds 	int ret;
1491da177e4SLinus Torvalds 
1507c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
1517c6a329eSMarcel Holtmann 		return -ENETDOWN;
1527c6a329eSMarcel Holtmann 
1531da177e4SLinus Torvalds 	/* Serialize all requests */
1541da177e4SLinus Torvalds 	hci_req_lock(hdev);
15501178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
1561da177e4SLinus Torvalds 	hci_req_unlock(hdev);
1571da177e4SLinus Torvalds 
1581da177e4SLinus Torvalds 	return ret;
1591da177e4SLinus Torvalds }
1601da177e4SLinus Torvalds 
16142c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
1621da177e4SLinus Torvalds {
16342c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
1641da177e4SLinus Torvalds 
1651da177e4SLinus Torvalds 	/* Reset device */
16642c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
16742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
1681da177e4SLinus Torvalds }
1691da177e4SLinus Torvalds 
17042c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
1711da177e4SLinus Torvalds {
17242c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
1732455a3eaSAndrei Emeltchenko 
1741da177e4SLinus Torvalds 	/* Read Local Supported Features */
17542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
1761da177e4SLinus Torvalds 
1771143e5a6SMarcel Holtmann 	/* Read Local Version */
17842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
1792177bab5SJohan Hedberg 
1802177bab5SJohan Hedberg 	/* Read BD Address */
18142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
1821da177e4SLinus Torvalds }
1831da177e4SLinus Torvalds 
18442c6b129SJohan Hedberg static void amp_init(struct hci_request *req)
185e61ef499SAndrei Emeltchenko {
18642c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
1872455a3eaSAndrei Emeltchenko 
188e61ef499SAndrei Emeltchenko 	/* Read Local Version */
18942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
1906bcbc489SAndrei Emeltchenko 
1916bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
19242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
193e71dfabaSAndrei Emeltchenko 
194e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
19542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
196e61ef499SAndrei Emeltchenko }
197e61ef499SAndrei Emeltchenko 
19842c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
199e61ef499SAndrei Emeltchenko {
20042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
20142c6b129SJohan Hedberg 	struct hci_request init_req;
202e61ef499SAndrei Emeltchenko 	struct sk_buff *skb;
203e61ef499SAndrei Emeltchenko 
204e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
205e61ef499SAndrei Emeltchenko 
206e61ef499SAndrei Emeltchenko 	/* Driver initialization */
207e61ef499SAndrei Emeltchenko 
20842c6b129SJohan Hedberg 	hci_req_init(&init_req, hdev);
20942c6b129SJohan Hedberg 
210e61ef499SAndrei Emeltchenko 	/* Special commands */
211e61ef499SAndrei Emeltchenko 	while ((skb = skb_dequeue(&hdev->driver_init))) {
212e61ef499SAndrei Emeltchenko 		bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
213e61ef499SAndrei Emeltchenko 		skb->dev = (void *) hdev;
214e61ef499SAndrei Emeltchenko 
21542c6b129SJohan Hedberg 		if (skb_queue_empty(&init_req.cmd_q))
21642c6b129SJohan Hedberg 			bt_cb(skb)->req.start = true;
21742c6b129SJohan Hedberg 
21842c6b129SJohan Hedberg 		skb_queue_tail(&init_req.cmd_q, skb);
219e61ef499SAndrei Emeltchenko 	}
220e61ef499SAndrei Emeltchenko 	skb_queue_purge(&hdev->driver_init);
221e61ef499SAndrei Emeltchenko 
22242c6b129SJohan Hedberg 	hci_req_run(&init_req, NULL);
22342c6b129SJohan Hedberg 
22411778716SAndrei Emeltchenko 	/* Reset */
22511778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
22642c6b129SJohan Hedberg 		hci_reset_req(req, 0);
22711778716SAndrei Emeltchenko 
228e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
229e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
23042c6b129SJohan Hedberg 		bredr_init(req);
231e61ef499SAndrei Emeltchenko 		break;
232e61ef499SAndrei Emeltchenko 
233e61ef499SAndrei Emeltchenko 	case HCI_AMP:
23442c6b129SJohan Hedberg 		amp_init(req);
235e61ef499SAndrei Emeltchenko 		break;
236e61ef499SAndrei Emeltchenko 
237e61ef499SAndrei Emeltchenko 	default:
238e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
239e61ef499SAndrei Emeltchenko 		break;
240e61ef499SAndrei Emeltchenko 	}
241e61ef499SAndrei Emeltchenko }
242e61ef499SAndrei Emeltchenko 
24342c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
2442177bab5SJohan Hedberg {
2452177bab5SJohan Hedberg 	struct hci_cp_delete_stored_link_key cp;
2462177bab5SJohan Hedberg 	__le16 param;
2472177bab5SJohan Hedberg 	__u8 flt_type;
2482177bab5SJohan Hedberg 
2492177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
25042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
2512177bab5SJohan Hedberg 
2522177bab5SJohan Hedberg 	/* Read Class of Device */
25342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
2542177bab5SJohan Hedberg 
2552177bab5SJohan Hedberg 	/* Read Local Name */
25642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
2572177bab5SJohan Hedberg 
2582177bab5SJohan Hedberg 	/* Read Voice Setting */
25942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
2602177bab5SJohan Hedberg 
2612177bab5SJohan Hedberg 	/* Clear Event Filters */
2622177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
26342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
2642177bab5SJohan Hedberg 
2652177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
2662177bab5SJohan Hedberg 	param = __constant_cpu_to_le16(0x7d00);
26742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
2682177bab5SJohan Hedberg 
2692177bab5SJohan Hedberg 	bacpy(&cp.bdaddr, BDADDR_ANY);
2702177bab5SJohan Hedberg 	cp.delete_all = 0x01;
27142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
2722177bab5SJohan Hedberg }
2732177bab5SJohan Hedberg 
27442c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
2752177bab5SJohan Hedberg {
2762177bab5SJohan Hedberg 	/* Read LE Buffer Size */
27742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
2782177bab5SJohan Hedberg 
2792177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
28042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
2812177bab5SJohan Hedberg 
2822177bab5SJohan Hedberg 	/* Read LE Advertising Channel TX Power */
28342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
2842177bab5SJohan Hedberg 
2852177bab5SJohan Hedberg 	/* Read LE White List Size */
28642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
2872177bab5SJohan Hedberg 
2882177bab5SJohan Hedberg 	/* Read LE Supported States */
28942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
2902177bab5SJohan Hedberg }
2912177bab5SJohan Hedberg 
2922177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
2932177bab5SJohan Hedberg {
2942177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
2952177bab5SJohan Hedberg 		return 0x02;
2962177bab5SJohan Hedberg 
2972177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
2982177bab5SJohan Hedberg 		return 0x01;
2992177bab5SJohan Hedberg 
3002177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
3012177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
3022177bab5SJohan Hedberg 		return 0x01;
3032177bab5SJohan Hedberg 
3042177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
3052177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
3062177bab5SJohan Hedberg 			return 0x01;
3072177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
3082177bab5SJohan Hedberg 			return 0x01;
3092177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
3102177bab5SJohan Hedberg 			return 0x01;
3112177bab5SJohan Hedberg 	}
3122177bab5SJohan Hedberg 
3132177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
3142177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
3152177bab5SJohan Hedberg 		return 0x01;
3162177bab5SJohan Hedberg 
3172177bab5SJohan Hedberg 	return 0x00;
3182177bab5SJohan Hedberg }
3192177bab5SJohan Hedberg 
32042c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
3212177bab5SJohan Hedberg {
3222177bab5SJohan Hedberg 	u8 mode;
3232177bab5SJohan Hedberg 
32442c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
3252177bab5SJohan Hedberg 
32642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
3272177bab5SJohan Hedberg }
3282177bab5SJohan Hedberg 
32942c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
3302177bab5SJohan Hedberg {
33142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
33242c6b129SJohan Hedberg 
3332177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
3342177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
3352177bab5SJohan Hedberg 	 * command otherwise.
3362177bab5SJohan Hedberg 	 */
3372177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
3382177bab5SJohan Hedberg 
3392177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
3402177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
3412177bab5SJohan Hedberg 	 */
3422177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
3432177bab5SJohan Hedberg 		return;
3442177bab5SJohan Hedberg 
3452177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
3462177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
3472177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
3482177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
3492177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
3502177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
3512177bab5SJohan Hedberg 	}
3522177bab5SJohan Hedberg 
3532177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
3542177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
3552177bab5SJohan Hedberg 
3562177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
3572177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
3582177bab5SJohan Hedberg 
3592177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
3602177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
3612177bab5SJohan Hedberg 
3622177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
3632177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
3642177bab5SJohan Hedberg 
3652177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
3662177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
3672177bab5SJohan Hedberg 
3682177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
3692177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
3702177bab5SJohan Hedberg 
3712177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
3722177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
3732177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
3742177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
3752177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
3762177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
3772177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
3782177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
3792177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
3802177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
3812177bab5SJohan Hedberg 					 * Features Notification
3822177bab5SJohan Hedberg 					 */
3832177bab5SJohan Hedberg 	}
3842177bab5SJohan Hedberg 
3852177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
3862177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
3872177bab5SJohan Hedberg 
38842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
3892177bab5SJohan Hedberg 
3902177bab5SJohan Hedberg 	if (lmp_le_capable(hdev)) {
3912177bab5SJohan Hedberg 		memset(events, 0, sizeof(events));
3922177bab5SJohan Hedberg 		events[0] = 0x1f;
39342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
3942177bab5SJohan Hedberg 			    sizeof(events), events);
3952177bab5SJohan Hedberg 	}
3962177bab5SJohan Hedberg }
3972177bab5SJohan Hedberg 
39842c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
3992177bab5SJohan Hedberg {
40042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
40142c6b129SJohan Hedberg 
4022177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
40342c6b129SJohan Hedberg 		bredr_setup(req);
4042177bab5SJohan Hedberg 
4052177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
40642c6b129SJohan Hedberg 		le_setup(req);
4072177bab5SJohan Hedberg 
40842c6b129SJohan Hedberg 	hci_setup_event_mask(req);
4092177bab5SJohan Hedberg 
4102177bab5SJohan Hedberg 	if (hdev->hci_ver > BLUETOOTH_VER_1_1)
41142c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
4122177bab5SJohan Hedberg 
4132177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
4142177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
4152177bab5SJohan Hedberg 			u8 mode = 0x01;
41642c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
4172177bab5SJohan Hedberg 				    sizeof(mode), &mode);
4182177bab5SJohan Hedberg 		} else {
4192177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
4202177bab5SJohan Hedberg 
4212177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
4222177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
4232177bab5SJohan Hedberg 
42442c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
4252177bab5SJohan Hedberg 		}
4262177bab5SJohan Hedberg 	}
4272177bab5SJohan Hedberg 
4282177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
42942c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
4302177bab5SJohan Hedberg 
4312177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
43242c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
4332177bab5SJohan Hedberg 
4342177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
4352177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
4362177bab5SJohan Hedberg 
4372177bab5SJohan Hedberg 		cp.page = 0x01;
43842c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
43942c6b129SJohan Hedberg 			    sizeof(cp), &cp);
4402177bab5SJohan Hedberg 	}
4412177bab5SJohan Hedberg 
4422177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
4432177bab5SJohan Hedberg 		u8 enable = 1;
44442c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
4452177bab5SJohan Hedberg 			    &enable);
4462177bab5SJohan Hedberg 	}
4472177bab5SJohan Hedberg }
4482177bab5SJohan Hedberg 
44942c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
4502177bab5SJohan Hedberg {
45142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
4522177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
4532177bab5SJohan Hedberg 	u16 link_policy = 0;
4542177bab5SJohan Hedberg 
4552177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
4562177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
4572177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
4582177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
4592177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
4602177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
4612177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
4622177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
4632177bab5SJohan Hedberg 
4642177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
46542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
4662177bab5SJohan Hedberg }
4672177bab5SJohan Hedberg 
46842c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
4692177bab5SJohan Hedberg {
47042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
4712177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
4722177bab5SJohan Hedberg 
4732177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
4742177bab5SJohan Hedberg 
4752177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
4762177bab5SJohan Hedberg 		cp.le = 0x01;
4772177bab5SJohan Hedberg 		cp.simul = lmp_le_br_capable(hdev);
4782177bab5SJohan Hedberg 	}
4792177bab5SJohan Hedberg 
4802177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
48142c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
4822177bab5SJohan Hedberg 			    &cp);
4832177bab5SJohan Hedberg }
4842177bab5SJohan Hedberg 
48542c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
4862177bab5SJohan Hedberg {
48742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
48842c6b129SJohan Hedberg 
4892177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
49042c6b129SJohan Hedberg 		hci_setup_link_policy(req);
4912177bab5SJohan Hedberg 
4922177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
49342c6b129SJohan Hedberg 		hci_set_le_support(req);
4942177bab5SJohan Hedberg }
4952177bab5SJohan Hedberg 
4962177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
4972177bab5SJohan Hedberg {
4982177bab5SJohan Hedberg 	int err;
4992177bab5SJohan Hedberg 
5002177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
5012177bab5SJohan Hedberg 	if (err < 0)
5022177bab5SJohan Hedberg 		return err;
5032177bab5SJohan Hedberg 
5042177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
5052177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
5062177bab5SJohan Hedberg 	 * first stage init.
5072177bab5SJohan Hedberg 	 */
5082177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
5092177bab5SJohan Hedberg 		return 0;
5102177bab5SJohan Hedberg 
5112177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
5122177bab5SJohan Hedberg 	if (err < 0)
5132177bab5SJohan Hedberg 		return err;
5142177bab5SJohan Hedberg 
5152177bab5SJohan Hedberg 	return __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
5162177bab5SJohan Hedberg }
5172177bab5SJohan Hedberg 
51842c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
5191da177e4SLinus Torvalds {
5201da177e4SLinus Torvalds 	__u8 scan = opt;
5211da177e4SLinus Torvalds 
52242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
5231da177e4SLinus Torvalds 
5241da177e4SLinus Torvalds 	/* Inquiry and Page scans */
52542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
5261da177e4SLinus Torvalds }
5271da177e4SLinus Torvalds 
52842c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
5291da177e4SLinus Torvalds {
5301da177e4SLinus Torvalds 	__u8 auth = opt;
5311da177e4SLinus Torvalds 
53242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
5331da177e4SLinus Torvalds 
5341da177e4SLinus Torvalds 	/* Authentication */
53542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
5361da177e4SLinus Torvalds }
5371da177e4SLinus Torvalds 
53842c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
5391da177e4SLinus Torvalds {
5401da177e4SLinus Torvalds 	__u8 encrypt = opt;
5411da177e4SLinus Torvalds 
54242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
5431da177e4SLinus Torvalds 
544e4e8e37cSMarcel Holtmann 	/* Encryption */
54542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
5461da177e4SLinus Torvalds }
5471da177e4SLinus Torvalds 
54842c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
549e4e8e37cSMarcel Holtmann {
550e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
551e4e8e37cSMarcel Holtmann 
55242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
553e4e8e37cSMarcel Holtmann 
554e4e8e37cSMarcel Holtmann 	/* Default link policy */
55542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
556e4e8e37cSMarcel Holtmann }
557e4e8e37cSMarcel Holtmann 
5581da177e4SLinus Torvalds /* Get HCI device by index.
5591da177e4SLinus Torvalds  * Device is held on return. */
5601da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
5611da177e4SLinus Torvalds {
5628035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
5631da177e4SLinus Torvalds 
5641da177e4SLinus Torvalds 	BT_DBG("%d", index);
5651da177e4SLinus Torvalds 
5661da177e4SLinus Torvalds 	if (index < 0)
5671da177e4SLinus Torvalds 		return NULL;
5681da177e4SLinus Torvalds 
5691da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
5708035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
5711da177e4SLinus Torvalds 		if (d->id == index) {
5721da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
5731da177e4SLinus Torvalds 			break;
5741da177e4SLinus Torvalds 		}
5751da177e4SLinus Torvalds 	}
5761da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
5771da177e4SLinus Torvalds 	return hdev;
5781da177e4SLinus Torvalds }
5791da177e4SLinus Torvalds 
5801da177e4SLinus Torvalds /* ---- Inquiry support ---- */
581ff9ef578SJohan Hedberg 
58230dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
58330dc78e1SJohan Hedberg {
58430dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
58530dc78e1SJohan Hedberg 
5866fbe195dSAndre Guedes 	switch (discov->state) {
587343f935bSAndre Guedes 	case DISCOVERY_FINDING:
5886fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
58930dc78e1SJohan Hedberg 		return true;
59030dc78e1SJohan Hedberg 
5916fbe195dSAndre Guedes 	default:
59230dc78e1SJohan Hedberg 		return false;
59330dc78e1SJohan Hedberg 	}
5946fbe195dSAndre Guedes }
59530dc78e1SJohan Hedberg 
596ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
597ff9ef578SJohan Hedberg {
598ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
599ff9ef578SJohan Hedberg 
600ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
601ff9ef578SJohan Hedberg 		return;
602ff9ef578SJohan Hedberg 
603ff9ef578SJohan Hedberg 	switch (state) {
604ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
6057b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
606ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
607ff9ef578SJohan Hedberg 		break;
608ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
609ff9ef578SJohan Hedberg 		break;
610343f935bSAndre Guedes 	case DISCOVERY_FINDING:
611ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
612ff9ef578SJohan Hedberg 		break;
61330dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
61430dc78e1SJohan Hedberg 		break;
615ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
616ff9ef578SJohan Hedberg 		break;
617ff9ef578SJohan Hedberg 	}
618ff9ef578SJohan Hedberg 
619ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
620ff9ef578SJohan Hedberg }
621ff9ef578SJohan Hedberg 
6221da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
6231da177e4SLinus Torvalds {
62430883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
625b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
6261da177e4SLinus Torvalds 
627561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
628561aafbcSJohan Hedberg 		list_del(&p->all);
629b57c1a56SJohan Hedberg 		kfree(p);
6301da177e4SLinus Torvalds 	}
631561aafbcSJohan Hedberg 
632561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
633561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
6341da177e4SLinus Torvalds }
6351da177e4SLinus Torvalds 
636a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
637a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
6381da177e4SLinus Torvalds {
63930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
6401da177e4SLinus Torvalds 	struct inquiry_entry *e;
6411da177e4SLinus Torvalds 
6426ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
6431da177e4SLinus Torvalds 
644561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
6451da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
6461da177e4SLinus Torvalds 			return e;
6471da177e4SLinus Torvalds 	}
6481da177e4SLinus Torvalds 
649b57c1a56SJohan Hedberg 	return NULL;
650b57c1a56SJohan Hedberg }
651b57c1a56SJohan Hedberg 
652561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
653561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
654561aafbcSJohan Hedberg {
65530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
656561aafbcSJohan Hedberg 	struct inquiry_entry *e;
657561aafbcSJohan Hedberg 
6586ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
659561aafbcSJohan Hedberg 
660561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
661561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
662561aafbcSJohan Hedberg 			return e;
663561aafbcSJohan Hedberg 	}
664561aafbcSJohan Hedberg 
665561aafbcSJohan Hedberg 	return NULL;
666561aafbcSJohan Hedberg }
667561aafbcSJohan Hedberg 
66830dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
66930dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
67030dc78e1SJohan Hedberg 						       int state)
67130dc78e1SJohan Hedberg {
67230dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
67330dc78e1SJohan Hedberg 	struct inquiry_entry *e;
67430dc78e1SJohan Hedberg 
6756ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
67630dc78e1SJohan Hedberg 
67730dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
67830dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
67930dc78e1SJohan Hedberg 			return e;
68030dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
68130dc78e1SJohan Hedberg 			return e;
68230dc78e1SJohan Hedberg 	}
68330dc78e1SJohan Hedberg 
68430dc78e1SJohan Hedberg 	return NULL;
68530dc78e1SJohan Hedberg }
68630dc78e1SJohan Hedberg 
687a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
688a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
689a3d4e20aSJohan Hedberg {
690a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
691a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
692a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
693a3d4e20aSJohan Hedberg 
694a3d4e20aSJohan Hedberg 	list_del(&ie->list);
695a3d4e20aSJohan Hedberg 
696a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
697a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
698a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
699a3d4e20aSJohan Hedberg 			break;
700a3d4e20aSJohan Hedberg 		pos = &p->list;
701a3d4e20aSJohan Hedberg 	}
702a3d4e20aSJohan Hedberg 
703a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
704a3d4e20aSJohan Hedberg }
705a3d4e20aSJohan Hedberg 
7063175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
707388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
7081da177e4SLinus Torvalds {
70930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
71070f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
7111da177e4SLinus Torvalds 
7126ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
7131da177e4SLinus Torvalds 
7142b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
7152b2fec4dSSzymon Janc 
716388fc8faSJohan Hedberg 	if (ssp)
717388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
718388fc8faSJohan Hedberg 
71970f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
720a3d4e20aSJohan Hedberg 	if (ie) {
721388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
722388fc8faSJohan Hedberg 			*ssp = true;
723388fc8faSJohan Hedberg 
724a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
725a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
726a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
727a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
728a3d4e20aSJohan Hedberg 		}
729a3d4e20aSJohan Hedberg 
730561aafbcSJohan Hedberg 		goto update;
731a3d4e20aSJohan Hedberg 	}
732561aafbcSJohan Hedberg 
7331da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
73470f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
73570f23020SAndrei Emeltchenko 	if (!ie)
7363175405bSJohan Hedberg 		return false;
73770f23020SAndrei Emeltchenko 
738561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
739561aafbcSJohan Hedberg 
740561aafbcSJohan Hedberg 	if (name_known) {
741561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
742561aafbcSJohan Hedberg 	} else {
743561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
744561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
745561aafbcSJohan Hedberg 	}
746561aafbcSJohan Hedberg 
747561aafbcSJohan Hedberg update:
748561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
749561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
750561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
751561aafbcSJohan Hedberg 		list_del(&ie->list);
7521da177e4SLinus Torvalds 	}
7531da177e4SLinus Torvalds 
75470f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
75570f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
7561da177e4SLinus Torvalds 	cache->timestamp = jiffies;
7573175405bSJohan Hedberg 
7583175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
7593175405bSJohan Hedberg 		return false;
7603175405bSJohan Hedberg 
7613175405bSJohan Hedberg 	return true;
7621da177e4SLinus Torvalds }
7631da177e4SLinus Torvalds 
7641da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
7651da177e4SLinus Torvalds {
76630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
7671da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
7681da177e4SLinus Torvalds 	struct inquiry_entry *e;
7691da177e4SLinus Torvalds 	int copied = 0;
7701da177e4SLinus Torvalds 
771561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
7721da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
773b57c1a56SJohan Hedberg 
774b57c1a56SJohan Hedberg 		if (copied >= num)
775b57c1a56SJohan Hedberg 			break;
776b57c1a56SJohan Hedberg 
7771da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
7781da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
7791da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
7801da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
7811da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
7821da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
783b57c1a56SJohan Hedberg 
7841da177e4SLinus Torvalds 		info++;
785b57c1a56SJohan Hedberg 		copied++;
7861da177e4SLinus Torvalds 	}
7871da177e4SLinus Torvalds 
7881da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
7891da177e4SLinus Torvalds 	return copied;
7901da177e4SLinus Torvalds }
7911da177e4SLinus Torvalds 
79242c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
7931da177e4SLinus Torvalds {
7941da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
79542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
7961da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
7971da177e4SLinus Torvalds 
7981da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
7991da177e4SLinus Torvalds 
8001da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
8011da177e4SLinus Torvalds 		return;
8021da177e4SLinus Torvalds 
8031da177e4SLinus Torvalds 	/* Start Inquiry */
8041da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
8051da177e4SLinus Torvalds 	cp.length  = ir->length;
8061da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
80742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
8081da177e4SLinus Torvalds }
8091da177e4SLinus Torvalds 
8101da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
8111da177e4SLinus Torvalds {
8121da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
8131da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
8141da177e4SLinus Torvalds 	struct hci_dev *hdev;
8151da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
8161da177e4SLinus Torvalds 	long timeo;
8171da177e4SLinus Torvalds 	__u8 *buf;
8181da177e4SLinus Torvalds 
8191da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
8201da177e4SLinus Torvalds 		return -EFAULT;
8211da177e4SLinus Torvalds 
8225a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
8235a08ecceSAndrei Emeltchenko 	if (!hdev)
8241da177e4SLinus Torvalds 		return -ENODEV;
8251da177e4SLinus Torvalds 
82609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
8271da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
828a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
8291da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
8301da177e4SLinus Torvalds 		do_inquiry = 1;
8311da177e4SLinus Torvalds 	}
83209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
8331da177e4SLinus Torvalds 
83404837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
83570f23020SAndrei Emeltchenko 
83670f23020SAndrei Emeltchenko 	if (do_inquiry) {
83701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
83801178cd4SJohan Hedberg 				   timeo);
83970f23020SAndrei Emeltchenko 		if (err < 0)
8401da177e4SLinus Torvalds 			goto done;
84170f23020SAndrei Emeltchenko 	}
8421da177e4SLinus Torvalds 
8438fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
8448fc9ced3SGustavo Padovan 	 * 255 entries
8458fc9ced3SGustavo Padovan 	 */
8461da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
8471da177e4SLinus Torvalds 
8481da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
8491da177e4SLinus Torvalds 	 * copy it to the user space.
8501da177e4SLinus Torvalds 	 */
85170f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
85270f23020SAndrei Emeltchenko 	if (!buf) {
8531da177e4SLinus Torvalds 		err = -ENOMEM;
8541da177e4SLinus Torvalds 		goto done;
8551da177e4SLinus Torvalds 	}
8561da177e4SLinus Torvalds 
85709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
8581da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
85909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
8601da177e4SLinus Torvalds 
8611da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
8621da177e4SLinus Torvalds 
8631da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
8641da177e4SLinus Torvalds 		ptr += sizeof(ir);
8651da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
8661da177e4SLinus Torvalds 				 ir.num_rsp))
8671da177e4SLinus Torvalds 			err = -EFAULT;
8681da177e4SLinus Torvalds 	} else
8691da177e4SLinus Torvalds 		err = -EFAULT;
8701da177e4SLinus Torvalds 
8711da177e4SLinus Torvalds 	kfree(buf);
8721da177e4SLinus Torvalds 
8731da177e4SLinus Torvalds done:
8741da177e4SLinus Torvalds 	hci_dev_put(hdev);
8751da177e4SLinus Torvalds 	return err;
8761da177e4SLinus Torvalds }
8771da177e4SLinus Torvalds 
8783f0f524bSJohan Hedberg static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
8793f0f524bSJohan Hedberg {
8803f0f524bSJohan Hedberg 	u8 ad_len = 0, flags = 0;
8813f0f524bSJohan Hedberg 	size_t name_len;
8823f0f524bSJohan Hedberg 
8833f0f524bSJohan Hedberg 	if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
8843f0f524bSJohan Hedberg 		flags |= LE_AD_GENERAL;
8853f0f524bSJohan Hedberg 
8863f0f524bSJohan Hedberg 	if (!lmp_bredr_capable(hdev))
8873f0f524bSJohan Hedberg 		flags |= LE_AD_NO_BREDR;
8883f0f524bSJohan Hedberg 
8893f0f524bSJohan Hedberg 	if (lmp_le_br_capable(hdev))
8903f0f524bSJohan Hedberg 		flags |= LE_AD_SIM_LE_BREDR_CTRL;
8913f0f524bSJohan Hedberg 
8923f0f524bSJohan Hedberg 	if (lmp_host_le_br_capable(hdev))
8933f0f524bSJohan Hedberg 		flags |= LE_AD_SIM_LE_BREDR_HOST;
8943f0f524bSJohan Hedberg 
8953f0f524bSJohan Hedberg 	if (flags) {
8963f0f524bSJohan Hedberg 		BT_DBG("adv flags 0x%02x", flags);
8973f0f524bSJohan Hedberg 
8983f0f524bSJohan Hedberg 		ptr[0] = 2;
8993f0f524bSJohan Hedberg 		ptr[1] = EIR_FLAGS;
9003f0f524bSJohan Hedberg 		ptr[2] = flags;
9013f0f524bSJohan Hedberg 
9023f0f524bSJohan Hedberg 		ad_len += 3;
9033f0f524bSJohan Hedberg 		ptr += 3;
9043f0f524bSJohan Hedberg 	}
9053f0f524bSJohan Hedberg 
9063f0f524bSJohan Hedberg 	if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) {
9073f0f524bSJohan Hedberg 		ptr[0] = 2;
9083f0f524bSJohan Hedberg 		ptr[1] = EIR_TX_POWER;
9093f0f524bSJohan Hedberg 		ptr[2] = (u8) hdev->adv_tx_power;
9103f0f524bSJohan Hedberg 
9113f0f524bSJohan Hedberg 		ad_len += 3;
9123f0f524bSJohan Hedberg 		ptr += 3;
9133f0f524bSJohan Hedberg 	}
9143f0f524bSJohan Hedberg 
9153f0f524bSJohan Hedberg 	name_len = strlen(hdev->dev_name);
9163f0f524bSJohan Hedberg 	if (name_len > 0) {
9173f0f524bSJohan Hedberg 		size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
9183f0f524bSJohan Hedberg 
9193f0f524bSJohan Hedberg 		if (name_len > max_len) {
9203f0f524bSJohan Hedberg 			name_len = max_len;
9213f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_SHORT;
9223f0f524bSJohan Hedberg 		} else
9233f0f524bSJohan Hedberg 			ptr[1] = EIR_NAME_COMPLETE;
9243f0f524bSJohan Hedberg 
9253f0f524bSJohan Hedberg 		ptr[0] = name_len + 1;
9263f0f524bSJohan Hedberg 
9273f0f524bSJohan Hedberg 		memcpy(ptr + 2, hdev->dev_name, name_len);
9283f0f524bSJohan Hedberg 
9293f0f524bSJohan Hedberg 		ad_len += (name_len + 2);
9303f0f524bSJohan Hedberg 		ptr += (name_len + 2);
9313f0f524bSJohan Hedberg 	}
9323f0f524bSJohan Hedberg 
9333f0f524bSJohan Hedberg 	return ad_len;
9343f0f524bSJohan Hedberg }
9353f0f524bSJohan Hedberg 
9363f0f524bSJohan Hedberg int hci_update_ad(struct hci_dev *hdev)
9373f0f524bSJohan Hedberg {
9383f0f524bSJohan Hedberg 	struct hci_cp_le_set_adv_data cp;
9393f0f524bSJohan Hedberg 	u8 len;
9403f0f524bSJohan Hedberg 	int err;
9413f0f524bSJohan Hedberg 
9423f0f524bSJohan Hedberg 	hci_dev_lock(hdev);
9433f0f524bSJohan Hedberg 
9443f0f524bSJohan Hedberg 	if (!lmp_le_capable(hdev)) {
9453f0f524bSJohan Hedberg 		err = -EINVAL;
9463f0f524bSJohan Hedberg 		goto unlock;
9473f0f524bSJohan Hedberg 	}
9483f0f524bSJohan Hedberg 
9493f0f524bSJohan Hedberg 	memset(&cp, 0, sizeof(cp));
9503f0f524bSJohan Hedberg 
9513f0f524bSJohan Hedberg 	len = create_ad(hdev, cp.data);
9523f0f524bSJohan Hedberg 
9533f0f524bSJohan Hedberg 	if (hdev->adv_data_len == len &&
9543f0f524bSJohan Hedberg 	    memcmp(cp.data, hdev->adv_data, len) == 0) {
9553f0f524bSJohan Hedberg 		err = 0;
9563f0f524bSJohan Hedberg 		goto unlock;
9573f0f524bSJohan Hedberg 	}
9583f0f524bSJohan Hedberg 
9593f0f524bSJohan Hedberg 	memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
9603f0f524bSJohan Hedberg 	hdev->adv_data_len = len;
9613f0f524bSJohan Hedberg 
9623f0f524bSJohan Hedberg 	cp.length = len;
9633f0f524bSJohan Hedberg 	err = hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
9643f0f524bSJohan Hedberg 
9653f0f524bSJohan Hedberg unlock:
9663f0f524bSJohan Hedberg 	hci_dev_unlock(hdev);
9673f0f524bSJohan Hedberg 
9683f0f524bSJohan Hedberg 	return err;
9693f0f524bSJohan Hedberg }
9703f0f524bSJohan Hedberg 
9711da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
9721da177e4SLinus Torvalds 
9731da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
9741da177e4SLinus Torvalds {
9751da177e4SLinus Torvalds 	struct hci_dev *hdev;
9761da177e4SLinus Torvalds 	int ret = 0;
9771da177e4SLinus Torvalds 
9785a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
9795a08ecceSAndrei Emeltchenko 	if (!hdev)
9801da177e4SLinus Torvalds 		return -ENODEV;
9811da177e4SLinus Torvalds 
9821da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
9831da177e4SLinus Torvalds 
9841da177e4SLinus Torvalds 	hci_req_lock(hdev);
9851da177e4SLinus Torvalds 
98694324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
98794324962SJohan Hovold 		ret = -ENODEV;
98894324962SJohan Hovold 		goto done;
98994324962SJohan Hovold 	}
99094324962SJohan Hovold 
991611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
992611b30f7SMarcel Holtmann 		ret = -ERFKILL;
993611b30f7SMarcel Holtmann 		goto done;
994611b30f7SMarcel Holtmann 	}
995611b30f7SMarcel Holtmann 
9961da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
9971da177e4SLinus Torvalds 		ret = -EALREADY;
9981da177e4SLinus Torvalds 		goto done;
9991da177e4SLinus Torvalds 	}
10001da177e4SLinus Torvalds 
10011da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
10021da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
10031da177e4SLinus Torvalds 
100407e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
100507e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
100607e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
1007943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
1008943da25dSMarcel Holtmann 
10091da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
10101da177e4SLinus Torvalds 		ret = -EIO;
10111da177e4SLinus Torvalds 		goto done;
10121da177e4SLinus Torvalds 	}
10131da177e4SLinus Torvalds 
10141da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
10151da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
10161da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
10172177bab5SJohan Hedberg 		ret = __hci_init(hdev);
10181da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
10191da177e4SLinus Torvalds 	}
10201da177e4SLinus Torvalds 
10211da177e4SLinus Torvalds 	if (!ret) {
10221da177e4SLinus Torvalds 		hci_dev_hold(hdev);
10231da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
10241da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
10253f0f524bSJohan Hedberg 		hci_update_ad(hdev);
1026bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
1027bb4b2a9aSAndrei Emeltchenko 		    mgmt_valid_hdev(hdev)) {
102809fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1029744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
103009fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
103156e5cb86SJohan Hedberg 		}
10321da177e4SLinus Torvalds 	} else {
10331da177e4SLinus Torvalds 		/* Init failed, cleanup */
10343eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1035c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1036b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
10371da177e4SLinus Torvalds 
10381da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
10391da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
10401da177e4SLinus Torvalds 
10411da177e4SLinus Torvalds 		if (hdev->flush)
10421da177e4SLinus Torvalds 			hdev->flush(hdev);
10431da177e4SLinus Torvalds 
10441da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
10451da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
10461da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
10471da177e4SLinus Torvalds 		}
10481da177e4SLinus Torvalds 
10491da177e4SLinus Torvalds 		hdev->close(hdev);
10501da177e4SLinus Torvalds 		hdev->flags = 0;
10511da177e4SLinus Torvalds 	}
10521da177e4SLinus Torvalds 
10531da177e4SLinus Torvalds done:
10541da177e4SLinus Torvalds 	hci_req_unlock(hdev);
10551da177e4SLinus Torvalds 	hci_dev_put(hdev);
10561da177e4SLinus Torvalds 	return ret;
10571da177e4SLinus Torvalds }
10581da177e4SLinus Torvalds 
10591da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
10601da177e4SLinus Torvalds {
10611da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
10621da177e4SLinus Torvalds 
106328b75a89SAndre Guedes 	cancel_work_sync(&hdev->le_scan);
106428b75a89SAndre Guedes 
106578c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
106678c04c0bSVinicius Costa Gomes 
10671da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
10681da177e4SLinus Torvalds 	hci_req_lock(hdev);
10691da177e4SLinus Torvalds 
10701da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
1071b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
10721da177e4SLinus Torvalds 		hci_req_unlock(hdev);
10731da177e4SLinus Torvalds 		return 0;
10741da177e4SLinus Torvalds 	}
10751da177e4SLinus Torvalds 
10763eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
10773eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1078b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
10791da177e4SLinus Torvalds 
108016ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
1081e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
108216ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
10835e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
108416ab91abSJohan Hedberg 	}
108516ab91abSJohan Hedberg 
1086a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
10877d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
10887d78525dSJohan Hedberg 
10897ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
10907ba8b4beSAndre Guedes 
109109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
10921da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
10931da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
109409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
10951da177e4SLinus Torvalds 
10961da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
10971da177e4SLinus Torvalds 
10981da177e4SLinus Torvalds 	if (hdev->flush)
10991da177e4SLinus Torvalds 		hdev->flush(hdev);
11001da177e4SLinus Torvalds 
11011da177e4SLinus Torvalds 	/* Reset device */
11021da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
11031da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
11048af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
1105a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
11061da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
110701178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
11081da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
11091da177e4SLinus Torvalds 	}
11101da177e4SLinus Torvalds 
1111c347b765SGustavo F. Padovan 	/* flush cmd  work */
1112c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
11131da177e4SLinus Torvalds 
11141da177e4SLinus Torvalds 	/* Drop queues */
11151da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
11161da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
11171da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
11181da177e4SLinus Torvalds 
11191da177e4SLinus Torvalds 	/* Drop last sent command */
11201da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
1121b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
11221da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
11231da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
11241da177e4SLinus Torvalds 	}
11251da177e4SLinus Torvalds 
11261da177e4SLinus Torvalds 	/* After this point our queues are empty
11271da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
11281da177e4SLinus Torvalds 	hdev->close(hdev);
11291da177e4SLinus Torvalds 
1130bb4b2a9aSAndrei Emeltchenko 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
1131bb4b2a9aSAndrei Emeltchenko 	    mgmt_valid_hdev(hdev)) {
113209fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1133744cf19eSJohan Hedberg 		mgmt_powered(hdev, 0);
113409fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
11358ee56540SMarcel Holtmann 	}
11365add6af8SJohan Hedberg 
11371da177e4SLinus Torvalds 	/* Clear flags */
11381da177e4SLinus Torvalds 	hdev->flags = 0;
11391da177e4SLinus Torvalds 
1140ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1141ced5c338SAndrei Emeltchenko 	hdev->amp_status = 0;
1142ced5c338SAndrei Emeltchenko 
1143e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
114409b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
1145e59fda8dSJohan Hedberg 
11461da177e4SLinus Torvalds 	hci_req_unlock(hdev);
11471da177e4SLinus Torvalds 
11481da177e4SLinus Torvalds 	hci_dev_put(hdev);
11491da177e4SLinus Torvalds 	return 0;
11501da177e4SLinus Torvalds }
11511da177e4SLinus Torvalds 
11521da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
11531da177e4SLinus Torvalds {
11541da177e4SLinus Torvalds 	struct hci_dev *hdev;
11551da177e4SLinus Torvalds 	int err;
11561da177e4SLinus Torvalds 
115770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
115870f23020SAndrei Emeltchenko 	if (!hdev)
11591da177e4SLinus Torvalds 		return -ENODEV;
11608ee56540SMarcel Holtmann 
11618ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
11628ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
11638ee56540SMarcel Holtmann 
11641da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
11658ee56540SMarcel Holtmann 
11661da177e4SLinus Torvalds 	hci_dev_put(hdev);
11671da177e4SLinus Torvalds 	return err;
11681da177e4SLinus Torvalds }
11691da177e4SLinus Torvalds 
11701da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
11711da177e4SLinus Torvalds {
11721da177e4SLinus Torvalds 	struct hci_dev *hdev;
11731da177e4SLinus Torvalds 	int ret = 0;
11741da177e4SLinus Torvalds 
117570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
117670f23020SAndrei Emeltchenko 	if (!hdev)
11771da177e4SLinus Torvalds 		return -ENODEV;
11781da177e4SLinus Torvalds 
11791da177e4SLinus Torvalds 	hci_req_lock(hdev);
11801da177e4SLinus Torvalds 
11811da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
11821da177e4SLinus Torvalds 		goto done;
11831da177e4SLinus Torvalds 
11841da177e4SLinus Torvalds 	/* Drop queues */
11851da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
11861da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
11871da177e4SLinus Torvalds 
118809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
11891da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
11901da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
119109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
11921da177e4SLinus Torvalds 
11931da177e4SLinus Torvalds 	if (hdev->flush)
11941da177e4SLinus Torvalds 		hdev->flush(hdev);
11951da177e4SLinus Torvalds 
11961da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
11976ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
11981da177e4SLinus Torvalds 
11991da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
120001178cd4SJohan Hedberg 		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
12011da177e4SLinus Torvalds 
12021da177e4SLinus Torvalds done:
12031da177e4SLinus Torvalds 	hci_req_unlock(hdev);
12041da177e4SLinus Torvalds 	hci_dev_put(hdev);
12051da177e4SLinus Torvalds 	return ret;
12061da177e4SLinus Torvalds }
12071da177e4SLinus Torvalds 
12081da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
12091da177e4SLinus Torvalds {
12101da177e4SLinus Torvalds 	struct hci_dev *hdev;
12111da177e4SLinus Torvalds 	int ret = 0;
12121da177e4SLinus Torvalds 
121370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
121470f23020SAndrei Emeltchenko 	if (!hdev)
12151da177e4SLinus Torvalds 		return -ENODEV;
12161da177e4SLinus Torvalds 
12171da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
12181da177e4SLinus Torvalds 
12191da177e4SLinus Torvalds 	hci_dev_put(hdev);
12201da177e4SLinus Torvalds 
12211da177e4SLinus Torvalds 	return ret;
12221da177e4SLinus Torvalds }
12231da177e4SLinus Torvalds 
12241da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
12251da177e4SLinus Torvalds {
12261da177e4SLinus Torvalds 	struct hci_dev *hdev;
12271da177e4SLinus Torvalds 	struct hci_dev_req dr;
12281da177e4SLinus Torvalds 	int err = 0;
12291da177e4SLinus Torvalds 
12301da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
12311da177e4SLinus Torvalds 		return -EFAULT;
12321da177e4SLinus Torvalds 
123370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
123470f23020SAndrei Emeltchenko 	if (!hdev)
12351da177e4SLinus Torvalds 		return -ENODEV;
12361da177e4SLinus Torvalds 
12371da177e4SLinus Torvalds 	switch (cmd) {
12381da177e4SLinus Torvalds 	case HCISETAUTH:
123901178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
12405f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
12411da177e4SLinus Torvalds 		break;
12421da177e4SLinus Torvalds 
12431da177e4SLinus Torvalds 	case HCISETENCRYPT:
12441da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
12451da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
12461da177e4SLinus Torvalds 			break;
12471da177e4SLinus Torvalds 		}
12481da177e4SLinus Torvalds 
12491da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
12501da177e4SLinus Torvalds 			/* Auth must be enabled first */
125101178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
12525f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
12531da177e4SLinus Torvalds 			if (err)
12541da177e4SLinus Torvalds 				break;
12551da177e4SLinus Torvalds 		}
12561da177e4SLinus Torvalds 
125701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
12585f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
12591da177e4SLinus Torvalds 		break;
12601da177e4SLinus Torvalds 
12611da177e4SLinus Torvalds 	case HCISETSCAN:
126201178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
12635f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
12641da177e4SLinus Torvalds 		break;
12651da177e4SLinus Torvalds 
12661da177e4SLinus Torvalds 	case HCISETLINKPOL:
126701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
12685f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
12691da177e4SLinus Torvalds 		break;
12701da177e4SLinus Torvalds 
12711da177e4SLinus Torvalds 	case HCISETLINKMODE:
1272e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
1273e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
1274e4e8e37cSMarcel Holtmann 		break;
1275e4e8e37cSMarcel Holtmann 
1276e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
1277e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
12781da177e4SLinus Torvalds 		break;
12791da177e4SLinus Torvalds 
12801da177e4SLinus Torvalds 	case HCISETACLMTU:
12811da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
12821da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
12831da177e4SLinus Torvalds 		break;
12841da177e4SLinus Torvalds 
12851da177e4SLinus Torvalds 	case HCISETSCOMTU:
12861da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
12871da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
12881da177e4SLinus Torvalds 		break;
12891da177e4SLinus Torvalds 
12901da177e4SLinus Torvalds 	default:
12911da177e4SLinus Torvalds 		err = -EINVAL;
12921da177e4SLinus Torvalds 		break;
12931da177e4SLinus Torvalds 	}
1294e4e8e37cSMarcel Holtmann 
12951da177e4SLinus Torvalds 	hci_dev_put(hdev);
12961da177e4SLinus Torvalds 	return err;
12971da177e4SLinus Torvalds }
12981da177e4SLinus Torvalds 
12991da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
13001da177e4SLinus Torvalds {
13018035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
13021da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
13031da177e4SLinus Torvalds 	struct hci_dev_req *dr;
13041da177e4SLinus Torvalds 	int n = 0, size, err;
13051da177e4SLinus Torvalds 	__u16 dev_num;
13061da177e4SLinus Torvalds 
13071da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
13081da177e4SLinus Torvalds 		return -EFAULT;
13091da177e4SLinus Torvalds 
13101da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
13111da177e4SLinus Torvalds 		return -EINVAL;
13121da177e4SLinus Torvalds 
13131da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
13141da177e4SLinus Torvalds 
131570f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
131670f23020SAndrei Emeltchenko 	if (!dl)
13171da177e4SLinus Torvalds 		return -ENOMEM;
13181da177e4SLinus Torvalds 
13191da177e4SLinus Torvalds 	dr = dl->dev_req;
13201da177e4SLinus Torvalds 
1321f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
13228035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
1323a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1324e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
1325c542a06cSJohan Hedberg 
1326a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1327a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1328c542a06cSJohan Hedberg 
13291da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
13301da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
1331c542a06cSJohan Hedberg 
13321da177e4SLinus Torvalds 		if (++n >= dev_num)
13331da177e4SLinus Torvalds 			break;
13341da177e4SLinus Torvalds 	}
1335f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
13361da177e4SLinus Torvalds 
13371da177e4SLinus Torvalds 	dl->dev_num = n;
13381da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
13391da177e4SLinus Torvalds 
13401da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
13411da177e4SLinus Torvalds 	kfree(dl);
13421da177e4SLinus Torvalds 
13431da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
13441da177e4SLinus Torvalds }
13451da177e4SLinus Torvalds 
13461da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
13471da177e4SLinus Torvalds {
13481da177e4SLinus Torvalds 	struct hci_dev *hdev;
13491da177e4SLinus Torvalds 	struct hci_dev_info di;
13501da177e4SLinus Torvalds 	int err = 0;
13511da177e4SLinus Torvalds 
13521da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
13531da177e4SLinus Torvalds 		return -EFAULT;
13541da177e4SLinus Torvalds 
135570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
135670f23020SAndrei Emeltchenko 	if (!hdev)
13571da177e4SLinus Torvalds 		return -ENODEV;
13581da177e4SLinus Torvalds 
1359a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
13603243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1361ab81cbf9SJohan Hedberg 
1362a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1363a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1364c542a06cSJohan Hedberg 
13651da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
13661da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
1367943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
13681da177e4SLinus Torvalds 	di.flags    = hdev->flags;
13691da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
1370572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
13711da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
13721da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
13731da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
13741da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
1375572c7f84SJohan Hedberg 	} else {
1376572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
1377572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
1378572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
1379572c7f84SJohan Hedberg 		di.sco_pkts = 0;
1380572c7f84SJohan Hedberg 	}
13811da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
13821da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
13831da177e4SLinus Torvalds 
13841da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
13851da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
13861da177e4SLinus Torvalds 
13871da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
13881da177e4SLinus Torvalds 		err = -EFAULT;
13891da177e4SLinus Torvalds 
13901da177e4SLinus Torvalds 	hci_dev_put(hdev);
13911da177e4SLinus Torvalds 
13921da177e4SLinus Torvalds 	return err;
13931da177e4SLinus Torvalds }
13941da177e4SLinus Torvalds 
13951da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
13961da177e4SLinus Torvalds 
1397611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1398611b30f7SMarcel Holtmann {
1399611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1400611b30f7SMarcel Holtmann 
1401611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1402611b30f7SMarcel Holtmann 
1403611b30f7SMarcel Holtmann 	if (!blocked)
1404611b30f7SMarcel Holtmann 		return 0;
1405611b30f7SMarcel Holtmann 
1406611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1407611b30f7SMarcel Holtmann 
1408611b30f7SMarcel Holtmann 	return 0;
1409611b30f7SMarcel Holtmann }
1410611b30f7SMarcel Holtmann 
1411611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1412611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1413611b30f7SMarcel Holtmann };
1414611b30f7SMarcel Holtmann 
1415ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1416ab81cbf9SJohan Hedberg {
1417ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
1418ab81cbf9SJohan Hedberg 
1419ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1420ab81cbf9SJohan Hedberg 
1421ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
1422ab81cbf9SJohan Hedberg 		return;
1423ab81cbf9SJohan Hedberg 
1424a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
142519202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
142619202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
1427ab81cbf9SJohan Hedberg 
1428a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1429744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1430ab81cbf9SJohan Hedberg }
1431ab81cbf9SJohan Hedberg 
1432ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1433ab81cbf9SJohan Hedberg {
14343243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
14353243553fSJohan Hedberg 					    power_off.work);
1436ab81cbf9SJohan Hedberg 
1437ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1438ab81cbf9SJohan Hedberg 
14398ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1440ab81cbf9SJohan Hedberg }
1441ab81cbf9SJohan Hedberg 
144216ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
144316ab91abSJohan Hedberg {
144416ab91abSJohan Hedberg 	struct hci_dev *hdev;
144516ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
144616ab91abSJohan Hedberg 
144716ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
144816ab91abSJohan Hedberg 
144916ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
145016ab91abSJohan Hedberg 
145109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
145216ab91abSJohan Hedberg 
145316ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
145416ab91abSJohan Hedberg 
145516ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
145616ab91abSJohan Hedberg 
145709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
145816ab91abSJohan Hedberg }
145916ab91abSJohan Hedberg 
14602aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
14612aeb9a1aSJohan Hedberg {
14624821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
14632aeb9a1aSJohan Hedberg 
14644821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
14654821002cSJohan Hedberg 		list_del(&uuid->list);
14662aeb9a1aSJohan Hedberg 		kfree(uuid);
14672aeb9a1aSJohan Hedberg 	}
14682aeb9a1aSJohan Hedberg 
14692aeb9a1aSJohan Hedberg 	return 0;
14702aeb9a1aSJohan Hedberg }
14712aeb9a1aSJohan Hedberg 
147255ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
147355ed8ca1SJohan Hedberg {
147455ed8ca1SJohan Hedberg 	struct list_head *p, *n;
147555ed8ca1SJohan Hedberg 
147655ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
147755ed8ca1SJohan Hedberg 		struct link_key *key;
147855ed8ca1SJohan Hedberg 
147955ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
148055ed8ca1SJohan Hedberg 
148155ed8ca1SJohan Hedberg 		list_del(p);
148255ed8ca1SJohan Hedberg 		kfree(key);
148355ed8ca1SJohan Hedberg 	}
148455ed8ca1SJohan Hedberg 
148555ed8ca1SJohan Hedberg 	return 0;
148655ed8ca1SJohan Hedberg }
148755ed8ca1SJohan Hedberg 
1488b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1489b899efafSVinicius Costa Gomes {
1490b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1491b899efafSVinicius Costa Gomes 
1492b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1493b899efafSVinicius Costa Gomes 		list_del(&k->list);
1494b899efafSVinicius Costa Gomes 		kfree(k);
1495b899efafSVinicius Costa Gomes 	}
1496b899efafSVinicius Costa Gomes 
1497b899efafSVinicius Costa Gomes 	return 0;
1498b899efafSVinicius Costa Gomes }
1499b899efafSVinicius Costa Gomes 
150055ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
150155ed8ca1SJohan Hedberg {
150255ed8ca1SJohan Hedberg 	struct link_key *k;
150355ed8ca1SJohan Hedberg 
15048035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
150555ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
150655ed8ca1SJohan Hedberg 			return k;
150755ed8ca1SJohan Hedberg 
150855ed8ca1SJohan Hedberg 	return NULL;
150955ed8ca1SJohan Hedberg }
151055ed8ca1SJohan Hedberg 
1511745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1512d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1513d25e28abSJohan Hedberg {
1514d25e28abSJohan Hedberg 	/* Legacy key */
1515d25e28abSJohan Hedberg 	if (key_type < 0x03)
1516745c0ce3SVishal Agarwal 		return true;
1517d25e28abSJohan Hedberg 
1518d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1519d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1520745c0ce3SVishal Agarwal 		return false;
1521d25e28abSJohan Hedberg 
1522d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1523d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1524745c0ce3SVishal Agarwal 		return false;
1525d25e28abSJohan Hedberg 
1526d25e28abSJohan Hedberg 	/* Security mode 3 case */
1527d25e28abSJohan Hedberg 	if (!conn)
1528745c0ce3SVishal Agarwal 		return true;
1529d25e28abSJohan Hedberg 
1530d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1531d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1532745c0ce3SVishal Agarwal 		return true;
1533d25e28abSJohan Hedberg 
1534d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1535d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1536745c0ce3SVishal Agarwal 		return true;
1537d25e28abSJohan Hedberg 
1538d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1539d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1540745c0ce3SVishal Agarwal 		return true;
1541d25e28abSJohan Hedberg 
1542d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1543d25e28abSJohan Hedberg 	 * persistently */
1544745c0ce3SVishal Agarwal 	return false;
1545d25e28abSJohan Hedberg }
1546d25e28abSJohan Hedberg 
1547c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
154875d262c2SVinicius Costa Gomes {
1549c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
155075d262c2SVinicius Costa Gomes 
1551c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1552c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1553c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
155475d262c2SVinicius Costa Gomes 			continue;
155575d262c2SVinicius Costa Gomes 
155675d262c2SVinicius Costa Gomes 		return k;
155775d262c2SVinicius Costa Gomes 	}
155875d262c2SVinicius Costa Gomes 
155975d262c2SVinicius Costa Gomes 	return NULL;
156075d262c2SVinicius Costa Gomes }
156175d262c2SVinicius Costa Gomes 
1562c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1563c9839a11SVinicius Costa Gomes 				     u8 addr_type)
156475d262c2SVinicius Costa Gomes {
1565c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
156675d262c2SVinicius Costa Gomes 
1567c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1568c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1569c9839a11SVinicius Costa Gomes 		    bacmp(bdaddr, &k->bdaddr) == 0)
157075d262c2SVinicius Costa Gomes 			return k;
157175d262c2SVinicius Costa Gomes 
157275d262c2SVinicius Costa Gomes 	return NULL;
157375d262c2SVinicius Costa Gomes }
157475d262c2SVinicius Costa Gomes 
1575d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1576d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
157755ed8ca1SJohan Hedberg {
157855ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1579745c0ce3SVishal Agarwal 	u8 old_key_type;
1580745c0ce3SVishal Agarwal 	bool persistent;
158155ed8ca1SJohan Hedberg 
158255ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
158355ed8ca1SJohan Hedberg 	if (old_key) {
158455ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
158555ed8ca1SJohan Hedberg 		key = old_key;
158655ed8ca1SJohan Hedberg 	} else {
158712adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
158855ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
158955ed8ca1SJohan Hedberg 		if (!key)
159055ed8ca1SJohan Hedberg 			return -ENOMEM;
159155ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
159255ed8ca1SJohan Hedberg 	}
159355ed8ca1SJohan Hedberg 
15946ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
159555ed8ca1SJohan Hedberg 
1596d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1597d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1598d25e28abSJohan Hedberg 	 * previous key */
1599d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1600a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1601d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1602655fe6ecSJohan Hedberg 		if (conn)
1603655fe6ecSJohan Hedberg 			conn->key_type = type;
1604655fe6ecSJohan Hedberg 	}
1605d25e28abSJohan Hedberg 
160655ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
16079b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
160855ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
160955ed8ca1SJohan Hedberg 
1610b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
161155ed8ca1SJohan Hedberg 		key->type = old_key_type;
16124748fed2SJohan Hedberg 	else
16134748fed2SJohan Hedberg 		key->type = type;
16144748fed2SJohan Hedberg 
16154df378a1SJohan Hedberg 	if (!new_key)
16164df378a1SJohan Hedberg 		return 0;
16174df378a1SJohan Hedberg 
16184df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
16194df378a1SJohan Hedberg 
1620744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
16214df378a1SJohan Hedberg 
16226ec5bcadSVishal Agarwal 	if (conn)
16236ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
162455ed8ca1SJohan Hedberg 
162555ed8ca1SJohan Hedberg 	return 0;
162655ed8ca1SJohan Hedberg }
162755ed8ca1SJohan Hedberg 
1628c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
16299a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
163004124681SGustavo F. Padovan 		ediv, u8 rand[8])
163175d262c2SVinicius Costa Gomes {
1632c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
163375d262c2SVinicius Costa Gomes 
1634c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1635c9839a11SVinicius Costa Gomes 		return 0;
163675d262c2SVinicius Costa Gomes 
1637c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1638c9839a11SVinicius Costa Gomes 	if (old_key)
163975d262c2SVinicius Costa Gomes 		key = old_key;
1640c9839a11SVinicius Costa Gomes 	else {
1641c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
164275d262c2SVinicius Costa Gomes 		if (!key)
164375d262c2SVinicius Costa Gomes 			return -ENOMEM;
1644c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
164575d262c2SVinicius Costa Gomes 	}
164675d262c2SVinicius Costa Gomes 
164775d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1648c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1649c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1650c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1651c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1652c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1653c9839a11SVinicius Costa Gomes 	key->type = type;
1654c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
165575d262c2SVinicius Costa Gomes 
1656c9839a11SVinicius Costa Gomes 	if (!new_key)
1657c9839a11SVinicius Costa Gomes 		return 0;
165875d262c2SVinicius Costa Gomes 
1659261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1660261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1661261cc5aaSVinicius Costa Gomes 
166275d262c2SVinicius Costa Gomes 	return 0;
166375d262c2SVinicius Costa Gomes }
166475d262c2SVinicius Costa Gomes 
166555ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
166655ed8ca1SJohan Hedberg {
166755ed8ca1SJohan Hedberg 	struct link_key *key;
166855ed8ca1SJohan Hedberg 
166955ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
167055ed8ca1SJohan Hedberg 	if (!key)
167155ed8ca1SJohan Hedberg 		return -ENOENT;
167255ed8ca1SJohan Hedberg 
16736ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
167455ed8ca1SJohan Hedberg 
167555ed8ca1SJohan Hedberg 	list_del(&key->list);
167655ed8ca1SJohan Hedberg 	kfree(key);
167755ed8ca1SJohan Hedberg 
167855ed8ca1SJohan Hedberg 	return 0;
167955ed8ca1SJohan Hedberg }
168055ed8ca1SJohan Hedberg 
1681b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1682b899efafSVinicius Costa Gomes {
1683b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1684b899efafSVinicius Costa Gomes 
1685b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1686b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1687b899efafSVinicius Costa Gomes 			continue;
1688b899efafSVinicius Costa Gomes 
16896ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1690b899efafSVinicius Costa Gomes 
1691b899efafSVinicius Costa Gomes 		list_del(&k->list);
1692b899efafSVinicius Costa Gomes 		kfree(k);
1693b899efafSVinicius Costa Gomes 	}
1694b899efafSVinicius Costa Gomes 
1695b899efafSVinicius Costa Gomes 	return 0;
1696b899efafSVinicius Costa Gomes }
1697b899efafSVinicius Costa Gomes 
16986bd32326SVille Tervo /* HCI command timer function */
1699bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
17006bd32326SVille Tervo {
17016bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
17026bd32326SVille Tervo 
1703bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
1704bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
1705bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
1706bda4f23aSAndrei Emeltchenko 
1707bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
1708bda4f23aSAndrei Emeltchenko 	} else {
17096bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
1710bda4f23aSAndrei Emeltchenko 	}
1711bda4f23aSAndrei Emeltchenko 
17126bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1713c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
17146bd32326SVille Tervo }
17156bd32326SVille Tervo 
17162763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
17172763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
17182763eda6SSzymon Janc {
17192763eda6SSzymon Janc 	struct oob_data *data;
17202763eda6SSzymon Janc 
17212763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
17222763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
17232763eda6SSzymon Janc 			return data;
17242763eda6SSzymon Janc 
17252763eda6SSzymon Janc 	return NULL;
17262763eda6SSzymon Janc }
17272763eda6SSzymon Janc 
17282763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
17292763eda6SSzymon Janc {
17302763eda6SSzymon Janc 	struct oob_data *data;
17312763eda6SSzymon Janc 
17322763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
17332763eda6SSzymon Janc 	if (!data)
17342763eda6SSzymon Janc 		return -ENOENT;
17352763eda6SSzymon Janc 
17366ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
17372763eda6SSzymon Janc 
17382763eda6SSzymon Janc 	list_del(&data->list);
17392763eda6SSzymon Janc 	kfree(data);
17402763eda6SSzymon Janc 
17412763eda6SSzymon Janc 	return 0;
17422763eda6SSzymon Janc }
17432763eda6SSzymon Janc 
17442763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
17452763eda6SSzymon Janc {
17462763eda6SSzymon Janc 	struct oob_data *data, *n;
17472763eda6SSzymon Janc 
17482763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
17492763eda6SSzymon Janc 		list_del(&data->list);
17502763eda6SSzymon Janc 		kfree(data);
17512763eda6SSzymon Janc 	}
17522763eda6SSzymon Janc 
17532763eda6SSzymon Janc 	return 0;
17542763eda6SSzymon Janc }
17552763eda6SSzymon Janc 
17562763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
17572763eda6SSzymon Janc 			    u8 *randomizer)
17582763eda6SSzymon Janc {
17592763eda6SSzymon Janc 	struct oob_data *data;
17602763eda6SSzymon Janc 
17612763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
17622763eda6SSzymon Janc 
17632763eda6SSzymon Janc 	if (!data) {
17642763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
17652763eda6SSzymon Janc 		if (!data)
17662763eda6SSzymon Janc 			return -ENOMEM;
17672763eda6SSzymon Janc 
17682763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
17692763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
17702763eda6SSzymon Janc 	}
17712763eda6SSzymon Janc 
17722763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
17732763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
17742763eda6SSzymon Janc 
17756ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
17762763eda6SSzymon Janc 
17772763eda6SSzymon Janc 	return 0;
17782763eda6SSzymon Janc }
17792763eda6SSzymon Janc 
178004124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
1781b2a66aadSAntti Julku {
1782b2a66aadSAntti Julku 	struct bdaddr_list *b;
1783b2a66aadSAntti Julku 
17848035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1785b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1786b2a66aadSAntti Julku 			return b;
1787b2a66aadSAntti Julku 
1788b2a66aadSAntti Julku 	return NULL;
1789b2a66aadSAntti Julku }
1790b2a66aadSAntti Julku 
1791b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1792b2a66aadSAntti Julku {
1793b2a66aadSAntti Julku 	struct list_head *p, *n;
1794b2a66aadSAntti Julku 
1795b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1796b2a66aadSAntti Julku 		struct bdaddr_list *b;
1797b2a66aadSAntti Julku 
1798b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1799b2a66aadSAntti Julku 
1800b2a66aadSAntti Julku 		list_del(p);
1801b2a66aadSAntti Julku 		kfree(b);
1802b2a66aadSAntti Julku 	}
1803b2a66aadSAntti Julku 
1804b2a66aadSAntti Julku 	return 0;
1805b2a66aadSAntti Julku }
1806b2a66aadSAntti Julku 
180788c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1808b2a66aadSAntti Julku {
1809b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1810b2a66aadSAntti Julku 
1811b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1812b2a66aadSAntti Julku 		return -EBADF;
1813b2a66aadSAntti Julku 
18145e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
18155e762444SAntti Julku 		return -EEXIST;
1816b2a66aadSAntti Julku 
1817b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
18185e762444SAntti Julku 	if (!entry)
18195e762444SAntti Julku 		return -ENOMEM;
1820b2a66aadSAntti Julku 
1821b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1822b2a66aadSAntti Julku 
1823b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1824b2a66aadSAntti Julku 
182588c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
1826b2a66aadSAntti Julku }
1827b2a66aadSAntti Julku 
182888c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1829b2a66aadSAntti Julku {
1830b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1831b2a66aadSAntti Julku 
18321ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
18335e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1834b2a66aadSAntti Julku 
1835b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
18361ec918ceSSzymon Janc 	if (!entry)
18375e762444SAntti Julku 		return -ENOENT;
1838b2a66aadSAntti Julku 
1839b2a66aadSAntti Julku 	list_del(&entry->list);
1840b2a66aadSAntti Julku 	kfree(entry);
1841b2a66aadSAntti Julku 
184288c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
1843b2a66aadSAntti Julku }
1844b2a66aadSAntti Julku 
184542c6b129SJohan Hedberg static void le_scan_param_req(struct hci_request *req, unsigned long opt)
18467ba8b4beSAndre Guedes {
18477ba8b4beSAndre Guedes 	struct le_scan_params *param =  (struct le_scan_params *) opt;
18487ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_param cp;
18497ba8b4beSAndre Guedes 
18507ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
18517ba8b4beSAndre Guedes 	cp.type = param->type;
18527ba8b4beSAndre Guedes 	cp.interval = cpu_to_le16(param->interval);
18537ba8b4beSAndre Guedes 	cp.window = cpu_to_le16(param->window);
18547ba8b4beSAndre Guedes 
185542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
18567ba8b4beSAndre Guedes }
18577ba8b4beSAndre Guedes 
185842c6b129SJohan Hedberg static void le_scan_enable_req(struct hci_request *req, unsigned long opt)
18597ba8b4beSAndre Guedes {
18607ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
18617ba8b4beSAndre Guedes 
18627ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
18637ba8b4beSAndre Guedes 	cp.enable = 1;
18640431a43cSAndre Guedes 	cp.filter_dup = 1;
18657ba8b4beSAndre Guedes 
186642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
18677ba8b4beSAndre Guedes }
18687ba8b4beSAndre Guedes 
18697ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
18707ba8b4beSAndre Guedes 			  u16 window, int timeout)
18717ba8b4beSAndre Guedes {
18727ba8b4beSAndre Guedes 	long timeo = msecs_to_jiffies(3000);
18737ba8b4beSAndre Guedes 	struct le_scan_params param;
18747ba8b4beSAndre Guedes 	int err;
18757ba8b4beSAndre Guedes 
18767ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
18777ba8b4beSAndre Guedes 
18787ba8b4beSAndre Guedes 	if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
18797ba8b4beSAndre Guedes 		return -EINPROGRESS;
18807ba8b4beSAndre Guedes 
18817ba8b4beSAndre Guedes 	param.type = type;
18827ba8b4beSAndre Guedes 	param.interval = interval;
18837ba8b4beSAndre Guedes 	param.window = window;
18847ba8b4beSAndre Guedes 
18857ba8b4beSAndre Guedes 	hci_req_lock(hdev);
18867ba8b4beSAndre Guedes 
188701178cd4SJohan Hedberg 	err = __hci_req_sync(hdev, le_scan_param_req, (unsigned long) &param,
18887ba8b4beSAndre Guedes 			     timeo);
18897ba8b4beSAndre Guedes 	if (!err)
189001178cd4SJohan Hedberg 		err = __hci_req_sync(hdev, le_scan_enable_req, 0, timeo);
18917ba8b4beSAndre Guedes 
18927ba8b4beSAndre Guedes 	hci_req_unlock(hdev);
18937ba8b4beSAndre Guedes 
18947ba8b4beSAndre Guedes 	if (err < 0)
18957ba8b4beSAndre Guedes 		return err;
18967ba8b4beSAndre Guedes 
189746818ed5SJohan Hedberg 	queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable,
18987ba8b4beSAndre Guedes 			   msecs_to_jiffies(timeout));
18997ba8b4beSAndre Guedes 
19007ba8b4beSAndre Guedes 	return 0;
19017ba8b4beSAndre Guedes }
19027ba8b4beSAndre Guedes 
19037dbfac1dSAndre Guedes int hci_cancel_le_scan(struct hci_dev *hdev)
19047dbfac1dSAndre Guedes {
19057dbfac1dSAndre Guedes 	BT_DBG("%s", hdev->name);
19067dbfac1dSAndre Guedes 
19077dbfac1dSAndre Guedes 	if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
19087dbfac1dSAndre Guedes 		return -EALREADY;
19097dbfac1dSAndre Guedes 
19107dbfac1dSAndre Guedes 	if (cancel_delayed_work(&hdev->le_scan_disable)) {
19117dbfac1dSAndre Guedes 		struct hci_cp_le_set_scan_enable cp;
19127dbfac1dSAndre Guedes 
19137dbfac1dSAndre Guedes 		/* Send HCI command to disable LE Scan */
19147dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
19157dbfac1dSAndre Guedes 		hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
19167dbfac1dSAndre Guedes 	}
19177dbfac1dSAndre Guedes 
19187dbfac1dSAndre Guedes 	return 0;
19197dbfac1dSAndre Guedes }
19207dbfac1dSAndre Guedes 
19217ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
19227ba8b4beSAndre Guedes {
19237ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
19247ba8b4beSAndre Guedes 					    le_scan_disable.work);
19257ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
19267ba8b4beSAndre Guedes 
19277ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
19287ba8b4beSAndre Guedes 
19297ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
19307ba8b4beSAndre Guedes 
19317ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
19327ba8b4beSAndre Guedes }
19337ba8b4beSAndre Guedes 
193428b75a89SAndre Guedes static void le_scan_work(struct work_struct *work)
193528b75a89SAndre Guedes {
193628b75a89SAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
193728b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
193828b75a89SAndre Guedes 
193928b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
194028b75a89SAndre Guedes 
194104124681SGustavo F. Padovan 	hci_do_le_scan(hdev, param->type, param->interval, param->window,
194204124681SGustavo F. Padovan 		       param->timeout);
194328b75a89SAndre Guedes }
194428b75a89SAndre Guedes 
194528b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
194628b75a89SAndre Guedes 		int timeout)
194728b75a89SAndre Guedes {
194828b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
194928b75a89SAndre Guedes 
195028b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
195128b75a89SAndre Guedes 
1952f1550478SJohan Hedberg 	if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
1953f1550478SJohan Hedberg 		return -ENOTSUPP;
1954f1550478SJohan Hedberg 
195528b75a89SAndre Guedes 	if (work_busy(&hdev->le_scan))
195628b75a89SAndre Guedes 		return -EINPROGRESS;
195728b75a89SAndre Guedes 
195828b75a89SAndre Guedes 	param->type = type;
195928b75a89SAndre Guedes 	param->interval = interval;
196028b75a89SAndre Guedes 	param->window = window;
196128b75a89SAndre Guedes 	param->timeout = timeout;
196228b75a89SAndre Guedes 
196328b75a89SAndre Guedes 	queue_work(system_long_wq, &hdev->le_scan);
196428b75a89SAndre Guedes 
196528b75a89SAndre Guedes 	return 0;
196628b75a89SAndre Guedes }
196728b75a89SAndre Guedes 
19689be0dab7SDavid Herrmann /* Alloc HCI device */
19699be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
19709be0dab7SDavid Herrmann {
19719be0dab7SDavid Herrmann 	struct hci_dev *hdev;
19729be0dab7SDavid Herrmann 
19739be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
19749be0dab7SDavid Herrmann 	if (!hdev)
19759be0dab7SDavid Herrmann 		return NULL;
19769be0dab7SDavid Herrmann 
1977b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
1978b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
1979b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
1980b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03; /* No Input No Output */
1981bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
1982bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
1983b1b813d4SDavid Herrmann 
1984b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
1985b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
1986b1b813d4SDavid Herrmann 
1987b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
1988b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
1989b1b813d4SDavid Herrmann 
1990b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
1991b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
1992b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
1993b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
1994b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
1995b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
19966b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
1997b1b813d4SDavid Herrmann 
1998b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1999b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2000b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
2001b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
2002b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->le_scan, le_scan_work);
2003b1b813d4SDavid Herrmann 
2004b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2005b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
2006b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
2007b1b813d4SDavid Herrmann 
20089be0dab7SDavid Herrmann 	skb_queue_head_init(&hdev->driver_init);
2009b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
2010b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
2011b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
2012b1b813d4SDavid Herrmann 
2013b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
2014b1b813d4SDavid Herrmann 
2015bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
2016b1b813d4SDavid Herrmann 
2017b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
2018b1b813d4SDavid Herrmann 	discovery_init(hdev);
20199be0dab7SDavid Herrmann 
20209be0dab7SDavid Herrmann 	return hdev;
20219be0dab7SDavid Herrmann }
20229be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
20239be0dab7SDavid Herrmann 
20249be0dab7SDavid Herrmann /* Free HCI device */
20259be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
20269be0dab7SDavid Herrmann {
20279be0dab7SDavid Herrmann 	skb_queue_purge(&hdev->driver_init);
20289be0dab7SDavid Herrmann 
20299be0dab7SDavid Herrmann 	/* will free via device release */
20309be0dab7SDavid Herrmann 	put_device(&hdev->dev);
20319be0dab7SDavid Herrmann }
20329be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
20339be0dab7SDavid Herrmann 
20341da177e4SLinus Torvalds /* Register HCI device */
20351da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
20361da177e4SLinus Torvalds {
2037b1b813d4SDavid Herrmann 	int id, error;
20381da177e4SLinus Torvalds 
2039010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
20401da177e4SLinus Torvalds 		return -EINVAL;
20411da177e4SLinus Torvalds 
204208add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
204308add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
204408add513SMat Martineau 	 */
20453df92b31SSasha Levin 	switch (hdev->dev_type) {
20463df92b31SSasha Levin 	case HCI_BREDR:
20473df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
20481da177e4SLinus Torvalds 		break;
20493df92b31SSasha Levin 	case HCI_AMP:
20503df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
20513df92b31SSasha Levin 		break;
20523df92b31SSasha Levin 	default:
20533df92b31SSasha Levin 		return -EINVAL;
20541da177e4SLinus Torvalds 	}
20551da177e4SLinus Torvalds 
20563df92b31SSasha Levin 	if (id < 0)
20573df92b31SSasha Levin 		return id;
20583df92b31SSasha Levin 
20591da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
20601da177e4SLinus Torvalds 	hdev->id = id;
20612d8b3a11SAndrei Emeltchenko 
20622d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
20632d8b3a11SAndrei Emeltchenko 
20643df92b31SSasha Levin 	write_lock(&hci_dev_list_lock);
20653df92b31SSasha Levin 	list_add(&hdev->list, &hci_dev_list);
2066f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
20671da177e4SLinus Torvalds 
206832845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
206932845eb1SGustavo F. Padovan 					  WQ_MEM_RECLAIM, 1);
207033ca954dSDavid Herrmann 	if (!hdev->workqueue) {
207133ca954dSDavid Herrmann 		error = -ENOMEM;
207233ca954dSDavid Herrmann 		goto err;
207333ca954dSDavid Herrmann 	}
2074f48fd9c8SMarcel Holtmann 
20756ead1bbcSJohan Hedberg 	hdev->req_workqueue = alloc_workqueue(hdev->name,
20766ead1bbcSJohan Hedberg 					      WQ_HIGHPRI | WQ_UNBOUND |
20776ead1bbcSJohan Hedberg 					      WQ_MEM_RECLAIM, 1);
20786ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
20796ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
20806ead1bbcSJohan Hedberg 		error = -ENOMEM;
20816ead1bbcSJohan Hedberg 		goto err;
20826ead1bbcSJohan Hedberg 	}
20836ead1bbcSJohan Hedberg 
208433ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
208533ca954dSDavid Herrmann 	if (error < 0)
208633ca954dSDavid Herrmann 		goto err_wqueue;
20871da177e4SLinus Torvalds 
2088611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2089a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2090a8c5fb1aSGustavo Padovan 				    hdev);
2091611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2092611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
2093611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
2094611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
2095611b30f7SMarcel Holtmann 		}
2096611b30f7SMarcel Holtmann 	}
2097611b30f7SMarcel Holtmann 
2098a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
2099ce2be9acSAndrei Emeltchenko 
2100ce2be9acSAndrei Emeltchenko 	if (hdev->dev_type != HCI_AMP)
2101ce2be9acSAndrei Emeltchenko 		set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2102ce2be9acSAndrei Emeltchenko 
21031da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
2104dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
21051da177e4SLinus Torvalds 
210619202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
2107fbe96d6fSMarcel Holtmann 
21081da177e4SLinus Torvalds 	return id;
2109f48fd9c8SMarcel Holtmann 
211033ca954dSDavid Herrmann err_wqueue:
211133ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
21126ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
211333ca954dSDavid Herrmann err:
21143df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
2115f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
2116f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
2117f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
2118f48fd9c8SMarcel Holtmann 
211933ca954dSDavid Herrmann 	return error;
21201da177e4SLinus Torvalds }
21211da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
21221da177e4SLinus Torvalds 
21231da177e4SLinus Torvalds /* Unregister HCI device */
212459735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
21251da177e4SLinus Torvalds {
21263df92b31SSasha Levin 	int i, id;
2127ef222013SMarcel Holtmann 
2128c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
21291da177e4SLinus Torvalds 
213094324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
213194324962SJohan Hovold 
21323df92b31SSasha Levin 	id = hdev->id;
21333df92b31SSasha Levin 
2134f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
21351da177e4SLinus Torvalds 	list_del(&hdev->list);
2136f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
21371da177e4SLinus Torvalds 
21381da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
21391da177e4SLinus Torvalds 
2140cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
2141ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
2142ef222013SMarcel Holtmann 
2143b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
2144b9b5ef18SGustavo Padovan 
2145ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
2146a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
214709fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
2148744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
214909fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
215056e5cb86SJohan Hedberg 	}
2151ab81cbf9SJohan Hedberg 
21522e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
21532e58ef3eSJohan Hedberg 	 * pending list */
21542e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
21552e58ef3eSJohan Hedberg 
21561da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
21571da177e4SLinus Torvalds 
2158611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
2159611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
2160611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
2161611b30f7SMarcel Holtmann 	}
2162611b30f7SMarcel Holtmann 
2163ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
2164147e2d59SDave Young 
2165f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
21666ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
2167f48fd9c8SMarcel Holtmann 
216809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
2169e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
21702aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
217155ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
2172b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
21732763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
217409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
2175e2e0cacbSJohan Hedberg 
2176dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
21773df92b31SSasha Levin 
21783df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
21791da177e4SLinus Torvalds }
21801da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
21811da177e4SLinus Torvalds 
21821da177e4SLinus Torvalds /* Suspend HCI device */
21831da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
21841da177e4SLinus Torvalds {
21851da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
21861da177e4SLinus Torvalds 	return 0;
21871da177e4SLinus Torvalds }
21881da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
21891da177e4SLinus Torvalds 
21901da177e4SLinus Torvalds /* Resume HCI device */
21911da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
21921da177e4SLinus Torvalds {
21931da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
21941da177e4SLinus Torvalds 	return 0;
21951da177e4SLinus Torvalds }
21961da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
21971da177e4SLinus Torvalds 
219876bca880SMarcel Holtmann /* Receive frame from HCI drivers */
219976bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
220076bca880SMarcel Holtmann {
220176bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
220276bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
220376bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
220476bca880SMarcel Holtmann 		kfree_skb(skb);
220576bca880SMarcel Holtmann 		return -ENXIO;
220676bca880SMarcel Holtmann 	}
220776bca880SMarcel Holtmann 
2208d82603c6SJorrit Schippers 	/* Incoming skb */
220976bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
221076bca880SMarcel Holtmann 
221176bca880SMarcel Holtmann 	/* Time stamp */
221276bca880SMarcel Holtmann 	__net_timestamp(skb);
221376bca880SMarcel Holtmann 
221476bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
2215b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
2216c78ae283SMarcel Holtmann 
221776bca880SMarcel Holtmann 	return 0;
221876bca880SMarcel Holtmann }
221976bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
222076bca880SMarcel Holtmann 
222133e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
22221e429f38SGustavo F. Padovan 			  int count, __u8 index)
222333e882a5SSuraj Sumangala {
222433e882a5SSuraj Sumangala 	int len = 0;
222533e882a5SSuraj Sumangala 	int hlen = 0;
222633e882a5SSuraj Sumangala 	int remain = count;
222733e882a5SSuraj Sumangala 	struct sk_buff *skb;
222833e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
222933e882a5SSuraj Sumangala 
223033e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
223133e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
223233e882a5SSuraj Sumangala 		return -EILSEQ;
223333e882a5SSuraj Sumangala 
223433e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
223533e882a5SSuraj Sumangala 
223633e882a5SSuraj Sumangala 	if (!skb) {
223733e882a5SSuraj Sumangala 		switch (type) {
223833e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
223933e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
224033e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
224133e882a5SSuraj Sumangala 			break;
224233e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
224333e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
224433e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
224533e882a5SSuraj Sumangala 			break;
224633e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
224733e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
224833e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
224933e882a5SSuraj Sumangala 			break;
225033e882a5SSuraj Sumangala 		}
225133e882a5SSuraj Sumangala 
22521e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
225333e882a5SSuraj Sumangala 		if (!skb)
225433e882a5SSuraj Sumangala 			return -ENOMEM;
225533e882a5SSuraj Sumangala 
225633e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
225733e882a5SSuraj Sumangala 		scb->expect = hlen;
225833e882a5SSuraj Sumangala 		scb->pkt_type = type;
225933e882a5SSuraj Sumangala 
226033e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
226133e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
226233e882a5SSuraj Sumangala 	}
226333e882a5SSuraj Sumangala 
226433e882a5SSuraj Sumangala 	while (count) {
226533e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
226689bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
226733e882a5SSuraj Sumangala 
226833e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
226933e882a5SSuraj Sumangala 
227033e882a5SSuraj Sumangala 		count -= len;
227133e882a5SSuraj Sumangala 		data += len;
227233e882a5SSuraj Sumangala 		scb->expect -= len;
227333e882a5SSuraj Sumangala 		remain = count;
227433e882a5SSuraj Sumangala 
227533e882a5SSuraj Sumangala 		switch (type) {
227633e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
227733e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
227833e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
227933e882a5SSuraj Sumangala 				scb->expect = h->plen;
228033e882a5SSuraj Sumangala 
228133e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
228233e882a5SSuraj Sumangala 					kfree_skb(skb);
228333e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
228433e882a5SSuraj Sumangala 					return -ENOMEM;
228533e882a5SSuraj Sumangala 				}
228633e882a5SSuraj Sumangala 			}
228733e882a5SSuraj Sumangala 			break;
228833e882a5SSuraj Sumangala 
228933e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
229033e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
229133e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
229233e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
229333e882a5SSuraj Sumangala 
229433e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
229533e882a5SSuraj Sumangala 					kfree_skb(skb);
229633e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
229733e882a5SSuraj Sumangala 					return -ENOMEM;
229833e882a5SSuraj Sumangala 				}
229933e882a5SSuraj Sumangala 			}
230033e882a5SSuraj Sumangala 			break;
230133e882a5SSuraj Sumangala 
230233e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
230333e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
230433e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
230533e882a5SSuraj Sumangala 				scb->expect = h->dlen;
230633e882a5SSuraj Sumangala 
230733e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
230833e882a5SSuraj Sumangala 					kfree_skb(skb);
230933e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
231033e882a5SSuraj Sumangala 					return -ENOMEM;
231133e882a5SSuraj Sumangala 				}
231233e882a5SSuraj Sumangala 			}
231333e882a5SSuraj Sumangala 			break;
231433e882a5SSuraj Sumangala 		}
231533e882a5SSuraj Sumangala 
231633e882a5SSuraj Sumangala 		if (scb->expect == 0) {
231733e882a5SSuraj Sumangala 			/* Complete frame */
231833e882a5SSuraj Sumangala 
231933e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
232033e882a5SSuraj Sumangala 			hci_recv_frame(skb);
232133e882a5SSuraj Sumangala 
232233e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
232333e882a5SSuraj Sumangala 			return remain;
232433e882a5SSuraj Sumangala 		}
232533e882a5SSuraj Sumangala 	}
232633e882a5SSuraj Sumangala 
232733e882a5SSuraj Sumangala 	return remain;
232833e882a5SSuraj Sumangala }
232933e882a5SSuraj Sumangala 
2330ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
2331ef222013SMarcel Holtmann {
2332f39a3c06SSuraj Sumangala 	int rem = 0;
2333f39a3c06SSuraj Sumangala 
2334ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
2335ef222013SMarcel Holtmann 		return -EILSEQ;
2336ef222013SMarcel Holtmann 
2337da5f6c37SGustavo F. Padovan 	while (count) {
23381e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
2339f39a3c06SSuraj Sumangala 		if (rem < 0)
2340f39a3c06SSuraj Sumangala 			return rem;
2341ef222013SMarcel Holtmann 
2342f39a3c06SSuraj Sumangala 		data += (count - rem);
2343f39a3c06SSuraj Sumangala 		count = rem;
2344f81c6224SJoe Perches 	}
2345ef222013SMarcel Holtmann 
2346f39a3c06SSuraj Sumangala 	return rem;
2347ef222013SMarcel Holtmann }
2348ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
2349ef222013SMarcel Holtmann 
235099811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
235199811510SSuraj Sumangala 
235299811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
235399811510SSuraj Sumangala {
235499811510SSuraj Sumangala 	int type;
235599811510SSuraj Sumangala 	int rem = 0;
235699811510SSuraj Sumangala 
2357da5f6c37SGustavo F. Padovan 	while (count) {
235899811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
235999811510SSuraj Sumangala 
236099811510SSuraj Sumangala 		if (!skb) {
236199811510SSuraj Sumangala 			struct { char type; } *pkt;
236299811510SSuraj Sumangala 
236399811510SSuraj Sumangala 			/* Start of the frame */
236499811510SSuraj Sumangala 			pkt = data;
236599811510SSuraj Sumangala 			type = pkt->type;
236699811510SSuraj Sumangala 
236799811510SSuraj Sumangala 			data++;
236899811510SSuraj Sumangala 			count--;
236999811510SSuraj Sumangala 		} else
237099811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
237199811510SSuraj Sumangala 
23721e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
23731e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
237499811510SSuraj Sumangala 		if (rem < 0)
237599811510SSuraj Sumangala 			return rem;
237699811510SSuraj Sumangala 
237799811510SSuraj Sumangala 		data += (count - rem);
237899811510SSuraj Sumangala 		count = rem;
2379f81c6224SJoe Perches 	}
238099811510SSuraj Sumangala 
238199811510SSuraj Sumangala 	return rem;
238299811510SSuraj Sumangala }
238399811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
238499811510SSuraj Sumangala 
23851da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
23861da177e4SLinus Torvalds 
23871da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
23881da177e4SLinus Torvalds {
23891da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
23901da177e4SLinus Torvalds 
2391f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
23921da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2393f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
23941da177e4SLinus Torvalds 
23951da177e4SLinus Torvalds 	return 0;
23961da177e4SLinus Torvalds }
23971da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
23981da177e4SLinus Torvalds 
23991da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
24001da177e4SLinus Torvalds {
24011da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
24021da177e4SLinus Torvalds 
2403f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
24041da177e4SLinus Torvalds 	list_del(&cb->list);
2405f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
24061da177e4SLinus Torvalds 
24071da177e4SLinus Torvalds 	return 0;
24081da177e4SLinus Torvalds }
24091da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
24101da177e4SLinus Torvalds 
24111da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
24121da177e4SLinus Torvalds {
24131da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
24141da177e4SLinus Torvalds 
24151da177e4SLinus Torvalds 	if (!hdev) {
24161da177e4SLinus Torvalds 		kfree_skb(skb);
24171da177e4SLinus Torvalds 		return -ENODEV;
24181da177e4SLinus Torvalds 	}
24191da177e4SLinus Torvalds 
24200d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
24211da177e4SLinus Torvalds 
24221da177e4SLinus Torvalds 	/* Time stamp */
2423a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
24241da177e4SLinus Torvalds 
2425cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2426cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2427cd82e61cSMarcel Holtmann 
2428cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2429cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2430470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
24311da177e4SLinus Torvalds 	}
24321da177e4SLinus Torvalds 
24331da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
24341da177e4SLinus Torvalds 	skb_orphan(skb);
24351da177e4SLinus Torvalds 
24361da177e4SLinus Torvalds 	return hdev->send(skb);
24371da177e4SLinus Torvalds }
24381da177e4SLinus Torvalds 
24393119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
24403119ae95SJohan Hedberg {
24413119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
24423119ae95SJohan Hedberg 	req->hdev = hdev;
24433119ae95SJohan Hedberg }
24443119ae95SJohan Hedberg 
24453119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
24463119ae95SJohan Hedberg {
24473119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
24483119ae95SJohan Hedberg 	struct sk_buff *skb;
24493119ae95SJohan Hedberg 	unsigned long flags;
24503119ae95SJohan Hedberg 
24513119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
24523119ae95SJohan Hedberg 
24533119ae95SJohan Hedberg 	/* Do not allow empty requests */
24543119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
2455382b0c39SAndre Guedes 		return -ENODATA;
24563119ae95SJohan Hedberg 
24573119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
24583119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
24593119ae95SJohan Hedberg 
24603119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
24613119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
24623119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
24633119ae95SJohan Hedberg 
24643119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
24653119ae95SJohan Hedberg 
24663119ae95SJohan Hedberg 	return 0;
24673119ae95SJohan Hedberg }
24683119ae95SJohan Hedberg 
24691ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
24701ca3a9d0SJohan Hedberg 				       u32 plen, void *param)
24711da177e4SLinus Torvalds {
24721da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
24731da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
24741da177e4SLinus Torvalds 	struct sk_buff *skb;
24751da177e4SLinus Torvalds 
24761da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
24771ca3a9d0SJohan Hedberg 	if (!skb)
24781ca3a9d0SJohan Hedberg 		return NULL;
24791da177e4SLinus Torvalds 
24801da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2481a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
24821da177e4SLinus Torvalds 	hdr->plen   = plen;
24831da177e4SLinus Torvalds 
24841da177e4SLinus Torvalds 	if (plen)
24851da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
24861da177e4SLinus Torvalds 
24871da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
24881da177e4SLinus Torvalds 
24890d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
24901da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2491c78ae283SMarcel Holtmann 
24921ca3a9d0SJohan Hedberg 	return skb;
24931ca3a9d0SJohan Hedberg }
24941ca3a9d0SJohan Hedberg 
24951ca3a9d0SJohan Hedberg /* Send HCI command */
24961ca3a9d0SJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
24971ca3a9d0SJohan Hedberg {
24981ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
24991ca3a9d0SJohan Hedberg 
25001ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
25011ca3a9d0SJohan Hedberg 
25021ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
25031ca3a9d0SJohan Hedberg 	if (!skb) {
25041ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
25051ca3a9d0SJohan Hedberg 		return -ENOMEM;
25061ca3a9d0SJohan Hedberg 	}
25071ca3a9d0SJohan Hedberg 
250811714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
250911714b3dSJohan Hedberg 	 * single-command requests.
251011714b3dSJohan Hedberg 	 */
251111714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
251211714b3dSJohan Hedberg 
25131da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2514c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
25151da177e4SLinus Torvalds 
25161da177e4SLinus Torvalds 	return 0;
25171da177e4SLinus Torvalds }
25181da177e4SLinus Torvalds 
251971c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
252071c76a17SJohan Hedberg int hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param)
252171c76a17SJohan Hedberg {
252271c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
252371c76a17SJohan Hedberg 	struct sk_buff *skb;
252471c76a17SJohan Hedberg 
252571c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
252671c76a17SJohan Hedberg 
252771c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
252871c76a17SJohan Hedberg 	if (!skb) {
252971c76a17SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
253071c76a17SJohan Hedberg 		return -ENOMEM;
253171c76a17SJohan Hedberg 	}
253271c76a17SJohan Hedberg 
253371c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
253471c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
253571c76a17SJohan Hedberg 
253671c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
253771c76a17SJohan Hedberg 
253871c76a17SJohan Hedberg 	return 0;
253971c76a17SJohan Hedberg }
254071c76a17SJohan Hedberg 
25411da177e4SLinus Torvalds /* Get data from the previously sent command */
2542a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
25431da177e4SLinus Torvalds {
25441da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
25451da177e4SLinus Torvalds 
25461da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
25471da177e4SLinus Torvalds 		return NULL;
25481da177e4SLinus Torvalds 
25491da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
25501da177e4SLinus Torvalds 
2551a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
25521da177e4SLinus Torvalds 		return NULL;
25531da177e4SLinus Torvalds 
2554f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
25551da177e4SLinus Torvalds 
25561da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
25571da177e4SLinus Torvalds }
25581da177e4SLinus Torvalds 
25591da177e4SLinus Torvalds /* Send ACL data */
25601da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
25611da177e4SLinus Torvalds {
25621da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
25631da177e4SLinus Torvalds 	int len = skb->len;
25641da177e4SLinus Torvalds 
2565badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2566badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
25679c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2568aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2569aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
25701da177e4SLinus Torvalds }
25711da177e4SLinus Torvalds 
2572ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
257373d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
25741da177e4SLinus Torvalds {
2575ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
25761da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
25771da177e4SLinus Torvalds 	struct sk_buff *list;
25781da177e4SLinus Torvalds 
2579087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
2580087bfd99SGustavo Padovan 	skb->data_len = 0;
2581087bfd99SGustavo Padovan 
2582087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2583204a6e54SAndrei Emeltchenko 
2584204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
2585204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
2586087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
2587204a6e54SAndrei Emeltchenko 		break;
2588204a6e54SAndrei Emeltchenko 	case HCI_AMP:
2589204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
2590204a6e54SAndrei Emeltchenko 		break;
2591204a6e54SAndrei Emeltchenko 	default:
2592204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2593204a6e54SAndrei Emeltchenko 		return;
2594204a6e54SAndrei Emeltchenko 	}
2595087bfd99SGustavo Padovan 
259670f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
259770f23020SAndrei Emeltchenko 	if (!list) {
25981da177e4SLinus Torvalds 		/* Non fragmented */
25991da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
26001da177e4SLinus Torvalds 
260173d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
26021da177e4SLinus Torvalds 	} else {
26031da177e4SLinus Torvalds 		/* Fragmented */
26041da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
26051da177e4SLinus Torvalds 
26061da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
26071da177e4SLinus Torvalds 
26081da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2609af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
26101da177e4SLinus Torvalds 
261173d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2612e702112fSAndrei Emeltchenko 
2613e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2614e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
26151da177e4SLinus Torvalds 		do {
26161da177e4SLinus Torvalds 			skb = list; list = list->next;
26171da177e4SLinus Torvalds 
26181da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
26190d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2620e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
26211da177e4SLinus Torvalds 
26221da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
26231da177e4SLinus Torvalds 
262473d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
26251da177e4SLinus Torvalds 		} while (list);
26261da177e4SLinus Torvalds 
2627af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
26281da177e4SLinus Torvalds 	}
262973d80debSLuiz Augusto von Dentz }
263073d80debSLuiz Augusto von Dentz 
263173d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
263273d80debSLuiz Augusto von Dentz {
2633ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
263473d80debSLuiz Augusto von Dentz 
2635f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
263673d80debSLuiz Augusto von Dentz 
263773d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
263873d80debSLuiz Augusto von Dentz 
2639ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
26401da177e4SLinus Torvalds 
26413eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
26421da177e4SLinus Torvalds }
26431da177e4SLinus Torvalds 
26441da177e4SLinus Torvalds /* Send SCO data */
26450d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
26461da177e4SLinus Torvalds {
26471da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
26481da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
26491da177e4SLinus Torvalds 
26501da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
26511da177e4SLinus Torvalds 
2652aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
26531da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
26541da177e4SLinus Torvalds 
2655badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2656badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
26579c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
26581da177e4SLinus Torvalds 
26591da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
26600d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2661c78ae283SMarcel Holtmann 
26621da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
26633eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
26641da177e4SLinus Torvalds }
26651da177e4SLinus Torvalds 
26661da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
26671da177e4SLinus Torvalds 
26681da177e4SLinus Torvalds /* HCI Connection scheduler */
26696039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
2670a8c5fb1aSGustavo Padovan 				     int *quote)
26711da177e4SLinus Torvalds {
26721da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
26738035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
2674abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
26751da177e4SLinus Torvalds 
26761da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
26771da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2678bf4c6325SGustavo F. Padovan 
2679bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2680bf4c6325SGustavo F. Padovan 
2681bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2682769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
26831da177e4SLinus Torvalds 			continue;
2684769be974SMarcel Holtmann 
2685769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2686769be974SMarcel Holtmann 			continue;
2687769be974SMarcel Holtmann 
26881da177e4SLinus Torvalds 		num++;
26891da177e4SLinus Torvalds 
26901da177e4SLinus Torvalds 		if (c->sent < min) {
26911da177e4SLinus Torvalds 			min  = c->sent;
26921da177e4SLinus Torvalds 			conn = c;
26931da177e4SLinus Torvalds 		}
269452087a79SLuiz Augusto von Dentz 
269552087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
269652087a79SLuiz Augusto von Dentz 			break;
26971da177e4SLinus Torvalds 	}
26981da177e4SLinus Torvalds 
2699bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2700bf4c6325SGustavo F. Padovan 
27011da177e4SLinus Torvalds 	if (conn) {
27026ed58ec5SVille Tervo 		int cnt, q;
27036ed58ec5SVille Tervo 
27046ed58ec5SVille Tervo 		switch (conn->type) {
27056ed58ec5SVille Tervo 		case ACL_LINK:
27066ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
27076ed58ec5SVille Tervo 			break;
27086ed58ec5SVille Tervo 		case SCO_LINK:
27096ed58ec5SVille Tervo 		case ESCO_LINK:
27106ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
27116ed58ec5SVille Tervo 			break;
27126ed58ec5SVille Tervo 		case LE_LINK:
27136ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
27146ed58ec5SVille Tervo 			break;
27156ed58ec5SVille Tervo 		default:
27166ed58ec5SVille Tervo 			cnt = 0;
27176ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
27186ed58ec5SVille Tervo 		}
27196ed58ec5SVille Tervo 
27206ed58ec5SVille Tervo 		q = cnt / num;
27211da177e4SLinus Torvalds 		*quote = q ? q : 1;
27221da177e4SLinus Torvalds 	} else
27231da177e4SLinus Torvalds 		*quote = 0;
27241da177e4SLinus Torvalds 
27251da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
27261da177e4SLinus Torvalds 	return conn;
27271da177e4SLinus Torvalds }
27281da177e4SLinus Torvalds 
27296039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
27301da177e4SLinus Torvalds {
27311da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
27321da177e4SLinus Torvalds 	struct hci_conn *c;
27331da177e4SLinus Torvalds 
2734bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
27351da177e4SLinus Torvalds 
2736bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2737bf4c6325SGustavo F. Padovan 
27381da177e4SLinus Torvalds 	/* Kill stalled connections */
2739bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2740bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
27416ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
27426ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
2743bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
27441da177e4SLinus Torvalds 		}
27451da177e4SLinus Torvalds 	}
2746bf4c6325SGustavo F. Padovan 
2747bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
27481da177e4SLinus Torvalds }
27491da177e4SLinus Torvalds 
27506039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
275173d80debSLuiz Augusto von Dentz 				      int *quote)
275273d80debSLuiz Augusto von Dentz {
275373d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
275473d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
2755abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
275673d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
275773d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
275873d80debSLuiz Augusto von Dentz 
275973d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
276073d80debSLuiz Augusto von Dentz 
2761bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2762bf4c6325SGustavo F. Padovan 
2763bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
276473d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
276573d80debSLuiz Augusto von Dentz 
276673d80debSLuiz Augusto von Dentz 		if (conn->type != type)
276773d80debSLuiz Augusto von Dentz 			continue;
276873d80debSLuiz Augusto von Dentz 
276973d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
277073d80debSLuiz Augusto von Dentz 			continue;
277173d80debSLuiz Augusto von Dentz 
277273d80debSLuiz Augusto von Dentz 		conn_num++;
277373d80debSLuiz Augusto von Dentz 
27748192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
277573d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
277673d80debSLuiz Augusto von Dentz 
277773d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
277873d80debSLuiz Augusto von Dentz 				continue;
277973d80debSLuiz Augusto von Dentz 
278073d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
278173d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
278273d80debSLuiz Augusto von Dentz 				continue;
278373d80debSLuiz Augusto von Dentz 
278473d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
278573d80debSLuiz Augusto von Dentz 				num = 0;
278673d80debSLuiz Augusto von Dentz 				min = ~0;
278773d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
278873d80debSLuiz Augusto von Dentz 			}
278973d80debSLuiz Augusto von Dentz 
279073d80debSLuiz Augusto von Dentz 			num++;
279173d80debSLuiz Augusto von Dentz 
279273d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
279373d80debSLuiz Augusto von Dentz 				min  = conn->sent;
279473d80debSLuiz Augusto von Dentz 				chan = tmp;
279573d80debSLuiz Augusto von Dentz 			}
279673d80debSLuiz Augusto von Dentz 		}
279773d80debSLuiz Augusto von Dentz 
279873d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
279973d80debSLuiz Augusto von Dentz 			break;
280073d80debSLuiz Augusto von Dentz 	}
280173d80debSLuiz Augusto von Dentz 
2802bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2803bf4c6325SGustavo F. Padovan 
280473d80debSLuiz Augusto von Dentz 	if (!chan)
280573d80debSLuiz Augusto von Dentz 		return NULL;
280673d80debSLuiz Augusto von Dentz 
280773d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
280873d80debSLuiz Augusto von Dentz 	case ACL_LINK:
280973d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
281073d80debSLuiz Augusto von Dentz 		break;
2811bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
2812bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
2813bd1eb66bSAndrei Emeltchenko 		break;
281473d80debSLuiz Augusto von Dentz 	case SCO_LINK:
281573d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
281673d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
281773d80debSLuiz Augusto von Dentz 		break;
281873d80debSLuiz Augusto von Dentz 	case LE_LINK:
281973d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
282073d80debSLuiz Augusto von Dentz 		break;
282173d80debSLuiz Augusto von Dentz 	default:
282273d80debSLuiz Augusto von Dentz 		cnt = 0;
282373d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
282473d80debSLuiz Augusto von Dentz 	}
282573d80debSLuiz Augusto von Dentz 
282673d80debSLuiz Augusto von Dentz 	q = cnt / num;
282773d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
282873d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
282973d80debSLuiz Augusto von Dentz 	return chan;
283073d80debSLuiz Augusto von Dentz }
283173d80debSLuiz Augusto von Dentz 
283202b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
283302b20f0bSLuiz Augusto von Dentz {
283402b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
283502b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
283602b20f0bSLuiz Augusto von Dentz 	int num = 0;
283702b20f0bSLuiz Augusto von Dentz 
283802b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
283902b20f0bSLuiz Augusto von Dentz 
2840bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2841bf4c6325SGustavo F. Padovan 
2842bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
284302b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
284402b20f0bSLuiz Augusto von Dentz 
284502b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
284602b20f0bSLuiz Augusto von Dentz 			continue;
284702b20f0bSLuiz Augusto von Dentz 
284802b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
284902b20f0bSLuiz Augusto von Dentz 			continue;
285002b20f0bSLuiz Augusto von Dentz 
285102b20f0bSLuiz Augusto von Dentz 		num++;
285202b20f0bSLuiz Augusto von Dentz 
28538192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
285402b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
285502b20f0bSLuiz Augusto von Dentz 
285602b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
285702b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
285802b20f0bSLuiz Augusto von Dentz 				continue;
285902b20f0bSLuiz Augusto von Dentz 			}
286002b20f0bSLuiz Augusto von Dentz 
286102b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
286202b20f0bSLuiz Augusto von Dentz 				continue;
286302b20f0bSLuiz Augusto von Dentz 
286402b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
286502b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
286602b20f0bSLuiz Augusto von Dentz 				continue;
286702b20f0bSLuiz Augusto von Dentz 
286802b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
286902b20f0bSLuiz Augusto von Dentz 
287002b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
287102b20f0bSLuiz Augusto von Dentz 			       skb->priority);
287202b20f0bSLuiz Augusto von Dentz 		}
287302b20f0bSLuiz Augusto von Dentz 
287402b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
287502b20f0bSLuiz Augusto von Dentz 			break;
287602b20f0bSLuiz Augusto von Dentz 	}
2877bf4c6325SGustavo F. Padovan 
2878bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2879bf4c6325SGustavo F. Padovan 
288002b20f0bSLuiz Augusto von Dentz }
288102b20f0bSLuiz Augusto von Dentz 
2882b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
2883b71d385aSAndrei Emeltchenko {
2884b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
2885b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
2886b71d385aSAndrei Emeltchenko }
2887b71d385aSAndrei Emeltchenko 
28886039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
28891da177e4SLinus Torvalds {
28901da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
28911da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
28921da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
289363d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
28945f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
2895bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
28961da177e4SLinus Torvalds 	}
289763d2bc1bSAndrei Emeltchenko }
28981da177e4SLinus Torvalds 
28996039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
290063d2bc1bSAndrei Emeltchenko {
290163d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
290263d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
290363d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
290463d2bc1bSAndrei Emeltchenko 	int quote;
290563d2bc1bSAndrei Emeltchenko 
290663d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
290704837f64SMarcel Holtmann 
290873d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
290973d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2910ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2911ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
291273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
291373d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
291473d80debSLuiz Augusto von Dentz 
2915ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2916ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2917ec1cce24SLuiz Augusto von Dentz 				break;
2918ec1cce24SLuiz Augusto von Dentz 
2919ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2920ec1cce24SLuiz Augusto von Dentz 
292173d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
292273d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
292304837f64SMarcel Holtmann 
29241da177e4SLinus Torvalds 			hci_send_frame(skb);
29251da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
29261da177e4SLinus Torvalds 
29271da177e4SLinus Torvalds 			hdev->acl_cnt--;
292873d80debSLuiz Augusto von Dentz 			chan->sent++;
292973d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
29301da177e4SLinus Torvalds 		}
29311da177e4SLinus Torvalds 	}
293202b20f0bSLuiz Augusto von Dentz 
293302b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
293402b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
29351da177e4SLinus Torvalds }
29361da177e4SLinus Torvalds 
29376039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
2938b71d385aSAndrei Emeltchenko {
293963d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
2940b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
2941b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
2942b71d385aSAndrei Emeltchenko 	int quote;
2943bd1eb66bSAndrei Emeltchenko 	u8 type;
2944b71d385aSAndrei Emeltchenko 
294563d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
2946b71d385aSAndrei Emeltchenko 
2947bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
2948bd1eb66bSAndrei Emeltchenko 
2949bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
2950bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
2951bd1eb66bSAndrei Emeltchenko 	else
2952bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
2953bd1eb66bSAndrei Emeltchenko 
2954b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
2955bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
2956b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
2957b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
2958b71d385aSAndrei Emeltchenko 			int blocks;
2959b71d385aSAndrei Emeltchenko 
2960b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
2961b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
2962b71d385aSAndrei Emeltchenko 
2963b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
2964b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
2965b71d385aSAndrei Emeltchenko 				break;
2966b71d385aSAndrei Emeltchenko 
2967b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
2968b71d385aSAndrei Emeltchenko 
2969b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
2970b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
2971b71d385aSAndrei Emeltchenko 				return;
2972b71d385aSAndrei Emeltchenko 
2973b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
2974b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
2975b71d385aSAndrei Emeltchenko 
2976b71d385aSAndrei Emeltchenko 			hci_send_frame(skb);
2977b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
2978b71d385aSAndrei Emeltchenko 
2979b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
2980b71d385aSAndrei Emeltchenko 			quote -= blocks;
2981b71d385aSAndrei Emeltchenko 
2982b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
2983b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
2984b71d385aSAndrei Emeltchenko 		}
2985b71d385aSAndrei Emeltchenko 	}
2986b71d385aSAndrei Emeltchenko 
2987b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
2988bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
2989b71d385aSAndrei Emeltchenko }
2990b71d385aSAndrei Emeltchenko 
29916039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
2992b71d385aSAndrei Emeltchenko {
2993b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
2994b71d385aSAndrei Emeltchenko 
2995bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
2996bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
2997bd1eb66bSAndrei Emeltchenko 		return;
2998bd1eb66bSAndrei Emeltchenko 
2999bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3000bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3001b71d385aSAndrei Emeltchenko 		return;
3002b71d385aSAndrei Emeltchenko 
3003b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3004b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3005b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3006b71d385aSAndrei Emeltchenko 		break;
3007b71d385aSAndrei Emeltchenko 
3008b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3009b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3010b71d385aSAndrei Emeltchenko 		break;
3011b71d385aSAndrei Emeltchenko 	}
3012b71d385aSAndrei Emeltchenko }
3013b71d385aSAndrei Emeltchenko 
30141da177e4SLinus Torvalds /* Schedule SCO */
30156039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
30161da177e4SLinus Torvalds {
30171da177e4SLinus Torvalds 	struct hci_conn *conn;
30181da177e4SLinus Torvalds 	struct sk_buff *skb;
30191da177e4SLinus Torvalds 	int quote;
30201da177e4SLinus Torvalds 
30211da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
30221da177e4SLinus Torvalds 
302352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
302452087a79SLuiz Augusto von Dentz 		return;
302552087a79SLuiz Augusto von Dentz 
30261da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
30271da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
30281da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
30291da177e4SLinus Torvalds 			hci_send_frame(skb);
30301da177e4SLinus Torvalds 
30311da177e4SLinus Torvalds 			conn->sent++;
30321da177e4SLinus Torvalds 			if (conn->sent == ~0)
30331da177e4SLinus Torvalds 				conn->sent = 0;
30341da177e4SLinus Torvalds 		}
30351da177e4SLinus Torvalds 	}
30361da177e4SLinus Torvalds }
30371da177e4SLinus Torvalds 
30386039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
3039b6a0dc82SMarcel Holtmann {
3040b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
3041b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
3042b6a0dc82SMarcel Holtmann 	int quote;
3043b6a0dc82SMarcel Holtmann 
3044b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
3045b6a0dc82SMarcel Holtmann 
304652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
304752087a79SLuiz Augusto von Dentz 		return;
304852087a79SLuiz Augusto von Dentz 
30498fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
30508fc9ced3SGustavo Padovan 						     &quote))) {
3051b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
3052b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
3053b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
3054b6a0dc82SMarcel Holtmann 
3055b6a0dc82SMarcel Holtmann 			conn->sent++;
3056b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
3057b6a0dc82SMarcel Holtmann 				conn->sent = 0;
3058b6a0dc82SMarcel Holtmann 		}
3059b6a0dc82SMarcel Holtmann 	}
3060b6a0dc82SMarcel Holtmann }
3061b6a0dc82SMarcel Holtmann 
30626039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
30636ed58ec5SVille Tervo {
306473d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
30656ed58ec5SVille Tervo 	struct sk_buff *skb;
306602b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
30676ed58ec5SVille Tervo 
30686ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
30696ed58ec5SVille Tervo 
307052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
307152087a79SLuiz Augusto von Dentz 		return;
307252087a79SLuiz Augusto von Dentz 
30736ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
30746ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
30756ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
3076bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
30776ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
3078bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
30796ed58ec5SVille Tervo 	}
30806ed58ec5SVille Tervo 
30816ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
308202b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
308373d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3084ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3085ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
308673d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
308773d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
30886ed58ec5SVille Tervo 
3089ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3090ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3091ec1cce24SLuiz Augusto von Dentz 				break;
3092ec1cce24SLuiz Augusto von Dentz 
3093ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3094ec1cce24SLuiz Augusto von Dentz 
30956ed58ec5SVille Tervo 			hci_send_frame(skb);
30966ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
30976ed58ec5SVille Tervo 
30986ed58ec5SVille Tervo 			cnt--;
309973d80debSLuiz Augusto von Dentz 			chan->sent++;
310073d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
31016ed58ec5SVille Tervo 		}
31026ed58ec5SVille Tervo 	}
310373d80debSLuiz Augusto von Dentz 
31046ed58ec5SVille Tervo 	if (hdev->le_pkts)
31056ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
31066ed58ec5SVille Tervo 	else
31076ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
310802b20f0bSLuiz Augusto von Dentz 
310902b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
311002b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
31116ed58ec5SVille Tervo }
31126ed58ec5SVille Tervo 
31133eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
31141da177e4SLinus Torvalds {
31153eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
31161da177e4SLinus Torvalds 	struct sk_buff *skb;
31171da177e4SLinus Torvalds 
31186ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
31196ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
31201da177e4SLinus Torvalds 
31211da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
31221da177e4SLinus Torvalds 
31231da177e4SLinus Torvalds 	hci_sched_acl(hdev);
31241da177e4SLinus Torvalds 
31251da177e4SLinus Torvalds 	hci_sched_sco(hdev);
31261da177e4SLinus Torvalds 
3127b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
3128b6a0dc82SMarcel Holtmann 
31296ed58ec5SVille Tervo 	hci_sched_le(hdev);
31306ed58ec5SVille Tervo 
31311da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
31321da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
31331da177e4SLinus Torvalds 		hci_send_frame(skb);
31341da177e4SLinus Torvalds }
31351da177e4SLinus Torvalds 
313625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
31371da177e4SLinus Torvalds 
31381da177e4SLinus Torvalds /* ACL data packet */
31396039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
31401da177e4SLinus Torvalds {
31411da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
31421da177e4SLinus Torvalds 	struct hci_conn *conn;
31431da177e4SLinus Torvalds 	__u16 handle, flags;
31441da177e4SLinus Torvalds 
31451da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
31461da177e4SLinus Torvalds 
31471da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
31481da177e4SLinus Torvalds 	flags  = hci_flags(handle);
31491da177e4SLinus Torvalds 	handle = hci_handle(handle);
31501da177e4SLinus Torvalds 
3151f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3152a8c5fb1aSGustavo Padovan 	       handle, flags);
31531da177e4SLinus Torvalds 
31541da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
31551da177e4SLinus Torvalds 
31561da177e4SLinus Torvalds 	hci_dev_lock(hdev);
31571da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
31581da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
31591da177e4SLinus Torvalds 
31601da177e4SLinus Torvalds 	if (conn) {
316165983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
316204837f64SMarcel Holtmann 
31631da177e4SLinus Torvalds 		/* Send to upper protocol */
3164686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
31651da177e4SLinus Torvalds 		return;
31661da177e4SLinus Torvalds 	} else {
31671da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
31681da177e4SLinus Torvalds 		       hdev->name, handle);
31691da177e4SLinus Torvalds 	}
31701da177e4SLinus Torvalds 
31711da177e4SLinus Torvalds 	kfree_skb(skb);
31721da177e4SLinus Torvalds }
31731da177e4SLinus Torvalds 
31741da177e4SLinus Torvalds /* SCO data packet */
31756039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
31761da177e4SLinus Torvalds {
31771da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
31781da177e4SLinus Torvalds 	struct hci_conn *conn;
31791da177e4SLinus Torvalds 	__u16 handle;
31801da177e4SLinus Torvalds 
31811da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
31821da177e4SLinus Torvalds 
31831da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
31841da177e4SLinus Torvalds 
3185f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
31861da177e4SLinus Torvalds 
31871da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
31881da177e4SLinus Torvalds 
31891da177e4SLinus Torvalds 	hci_dev_lock(hdev);
31901da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
31911da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
31921da177e4SLinus Torvalds 
31931da177e4SLinus Torvalds 	if (conn) {
31941da177e4SLinus Torvalds 		/* Send to upper protocol */
3195686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
31961da177e4SLinus Torvalds 		return;
31971da177e4SLinus Torvalds 	} else {
31981da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
31991da177e4SLinus Torvalds 		       hdev->name, handle);
32001da177e4SLinus Torvalds 	}
32011da177e4SLinus Torvalds 
32021da177e4SLinus Torvalds 	kfree_skb(skb);
32031da177e4SLinus Torvalds }
32041da177e4SLinus Torvalds 
32059238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
32069238f36aSJohan Hedberg {
32079238f36aSJohan Hedberg 	struct sk_buff *skb;
32089238f36aSJohan Hedberg 
32099238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
32109238f36aSJohan Hedberg 	if (!skb)
32119238f36aSJohan Hedberg 		return true;
32129238f36aSJohan Hedberg 
32139238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
32149238f36aSJohan Hedberg }
32159238f36aSJohan Hedberg 
321642c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
321742c6b129SJohan Hedberg {
321842c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
321942c6b129SJohan Hedberg 	struct sk_buff *skb;
322042c6b129SJohan Hedberg 	u16 opcode;
322142c6b129SJohan Hedberg 
322242c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
322342c6b129SJohan Hedberg 		return;
322442c6b129SJohan Hedberg 
322542c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
322642c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
322742c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
322842c6b129SJohan Hedberg 		return;
322942c6b129SJohan Hedberg 
323042c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
323142c6b129SJohan Hedberg 	if (!skb)
323242c6b129SJohan Hedberg 		return;
323342c6b129SJohan Hedberg 
323442c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
323542c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
323642c6b129SJohan Hedberg }
323742c6b129SJohan Hedberg 
32389238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
32399238f36aSJohan Hedberg {
32409238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
32419238f36aSJohan Hedberg 	struct sk_buff *skb;
32429238f36aSJohan Hedberg 	unsigned long flags;
32439238f36aSJohan Hedberg 
32449238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
32459238f36aSJohan Hedberg 
324642c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
324742c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
32489238f36aSJohan Hedberg 	 */
324942c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
325042c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
325142c6b129SJohan Hedberg 		 * reset complete event during init and any pending
325242c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
325342c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
325442c6b129SJohan Hedberg 		 * command.
325542c6b129SJohan Hedberg 		 */
325642c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
325742c6b129SJohan Hedberg 			hci_resend_last(hdev);
325842c6b129SJohan Hedberg 
32599238f36aSJohan Hedberg 		return;
326042c6b129SJohan Hedberg 	}
32619238f36aSJohan Hedberg 
32629238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
32639238f36aSJohan Hedberg 	 * this request the request is not yet complete.
32649238f36aSJohan Hedberg 	 */
32659238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
32669238f36aSJohan Hedberg 		return;
32679238f36aSJohan Hedberg 
32689238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
32699238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
32709238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
32719238f36aSJohan Hedberg 	 */
32729238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
32739238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
32749238f36aSJohan Hedberg 		if (req_complete)
32759238f36aSJohan Hedberg 			goto call_complete;
32769238f36aSJohan Hedberg 	}
32779238f36aSJohan Hedberg 
32789238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
32799238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
32809238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
32819238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
32829238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
32839238f36aSJohan Hedberg 			break;
32849238f36aSJohan Hedberg 		}
32859238f36aSJohan Hedberg 
32869238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
32879238f36aSJohan Hedberg 		kfree_skb(skb);
32889238f36aSJohan Hedberg 	}
32899238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
32909238f36aSJohan Hedberg 
32919238f36aSJohan Hedberg call_complete:
32929238f36aSJohan Hedberg 	if (req_complete)
32939238f36aSJohan Hedberg 		req_complete(hdev, status);
32949238f36aSJohan Hedberg }
32959238f36aSJohan Hedberg 
32969238f36aSJohan Hedberg void hci_req_cmd_status(struct hci_dev *hdev, u16 opcode, u8 status)
32979238f36aSJohan Hedberg {
32989238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
32999238f36aSJohan Hedberg 
33009238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
33019238f36aSJohan Hedberg 
33029238f36aSJohan Hedberg 	if (status) {
33039238f36aSJohan Hedberg 		hci_req_cmd_complete(hdev, opcode, status);
33049238f36aSJohan Hedberg 		return;
33059238f36aSJohan Hedberg 	}
33069238f36aSJohan Hedberg 
33079238f36aSJohan Hedberg 	/* No need to handle success status if there are more commands */
33089238f36aSJohan Hedberg 	if (!hci_req_is_complete(hdev))
33099238f36aSJohan Hedberg 		return;
33109238f36aSJohan Hedberg 
33119238f36aSJohan Hedberg 	if (hdev->sent_cmd)
33129238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
33139238f36aSJohan Hedberg 
33149238f36aSJohan Hedberg 	/* If the request doesn't have a complete callback or there
33159238f36aSJohan Hedberg 	 * are other commands/requests in the hdev queue we consider
33169238f36aSJohan Hedberg 	 * this request as completed.
33179238f36aSJohan Hedberg 	 */
33189238f36aSJohan Hedberg 	if (!req_complete || !skb_queue_empty(&hdev->cmd_q))
33199238f36aSJohan Hedberg 		hci_req_cmd_complete(hdev, opcode, status);
33209238f36aSJohan Hedberg }
33219238f36aSJohan Hedberg 
3322b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
33231da177e4SLinus Torvalds {
3324b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
33251da177e4SLinus Torvalds 	struct sk_buff *skb;
33261da177e4SLinus Torvalds 
33271da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
33281da177e4SLinus Torvalds 
33291da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
3330cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
3331cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
3332cd82e61cSMarcel Holtmann 
33331da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
33341da177e4SLinus Torvalds 			/* Send copy to the sockets */
3335470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
33361da177e4SLinus Torvalds 		}
33371da177e4SLinus Torvalds 
33381da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
33391da177e4SLinus Torvalds 			kfree_skb(skb);
33401da177e4SLinus Torvalds 			continue;
33411da177e4SLinus Torvalds 		}
33421da177e4SLinus Torvalds 
33431da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
33441da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
33450d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
33461da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
33471da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
33481da177e4SLinus Torvalds 				kfree_skb(skb);
33491da177e4SLinus Torvalds 				continue;
33503ff50b79SStephen Hemminger 			}
33511da177e4SLinus Torvalds 		}
33521da177e4SLinus Torvalds 
33531da177e4SLinus Torvalds 		/* Process frame */
33540d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
33551da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
3356b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
33571da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
33581da177e4SLinus Torvalds 			break;
33591da177e4SLinus Torvalds 
33601da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
33611da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
33621da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
33631da177e4SLinus Torvalds 			break;
33641da177e4SLinus Torvalds 
33651da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
33661da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
33671da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
33681da177e4SLinus Torvalds 			break;
33691da177e4SLinus Torvalds 
33701da177e4SLinus Torvalds 		default:
33711da177e4SLinus Torvalds 			kfree_skb(skb);
33721da177e4SLinus Torvalds 			break;
33731da177e4SLinus Torvalds 		}
33741da177e4SLinus Torvalds 	}
33751da177e4SLinus Torvalds }
33761da177e4SLinus Torvalds 
3377c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
33781da177e4SLinus Torvalds {
3379c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
33801da177e4SLinus Torvalds 	struct sk_buff *skb;
33811da177e4SLinus Torvalds 
33822104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
33832104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
33841da177e4SLinus Torvalds 
33851da177e4SLinus Torvalds 	/* Send queued commands */
33865a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
33875a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
33885a08ecceSAndrei Emeltchenko 		if (!skb)
33895a08ecceSAndrei Emeltchenko 			return;
33905a08ecceSAndrei Emeltchenko 
33911da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
33921da177e4SLinus Torvalds 
339370f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
339470f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
33951da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
33961da177e4SLinus Torvalds 			hci_send_frame(skb);
33977bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
33987bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
33997bdb8a5cSSzymon Janc 			else
34006bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
34015f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
34021da177e4SLinus Torvalds 		} else {
34031da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
3404c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
34051da177e4SLinus Torvalds 		}
34061da177e4SLinus Torvalds 	}
34071da177e4SLinus Torvalds }
34082519a1fcSAndre Guedes 
34092519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
34102519a1fcSAndre Guedes {
34112519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
34122519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
34132519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
34142519a1fcSAndre Guedes 
34152519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
34162519a1fcSAndre Guedes 
34172519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
34182519a1fcSAndre Guedes 		return -EINPROGRESS;
34192519a1fcSAndre Guedes 
34204663262cSJohan Hedberg 	inquiry_cache_flush(hdev);
34214663262cSJohan Hedberg 
34222519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
34232519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
34242519a1fcSAndre Guedes 	cp.length  = length;
34252519a1fcSAndre Guedes 
34262519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
34272519a1fcSAndre Guedes }
3428023d5049SAndre Guedes 
3429023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
3430023d5049SAndre Guedes {
3431023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
3432023d5049SAndre Guedes 
3433023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
34347537e5c3SAndre Guedes 		return -EALREADY;
3435023d5049SAndre Guedes 
3436023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
3437023d5049SAndre Guedes }
343831f7956cSAndre Guedes 
343931f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type)
344031f7956cSAndre Guedes {
344131f7956cSAndre Guedes 	switch (bdaddr_type) {
344231f7956cSAndre Guedes 	case BDADDR_LE_PUBLIC:
344331f7956cSAndre Guedes 		return ADDR_LE_DEV_PUBLIC;
344431f7956cSAndre Guedes 
344531f7956cSAndre Guedes 	default:
344631f7956cSAndre Guedes 		/* Fallback to LE Random address type */
344731f7956cSAndre Guedes 		return ADDR_LE_DEV_RANDOM;
344831f7956cSAndre Guedes 	}
344931f7956cSAndre Guedes }
3450