xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 9345d40c)
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 
6023bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
611da177e4SLinus Torvalds {
62f0e09510SAndrei Emeltchenko 	BT_DBG("%s command 0x%4.4x result 0x%2.2x", hdev->name, cmd, result);
6323bb5763SJohan Hedberg 
64a5040efaSJohan Hedberg 	/* If this is the init phase check if the completed command matches
65a5040efaSJohan Hedberg 	 * the last init command, and if not just return.
66a5040efaSJohan Hedberg 	 */
6775fb0e32SJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) {
6875fb0e32SJohan Hedberg 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
691036b890SAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
7075fb0e32SJohan Hedberg 		struct sk_buff *skb;
7175fb0e32SJohan Hedberg 
7275fb0e32SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
7375fb0e32SJohan Hedberg 		 * reset complete event during init and any pending
7475fb0e32SJohan Hedberg 		 * command will never be completed. In such a case we
7575fb0e32SJohan Hedberg 		 * need to resend whatever was the last sent
7675fb0e32SJohan Hedberg 		 * command.
7775fb0e32SJohan Hedberg 		 */
7875fb0e32SJohan Hedberg 
791036b890SAndrei Emeltchenko 		if (cmd != HCI_OP_RESET || opcode == HCI_OP_RESET)
8023bb5763SJohan Hedberg 			return;
811da177e4SLinus Torvalds 
8275fb0e32SJohan Hedberg 		skb = skb_clone(hdev->sent_cmd, GFP_ATOMIC);
8375fb0e32SJohan Hedberg 		if (skb) {
8475fb0e32SJohan Hedberg 			skb_queue_head(&hdev->cmd_q, skb);
8575fb0e32SJohan Hedberg 			queue_work(hdev->workqueue, &hdev->cmd_work);
8675fb0e32SJohan Hedberg 		}
8775fb0e32SJohan Hedberg 
8875fb0e32SJohan Hedberg 		return;
8975fb0e32SJohan Hedberg 	}
9075fb0e32SJohan Hedberg 
911da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
921da177e4SLinus Torvalds 		hdev->req_result = result;
931da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
941da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
951da177e4SLinus Torvalds 	}
961da177e4SLinus Torvalds }
971da177e4SLinus Torvalds 
981da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
991da177e4SLinus Torvalds {
1001da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
1011da177e4SLinus Torvalds 
1021da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1031da177e4SLinus Torvalds 		hdev->req_result = err;
1041da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
1051da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1061da177e4SLinus Torvalds 	}
1071da177e4SLinus Torvalds }
1081da177e4SLinus Torvalds 
1091da177e4SLinus Torvalds /* Execute request and wait for completion. */
110a8c5fb1aSGustavo Padovan static int __hci_request(struct hci_dev *hdev,
111a8c5fb1aSGustavo Padovan 			 void (*req)(struct hci_dev *hdev, unsigned long opt),
1121da177e4SLinus Torvalds 			 unsigned long opt, __u32 timeout)
1131da177e4SLinus Torvalds {
1141da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
1151da177e4SLinus Torvalds 	int err = 0;
1161da177e4SLinus Torvalds 
1171da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
1181da177e4SLinus Torvalds 
1191da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
1201da177e4SLinus Torvalds 
1211da177e4SLinus Torvalds 	add_wait_queue(&hdev->req_wait_q, &wait);
1221da177e4SLinus Torvalds 	set_current_state(TASK_INTERRUPTIBLE);
1231da177e4SLinus Torvalds 
1241da177e4SLinus Torvalds 	req(hdev, opt);
1251da177e4SLinus Torvalds 	schedule_timeout(timeout);
1261da177e4SLinus Torvalds 
1271da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
1281da177e4SLinus Torvalds 
1291da177e4SLinus Torvalds 	if (signal_pending(current))
1301da177e4SLinus Torvalds 		return -EINTR;
1311da177e4SLinus Torvalds 
1321da177e4SLinus Torvalds 	switch (hdev->req_status) {
1331da177e4SLinus Torvalds 	case HCI_REQ_DONE:
134e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
1351da177e4SLinus Torvalds 		break;
1361da177e4SLinus Torvalds 
1371da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
1381da177e4SLinus Torvalds 		err = -hdev->req_result;
1391da177e4SLinus Torvalds 		break;
1401da177e4SLinus Torvalds 
1411da177e4SLinus Torvalds 	default:
1421da177e4SLinus Torvalds 		err = -ETIMEDOUT;
1431da177e4SLinus Torvalds 		break;
1443ff50b79SStephen Hemminger 	}
1451da177e4SLinus Torvalds 
146a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
1471da177e4SLinus Torvalds 
1481da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
1491da177e4SLinus Torvalds 
1501da177e4SLinus Torvalds 	return err;
1511da177e4SLinus Torvalds }
1521da177e4SLinus Torvalds 
1536039aa73SGustavo Padovan static int hci_request(struct hci_dev *hdev,
1546039aa73SGustavo Padovan 		       void (*req)(struct hci_dev *hdev, unsigned long opt),
1551da177e4SLinus Torvalds 		       unsigned long opt, __u32 timeout)
1561da177e4SLinus Torvalds {
1571da177e4SLinus Torvalds 	int ret;
1581da177e4SLinus Torvalds 
1597c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
1607c6a329eSMarcel Holtmann 		return -ENETDOWN;
1617c6a329eSMarcel Holtmann 
1621da177e4SLinus Torvalds 	/* Serialize all requests */
1631da177e4SLinus Torvalds 	hci_req_lock(hdev);
1641da177e4SLinus Torvalds 	ret = __hci_request(hdev, req, opt, timeout);
1651da177e4SLinus Torvalds 	hci_req_unlock(hdev);
1661da177e4SLinus Torvalds 
1671da177e4SLinus Torvalds 	return ret;
1681da177e4SLinus Torvalds }
1691da177e4SLinus Torvalds 
1701da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
1711da177e4SLinus Torvalds {
1721da177e4SLinus Torvalds 	BT_DBG("%s %ld", hdev->name, opt);
1731da177e4SLinus Torvalds 
1741da177e4SLinus Torvalds 	/* Reset device */
175f630cf0dSGustavo F. Padovan 	set_bit(HCI_RESET, &hdev->flags);
176a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
1771da177e4SLinus Torvalds }
1781da177e4SLinus Torvalds 
179e61ef499SAndrei Emeltchenko static void bredr_init(struct hci_dev *hdev)
1801da177e4SLinus Torvalds {
181b0916ea0SJohan Hedberg 	struct hci_cp_delete_stored_link_key cp;
1821ebb9252SMarcel Holtmann 	__le16 param;
18389f2783dSMarcel Holtmann 	__u8 flt_type;
1841da177e4SLinus Torvalds 
1852455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
1862455a3eaSAndrei Emeltchenko 
1871da177e4SLinus Torvalds 	/* Mandatory initialization */
1881da177e4SLinus Torvalds 
1891da177e4SLinus Torvalds 	/* Read Local Supported Features */
190a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
1911da177e4SLinus Torvalds 
1921143e5a6SMarcel Holtmann 	/* Read Local Version */
193a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
1941143e5a6SMarcel Holtmann 
1951da177e4SLinus Torvalds 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
196a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
1971da177e4SLinus Torvalds 
1981da177e4SLinus Torvalds 	/* Read BD Address */
199a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
200a9de9248SMarcel Holtmann 
201a9de9248SMarcel Holtmann 	/* Read Class of Device */
202a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
203a9de9248SMarcel Holtmann 
204a9de9248SMarcel Holtmann 	/* Read Local Name */
205a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
2061da177e4SLinus Torvalds 
2071da177e4SLinus Torvalds 	/* Read Voice Setting */
208a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
2091da177e4SLinus Torvalds 
2101da177e4SLinus Torvalds 	/* Optional initialization */
2111da177e4SLinus Torvalds 
2121da177e4SLinus Torvalds 	/* Clear Event Filters */
21389f2783dSMarcel Holtmann 	flt_type = HCI_FLT_CLEAR_ALL;
214a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
2151da177e4SLinus Torvalds 
2161da177e4SLinus Torvalds 	/* Connection accept timeout ~20 secs */
21782781e63SAndrei Emeltchenko 	param = __constant_cpu_to_le16(0x7d00);
218a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
219b0916ea0SJohan Hedberg 
220b0916ea0SJohan Hedberg 	bacpy(&cp.bdaddr, BDADDR_ANY);
221b0916ea0SJohan Hedberg 	cp.delete_all = 1;
222b0916ea0SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
2231da177e4SLinus Torvalds }
2241da177e4SLinus Torvalds 
225e61ef499SAndrei Emeltchenko static void amp_init(struct hci_dev *hdev)
226e61ef499SAndrei Emeltchenko {
2272455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
2282455a3eaSAndrei Emeltchenko 
229e61ef499SAndrei Emeltchenko 	/* Read Local Version */
230e61ef499SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2316bcbc489SAndrei Emeltchenko 
2326bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
2336bcbc489SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
234e61ef499SAndrei Emeltchenko }
235e61ef499SAndrei Emeltchenko 
236e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
237e61ef499SAndrei Emeltchenko {
238e61ef499SAndrei Emeltchenko 	struct sk_buff *skb;
239e61ef499SAndrei Emeltchenko 
240e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
241e61ef499SAndrei Emeltchenko 
242e61ef499SAndrei Emeltchenko 	/* Driver initialization */
243e61ef499SAndrei Emeltchenko 
244e61ef499SAndrei Emeltchenko 	/* Special commands */
245e61ef499SAndrei Emeltchenko 	while ((skb = skb_dequeue(&hdev->driver_init))) {
246e61ef499SAndrei Emeltchenko 		bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
247e61ef499SAndrei Emeltchenko 		skb->dev = (void *) hdev;
248e61ef499SAndrei Emeltchenko 
249e61ef499SAndrei Emeltchenko 		skb_queue_tail(&hdev->cmd_q, skb);
250e61ef499SAndrei Emeltchenko 		queue_work(hdev->workqueue, &hdev->cmd_work);
251e61ef499SAndrei Emeltchenko 	}
252e61ef499SAndrei Emeltchenko 	skb_queue_purge(&hdev->driver_init);
253e61ef499SAndrei Emeltchenko 
25411778716SAndrei Emeltchenko 	/* Reset */
25511778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
25611778716SAndrei Emeltchenko 		hci_reset_req(hdev, 0);
25711778716SAndrei Emeltchenko 
258e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
259e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
260e61ef499SAndrei Emeltchenko 		bredr_init(hdev);
261e61ef499SAndrei Emeltchenko 		break;
262e61ef499SAndrei Emeltchenko 
263e61ef499SAndrei Emeltchenko 	case HCI_AMP:
264e61ef499SAndrei Emeltchenko 		amp_init(hdev);
265e61ef499SAndrei Emeltchenko 		break;
266e61ef499SAndrei Emeltchenko 
267e61ef499SAndrei Emeltchenko 	default:
268e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
269e61ef499SAndrei Emeltchenko 		break;
270e61ef499SAndrei Emeltchenko 	}
271e61ef499SAndrei Emeltchenko 
272e61ef499SAndrei Emeltchenko }
273e61ef499SAndrei Emeltchenko 
2746ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
2756ed58ec5SVille Tervo {
2766ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
2776ed58ec5SVille Tervo 
2786ed58ec5SVille Tervo 	/* Read LE buffer size */
2796ed58ec5SVille Tervo 	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
2806ed58ec5SVille Tervo }
2816ed58ec5SVille Tervo 
2821da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
2831da177e4SLinus Torvalds {
2841da177e4SLinus Torvalds 	__u8 scan = opt;
2851da177e4SLinus Torvalds 
2861da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, scan);
2871da177e4SLinus Torvalds 
2881da177e4SLinus Torvalds 	/* Inquiry and Page scans */
289a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
2901da177e4SLinus Torvalds }
2911da177e4SLinus Torvalds 
2921da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
2931da177e4SLinus Torvalds {
2941da177e4SLinus Torvalds 	__u8 auth = opt;
2951da177e4SLinus Torvalds 
2961da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, auth);
2971da177e4SLinus Torvalds 
2981da177e4SLinus Torvalds 	/* Authentication */
299a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
3001da177e4SLinus Torvalds }
3011da177e4SLinus Torvalds 
3021da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
3031da177e4SLinus Torvalds {
3041da177e4SLinus Torvalds 	__u8 encrypt = opt;
3051da177e4SLinus Torvalds 
3061da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, encrypt);
3071da177e4SLinus Torvalds 
308e4e8e37cSMarcel Holtmann 	/* Encryption */
309a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
3101da177e4SLinus Torvalds }
3111da177e4SLinus Torvalds 
312e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt)
313e4e8e37cSMarcel Holtmann {
314e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
315e4e8e37cSMarcel Holtmann 
316a418b893SMarcel Holtmann 	BT_DBG("%s %x", hdev->name, policy);
317e4e8e37cSMarcel Holtmann 
318e4e8e37cSMarcel Holtmann 	/* Default link policy */
319e4e8e37cSMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
320e4e8e37cSMarcel Holtmann }
321e4e8e37cSMarcel Holtmann 
3221da177e4SLinus Torvalds /* Get HCI device by index.
3231da177e4SLinus Torvalds  * Device is held on return. */
3241da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
3251da177e4SLinus Torvalds {
3268035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
3271da177e4SLinus Torvalds 
3281da177e4SLinus Torvalds 	BT_DBG("%d", index);
3291da177e4SLinus Torvalds 
3301da177e4SLinus Torvalds 	if (index < 0)
3311da177e4SLinus Torvalds 		return NULL;
3321da177e4SLinus Torvalds 
3331da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
3348035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
3351da177e4SLinus Torvalds 		if (d->id == index) {
3361da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
3371da177e4SLinus Torvalds 			break;
3381da177e4SLinus Torvalds 		}
3391da177e4SLinus Torvalds 	}
3401da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
3411da177e4SLinus Torvalds 	return hdev;
3421da177e4SLinus Torvalds }
3431da177e4SLinus Torvalds 
3441da177e4SLinus Torvalds /* ---- Inquiry support ---- */
345ff9ef578SJohan Hedberg 
34630dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
34730dc78e1SJohan Hedberg {
34830dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
34930dc78e1SJohan Hedberg 
3506fbe195dSAndre Guedes 	switch (discov->state) {
351343f935bSAndre Guedes 	case DISCOVERY_FINDING:
3526fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
35330dc78e1SJohan Hedberg 		return true;
35430dc78e1SJohan Hedberg 
3556fbe195dSAndre Guedes 	default:
35630dc78e1SJohan Hedberg 		return false;
35730dc78e1SJohan Hedberg 	}
3586fbe195dSAndre Guedes }
35930dc78e1SJohan Hedberg 
360ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
361ff9ef578SJohan Hedberg {
362ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
363ff9ef578SJohan Hedberg 
364ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
365ff9ef578SJohan Hedberg 		return;
366ff9ef578SJohan Hedberg 
367ff9ef578SJohan Hedberg 	switch (state) {
368ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
3697b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
370ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
371ff9ef578SJohan Hedberg 		break;
372ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
373ff9ef578SJohan Hedberg 		break;
374343f935bSAndre Guedes 	case DISCOVERY_FINDING:
375ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
376ff9ef578SJohan Hedberg 		break;
37730dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
37830dc78e1SJohan Hedberg 		break;
379ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
380ff9ef578SJohan Hedberg 		break;
381ff9ef578SJohan Hedberg 	}
382ff9ef578SJohan Hedberg 
383ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
384ff9ef578SJohan Hedberg }
385ff9ef578SJohan Hedberg 
3861da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
3871da177e4SLinus Torvalds {
38830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
389b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
3901da177e4SLinus Torvalds 
391561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
392561aafbcSJohan Hedberg 		list_del(&p->all);
393b57c1a56SJohan Hedberg 		kfree(p);
3941da177e4SLinus Torvalds 	}
395561aafbcSJohan Hedberg 
396561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
397561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
3981da177e4SLinus Torvalds }
3991da177e4SLinus Torvalds 
400a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
401a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
4021da177e4SLinus Torvalds {
40330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
4041da177e4SLinus Torvalds 	struct inquiry_entry *e;
4051da177e4SLinus Torvalds 
4061da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
4071da177e4SLinus Torvalds 
408561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
4091da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
4101da177e4SLinus Torvalds 			return e;
4111da177e4SLinus Torvalds 	}
4121da177e4SLinus Torvalds 
413b57c1a56SJohan Hedberg 	return NULL;
414b57c1a56SJohan Hedberg }
415b57c1a56SJohan Hedberg 
416561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
417561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
418561aafbcSJohan Hedberg {
41930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
420561aafbcSJohan Hedberg 	struct inquiry_entry *e;
421561aafbcSJohan Hedberg 
422561aafbcSJohan Hedberg 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
423561aafbcSJohan Hedberg 
424561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
425561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
426561aafbcSJohan Hedberg 			return e;
427561aafbcSJohan Hedberg 	}
428561aafbcSJohan Hedberg 
429561aafbcSJohan Hedberg 	return NULL;
430561aafbcSJohan Hedberg }
431561aafbcSJohan Hedberg 
43230dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
43330dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
43430dc78e1SJohan Hedberg 						       int state)
43530dc78e1SJohan Hedberg {
43630dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
43730dc78e1SJohan Hedberg 	struct inquiry_entry *e;
43830dc78e1SJohan Hedberg 
43930dc78e1SJohan Hedberg 	BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state);
44030dc78e1SJohan Hedberg 
44130dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
44230dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
44330dc78e1SJohan Hedberg 			return e;
44430dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
44530dc78e1SJohan Hedberg 			return e;
44630dc78e1SJohan Hedberg 	}
44730dc78e1SJohan Hedberg 
44830dc78e1SJohan Hedberg 	return NULL;
44930dc78e1SJohan Hedberg }
45030dc78e1SJohan Hedberg 
451a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
452a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
453a3d4e20aSJohan Hedberg {
454a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
455a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
456a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
457a3d4e20aSJohan Hedberg 
458a3d4e20aSJohan Hedberg 	list_del(&ie->list);
459a3d4e20aSJohan Hedberg 
460a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
461a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
462a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
463a3d4e20aSJohan Hedberg 			break;
464a3d4e20aSJohan Hedberg 		pos = &p->list;
465a3d4e20aSJohan Hedberg 	}
466a3d4e20aSJohan Hedberg 
467a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
468a3d4e20aSJohan Hedberg }
469a3d4e20aSJohan Hedberg 
4703175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
471388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
4721da177e4SLinus Torvalds {
47330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
47470f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
4751da177e4SLinus Torvalds 
4761da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
4771da177e4SLinus Torvalds 
478388fc8faSJohan Hedberg 	if (ssp)
479388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
480388fc8faSJohan Hedberg 
48170f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
482a3d4e20aSJohan Hedberg 	if (ie) {
483388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
484388fc8faSJohan Hedberg 			*ssp = true;
485388fc8faSJohan Hedberg 
486a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
487a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
488a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
489a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
490a3d4e20aSJohan Hedberg 		}
491a3d4e20aSJohan Hedberg 
492561aafbcSJohan Hedberg 		goto update;
493a3d4e20aSJohan Hedberg 	}
494561aafbcSJohan Hedberg 
4951da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
49670f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
49770f23020SAndrei Emeltchenko 	if (!ie)
4983175405bSJohan Hedberg 		return false;
49970f23020SAndrei Emeltchenko 
500561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
501561aafbcSJohan Hedberg 
502561aafbcSJohan Hedberg 	if (name_known) {
503561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
504561aafbcSJohan Hedberg 	} else {
505561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
506561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
507561aafbcSJohan Hedberg 	}
508561aafbcSJohan Hedberg 
509561aafbcSJohan Hedberg update:
510561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
511561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
512561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
513561aafbcSJohan Hedberg 		list_del(&ie->list);
5141da177e4SLinus Torvalds 	}
5151da177e4SLinus Torvalds 
51670f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
51770f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
5181da177e4SLinus Torvalds 	cache->timestamp = jiffies;
5193175405bSJohan Hedberg 
5203175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
5213175405bSJohan Hedberg 		return false;
5223175405bSJohan Hedberg 
5233175405bSJohan Hedberg 	return true;
5241da177e4SLinus Torvalds }
5251da177e4SLinus Torvalds 
5261da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
5271da177e4SLinus Torvalds {
52830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
5291da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
5301da177e4SLinus Torvalds 	struct inquiry_entry *e;
5311da177e4SLinus Torvalds 	int copied = 0;
5321da177e4SLinus Torvalds 
533561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
5341da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
535b57c1a56SJohan Hedberg 
536b57c1a56SJohan Hedberg 		if (copied >= num)
537b57c1a56SJohan Hedberg 			break;
538b57c1a56SJohan Hedberg 
5391da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
5401da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
5411da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
5421da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
5431da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
5441da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
545b57c1a56SJohan Hedberg 
5461da177e4SLinus Torvalds 		info++;
547b57c1a56SJohan Hedberg 		copied++;
5481da177e4SLinus Torvalds 	}
5491da177e4SLinus Torvalds 
5501da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
5511da177e4SLinus Torvalds 	return copied;
5521da177e4SLinus Torvalds }
5531da177e4SLinus Torvalds 
5541da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
5551da177e4SLinus Torvalds {
5561da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
5571da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
5581da177e4SLinus Torvalds 
5591da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
5601da177e4SLinus Torvalds 
5611da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
5621da177e4SLinus Torvalds 		return;
5631da177e4SLinus Torvalds 
5641da177e4SLinus Torvalds 	/* Start Inquiry */
5651da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
5661da177e4SLinus Torvalds 	cp.length  = ir->length;
5671da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
568a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
5691da177e4SLinus Torvalds }
5701da177e4SLinus Torvalds 
5711da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
5721da177e4SLinus Torvalds {
5731da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
5741da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
5751da177e4SLinus Torvalds 	struct hci_dev *hdev;
5761da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
5771da177e4SLinus Torvalds 	long timeo;
5781da177e4SLinus Torvalds 	__u8 *buf;
5791da177e4SLinus Torvalds 
5801da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
5811da177e4SLinus Torvalds 		return -EFAULT;
5821da177e4SLinus Torvalds 
5835a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
5845a08ecceSAndrei Emeltchenko 	if (!hdev)
5851da177e4SLinus Torvalds 		return -ENODEV;
5861da177e4SLinus Torvalds 
58709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5881da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
589a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
5901da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
5911da177e4SLinus Torvalds 		do_inquiry = 1;
5921da177e4SLinus Torvalds 	}
59309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
5941da177e4SLinus Torvalds 
59504837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
59670f23020SAndrei Emeltchenko 
59770f23020SAndrei Emeltchenko 	if (do_inquiry) {
59870f23020SAndrei Emeltchenko 		err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
59970f23020SAndrei Emeltchenko 		if (err < 0)
6001da177e4SLinus Torvalds 			goto done;
60170f23020SAndrei Emeltchenko 	}
6021da177e4SLinus Torvalds 
6038fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
6048fc9ced3SGustavo Padovan 	 * 255 entries
6058fc9ced3SGustavo Padovan 	 */
6061da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
6071da177e4SLinus Torvalds 
6081da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
6091da177e4SLinus Torvalds 	 * copy it to the user space.
6101da177e4SLinus Torvalds 	 */
61170f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
61270f23020SAndrei Emeltchenko 	if (!buf) {
6131da177e4SLinus Torvalds 		err = -ENOMEM;
6141da177e4SLinus Torvalds 		goto done;
6151da177e4SLinus Torvalds 	}
6161da177e4SLinus Torvalds 
61709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6181da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
61909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6201da177e4SLinus Torvalds 
6211da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
6221da177e4SLinus Torvalds 
6231da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
6241da177e4SLinus Torvalds 		ptr += sizeof(ir);
6251da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
6261da177e4SLinus Torvalds 				 ir.num_rsp))
6271da177e4SLinus Torvalds 			err = -EFAULT;
6281da177e4SLinus Torvalds 	} else
6291da177e4SLinus Torvalds 		err = -EFAULT;
6301da177e4SLinus Torvalds 
6311da177e4SLinus Torvalds 	kfree(buf);
6321da177e4SLinus Torvalds 
6331da177e4SLinus Torvalds done:
6341da177e4SLinus Torvalds 	hci_dev_put(hdev);
6351da177e4SLinus Torvalds 	return err;
6361da177e4SLinus Torvalds }
6371da177e4SLinus Torvalds 
6381da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
6391da177e4SLinus Torvalds 
6401da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
6411da177e4SLinus Torvalds {
6421da177e4SLinus Torvalds 	struct hci_dev *hdev;
6431da177e4SLinus Torvalds 	int ret = 0;
6441da177e4SLinus Torvalds 
6455a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
6465a08ecceSAndrei Emeltchenko 	if (!hdev)
6471da177e4SLinus Torvalds 		return -ENODEV;
6481da177e4SLinus Torvalds 
6491da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
6501da177e4SLinus Torvalds 
6511da177e4SLinus Torvalds 	hci_req_lock(hdev);
6521da177e4SLinus Torvalds 
65394324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
65494324962SJohan Hovold 		ret = -ENODEV;
65594324962SJohan Hovold 		goto done;
65694324962SJohan Hovold 	}
65794324962SJohan Hovold 
658611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
659611b30f7SMarcel Holtmann 		ret = -ERFKILL;
660611b30f7SMarcel Holtmann 		goto done;
661611b30f7SMarcel Holtmann 	}
662611b30f7SMarcel Holtmann 
6631da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
6641da177e4SLinus Torvalds 		ret = -EALREADY;
6651da177e4SLinus Torvalds 		goto done;
6661da177e4SLinus Torvalds 	}
6671da177e4SLinus Torvalds 
6681da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
6691da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
6701da177e4SLinus Torvalds 
67107e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
67207e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
67307e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
674943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
675943da25dSMarcel Holtmann 
6761da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
6771da177e4SLinus Torvalds 		ret = -EIO;
6781da177e4SLinus Torvalds 		goto done;
6791da177e4SLinus Torvalds 	}
6801da177e4SLinus Torvalds 
6811da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
6821da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
6831da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
684a5040efaSJohan Hedberg 		hdev->init_last_cmd = 0;
6851da177e4SLinus Torvalds 
6865f246e89SAndrei Emeltchenko 		ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
6871da177e4SLinus Torvalds 
688eead27daSAndre Guedes 		if (lmp_host_le_capable(hdev))
6896ed58ec5SVille Tervo 			ret = __hci_request(hdev, hci_le_init_req, 0,
6905f246e89SAndrei Emeltchenko 					    HCI_INIT_TIMEOUT);
6916ed58ec5SVille Tervo 
6921da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
6931da177e4SLinus Torvalds 	}
6941da177e4SLinus Torvalds 
6951da177e4SLinus Torvalds 	if (!ret) {
6961da177e4SLinus Torvalds 		hci_dev_hold(hdev);
6971da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
6981da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
699a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
70009fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
701744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
70209fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
70356e5cb86SJohan Hedberg 		}
7041da177e4SLinus Torvalds 	} else {
7051da177e4SLinus Torvalds 		/* Init failed, cleanup */
7063eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
707c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
708b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
7091da177e4SLinus Torvalds 
7101da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
7111da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
7121da177e4SLinus Torvalds 
7131da177e4SLinus Torvalds 		if (hdev->flush)
7141da177e4SLinus Torvalds 			hdev->flush(hdev);
7151da177e4SLinus Torvalds 
7161da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
7171da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
7181da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
7191da177e4SLinus Torvalds 		}
7201da177e4SLinus Torvalds 
7211da177e4SLinus Torvalds 		hdev->close(hdev);
7221da177e4SLinus Torvalds 		hdev->flags = 0;
7231da177e4SLinus Torvalds 	}
7241da177e4SLinus Torvalds 
7251da177e4SLinus Torvalds done:
7261da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7271da177e4SLinus Torvalds 	hci_dev_put(hdev);
7281da177e4SLinus Torvalds 	return ret;
7291da177e4SLinus Torvalds }
7301da177e4SLinus Torvalds 
7311da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
7321da177e4SLinus Torvalds {
7331da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
7341da177e4SLinus Torvalds 
73528b75a89SAndre Guedes 	cancel_work_sync(&hdev->le_scan);
73628b75a89SAndre Guedes 
7371da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
7381da177e4SLinus Torvalds 	hci_req_lock(hdev);
7391da177e4SLinus Torvalds 
7401da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
741b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7421da177e4SLinus Torvalds 		hci_req_unlock(hdev);
7431da177e4SLinus Torvalds 		return 0;
7441da177e4SLinus Torvalds 	}
7451da177e4SLinus Torvalds 
7463eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
7473eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
748b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
7491da177e4SLinus Torvalds 
75016ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
751e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
75216ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
7535e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
75416ab91abSJohan Hedberg 	}
75516ab91abSJohan Hedberg 
756a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
7577d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
7587d78525dSJohan Hedberg 
7597ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
7607ba8b4beSAndre Guedes 
76109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
7621da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
7631da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
76409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7651da177e4SLinus Torvalds 
7661da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
7671da177e4SLinus Torvalds 
7681da177e4SLinus Torvalds 	if (hdev->flush)
7691da177e4SLinus Torvalds 		hdev->flush(hdev);
7701da177e4SLinus Torvalds 
7711da177e4SLinus Torvalds 	/* Reset device */
7721da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7731da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
7748af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
775a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
7761da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
7775f246e89SAndrei Emeltchenko 		__hci_request(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
7781da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
7791da177e4SLinus Torvalds 	}
7801da177e4SLinus Torvalds 
781c347b765SGustavo F. Padovan 	/* flush cmd  work */
782c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
7831da177e4SLinus Torvalds 
7841da177e4SLinus Torvalds 	/* Drop queues */
7851da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
7861da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7871da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
7881da177e4SLinus Torvalds 
7891da177e4SLinus Torvalds 	/* Drop last sent command */
7901da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
791b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7921da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
7931da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
7941da177e4SLinus Torvalds 	}
7951da177e4SLinus Torvalds 
7961da177e4SLinus Torvalds 	/* After this point our queues are empty
7971da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
7981da177e4SLinus Torvalds 	hdev->close(hdev);
7991da177e4SLinus Torvalds 
8008ee56540SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
80109fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
802744cf19eSJohan Hedberg 		mgmt_powered(hdev, 0);
80309fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
8048ee56540SMarcel Holtmann 	}
8055add6af8SJohan Hedberg 
8061da177e4SLinus Torvalds 	/* Clear flags */
8071da177e4SLinus Torvalds 	hdev->flags = 0;
8081da177e4SLinus Torvalds 
809e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
81009b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
811e59fda8dSJohan Hedberg 
8121da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8131da177e4SLinus Torvalds 
8141da177e4SLinus Torvalds 	hci_dev_put(hdev);
8151da177e4SLinus Torvalds 	return 0;
8161da177e4SLinus Torvalds }
8171da177e4SLinus Torvalds 
8181da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
8191da177e4SLinus Torvalds {
8201da177e4SLinus Torvalds 	struct hci_dev *hdev;
8211da177e4SLinus Torvalds 	int err;
8221da177e4SLinus Torvalds 
82370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
82470f23020SAndrei Emeltchenko 	if (!hdev)
8251da177e4SLinus Torvalds 		return -ENODEV;
8268ee56540SMarcel Holtmann 
8278ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
8288ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
8298ee56540SMarcel Holtmann 
8301da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
8318ee56540SMarcel Holtmann 
8321da177e4SLinus Torvalds 	hci_dev_put(hdev);
8331da177e4SLinus Torvalds 	return err;
8341da177e4SLinus Torvalds }
8351da177e4SLinus Torvalds 
8361da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
8371da177e4SLinus Torvalds {
8381da177e4SLinus Torvalds 	struct hci_dev *hdev;
8391da177e4SLinus Torvalds 	int ret = 0;
8401da177e4SLinus Torvalds 
84170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
84270f23020SAndrei Emeltchenko 	if (!hdev)
8431da177e4SLinus Torvalds 		return -ENODEV;
8441da177e4SLinus Torvalds 
8451da177e4SLinus Torvalds 	hci_req_lock(hdev);
8461da177e4SLinus Torvalds 
8471da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
8481da177e4SLinus Torvalds 		goto done;
8491da177e4SLinus Torvalds 
8501da177e4SLinus Torvalds 	/* Drop queues */
8511da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
8521da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
8531da177e4SLinus Torvalds 
85409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
8551da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
8561da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
85709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
8581da177e4SLinus Torvalds 
8591da177e4SLinus Torvalds 	if (hdev->flush)
8601da177e4SLinus Torvalds 		hdev->flush(hdev);
8611da177e4SLinus Torvalds 
8621da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
8636ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
8641da177e4SLinus Torvalds 
8651da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
8665f246e89SAndrei Emeltchenko 		ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
8671da177e4SLinus Torvalds 
8681da177e4SLinus Torvalds done:
8691da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8701da177e4SLinus Torvalds 	hci_dev_put(hdev);
8711da177e4SLinus Torvalds 	return ret;
8721da177e4SLinus Torvalds }
8731da177e4SLinus Torvalds 
8741da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
8751da177e4SLinus Torvalds {
8761da177e4SLinus Torvalds 	struct hci_dev *hdev;
8771da177e4SLinus Torvalds 	int ret = 0;
8781da177e4SLinus Torvalds 
87970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
88070f23020SAndrei Emeltchenko 	if (!hdev)
8811da177e4SLinus Torvalds 		return -ENODEV;
8821da177e4SLinus Torvalds 
8831da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
8841da177e4SLinus Torvalds 
8851da177e4SLinus Torvalds 	hci_dev_put(hdev);
8861da177e4SLinus Torvalds 
8871da177e4SLinus Torvalds 	return ret;
8881da177e4SLinus Torvalds }
8891da177e4SLinus Torvalds 
8901da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
8911da177e4SLinus Torvalds {
8921da177e4SLinus Torvalds 	struct hci_dev *hdev;
8931da177e4SLinus Torvalds 	struct hci_dev_req dr;
8941da177e4SLinus Torvalds 	int err = 0;
8951da177e4SLinus Torvalds 
8961da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
8971da177e4SLinus Torvalds 		return -EFAULT;
8981da177e4SLinus Torvalds 
89970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
90070f23020SAndrei Emeltchenko 	if (!hdev)
9011da177e4SLinus Torvalds 		return -ENODEV;
9021da177e4SLinus Torvalds 
9031da177e4SLinus Torvalds 	switch (cmd) {
9041da177e4SLinus Torvalds 	case HCISETAUTH:
90504837f64SMarcel Holtmann 		err = hci_request(hdev, hci_auth_req, dr.dev_opt,
9065f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
9071da177e4SLinus Torvalds 		break;
9081da177e4SLinus Torvalds 
9091da177e4SLinus Torvalds 	case HCISETENCRYPT:
9101da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
9111da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
9121da177e4SLinus Torvalds 			break;
9131da177e4SLinus Torvalds 		}
9141da177e4SLinus Torvalds 
9151da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
9161da177e4SLinus Torvalds 			/* Auth must be enabled first */
91704837f64SMarcel Holtmann 			err = hci_request(hdev, hci_auth_req, dr.dev_opt,
9185f246e89SAndrei Emeltchenko 					  HCI_INIT_TIMEOUT);
9191da177e4SLinus Torvalds 			if (err)
9201da177e4SLinus Torvalds 				break;
9211da177e4SLinus Torvalds 		}
9221da177e4SLinus Torvalds 
92304837f64SMarcel Holtmann 		err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
9245f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
9251da177e4SLinus Torvalds 		break;
9261da177e4SLinus Torvalds 
9271da177e4SLinus Torvalds 	case HCISETSCAN:
92804837f64SMarcel Holtmann 		err = hci_request(hdev, hci_scan_req, dr.dev_opt,
9295f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
9301da177e4SLinus Torvalds 		break;
9311da177e4SLinus Torvalds 
9321da177e4SLinus Torvalds 	case HCISETLINKPOL:
933e4e8e37cSMarcel Holtmann 		err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
9345f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
9351da177e4SLinus Torvalds 		break;
9361da177e4SLinus Torvalds 
9371da177e4SLinus Torvalds 	case HCISETLINKMODE:
938e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
939e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
940e4e8e37cSMarcel Holtmann 		break;
941e4e8e37cSMarcel Holtmann 
942e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
943e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
9441da177e4SLinus Torvalds 		break;
9451da177e4SLinus Torvalds 
9461da177e4SLinus Torvalds 	case HCISETACLMTU:
9471da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
9481da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
9491da177e4SLinus Torvalds 		break;
9501da177e4SLinus Torvalds 
9511da177e4SLinus Torvalds 	case HCISETSCOMTU:
9521da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
9531da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
9541da177e4SLinus Torvalds 		break;
9551da177e4SLinus Torvalds 
9561da177e4SLinus Torvalds 	default:
9571da177e4SLinus Torvalds 		err = -EINVAL;
9581da177e4SLinus Torvalds 		break;
9591da177e4SLinus Torvalds 	}
960e4e8e37cSMarcel Holtmann 
9611da177e4SLinus Torvalds 	hci_dev_put(hdev);
9621da177e4SLinus Torvalds 	return err;
9631da177e4SLinus Torvalds }
9641da177e4SLinus Torvalds 
9651da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
9661da177e4SLinus Torvalds {
9678035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
9681da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
9691da177e4SLinus Torvalds 	struct hci_dev_req *dr;
9701da177e4SLinus Torvalds 	int n = 0, size, err;
9711da177e4SLinus Torvalds 	__u16 dev_num;
9721da177e4SLinus Torvalds 
9731da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
9741da177e4SLinus Torvalds 		return -EFAULT;
9751da177e4SLinus Torvalds 
9761da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
9771da177e4SLinus Torvalds 		return -EINVAL;
9781da177e4SLinus Torvalds 
9791da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
9801da177e4SLinus Torvalds 
98170f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
98270f23020SAndrei Emeltchenko 	if (!dl)
9831da177e4SLinus Torvalds 		return -ENOMEM;
9841da177e4SLinus Torvalds 
9851da177e4SLinus Torvalds 	dr = dl->dev_req;
9861da177e4SLinus Torvalds 
987f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
9888035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
989a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
990e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
991c542a06cSJohan Hedberg 
992a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
993a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
994c542a06cSJohan Hedberg 
9951da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
9961da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
997c542a06cSJohan Hedberg 
9981da177e4SLinus Torvalds 		if (++n >= dev_num)
9991da177e4SLinus Torvalds 			break;
10001da177e4SLinus Torvalds 	}
1001f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
10021da177e4SLinus Torvalds 
10031da177e4SLinus Torvalds 	dl->dev_num = n;
10041da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
10051da177e4SLinus Torvalds 
10061da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
10071da177e4SLinus Torvalds 	kfree(dl);
10081da177e4SLinus Torvalds 
10091da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
10101da177e4SLinus Torvalds }
10111da177e4SLinus Torvalds 
10121da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
10131da177e4SLinus Torvalds {
10141da177e4SLinus Torvalds 	struct hci_dev *hdev;
10151da177e4SLinus Torvalds 	struct hci_dev_info di;
10161da177e4SLinus Torvalds 	int err = 0;
10171da177e4SLinus Torvalds 
10181da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
10191da177e4SLinus Torvalds 		return -EFAULT;
10201da177e4SLinus Torvalds 
102170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
102270f23020SAndrei Emeltchenko 	if (!hdev)
10231da177e4SLinus Torvalds 		return -ENODEV;
10241da177e4SLinus Torvalds 
1025a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
10263243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1027ab81cbf9SJohan Hedberg 
1028a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1029a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1030c542a06cSJohan Hedberg 
10311da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
10321da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
1033943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
10341da177e4SLinus Torvalds 	di.flags    = hdev->flags;
10351da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
10361da177e4SLinus Torvalds 	di.acl_mtu  = hdev->acl_mtu;
10371da177e4SLinus Torvalds 	di.acl_pkts = hdev->acl_pkts;
10381da177e4SLinus Torvalds 	di.sco_mtu  = hdev->sco_mtu;
10391da177e4SLinus Torvalds 	di.sco_pkts = hdev->sco_pkts;
10401da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
10411da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
10421da177e4SLinus Torvalds 
10431da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
10441da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
10451da177e4SLinus Torvalds 
10461da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
10471da177e4SLinus Torvalds 		err = -EFAULT;
10481da177e4SLinus Torvalds 
10491da177e4SLinus Torvalds 	hci_dev_put(hdev);
10501da177e4SLinus Torvalds 
10511da177e4SLinus Torvalds 	return err;
10521da177e4SLinus Torvalds }
10531da177e4SLinus Torvalds 
10541da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
10551da177e4SLinus Torvalds 
1056611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1057611b30f7SMarcel Holtmann {
1058611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1059611b30f7SMarcel Holtmann 
1060611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1061611b30f7SMarcel Holtmann 
1062611b30f7SMarcel Holtmann 	if (!blocked)
1063611b30f7SMarcel Holtmann 		return 0;
1064611b30f7SMarcel Holtmann 
1065611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1066611b30f7SMarcel Holtmann 
1067611b30f7SMarcel Holtmann 	return 0;
1068611b30f7SMarcel Holtmann }
1069611b30f7SMarcel Holtmann 
1070611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1071611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1072611b30f7SMarcel Holtmann };
1073611b30f7SMarcel Holtmann 
1074ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1075ab81cbf9SJohan Hedberg {
1076ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
1077ab81cbf9SJohan Hedberg 
1078ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1079ab81cbf9SJohan Hedberg 
1080ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
1081ab81cbf9SJohan Hedberg 		return;
1082ab81cbf9SJohan Hedberg 
1083a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
10849345d40cSAndrei Emeltchenko 		schedule_delayed_work(&hdev->power_off, HCI_AUTO_OFF_TIMEOUT);
1085ab81cbf9SJohan Hedberg 
1086a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1087744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1088ab81cbf9SJohan Hedberg }
1089ab81cbf9SJohan Hedberg 
1090ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1091ab81cbf9SJohan Hedberg {
10923243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
10933243553fSJohan Hedberg 					    power_off.work);
1094ab81cbf9SJohan Hedberg 
1095ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1096ab81cbf9SJohan Hedberg 
10978ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1098ab81cbf9SJohan Hedberg }
1099ab81cbf9SJohan Hedberg 
110016ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
110116ab91abSJohan Hedberg {
110216ab91abSJohan Hedberg 	struct hci_dev *hdev;
110316ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
110416ab91abSJohan Hedberg 
110516ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
110616ab91abSJohan Hedberg 
110716ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
110816ab91abSJohan Hedberg 
110909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
111016ab91abSJohan Hedberg 
111116ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
111216ab91abSJohan Hedberg 
111316ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
111416ab91abSJohan Hedberg 
111509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
111616ab91abSJohan Hedberg }
111716ab91abSJohan Hedberg 
11182aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
11192aeb9a1aSJohan Hedberg {
11202aeb9a1aSJohan Hedberg 	struct list_head *p, *n;
11212aeb9a1aSJohan Hedberg 
11222aeb9a1aSJohan Hedberg 	list_for_each_safe(p, n, &hdev->uuids) {
11232aeb9a1aSJohan Hedberg 		struct bt_uuid *uuid;
11242aeb9a1aSJohan Hedberg 
11252aeb9a1aSJohan Hedberg 		uuid = list_entry(p, struct bt_uuid, list);
11262aeb9a1aSJohan Hedberg 
11272aeb9a1aSJohan Hedberg 		list_del(p);
11282aeb9a1aSJohan Hedberg 		kfree(uuid);
11292aeb9a1aSJohan Hedberg 	}
11302aeb9a1aSJohan Hedberg 
11312aeb9a1aSJohan Hedberg 	return 0;
11322aeb9a1aSJohan Hedberg }
11332aeb9a1aSJohan Hedberg 
113455ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
113555ed8ca1SJohan Hedberg {
113655ed8ca1SJohan Hedberg 	struct list_head *p, *n;
113755ed8ca1SJohan Hedberg 
113855ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
113955ed8ca1SJohan Hedberg 		struct link_key *key;
114055ed8ca1SJohan Hedberg 
114155ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
114255ed8ca1SJohan Hedberg 
114355ed8ca1SJohan Hedberg 		list_del(p);
114455ed8ca1SJohan Hedberg 		kfree(key);
114555ed8ca1SJohan Hedberg 	}
114655ed8ca1SJohan Hedberg 
114755ed8ca1SJohan Hedberg 	return 0;
114855ed8ca1SJohan Hedberg }
114955ed8ca1SJohan Hedberg 
1150b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1151b899efafSVinicius Costa Gomes {
1152b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1153b899efafSVinicius Costa Gomes 
1154b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1155b899efafSVinicius Costa Gomes 		list_del(&k->list);
1156b899efafSVinicius Costa Gomes 		kfree(k);
1157b899efafSVinicius Costa Gomes 	}
1158b899efafSVinicius Costa Gomes 
1159b899efafSVinicius Costa Gomes 	return 0;
1160b899efafSVinicius Costa Gomes }
1161b899efafSVinicius Costa Gomes 
116255ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
116355ed8ca1SJohan Hedberg {
116455ed8ca1SJohan Hedberg 	struct link_key *k;
116555ed8ca1SJohan Hedberg 
11668035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
116755ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
116855ed8ca1SJohan Hedberg 			return k;
116955ed8ca1SJohan Hedberg 
117055ed8ca1SJohan Hedberg 	return NULL;
117155ed8ca1SJohan Hedberg }
117255ed8ca1SJohan Hedberg 
1173745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1174d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1175d25e28abSJohan Hedberg {
1176d25e28abSJohan Hedberg 	/* Legacy key */
1177d25e28abSJohan Hedberg 	if (key_type < 0x03)
1178745c0ce3SVishal Agarwal 		return true;
1179d25e28abSJohan Hedberg 
1180d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1181d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1182745c0ce3SVishal Agarwal 		return false;
1183d25e28abSJohan Hedberg 
1184d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1185d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1186745c0ce3SVishal Agarwal 		return false;
1187d25e28abSJohan Hedberg 
1188d25e28abSJohan Hedberg 	/* Security mode 3 case */
1189d25e28abSJohan Hedberg 	if (!conn)
1190745c0ce3SVishal Agarwal 		return true;
1191d25e28abSJohan Hedberg 
1192d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1193d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1194745c0ce3SVishal Agarwal 		return true;
1195d25e28abSJohan Hedberg 
1196d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1197d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1198745c0ce3SVishal Agarwal 		return true;
1199d25e28abSJohan Hedberg 
1200d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1201d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1202745c0ce3SVishal Agarwal 		return true;
1203d25e28abSJohan Hedberg 
1204d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1205d25e28abSJohan Hedberg 	 * persistently */
1206745c0ce3SVishal Agarwal 	return false;
1207d25e28abSJohan Hedberg }
1208d25e28abSJohan Hedberg 
1209c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
121075d262c2SVinicius Costa Gomes {
1211c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
121275d262c2SVinicius Costa Gomes 
1213c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1214c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1215c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
121675d262c2SVinicius Costa Gomes 			continue;
121775d262c2SVinicius Costa Gomes 
121875d262c2SVinicius Costa Gomes 		return k;
121975d262c2SVinicius Costa Gomes 	}
122075d262c2SVinicius Costa Gomes 
122175d262c2SVinicius Costa Gomes 	return NULL;
122275d262c2SVinicius Costa Gomes }
122375d262c2SVinicius Costa Gomes 
1224c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1225c9839a11SVinicius Costa Gomes 				     u8 addr_type)
122675d262c2SVinicius Costa Gomes {
1227c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
122875d262c2SVinicius Costa Gomes 
1229c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1230c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1231c9839a11SVinicius Costa Gomes 		    bacmp(bdaddr, &k->bdaddr) == 0)
123275d262c2SVinicius Costa Gomes 			return k;
123375d262c2SVinicius Costa Gomes 
123475d262c2SVinicius Costa Gomes 	return NULL;
123575d262c2SVinicius Costa Gomes }
123675d262c2SVinicius Costa Gomes 
1237d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1238d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
123955ed8ca1SJohan Hedberg {
124055ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1241745c0ce3SVishal Agarwal 	u8 old_key_type;
1242745c0ce3SVishal Agarwal 	bool persistent;
124355ed8ca1SJohan Hedberg 
124455ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
124555ed8ca1SJohan Hedberg 	if (old_key) {
124655ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
124755ed8ca1SJohan Hedberg 		key = old_key;
124855ed8ca1SJohan Hedberg 	} else {
124912adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
125055ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
125155ed8ca1SJohan Hedberg 		if (!key)
125255ed8ca1SJohan Hedberg 			return -ENOMEM;
125355ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
125455ed8ca1SJohan Hedberg 	}
125555ed8ca1SJohan Hedberg 
125655ed8ca1SJohan Hedberg 	BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
125755ed8ca1SJohan Hedberg 
1258d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1259d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1260d25e28abSJohan Hedberg 	 * previous key */
1261d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1262a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1263d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1264655fe6ecSJohan Hedberg 		if (conn)
1265655fe6ecSJohan Hedberg 			conn->key_type = type;
1266655fe6ecSJohan Hedberg 	}
1267d25e28abSJohan Hedberg 
126855ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
12699b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
127055ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
127155ed8ca1SJohan Hedberg 
1272b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
127355ed8ca1SJohan Hedberg 		key->type = old_key_type;
12744748fed2SJohan Hedberg 	else
12754748fed2SJohan Hedberg 		key->type = type;
12764748fed2SJohan Hedberg 
12774df378a1SJohan Hedberg 	if (!new_key)
12784df378a1SJohan Hedberg 		return 0;
12794df378a1SJohan Hedberg 
12804df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
12814df378a1SJohan Hedberg 
1282744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
12834df378a1SJohan Hedberg 
12846ec5bcadSVishal Agarwal 	if (conn)
12856ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
128655ed8ca1SJohan Hedberg 
128755ed8ca1SJohan Hedberg 	return 0;
128855ed8ca1SJohan Hedberg }
128955ed8ca1SJohan Hedberg 
1290c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
12919a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
129204124681SGustavo F. Padovan 		ediv, u8 rand[8])
129375d262c2SVinicius Costa Gomes {
1294c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
129575d262c2SVinicius Costa Gomes 
1296c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1297c9839a11SVinicius Costa Gomes 		return 0;
129875d262c2SVinicius Costa Gomes 
1299c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1300c9839a11SVinicius Costa Gomes 	if (old_key)
130175d262c2SVinicius Costa Gomes 		key = old_key;
1302c9839a11SVinicius Costa Gomes 	else {
1303c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
130475d262c2SVinicius Costa Gomes 		if (!key)
130575d262c2SVinicius Costa Gomes 			return -ENOMEM;
1306c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
130775d262c2SVinicius Costa Gomes 	}
130875d262c2SVinicius Costa Gomes 
130975d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1310c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1311c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1312c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1313c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1314c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1315c9839a11SVinicius Costa Gomes 	key->type = type;
1316c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
131775d262c2SVinicius Costa Gomes 
1318c9839a11SVinicius Costa Gomes 	if (!new_key)
1319c9839a11SVinicius Costa Gomes 		return 0;
132075d262c2SVinicius Costa Gomes 
1321261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1322261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1323261cc5aaSVinicius Costa Gomes 
132475d262c2SVinicius Costa Gomes 	return 0;
132575d262c2SVinicius Costa Gomes }
132675d262c2SVinicius Costa Gomes 
132755ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
132855ed8ca1SJohan Hedberg {
132955ed8ca1SJohan Hedberg 	struct link_key *key;
133055ed8ca1SJohan Hedberg 
133155ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
133255ed8ca1SJohan Hedberg 	if (!key)
133355ed8ca1SJohan Hedberg 		return -ENOENT;
133455ed8ca1SJohan Hedberg 
133555ed8ca1SJohan Hedberg 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
133655ed8ca1SJohan Hedberg 
133755ed8ca1SJohan Hedberg 	list_del(&key->list);
133855ed8ca1SJohan Hedberg 	kfree(key);
133955ed8ca1SJohan Hedberg 
134055ed8ca1SJohan Hedberg 	return 0;
134155ed8ca1SJohan Hedberg }
134255ed8ca1SJohan Hedberg 
1343b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1344b899efafSVinicius Costa Gomes {
1345b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1346b899efafSVinicius Costa Gomes 
1347b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1348b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1349b899efafSVinicius Costa Gomes 			continue;
1350b899efafSVinicius Costa Gomes 
1351b899efafSVinicius Costa Gomes 		BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
1352b899efafSVinicius Costa Gomes 
1353b899efafSVinicius Costa Gomes 		list_del(&k->list);
1354b899efafSVinicius Costa Gomes 		kfree(k);
1355b899efafSVinicius Costa Gomes 	}
1356b899efafSVinicius Costa Gomes 
1357b899efafSVinicius Costa Gomes 	return 0;
1358b899efafSVinicius Costa Gomes }
1359b899efafSVinicius Costa Gomes 
13606bd32326SVille Tervo /* HCI command timer function */
1361bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
13626bd32326SVille Tervo {
13636bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
13646bd32326SVille Tervo 
1365bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
1366bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
1367bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
1368bda4f23aSAndrei Emeltchenko 
1369bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
1370bda4f23aSAndrei Emeltchenko 	} else {
13716bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
1372bda4f23aSAndrei Emeltchenko 	}
1373bda4f23aSAndrei Emeltchenko 
13746bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1375c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
13766bd32326SVille Tervo }
13776bd32326SVille Tervo 
13782763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
13792763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
13802763eda6SSzymon Janc {
13812763eda6SSzymon Janc 	struct oob_data *data;
13822763eda6SSzymon Janc 
13832763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
13842763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
13852763eda6SSzymon Janc 			return data;
13862763eda6SSzymon Janc 
13872763eda6SSzymon Janc 	return NULL;
13882763eda6SSzymon Janc }
13892763eda6SSzymon Janc 
13902763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
13912763eda6SSzymon Janc {
13922763eda6SSzymon Janc 	struct oob_data *data;
13932763eda6SSzymon Janc 
13942763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
13952763eda6SSzymon Janc 	if (!data)
13962763eda6SSzymon Janc 		return -ENOENT;
13972763eda6SSzymon Janc 
13982763eda6SSzymon Janc 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
13992763eda6SSzymon Janc 
14002763eda6SSzymon Janc 	list_del(&data->list);
14012763eda6SSzymon Janc 	kfree(data);
14022763eda6SSzymon Janc 
14032763eda6SSzymon Janc 	return 0;
14042763eda6SSzymon Janc }
14052763eda6SSzymon Janc 
14062763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
14072763eda6SSzymon Janc {
14082763eda6SSzymon Janc 	struct oob_data *data, *n;
14092763eda6SSzymon Janc 
14102763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
14112763eda6SSzymon Janc 		list_del(&data->list);
14122763eda6SSzymon Janc 		kfree(data);
14132763eda6SSzymon Janc 	}
14142763eda6SSzymon Janc 
14152763eda6SSzymon Janc 	return 0;
14162763eda6SSzymon Janc }
14172763eda6SSzymon Janc 
14182763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
14192763eda6SSzymon Janc 			    u8 *randomizer)
14202763eda6SSzymon Janc {
14212763eda6SSzymon Janc 	struct oob_data *data;
14222763eda6SSzymon Janc 
14232763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
14242763eda6SSzymon Janc 
14252763eda6SSzymon Janc 	if (!data) {
14262763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
14272763eda6SSzymon Janc 		if (!data)
14282763eda6SSzymon Janc 			return -ENOMEM;
14292763eda6SSzymon Janc 
14302763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
14312763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
14322763eda6SSzymon Janc 	}
14332763eda6SSzymon Janc 
14342763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
14352763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
14362763eda6SSzymon Janc 
14372763eda6SSzymon Janc 	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
14382763eda6SSzymon Janc 
14392763eda6SSzymon Janc 	return 0;
14402763eda6SSzymon Janc }
14412763eda6SSzymon Janc 
144204124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
1443b2a66aadSAntti Julku {
1444b2a66aadSAntti Julku 	struct bdaddr_list *b;
1445b2a66aadSAntti Julku 
14468035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1447b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1448b2a66aadSAntti Julku 			return b;
1449b2a66aadSAntti Julku 
1450b2a66aadSAntti Julku 	return NULL;
1451b2a66aadSAntti Julku }
1452b2a66aadSAntti Julku 
1453b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1454b2a66aadSAntti Julku {
1455b2a66aadSAntti Julku 	struct list_head *p, *n;
1456b2a66aadSAntti Julku 
1457b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1458b2a66aadSAntti Julku 		struct bdaddr_list *b;
1459b2a66aadSAntti Julku 
1460b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1461b2a66aadSAntti Julku 
1462b2a66aadSAntti Julku 		list_del(p);
1463b2a66aadSAntti Julku 		kfree(b);
1464b2a66aadSAntti Julku 	}
1465b2a66aadSAntti Julku 
1466b2a66aadSAntti Julku 	return 0;
1467b2a66aadSAntti Julku }
1468b2a66aadSAntti Julku 
146988c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1470b2a66aadSAntti Julku {
1471b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1472b2a66aadSAntti Julku 
1473b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1474b2a66aadSAntti Julku 		return -EBADF;
1475b2a66aadSAntti Julku 
14765e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
14775e762444SAntti Julku 		return -EEXIST;
1478b2a66aadSAntti Julku 
1479b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
14805e762444SAntti Julku 	if (!entry)
14815e762444SAntti Julku 		return -ENOMEM;
1482b2a66aadSAntti Julku 
1483b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1484b2a66aadSAntti Julku 
1485b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1486b2a66aadSAntti Julku 
148788c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
1488b2a66aadSAntti Julku }
1489b2a66aadSAntti Julku 
149088c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1491b2a66aadSAntti Julku {
1492b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1493b2a66aadSAntti Julku 
14941ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
14955e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1496b2a66aadSAntti Julku 
1497b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
14981ec918ceSSzymon Janc 	if (!entry)
14995e762444SAntti Julku 		return -ENOENT;
1500b2a66aadSAntti Julku 
1501b2a66aadSAntti Julku 	list_del(&entry->list);
1502b2a66aadSAntti Julku 	kfree(entry);
1503b2a66aadSAntti Julku 
150488c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
1505b2a66aadSAntti Julku }
1506b2a66aadSAntti Julku 
15077ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt)
15087ba8b4beSAndre Guedes {
15097ba8b4beSAndre Guedes 	struct le_scan_params *param =  (struct le_scan_params *) opt;
15107ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_param cp;
15117ba8b4beSAndre Guedes 
15127ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
15137ba8b4beSAndre Guedes 	cp.type = param->type;
15147ba8b4beSAndre Guedes 	cp.interval = cpu_to_le16(param->interval);
15157ba8b4beSAndre Guedes 	cp.window = cpu_to_le16(param->window);
15167ba8b4beSAndre Guedes 
15177ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
15187ba8b4beSAndre Guedes }
15197ba8b4beSAndre Guedes 
15207ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt)
15217ba8b4beSAndre Guedes {
15227ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
15237ba8b4beSAndre Guedes 
15247ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
15257ba8b4beSAndre Guedes 	cp.enable = 1;
15260431a43cSAndre Guedes 	cp.filter_dup = 1;
15277ba8b4beSAndre Guedes 
15287ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
15297ba8b4beSAndre Guedes }
15307ba8b4beSAndre Guedes 
15317ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
15327ba8b4beSAndre Guedes 			  u16 window, int timeout)
15337ba8b4beSAndre Guedes {
15347ba8b4beSAndre Guedes 	long timeo = msecs_to_jiffies(3000);
15357ba8b4beSAndre Guedes 	struct le_scan_params param;
15367ba8b4beSAndre Guedes 	int err;
15377ba8b4beSAndre Guedes 
15387ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
15397ba8b4beSAndre Guedes 
15407ba8b4beSAndre Guedes 	if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
15417ba8b4beSAndre Guedes 		return -EINPROGRESS;
15427ba8b4beSAndre Guedes 
15437ba8b4beSAndre Guedes 	param.type = type;
15447ba8b4beSAndre Guedes 	param.interval = interval;
15457ba8b4beSAndre Guedes 	param.window = window;
15467ba8b4beSAndre Guedes 
15477ba8b4beSAndre Guedes 	hci_req_lock(hdev);
15487ba8b4beSAndre Guedes 
15497ba8b4beSAndre Guedes 	err = __hci_request(hdev, le_scan_param_req, (unsigned long) &param,
15507ba8b4beSAndre Guedes 			    timeo);
15517ba8b4beSAndre Guedes 	if (!err)
15527ba8b4beSAndre Guedes 		err = __hci_request(hdev, le_scan_enable_req, 0, timeo);
15537ba8b4beSAndre Guedes 
15547ba8b4beSAndre Guedes 	hci_req_unlock(hdev);
15557ba8b4beSAndre Guedes 
15567ba8b4beSAndre Guedes 	if (err < 0)
15577ba8b4beSAndre Guedes 		return err;
15587ba8b4beSAndre Guedes 
15597ba8b4beSAndre Guedes 	schedule_delayed_work(&hdev->le_scan_disable,
15607ba8b4beSAndre Guedes 			      msecs_to_jiffies(timeout));
15617ba8b4beSAndre Guedes 
15627ba8b4beSAndre Guedes 	return 0;
15637ba8b4beSAndre Guedes }
15647ba8b4beSAndre Guedes 
15657dbfac1dSAndre Guedes int hci_cancel_le_scan(struct hci_dev *hdev)
15667dbfac1dSAndre Guedes {
15677dbfac1dSAndre Guedes 	BT_DBG("%s", hdev->name);
15687dbfac1dSAndre Guedes 
15697dbfac1dSAndre Guedes 	if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
15707dbfac1dSAndre Guedes 		return -EALREADY;
15717dbfac1dSAndre Guedes 
15727dbfac1dSAndre Guedes 	if (cancel_delayed_work(&hdev->le_scan_disable)) {
15737dbfac1dSAndre Guedes 		struct hci_cp_le_set_scan_enable cp;
15747dbfac1dSAndre Guedes 
15757dbfac1dSAndre Guedes 		/* Send HCI command to disable LE Scan */
15767dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
15777dbfac1dSAndre Guedes 		hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
15787dbfac1dSAndre Guedes 	}
15797dbfac1dSAndre Guedes 
15807dbfac1dSAndre Guedes 	return 0;
15817dbfac1dSAndre Guedes }
15827dbfac1dSAndre Guedes 
15837ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
15847ba8b4beSAndre Guedes {
15857ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
15867ba8b4beSAndre Guedes 					    le_scan_disable.work);
15877ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
15887ba8b4beSAndre Guedes 
15897ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
15907ba8b4beSAndre Guedes 
15917ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
15927ba8b4beSAndre Guedes 
15937ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
15947ba8b4beSAndre Guedes }
15957ba8b4beSAndre Guedes 
159628b75a89SAndre Guedes static void le_scan_work(struct work_struct *work)
159728b75a89SAndre Guedes {
159828b75a89SAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
159928b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
160028b75a89SAndre Guedes 
160128b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
160228b75a89SAndre Guedes 
160304124681SGustavo F. Padovan 	hci_do_le_scan(hdev, param->type, param->interval, param->window,
160404124681SGustavo F. Padovan 		       param->timeout);
160528b75a89SAndre Guedes }
160628b75a89SAndre Guedes 
160728b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
160828b75a89SAndre Guedes 		int timeout)
160928b75a89SAndre Guedes {
161028b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
161128b75a89SAndre Guedes 
161228b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
161328b75a89SAndre Guedes 
161428b75a89SAndre Guedes 	if (work_busy(&hdev->le_scan))
161528b75a89SAndre Guedes 		return -EINPROGRESS;
161628b75a89SAndre Guedes 
161728b75a89SAndre Guedes 	param->type = type;
161828b75a89SAndre Guedes 	param->interval = interval;
161928b75a89SAndre Guedes 	param->window = window;
162028b75a89SAndre Guedes 	param->timeout = timeout;
162128b75a89SAndre Guedes 
162228b75a89SAndre Guedes 	queue_work(system_long_wq, &hdev->le_scan);
162328b75a89SAndre Guedes 
162428b75a89SAndre Guedes 	return 0;
162528b75a89SAndre Guedes }
162628b75a89SAndre Guedes 
16279be0dab7SDavid Herrmann /* Alloc HCI device */
16289be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
16299be0dab7SDavid Herrmann {
16309be0dab7SDavid Herrmann 	struct hci_dev *hdev;
16319be0dab7SDavid Herrmann 
16329be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
16339be0dab7SDavid Herrmann 	if (!hdev)
16349be0dab7SDavid Herrmann 		return NULL;
16359be0dab7SDavid Herrmann 
1636b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
1637b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
1638b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
1639b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03; /* No Input No Output */
1640b1b813d4SDavid Herrmann 
1641b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
1642b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
1643b1b813d4SDavid Herrmann 
1644b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
1645b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
1646b1b813d4SDavid Herrmann 
1647b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
1648b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
1649b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
1650b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
1651b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
1652b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
1653b1b813d4SDavid Herrmann 
1654b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1655b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
1656b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
1657b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
1658b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->le_scan, le_scan_work);
1659b1b813d4SDavid Herrmann 
1660b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
1661b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
1662b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
1663b1b813d4SDavid Herrmann 
16649be0dab7SDavid Herrmann 	skb_queue_head_init(&hdev->driver_init);
1665b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
1666b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
1667b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
1668b1b813d4SDavid Herrmann 
1669b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
1670b1b813d4SDavid Herrmann 
1671bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
1672b1b813d4SDavid Herrmann 
1673b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
1674b1b813d4SDavid Herrmann 	discovery_init(hdev);
1675b1b813d4SDavid Herrmann 	hci_conn_hash_init(hdev);
16769be0dab7SDavid Herrmann 
16779be0dab7SDavid Herrmann 	return hdev;
16789be0dab7SDavid Herrmann }
16799be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
16809be0dab7SDavid Herrmann 
16819be0dab7SDavid Herrmann /* Free HCI device */
16829be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
16839be0dab7SDavid Herrmann {
16849be0dab7SDavid Herrmann 	skb_queue_purge(&hdev->driver_init);
16859be0dab7SDavid Herrmann 
16869be0dab7SDavid Herrmann 	/* will free via device release */
16879be0dab7SDavid Herrmann 	put_device(&hdev->dev);
16889be0dab7SDavid Herrmann }
16899be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
16909be0dab7SDavid Herrmann 
16911da177e4SLinus Torvalds /* Register HCI device */
16921da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
16931da177e4SLinus Torvalds {
1694b1b813d4SDavid Herrmann 	int id, error;
16951da177e4SLinus Torvalds 
1696010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
16971da177e4SLinus Torvalds 		return -EINVAL;
16981da177e4SLinus Torvalds 
169908add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
170008add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
170108add513SMat Martineau 	 */
17023df92b31SSasha Levin 	switch (hdev->dev_type) {
17033df92b31SSasha Levin 	case HCI_BREDR:
17043df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
17051da177e4SLinus Torvalds 		break;
17063df92b31SSasha Levin 	case HCI_AMP:
17073df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
17083df92b31SSasha Levin 		break;
17093df92b31SSasha Levin 	default:
17103df92b31SSasha Levin 		return -EINVAL;
17111da177e4SLinus Torvalds 	}
17121da177e4SLinus Torvalds 
17133df92b31SSasha Levin 	if (id < 0)
17143df92b31SSasha Levin 		return id;
17153df92b31SSasha Levin 
17161da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
17171da177e4SLinus Torvalds 	hdev->id = id;
17182d8b3a11SAndrei Emeltchenko 
17192d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
17202d8b3a11SAndrei Emeltchenko 
17213df92b31SSasha Levin 	write_lock(&hci_dev_list_lock);
17223df92b31SSasha Levin 	list_add(&hdev->list, &hci_dev_list);
1723f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
17241da177e4SLinus Torvalds 
172532845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
172632845eb1SGustavo F. Padovan 					  WQ_MEM_RECLAIM, 1);
172733ca954dSDavid Herrmann 	if (!hdev->workqueue) {
172833ca954dSDavid Herrmann 		error = -ENOMEM;
172933ca954dSDavid Herrmann 		goto err;
173033ca954dSDavid Herrmann 	}
1731f48fd9c8SMarcel Holtmann 
173233ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
173333ca954dSDavid Herrmann 	if (error < 0)
173433ca954dSDavid Herrmann 		goto err_wqueue;
17351da177e4SLinus Torvalds 
1736611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1737a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
1738a8c5fb1aSGustavo Padovan 				    hdev);
1739611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1740611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
1741611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
1742611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
1743611b30f7SMarcel Holtmann 		}
1744611b30f7SMarcel Holtmann 	}
1745611b30f7SMarcel Holtmann 
1746a8b2d5c2SJohan Hedberg 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
1747a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
17487f971041SGustavo F. Padovan 	schedule_work(&hdev->power_on);
1749ab81cbf9SJohan Hedberg 
17501da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
1751dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
17521da177e4SLinus Torvalds 
17531da177e4SLinus Torvalds 	return id;
1754f48fd9c8SMarcel Holtmann 
175533ca954dSDavid Herrmann err_wqueue:
175633ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
175733ca954dSDavid Herrmann err:
17583df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
1759f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
1760f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
1761f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
1762f48fd9c8SMarcel Holtmann 
176333ca954dSDavid Herrmann 	return error;
17641da177e4SLinus Torvalds }
17651da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
17661da177e4SLinus Torvalds 
17671da177e4SLinus Torvalds /* Unregister HCI device */
176859735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
17691da177e4SLinus Torvalds {
17703df92b31SSasha Levin 	int i, id;
1771ef222013SMarcel Holtmann 
1772c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
17731da177e4SLinus Torvalds 
177494324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
177594324962SJohan Hovold 
17763df92b31SSasha Levin 	id = hdev->id;
17773df92b31SSasha Levin 
1778f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
17791da177e4SLinus Torvalds 	list_del(&hdev->list);
1780f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
17811da177e4SLinus Torvalds 
17821da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
17831da177e4SLinus Torvalds 
1784cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1785ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
1786ef222013SMarcel Holtmann 
1787ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
1788a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
178909fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1790744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
179109fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
179256e5cb86SJohan Hedberg 	}
1793ab81cbf9SJohan Hedberg 
17942e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
17952e58ef3eSJohan Hedberg 	 * pending list */
17962e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
17972e58ef3eSJohan Hedberg 
17981da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
17991da177e4SLinus Torvalds 
1800611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1801611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
1802611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
1803611b30f7SMarcel Holtmann 	}
1804611b30f7SMarcel Holtmann 
1805ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
1806147e2d59SDave Young 
1807f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
1808f48fd9c8SMarcel Holtmann 
180909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
1810e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
18112aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
181255ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
1813b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
18142763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
181509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
1816e2e0cacbSJohan Hedberg 
1817dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
18183df92b31SSasha Levin 
18193df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
18201da177e4SLinus Torvalds }
18211da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
18221da177e4SLinus Torvalds 
18231da177e4SLinus Torvalds /* Suspend HCI device */
18241da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
18251da177e4SLinus Torvalds {
18261da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
18271da177e4SLinus Torvalds 	return 0;
18281da177e4SLinus Torvalds }
18291da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
18301da177e4SLinus Torvalds 
18311da177e4SLinus Torvalds /* Resume HCI device */
18321da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
18331da177e4SLinus Torvalds {
18341da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
18351da177e4SLinus Torvalds 	return 0;
18361da177e4SLinus Torvalds }
18371da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
18381da177e4SLinus Torvalds 
183976bca880SMarcel Holtmann /* Receive frame from HCI drivers */
184076bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
184176bca880SMarcel Holtmann {
184276bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
184376bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
184476bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
184576bca880SMarcel Holtmann 		kfree_skb(skb);
184676bca880SMarcel Holtmann 		return -ENXIO;
184776bca880SMarcel Holtmann 	}
184876bca880SMarcel Holtmann 
184976bca880SMarcel Holtmann 	/* Incomming skb */
185076bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
185176bca880SMarcel Holtmann 
185276bca880SMarcel Holtmann 	/* Time stamp */
185376bca880SMarcel Holtmann 	__net_timestamp(skb);
185476bca880SMarcel Holtmann 
185576bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
1856b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
1857c78ae283SMarcel Holtmann 
185876bca880SMarcel Holtmann 	return 0;
185976bca880SMarcel Holtmann }
186076bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
186176bca880SMarcel Holtmann 
186233e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
18631e429f38SGustavo F. Padovan 			  int count, __u8 index)
186433e882a5SSuraj Sumangala {
186533e882a5SSuraj Sumangala 	int len = 0;
186633e882a5SSuraj Sumangala 	int hlen = 0;
186733e882a5SSuraj Sumangala 	int remain = count;
186833e882a5SSuraj Sumangala 	struct sk_buff *skb;
186933e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
187033e882a5SSuraj Sumangala 
187133e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
187233e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
187333e882a5SSuraj Sumangala 		return -EILSEQ;
187433e882a5SSuraj Sumangala 
187533e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
187633e882a5SSuraj Sumangala 
187733e882a5SSuraj Sumangala 	if (!skb) {
187833e882a5SSuraj Sumangala 		switch (type) {
187933e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
188033e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
188133e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
188233e882a5SSuraj Sumangala 			break;
188333e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
188433e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
188533e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
188633e882a5SSuraj Sumangala 			break;
188733e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
188833e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
188933e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
189033e882a5SSuraj Sumangala 			break;
189133e882a5SSuraj Sumangala 		}
189233e882a5SSuraj Sumangala 
18931e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
189433e882a5SSuraj Sumangala 		if (!skb)
189533e882a5SSuraj Sumangala 			return -ENOMEM;
189633e882a5SSuraj Sumangala 
189733e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
189833e882a5SSuraj Sumangala 		scb->expect = hlen;
189933e882a5SSuraj Sumangala 		scb->pkt_type = type;
190033e882a5SSuraj Sumangala 
190133e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
190233e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
190333e882a5SSuraj Sumangala 	}
190433e882a5SSuraj Sumangala 
190533e882a5SSuraj Sumangala 	while (count) {
190633e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
190789bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
190833e882a5SSuraj Sumangala 
190933e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
191033e882a5SSuraj Sumangala 
191133e882a5SSuraj Sumangala 		count -= len;
191233e882a5SSuraj Sumangala 		data += len;
191333e882a5SSuraj Sumangala 		scb->expect -= len;
191433e882a5SSuraj Sumangala 		remain = count;
191533e882a5SSuraj Sumangala 
191633e882a5SSuraj Sumangala 		switch (type) {
191733e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
191833e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
191933e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
192033e882a5SSuraj Sumangala 				scb->expect = h->plen;
192133e882a5SSuraj Sumangala 
192233e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
192333e882a5SSuraj Sumangala 					kfree_skb(skb);
192433e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
192533e882a5SSuraj Sumangala 					return -ENOMEM;
192633e882a5SSuraj Sumangala 				}
192733e882a5SSuraj Sumangala 			}
192833e882a5SSuraj Sumangala 			break;
192933e882a5SSuraj Sumangala 
193033e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
193133e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
193233e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
193333e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
193433e882a5SSuraj Sumangala 
193533e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
193633e882a5SSuraj Sumangala 					kfree_skb(skb);
193733e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
193833e882a5SSuraj Sumangala 					return -ENOMEM;
193933e882a5SSuraj Sumangala 				}
194033e882a5SSuraj Sumangala 			}
194133e882a5SSuraj Sumangala 			break;
194233e882a5SSuraj Sumangala 
194333e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
194433e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
194533e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
194633e882a5SSuraj Sumangala 				scb->expect = h->dlen;
194733e882a5SSuraj Sumangala 
194833e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
194933e882a5SSuraj Sumangala 					kfree_skb(skb);
195033e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
195133e882a5SSuraj Sumangala 					return -ENOMEM;
195233e882a5SSuraj Sumangala 				}
195333e882a5SSuraj Sumangala 			}
195433e882a5SSuraj Sumangala 			break;
195533e882a5SSuraj Sumangala 		}
195633e882a5SSuraj Sumangala 
195733e882a5SSuraj Sumangala 		if (scb->expect == 0) {
195833e882a5SSuraj Sumangala 			/* Complete frame */
195933e882a5SSuraj Sumangala 
196033e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
196133e882a5SSuraj Sumangala 			hci_recv_frame(skb);
196233e882a5SSuraj Sumangala 
196333e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
196433e882a5SSuraj Sumangala 			return remain;
196533e882a5SSuraj Sumangala 		}
196633e882a5SSuraj Sumangala 	}
196733e882a5SSuraj Sumangala 
196833e882a5SSuraj Sumangala 	return remain;
196933e882a5SSuraj Sumangala }
197033e882a5SSuraj Sumangala 
1971ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
1972ef222013SMarcel Holtmann {
1973f39a3c06SSuraj Sumangala 	int rem = 0;
1974f39a3c06SSuraj Sumangala 
1975ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
1976ef222013SMarcel Holtmann 		return -EILSEQ;
1977ef222013SMarcel Holtmann 
1978da5f6c37SGustavo F. Padovan 	while (count) {
19791e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
1980f39a3c06SSuraj Sumangala 		if (rem < 0)
1981f39a3c06SSuraj Sumangala 			return rem;
1982ef222013SMarcel Holtmann 
1983f39a3c06SSuraj Sumangala 		data += (count - rem);
1984f39a3c06SSuraj Sumangala 		count = rem;
1985f81c6224SJoe Perches 	}
1986ef222013SMarcel Holtmann 
1987f39a3c06SSuraj Sumangala 	return rem;
1988ef222013SMarcel Holtmann }
1989ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
1990ef222013SMarcel Holtmann 
199199811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
199299811510SSuraj Sumangala 
199399811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
199499811510SSuraj Sumangala {
199599811510SSuraj Sumangala 	int type;
199699811510SSuraj Sumangala 	int rem = 0;
199799811510SSuraj Sumangala 
1998da5f6c37SGustavo F. Padovan 	while (count) {
199999811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
200099811510SSuraj Sumangala 
200199811510SSuraj Sumangala 		if (!skb) {
200299811510SSuraj Sumangala 			struct { char type; } *pkt;
200399811510SSuraj Sumangala 
200499811510SSuraj Sumangala 			/* Start of the frame */
200599811510SSuraj Sumangala 			pkt = data;
200699811510SSuraj Sumangala 			type = pkt->type;
200799811510SSuraj Sumangala 
200899811510SSuraj Sumangala 			data++;
200999811510SSuraj Sumangala 			count--;
201099811510SSuraj Sumangala 		} else
201199811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
201299811510SSuraj Sumangala 
20131e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
20141e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
201599811510SSuraj Sumangala 		if (rem < 0)
201699811510SSuraj Sumangala 			return rem;
201799811510SSuraj Sumangala 
201899811510SSuraj Sumangala 		data += (count - rem);
201999811510SSuraj Sumangala 		count = rem;
2020f81c6224SJoe Perches 	}
202199811510SSuraj Sumangala 
202299811510SSuraj Sumangala 	return rem;
202399811510SSuraj Sumangala }
202499811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
202599811510SSuraj Sumangala 
20261da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
20271da177e4SLinus Torvalds 
20281da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
20291da177e4SLinus Torvalds {
20301da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
20311da177e4SLinus Torvalds 
2032f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
20331da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2034f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
20351da177e4SLinus Torvalds 
20361da177e4SLinus Torvalds 	return 0;
20371da177e4SLinus Torvalds }
20381da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
20391da177e4SLinus Torvalds 
20401da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
20411da177e4SLinus Torvalds {
20421da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
20431da177e4SLinus Torvalds 
2044f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
20451da177e4SLinus Torvalds 	list_del(&cb->list);
2046f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
20471da177e4SLinus Torvalds 
20481da177e4SLinus Torvalds 	return 0;
20491da177e4SLinus Torvalds }
20501da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
20511da177e4SLinus Torvalds 
20521da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
20531da177e4SLinus Torvalds {
20541da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
20551da177e4SLinus Torvalds 
20561da177e4SLinus Torvalds 	if (!hdev) {
20571da177e4SLinus Torvalds 		kfree_skb(skb);
20581da177e4SLinus Torvalds 		return -ENODEV;
20591da177e4SLinus Torvalds 	}
20601da177e4SLinus Torvalds 
20610d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
20621da177e4SLinus Torvalds 
20631da177e4SLinus Torvalds 	/* Time stamp */
2064a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
20651da177e4SLinus Torvalds 
2066cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2067cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2068cd82e61cSMarcel Holtmann 
2069cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2070cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2071470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
20721da177e4SLinus Torvalds 	}
20731da177e4SLinus Torvalds 
20741da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
20751da177e4SLinus Torvalds 	skb_orphan(skb);
20761da177e4SLinus Torvalds 
20771da177e4SLinus Torvalds 	return hdev->send(skb);
20781da177e4SLinus Torvalds }
20791da177e4SLinus Torvalds 
20801da177e4SLinus Torvalds /* Send HCI command */
2081a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
20821da177e4SLinus Torvalds {
20831da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
20841da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
20851da177e4SLinus Torvalds 	struct sk_buff *skb;
20861da177e4SLinus Torvalds 
2087f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
20881da177e4SLinus Torvalds 
20891da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
20901da177e4SLinus Torvalds 	if (!skb) {
2091ef222013SMarcel Holtmann 		BT_ERR("%s no memory for command", hdev->name);
20921da177e4SLinus Torvalds 		return -ENOMEM;
20931da177e4SLinus Torvalds 	}
20941da177e4SLinus Torvalds 
20951da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2096a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
20971da177e4SLinus Torvalds 	hdr->plen   = plen;
20981da177e4SLinus Torvalds 
20991da177e4SLinus Torvalds 	if (plen)
21001da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
21011da177e4SLinus Torvalds 
21021da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
21031da177e4SLinus Torvalds 
21040d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
21051da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2106c78ae283SMarcel Holtmann 
2107a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
2108a5040efaSJohan Hedberg 		hdev->init_last_cmd = opcode;
2109a5040efaSJohan Hedberg 
21101da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2111c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
21121da177e4SLinus Torvalds 
21131da177e4SLinus Torvalds 	return 0;
21141da177e4SLinus Torvalds }
21151da177e4SLinus Torvalds 
21161da177e4SLinus Torvalds /* Get data from the previously sent command */
2117a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
21181da177e4SLinus Torvalds {
21191da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
21201da177e4SLinus Torvalds 
21211da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
21221da177e4SLinus Torvalds 		return NULL;
21231da177e4SLinus Torvalds 
21241da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
21251da177e4SLinus Torvalds 
2126a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
21271da177e4SLinus Torvalds 		return NULL;
21281da177e4SLinus Torvalds 
2129f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
21301da177e4SLinus Torvalds 
21311da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
21321da177e4SLinus Torvalds }
21331da177e4SLinus Torvalds 
21341da177e4SLinus Torvalds /* Send ACL data */
21351da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
21361da177e4SLinus Torvalds {
21371da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
21381da177e4SLinus Torvalds 	int len = skb->len;
21391da177e4SLinus Torvalds 
2140badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2141badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
21429c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2143aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2144aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
21451da177e4SLinus Torvalds }
21461da177e4SLinus Torvalds 
214773d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
214873d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
21491da177e4SLinus Torvalds {
21501da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
21511da177e4SLinus Torvalds 	struct sk_buff *list;
21521da177e4SLinus Torvalds 
2153087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
2154087bfd99SGustavo Padovan 	skb->data_len = 0;
2155087bfd99SGustavo Padovan 
2156087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2157087bfd99SGustavo Padovan 	hci_add_acl_hdr(skb, conn->handle, flags);
2158087bfd99SGustavo Padovan 
215970f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
216070f23020SAndrei Emeltchenko 	if (!list) {
21611da177e4SLinus Torvalds 		/* Non fragmented */
21621da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
21631da177e4SLinus Torvalds 
216473d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
21651da177e4SLinus Torvalds 	} else {
21661da177e4SLinus Torvalds 		/* Fragmented */
21671da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
21681da177e4SLinus Torvalds 
21691da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
21701da177e4SLinus Torvalds 
21711da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2172af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
21731da177e4SLinus Torvalds 
217473d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2175e702112fSAndrei Emeltchenko 
2176e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2177e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
21781da177e4SLinus Torvalds 		do {
21791da177e4SLinus Torvalds 			skb = list; list = list->next;
21801da177e4SLinus Torvalds 
21811da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
21820d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2183e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
21841da177e4SLinus Torvalds 
21851da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
21861da177e4SLinus Torvalds 
218773d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
21881da177e4SLinus Torvalds 		} while (list);
21891da177e4SLinus Torvalds 
2190af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
21911da177e4SLinus Torvalds 	}
219273d80debSLuiz Augusto von Dentz }
219373d80debSLuiz Augusto von Dentz 
219473d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
219573d80debSLuiz Augusto von Dentz {
219673d80debSLuiz Augusto von Dentz 	struct hci_conn *conn = chan->conn;
219773d80debSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
219873d80debSLuiz Augusto von Dentz 
2199f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
220073d80debSLuiz Augusto von Dentz 
220173d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
220273d80debSLuiz Augusto von Dentz 
220373d80debSLuiz Augusto von Dentz 	hci_queue_acl(conn, &chan->data_q, skb, flags);
22041da177e4SLinus Torvalds 
22053eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
22061da177e4SLinus Torvalds }
22071da177e4SLinus Torvalds 
22081da177e4SLinus Torvalds /* Send SCO data */
22090d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
22101da177e4SLinus Torvalds {
22111da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
22121da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
22131da177e4SLinus Torvalds 
22141da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
22151da177e4SLinus Torvalds 
2216aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
22171da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
22181da177e4SLinus Torvalds 
2219badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2220badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
22219c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
22221da177e4SLinus Torvalds 
22231da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
22240d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2225c78ae283SMarcel Holtmann 
22261da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
22273eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
22281da177e4SLinus Torvalds }
22291da177e4SLinus Torvalds 
22301da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
22311da177e4SLinus Torvalds 
22321da177e4SLinus Torvalds /* HCI Connection scheduler */
22336039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
2234a8c5fb1aSGustavo Padovan 				     int *quote)
22351da177e4SLinus Torvalds {
22361da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
22378035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
2238abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
22391da177e4SLinus Torvalds 
22401da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
22411da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2242bf4c6325SGustavo F. Padovan 
2243bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2244bf4c6325SGustavo F. Padovan 
2245bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2246769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
22471da177e4SLinus Torvalds 			continue;
2248769be974SMarcel Holtmann 
2249769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2250769be974SMarcel Holtmann 			continue;
2251769be974SMarcel Holtmann 
22521da177e4SLinus Torvalds 		num++;
22531da177e4SLinus Torvalds 
22541da177e4SLinus Torvalds 		if (c->sent < min) {
22551da177e4SLinus Torvalds 			min  = c->sent;
22561da177e4SLinus Torvalds 			conn = c;
22571da177e4SLinus Torvalds 		}
225852087a79SLuiz Augusto von Dentz 
225952087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
226052087a79SLuiz Augusto von Dentz 			break;
22611da177e4SLinus Torvalds 	}
22621da177e4SLinus Torvalds 
2263bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2264bf4c6325SGustavo F. Padovan 
22651da177e4SLinus Torvalds 	if (conn) {
22666ed58ec5SVille Tervo 		int cnt, q;
22676ed58ec5SVille Tervo 
22686ed58ec5SVille Tervo 		switch (conn->type) {
22696ed58ec5SVille Tervo 		case ACL_LINK:
22706ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
22716ed58ec5SVille Tervo 			break;
22726ed58ec5SVille Tervo 		case SCO_LINK:
22736ed58ec5SVille Tervo 		case ESCO_LINK:
22746ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
22756ed58ec5SVille Tervo 			break;
22766ed58ec5SVille Tervo 		case LE_LINK:
22776ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
22786ed58ec5SVille Tervo 			break;
22796ed58ec5SVille Tervo 		default:
22806ed58ec5SVille Tervo 			cnt = 0;
22816ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
22826ed58ec5SVille Tervo 		}
22836ed58ec5SVille Tervo 
22846ed58ec5SVille Tervo 		q = cnt / num;
22851da177e4SLinus Torvalds 		*quote = q ? q : 1;
22861da177e4SLinus Torvalds 	} else
22871da177e4SLinus Torvalds 		*quote = 0;
22881da177e4SLinus Torvalds 
22891da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
22901da177e4SLinus Torvalds 	return conn;
22911da177e4SLinus Torvalds }
22921da177e4SLinus Torvalds 
22936039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
22941da177e4SLinus Torvalds {
22951da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
22961da177e4SLinus Torvalds 	struct hci_conn *c;
22971da177e4SLinus Torvalds 
2298bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
22991da177e4SLinus Torvalds 
2300bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2301bf4c6325SGustavo F. Padovan 
23021da177e4SLinus Torvalds 	/* Kill stalled connections */
2303bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2304bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
2305bae1f5d9SVille Tervo 			BT_ERR("%s killing stalled connection %s",
23061da177e4SLinus Torvalds 			       hdev->name, batostr(&c->dst));
23077490c6c2SAndrei Emeltchenko 			hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM);
23081da177e4SLinus Torvalds 		}
23091da177e4SLinus Torvalds 	}
2310bf4c6325SGustavo F. Padovan 
2311bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
23121da177e4SLinus Torvalds }
23131da177e4SLinus Torvalds 
23146039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
231573d80debSLuiz Augusto von Dentz 				      int *quote)
231673d80debSLuiz Augusto von Dentz {
231773d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
231873d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
2319abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
232073d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
232173d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
232273d80debSLuiz Augusto von Dentz 
232373d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
232473d80debSLuiz Augusto von Dentz 
2325bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2326bf4c6325SGustavo F. Padovan 
2327bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
232873d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
232973d80debSLuiz Augusto von Dentz 
233073d80debSLuiz Augusto von Dentz 		if (conn->type != type)
233173d80debSLuiz Augusto von Dentz 			continue;
233273d80debSLuiz Augusto von Dentz 
233373d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
233473d80debSLuiz Augusto von Dentz 			continue;
233573d80debSLuiz Augusto von Dentz 
233673d80debSLuiz Augusto von Dentz 		conn_num++;
233773d80debSLuiz Augusto von Dentz 
23388192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
233973d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
234073d80debSLuiz Augusto von Dentz 
234173d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
234273d80debSLuiz Augusto von Dentz 				continue;
234373d80debSLuiz Augusto von Dentz 
234473d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
234573d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
234673d80debSLuiz Augusto von Dentz 				continue;
234773d80debSLuiz Augusto von Dentz 
234873d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
234973d80debSLuiz Augusto von Dentz 				num = 0;
235073d80debSLuiz Augusto von Dentz 				min = ~0;
235173d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
235273d80debSLuiz Augusto von Dentz 			}
235373d80debSLuiz Augusto von Dentz 
235473d80debSLuiz Augusto von Dentz 			num++;
235573d80debSLuiz Augusto von Dentz 
235673d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
235773d80debSLuiz Augusto von Dentz 				min  = conn->sent;
235873d80debSLuiz Augusto von Dentz 				chan = tmp;
235973d80debSLuiz Augusto von Dentz 			}
236073d80debSLuiz Augusto von Dentz 		}
236173d80debSLuiz Augusto von Dentz 
236273d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
236373d80debSLuiz Augusto von Dentz 			break;
236473d80debSLuiz Augusto von Dentz 	}
236573d80debSLuiz Augusto von Dentz 
2366bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2367bf4c6325SGustavo F. Padovan 
236873d80debSLuiz Augusto von Dentz 	if (!chan)
236973d80debSLuiz Augusto von Dentz 		return NULL;
237073d80debSLuiz Augusto von Dentz 
237173d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
237273d80debSLuiz Augusto von Dentz 	case ACL_LINK:
237373d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
237473d80debSLuiz Augusto von Dentz 		break;
237573d80debSLuiz Augusto von Dentz 	case SCO_LINK:
237673d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
237773d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
237873d80debSLuiz Augusto von Dentz 		break;
237973d80debSLuiz Augusto von Dentz 	case LE_LINK:
238073d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
238173d80debSLuiz Augusto von Dentz 		break;
238273d80debSLuiz Augusto von Dentz 	default:
238373d80debSLuiz Augusto von Dentz 		cnt = 0;
238473d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
238573d80debSLuiz Augusto von Dentz 	}
238673d80debSLuiz Augusto von Dentz 
238773d80debSLuiz Augusto von Dentz 	q = cnt / num;
238873d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
238973d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
239073d80debSLuiz Augusto von Dentz 	return chan;
239173d80debSLuiz Augusto von Dentz }
239273d80debSLuiz Augusto von Dentz 
239302b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
239402b20f0bSLuiz Augusto von Dentz {
239502b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
239602b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
239702b20f0bSLuiz Augusto von Dentz 	int num = 0;
239802b20f0bSLuiz Augusto von Dentz 
239902b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
240002b20f0bSLuiz Augusto von Dentz 
2401bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2402bf4c6325SGustavo F. Padovan 
2403bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
240402b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
240502b20f0bSLuiz Augusto von Dentz 
240602b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
240702b20f0bSLuiz Augusto von Dentz 			continue;
240802b20f0bSLuiz Augusto von Dentz 
240902b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
241002b20f0bSLuiz Augusto von Dentz 			continue;
241102b20f0bSLuiz Augusto von Dentz 
241202b20f0bSLuiz Augusto von Dentz 		num++;
241302b20f0bSLuiz Augusto von Dentz 
24148192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
241502b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
241602b20f0bSLuiz Augusto von Dentz 
241702b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
241802b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
241902b20f0bSLuiz Augusto von Dentz 				continue;
242002b20f0bSLuiz Augusto von Dentz 			}
242102b20f0bSLuiz Augusto von Dentz 
242202b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
242302b20f0bSLuiz Augusto von Dentz 				continue;
242402b20f0bSLuiz Augusto von Dentz 
242502b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
242602b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
242702b20f0bSLuiz Augusto von Dentz 				continue;
242802b20f0bSLuiz Augusto von Dentz 
242902b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
243002b20f0bSLuiz Augusto von Dentz 
243102b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
243202b20f0bSLuiz Augusto von Dentz 			       skb->priority);
243302b20f0bSLuiz Augusto von Dentz 		}
243402b20f0bSLuiz Augusto von Dentz 
243502b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
243602b20f0bSLuiz Augusto von Dentz 			break;
243702b20f0bSLuiz Augusto von Dentz 	}
2438bf4c6325SGustavo F. Padovan 
2439bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2440bf4c6325SGustavo F. Padovan 
244102b20f0bSLuiz Augusto von Dentz }
244202b20f0bSLuiz Augusto von Dentz 
2443b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
2444b71d385aSAndrei Emeltchenko {
2445b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
2446b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
2447b71d385aSAndrei Emeltchenko }
2448b71d385aSAndrei Emeltchenko 
24496039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
24501da177e4SLinus Torvalds {
24511da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
24521da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
24531da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
245463d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
24555f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
2456bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
24571da177e4SLinus Torvalds 	}
245863d2bc1bSAndrei Emeltchenko }
24591da177e4SLinus Torvalds 
24606039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
246163d2bc1bSAndrei Emeltchenko {
246263d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
246363d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
246463d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
246563d2bc1bSAndrei Emeltchenko 	int quote;
246663d2bc1bSAndrei Emeltchenko 
246763d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
246804837f64SMarcel Holtmann 
246973d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
247073d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2471ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2472ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
247373d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
247473d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
247573d80debSLuiz Augusto von Dentz 
2476ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2477ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2478ec1cce24SLuiz Augusto von Dentz 				break;
2479ec1cce24SLuiz Augusto von Dentz 
2480ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2481ec1cce24SLuiz Augusto von Dentz 
248273d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
248373d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
248404837f64SMarcel Holtmann 
24851da177e4SLinus Torvalds 			hci_send_frame(skb);
24861da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
24871da177e4SLinus Torvalds 
24881da177e4SLinus Torvalds 			hdev->acl_cnt--;
248973d80debSLuiz Augusto von Dentz 			chan->sent++;
249073d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
24911da177e4SLinus Torvalds 		}
24921da177e4SLinus Torvalds 	}
249302b20f0bSLuiz Augusto von Dentz 
249402b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
249502b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
24961da177e4SLinus Torvalds }
24971da177e4SLinus Torvalds 
24986039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
2499b71d385aSAndrei Emeltchenko {
250063d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
2501b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
2502b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
2503b71d385aSAndrei Emeltchenko 	int quote;
2504b71d385aSAndrei Emeltchenko 
250563d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
2506b71d385aSAndrei Emeltchenko 
2507b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
2508b71d385aSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2509b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
2510b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
2511b71d385aSAndrei Emeltchenko 			int blocks;
2512b71d385aSAndrei Emeltchenko 
2513b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
2514b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
2515b71d385aSAndrei Emeltchenko 
2516b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
2517b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
2518b71d385aSAndrei Emeltchenko 				break;
2519b71d385aSAndrei Emeltchenko 
2520b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
2521b71d385aSAndrei Emeltchenko 
2522b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
2523b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
2524b71d385aSAndrei Emeltchenko 				return;
2525b71d385aSAndrei Emeltchenko 
2526b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
2527b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
2528b71d385aSAndrei Emeltchenko 
2529b71d385aSAndrei Emeltchenko 			hci_send_frame(skb);
2530b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
2531b71d385aSAndrei Emeltchenko 
2532b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
2533b71d385aSAndrei Emeltchenko 			quote -= blocks;
2534b71d385aSAndrei Emeltchenko 
2535b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
2536b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
2537b71d385aSAndrei Emeltchenko 		}
2538b71d385aSAndrei Emeltchenko 	}
2539b71d385aSAndrei Emeltchenko 
2540b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
2541b71d385aSAndrei Emeltchenko 		hci_prio_recalculate(hdev, ACL_LINK);
2542b71d385aSAndrei Emeltchenko }
2543b71d385aSAndrei Emeltchenko 
25446039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
2545b71d385aSAndrei Emeltchenko {
2546b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
2547b71d385aSAndrei Emeltchenko 
2548b71d385aSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK))
2549b71d385aSAndrei Emeltchenko 		return;
2550b71d385aSAndrei Emeltchenko 
2551b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
2552b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
2553b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
2554b71d385aSAndrei Emeltchenko 		break;
2555b71d385aSAndrei Emeltchenko 
2556b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
2557b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
2558b71d385aSAndrei Emeltchenko 		break;
2559b71d385aSAndrei Emeltchenko 	}
2560b71d385aSAndrei Emeltchenko }
2561b71d385aSAndrei Emeltchenko 
25621da177e4SLinus Torvalds /* Schedule SCO */
25636039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
25641da177e4SLinus Torvalds {
25651da177e4SLinus Torvalds 	struct hci_conn *conn;
25661da177e4SLinus Torvalds 	struct sk_buff *skb;
25671da177e4SLinus Torvalds 	int quote;
25681da177e4SLinus Torvalds 
25691da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
25701da177e4SLinus Torvalds 
257152087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
257252087a79SLuiz Augusto von Dentz 		return;
257352087a79SLuiz Augusto von Dentz 
25741da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
25751da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
25761da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
25771da177e4SLinus Torvalds 			hci_send_frame(skb);
25781da177e4SLinus Torvalds 
25791da177e4SLinus Torvalds 			conn->sent++;
25801da177e4SLinus Torvalds 			if (conn->sent == ~0)
25811da177e4SLinus Torvalds 				conn->sent = 0;
25821da177e4SLinus Torvalds 		}
25831da177e4SLinus Torvalds 	}
25841da177e4SLinus Torvalds }
25851da177e4SLinus Torvalds 
25866039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
2587b6a0dc82SMarcel Holtmann {
2588b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
2589b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
2590b6a0dc82SMarcel Holtmann 	int quote;
2591b6a0dc82SMarcel Holtmann 
2592b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2593b6a0dc82SMarcel Holtmann 
259452087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
259552087a79SLuiz Augusto von Dentz 		return;
259652087a79SLuiz Augusto von Dentz 
25978fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
25988fc9ced3SGustavo Padovan 						     &quote))) {
2599b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
2600b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
2601b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
2602b6a0dc82SMarcel Holtmann 
2603b6a0dc82SMarcel Holtmann 			conn->sent++;
2604b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
2605b6a0dc82SMarcel Holtmann 				conn->sent = 0;
2606b6a0dc82SMarcel Holtmann 		}
2607b6a0dc82SMarcel Holtmann 	}
2608b6a0dc82SMarcel Holtmann }
2609b6a0dc82SMarcel Holtmann 
26106039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
26116ed58ec5SVille Tervo {
261273d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
26136ed58ec5SVille Tervo 	struct sk_buff *skb;
261402b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
26156ed58ec5SVille Tervo 
26166ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
26176ed58ec5SVille Tervo 
261852087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
261952087a79SLuiz Augusto von Dentz 		return;
262052087a79SLuiz Augusto von Dentz 
26216ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
26226ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
26236ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
2624bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
26256ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
2626bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
26276ed58ec5SVille Tervo 	}
26286ed58ec5SVille Tervo 
26296ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
263002b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
263173d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
2632ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2633ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
263473d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
263573d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
26366ed58ec5SVille Tervo 
2637ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2638ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2639ec1cce24SLuiz Augusto von Dentz 				break;
2640ec1cce24SLuiz Augusto von Dentz 
2641ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2642ec1cce24SLuiz Augusto von Dentz 
26436ed58ec5SVille Tervo 			hci_send_frame(skb);
26446ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
26456ed58ec5SVille Tervo 
26466ed58ec5SVille Tervo 			cnt--;
264773d80debSLuiz Augusto von Dentz 			chan->sent++;
264873d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
26496ed58ec5SVille Tervo 		}
26506ed58ec5SVille Tervo 	}
265173d80debSLuiz Augusto von Dentz 
26526ed58ec5SVille Tervo 	if (hdev->le_pkts)
26536ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
26546ed58ec5SVille Tervo 	else
26556ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
265602b20f0bSLuiz Augusto von Dentz 
265702b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
265802b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
26596ed58ec5SVille Tervo }
26606ed58ec5SVille Tervo 
26613eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
26621da177e4SLinus Torvalds {
26633eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
26641da177e4SLinus Torvalds 	struct sk_buff *skb;
26651da177e4SLinus Torvalds 
26666ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
26676ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
26681da177e4SLinus Torvalds 
26691da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
26701da177e4SLinus Torvalds 
26711da177e4SLinus Torvalds 	hci_sched_acl(hdev);
26721da177e4SLinus Torvalds 
26731da177e4SLinus Torvalds 	hci_sched_sco(hdev);
26741da177e4SLinus Torvalds 
2675b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
2676b6a0dc82SMarcel Holtmann 
26776ed58ec5SVille Tervo 	hci_sched_le(hdev);
26786ed58ec5SVille Tervo 
26791da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
26801da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
26811da177e4SLinus Torvalds 		hci_send_frame(skb);
26821da177e4SLinus Torvalds }
26831da177e4SLinus Torvalds 
268425985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
26851da177e4SLinus Torvalds 
26861da177e4SLinus Torvalds /* ACL data packet */
26876039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
26881da177e4SLinus Torvalds {
26891da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
26901da177e4SLinus Torvalds 	struct hci_conn *conn;
26911da177e4SLinus Torvalds 	__u16 handle, flags;
26921da177e4SLinus Torvalds 
26931da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
26941da177e4SLinus Torvalds 
26951da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
26961da177e4SLinus Torvalds 	flags  = hci_flags(handle);
26971da177e4SLinus Torvalds 	handle = hci_handle(handle);
26981da177e4SLinus Torvalds 
2699f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
2700a8c5fb1aSGustavo Padovan 	       handle, flags);
27011da177e4SLinus Torvalds 
27021da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
27031da177e4SLinus Torvalds 
27041da177e4SLinus Torvalds 	hci_dev_lock(hdev);
27051da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
27061da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
27071da177e4SLinus Torvalds 
27081da177e4SLinus Torvalds 	if (conn) {
270965983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
271004837f64SMarcel Holtmann 
2711671267bfSJohan Hedberg 		hci_dev_lock(hdev);
2712671267bfSJohan Hedberg 		if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
2713671267bfSJohan Hedberg 		    !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2714671267bfSJohan Hedberg 			mgmt_device_connected(hdev, &conn->dst, conn->type,
2715671267bfSJohan Hedberg 					      conn->dst_type, 0, NULL, 0,
2716671267bfSJohan Hedberg 					      conn->dev_class);
2717671267bfSJohan Hedberg 		hci_dev_unlock(hdev);
2718671267bfSJohan Hedberg 
27191da177e4SLinus Torvalds 		/* Send to upper protocol */
2720686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
27211da177e4SLinus Torvalds 		return;
27221da177e4SLinus Torvalds 	} else {
27231da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
27241da177e4SLinus Torvalds 		       hdev->name, handle);
27251da177e4SLinus Torvalds 	}
27261da177e4SLinus Torvalds 
27271da177e4SLinus Torvalds 	kfree_skb(skb);
27281da177e4SLinus Torvalds }
27291da177e4SLinus Torvalds 
27301da177e4SLinus Torvalds /* SCO data packet */
27316039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
27321da177e4SLinus Torvalds {
27331da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
27341da177e4SLinus Torvalds 	struct hci_conn *conn;
27351da177e4SLinus Torvalds 	__u16 handle;
27361da177e4SLinus Torvalds 
27371da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
27381da177e4SLinus Torvalds 
27391da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
27401da177e4SLinus Torvalds 
2741f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
27421da177e4SLinus Torvalds 
27431da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
27441da177e4SLinus Torvalds 
27451da177e4SLinus Torvalds 	hci_dev_lock(hdev);
27461da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
27471da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
27481da177e4SLinus Torvalds 
27491da177e4SLinus Torvalds 	if (conn) {
27501da177e4SLinus Torvalds 		/* Send to upper protocol */
2751686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
27521da177e4SLinus Torvalds 		return;
27531da177e4SLinus Torvalds 	} else {
27541da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
27551da177e4SLinus Torvalds 		       hdev->name, handle);
27561da177e4SLinus Torvalds 	}
27571da177e4SLinus Torvalds 
27581da177e4SLinus Torvalds 	kfree_skb(skb);
27591da177e4SLinus Torvalds }
27601da177e4SLinus Torvalds 
2761b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
27621da177e4SLinus Torvalds {
2763b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
27641da177e4SLinus Torvalds 	struct sk_buff *skb;
27651da177e4SLinus Torvalds 
27661da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
27671da177e4SLinus Torvalds 
27681da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
2769cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
2770cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
2771cd82e61cSMarcel Holtmann 
27721da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
27731da177e4SLinus Torvalds 			/* Send copy to the sockets */
2774470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
27751da177e4SLinus Torvalds 		}
27761da177e4SLinus Torvalds 
27771da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
27781da177e4SLinus Torvalds 			kfree_skb(skb);
27791da177e4SLinus Torvalds 			continue;
27801da177e4SLinus Torvalds 		}
27811da177e4SLinus Torvalds 
27821da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
27831da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
27840d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
27851da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
27861da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
27871da177e4SLinus Torvalds 				kfree_skb(skb);
27881da177e4SLinus Torvalds 				continue;
27893ff50b79SStephen Hemminger 			}
27901da177e4SLinus Torvalds 		}
27911da177e4SLinus Torvalds 
27921da177e4SLinus Torvalds 		/* Process frame */
27930d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
27941da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
2795b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
27961da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
27971da177e4SLinus Torvalds 			break;
27981da177e4SLinus Torvalds 
27991da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
28001da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
28011da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
28021da177e4SLinus Torvalds 			break;
28031da177e4SLinus Torvalds 
28041da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
28051da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
28061da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
28071da177e4SLinus Torvalds 			break;
28081da177e4SLinus Torvalds 
28091da177e4SLinus Torvalds 		default:
28101da177e4SLinus Torvalds 			kfree_skb(skb);
28111da177e4SLinus Torvalds 			break;
28121da177e4SLinus Torvalds 		}
28131da177e4SLinus Torvalds 	}
28141da177e4SLinus Torvalds }
28151da177e4SLinus Torvalds 
2816c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
28171da177e4SLinus Torvalds {
2818c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
28191da177e4SLinus Torvalds 	struct sk_buff *skb;
28201da177e4SLinus Torvalds 
28211da177e4SLinus Torvalds 	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
28221da177e4SLinus Torvalds 
28231da177e4SLinus Torvalds 	/* Send queued commands */
28245a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
28255a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
28265a08ecceSAndrei Emeltchenko 		if (!skb)
28275a08ecceSAndrei Emeltchenko 			return;
28285a08ecceSAndrei Emeltchenko 
28291da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
28301da177e4SLinus Torvalds 
283170f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
283270f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
28331da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
28341da177e4SLinus Torvalds 			hci_send_frame(skb);
28357bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
28367bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
28377bdb8a5cSSzymon Janc 			else
28386bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
28395f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
28401da177e4SLinus Torvalds 		} else {
28411da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
2842c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
28431da177e4SLinus Torvalds 		}
28441da177e4SLinus Torvalds 	}
28451da177e4SLinus Torvalds }
28462519a1fcSAndre Guedes 
28472519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
28482519a1fcSAndre Guedes {
28492519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
28502519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
28512519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
28522519a1fcSAndre Guedes 
28532519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
28542519a1fcSAndre Guedes 
28552519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
28562519a1fcSAndre Guedes 		return -EINPROGRESS;
28572519a1fcSAndre Guedes 
28584663262cSJohan Hedberg 	inquiry_cache_flush(hdev);
28594663262cSJohan Hedberg 
28602519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
28612519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
28622519a1fcSAndre Guedes 	cp.length  = length;
28632519a1fcSAndre Guedes 
28642519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
28652519a1fcSAndre Guedes }
2866023d5049SAndre Guedes 
2867023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
2868023d5049SAndre Guedes {
2869023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
2870023d5049SAndre Guedes 
2871023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
28727537e5c3SAndre Guedes 		return -EALREADY;
2873023d5049SAndre Guedes 
2874023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2875023d5049SAndre Guedes }
287631f7956cSAndre Guedes 
287731f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type)
287831f7956cSAndre Guedes {
287931f7956cSAndre Guedes 	switch (bdaddr_type) {
288031f7956cSAndre Guedes 	case BDADDR_LE_PUBLIC:
288131f7956cSAndre Guedes 		return ADDR_LE_DEV_PUBLIC;
288231f7956cSAndre Guedes 
288331f7956cSAndre Guedes 	default:
288431f7956cSAndre Guedes 		/* Fallback to LE Random address type */
288531f7956cSAndre Guedes 		return ADDR_LE_DEV_RANDOM;
288631f7956cSAndre Guedes 	}
288731f7956cSAndre Guedes }
2888