xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 204a6e54)
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);
234e71dfabaSAndrei Emeltchenko 
235e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
236e71dfabaSAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
237e61ef499SAndrei Emeltchenko }
238e61ef499SAndrei Emeltchenko 
239e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
240e61ef499SAndrei Emeltchenko {
241e61ef499SAndrei Emeltchenko 	struct sk_buff *skb;
242e61ef499SAndrei Emeltchenko 
243e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
244e61ef499SAndrei Emeltchenko 
245e61ef499SAndrei Emeltchenko 	/* Driver initialization */
246e61ef499SAndrei Emeltchenko 
247e61ef499SAndrei Emeltchenko 	/* Special commands */
248e61ef499SAndrei Emeltchenko 	while ((skb = skb_dequeue(&hdev->driver_init))) {
249e61ef499SAndrei Emeltchenko 		bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
250e61ef499SAndrei Emeltchenko 		skb->dev = (void *) hdev;
251e61ef499SAndrei Emeltchenko 
252e61ef499SAndrei Emeltchenko 		skb_queue_tail(&hdev->cmd_q, skb);
253e61ef499SAndrei Emeltchenko 		queue_work(hdev->workqueue, &hdev->cmd_work);
254e61ef499SAndrei Emeltchenko 	}
255e61ef499SAndrei Emeltchenko 	skb_queue_purge(&hdev->driver_init);
256e61ef499SAndrei Emeltchenko 
25711778716SAndrei Emeltchenko 	/* Reset */
25811778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
25911778716SAndrei Emeltchenko 		hci_reset_req(hdev, 0);
26011778716SAndrei Emeltchenko 
261e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
262e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
263e61ef499SAndrei Emeltchenko 		bredr_init(hdev);
264e61ef499SAndrei Emeltchenko 		break;
265e61ef499SAndrei Emeltchenko 
266e61ef499SAndrei Emeltchenko 	case HCI_AMP:
267e61ef499SAndrei Emeltchenko 		amp_init(hdev);
268e61ef499SAndrei Emeltchenko 		break;
269e61ef499SAndrei Emeltchenko 
270e61ef499SAndrei Emeltchenko 	default:
271e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
272e61ef499SAndrei Emeltchenko 		break;
273e61ef499SAndrei Emeltchenko 	}
274e61ef499SAndrei Emeltchenko }
275e61ef499SAndrei Emeltchenko 
2766ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
2776ed58ec5SVille Tervo {
2786ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
2796ed58ec5SVille Tervo 
2806ed58ec5SVille Tervo 	/* Read LE buffer size */
2816ed58ec5SVille Tervo 	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
2826ed58ec5SVille Tervo }
2836ed58ec5SVille Tervo 
2841da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
2851da177e4SLinus Torvalds {
2861da177e4SLinus Torvalds 	__u8 scan = opt;
2871da177e4SLinus Torvalds 
2881da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, scan);
2891da177e4SLinus Torvalds 
2901da177e4SLinus Torvalds 	/* Inquiry and Page scans */
291a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
2921da177e4SLinus Torvalds }
2931da177e4SLinus Torvalds 
2941da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
2951da177e4SLinus Torvalds {
2961da177e4SLinus Torvalds 	__u8 auth = opt;
2971da177e4SLinus Torvalds 
2981da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, auth);
2991da177e4SLinus Torvalds 
3001da177e4SLinus Torvalds 	/* Authentication */
301a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
3021da177e4SLinus Torvalds }
3031da177e4SLinus Torvalds 
3041da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
3051da177e4SLinus Torvalds {
3061da177e4SLinus Torvalds 	__u8 encrypt = opt;
3071da177e4SLinus Torvalds 
3081da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, encrypt);
3091da177e4SLinus Torvalds 
310e4e8e37cSMarcel Holtmann 	/* Encryption */
311a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
3121da177e4SLinus Torvalds }
3131da177e4SLinus Torvalds 
314e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt)
315e4e8e37cSMarcel Holtmann {
316e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
317e4e8e37cSMarcel Holtmann 
318a418b893SMarcel Holtmann 	BT_DBG("%s %x", hdev->name, policy);
319e4e8e37cSMarcel Holtmann 
320e4e8e37cSMarcel Holtmann 	/* Default link policy */
321e4e8e37cSMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
322e4e8e37cSMarcel Holtmann }
323e4e8e37cSMarcel Holtmann 
3241da177e4SLinus Torvalds /* Get HCI device by index.
3251da177e4SLinus Torvalds  * Device is held on return. */
3261da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
3271da177e4SLinus Torvalds {
3288035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
3291da177e4SLinus Torvalds 
3301da177e4SLinus Torvalds 	BT_DBG("%d", index);
3311da177e4SLinus Torvalds 
3321da177e4SLinus Torvalds 	if (index < 0)
3331da177e4SLinus Torvalds 		return NULL;
3341da177e4SLinus Torvalds 
3351da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
3368035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
3371da177e4SLinus Torvalds 		if (d->id == index) {
3381da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
3391da177e4SLinus Torvalds 			break;
3401da177e4SLinus Torvalds 		}
3411da177e4SLinus Torvalds 	}
3421da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
3431da177e4SLinus Torvalds 	return hdev;
3441da177e4SLinus Torvalds }
3451da177e4SLinus Torvalds 
3461da177e4SLinus Torvalds /* ---- Inquiry support ---- */
347ff9ef578SJohan Hedberg 
34830dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
34930dc78e1SJohan Hedberg {
35030dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
35130dc78e1SJohan Hedberg 
3526fbe195dSAndre Guedes 	switch (discov->state) {
353343f935bSAndre Guedes 	case DISCOVERY_FINDING:
3546fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
35530dc78e1SJohan Hedberg 		return true;
35630dc78e1SJohan Hedberg 
3576fbe195dSAndre Guedes 	default:
35830dc78e1SJohan Hedberg 		return false;
35930dc78e1SJohan Hedberg 	}
3606fbe195dSAndre Guedes }
36130dc78e1SJohan Hedberg 
362ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
363ff9ef578SJohan Hedberg {
364ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
365ff9ef578SJohan Hedberg 
366ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
367ff9ef578SJohan Hedberg 		return;
368ff9ef578SJohan Hedberg 
369ff9ef578SJohan Hedberg 	switch (state) {
370ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
3717b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
372ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
373ff9ef578SJohan Hedberg 		break;
374ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
375ff9ef578SJohan Hedberg 		break;
376343f935bSAndre Guedes 	case DISCOVERY_FINDING:
377ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
378ff9ef578SJohan Hedberg 		break;
37930dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
38030dc78e1SJohan Hedberg 		break;
381ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
382ff9ef578SJohan Hedberg 		break;
383ff9ef578SJohan Hedberg 	}
384ff9ef578SJohan Hedberg 
385ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
386ff9ef578SJohan Hedberg }
387ff9ef578SJohan Hedberg 
3881da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
3891da177e4SLinus Torvalds {
39030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
391b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
3921da177e4SLinus Torvalds 
393561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
394561aafbcSJohan Hedberg 		list_del(&p->all);
395b57c1a56SJohan Hedberg 		kfree(p);
3961da177e4SLinus Torvalds 	}
397561aafbcSJohan Hedberg 
398561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
399561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
4001da177e4SLinus Torvalds }
4011da177e4SLinus Torvalds 
402a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
403a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
4041da177e4SLinus Torvalds {
40530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
4061da177e4SLinus Torvalds 	struct inquiry_entry *e;
4071da177e4SLinus Torvalds 
4086ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
4091da177e4SLinus Torvalds 
410561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
4111da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
4121da177e4SLinus Torvalds 			return e;
4131da177e4SLinus Torvalds 	}
4141da177e4SLinus Torvalds 
415b57c1a56SJohan Hedberg 	return NULL;
416b57c1a56SJohan Hedberg }
417b57c1a56SJohan Hedberg 
418561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
419561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
420561aafbcSJohan Hedberg {
42130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
422561aafbcSJohan Hedberg 	struct inquiry_entry *e;
423561aafbcSJohan Hedberg 
4246ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
425561aafbcSJohan Hedberg 
426561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
427561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
428561aafbcSJohan Hedberg 			return e;
429561aafbcSJohan Hedberg 	}
430561aafbcSJohan Hedberg 
431561aafbcSJohan Hedberg 	return NULL;
432561aafbcSJohan Hedberg }
433561aafbcSJohan Hedberg 
43430dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
43530dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
43630dc78e1SJohan Hedberg 						       int state)
43730dc78e1SJohan Hedberg {
43830dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
43930dc78e1SJohan Hedberg 	struct inquiry_entry *e;
44030dc78e1SJohan Hedberg 
4416ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
44230dc78e1SJohan Hedberg 
44330dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
44430dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
44530dc78e1SJohan Hedberg 			return e;
44630dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
44730dc78e1SJohan Hedberg 			return e;
44830dc78e1SJohan Hedberg 	}
44930dc78e1SJohan Hedberg 
45030dc78e1SJohan Hedberg 	return NULL;
45130dc78e1SJohan Hedberg }
45230dc78e1SJohan Hedberg 
453a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
454a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
455a3d4e20aSJohan Hedberg {
456a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
457a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
458a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
459a3d4e20aSJohan Hedberg 
460a3d4e20aSJohan Hedberg 	list_del(&ie->list);
461a3d4e20aSJohan Hedberg 
462a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
463a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
464a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
465a3d4e20aSJohan Hedberg 			break;
466a3d4e20aSJohan Hedberg 		pos = &p->list;
467a3d4e20aSJohan Hedberg 	}
468a3d4e20aSJohan Hedberg 
469a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
470a3d4e20aSJohan Hedberg }
471a3d4e20aSJohan Hedberg 
4723175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
473388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
4741da177e4SLinus Torvalds {
47530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
47670f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
4771da177e4SLinus Torvalds 
4786ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
4791da177e4SLinus Torvalds 
480388fc8faSJohan Hedberg 	if (ssp)
481388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
482388fc8faSJohan Hedberg 
48370f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
484a3d4e20aSJohan Hedberg 	if (ie) {
485388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
486388fc8faSJohan Hedberg 			*ssp = true;
487388fc8faSJohan Hedberg 
488a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
489a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
490a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
491a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
492a3d4e20aSJohan Hedberg 		}
493a3d4e20aSJohan Hedberg 
494561aafbcSJohan Hedberg 		goto update;
495a3d4e20aSJohan Hedberg 	}
496561aafbcSJohan Hedberg 
4971da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
49870f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
49970f23020SAndrei Emeltchenko 	if (!ie)
5003175405bSJohan Hedberg 		return false;
50170f23020SAndrei Emeltchenko 
502561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
503561aafbcSJohan Hedberg 
504561aafbcSJohan Hedberg 	if (name_known) {
505561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
506561aafbcSJohan Hedberg 	} else {
507561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
508561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
509561aafbcSJohan Hedberg 	}
510561aafbcSJohan Hedberg 
511561aafbcSJohan Hedberg update:
512561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
513561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
514561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
515561aafbcSJohan Hedberg 		list_del(&ie->list);
5161da177e4SLinus Torvalds 	}
5171da177e4SLinus Torvalds 
51870f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
51970f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
5201da177e4SLinus Torvalds 	cache->timestamp = jiffies;
5213175405bSJohan Hedberg 
5223175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
5233175405bSJohan Hedberg 		return false;
5243175405bSJohan Hedberg 
5253175405bSJohan Hedberg 	return true;
5261da177e4SLinus Torvalds }
5271da177e4SLinus Torvalds 
5281da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
5291da177e4SLinus Torvalds {
53030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
5311da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
5321da177e4SLinus Torvalds 	struct inquiry_entry *e;
5331da177e4SLinus Torvalds 	int copied = 0;
5341da177e4SLinus Torvalds 
535561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
5361da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
537b57c1a56SJohan Hedberg 
538b57c1a56SJohan Hedberg 		if (copied >= num)
539b57c1a56SJohan Hedberg 			break;
540b57c1a56SJohan Hedberg 
5411da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
5421da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
5431da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
5441da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
5451da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
5461da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
547b57c1a56SJohan Hedberg 
5481da177e4SLinus Torvalds 		info++;
549b57c1a56SJohan Hedberg 		copied++;
5501da177e4SLinus Torvalds 	}
5511da177e4SLinus Torvalds 
5521da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
5531da177e4SLinus Torvalds 	return copied;
5541da177e4SLinus Torvalds }
5551da177e4SLinus Torvalds 
5561da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
5571da177e4SLinus Torvalds {
5581da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
5591da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
5601da177e4SLinus Torvalds 
5611da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
5621da177e4SLinus Torvalds 
5631da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
5641da177e4SLinus Torvalds 		return;
5651da177e4SLinus Torvalds 
5661da177e4SLinus Torvalds 	/* Start Inquiry */
5671da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
5681da177e4SLinus Torvalds 	cp.length  = ir->length;
5691da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
570a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
5711da177e4SLinus Torvalds }
5721da177e4SLinus Torvalds 
5731da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
5741da177e4SLinus Torvalds {
5751da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
5761da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
5771da177e4SLinus Torvalds 	struct hci_dev *hdev;
5781da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
5791da177e4SLinus Torvalds 	long timeo;
5801da177e4SLinus Torvalds 	__u8 *buf;
5811da177e4SLinus Torvalds 
5821da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
5831da177e4SLinus Torvalds 		return -EFAULT;
5841da177e4SLinus Torvalds 
5855a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
5865a08ecceSAndrei Emeltchenko 	if (!hdev)
5871da177e4SLinus Torvalds 		return -ENODEV;
5881da177e4SLinus Torvalds 
58909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5901da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
591a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
5921da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
5931da177e4SLinus Torvalds 		do_inquiry = 1;
5941da177e4SLinus Torvalds 	}
59509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
5961da177e4SLinus Torvalds 
59704837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
59870f23020SAndrei Emeltchenko 
59970f23020SAndrei Emeltchenko 	if (do_inquiry) {
60070f23020SAndrei Emeltchenko 		err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
60170f23020SAndrei Emeltchenko 		if (err < 0)
6021da177e4SLinus Torvalds 			goto done;
60370f23020SAndrei Emeltchenko 	}
6041da177e4SLinus Torvalds 
6058fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
6068fc9ced3SGustavo Padovan 	 * 255 entries
6078fc9ced3SGustavo Padovan 	 */
6081da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
6091da177e4SLinus Torvalds 
6101da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
6111da177e4SLinus Torvalds 	 * copy it to the user space.
6121da177e4SLinus Torvalds 	 */
61370f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
61470f23020SAndrei Emeltchenko 	if (!buf) {
6151da177e4SLinus Torvalds 		err = -ENOMEM;
6161da177e4SLinus Torvalds 		goto done;
6171da177e4SLinus Torvalds 	}
6181da177e4SLinus Torvalds 
61909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6201da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
62109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6221da177e4SLinus Torvalds 
6231da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
6241da177e4SLinus Torvalds 
6251da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
6261da177e4SLinus Torvalds 		ptr += sizeof(ir);
6271da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
6281da177e4SLinus Torvalds 				 ir.num_rsp))
6291da177e4SLinus Torvalds 			err = -EFAULT;
6301da177e4SLinus Torvalds 	} else
6311da177e4SLinus Torvalds 		err = -EFAULT;
6321da177e4SLinus Torvalds 
6331da177e4SLinus Torvalds 	kfree(buf);
6341da177e4SLinus Torvalds 
6351da177e4SLinus Torvalds done:
6361da177e4SLinus Torvalds 	hci_dev_put(hdev);
6371da177e4SLinus Torvalds 	return err;
6381da177e4SLinus Torvalds }
6391da177e4SLinus Torvalds 
6401da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
6411da177e4SLinus Torvalds 
6421da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
6431da177e4SLinus Torvalds {
6441da177e4SLinus Torvalds 	struct hci_dev *hdev;
6451da177e4SLinus Torvalds 	int ret = 0;
6461da177e4SLinus Torvalds 
6475a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
6485a08ecceSAndrei Emeltchenko 	if (!hdev)
6491da177e4SLinus Torvalds 		return -ENODEV;
6501da177e4SLinus Torvalds 
6511da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
6521da177e4SLinus Torvalds 
6531da177e4SLinus Torvalds 	hci_req_lock(hdev);
6541da177e4SLinus Torvalds 
65594324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
65694324962SJohan Hovold 		ret = -ENODEV;
65794324962SJohan Hovold 		goto done;
65894324962SJohan Hovold 	}
65994324962SJohan Hovold 
660611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
661611b30f7SMarcel Holtmann 		ret = -ERFKILL;
662611b30f7SMarcel Holtmann 		goto done;
663611b30f7SMarcel Holtmann 	}
664611b30f7SMarcel Holtmann 
6651da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
6661da177e4SLinus Torvalds 		ret = -EALREADY;
6671da177e4SLinus Torvalds 		goto done;
6681da177e4SLinus Torvalds 	}
6691da177e4SLinus Torvalds 
6701da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
6711da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
6721da177e4SLinus Torvalds 
67307e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
67407e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
67507e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
676943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
677943da25dSMarcel Holtmann 
6781da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
6791da177e4SLinus Torvalds 		ret = -EIO;
6801da177e4SLinus Torvalds 		goto done;
6811da177e4SLinus Torvalds 	}
6821da177e4SLinus Torvalds 
6831da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
6841da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
6851da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
686a5040efaSJohan Hedberg 		hdev->init_last_cmd = 0;
6871da177e4SLinus Torvalds 
6885f246e89SAndrei Emeltchenko 		ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
6891da177e4SLinus Torvalds 
690eead27daSAndre Guedes 		if (lmp_host_le_capable(hdev))
6916ed58ec5SVille Tervo 			ret = __hci_request(hdev, hci_le_init_req, 0,
6925f246e89SAndrei Emeltchenko 					    HCI_INIT_TIMEOUT);
6936ed58ec5SVille Tervo 
6941da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
6951da177e4SLinus Torvalds 	}
6961da177e4SLinus Torvalds 
6971da177e4SLinus Torvalds 	if (!ret) {
6981da177e4SLinus Torvalds 		hci_dev_hold(hdev);
6991da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
7001da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
701bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
702bb4b2a9aSAndrei Emeltchenko 		    mgmt_valid_hdev(hdev)) {
70309fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
704744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
70509fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
70656e5cb86SJohan Hedberg 		}
7071da177e4SLinus Torvalds 	} else {
7081da177e4SLinus Torvalds 		/* Init failed, cleanup */
7093eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
710c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
711b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
7121da177e4SLinus Torvalds 
7131da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
7141da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
7151da177e4SLinus Torvalds 
7161da177e4SLinus Torvalds 		if (hdev->flush)
7171da177e4SLinus Torvalds 			hdev->flush(hdev);
7181da177e4SLinus Torvalds 
7191da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
7201da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
7211da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
7221da177e4SLinus Torvalds 		}
7231da177e4SLinus Torvalds 
7241da177e4SLinus Torvalds 		hdev->close(hdev);
7251da177e4SLinus Torvalds 		hdev->flags = 0;
7261da177e4SLinus Torvalds 	}
7271da177e4SLinus Torvalds 
7281da177e4SLinus Torvalds done:
7291da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7301da177e4SLinus Torvalds 	hci_dev_put(hdev);
7311da177e4SLinus Torvalds 	return ret;
7321da177e4SLinus Torvalds }
7331da177e4SLinus Torvalds 
7341da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
7351da177e4SLinus Torvalds {
7361da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
7371da177e4SLinus Torvalds 
73828b75a89SAndre Guedes 	cancel_work_sync(&hdev->le_scan);
73928b75a89SAndre Guedes 
7401da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
7411da177e4SLinus Torvalds 	hci_req_lock(hdev);
7421da177e4SLinus Torvalds 
7431da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
744b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7451da177e4SLinus Torvalds 		hci_req_unlock(hdev);
7461da177e4SLinus Torvalds 		return 0;
7471da177e4SLinus Torvalds 	}
7481da177e4SLinus Torvalds 
7493eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
7503eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
751b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
7521da177e4SLinus Torvalds 
75316ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
754e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
75516ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
7565e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
75716ab91abSJohan Hedberg 	}
75816ab91abSJohan Hedberg 
759a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
7607d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
7617d78525dSJohan Hedberg 
7627ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
7637ba8b4beSAndre Guedes 
76409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
7651da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
7661da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
76709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7681da177e4SLinus Torvalds 
7691da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
7701da177e4SLinus Torvalds 
7711da177e4SLinus Torvalds 	if (hdev->flush)
7721da177e4SLinus Torvalds 		hdev->flush(hdev);
7731da177e4SLinus Torvalds 
7741da177e4SLinus Torvalds 	/* Reset device */
7751da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7761da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
7778af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
778a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
7791da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
7805f246e89SAndrei Emeltchenko 		__hci_request(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
7811da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
7821da177e4SLinus Torvalds 	}
7831da177e4SLinus Torvalds 
784c347b765SGustavo F. Padovan 	/* flush cmd  work */
785c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
7861da177e4SLinus Torvalds 
7871da177e4SLinus Torvalds 	/* Drop queues */
7881da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
7891da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7901da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
7911da177e4SLinus Torvalds 
7921da177e4SLinus Torvalds 	/* Drop last sent command */
7931da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
794b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7951da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
7961da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
7971da177e4SLinus Torvalds 	}
7981da177e4SLinus Torvalds 
7991da177e4SLinus Torvalds 	/* After this point our queues are empty
8001da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
8011da177e4SLinus Torvalds 	hdev->close(hdev);
8021da177e4SLinus Torvalds 
803bb4b2a9aSAndrei Emeltchenko 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
804bb4b2a9aSAndrei Emeltchenko 	    mgmt_valid_hdev(hdev)) {
80509fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
806744cf19eSJohan Hedberg 		mgmt_powered(hdev, 0);
80709fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
8088ee56540SMarcel Holtmann 	}
8095add6af8SJohan Hedberg 
8101da177e4SLinus Torvalds 	/* Clear flags */
8111da177e4SLinus Torvalds 	hdev->flags = 0;
8121da177e4SLinus Torvalds 
813e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
81409b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
815e59fda8dSJohan Hedberg 
8161da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8171da177e4SLinus Torvalds 
8181da177e4SLinus Torvalds 	hci_dev_put(hdev);
8191da177e4SLinus Torvalds 	return 0;
8201da177e4SLinus Torvalds }
8211da177e4SLinus Torvalds 
8221da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
8231da177e4SLinus Torvalds {
8241da177e4SLinus Torvalds 	struct hci_dev *hdev;
8251da177e4SLinus Torvalds 	int err;
8261da177e4SLinus Torvalds 
82770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
82870f23020SAndrei Emeltchenko 	if (!hdev)
8291da177e4SLinus Torvalds 		return -ENODEV;
8308ee56540SMarcel Holtmann 
8318ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
8328ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
8338ee56540SMarcel Holtmann 
8341da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
8358ee56540SMarcel Holtmann 
8361da177e4SLinus Torvalds 	hci_dev_put(hdev);
8371da177e4SLinus Torvalds 	return err;
8381da177e4SLinus Torvalds }
8391da177e4SLinus Torvalds 
8401da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
8411da177e4SLinus Torvalds {
8421da177e4SLinus Torvalds 	struct hci_dev *hdev;
8431da177e4SLinus Torvalds 	int ret = 0;
8441da177e4SLinus Torvalds 
84570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
84670f23020SAndrei Emeltchenko 	if (!hdev)
8471da177e4SLinus Torvalds 		return -ENODEV;
8481da177e4SLinus Torvalds 
8491da177e4SLinus Torvalds 	hci_req_lock(hdev);
8501da177e4SLinus Torvalds 
8511da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
8521da177e4SLinus Torvalds 		goto done;
8531da177e4SLinus Torvalds 
8541da177e4SLinus Torvalds 	/* Drop queues */
8551da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
8561da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
8571da177e4SLinus Torvalds 
85809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
8591da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
8601da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
86109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
8621da177e4SLinus Torvalds 
8631da177e4SLinus Torvalds 	if (hdev->flush)
8641da177e4SLinus Torvalds 		hdev->flush(hdev);
8651da177e4SLinus Torvalds 
8661da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
8676ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
8681da177e4SLinus Torvalds 
8691da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
8705f246e89SAndrei Emeltchenko 		ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
8711da177e4SLinus Torvalds 
8721da177e4SLinus Torvalds done:
8731da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8741da177e4SLinus Torvalds 	hci_dev_put(hdev);
8751da177e4SLinus Torvalds 	return ret;
8761da177e4SLinus Torvalds }
8771da177e4SLinus Torvalds 
8781da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
8791da177e4SLinus Torvalds {
8801da177e4SLinus Torvalds 	struct hci_dev *hdev;
8811da177e4SLinus Torvalds 	int ret = 0;
8821da177e4SLinus Torvalds 
88370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
88470f23020SAndrei Emeltchenko 	if (!hdev)
8851da177e4SLinus Torvalds 		return -ENODEV;
8861da177e4SLinus Torvalds 
8871da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
8881da177e4SLinus Torvalds 
8891da177e4SLinus Torvalds 	hci_dev_put(hdev);
8901da177e4SLinus Torvalds 
8911da177e4SLinus Torvalds 	return ret;
8921da177e4SLinus Torvalds }
8931da177e4SLinus Torvalds 
8941da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
8951da177e4SLinus Torvalds {
8961da177e4SLinus Torvalds 	struct hci_dev *hdev;
8971da177e4SLinus Torvalds 	struct hci_dev_req dr;
8981da177e4SLinus Torvalds 	int err = 0;
8991da177e4SLinus Torvalds 
9001da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
9011da177e4SLinus Torvalds 		return -EFAULT;
9021da177e4SLinus Torvalds 
90370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
90470f23020SAndrei Emeltchenko 	if (!hdev)
9051da177e4SLinus Torvalds 		return -ENODEV;
9061da177e4SLinus Torvalds 
9071da177e4SLinus Torvalds 	switch (cmd) {
9081da177e4SLinus Torvalds 	case HCISETAUTH:
90904837f64SMarcel Holtmann 		err = hci_request(hdev, hci_auth_req, dr.dev_opt,
9105f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
9111da177e4SLinus Torvalds 		break;
9121da177e4SLinus Torvalds 
9131da177e4SLinus Torvalds 	case HCISETENCRYPT:
9141da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
9151da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
9161da177e4SLinus Torvalds 			break;
9171da177e4SLinus Torvalds 		}
9181da177e4SLinus Torvalds 
9191da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
9201da177e4SLinus Torvalds 			/* Auth must be enabled first */
92104837f64SMarcel Holtmann 			err = hci_request(hdev, hci_auth_req, dr.dev_opt,
9225f246e89SAndrei Emeltchenko 					  HCI_INIT_TIMEOUT);
9231da177e4SLinus Torvalds 			if (err)
9241da177e4SLinus Torvalds 				break;
9251da177e4SLinus Torvalds 		}
9261da177e4SLinus Torvalds 
92704837f64SMarcel Holtmann 		err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
9285f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
9291da177e4SLinus Torvalds 		break;
9301da177e4SLinus Torvalds 
9311da177e4SLinus Torvalds 	case HCISETSCAN:
93204837f64SMarcel Holtmann 		err = hci_request(hdev, hci_scan_req, dr.dev_opt,
9335f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
9341da177e4SLinus Torvalds 		break;
9351da177e4SLinus Torvalds 
9361da177e4SLinus Torvalds 	case HCISETLINKPOL:
937e4e8e37cSMarcel Holtmann 		err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
9385f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
9391da177e4SLinus Torvalds 		break;
9401da177e4SLinus Torvalds 
9411da177e4SLinus Torvalds 	case HCISETLINKMODE:
942e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
943e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
944e4e8e37cSMarcel Holtmann 		break;
945e4e8e37cSMarcel Holtmann 
946e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
947e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
9481da177e4SLinus Torvalds 		break;
9491da177e4SLinus Torvalds 
9501da177e4SLinus Torvalds 	case HCISETACLMTU:
9511da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
9521da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
9531da177e4SLinus Torvalds 		break;
9541da177e4SLinus Torvalds 
9551da177e4SLinus Torvalds 	case HCISETSCOMTU:
9561da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
9571da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
9581da177e4SLinus Torvalds 		break;
9591da177e4SLinus Torvalds 
9601da177e4SLinus Torvalds 	default:
9611da177e4SLinus Torvalds 		err = -EINVAL;
9621da177e4SLinus Torvalds 		break;
9631da177e4SLinus Torvalds 	}
964e4e8e37cSMarcel Holtmann 
9651da177e4SLinus Torvalds 	hci_dev_put(hdev);
9661da177e4SLinus Torvalds 	return err;
9671da177e4SLinus Torvalds }
9681da177e4SLinus Torvalds 
9691da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
9701da177e4SLinus Torvalds {
9718035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
9721da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
9731da177e4SLinus Torvalds 	struct hci_dev_req *dr;
9741da177e4SLinus Torvalds 	int n = 0, size, err;
9751da177e4SLinus Torvalds 	__u16 dev_num;
9761da177e4SLinus Torvalds 
9771da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
9781da177e4SLinus Torvalds 		return -EFAULT;
9791da177e4SLinus Torvalds 
9801da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
9811da177e4SLinus Torvalds 		return -EINVAL;
9821da177e4SLinus Torvalds 
9831da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
9841da177e4SLinus Torvalds 
98570f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
98670f23020SAndrei Emeltchenko 	if (!dl)
9871da177e4SLinus Torvalds 		return -ENOMEM;
9881da177e4SLinus Torvalds 
9891da177e4SLinus Torvalds 	dr = dl->dev_req;
9901da177e4SLinus Torvalds 
991f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
9928035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
993a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
994e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
995c542a06cSJohan Hedberg 
996a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
997a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
998c542a06cSJohan Hedberg 
9991da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
10001da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
1001c542a06cSJohan Hedberg 
10021da177e4SLinus Torvalds 		if (++n >= dev_num)
10031da177e4SLinus Torvalds 			break;
10041da177e4SLinus Torvalds 	}
1005f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
10061da177e4SLinus Torvalds 
10071da177e4SLinus Torvalds 	dl->dev_num = n;
10081da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
10091da177e4SLinus Torvalds 
10101da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
10111da177e4SLinus Torvalds 	kfree(dl);
10121da177e4SLinus Torvalds 
10131da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
10141da177e4SLinus Torvalds }
10151da177e4SLinus Torvalds 
10161da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
10171da177e4SLinus Torvalds {
10181da177e4SLinus Torvalds 	struct hci_dev *hdev;
10191da177e4SLinus Torvalds 	struct hci_dev_info di;
10201da177e4SLinus Torvalds 	int err = 0;
10211da177e4SLinus Torvalds 
10221da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
10231da177e4SLinus Torvalds 		return -EFAULT;
10241da177e4SLinus Torvalds 
102570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
102670f23020SAndrei Emeltchenko 	if (!hdev)
10271da177e4SLinus Torvalds 		return -ENODEV;
10281da177e4SLinus Torvalds 
1029a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
10303243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1031ab81cbf9SJohan Hedberg 
1032a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1033a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1034c542a06cSJohan Hedberg 
10351da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
10361da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
1037943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
10381da177e4SLinus Torvalds 	di.flags    = hdev->flags;
10391da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
10401da177e4SLinus Torvalds 	di.acl_mtu  = hdev->acl_mtu;
10411da177e4SLinus Torvalds 	di.acl_pkts = hdev->acl_pkts;
10421da177e4SLinus Torvalds 	di.sco_mtu  = hdev->sco_mtu;
10431da177e4SLinus Torvalds 	di.sco_pkts = hdev->sco_pkts;
10441da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
10451da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
10461da177e4SLinus Torvalds 
10471da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
10481da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
10491da177e4SLinus Torvalds 
10501da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
10511da177e4SLinus Torvalds 		err = -EFAULT;
10521da177e4SLinus Torvalds 
10531da177e4SLinus Torvalds 	hci_dev_put(hdev);
10541da177e4SLinus Torvalds 
10551da177e4SLinus Torvalds 	return err;
10561da177e4SLinus Torvalds }
10571da177e4SLinus Torvalds 
10581da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
10591da177e4SLinus Torvalds 
1060611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1061611b30f7SMarcel Holtmann {
1062611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1063611b30f7SMarcel Holtmann 
1064611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1065611b30f7SMarcel Holtmann 
1066611b30f7SMarcel Holtmann 	if (!blocked)
1067611b30f7SMarcel Holtmann 		return 0;
1068611b30f7SMarcel Holtmann 
1069611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1070611b30f7SMarcel Holtmann 
1071611b30f7SMarcel Holtmann 	return 0;
1072611b30f7SMarcel Holtmann }
1073611b30f7SMarcel Holtmann 
1074611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1075611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1076611b30f7SMarcel Holtmann };
1077611b30f7SMarcel Holtmann 
1078ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1079ab81cbf9SJohan Hedberg {
1080ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
1081ab81cbf9SJohan Hedberg 
1082ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1083ab81cbf9SJohan Hedberg 
1084ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
1085ab81cbf9SJohan Hedberg 		return;
1086ab81cbf9SJohan Hedberg 
1087a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
10889345d40cSAndrei Emeltchenko 		schedule_delayed_work(&hdev->power_off, HCI_AUTO_OFF_TIMEOUT);
1089ab81cbf9SJohan Hedberg 
1090a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1091744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1092ab81cbf9SJohan Hedberg }
1093ab81cbf9SJohan Hedberg 
1094ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1095ab81cbf9SJohan Hedberg {
10963243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
10973243553fSJohan Hedberg 					    power_off.work);
1098ab81cbf9SJohan Hedberg 
1099ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1100ab81cbf9SJohan Hedberg 
11018ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1102ab81cbf9SJohan Hedberg }
1103ab81cbf9SJohan Hedberg 
110416ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
110516ab91abSJohan Hedberg {
110616ab91abSJohan Hedberg 	struct hci_dev *hdev;
110716ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
110816ab91abSJohan Hedberg 
110916ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
111016ab91abSJohan Hedberg 
111116ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
111216ab91abSJohan Hedberg 
111309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
111416ab91abSJohan Hedberg 
111516ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
111616ab91abSJohan Hedberg 
111716ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
111816ab91abSJohan Hedberg 
111909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
112016ab91abSJohan Hedberg }
112116ab91abSJohan Hedberg 
11222aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
11232aeb9a1aSJohan Hedberg {
11242aeb9a1aSJohan Hedberg 	struct list_head *p, *n;
11252aeb9a1aSJohan Hedberg 
11262aeb9a1aSJohan Hedberg 	list_for_each_safe(p, n, &hdev->uuids) {
11272aeb9a1aSJohan Hedberg 		struct bt_uuid *uuid;
11282aeb9a1aSJohan Hedberg 
11292aeb9a1aSJohan Hedberg 		uuid = list_entry(p, struct bt_uuid, list);
11302aeb9a1aSJohan Hedberg 
11312aeb9a1aSJohan Hedberg 		list_del(p);
11322aeb9a1aSJohan Hedberg 		kfree(uuid);
11332aeb9a1aSJohan Hedberg 	}
11342aeb9a1aSJohan Hedberg 
11352aeb9a1aSJohan Hedberg 	return 0;
11362aeb9a1aSJohan Hedberg }
11372aeb9a1aSJohan Hedberg 
113855ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
113955ed8ca1SJohan Hedberg {
114055ed8ca1SJohan Hedberg 	struct list_head *p, *n;
114155ed8ca1SJohan Hedberg 
114255ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
114355ed8ca1SJohan Hedberg 		struct link_key *key;
114455ed8ca1SJohan Hedberg 
114555ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
114655ed8ca1SJohan Hedberg 
114755ed8ca1SJohan Hedberg 		list_del(p);
114855ed8ca1SJohan Hedberg 		kfree(key);
114955ed8ca1SJohan Hedberg 	}
115055ed8ca1SJohan Hedberg 
115155ed8ca1SJohan Hedberg 	return 0;
115255ed8ca1SJohan Hedberg }
115355ed8ca1SJohan Hedberg 
1154b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1155b899efafSVinicius Costa Gomes {
1156b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1157b899efafSVinicius Costa Gomes 
1158b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1159b899efafSVinicius Costa Gomes 		list_del(&k->list);
1160b899efafSVinicius Costa Gomes 		kfree(k);
1161b899efafSVinicius Costa Gomes 	}
1162b899efafSVinicius Costa Gomes 
1163b899efafSVinicius Costa Gomes 	return 0;
1164b899efafSVinicius Costa Gomes }
1165b899efafSVinicius Costa Gomes 
116655ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
116755ed8ca1SJohan Hedberg {
116855ed8ca1SJohan Hedberg 	struct link_key *k;
116955ed8ca1SJohan Hedberg 
11708035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
117155ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
117255ed8ca1SJohan Hedberg 			return k;
117355ed8ca1SJohan Hedberg 
117455ed8ca1SJohan Hedberg 	return NULL;
117555ed8ca1SJohan Hedberg }
117655ed8ca1SJohan Hedberg 
1177745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1178d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1179d25e28abSJohan Hedberg {
1180d25e28abSJohan Hedberg 	/* Legacy key */
1181d25e28abSJohan Hedberg 	if (key_type < 0x03)
1182745c0ce3SVishal Agarwal 		return true;
1183d25e28abSJohan Hedberg 
1184d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1185d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1186745c0ce3SVishal Agarwal 		return false;
1187d25e28abSJohan Hedberg 
1188d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1189d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1190745c0ce3SVishal Agarwal 		return false;
1191d25e28abSJohan Hedberg 
1192d25e28abSJohan Hedberg 	/* Security mode 3 case */
1193d25e28abSJohan Hedberg 	if (!conn)
1194745c0ce3SVishal Agarwal 		return true;
1195d25e28abSJohan Hedberg 
1196d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1197d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1198745c0ce3SVishal Agarwal 		return true;
1199d25e28abSJohan Hedberg 
1200d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1201d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1202745c0ce3SVishal Agarwal 		return true;
1203d25e28abSJohan Hedberg 
1204d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1205d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1206745c0ce3SVishal Agarwal 		return true;
1207d25e28abSJohan Hedberg 
1208d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1209d25e28abSJohan Hedberg 	 * persistently */
1210745c0ce3SVishal Agarwal 	return false;
1211d25e28abSJohan Hedberg }
1212d25e28abSJohan Hedberg 
1213c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
121475d262c2SVinicius Costa Gomes {
1215c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
121675d262c2SVinicius Costa Gomes 
1217c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1218c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1219c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
122075d262c2SVinicius Costa Gomes 			continue;
122175d262c2SVinicius Costa Gomes 
122275d262c2SVinicius Costa Gomes 		return k;
122375d262c2SVinicius Costa Gomes 	}
122475d262c2SVinicius Costa Gomes 
122575d262c2SVinicius Costa Gomes 	return NULL;
122675d262c2SVinicius Costa Gomes }
122775d262c2SVinicius Costa Gomes 
1228c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1229c9839a11SVinicius Costa Gomes 				     u8 addr_type)
123075d262c2SVinicius Costa Gomes {
1231c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
123275d262c2SVinicius Costa Gomes 
1233c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1234c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1235c9839a11SVinicius Costa Gomes 		    bacmp(bdaddr, &k->bdaddr) == 0)
123675d262c2SVinicius Costa Gomes 			return k;
123775d262c2SVinicius Costa Gomes 
123875d262c2SVinicius Costa Gomes 	return NULL;
123975d262c2SVinicius Costa Gomes }
124075d262c2SVinicius Costa Gomes 
1241d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1242d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
124355ed8ca1SJohan Hedberg {
124455ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1245745c0ce3SVishal Agarwal 	u8 old_key_type;
1246745c0ce3SVishal Agarwal 	bool persistent;
124755ed8ca1SJohan Hedberg 
124855ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
124955ed8ca1SJohan Hedberg 	if (old_key) {
125055ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
125155ed8ca1SJohan Hedberg 		key = old_key;
125255ed8ca1SJohan Hedberg 	} else {
125312adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
125455ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
125555ed8ca1SJohan Hedberg 		if (!key)
125655ed8ca1SJohan Hedberg 			return -ENOMEM;
125755ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
125855ed8ca1SJohan Hedberg 	}
125955ed8ca1SJohan Hedberg 
12606ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
126155ed8ca1SJohan Hedberg 
1262d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1263d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1264d25e28abSJohan Hedberg 	 * previous key */
1265d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1266a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1267d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1268655fe6ecSJohan Hedberg 		if (conn)
1269655fe6ecSJohan Hedberg 			conn->key_type = type;
1270655fe6ecSJohan Hedberg 	}
1271d25e28abSJohan Hedberg 
127255ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
12739b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
127455ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
127555ed8ca1SJohan Hedberg 
1276b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
127755ed8ca1SJohan Hedberg 		key->type = old_key_type;
12784748fed2SJohan Hedberg 	else
12794748fed2SJohan Hedberg 		key->type = type;
12804748fed2SJohan Hedberg 
12814df378a1SJohan Hedberg 	if (!new_key)
12824df378a1SJohan Hedberg 		return 0;
12834df378a1SJohan Hedberg 
12844df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
12854df378a1SJohan Hedberg 
1286744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
12874df378a1SJohan Hedberg 
12886ec5bcadSVishal Agarwal 	if (conn)
12896ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
129055ed8ca1SJohan Hedberg 
129155ed8ca1SJohan Hedberg 	return 0;
129255ed8ca1SJohan Hedberg }
129355ed8ca1SJohan Hedberg 
1294c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
12959a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
129604124681SGustavo F. Padovan 		ediv, u8 rand[8])
129775d262c2SVinicius Costa Gomes {
1298c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
129975d262c2SVinicius Costa Gomes 
1300c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1301c9839a11SVinicius Costa Gomes 		return 0;
130275d262c2SVinicius Costa Gomes 
1303c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1304c9839a11SVinicius Costa Gomes 	if (old_key)
130575d262c2SVinicius Costa Gomes 		key = old_key;
1306c9839a11SVinicius Costa Gomes 	else {
1307c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
130875d262c2SVinicius Costa Gomes 		if (!key)
130975d262c2SVinicius Costa Gomes 			return -ENOMEM;
1310c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
131175d262c2SVinicius Costa Gomes 	}
131275d262c2SVinicius Costa Gomes 
131375d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1314c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1315c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1316c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1317c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1318c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1319c9839a11SVinicius Costa Gomes 	key->type = type;
1320c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
132175d262c2SVinicius Costa Gomes 
1322c9839a11SVinicius Costa Gomes 	if (!new_key)
1323c9839a11SVinicius Costa Gomes 		return 0;
132475d262c2SVinicius Costa Gomes 
1325261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1326261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1327261cc5aaSVinicius Costa Gomes 
132875d262c2SVinicius Costa Gomes 	return 0;
132975d262c2SVinicius Costa Gomes }
133075d262c2SVinicius Costa Gomes 
133155ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
133255ed8ca1SJohan Hedberg {
133355ed8ca1SJohan Hedberg 	struct link_key *key;
133455ed8ca1SJohan Hedberg 
133555ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
133655ed8ca1SJohan Hedberg 	if (!key)
133755ed8ca1SJohan Hedberg 		return -ENOENT;
133855ed8ca1SJohan Hedberg 
13396ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
134055ed8ca1SJohan Hedberg 
134155ed8ca1SJohan Hedberg 	list_del(&key->list);
134255ed8ca1SJohan Hedberg 	kfree(key);
134355ed8ca1SJohan Hedberg 
134455ed8ca1SJohan Hedberg 	return 0;
134555ed8ca1SJohan Hedberg }
134655ed8ca1SJohan Hedberg 
1347b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1348b899efafSVinicius Costa Gomes {
1349b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1350b899efafSVinicius Costa Gomes 
1351b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1352b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1353b899efafSVinicius Costa Gomes 			continue;
1354b899efafSVinicius Costa Gomes 
13556ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1356b899efafSVinicius Costa Gomes 
1357b899efafSVinicius Costa Gomes 		list_del(&k->list);
1358b899efafSVinicius Costa Gomes 		kfree(k);
1359b899efafSVinicius Costa Gomes 	}
1360b899efafSVinicius Costa Gomes 
1361b899efafSVinicius Costa Gomes 	return 0;
1362b899efafSVinicius Costa Gomes }
1363b899efafSVinicius Costa Gomes 
13646bd32326SVille Tervo /* HCI command timer function */
1365bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
13666bd32326SVille Tervo {
13676bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
13686bd32326SVille Tervo 
1369bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
1370bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
1371bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
1372bda4f23aSAndrei Emeltchenko 
1373bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
1374bda4f23aSAndrei Emeltchenko 	} else {
13756bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
1376bda4f23aSAndrei Emeltchenko 	}
1377bda4f23aSAndrei Emeltchenko 
13786bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1379c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
13806bd32326SVille Tervo }
13816bd32326SVille Tervo 
13822763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
13832763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
13842763eda6SSzymon Janc {
13852763eda6SSzymon Janc 	struct oob_data *data;
13862763eda6SSzymon Janc 
13872763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
13882763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
13892763eda6SSzymon Janc 			return data;
13902763eda6SSzymon Janc 
13912763eda6SSzymon Janc 	return NULL;
13922763eda6SSzymon Janc }
13932763eda6SSzymon Janc 
13942763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
13952763eda6SSzymon Janc {
13962763eda6SSzymon Janc 	struct oob_data *data;
13972763eda6SSzymon Janc 
13982763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
13992763eda6SSzymon Janc 	if (!data)
14002763eda6SSzymon Janc 		return -ENOENT;
14012763eda6SSzymon Janc 
14026ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
14032763eda6SSzymon Janc 
14042763eda6SSzymon Janc 	list_del(&data->list);
14052763eda6SSzymon Janc 	kfree(data);
14062763eda6SSzymon Janc 
14072763eda6SSzymon Janc 	return 0;
14082763eda6SSzymon Janc }
14092763eda6SSzymon Janc 
14102763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
14112763eda6SSzymon Janc {
14122763eda6SSzymon Janc 	struct oob_data *data, *n;
14132763eda6SSzymon Janc 
14142763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
14152763eda6SSzymon Janc 		list_del(&data->list);
14162763eda6SSzymon Janc 		kfree(data);
14172763eda6SSzymon Janc 	}
14182763eda6SSzymon Janc 
14192763eda6SSzymon Janc 	return 0;
14202763eda6SSzymon Janc }
14212763eda6SSzymon Janc 
14222763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
14232763eda6SSzymon Janc 			    u8 *randomizer)
14242763eda6SSzymon Janc {
14252763eda6SSzymon Janc 	struct oob_data *data;
14262763eda6SSzymon Janc 
14272763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
14282763eda6SSzymon Janc 
14292763eda6SSzymon Janc 	if (!data) {
14302763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
14312763eda6SSzymon Janc 		if (!data)
14322763eda6SSzymon Janc 			return -ENOMEM;
14332763eda6SSzymon Janc 
14342763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
14352763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
14362763eda6SSzymon Janc 	}
14372763eda6SSzymon Janc 
14382763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
14392763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
14402763eda6SSzymon Janc 
14416ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
14422763eda6SSzymon Janc 
14432763eda6SSzymon Janc 	return 0;
14442763eda6SSzymon Janc }
14452763eda6SSzymon Janc 
144604124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
1447b2a66aadSAntti Julku {
1448b2a66aadSAntti Julku 	struct bdaddr_list *b;
1449b2a66aadSAntti Julku 
14508035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1451b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1452b2a66aadSAntti Julku 			return b;
1453b2a66aadSAntti Julku 
1454b2a66aadSAntti Julku 	return NULL;
1455b2a66aadSAntti Julku }
1456b2a66aadSAntti Julku 
1457b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1458b2a66aadSAntti Julku {
1459b2a66aadSAntti Julku 	struct list_head *p, *n;
1460b2a66aadSAntti Julku 
1461b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1462b2a66aadSAntti Julku 		struct bdaddr_list *b;
1463b2a66aadSAntti Julku 
1464b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1465b2a66aadSAntti Julku 
1466b2a66aadSAntti Julku 		list_del(p);
1467b2a66aadSAntti Julku 		kfree(b);
1468b2a66aadSAntti Julku 	}
1469b2a66aadSAntti Julku 
1470b2a66aadSAntti Julku 	return 0;
1471b2a66aadSAntti Julku }
1472b2a66aadSAntti Julku 
147388c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1474b2a66aadSAntti Julku {
1475b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1476b2a66aadSAntti Julku 
1477b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1478b2a66aadSAntti Julku 		return -EBADF;
1479b2a66aadSAntti Julku 
14805e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
14815e762444SAntti Julku 		return -EEXIST;
1482b2a66aadSAntti Julku 
1483b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
14845e762444SAntti Julku 	if (!entry)
14855e762444SAntti Julku 		return -ENOMEM;
1486b2a66aadSAntti Julku 
1487b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1488b2a66aadSAntti Julku 
1489b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1490b2a66aadSAntti Julku 
149188c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
1492b2a66aadSAntti Julku }
1493b2a66aadSAntti Julku 
149488c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1495b2a66aadSAntti Julku {
1496b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1497b2a66aadSAntti Julku 
14981ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
14995e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1500b2a66aadSAntti Julku 
1501b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
15021ec918ceSSzymon Janc 	if (!entry)
15035e762444SAntti Julku 		return -ENOENT;
1504b2a66aadSAntti Julku 
1505b2a66aadSAntti Julku 	list_del(&entry->list);
1506b2a66aadSAntti Julku 	kfree(entry);
1507b2a66aadSAntti Julku 
150888c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
1509b2a66aadSAntti Julku }
1510b2a66aadSAntti Julku 
15117ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt)
15127ba8b4beSAndre Guedes {
15137ba8b4beSAndre Guedes 	struct le_scan_params *param =  (struct le_scan_params *) opt;
15147ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_param cp;
15157ba8b4beSAndre Guedes 
15167ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
15177ba8b4beSAndre Guedes 	cp.type = param->type;
15187ba8b4beSAndre Guedes 	cp.interval = cpu_to_le16(param->interval);
15197ba8b4beSAndre Guedes 	cp.window = cpu_to_le16(param->window);
15207ba8b4beSAndre Guedes 
15217ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
15227ba8b4beSAndre Guedes }
15237ba8b4beSAndre Guedes 
15247ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt)
15257ba8b4beSAndre Guedes {
15267ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
15277ba8b4beSAndre Guedes 
15287ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
15297ba8b4beSAndre Guedes 	cp.enable = 1;
15300431a43cSAndre Guedes 	cp.filter_dup = 1;
15317ba8b4beSAndre Guedes 
15327ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
15337ba8b4beSAndre Guedes }
15347ba8b4beSAndre Guedes 
15357ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
15367ba8b4beSAndre Guedes 			  u16 window, int timeout)
15377ba8b4beSAndre Guedes {
15387ba8b4beSAndre Guedes 	long timeo = msecs_to_jiffies(3000);
15397ba8b4beSAndre Guedes 	struct le_scan_params param;
15407ba8b4beSAndre Guedes 	int err;
15417ba8b4beSAndre Guedes 
15427ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
15437ba8b4beSAndre Guedes 
15447ba8b4beSAndre Guedes 	if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
15457ba8b4beSAndre Guedes 		return -EINPROGRESS;
15467ba8b4beSAndre Guedes 
15477ba8b4beSAndre Guedes 	param.type = type;
15487ba8b4beSAndre Guedes 	param.interval = interval;
15497ba8b4beSAndre Guedes 	param.window = window;
15507ba8b4beSAndre Guedes 
15517ba8b4beSAndre Guedes 	hci_req_lock(hdev);
15527ba8b4beSAndre Guedes 
15537ba8b4beSAndre Guedes 	err = __hci_request(hdev, le_scan_param_req, (unsigned long) &param,
15547ba8b4beSAndre Guedes 			    timeo);
15557ba8b4beSAndre Guedes 	if (!err)
15567ba8b4beSAndre Guedes 		err = __hci_request(hdev, le_scan_enable_req, 0, timeo);
15577ba8b4beSAndre Guedes 
15587ba8b4beSAndre Guedes 	hci_req_unlock(hdev);
15597ba8b4beSAndre Guedes 
15607ba8b4beSAndre Guedes 	if (err < 0)
15617ba8b4beSAndre Guedes 		return err;
15627ba8b4beSAndre Guedes 
15637ba8b4beSAndre Guedes 	schedule_delayed_work(&hdev->le_scan_disable,
15647ba8b4beSAndre Guedes 			      msecs_to_jiffies(timeout));
15657ba8b4beSAndre Guedes 
15667ba8b4beSAndre Guedes 	return 0;
15677ba8b4beSAndre Guedes }
15687ba8b4beSAndre Guedes 
15697dbfac1dSAndre Guedes int hci_cancel_le_scan(struct hci_dev *hdev)
15707dbfac1dSAndre Guedes {
15717dbfac1dSAndre Guedes 	BT_DBG("%s", hdev->name);
15727dbfac1dSAndre Guedes 
15737dbfac1dSAndre Guedes 	if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
15747dbfac1dSAndre Guedes 		return -EALREADY;
15757dbfac1dSAndre Guedes 
15767dbfac1dSAndre Guedes 	if (cancel_delayed_work(&hdev->le_scan_disable)) {
15777dbfac1dSAndre Guedes 		struct hci_cp_le_set_scan_enable cp;
15787dbfac1dSAndre Guedes 
15797dbfac1dSAndre Guedes 		/* Send HCI command to disable LE Scan */
15807dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
15817dbfac1dSAndre Guedes 		hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
15827dbfac1dSAndre Guedes 	}
15837dbfac1dSAndre Guedes 
15847dbfac1dSAndre Guedes 	return 0;
15857dbfac1dSAndre Guedes }
15867dbfac1dSAndre Guedes 
15877ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
15887ba8b4beSAndre Guedes {
15897ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
15907ba8b4beSAndre Guedes 					    le_scan_disable.work);
15917ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
15927ba8b4beSAndre Guedes 
15937ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
15947ba8b4beSAndre Guedes 
15957ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
15967ba8b4beSAndre Guedes 
15977ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
15987ba8b4beSAndre Guedes }
15997ba8b4beSAndre Guedes 
160028b75a89SAndre Guedes static void le_scan_work(struct work_struct *work)
160128b75a89SAndre Guedes {
160228b75a89SAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
160328b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
160428b75a89SAndre Guedes 
160528b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
160628b75a89SAndre Guedes 
160704124681SGustavo F. Padovan 	hci_do_le_scan(hdev, param->type, param->interval, param->window,
160804124681SGustavo F. Padovan 		       param->timeout);
160928b75a89SAndre Guedes }
161028b75a89SAndre Guedes 
161128b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
161228b75a89SAndre Guedes 		int timeout)
161328b75a89SAndre Guedes {
161428b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
161528b75a89SAndre Guedes 
161628b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
161728b75a89SAndre Guedes 
161828b75a89SAndre Guedes 	if (work_busy(&hdev->le_scan))
161928b75a89SAndre Guedes 		return -EINPROGRESS;
162028b75a89SAndre Guedes 
162128b75a89SAndre Guedes 	param->type = type;
162228b75a89SAndre Guedes 	param->interval = interval;
162328b75a89SAndre Guedes 	param->window = window;
162428b75a89SAndre Guedes 	param->timeout = timeout;
162528b75a89SAndre Guedes 
162628b75a89SAndre Guedes 	queue_work(system_long_wq, &hdev->le_scan);
162728b75a89SAndre Guedes 
162828b75a89SAndre Guedes 	return 0;
162928b75a89SAndre Guedes }
163028b75a89SAndre Guedes 
16319be0dab7SDavid Herrmann /* Alloc HCI device */
16329be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
16339be0dab7SDavid Herrmann {
16349be0dab7SDavid Herrmann 	struct hci_dev *hdev;
16359be0dab7SDavid Herrmann 
16369be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
16379be0dab7SDavid Herrmann 	if (!hdev)
16389be0dab7SDavid Herrmann 		return NULL;
16399be0dab7SDavid Herrmann 
1640b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
1641b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
1642b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
1643b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03; /* No Input No Output */
1644b1b813d4SDavid Herrmann 
1645b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
1646b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
1647b1b813d4SDavid Herrmann 
1648b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
1649b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
1650b1b813d4SDavid Herrmann 
1651b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
1652b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
1653b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
1654b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
1655b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
1656b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
16576b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
1658b1b813d4SDavid Herrmann 
1659b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1660b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
1661b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
1662b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
1663b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->le_scan, le_scan_work);
1664b1b813d4SDavid Herrmann 
1665b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
1666b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
1667b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
1668b1b813d4SDavid Herrmann 
16699be0dab7SDavid Herrmann 	skb_queue_head_init(&hdev->driver_init);
1670b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
1671b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
1672b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
1673b1b813d4SDavid Herrmann 
1674b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
1675b1b813d4SDavid Herrmann 
1676bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
1677b1b813d4SDavid Herrmann 
1678b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
1679b1b813d4SDavid Herrmann 	discovery_init(hdev);
16809be0dab7SDavid Herrmann 
16819be0dab7SDavid Herrmann 	return hdev;
16829be0dab7SDavid Herrmann }
16839be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
16849be0dab7SDavid Herrmann 
16859be0dab7SDavid Herrmann /* Free HCI device */
16869be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
16879be0dab7SDavid Herrmann {
16889be0dab7SDavid Herrmann 	skb_queue_purge(&hdev->driver_init);
16899be0dab7SDavid Herrmann 
16909be0dab7SDavid Herrmann 	/* will free via device release */
16919be0dab7SDavid Herrmann 	put_device(&hdev->dev);
16929be0dab7SDavid Herrmann }
16939be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
16949be0dab7SDavid Herrmann 
16951da177e4SLinus Torvalds /* Register HCI device */
16961da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
16971da177e4SLinus Torvalds {
1698b1b813d4SDavid Herrmann 	int id, error;
16991da177e4SLinus Torvalds 
1700010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
17011da177e4SLinus Torvalds 		return -EINVAL;
17021da177e4SLinus Torvalds 
170308add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
170408add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
170508add513SMat Martineau 	 */
17063df92b31SSasha Levin 	switch (hdev->dev_type) {
17073df92b31SSasha Levin 	case HCI_BREDR:
17083df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
17091da177e4SLinus Torvalds 		break;
17103df92b31SSasha Levin 	case HCI_AMP:
17113df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
17123df92b31SSasha Levin 		break;
17133df92b31SSasha Levin 	default:
17143df92b31SSasha Levin 		return -EINVAL;
17151da177e4SLinus Torvalds 	}
17161da177e4SLinus Torvalds 
17173df92b31SSasha Levin 	if (id < 0)
17183df92b31SSasha Levin 		return id;
17193df92b31SSasha Levin 
17201da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
17211da177e4SLinus Torvalds 	hdev->id = id;
17222d8b3a11SAndrei Emeltchenko 
17232d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
17242d8b3a11SAndrei Emeltchenko 
17253df92b31SSasha Levin 	write_lock(&hci_dev_list_lock);
17263df92b31SSasha Levin 	list_add(&hdev->list, &hci_dev_list);
1727f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
17281da177e4SLinus Torvalds 
172932845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
173032845eb1SGustavo F. Padovan 					  WQ_MEM_RECLAIM, 1);
173133ca954dSDavid Herrmann 	if (!hdev->workqueue) {
173233ca954dSDavid Herrmann 		error = -ENOMEM;
173333ca954dSDavid Herrmann 		goto err;
173433ca954dSDavid Herrmann 	}
1735f48fd9c8SMarcel Holtmann 
173633ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
173733ca954dSDavid Herrmann 	if (error < 0)
173833ca954dSDavid Herrmann 		goto err_wqueue;
17391da177e4SLinus Torvalds 
1740611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1741a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
1742a8c5fb1aSGustavo Padovan 				    hdev);
1743611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1744611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
1745611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
1746611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
1747611b30f7SMarcel Holtmann 		}
1748611b30f7SMarcel Holtmann 	}
1749611b30f7SMarcel Holtmann 
1750a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
1751ce2be9acSAndrei Emeltchenko 
1752ce2be9acSAndrei Emeltchenko 	if (hdev->dev_type != HCI_AMP)
1753ce2be9acSAndrei Emeltchenko 		set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
1754ce2be9acSAndrei Emeltchenko 
17557f971041SGustavo F. Padovan 	schedule_work(&hdev->power_on);
1756ab81cbf9SJohan Hedberg 
17571da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
1758dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
17591da177e4SLinus Torvalds 
17601da177e4SLinus Torvalds 	return id;
1761f48fd9c8SMarcel Holtmann 
176233ca954dSDavid Herrmann err_wqueue:
176333ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
176433ca954dSDavid Herrmann err:
17653df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
1766f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
1767f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
1768f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
1769f48fd9c8SMarcel Holtmann 
177033ca954dSDavid Herrmann 	return error;
17711da177e4SLinus Torvalds }
17721da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
17731da177e4SLinus Torvalds 
17741da177e4SLinus Torvalds /* Unregister HCI device */
177559735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
17761da177e4SLinus Torvalds {
17773df92b31SSasha Levin 	int i, id;
1778ef222013SMarcel Holtmann 
1779c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
17801da177e4SLinus Torvalds 
178194324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
178294324962SJohan Hovold 
17833df92b31SSasha Levin 	id = hdev->id;
17843df92b31SSasha Levin 
1785f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
17861da177e4SLinus Torvalds 	list_del(&hdev->list);
1787f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
17881da177e4SLinus Torvalds 
17891da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
17901da177e4SLinus Torvalds 
1791cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1792ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
1793ef222013SMarcel Holtmann 
1794ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
1795a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
179609fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1797744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
179809fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
179956e5cb86SJohan Hedberg 	}
1800ab81cbf9SJohan Hedberg 
18012e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
18022e58ef3eSJohan Hedberg 	 * pending list */
18032e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
18042e58ef3eSJohan Hedberg 
18051da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
18061da177e4SLinus Torvalds 
1807611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1808611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
1809611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
1810611b30f7SMarcel Holtmann 	}
1811611b30f7SMarcel Holtmann 
1812ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
1813147e2d59SDave Young 
1814f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
1815f48fd9c8SMarcel Holtmann 
181609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
1817e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
18182aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
181955ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
1820b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
18212763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
182209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
1823e2e0cacbSJohan Hedberg 
1824dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
18253df92b31SSasha Levin 
18263df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
18271da177e4SLinus Torvalds }
18281da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
18291da177e4SLinus Torvalds 
18301da177e4SLinus Torvalds /* Suspend HCI device */
18311da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
18321da177e4SLinus Torvalds {
18331da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
18341da177e4SLinus Torvalds 	return 0;
18351da177e4SLinus Torvalds }
18361da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
18371da177e4SLinus Torvalds 
18381da177e4SLinus Torvalds /* Resume HCI device */
18391da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
18401da177e4SLinus Torvalds {
18411da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
18421da177e4SLinus Torvalds 	return 0;
18431da177e4SLinus Torvalds }
18441da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
18451da177e4SLinus Torvalds 
184676bca880SMarcel Holtmann /* Receive frame from HCI drivers */
184776bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
184876bca880SMarcel Holtmann {
184976bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
185076bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
185176bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
185276bca880SMarcel Holtmann 		kfree_skb(skb);
185376bca880SMarcel Holtmann 		return -ENXIO;
185476bca880SMarcel Holtmann 	}
185576bca880SMarcel Holtmann 
185676bca880SMarcel Holtmann 	/* Incomming skb */
185776bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
185876bca880SMarcel Holtmann 
185976bca880SMarcel Holtmann 	/* Time stamp */
186076bca880SMarcel Holtmann 	__net_timestamp(skb);
186176bca880SMarcel Holtmann 
186276bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
1863b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
1864c78ae283SMarcel Holtmann 
186576bca880SMarcel Holtmann 	return 0;
186676bca880SMarcel Holtmann }
186776bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
186876bca880SMarcel Holtmann 
186933e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
18701e429f38SGustavo F. Padovan 			  int count, __u8 index)
187133e882a5SSuraj Sumangala {
187233e882a5SSuraj Sumangala 	int len = 0;
187333e882a5SSuraj Sumangala 	int hlen = 0;
187433e882a5SSuraj Sumangala 	int remain = count;
187533e882a5SSuraj Sumangala 	struct sk_buff *skb;
187633e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
187733e882a5SSuraj Sumangala 
187833e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
187933e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
188033e882a5SSuraj Sumangala 		return -EILSEQ;
188133e882a5SSuraj Sumangala 
188233e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
188333e882a5SSuraj Sumangala 
188433e882a5SSuraj Sumangala 	if (!skb) {
188533e882a5SSuraj Sumangala 		switch (type) {
188633e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
188733e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
188833e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
188933e882a5SSuraj Sumangala 			break;
189033e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
189133e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
189233e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
189333e882a5SSuraj Sumangala 			break;
189433e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
189533e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
189633e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
189733e882a5SSuraj Sumangala 			break;
189833e882a5SSuraj Sumangala 		}
189933e882a5SSuraj Sumangala 
19001e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
190133e882a5SSuraj Sumangala 		if (!skb)
190233e882a5SSuraj Sumangala 			return -ENOMEM;
190333e882a5SSuraj Sumangala 
190433e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
190533e882a5SSuraj Sumangala 		scb->expect = hlen;
190633e882a5SSuraj Sumangala 		scb->pkt_type = type;
190733e882a5SSuraj Sumangala 
190833e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
190933e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
191033e882a5SSuraj Sumangala 	}
191133e882a5SSuraj Sumangala 
191233e882a5SSuraj Sumangala 	while (count) {
191333e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
191489bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
191533e882a5SSuraj Sumangala 
191633e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
191733e882a5SSuraj Sumangala 
191833e882a5SSuraj Sumangala 		count -= len;
191933e882a5SSuraj Sumangala 		data += len;
192033e882a5SSuraj Sumangala 		scb->expect -= len;
192133e882a5SSuraj Sumangala 		remain = count;
192233e882a5SSuraj Sumangala 
192333e882a5SSuraj Sumangala 		switch (type) {
192433e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
192533e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
192633e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
192733e882a5SSuraj Sumangala 				scb->expect = h->plen;
192833e882a5SSuraj Sumangala 
192933e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
193033e882a5SSuraj Sumangala 					kfree_skb(skb);
193133e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
193233e882a5SSuraj Sumangala 					return -ENOMEM;
193333e882a5SSuraj Sumangala 				}
193433e882a5SSuraj Sumangala 			}
193533e882a5SSuraj Sumangala 			break;
193633e882a5SSuraj Sumangala 
193733e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
193833e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
193933e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
194033e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
194133e882a5SSuraj Sumangala 
194233e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
194333e882a5SSuraj Sumangala 					kfree_skb(skb);
194433e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
194533e882a5SSuraj Sumangala 					return -ENOMEM;
194633e882a5SSuraj Sumangala 				}
194733e882a5SSuraj Sumangala 			}
194833e882a5SSuraj Sumangala 			break;
194933e882a5SSuraj Sumangala 
195033e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
195133e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
195233e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
195333e882a5SSuraj Sumangala 				scb->expect = h->dlen;
195433e882a5SSuraj Sumangala 
195533e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
195633e882a5SSuraj Sumangala 					kfree_skb(skb);
195733e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
195833e882a5SSuraj Sumangala 					return -ENOMEM;
195933e882a5SSuraj Sumangala 				}
196033e882a5SSuraj Sumangala 			}
196133e882a5SSuraj Sumangala 			break;
196233e882a5SSuraj Sumangala 		}
196333e882a5SSuraj Sumangala 
196433e882a5SSuraj Sumangala 		if (scb->expect == 0) {
196533e882a5SSuraj Sumangala 			/* Complete frame */
196633e882a5SSuraj Sumangala 
196733e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
196833e882a5SSuraj Sumangala 			hci_recv_frame(skb);
196933e882a5SSuraj Sumangala 
197033e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
197133e882a5SSuraj Sumangala 			return remain;
197233e882a5SSuraj Sumangala 		}
197333e882a5SSuraj Sumangala 	}
197433e882a5SSuraj Sumangala 
197533e882a5SSuraj Sumangala 	return remain;
197633e882a5SSuraj Sumangala }
197733e882a5SSuraj Sumangala 
1978ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
1979ef222013SMarcel Holtmann {
1980f39a3c06SSuraj Sumangala 	int rem = 0;
1981f39a3c06SSuraj Sumangala 
1982ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
1983ef222013SMarcel Holtmann 		return -EILSEQ;
1984ef222013SMarcel Holtmann 
1985da5f6c37SGustavo F. Padovan 	while (count) {
19861e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
1987f39a3c06SSuraj Sumangala 		if (rem < 0)
1988f39a3c06SSuraj Sumangala 			return rem;
1989ef222013SMarcel Holtmann 
1990f39a3c06SSuraj Sumangala 		data += (count - rem);
1991f39a3c06SSuraj Sumangala 		count = rem;
1992f81c6224SJoe Perches 	}
1993ef222013SMarcel Holtmann 
1994f39a3c06SSuraj Sumangala 	return rem;
1995ef222013SMarcel Holtmann }
1996ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
1997ef222013SMarcel Holtmann 
199899811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
199999811510SSuraj Sumangala 
200099811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
200199811510SSuraj Sumangala {
200299811510SSuraj Sumangala 	int type;
200399811510SSuraj Sumangala 	int rem = 0;
200499811510SSuraj Sumangala 
2005da5f6c37SGustavo F. Padovan 	while (count) {
200699811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
200799811510SSuraj Sumangala 
200899811510SSuraj Sumangala 		if (!skb) {
200999811510SSuraj Sumangala 			struct { char type; } *pkt;
201099811510SSuraj Sumangala 
201199811510SSuraj Sumangala 			/* Start of the frame */
201299811510SSuraj Sumangala 			pkt = data;
201399811510SSuraj Sumangala 			type = pkt->type;
201499811510SSuraj Sumangala 
201599811510SSuraj Sumangala 			data++;
201699811510SSuraj Sumangala 			count--;
201799811510SSuraj Sumangala 		} else
201899811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
201999811510SSuraj Sumangala 
20201e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
20211e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
202299811510SSuraj Sumangala 		if (rem < 0)
202399811510SSuraj Sumangala 			return rem;
202499811510SSuraj Sumangala 
202599811510SSuraj Sumangala 		data += (count - rem);
202699811510SSuraj Sumangala 		count = rem;
2027f81c6224SJoe Perches 	}
202899811510SSuraj Sumangala 
202999811510SSuraj Sumangala 	return rem;
203099811510SSuraj Sumangala }
203199811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
203299811510SSuraj Sumangala 
20331da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
20341da177e4SLinus Torvalds 
20351da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
20361da177e4SLinus Torvalds {
20371da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
20381da177e4SLinus Torvalds 
2039f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
20401da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2041f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
20421da177e4SLinus Torvalds 
20431da177e4SLinus Torvalds 	return 0;
20441da177e4SLinus Torvalds }
20451da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
20461da177e4SLinus Torvalds 
20471da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
20481da177e4SLinus Torvalds {
20491da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
20501da177e4SLinus Torvalds 
2051f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
20521da177e4SLinus Torvalds 	list_del(&cb->list);
2053f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
20541da177e4SLinus Torvalds 
20551da177e4SLinus Torvalds 	return 0;
20561da177e4SLinus Torvalds }
20571da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
20581da177e4SLinus Torvalds 
20591da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
20601da177e4SLinus Torvalds {
20611da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
20621da177e4SLinus Torvalds 
20631da177e4SLinus Torvalds 	if (!hdev) {
20641da177e4SLinus Torvalds 		kfree_skb(skb);
20651da177e4SLinus Torvalds 		return -ENODEV;
20661da177e4SLinus Torvalds 	}
20671da177e4SLinus Torvalds 
20680d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
20691da177e4SLinus Torvalds 
20701da177e4SLinus Torvalds 	/* Time stamp */
2071a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
20721da177e4SLinus Torvalds 
2073cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2074cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2075cd82e61cSMarcel Holtmann 
2076cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2077cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2078470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
20791da177e4SLinus Torvalds 	}
20801da177e4SLinus Torvalds 
20811da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
20821da177e4SLinus Torvalds 	skb_orphan(skb);
20831da177e4SLinus Torvalds 
20841da177e4SLinus Torvalds 	return hdev->send(skb);
20851da177e4SLinus Torvalds }
20861da177e4SLinus Torvalds 
20871da177e4SLinus Torvalds /* Send HCI command */
2088a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
20891da177e4SLinus Torvalds {
20901da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
20911da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
20921da177e4SLinus Torvalds 	struct sk_buff *skb;
20931da177e4SLinus Torvalds 
2094f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
20951da177e4SLinus Torvalds 
20961da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
20971da177e4SLinus Torvalds 	if (!skb) {
2098ef222013SMarcel Holtmann 		BT_ERR("%s no memory for command", hdev->name);
20991da177e4SLinus Torvalds 		return -ENOMEM;
21001da177e4SLinus Torvalds 	}
21011da177e4SLinus Torvalds 
21021da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2103a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
21041da177e4SLinus Torvalds 	hdr->plen   = plen;
21051da177e4SLinus Torvalds 
21061da177e4SLinus Torvalds 	if (plen)
21071da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
21081da177e4SLinus Torvalds 
21091da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
21101da177e4SLinus Torvalds 
21110d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
21121da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2113c78ae283SMarcel Holtmann 
2114a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
2115a5040efaSJohan Hedberg 		hdev->init_last_cmd = opcode;
2116a5040efaSJohan Hedberg 
21171da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2118c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
21191da177e4SLinus Torvalds 
21201da177e4SLinus Torvalds 	return 0;
21211da177e4SLinus Torvalds }
21221da177e4SLinus Torvalds 
21231da177e4SLinus Torvalds /* Get data from the previously sent command */
2124a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
21251da177e4SLinus Torvalds {
21261da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
21271da177e4SLinus Torvalds 
21281da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
21291da177e4SLinus Torvalds 		return NULL;
21301da177e4SLinus Torvalds 
21311da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
21321da177e4SLinus Torvalds 
2133a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
21341da177e4SLinus Torvalds 		return NULL;
21351da177e4SLinus Torvalds 
2136f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
21371da177e4SLinus Torvalds 
21381da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
21391da177e4SLinus Torvalds }
21401da177e4SLinus Torvalds 
21411da177e4SLinus Torvalds /* Send ACL data */
21421da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
21431da177e4SLinus Torvalds {
21441da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
21451da177e4SLinus Torvalds 	int len = skb->len;
21461da177e4SLinus Torvalds 
2147badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2148badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
21499c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2150aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2151aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
21521da177e4SLinus Torvalds }
21531da177e4SLinus Torvalds 
2154ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
215573d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
21561da177e4SLinus Torvalds {
2157ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
21581da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
21591da177e4SLinus Torvalds 	struct sk_buff *list;
21601da177e4SLinus Torvalds 
2161087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
2162087bfd99SGustavo Padovan 	skb->data_len = 0;
2163087bfd99SGustavo Padovan 
2164087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2165204a6e54SAndrei Emeltchenko 
2166204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
2167204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
2168087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
2169204a6e54SAndrei Emeltchenko 		break;
2170204a6e54SAndrei Emeltchenko 	case HCI_AMP:
2171204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
2172204a6e54SAndrei Emeltchenko 		break;
2173204a6e54SAndrei Emeltchenko 	default:
2174204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2175204a6e54SAndrei Emeltchenko 		return;
2176204a6e54SAndrei Emeltchenko 	}
2177087bfd99SGustavo Padovan 
217870f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
217970f23020SAndrei Emeltchenko 	if (!list) {
21801da177e4SLinus Torvalds 		/* Non fragmented */
21811da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
21821da177e4SLinus Torvalds 
218373d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
21841da177e4SLinus Torvalds 	} else {
21851da177e4SLinus Torvalds 		/* Fragmented */
21861da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
21871da177e4SLinus Torvalds 
21881da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
21891da177e4SLinus Torvalds 
21901da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2191af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
21921da177e4SLinus Torvalds 
219373d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2194e702112fSAndrei Emeltchenko 
2195e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2196e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
21971da177e4SLinus Torvalds 		do {
21981da177e4SLinus Torvalds 			skb = list; list = list->next;
21991da177e4SLinus Torvalds 
22001da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
22010d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2202e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
22031da177e4SLinus Torvalds 
22041da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
22051da177e4SLinus Torvalds 
220673d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
22071da177e4SLinus Torvalds 		} while (list);
22081da177e4SLinus Torvalds 
2209af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
22101da177e4SLinus Torvalds 	}
221173d80debSLuiz Augusto von Dentz }
221273d80debSLuiz Augusto von Dentz 
221373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
221473d80debSLuiz Augusto von Dentz {
2215ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
221673d80debSLuiz Augusto von Dentz 
2217f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
221873d80debSLuiz Augusto von Dentz 
221973d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
222073d80debSLuiz Augusto von Dentz 
2221ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
22221da177e4SLinus Torvalds 
22233eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
22241da177e4SLinus Torvalds }
22251da177e4SLinus Torvalds 
22261da177e4SLinus Torvalds /* Send SCO data */
22270d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
22281da177e4SLinus Torvalds {
22291da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
22301da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
22311da177e4SLinus Torvalds 
22321da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
22331da177e4SLinus Torvalds 
2234aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
22351da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
22361da177e4SLinus Torvalds 
2237badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2238badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
22399c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
22401da177e4SLinus Torvalds 
22411da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
22420d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2243c78ae283SMarcel Holtmann 
22441da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
22453eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
22461da177e4SLinus Torvalds }
22471da177e4SLinus Torvalds 
22481da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
22491da177e4SLinus Torvalds 
22501da177e4SLinus Torvalds /* HCI Connection scheduler */
22516039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
2252a8c5fb1aSGustavo Padovan 				     int *quote)
22531da177e4SLinus Torvalds {
22541da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
22558035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
2256abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
22571da177e4SLinus Torvalds 
22581da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
22591da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2260bf4c6325SGustavo F. Padovan 
2261bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2262bf4c6325SGustavo F. Padovan 
2263bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2264769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
22651da177e4SLinus Torvalds 			continue;
2266769be974SMarcel Holtmann 
2267769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2268769be974SMarcel Holtmann 			continue;
2269769be974SMarcel Holtmann 
22701da177e4SLinus Torvalds 		num++;
22711da177e4SLinus Torvalds 
22721da177e4SLinus Torvalds 		if (c->sent < min) {
22731da177e4SLinus Torvalds 			min  = c->sent;
22741da177e4SLinus Torvalds 			conn = c;
22751da177e4SLinus Torvalds 		}
227652087a79SLuiz Augusto von Dentz 
227752087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
227852087a79SLuiz Augusto von Dentz 			break;
22791da177e4SLinus Torvalds 	}
22801da177e4SLinus Torvalds 
2281bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2282bf4c6325SGustavo F. Padovan 
22831da177e4SLinus Torvalds 	if (conn) {
22846ed58ec5SVille Tervo 		int cnt, q;
22856ed58ec5SVille Tervo 
22866ed58ec5SVille Tervo 		switch (conn->type) {
22876ed58ec5SVille Tervo 		case ACL_LINK:
22886ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
22896ed58ec5SVille Tervo 			break;
22906ed58ec5SVille Tervo 		case SCO_LINK:
22916ed58ec5SVille Tervo 		case ESCO_LINK:
22926ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
22936ed58ec5SVille Tervo 			break;
22946ed58ec5SVille Tervo 		case LE_LINK:
22956ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
22966ed58ec5SVille Tervo 			break;
22976ed58ec5SVille Tervo 		default:
22986ed58ec5SVille Tervo 			cnt = 0;
22996ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
23006ed58ec5SVille Tervo 		}
23016ed58ec5SVille Tervo 
23026ed58ec5SVille Tervo 		q = cnt / num;
23031da177e4SLinus Torvalds 		*quote = q ? q : 1;
23041da177e4SLinus Torvalds 	} else
23051da177e4SLinus Torvalds 		*quote = 0;
23061da177e4SLinus Torvalds 
23071da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
23081da177e4SLinus Torvalds 	return conn;
23091da177e4SLinus Torvalds }
23101da177e4SLinus Torvalds 
23116039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
23121da177e4SLinus Torvalds {
23131da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
23141da177e4SLinus Torvalds 	struct hci_conn *c;
23151da177e4SLinus Torvalds 
2316bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
23171da177e4SLinus Torvalds 
2318bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2319bf4c6325SGustavo F. Padovan 
23201da177e4SLinus Torvalds 	/* Kill stalled connections */
2321bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2322bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
23236ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
23246ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
23257490c6c2SAndrei Emeltchenko 			hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM);
23261da177e4SLinus Torvalds 		}
23271da177e4SLinus Torvalds 	}
2328bf4c6325SGustavo F. Padovan 
2329bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
23301da177e4SLinus Torvalds }
23311da177e4SLinus Torvalds 
23326039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
233373d80debSLuiz Augusto von Dentz 				      int *quote)
233473d80debSLuiz Augusto von Dentz {
233573d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
233673d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
2337abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
233873d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
233973d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
234073d80debSLuiz Augusto von Dentz 
234173d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
234273d80debSLuiz Augusto von Dentz 
2343bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2344bf4c6325SGustavo F. Padovan 
2345bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
234673d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
234773d80debSLuiz Augusto von Dentz 
234873d80debSLuiz Augusto von Dentz 		if (conn->type != type)
234973d80debSLuiz Augusto von Dentz 			continue;
235073d80debSLuiz Augusto von Dentz 
235173d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
235273d80debSLuiz Augusto von Dentz 			continue;
235373d80debSLuiz Augusto von Dentz 
235473d80debSLuiz Augusto von Dentz 		conn_num++;
235573d80debSLuiz Augusto von Dentz 
23568192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
235773d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
235873d80debSLuiz Augusto von Dentz 
235973d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
236073d80debSLuiz Augusto von Dentz 				continue;
236173d80debSLuiz Augusto von Dentz 
236273d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
236373d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
236473d80debSLuiz Augusto von Dentz 				continue;
236573d80debSLuiz Augusto von Dentz 
236673d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
236773d80debSLuiz Augusto von Dentz 				num = 0;
236873d80debSLuiz Augusto von Dentz 				min = ~0;
236973d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
237073d80debSLuiz Augusto von Dentz 			}
237173d80debSLuiz Augusto von Dentz 
237273d80debSLuiz Augusto von Dentz 			num++;
237373d80debSLuiz Augusto von Dentz 
237473d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
237573d80debSLuiz Augusto von Dentz 				min  = conn->sent;
237673d80debSLuiz Augusto von Dentz 				chan = tmp;
237773d80debSLuiz Augusto von Dentz 			}
237873d80debSLuiz Augusto von Dentz 		}
237973d80debSLuiz Augusto von Dentz 
238073d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
238173d80debSLuiz Augusto von Dentz 			break;
238273d80debSLuiz Augusto von Dentz 	}
238373d80debSLuiz Augusto von Dentz 
2384bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2385bf4c6325SGustavo F. Padovan 
238673d80debSLuiz Augusto von Dentz 	if (!chan)
238773d80debSLuiz Augusto von Dentz 		return NULL;
238873d80debSLuiz Augusto von Dentz 
238973d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
239073d80debSLuiz Augusto von Dentz 	case ACL_LINK:
239173d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
239273d80debSLuiz Augusto von Dentz 		break;
2393bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
2394bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
2395bd1eb66bSAndrei Emeltchenko 		break;
239673d80debSLuiz Augusto von Dentz 	case SCO_LINK:
239773d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
239873d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
239973d80debSLuiz Augusto von Dentz 		break;
240073d80debSLuiz Augusto von Dentz 	case LE_LINK:
240173d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
240273d80debSLuiz Augusto von Dentz 		break;
240373d80debSLuiz Augusto von Dentz 	default:
240473d80debSLuiz Augusto von Dentz 		cnt = 0;
240573d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
240673d80debSLuiz Augusto von Dentz 	}
240773d80debSLuiz Augusto von Dentz 
240873d80debSLuiz Augusto von Dentz 	q = cnt / num;
240973d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
241073d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
241173d80debSLuiz Augusto von Dentz 	return chan;
241273d80debSLuiz Augusto von Dentz }
241373d80debSLuiz Augusto von Dentz 
241402b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
241502b20f0bSLuiz Augusto von Dentz {
241602b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
241702b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
241802b20f0bSLuiz Augusto von Dentz 	int num = 0;
241902b20f0bSLuiz Augusto von Dentz 
242002b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
242102b20f0bSLuiz Augusto von Dentz 
2422bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2423bf4c6325SGustavo F. Padovan 
2424bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
242502b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
242602b20f0bSLuiz Augusto von Dentz 
242702b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
242802b20f0bSLuiz Augusto von Dentz 			continue;
242902b20f0bSLuiz Augusto von Dentz 
243002b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
243102b20f0bSLuiz Augusto von Dentz 			continue;
243202b20f0bSLuiz Augusto von Dentz 
243302b20f0bSLuiz Augusto von Dentz 		num++;
243402b20f0bSLuiz Augusto von Dentz 
24358192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
243602b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
243702b20f0bSLuiz Augusto von Dentz 
243802b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
243902b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
244002b20f0bSLuiz Augusto von Dentz 				continue;
244102b20f0bSLuiz Augusto von Dentz 			}
244202b20f0bSLuiz Augusto von Dentz 
244302b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
244402b20f0bSLuiz Augusto von Dentz 				continue;
244502b20f0bSLuiz Augusto von Dentz 
244602b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
244702b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
244802b20f0bSLuiz Augusto von Dentz 				continue;
244902b20f0bSLuiz Augusto von Dentz 
245002b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
245102b20f0bSLuiz Augusto von Dentz 
245202b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
245302b20f0bSLuiz Augusto von Dentz 			       skb->priority);
245402b20f0bSLuiz Augusto von Dentz 		}
245502b20f0bSLuiz Augusto von Dentz 
245602b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
245702b20f0bSLuiz Augusto von Dentz 			break;
245802b20f0bSLuiz Augusto von Dentz 	}
2459bf4c6325SGustavo F. Padovan 
2460bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2461bf4c6325SGustavo F. Padovan 
246202b20f0bSLuiz Augusto von Dentz }
246302b20f0bSLuiz Augusto von Dentz 
2464b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
2465b71d385aSAndrei Emeltchenko {
2466b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
2467b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
2468b71d385aSAndrei Emeltchenko }
2469b71d385aSAndrei Emeltchenko 
24706039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
24711da177e4SLinus Torvalds {
24721da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
24731da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
24741da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
247563d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
24765f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
2477bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
24781da177e4SLinus Torvalds 	}
247963d2bc1bSAndrei Emeltchenko }
24801da177e4SLinus Torvalds 
24816039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
248263d2bc1bSAndrei Emeltchenko {
248363d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
248463d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
248563d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
248663d2bc1bSAndrei Emeltchenko 	int quote;
248763d2bc1bSAndrei Emeltchenko 
248863d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
248904837f64SMarcel Holtmann 
249073d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
249173d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2492ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2493ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
249473d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
249573d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
249673d80debSLuiz Augusto von Dentz 
2497ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2498ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2499ec1cce24SLuiz Augusto von Dentz 				break;
2500ec1cce24SLuiz Augusto von Dentz 
2501ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2502ec1cce24SLuiz Augusto von Dentz 
250373d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
250473d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
250504837f64SMarcel Holtmann 
25061da177e4SLinus Torvalds 			hci_send_frame(skb);
25071da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
25081da177e4SLinus Torvalds 
25091da177e4SLinus Torvalds 			hdev->acl_cnt--;
251073d80debSLuiz Augusto von Dentz 			chan->sent++;
251173d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
25121da177e4SLinus Torvalds 		}
25131da177e4SLinus Torvalds 	}
251402b20f0bSLuiz Augusto von Dentz 
251502b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
251602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
25171da177e4SLinus Torvalds }
25181da177e4SLinus Torvalds 
25196039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
2520b71d385aSAndrei Emeltchenko {
252163d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
2522b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
2523b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
2524b71d385aSAndrei Emeltchenko 	int quote;
2525bd1eb66bSAndrei Emeltchenko 	u8 type;
2526b71d385aSAndrei Emeltchenko 
252763d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
2528b71d385aSAndrei Emeltchenko 
2529bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
2530bd1eb66bSAndrei Emeltchenko 
2531bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
2532bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
2533bd1eb66bSAndrei Emeltchenko 	else
2534bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
2535bd1eb66bSAndrei Emeltchenko 
2536b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
2537bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
2538b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
2539b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
2540b71d385aSAndrei Emeltchenko 			int blocks;
2541b71d385aSAndrei Emeltchenko 
2542b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
2543b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
2544b71d385aSAndrei Emeltchenko 
2545b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
2546b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
2547b71d385aSAndrei Emeltchenko 				break;
2548b71d385aSAndrei Emeltchenko 
2549b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
2550b71d385aSAndrei Emeltchenko 
2551b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
2552b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
2553b71d385aSAndrei Emeltchenko 				return;
2554b71d385aSAndrei Emeltchenko 
2555b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
2556b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
2557b71d385aSAndrei Emeltchenko 
2558b71d385aSAndrei Emeltchenko 			hci_send_frame(skb);
2559b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
2560b71d385aSAndrei Emeltchenko 
2561b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
2562b71d385aSAndrei Emeltchenko 			quote -= blocks;
2563b71d385aSAndrei Emeltchenko 
2564b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
2565b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
2566b71d385aSAndrei Emeltchenko 		}
2567b71d385aSAndrei Emeltchenko 	}
2568b71d385aSAndrei Emeltchenko 
2569b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
2570bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
2571b71d385aSAndrei Emeltchenko }
2572b71d385aSAndrei Emeltchenko 
25736039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
2574b71d385aSAndrei Emeltchenko {
2575b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
2576b71d385aSAndrei Emeltchenko 
2577bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
2578bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
2579bd1eb66bSAndrei Emeltchenko 		return;
2580bd1eb66bSAndrei Emeltchenko 
2581bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
2582bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
2583b71d385aSAndrei Emeltchenko 		return;
2584b71d385aSAndrei Emeltchenko 
2585b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
2586b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
2587b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
2588b71d385aSAndrei Emeltchenko 		break;
2589b71d385aSAndrei Emeltchenko 
2590b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
2591b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
2592b71d385aSAndrei Emeltchenko 		break;
2593b71d385aSAndrei Emeltchenko 	}
2594b71d385aSAndrei Emeltchenko }
2595b71d385aSAndrei Emeltchenko 
25961da177e4SLinus Torvalds /* Schedule SCO */
25976039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
25981da177e4SLinus Torvalds {
25991da177e4SLinus Torvalds 	struct hci_conn *conn;
26001da177e4SLinus Torvalds 	struct sk_buff *skb;
26011da177e4SLinus Torvalds 	int quote;
26021da177e4SLinus Torvalds 
26031da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
26041da177e4SLinus Torvalds 
260552087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
260652087a79SLuiz Augusto von Dentz 		return;
260752087a79SLuiz Augusto von Dentz 
26081da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
26091da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
26101da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
26111da177e4SLinus Torvalds 			hci_send_frame(skb);
26121da177e4SLinus Torvalds 
26131da177e4SLinus Torvalds 			conn->sent++;
26141da177e4SLinus Torvalds 			if (conn->sent == ~0)
26151da177e4SLinus Torvalds 				conn->sent = 0;
26161da177e4SLinus Torvalds 		}
26171da177e4SLinus Torvalds 	}
26181da177e4SLinus Torvalds }
26191da177e4SLinus Torvalds 
26206039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
2621b6a0dc82SMarcel Holtmann {
2622b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
2623b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
2624b6a0dc82SMarcel Holtmann 	int quote;
2625b6a0dc82SMarcel Holtmann 
2626b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2627b6a0dc82SMarcel Holtmann 
262852087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
262952087a79SLuiz Augusto von Dentz 		return;
263052087a79SLuiz Augusto von Dentz 
26318fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
26328fc9ced3SGustavo Padovan 						     &quote))) {
2633b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
2634b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
2635b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
2636b6a0dc82SMarcel Holtmann 
2637b6a0dc82SMarcel Holtmann 			conn->sent++;
2638b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
2639b6a0dc82SMarcel Holtmann 				conn->sent = 0;
2640b6a0dc82SMarcel Holtmann 		}
2641b6a0dc82SMarcel Holtmann 	}
2642b6a0dc82SMarcel Holtmann }
2643b6a0dc82SMarcel Holtmann 
26446039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
26456ed58ec5SVille Tervo {
264673d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
26476ed58ec5SVille Tervo 	struct sk_buff *skb;
264802b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
26496ed58ec5SVille Tervo 
26506ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
26516ed58ec5SVille Tervo 
265252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
265352087a79SLuiz Augusto von Dentz 		return;
265452087a79SLuiz Augusto von Dentz 
26556ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
26566ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
26576ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
2658bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
26596ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
2660bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
26616ed58ec5SVille Tervo 	}
26626ed58ec5SVille Tervo 
26636ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
266402b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
266573d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
2666ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2667ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
266873d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
266973d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
26706ed58ec5SVille Tervo 
2671ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2672ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2673ec1cce24SLuiz Augusto von Dentz 				break;
2674ec1cce24SLuiz Augusto von Dentz 
2675ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2676ec1cce24SLuiz Augusto von Dentz 
26776ed58ec5SVille Tervo 			hci_send_frame(skb);
26786ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
26796ed58ec5SVille Tervo 
26806ed58ec5SVille Tervo 			cnt--;
268173d80debSLuiz Augusto von Dentz 			chan->sent++;
268273d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
26836ed58ec5SVille Tervo 		}
26846ed58ec5SVille Tervo 	}
268573d80debSLuiz Augusto von Dentz 
26866ed58ec5SVille Tervo 	if (hdev->le_pkts)
26876ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
26886ed58ec5SVille Tervo 	else
26896ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
269002b20f0bSLuiz Augusto von Dentz 
269102b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
269202b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
26936ed58ec5SVille Tervo }
26946ed58ec5SVille Tervo 
26953eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
26961da177e4SLinus Torvalds {
26973eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
26981da177e4SLinus Torvalds 	struct sk_buff *skb;
26991da177e4SLinus Torvalds 
27006ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
27016ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
27021da177e4SLinus Torvalds 
27031da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
27041da177e4SLinus Torvalds 
27051da177e4SLinus Torvalds 	hci_sched_acl(hdev);
27061da177e4SLinus Torvalds 
27071da177e4SLinus Torvalds 	hci_sched_sco(hdev);
27081da177e4SLinus Torvalds 
2709b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
2710b6a0dc82SMarcel Holtmann 
27116ed58ec5SVille Tervo 	hci_sched_le(hdev);
27126ed58ec5SVille Tervo 
27131da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
27141da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
27151da177e4SLinus Torvalds 		hci_send_frame(skb);
27161da177e4SLinus Torvalds }
27171da177e4SLinus Torvalds 
271825985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
27191da177e4SLinus Torvalds 
27201da177e4SLinus Torvalds /* ACL data packet */
27216039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
27221da177e4SLinus Torvalds {
27231da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
27241da177e4SLinus Torvalds 	struct hci_conn *conn;
27251da177e4SLinus Torvalds 	__u16 handle, flags;
27261da177e4SLinus Torvalds 
27271da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
27281da177e4SLinus Torvalds 
27291da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
27301da177e4SLinus Torvalds 	flags  = hci_flags(handle);
27311da177e4SLinus Torvalds 	handle = hci_handle(handle);
27321da177e4SLinus Torvalds 
2733f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
2734a8c5fb1aSGustavo Padovan 	       handle, flags);
27351da177e4SLinus Torvalds 
27361da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
27371da177e4SLinus Torvalds 
27381da177e4SLinus Torvalds 	hci_dev_lock(hdev);
27391da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
27401da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
27411da177e4SLinus Torvalds 
27421da177e4SLinus Torvalds 	if (conn) {
274365983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
274404837f64SMarcel Holtmann 
2745671267bfSJohan Hedberg 		hci_dev_lock(hdev);
2746671267bfSJohan Hedberg 		if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
2747671267bfSJohan Hedberg 		    !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2748671267bfSJohan Hedberg 			mgmt_device_connected(hdev, &conn->dst, conn->type,
2749671267bfSJohan Hedberg 					      conn->dst_type, 0, NULL, 0,
2750671267bfSJohan Hedberg 					      conn->dev_class);
2751671267bfSJohan Hedberg 		hci_dev_unlock(hdev);
2752671267bfSJohan Hedberg 
27531da177e4SLinus Torvalds 		/* Send to upper protocol */
2754686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
27551da177e4SLinus Torvalds 		return;
27561da177e4SLinus Torvalds 	} else {
27571da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
27581da177e4SLinus Torvalds 		       hdev->name, handle);
27591da177e4SLinus Torvalds 	}
27601da177e4SLinus Torvalds 
27611da177e4SLinus Torvalds 	kfree_skb(skb);
27621da177e4SLinus Torvalds }
27631da177e4SLinus Torvalds 
27641da177e4SLinus Torvalds /* SCO data packet */
27656039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
27661da177e4SLinus Torvalds {
27671da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
27681da177e4SLinus Torvalds 	struct hci_conn *conn;
27691da177e4SLinus Torvalds 	__u16 handle;
27701da177e4SLinus Torvalds 
27711da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
27721da177e4SLinus Torvalds 
27731da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
27741da177e4SLinus Torvalds 
2775f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
27761da177e4SLinus Torvalds 
27771da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
27781da177e4SLinus Torvalds 
27791da177e4SLinus Torvalds 	hci_dev_lock(hdev);
27801da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
27811da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
27821da177e4SLinus Torvalds 
27831da177e4SLinus Torvalds 	if (conn) {
27841da177e4SLinus Torvalds 		/* Send to upper protocol */
2785686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
27861da177e4SLinus Torvalds 		return;
27871da177e4SLinus Torvalds 	} else {
27881da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
27891da177e4SLinus Torvalds 		       hdev->name, handle);
27901da177e4SLinus Torvalds 	}
27911da177e4SLinus Torvalds 
27921da177e4SLinus Torvalds 	kfree_skb(skb);
27931da177e4SLinus Torvalds }
27941da177e4SLinus Torvalds 
2795b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
27961da177e4SLinus Torvalds {
2797b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
27981da177e4SLinus Torvalds 	struct sk_buff *skb;
27991da177e4SLinus Torvalds 
28001da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
28011da177e4SLinus Torvalds 
28021da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
2803cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
2804cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
2805cd82e61cSMarcel Holtmann 
28061da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
28071da177e4SLinus Torvalds 			/* Send copy to the sockets */
2808470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
28091da177e4SLinus Torvalds 		}
28101da177e4SLinus Torvalds 
28111da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
28121da177e4SLinus Torvalds 			kfree_skb(skb);
28131da177e4SLinus Torvalds 			continue;
28141da177e4SLinus Torvalds 		}
28151da177e4SLinus Torvalds 
28161da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
28171da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
28180d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
28191da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
28201da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
28211da177e4SLinus Torvalds 				kfree_skb(skb);
28221da177e4SLinus Torvalds 				continue;
28233ff50b79SStephen Hemminger 			}
28241da177e4SLinus Torvalds 		}
28251da177e4SLinus Torvalds 
28261da177e4SLinus Torvalds 		/* Process frame */
28270d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
28281da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
2829b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
28301da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
28311da177e4SLinus Torvalds 			break;
28321da177e4SLinus Torvalds 
28331da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
28341da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
28351da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
28361da177e4SLinus Torvalds 			break;
28371da177e4SLinus Torvalds 
28381da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
28391da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
28401da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
28411da177e4SLinus Torvalds 			break;
28421da177e4SLinus Torvalds 
28431da177e4SLinus Torvalds 		default:
28441da177e4SLinus Torvalds 			kfree_skb(skb);
28451da177e4SLinus Torvalds 			break;
28461da177e4SLinus Torvalds 		}
28471da177e4SLinus Torvalds 	}
28481da177e4SLinus Torvalds }
28491da177e4SLinus Torvalds 
2850c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
28511da177e4SLinus Torvalds {
2852c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
28531da177e4SLinus Torvalds 	struct sk_buff *skb;
28541da177e4SLinus Torvalds 
28552104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
28562104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
28571da177e4SLinus Torvalds 
28581da177e4SLinus Torvalds 	/* Send queued commands */
28595a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
28605a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
28615a08ecceSAndrei Emeltchenko 		if (!skb)
28625a08ecceSAndrei Emeltchenko 			return;
28635a08ecceSAndrei Emeltchenko 
28641da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
28651da177e4SLinus Torvalds 
286670f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
286770f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
28681da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
28691da177e4SLinus Torvalds 			hci_send_frame(skb);
28707bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
28717bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
28727bdb8a5cSSzymon Janc 			else
28736bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
28745f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
28751da177e4SLinus Torvalds 		} else {
28761da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
2877c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
28781da177e4SLinus Torvalds 		}
28791da177e4SLinus Torvalds 	}
28801da177e4SLinus Torvalds }
28812519a1fcSAndre Guedes 
28822519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
28832519a1fcSAndre Guedes {
28842519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
28852519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
28862519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
28872519a1fcSAndre Guedes 
28882519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
28892519a1fcSAndre Guedes 
28902519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
28912519a1fcSAndre Guedes 		return -EINPROGRESS;
28922519a1fcSAndre Guedes 
28934663262cSJohan Hedberg 	inquiry_cache_flush(hdev);
28944663262cSJohan Hedberg 
28952519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
28962519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
28972519a1fcSAndre Guedes 	cp.length  = length;
28982519a1fcSAndre Guedes 
28992519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
29002519a1fcSAndre Guedes }
2901023d5049SAndre Guedes 
2902023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
2903023d5049SAndre Guedes {
2904023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
2905023d5049SAndre Guedes 
2906023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
29077537e5c3SAndre Guedes 		return -EALREADY;
2908023d5049SAndre Guedes 
2909023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2910023d5049SAndre Guedes }
291131f7956cSAndre Guedes 
291231f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type)
291331f7956cSAndre Guedes {
291431f7956cSAndre Guedes 	switch (bdaddr_type) {
291531f7956cSAndre Guedes 	case BDADDR_LE_PUBLIC:
291631f7956cSAndre Guedes 		return ADDR_LE_DEV_PUBLIC;
291731f7956cSAndre Guedes 
291831f7956cSAndre Guedes 	default:
291931f7956cSAndre Guedes 		/* Fallback to LE Random address type */
292031f7956cSAndre Guedes 		return ADDR_LE_DEV_RANDOM;
292131f7956cSAndre Guedes 	}
292231f7956cSAndre Guedes }
2923