xref: /openbmc/linux/net/bluetooth/hci_core.c (revision bda4f23a)
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 
36ab81cbf9SJohan Hedberg #define AUTO_OFF_TIMEOUT 2000
37ab81cbf9SJohan Hedberg 
38b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
39c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
403eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
411da177e4SLinus Torvalds 
421da177e4SLinus Torvalds /* HCI device list */
431da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
441da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds /* HCI callback list */
471da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
481da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
491da177e4SLinus Torvalds 
503df92b31SSasha Levin /* HCI ID Numbering */
513df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
523df92b31SSasha Levin 
531da177e4SLinus Torvalds /* ---- HCI notifications ---- */
541da177e4SLinus Torvalds 
556516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
561da177e4SLinus Torvalds {
57040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
581da177e4SLinus Torvalds }
591da177e4SLinus Torvalds 
601da177e4SLinus Torvalds /* ---- HCI requests ---- */
611da177e4SLinus Torvalds 
6223bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
631da177e4SLinus Torvalds {
6423bb5763SJohan Hedberg 	BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result);
6523bb5763SJohan Hedberg 
66a5040efaSJohan Hedberg 	/* If this is the init phase check if the completed command matches
67a5040efaSJohan Hedberg 	 * the last init command, and if not just return.
68a5040efaSJohan Hedberg 	 */
6975fb0e32SJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) {
7075fb0e32SJohan Hedberg 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
711036b890SAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
7275fb0e32SJohan Hedberg 		struct sk_buff *skb;
7375fb0e32SJohan Hedberg 
7475fb0e32SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
7575fb0e32SJohan Hedberg 		 * reset complete event during init and any pending
7675fb0e32SJohan Hedberg 		 * command will never be completed. In such a case we
7775fb0e32SJohan Hedberg 		 * need to resend whatever was the last sent
7875fb0e32SJohan Hedberg 		 * command.
7975fb0e32SJohan Hedberg 		 */
8075fb0e32SJohan Hedberg 
811036b890SAndrei Emeltchenko 		if (cmd != HCI_OP_RESET || opcode == HCI_OP_RESET)
8223bb5763SJohan Hedberg 			return;
831da177e4SLinus Torvalds 
8475fb0e32SJohan Hedberg 		skb = skb_clone(hdev->sent_cmd, GFP_ATOMIC);
8575fb0e32SJohan Hedberg 		if (skb) {
8675fb0e32SJohan Hedberg 			skb_queue_head(&hdev->cmd_q, skb);
8775fb0e32SJohan Hedberg 			queue_work(hdev->workqueue, &hdev->cmd_work);
8875fb0e32SJohan Hedberg 		}
8975fb0e32SJohan Hedberg 
9075fb0e32SJohan Hedberg 		return;
9175fb0e32SJohan Hedberg 	}
9275fb0e32SJohan Hedberg 
931da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
941da177e4SLinus Torvalds 		hdev->req_result = result;
951da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
961da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
971da177e4SLinus Torvalds 	}
981da177e4SLinus Torvalds }
991da177e4SLinus Torvalds 
1001da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
1011da177e4SLinus Torvalds {
1021da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
1031da177e4SLinus Torvalds 
1041da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1051da177e4SLinus Torvalds 		hdev->req_result = err;
1061da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
1071da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1081da177e4SLinus Torvalds 	}
1091da177e4SLinus Torvalds }
1101da177e4SLinus Torvalds 
1111da177e4SLinus Torvalds /* Execute request and wait for completion. */
112a8c5fb1aSGustavo Padovan static int __hci_request(struct hci_dev *hdev,
113a8c5fb1aSGustavo Padovan 			 void (*req)(struct hci_dev *hdev, unsigned long opt),
1141da177e4SLinus Torvalds 			 unsigned long opt, __u32 timeout)
1151da177e4SLinus Torvalds {
1161da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
1171da177e4SLinus Torvalds 	int err = 0;
1181da177e4SLinus Torvalds 
1191da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
1201da177e4SLinus Torvalds 
1211da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
1221da177e4SLinus Torvalds 
1231da177e4SLinus Torvalds 	add_wait_queue(&hdev->req_wait_q, &wait);
1241da177e4SLinus Torvalds 	set_current_state(TASK_INTERRUPTIBLE);
1251da177e4SLinus Torvalds 
1261da177e4SLinus Torvalds 	req(hdev, opt);
1271da177e4SLinus Torvalds 	schedule_timeout(timeout);
1281da177e4SLinus Torvalds 
1291da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
1301da177e4SLinus Torvalds 
1311da177e4SLinus Torvalds 	if (signal_pending(current))
1321da177e4SLinus Torvalds 		return -EINTR;
1331da177e4SLinus Torvalds 
1341da177e4SLinus Torvalds 	switch (hdev->req_status) {
1351da177e4SLinus Torvalds 	case HCI_REQ_DONE:
136e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
1371da177e4SLinus Torvalds 		break;
1381da177e4SLinus Torvalds 
1391da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
1401da177e4SLinus Torvalds 		err = -hdev->req_result;
1411da177e4SLinus Torvalds 		break;
1421da177e4SLinus Torvalds 
1431da177e4SLinus Torvalds 	default:
1441da177e4SLinus Torvalds 		err = -ETIMEDOUT;
1451da177e4SLinus Torvalds 		break;
1463ff50b79SStephen Hemminger 	}
1471da177e4SLinus Torvalds 
148a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
1491da177e4SLinus Torvalds 
1501da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
1511da177e4SLinus Torvalds 
1521da177e4SLinus Torvalds 	return err;
1531da177e4SLinus Torvalds }
1541da177e4SLinus Torvalds 
1556039aa73SGustavo Padovan static int hci_request(struct hci_dev *hdev,
1566039aa73SGustavo Padovan 		       void (*req)(struct hci_dev *hdev, unsigned long opt),
1571da177e4SLinus Torvalds 		       unsigned long opt, __u32 timeout)
1581da177e4SLinus Torvalds {
1591da177e4SLinus Torvalds 	int ret;
1601da177e4SLinus Torvalds 
1617c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
1627c6a329eSMarcel Holtmann 		return -ENETDOWN;
1637c6a329eSMarcel Holtmann 
1641da177e4SLinus Torvalds 	/* Serialize all requests */
1651da177e4SLinus Torvalds 	hci_req_lock(hdev);
1661da177e4SLinus Torvalds 	ret = __hci_request(hdev, req, opt, timeout);
1671da177e4SLinus Torvalds 	hci_req_unlock(hdev);
1681da177e4SLinus Torvalds 
1691da177e4SLinus Torvalds 	return ret;
1701da177e4SLinus Torvalds }
1711da177e4SLinus Torvalds 
1721da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
1731da177e4SLinus Torvalds {
1741da177e4SLinus Torvalds 	BT_DBG("%s %ld", hdev->name, opt);
1751da177e4SLinus Torvalds 
1761da177e4SLinus Torvalds 	/* Reset device */
177f630cf0dSGustavo F. Padovan 	set_bit(HCI_RESET, &hdev->flags);
178a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
1791da177e4SLinus Torvalds }
1801da177e4SLinus Torvalds 
181e61ef499SAndrei Emeltchenko static void bredr_init(struct hci_dev *hdev)
1821da177e4SLinus Torvalds {
183b0916ea0SJohan Hedberg 	struct hci_cp_delete_stored_link_key cp;
1841ebb9252SMarcel Holtmann 	__le16 param;
18589f2783dSMarcel Holtmann 	__u8 flt_type;
1861da177e4SLinus Torvalds 
1872455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
1882455a3eaSAndrei Emeltchenko 
1891da177e4SLinus Torvalds 	/* Mandatory initialization */
1901da177e4SLinus Torvalds 
1911da177e4SLinus Torvalds 	/* Reset */
192a6c511c6SSzymon Janc 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
193f630cf0dSGustavo F. Padovan 		set_bit(HCI_RESET, &hdev->flags);
194a9de9248SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
195f630cf0dSGustavo F. Padovan 	}
1961da177e4SLinus Torvalds 
1971da177e4SLinus Torvalds 	/* Read Local Supported Features */
198a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
1991da177e4SLinus Torvalds 
2001143e5a6SMarcel Holtmann 	/* Read Local Version */
201a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2021143e5a6SMarcel Holtmann 
2031da177e4SLinus Torvalds 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
204a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
2051da177e4SLinus Torvalds 
2061da177e4SLinus Torvalds 	/* Read BD Address */
207a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
208a9de9248SMarcel Holtmann 
209a9de9248SMarcel Holtmann 	/* Read Class of Device */
210a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
211a9de9248SMarcel Holtmann 
212a9de9248SMarcel Holtmann 	/* Read Local Name */
213a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
2141da177e4SLinus Torvalds 
2151da177e4SLinus Torvalds 	/* Read Voice Setting */
216a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
2171da177e4SLinus Torvalds 
2181da177e4SLinus Torvalds 	/* Optional initialization */
2191da177e4SLinus Torvalds 
2201da177e4SLinus Torvalds 	/* Clear Event Filters */
22189f2783dSMarcel Holtmann 	flt_type = HCI_FLT_CLEAR_ALL;
222a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
2231da177e4SLinus Torvalds 
2241da177e4SLinus Torvalds 	/* Connection accept timeout ~20 secs */
22582781e63SAndrei Emeltchenko 	param = __constant_cpu_to_le16(0x7d00);
226a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
227b0916ea0SJohan Hedberg 
228b0916ea0SJohan Hedberg 	bacpy(&cp.bdaddr, BDADDR_ANY);
229b0916ea0SJohan Hedberg 	cp.delete_all = 1;
230b0916ea0SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
2311da177e4SLinus Torvalds }
2321da177e4SLinus Torvalds 
233e61ef499SAndrei Emeltchenko static void amp_init(struct hci_dev *hdev)
234e61ef499SAndrei Emeltchenko {
2352455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
2362455a3eaSAndrei Emeltchenko 
237e61ef499SAndrei Emeltchenko 	/* Reset */
238e61ef499SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
239e61ef499SAndrei Emeltchenko 
240e61ef499SAndrei Emeltchenko 	/* Read Local Version */
241e61ef499SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2426bcbc489SAndrei Emeltchenko 
2436bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
2446bcbc489SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
245e61ef499SAndrei Emeltchenko }
246e61ef499SAndrei Emeltchenko 
247e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
248e61ef499SAndrei Emeltchenko {
249e61ef499SAndrei Emeltchenko 	struct sk_buff *skb;
250e61ef499SAndrei Emeltchenko 
251e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
252e61ef499SAndrei Emeltchenko 
253e61ef499SAndrei Emeltchenko 	/* Driver initialization */
254e61ef499SAndrei Emeltchenko 
255e61ef499SAndrei Emeltchenko 	/* Special commands */
256e61ef499SAndrei Emeltchenko 	while ((skb = skb_dequeue(&hdev->driver_init))) {
257e61ef499SAndrei Emeltchenko 		bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
258e61ef499SAndrei Emeltchenko 		skb->dev = (void *) hdev;
259e61ef499SAndrei Emeltchenko 
260e61ef499SAndrei Emeltchenko 		skb_queue_tail(&hdev->cmd_q, skb);
261e61ef499SAndrei Emeltchenko 		queue_work(hdev->workqueue, &hdev->cmd_work);
262e61ef499SAndrei Emeltchenko 	}
263e61ef499SAndrei Emeltchenko 	skb_queue_purge(&hdev->driver_init);
264e61ef499SAndrei Emeltchenko 
265e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
266e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
267e61ef499SAndrei Emeltchenko 		bredr_init(hdev);
268e61ef499SAndrei Emeltchenko 		break;
269e61ef499SAndrei Emeltchenko 
270e61ef499SAndrei Emeltchenko 	case HCI_AMP:
271e61ef499SAndrei Emeltchenko 		amp_init(hdev);
272e61ef499SAndrei Emeltchenko 		break;
273e61ef499SAndrei Emeltchenko 
274e61ef499SAndrei Emeltchenko 	default:
275e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
276e61ef499SAndrei Emeltchenko 		break;
277e61ef499SAndrei Emeltchenko 	}
278e61ef499SAndrei Emeltchenko 
279e61ef499SAndrei Emeltchenko }
280e61ef499SAndrei Emeltchenko 
2816ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
2826ed58ec5SVille Tervo {
2836ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
2846ed58ec5SVille Tervo 
2856ed58ec5SVille Tervo 	/* Read LE buffer size */
2866ed58ec5SVille Tervo 	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
2876ed58ec5SVille Tervo }
2886ed58ec5SVille Tervo 
2891da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
2901da177e4SLinus Torvalds {
2911da177e4SLinus Torvalds 	__u8 scan = opt;
2921da177e4SLinus Torvalds 
2931da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, scan);
2941da177e4SLinus Torvalds 
2951da177e4SLinus Torvalds 	/* Inquiry and Page scans */
296a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
2971da177e4SLinus Torvalds }
2981da177e4SLinus Torvalds 
2991da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
3001da177e4SLinus Torvalds {
3011da177e4SLinus Torvalds 	__u8 auth = opt;
3021da177e4SLinus Torvalds 
3031da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, auth);
3041da177e4SLinus Torvalds 
3051da177e4SLinus Torvalds 	/* Authentication */
306a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
3071da177e4SLinus Torvalds }
3081da177e4SLinus Torvalds 
3091da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
3101da177e4SLinus Torvalds {
3111da177e4SLinus Torvalds 	__u8 encrypt = opt;
3121da177e4SLinus Torvalds 
3131da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, encrypt);
3141da177e4SLinus Torvalds 
315e4e8e37cSMarcel Holtmann 	/* Encryption */
316a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
3171da177e4SLinus Torvalds }
3181da177e4SLinus Torvalds 
319e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt)
320e4e8e37cSMarcel Holtmann {
321e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
322e4e8e37cSMarcel Holtmann 
323a418b893SMarcel Holtmann 	BT_DBG("%s %x", hdev->name, policy);
324e4e8e37cSMarcel Holtmann 
325e4e8e37cSMarcel Holtmann 	/* Default link policy */
326e4e8e37cSMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
327e4e8e37cSMarcel Holtmann }
328e4e8e37cSMarcel Holtmann 
3291da177e4SLinus Torvalds /* Get HCI device by index.
3301da177e4SLinus Torvalds  * Device is held on return. */
3311da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
3321da177e4SLinus Torvalds {
3338035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
3341da177e4SLinus Torvalds 
3351da177e4SLinus Torvalds 	BT_DBG("%d", index);
3361da177e4SLinus Torvalds 
3371da177e4SLinus Torvalds 	if (index < 0)
3381da177e4SLinus Torvalds 		return NULL;
3391da177e4SLinus Torvalds 
3401da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
3418035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
3421da177e4SLinus Torvalds 		if (d->id == index) {
3431da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
3441da177e4SLinus Torvalds 			break;
3451da177e4SLinus Torvalds 		}
3461da177e4SLinus Torvalds 	}
3471da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
3481da177e4SLinus Torvalds 	return hdev;
3491da177e4SLinus Torvalds }
3501da177e4SLinus Torvalds 
3511da177e4SLinus Torvalds /* ---- Inquiry support ---- */
352ff9ef578SJohan Hedberg 
35330dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
35430dc78e1SJohan Hedberg {
35530dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
35630dc78e1SJohan Hedberg 
3576fbe195dSAndre Guedes 	switch (discov->state) {
358343f935bSAndre Guedes 	case DISCOVERY_FINDING:
3596fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
36030dc78e1SJohan Hedberg 		return true;
36130dc78e1SJohan Hedberg 
3626fbe195dSAndre Guedes 	default:
36330dc78e1SJohan Hedberg 		return false;
36430dc78e1SJohan Hedberg 	}
3656fbe195dSAndre Guedes }
36630dc78e1SJohan Hedberg 
367ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
368ff9ef578SJohan Hedberg {
369ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
370ff9ef578SJohan Hedberg 
371ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
372ff9ef578SJohan Hedberg 		return;
373ff9ef578SJohan Hedberg 
374ff9ef578SJohan Hedberg 	switch (state) {
375ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
3767b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
377ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
378ff9ef578SJohan Hedberg 		break;
379ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
380ff9ef578SJohan Hedberg 		break;
381343f935bSAndre Guedes 	case DISCOVERY_FINDING:
382ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
383ff9ef578SJohan Hedberg 		break;
38430dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
38530dc78e1SJohan Hedberg 		break;
386ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
387ff9ef578SJohan Hedberg 		break;
388ff9ef578SJohan Hedberg 	}
389ff9ef578SJohan Hedberg 
390ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
391ff9ef578SJohan Hedberg }
392ff9ef578SJohan Hedberg 
3931da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
3941da177e4SLinus Torvalds {
39530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
396b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
3971da177e4SLinus Torvalds 
398561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
399561aafbcSJohan Hedberg 		list_del(&p->all);
400b57c1a56SJohan Hedberg 		kfree(p);
4011da177e4SLinus Torvalds 	}
402561aafbcSJohan Hedberg 
403561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
404561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
4051da177e4SLinus Torvalds }
4061da177e4SLinus Torvalds 
407a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
408a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
4091da177e4SLinus Torvalds {
41030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
4111da177e4SLinus Torvalds 	struct inquiry_entry *e;
4121da177e4SLinus Torvalds 
4131da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
4141da177e4SLinus Torvalds 
415561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
4161da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
4171da177e4SLinus Torvalds 			return e;
4181da177e4SLinus Torvalds 	}
4191da177e4SLinus Torvalds 
420b57c1a56SJohan Hedberg 	return NULL;
421b57c1a56SJohan Hedberg }
422b57c1a56SJohan Hedberg 
423561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
424561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
425561aafbcSJohan Hedberg {
42630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
427561aafbcSJohan Hedberg 	struct inquiry_entry *e;
428561aafbcSJohan Hedberg 
429561aafbcSJohan Hedberg 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
430561aafbcSJohan Hedberg 
431561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
432561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
433561aafbcSJohan Hedberg 			return e;
434561aafbcSJohan Hedberg 	}
435561aafbcSJohan Hedberg 
436561aafbcSJohan Hedberg 	return NULL;
437561aafbcSJohan Hedberg }
438561aafbcSJohan Hedberg 
43930dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
44030dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
44130dc78e1SJohan Hedberg 						       int state)
44230dc78e1SJohan Hedberg {
44330dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
44430dc78e1SJohan Hedberg 	struct inquiry_entry *e;
44530dc78e1SJohan Hedberg 
44630dc78e1SJohan Hedberg 	BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state);
44730dc78e1SJohan Hedberg 
44830dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
44930dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
45030dc78e1SJohan Hedberg 			return e;
45130dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
45230dc78e1SJohan Hedberg 			return e;
45330dc78e1SJohan Hedberg 	}
45430dc78e1SJohan Hedberg 
45530dc78e1SJohan Hedberg 	return NULL;
45630dc78e1SJohan Hedberg }
45730dc78e1SJohan Hedberg 
458a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
459a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
460a3d4e20aSJohan Hedberg {
461a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
462a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
463a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
464a3d4e20aSJohan Hedberg 
465a3d4e20aSJohan Hedberg 	list_del(&ie->list);
466a3d4e20aSJohan Hedberg 
467a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
468a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
469a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
470a3d4e20aSJohan Hedberg 			break;
471a3d4e20aSJohan Hedberg 		pos = &p->list;
472a3d4e20aSJohan Hedberg 	}
473a3d4e20aSJohan Hedberg 
474a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
475a3d4e20aSJohan Hedberg }
476a3d4e20aSJohan Hedberg 
4773175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
478388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
4791da177e4SLinus Torvalds {
48030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
48170f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
4821da177e4SLinus Torvalds 
4831da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
4841da177e4SLinus Torvalds 
485388fc8faSJohan Hedberg 	if (ssp)
486388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
487388fc8faSJohan Hedberg 
48870f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
489a3d4e20aSJohan Hedberg 	if (ie) {
490388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
491388fc8faSJohan Hedberg 			*ssp = true;
492388fc8faSJohan Hedberg 
493a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
494a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
495a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
496a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
497a3d4e20aSJohan Hedberg 		}
498a3d4e20aSJohan Hedberg 
499561aafbcSJohan Hedberg 		goto update;
500a3d4e20aSJohan Hedberg 	}
501561aafbcSJohan Hedberg 
5021da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
50370f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
50470f23020SAndrei Emeltchenko 	if (!ie)
5053175405bSJohan Hedberg 		return false;
50670f23020SAndrei Emeltchenko 
507561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
508561aafbcSJohan Hedberg 
509561aafbcSJohan Hedberg 	if (name_known) {
510561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
511561aafbcSJohan Hedberg 	} else {
512561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
513561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
514561aafbcSJohan Hedberg 	}
515561aafbcSJohan Hedberg 
516561aafbcSJohan Hedberg update:
517561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
518561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
519561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
520561aafbcSJohan Hedberg 		list_del(&ie->list);
5211da177e4SLinus Torvalds 	}
5221da177e4SLinus Torvalds 
52370f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
52470f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
5251da177e4SLinus Torvalds 	cache->timestamp = jiffies;
5263175405bSJohan Hedberg 
5273175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
5283175405bSJohan Hedberg 		return false;
5293175405bSJohan Hedberg 
5303175405bSJohan Hedberg 	return true;
5311da177e4SLinus Torvalds }
5321da177e4SLinus Torvalds 
5331da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
5341da177e4SLinus Torvalds {
53530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
5361da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
5371da177e4SLinus Torvalds 	struct inquiry_entry *e;
5381da177e4SLinus Torvalds 	int copied = 0;
5391da177e4SLinus Torvalds 
540561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
5411da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
542b57c1a56SJohan Hedberg 
543b57c1a56SJohan Hedberg 		if (copied >= num)
544b57c1a56SJohan Hedberg 			break;
545b57c1a56SJohan Hedberg 
5461da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
5471da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
5481da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
5491da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
5501da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
5511da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
552b57c1a56SJohan Hedberg 
5531da177e4SLinus Torvalds 		info++;
554b57c1a56SJohan Hedberg 		copied++;
5551da177e4SLinus Torvalds 	}
5561da177e4SLinus Torvalds 
5571da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
5581da177e4SLinus Torvalds 	return copied;
5591da177e4SLinus Torvalds }
5601da177e4SLinus Torvalds 
5611da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
5621da177e4SLinus Torvalds {
5631da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
5641da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
5651da177e4SLinus Torvalds 
5661da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
5671da177e4SLinus Torvalds 
5681da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
5691da177e4SLinus Torvalds 		return;
5701da177e4SLinus Torvalds 
5711da177e4SLinus Torvalds 	/* Start Inquiry */
5721da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
5731da177e4SLinus Torvalds 	cp.length  = ir->length;
5741da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
575a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
5761da177e4SLinus Torvalds }
5771da177e4SLinus Torvalds 
5781da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
5791da177e4SLinus Torvalds {
5801da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
5811da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
5821da177e4SLinus Torvalds 	struct hci_dev *hdev;
5831da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
5841da177e4SLinus Torvalds 	long timeo;
5851da177e4SLinus Torvalds 	__u8 *buf;
5861da177e4SLinus Torvalds 
5871da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
5881da177e4SLinus Torvalds 		return -EFAULT;
5891da177e4SLinus Torvalds 
5905a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
5915a08ecceSAndrei Emeltchenko 	if (!hdev)
5921da177e4SLinus Torvalds 		return -ENODEV;
5931da177e4SLinus Torvalds 
59409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5951da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
596a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
5971da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
5981da177e4SLinus Torvalds 		do_inquiry = 1;
5991da177e4SLinus Torvalds 	}
60009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6011da177e4SLinus Torvalds 
60204837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
60370f23020SAndrei Emeltchenko 
60470f23020SAndrei Emeltchenko 	if (do_inquiry) {
60570f23020SAndrei Emeltchenko 		err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
60670f23020SAndrei Emeltchenko 		if (err < 0)
6071da177e4SLinus Torvalds 			goto done;
60870f23020SAndrei Emeltchenko 	}
6091da177e4SLinus Torvalds 
6108fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
6118fc9ced3SGustavo Padovan 	 * 255 entries
6128fc9ced3SGustavo Padovan 	 */
6131da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
6141da177e4SLinus Torvalds 
6151da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
6161da177e4SLinus Torvalds 	 * copy it to the user space.
6171da177e4SLinus Torvalds 	 */
61870f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
61970f23020SAndrei Emeltchenko 	if (!buf) {
6201da177e4SLinus Torvalds 		err = -ENOMEM;
6211da177e4SLinus Torvalds 		goto done;
6221da177e4SLinus Torvalds 	}
6231da177e4SLinus Torvalds 
62409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6251da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
62609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6271da177e4SLinus Torvalds 
6281da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
6291da177e4SLinus Torvalds 
6301da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
6311da177e4SLinus Torvalds 		ptr += sizeof(ir);
6321da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
6331da177e4SLinus Torvalds 				 ir.num_rsp))
6341da177e4SLinus Torvalds 			err = -EFAULT;
6351da177e4SLinus Torvalds 	} else
6361da177e4SLinus Torvalds 		err = -EFAULT;
6371da177e4SLinus Torvalds 
6381da177e4SLinus Torvalds 	kfree(buf);
6391da177e4SLinus Torvalds 
6401da177e4SLinus Torvalds done:
6411da177e4SLinus Torvalds 	hci_dev_put(hdev);
6421da177e4SLinus Torvalds 	return err;
6431da177e4SLinus Torvalds }
6441da177e4SLinus Torvalds 
6451da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
6461da177e4SLinus Torvalds 
6471da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
6481da177e4SLinus Torvalds {
6491da177e4SLinus Torvalds 	struct hci_dev *hdev;
6501da177e4SLinus Torvalds 	int ret = 0;
6511da177e4SLinus Torvalds 
6525a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
6535a08ecceSAndrei Emeltchenko 	if (!hdev)
6541da177e4SLinus Torvalds 		return -ENODEV;
6551da177e4SLinus Torvalds 
6561da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
6571da177e4SLinus Torvalds 
6581da177e4SLinus Torvalds 	hci_req_lock(hdev);
6591da177e4SLinus Torvalds 
66094324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
66194324962SJohan Hovold 		ret = -ENODEV;
66294324962SJohan Hovold 		goto done;
66394324962SJohan Hovold 	}
66494324962SJohan Hovold 
665611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
666611b30f7SMarcel Holtmann 		ret = -ERFKILL;
667611b30f7SMarcel Holtmann 		goto done;
668611b30f7SMarcel Holtmann 	}
669611b30f7SMarcel Holtmann 
6701da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
6711da177e4SLinus Torvalds 		ret = -EALREADY;
6721da177e4SLinus Torvalds 		goto done;
6731da177e4SLinus Torvalds 	}
6741da177e4SLinus Torvalds 
6751da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
6761da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
6771da177e4SLinus Torvalds 
67807e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
67907e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
68007e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
681943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
682943da25dSMarcel Holtmann 
6831da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
6841da177e4SLinus Torvalds 		ret = -EIO;
6851da177e4SLinus Torvalds 		goto done;
6861da177e4SLinus Torvalds 	}
6871da177e4SLinus Torvalds 
6881da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
6891da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
6901da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
691a5040efaSJohan Hedberg 		hdev->init_last_cmd = 0;
6921da177e4SLinus Torvalds 
6935f246e89SAndrei Emeltchenko 		ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
6941da177e4SLinus Torvalds 
695eead27daSAndre Guedes 		if (lmp_host_le_capable(hdev))
6966ed58ec5SVille Tervo 			ret = __hci_request(hdev, hci_le_init_req, 0,
6975f246e89SAndrei Emeltchenko 					    HCI_INIT_TIMEOUT);
6986ed58ec5SVille Tervo 
6991da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
7001da177e4SLinus Torvalds 	}
7011da177e4SLinus Torvalds 
7021da177e4SLinus Torvalds 	if (!ret) {
7031da177e4SLinus Torvalds 		hci_dev_hold(hdev);
7041da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
7051da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
706a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
70709fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
708744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
70909fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
71056e5cb86SJohan Hedberg 		}
7111da177e4SLinus Torvalds 	} else {
7121da177e4SLinus Torvalds 		/* Init failed, cleanup */
7133eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
714c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
715b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
7161da177e4SLinus Torvalds 
7171da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
7181da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
7191da177e4SLinus Torvalds 
7201da177e4SLinus Torvalds 		if (hdev->flush)
7211da177e4SLinus Torvalds 			hdev->flush(hdev);
7221da177e4SLinus Torvalds 
7231da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
7241da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
7251da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
7261da177e4SLinus Torvalds 		}
7271da177e4SLinus Torvalds 
7281da177e4SLinus Torvalds 		hdev->close(hdev);
7291da177e4SLinus Torvalds 		hdev->flags = 0;
7301da177e4SLinus Torvalds 	}
7311da177e4SLinus Torvalds 
7321da177e4SLinus Torvalds done:
7331da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7341da177e4SLinus Torvalds 	hci_dev_put(hdev);
7351da177e4SLinus Torvalds 	return ret;
7361da177e4SLinus Torvalds }
7371da177e4SLinus Torvalds 
7381da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
7391da177e4SLinus Torvalds {
7401da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
7411da177e4SLinus Torvalds 
74228b75a89SAndre Guedes 	cancel_work_sync(&hdev->le_scan);
74328b75a89SAndre Guedes 
7441da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
7451da177e4SLinus Torvalds 	hci_req_lock(hdev);
7461da177e4SLinus Torvalds 
7471da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
748b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7491da177e4SLinus Torvalds 		hci_req_unlock(hdev);
7501da177e4SLinus Torvalds 		return 0;
7511da177e4SLinus Torvalds 	}
7521da177e4SLinus Torvalds 
7533eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
7543eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
755b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
7561da177e4SLinus Torvalds 
75716ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
758e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
75916ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
7605e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
76116ab91abSJohan Hedberg 	}
76216ab91abSJohan Hedberg 
763a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
7647d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
7657d78525dSJohan Hedberg 
7667ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
7677ba8b4beSAndre Guedes 
76809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
7691da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
7701da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
77109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7721da177e4SLinus Torvalds 
7731da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
7741da177e4SLinus Torvalds 
7751da177e4SLinus Torvalds 	if (hdev->flush)
7761da177e4SLinus Torvalds 		hdev->flush(hdev);
7771da177e4SLinus Torvalds 
7781da177e4SLinus Torvalds 	/* Reset device */
7791da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7801da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
7818af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
782a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
7831da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
7845f246e89SAndrei Emeltchenko 		__hci_request(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
7851da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
7861da177e4SLinus Torvalds 	}
7871da177e4SLinus Torvalds 
788c347b765SGustavo F. Padovan 	/* flush cmd  work */
789c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
7901da177e4SLinus Torvalds 
7911da177e4SLinus Torvalds 	/* Drop queues */
7921da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
7931da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7941da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
7951da177e4SLinus Torvalds 
7961da177e4SLinus Torvalds 	/* Drop last sent command */
7971da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
798b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7991da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
8001da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
8011da177e4SLinus Torvalds 	}
8021da177e4SLinus Torvalds 
8031da177e4SLinus Torvalds 	/* After this point our queues are empty
8041da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
8051da177e4SLinus Torvalds 	hdev->close(hdev);
8061da177e4SLinus Torvalds 
8078ee56540SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
80809fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
809744cf19eSJohan Hedberg 		mgmt_powered(hdev, 0);
81009fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
8118ee56540SMarcel Holtmann 	}
8125add6af8SJohan Hedberg 
8131da177e4SLinus Torvalds 	/* Clear flags */
8141da177e4SLinus Torvalds 	hdev->flags = 0;
8151da177e4SLinus Torvalds 
816e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
81709b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
818e59fda8dSJohan Hedberg 
8191da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8201da177e4SLinus Torvalds 
8211da177e4SLinus Torvalds 	hci_dev_put(hdev);
8221da177e4SLinus Torvalds 	return 0;
8231da177e4SLinus Torvalds }
8241da177e4SLinus Torvalds 
8251da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
8261da177e4SLinus Torvalds {
8271da177e4SLinus Torvalds 	struct hci_dev *hdev;
8281da177e4SLinus Torvalds 	int err;
8291da177e4SLinus Torvalds 
83070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
83170f23020SAndrei Emeltchenko 	if (!hdev)
8321da177e4SLinus Torvalds 		return -ENODEV;
8338ee56540SMarcel Holtmann 
8348ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
8358ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
8368ee56540SMarcel Holtmann 
8371da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
8388ee56540SMarcel Holtmann 
8391da177e4SLinus Torvalds 	hci_dev_put(hdev);
8401da177e4SLinus Torvalds 	return err;
8411da177e4SLinus Torvalds }
8421da177e4SLinus Torvalds 
8431da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
8441da177e4SLinus Torvalds {
8451da177e4SLinus Torvalds 	struct hci_dev *hdev;
8461da177e4SLinus Torvalds 	int ret = 0;
8471da177e4SLinus Torvalds 
84870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
84970f23020SAndrei Emeltchenko 	if (!hdev)
8501da177e4SLinus Torvalds 		return -ENODEV;
8511da177e4SLinus Torvalds 
8521da177e4SLinus Torvalds 	hci_req_lock(hdev);
8531da177e4SLinus Torvalds 
8541da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
8551da177e4SLinus Torvalds 		goto done;
8561da177e4SLinus Torvalds 
8571da177e4SLinus Torvalds 	/* Drop queues */
8581da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
8591da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
8601da177e4SLinus Torvalds 
86109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
8621da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
8631da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
86409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
8651da177e4SLinus Torvalds 
8661da177e4SLinus Torvalds 	if (hdev->flush)
8671da177e4SLinus Torvalds 		hdev->flush(hdev);
8681da177e4SLinus Torvalds 
8691da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
8706ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
8711da177e4SLinus Torvalds 
8721da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
8735f246e89SAndrei Emeltchenko 		ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
8741da177e4SLinus Torvalds 
8751da177e4SLinus Torvalds done:
8761da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8771da177e4SLinus Torvalds 	hci_dev_put(hdev);
8781da177e4SLinus Torvalds 	return ret;
8791da177e4SLinus Torvalds }
8801da177e4SLinus Torvalds 
8811da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
8821da177e4SLinus Torvalds {
8831da177e4SLinus Torvalds 	struct hci_dev *hdev;
8841da177e4SLinus Torvalds 	int ret = 0;
8851da177e4SLinus Torvalds 
88670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
88770f23020SAndrei Emeltchenko 	if (!hdev)
8881da177e4SLinus Torvalds 		return -ENODEV;
8891da177e4SLinus Torvalds 
8901da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
8911da177e4SLinus Torvalds 
8921da177e4SLinus Torvalds 	hci_dev_put(hdev);
8931da177e4SLinus Torvalds 
8941da177e4SLinus Torvalds 	return ret;
8951da177e4SLinus Torvalds }
8961da177e4SLinus Torvalds 
8971da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
8981da177e4SLinus Torvalds {
8991da177e4SLinus Torvalds 	struct hci_dev *hdev;
9001da177e4SLinus Torvalds 	struct hci_dev_req dr;
9011da177e4SLinus Torvalds 	int err = 0;
9021da177e4SLinus Torvalds 
9031da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
9041da177e4SLinus Torvalds 		return -EFAULT;
9051da177e4SLinus Torvalds 
90670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
90770f23020SAndrei Emeltchenko 	if (!hdev)
9081da177e4SLinus Torvalds 		return -ENODEV;
9091da177e4SLinus Torvalds 
9101da177e4SLinus Torvalds 	switch (cmd) {
9111da177e4SLinus Torvalds 	case HCISETAUTH:
91204837f64SMarcel Holtmann 		err = hci_request(hdev, hci_auth_req, dr.dev_opt,
9135f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
9141da177e4SLinus Torvalds 		break;
9151da177e4SLinus Torvalds 
9161da177e4SLinus Torvalds 	case HCISETENCRYPT:
9171da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
9181da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
9191da177e4SLinus Torvalds 			break;
9201da177e4SLinus Torvalds 		}
9211da177e4SLinus Torvalds 
9221da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
9231da177e4SLinus Torvalds 			/* Auth must be enabled first */
92404837f64SMarcel Holtmann 			err = hci_request(hdev, hci_auth_req, dr.dev_opt,
9255f246e89SAndrei Emeltchenko 					  HCI_INIT_TIMEOUT);
9261da177e4SLinus Torvalds 			if (err)
9271da177e4SLinus Torvalds 				break;
9281da177e4SLinus Torvalds 		}
9291da177e4SLinus Torvalds 
93004837f64SMarcel Holtmann 		err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
9315f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
9321da177e4SLinus Torvalds 		break;
9331da177e4SLinus Torvalds 
9341da177e4SLinus Torvalds 	case HCISETSCAN:
93504837f64SMarcel Holtmann 		err = hci_request(hdev, hci_scan_req, dr.dev_opt,
9365f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
9371da177e4SLinus Torvalds 		break;
9381da177e4SLinus Torvalds 
9391da177e4SLinus Torvalds 	case HCISETLINKPOL:
940e4e8e37cSMarcel Holtmann 		err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
9415f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
9421da177e4SLinus Torvalds 		break;
9431da177e4SLinus Torvalds 
9441da177e4SLinus Torvalds 	case HCISETLINKMODE:
945e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
946e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
947e4e8e37cSMarcel Holtmann 		break;
948e4e8e37cSMarcel Holtmann 
949e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
950e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
9511da177e4SLinus Torvalds 		break;
9521da177e4SLinus Torvalds 
9531da177e4SLinus Torvalds 	case HCISETACLMTU:
9541da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
9551da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
9561da177e4SLinus Torvalds 		break;
9571da177e4SLinus Torvalds 
9581da177e4SLinus Torvalds 	case HCISETSCOMTU:
9591da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
9601da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
9611da177e4SLinus Torvalds 		break;
9621da177e4SLinus Torvalds 
9631da177e4SLinus Torvalds 	default:
9641da177e4SLinus Torvalds 		err = -EINVAL;
9651da177e4SLinus Torvalds 		break;
9661da177e4SLinus Torvalds 	}
967e4e8e37cSMarcel Holtmann 
9681da177e4SLinus Torvalds 	hci_dev_put(hdev);
9691da177e4SLinus Torvalds 	return err;
9701da177e4SLinus Torvalds }
9711da177e4SLinus Torvalds 
9721da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
9731da177e4SLinus Torvalds {
9748035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
9751da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
9761da177e4SLinus Torvalds 	struct hci_dev_req *dr;
9771da177e4SLinus Torvalds 	int n = 0, size, err;
9781da177e4SLinus Torvalds 	__u16 dev_num;
9791da177e4SLinus Torvalds 
9801da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
9811da177e4SLinus Torvalds 		return -EFAULT;
9821da177e4SLinus Torvalds 
9831da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
9841da177e4SLinus Torvalds 		return -EINVAL;
9851da177e4SLinus Torvalds 
9861da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
9871da177e4SLinus Torvalds 
98870f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
98970f23020SAndrei Emeltchenko 	if (!dl)
9901da177e4SLinus Torvalds 		return -ENOMEM;
9911da177e4SLinus Torvalds 
9921da177e4SLinus Torvalds 	dr = dl->dev_req;
9931da177e4SLinus Torvalds 
994f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
9958035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
996a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
997e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
998c542a06cSJohan Hedberg 
999a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1000a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1001c542a06cSJohan Hedberg 
10021da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
10031da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
1004c542a06cSJohan Hedberg 
10051da177e4SLinus Torvalds 		if (++n >= dev_num)
10061da177e4SLinus Torvalds 			break;
10071da177e4SLinus Torvalds 	}
1008f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
10091da177e4SLinus Torvalds 
10101da177e4SLinus Torvalds 	dl->dev_num = n;
10111da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
10121da177e4SLinus Torvalds 
10131da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
10141da177e4SLinus Torvalds 	kfree(dl);
10151da177e4SLinus Torvalds 
10161da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
10171da177e4SLinus Torvalds }
10181da177e4SLinus Torvalds 
10191da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
10201da177e4SLinus Torvalds {
10211da177e4SLinus Torvalds 	struct hci_dev *hdev;
10221da177e4SLinus Torvalds 	struct hci_dev_info di;
10231da177e4SLinus Torvalds 	int err = 0;
10241da177e4SLinus Torvalds 
10251da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
10261da177e4SLinus Torvalds 		return -EFAULT;
10271da177e4SLinus Torvalds 
102870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
102970f23020SAndrei Emeltchenko 	if (!hdev)
10301da177e4SLinus Torvalds 		return -ENODEV;
10311da177e4SLinus Torvalds 
1032a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
10333243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1034ab81cbf9SJohan Hedberg 
1035a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1036a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1037c542a06cSJohan Hedberg 
10381da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
10391da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
1040943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
10411da177e4SLinus Torvalds 	di.flags    = hdev->flags;
10421da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
10431da177e4SLinus Torvalds 	di.acl_mtu  = hdev->acl_mtu;
10441da177e4SLinus Torvalds 	di.acl_pkts = hdev->acl_pkts;
10451da177e4SLinus Torvalds 	di.sco_mtu  = hdev->sco_mtu;
10461da177e4SLinus Torvalds 	di.sco_pkts = hdev->sco_pkts;
10471da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
10481da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
10491da177e4SLinus Torvalds 
10501da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
10511da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
10521da177e4SLinus Torvalds 
10531da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
10541da177e4SLinus Torvalds 		err = -EFAULT;
10551da177e4SLinus Torvalds 
10561da177e4SLinus Torvalds 	hci_dev_put(hdev);
10571da177e4SLinus Torvalds 
10581da177e4SLinus Torvalds 	return err;
10591da177e4SLinus Torvalds }
10601da177e4SLinus Torvalds 
10611da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
10621da177e4SLinus Torvalds 
1063611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1064611b30f7SMarcel Holtmann {
1065611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1066611b30f7SMarcel Holtmann 
1067611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1068611b30f7SMarcel Holtmann 
1069611b30f7SMarcel Holtmann 	if (!blocked)
1070611b30f7SMarcel Holtmann 		return 0;
1071611b30f7SMarcel Holtmann 
1072611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1073611b30f7SMarcel Holtmann 
1074611b30f7SMarcel Holtmann 	return 0;
1075611b30f7SMarcel Holtmann }
1076611b30f7SMarcel Holtmann 
1077611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1078611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1079611b30f7SMarcel Holtmann };
1080611b30f7SMarcel Holtmann 
1081ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1082ab81cbf9SJohan Hedberg {
1083ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
1084ab81cbf9SJohan Hedberg 
1085ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1086ab81cbf9SJohan Hedberg 
1087ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
1088ab81cbf9SJohan Hedberg 		return;
1089ab81cbf9SJohan Hedberg 
1090a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
109180b7ab33SGustavo F. Padovan 		schedule_delayed_work(&hdev->power_off,
10923243553fSJohan Hedberg 				      msecs_to_jiffies(AUTO_OFF_TIMEOUT));
1093ab81cbf9SJohan Hedberg 
1094a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1095744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1096ab81cbf9SJohan Hedberg }
1097ab81cbf9SJohan Hedberg 
1098ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1099ab81cbf9SJohan Hedberg {
11003243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
11013243553fSJohan Hedberg 					    power_off.work);
1102ab81cbf9SJohan Hedberg 
1103ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1104ab81cbf9SJohan Hedberg 
11058ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1106ab81cbf9SJohan Hedberg }
1107ab81cbf9SJohan Hedberg 
110816ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
110916ab91abSJohan Hedberg {
111016ab91abSJohan Hedberg 	struct hci_dev *hdev;
111116ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
111216ab91abSJohan Hedberg 
111316ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
111416ab91abSJohan Hedberg 
111516ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
111616ab91abSJohan Hedberg 
111709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
111816ab91abSJohan Hedberg 
111916ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
112016ab91abSJohan Hedberg 
112116ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
112216ab91abSJohan Hedberg 
112309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
112416ab91abSJohan Hedberg }
112516ab91abSJohan Hedberg 
11262aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
11272aeb9a1aSJohan Hedberg {
11282aeb9a1aSJohan Hedberg 	struct list_head *p, *n;
11292aeb9a1aSJohan Hedberg 
11302aeb9a1aSJohan Hedberg 	list_for_each_safe(p, n, &hdev->uuids) {
11312aeb9a1aSJohan Hedberg 		struct bt_uuid *uuid;
11322aeb9a1aSJohan Hedberg 
11332aeb9a1aSJohan Hedberg 		uuid = list_entry(p, struct bt_uuid, list);
11342aeb9a1aSJohan Hedberg 
11352aeb9a1aSJohan Hedberg 		list_del(p);
11362aeb9a1aSJohan Hedberg 		kfree(uuid);
11372aeb9a1aSJohan Hedberg 	}
11382aeb9a1aSJohan Hedberg 
11392aeb9a1aSJohan Hedberg 	return 0;
11402aeb9a1aSJohan Hedberg }
11412aeb9a1aSJohan Hedberg 
114255ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
114355ed8ca1SJohan Hedberg {
114455ed8ca1SJohan Hedberg 	struct list_head *p, *n;
114555ed8ca1SJohan Hedberg 
114655ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
114755ed8ca1SJohan Hedberg 		struct link_key *key;
114855ed8ca1SJohan Hedberg 
114955ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
115055ed8ca1SJohan Hedberg 
115155ed8ca1SJohan Hedberg 		list_del(p);
115255ed8ca1SJohan Hedberg 		kfree(key);
115355ed8ca1SJohan Hedberg 	}
115455ed8ca1SJohan Hedberg 
115555ed8ca1SJohan Hedberg 	return 0;
115655ed8ca1SJohan Hedberg }
115755ed8ca1SJohan Hedberg 
1158b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1159b899efafSVinicius Costa Gomes {
1160b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1161b899efafSVinicius Costa Gomes 
1162b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1163b899efafSVinicius Costa Gomes 		list_del(&k->list);
1164b899efafSVinicius Costa Gomes 		kfree(k);
1165b899efafSVinicius Costa Gomes 	}
1166b899efafSVinicius Costa Gomes 
1167b899efafSVinicius Costa Gomes 	return 0;
1168b899efafSVinicius Costa Gomes }
1169b899efafSVinicius Costa Gomes 
117055ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
117155ed8ca1SJohan Hedberg {
117255ed8ca1SJohan Hedberg 	struct link_key *k;
117355ed8ca1SJohan Hedberg 
11748035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
117555ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
117655ed8ca1SJohan Hedberg 			return k;
117755ed8ca1SJohan Hedberg 
117855ed8ca1SJohan Hedberg 	return NULL;
117955ed8ca1SJohan Hedberg }
118055ed8ca1SJohan Hedberg 
1181745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1182d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1183d25e28abSJohan Hedberg {
1184d25e28abSJohan Hedberg 	/* Legacy key */
1185d25e28abSJohan Hedberg 	if (key_type < 0x03)
1186745c0ce3SVishal Agarwal 		return true;
1187d25e28abSJohan Hedberg 
1188d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1189d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1190745c0ce3SVishal Agarwal 		return false;
1191d25e28abSJohan Hedberg 
1192d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1193d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1194745c0ce3SVishal Agarwal 		return false;
1195d25e28abSJohan Hedberg 
1196d25e28abSJohan Hedberg 	/* Security mode 3 case */
1197d25e28abSJohan Hedberg 	if (!conn)
1198745c0ce3SVishal Agarwal 		return true;
1199d25e28abSJohan Hedberg 
1200d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1201d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1202745c0ce3SVishal Agarwal 		return true;
1203d25e28abSJohan Hedberg 
1204d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1205d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1206745c0ce3SVishal Agarwal 		return true;
1207d25e28abSJohan Hedberg 
1208d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1209d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1210745c0ce3SVishal Agarwal 		return true;
1211d25e28abSJohan Hedberg 
1212d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1213d25e28abSJohan Hedberg 	 * persistently */
1214745c0ce3SVishal Agarwal 	return false;
1215d25e28abSJohan Hedberg }
1216d25e28abSJohan Hedberg 
1217c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
121875d262c2SVinicius Costa Gomes {
1219c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
122075d262c2SVinicius Costa Gomes 
1221c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1222c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1223c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
122475d262c2SVinicius Costa Gomes 			continue;
122575d262c2SVinicius Costa Gomes 
122675d262c2SVinicius Costa Gomes 		return k;
122775d262c2SVinicius Costa Gomes 	}
122875d262c2SVinicius Costa Gomes 
122975d262c2SVinicius Costa Gomes 	return NULL;
123075d262c2SVinicius Costa Gomes }
123175d262c2SVinicius Costa Gomes 
1232c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1233c9839a11SVinicius Costa Gomes 				     u8 addr_type)
123475d262c2SVinicius Costa Gomes {
1235c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
123675d262c2SVinicius Costa Gomes 
1237c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1238c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1239c9839a11SVinicius Costa Gomes 		    bacmp(bdaddr, &k->bdaddr) == 0)
124075d262c2SVinicius Costa Gomes 			return k;
124175d262c2SVinicius Costa Gomes 
124275d262c2SVinicius Costa Gomes 	return NULL;
124375d262c2SVinicius Costa Gomes }
124475d262c2SVinicius Costa Gomes 
1245d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1246d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
124755ed8ca1SJohan Hedberg {
124855ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1249745c0ce3SVishal Agarwal 	u8 old_key_type;
1250745c0ce3SVishal Agarwal 	bool persistent;
125155ed8ca1SJohan Hedberg 
125255ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
125355ed8ca1SJohan Hedberg 	if (old_key) {
125455ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
125555ed8ca1SJohan Hedberg 		key = old_key;
125655ed8ca1SJohan Hedberg 	} else {
125712adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
125855ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
125955ed8ca1SJohan Hedberg 		if (!key)
126055ed8ca1SJohan Hedberg 			return -ENOMEM;
126155ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
126255ed8ca1SJohan Hedberg 	}
126355ed8ca1SJohan Hedberg 
126455ed8ca1SJohan Hedberg 	BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
126555ed8ca1SJohan Hedberg 
1266d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1267d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1268d25e28abSJohan Hedberg 	 * previous key */
1269d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1270a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1271d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1272655fe6ecSJohan Hedberg 		if (conn)
1273655fe6ecSJohan Hedberg 			conn->key_type = type;
1274655fe6ecSJohan Hedberg 	}
1275d25e28abSJohan Hedberg 
127655ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
12779b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
127855ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
127955ed8ca1SJohan Hedberg 
1280b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
128155ed8ca1SJohan Hedberg 		key->type = old_key_type;
12824748fed2SJohan Hedberg 	else
12834748fed2SJohan Hedberg 		key->type = type;
12844748fed2SJohan Hedberg 
12854df378a1SJohan Hedberg 	if (!new_key)
12864df378a1SJohan Hedberg 		return 0;
12874df378a1SJohan Hedberg 
12884df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
12894df378a1SJohan Hedberg 
1290744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
12914df378a1SJohan Hedberg 
12926ec5bcadSVishal Agarwal 	if (conn)
12936ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
129455ed8ca1SJohan Hedberg 
129555ed8ca1SJohan Hedberg 	return 0;
129655ed8ca1SJohan Hedberg }
129755ed8ca1SJohan Hedberg 
1298c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
12999a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
130004124681SGustavo F. Padovan 		ediv, u8 rand[8])
130175d262c2SVinicius Costa Gomes {
1302c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
130375d262c2SVinicius Costa Gomes 
1304c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1305c9839a11SVinicius Costa Gomes 		return 0;
130675d262c2SVinicius Costa Gomes 
1307c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1308c9839a11SVinicius Costa Gomes 	if (old_key)
130975d262c2SVinicius Costa Gomes 		key = old_key;
1310c9839a11SVinicius Costa Gomes 	else {
1311c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
131275d262c2SVinicius Costa Gomes 		if (!key)
131375d262c2SVinicius Costa Gomes 			return -ENOMEM;
1314c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
131575d262c2SVinicius Costa Gomes 	}
131675d262c2SVinicius Costa Gomes 
131775d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1318c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1319c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1320c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1321c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1322c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1323c9839a11SVinicius Costa Gomes 	key->type = type;
1324c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
132575d262c2SVinicius Costa Gomes 
1326c9839a11SVinicius Costa Gomes 	if (!new_key)
1327c9839a11SVinicius Costa Gomes 		return 0;
132875d262c2SVinicius Costa Gomes 
1329261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1330261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1331261cc5aaSVinicius Costa Gomes 
133275d262c2SVinicius Costa Gomes 	return 0;
133375d262c2SVinicius Costa Gomes }
133475d262c2SVinicius Costa Gomes 
133555ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
133655ed8ca1SJohan Hedberg {
133755ed8ca1SJohan Hedberg 	struct link_key *key;
133855ed8ca1SJohan Hedberg 
133955ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
134055ed8ca1SJohan Hedberg 	if (!key)
134155ed8ca1SJohan Hedberg 		return -ENOENT;
134255ed8ca1SJohan Hedberg 
134355ed8ca1SJohan Hedberg 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
134455ed8ca1SJohan Hedberg 
134555ed8ca1SJohan Hedberg 	list_del(&key->list);
134655ed8ca1SJohan Hedberg 	kfree(key);
134755ed8ca1SJohan Hedberg 
134855ed8ca1SJohan Hedberg 	return 0;
134955ed8ca1SJohan Hedberg }
135055ed8ca1SJohan Hedberg 
1351b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1352b899efafSVinicius Costa Gomes {
1353b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1354b899efafSVinicius Costa Gomes 
1355b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1356b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1357b899efafSVinicius Costa Gomes 			continue;
1358b899efafSVinicius Costa Gomes 
1359b899efafSVinicius Costa Gomes 		BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
1360b899efafSVinicius Costa Gomes 
1361b899efafSVinicius Costa Gomes 		list_del(&k->list);
1362b899efafSVinicius Costa Gomes 		kfree(k);
1363b899efafSVinicius Costa Gomes 	}
1364b899efafSVinicius Costa Gomes 
1365b899efafSVinicius Costa Gomes 	return 0;
1366b899efafSVinicius Costa Gomes }
1367b899efafSVinicius Costa Gomes 
13686bd32326SVille Tervo /* HCI command timer function */
1369bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
13706bd32326SVille Tervo {
13716bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
13726bd32326SVille Tervo 
1373bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
1374bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
1375bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
1376bda4f23aSAndrei Emeltchenko 
1377bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
1378bda4f23aSAndrei Emeltchenko 	} else {
13796bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
1380bda4f23aSAndrei Emeltchenko 	}
1381bda4f23aSAndrei Emeltchenko 
13826bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1383c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
13846bd32326SVille Tervo }
13856bd32326SVille Tervo 
13862763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
13872763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
13882763eda6SSzymon Janc {
13892763eda6SSzymon Janc 	struct oob_data *data;
13902763eda6SSzymon Janc 
13912763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
13922763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
13932763eda6SSzymon Janc 			return data;
13942763eda6SSzymon Janc 
13952763eda6SSzymon Janc 	return NULL;
13962763eda6SSzymon Janc }
13972763eda6SSzymon Janc 
13982763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
13992763eda6SSzymon Janc {
14002763eda6SSzymon Janc 	struct oob_data *data;
14012763eda6SSzymon Janc 
14022763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
14032763eda6SSzymon Janc 	if (!data)
14042763eda6SSzymon Janc 		return -ENOENT;
14052763eda6SSzymon Janc 
14062763eda6SSzymon Janc 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
14072763eda6SSzymon Janc 
14082763eda6SSzymon Janc 	list_del(&data->list);
14092763eda6SSzymon Janc 	kfree(data);
14102763eda6SSzymon Janc 
14112763eda6SSzymon Janc 	return 0;
14122763eda6SSzymon Janc }
14132763eda6SSzymon Janc 
14142763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
14152763eda6SSzymon Janc {
14162763eda6SSzymon Janc 	struct oob_data *data, *n;
14172763eda6SSzymon Janc 
14182763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
14192763eda6SSzymon Janc 		list_del(&data->list);
14202763eda6SSzymon Janc 		kfree(data);
14212763eda6SSzymon Janc 	}
14222763eda6SSzymon Janc 
14232763eda6SSzymon Janc 	return 0;
14242763eda6SSzymon Janc }
14252763eda6SSzymon Janc 
14262763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
14272763eda6SSzymon Janc 			    u8 *randomizer)
14282763eda6SSzymon Janc {
14292763eda6SSzymon Janc 	struct oob_data *data;
14302763eda6SSzymon Janc 
14312763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
14322763eda6SSzymon Janc 
14332763eda6SSzymon Janc 	if (!data) {
14342763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
14352763eda6SSzymon Janc 		if (!data)
14362763eda6SSzymon Janc 			return -ENOMEM;
14372763eda6SSzymon Janc 
14382763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
14392763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
14402763eda6SSzymon Janc 	}
14412763eda6SSzymon Janc 
14422763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
14432763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
14442763eda6SSzymon Janc 
14452763eda6SSzymon Janc 	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
14462763eda6SSzymon Janc 
14472763eda6SSzymon Janc 	return 0;
14482763eda6SSzymon Janc }
14492763eda6SSzymon Janc 
145004124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
1451b2a66aadSAntti Julku {
1452b2a66aadSAntti Julku 	struct bdaddr_list *b;
1453b2a66aadSAntti Julku 
14548035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1455b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1456b2a66aadSAntti Julku 			return b;
1457b2a66aadSAntti Julku 
1458b2a66aadSAntti Julku 	return NULL;
1459b2a66aadSAntti Julku }
1460b2a66aadSAntti Julku 
1461b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1462b2a66aadSAntti Julku {
1463b2a66aadSAntti Julku 	struct list_head *p, *n;
1464b2a66aadSAntti Julku 
1465b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1466b2a66aadSAntti Julku 		struct bdaddr_list *b;
1467b2a66aadSAntti Julku 
1468b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1469b2a66aadSAntti Julku 
1470b2a66aadSAntti Julku 		list_del(p);
1471b2a66aadSAntti Julku 		kfree(b);
1472b2a66aadSAntti Julku 	}
1473b2a66aadSAntti Julku 
1474b2a66aadSAntti Julku 	return 0;
1475b2a66aadSAntti Julku }
1476b2a66aadSAntti Julku 
147788c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1478b2a66aadSAntti Julku {
1479b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1480b2a66aadSAntti Julku 
1481b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1482b2a66aadSAntti Julku 		return -EBADF;
1483b2a66aadSAntti Julku 
14845e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
14855e762444SAntti Julku 		return -EEXIST;
1486b2a66aadSAntti Julku 
1487b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
14885e762444SAntti Julku 	if (!entry)
14895e762444SAntti Julku 		return -ENOMEM;
1490b2a66aadSAntti Julku 
1491b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1492b2a66aadSAntti Julku 
1493b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1494b2a66aadSAntti Julku 
149588c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
1496b2a66aadSAntti Julku }
1497b2a66aadSAntti Julku 
149888c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1499b2a66aadSAntti Julku {
1500b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1501b2a66aadSAntti Julku 
15021ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
15035e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1504b2a66aadSAntti Julku 
1505b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
15061ec918ceSSzymon Janc 	if (!entry)
15075e762444SAntti Julku 		return -ENOENT;
1508b2a66aadSAntti Julku 
1509b2a66aadSAntti Julku 	list_del(&entry->list);
1510b2a66aadSAntti Julku 	kfree(entry);
1511b2a66aadSAntti Julku 
151288c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
1513b2a66aadSAntti Julku }
1514b2a66aadSAntti Julku 
15157ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt)
15167ba8b4beSAndre Guedes {
15177ba8b4beSAndre Guedes 	struct le_scan_params *param =  (struct le_scan_params *) opt;
15187ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_param cp;
15197ba8b4beSAndre Guedes 
15207ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
15217ba8b4beSAndre Guedes 	cp.type = param->type;
15227ba8b4beSAndre Guedes 	cp.interval = cpu_to_le16(param->interval);
15237ba8b4beSAndre Guedes 	cp.window = cpu_to_le16(param->window);
15247ba8b4beSAndre Guedes 
15257ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
15267ba8b4beSAndre Guedes }
15277ba8b4beSAndre Guedes 
15287ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt)
15297ba8b4beSAndre Guedes {
15307ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
15317ba8b4beSAndre Guedes 
15327ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
15337ba8b4beSAndre Guedes 	cp.enable = 1;
15340431a43cSAndre Guedes 	cp.filter_dup = 1;
15357ba8b4beSAndre Guedes 
15367ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
15377ba8b4beSAndre Guedes }
15387ba8b4beSAndre Guedes 
15397ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
15407ba8b4beSAndre Guedes 			  u16 window, int timeout)
15417ba8b4beSAndre Guedes {
15427ba8b4beSAndre Guedes 	long timeo = msecs_to_jiffies(3000);
15437ba8b4beSAndre Guedes 	struct le_scan_params param;
15447ba8b4beSAndre Guedes 	int err;
15457ba8b4beSAndre Guedes 
15467ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
15477ba8b4beSAndre Guedes 
15487ba8b4beSAndre Guedes 	if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
15497ba8b4beSAndre Guedes 		return -EINPROGRESS;
15507ba8b4beSAndre Guedes 
15517ba8b4beSAndre Guedes 	param.type = type;
15527ba8b4beSAndre Guedes 	param.interval = interval;
15537ba8b4beSAndre Guedes 	param.window = window;
15547ba8b4beSAndre Guedes 
15557ba8b4beSAndre Guedes 	hci_req_lock(hdev);
15567ba8b4beSAndre Guedes 
15577ba8b4beSAndre Guedes 	err = __hci_request(hdev, le_scan_param_req, (unsigned long) &param,
15587ba8b4beSAndre Guedes 			    timeo);
15597ba8b4beSAndre Guedes 	if (!err)
15607ba8b4beSAndre Guedes 		err = __hci_request(hdev, le_scan_enable_req, 0, timeo);
15617ba8b4beSAndre Guedes 
15627ba8b4beSAndre Guedes 	hci_req_unlock(hdev);
15637ba8b4beSAndre Guedes 
15647ba8b4beSAndre Guedes 	if (err < 0)
15657ba8b4beSAndre Guedes 		return err;
15667ba8b4beSAndre Guedes 
15677ba8b4beSAndre Guedes 	schedule_delayed_work(&hdev->le_scan_disable,
15687ba8b4beSAndre Guedes 			      msecs_to_jiffies(timeout));
15697ba8b4beSAndre Guedes 
15707ba8b4beSAndre Guedes 	return 0;
15717ba8b4beSAndre Guedes }
15727ba8b4beSAndre Guedes 
15737dbfac1dSAndre Guedes int hci_cancel_le_scan(struct hci_dev *hdev)
15747dbfac1dSAndre Guedes {
15757dbfac1dSAndre Guedes 	BT_DBG("%s", hdev->name);
15767dbfac1dSAndre Guedes 
15777dbfac1dSAndre Guedes 	if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
15787dbfac1dSAndre Guedes 		return -EALREADY;
15797dbfac1dSAndre Guedes 
15807dbfac1dSAndre Guedes 	if (cancel_delayed_work(&hdev->le_scan_disable)) {
15817dbfac1dSAndre Guedes 		struct hci_cp_le_set_scan_enable cp;
15827dbfac1dSAndre Guedes 
15837dbfac1dSAndre Guedes 		/* Send HCI command to disable LE Scan */
15847dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
15857dbfac1dSAndre Guedes 		hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
15867dbfac1dSAndre Guedes 	}
15877dbfac1dSAndre Guedes 
15887dbfac1dSAndre Guedes 	return 0;
15897dbfac1dSAndre Guedes }
15907dbfac1dSAndre Guedes 
15917ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
15927ba8b4beSAndre Guedes {
15937ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
15947ba8b4beSAndre Guedes 					    le_scan_disable.work);
15957ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
15967ba8b4beSAndre Guedes 
15977ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
15987ba8b4beSAndre Guedes 
15997ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
16007ba8b4beSAndre Guedes 
16017ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
16027ba8b4beSAndre Guedes }
16037ba8b4beSAndre Guedes 
160428b75a89SAndre Guedes static void le_scan_work(struct work_struct *work)
160528b75a89SAndre Guedes {
160628b75a89SAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
160728b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
160828b75a89SAndre Guedes 
160928b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
161028b75a89SAndre Guedes 
161104124681SGustavo F. Padovan 	hci_do_le_scan(hdev, param->type, param->interval, param->window,
161204124681SGustavo F. Padovan 		       param->timeout);
161328b75a89SAndre Guedes }
161428b75a89SAndre Guedes 
161528b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
161628b75a89SAndre Guedes 		int timeout)
161728b75a89SAndre Guedes {
161828b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
161928b75a89SAndre Guedes 
162028b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
162128b75a89SAndre Guedes 
162228b75a89SAndre Guedes 	if (work_busy(&hdev->le_scan))
162328b75a89SAndre Guedes 		return -EINPROGRESS;
162428b75a89SAndre Guedes 
162528b75a89SAndre Guedes 	param->type = type;
162628b75a89SAndre Guedes 	param->interval = interval;
162728b75a89SAndre Guedes 	param->window = window;
162828b75a89SAndre Guedes 	param->timeout = timeout;
162928b75a89SAndre Guedes 
163028b75a89SAndre Guedes 	queue_work(system_long_wq, &hdev->le_scan);
163128b75a89SAndre Guedes 
163228b75a89SAndre Guedes 	return 0;
163328b75a89SAndre Guedes }
163428b75a89SAndre Guedes 
16359be0dab7SDavid Herrmann /* Alloc HCI device */
16369be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
16379be0dab7SDavid Herrmann {
16389be0dab7SDavid Herrmann 	struct hci_dev *hdev;
16399be0dab7SDavid Herrmann 
16409be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
16419be0dab7SDavid Herrmann 	if (!hdev)
16429be0dab7SDavid Herrmann 		return NULL;
16439be0dab7SDavid Herrmann 
1644b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
1645b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
1646b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
1647b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03; /* No Input No Output */
1648b1b813d4SDavid Herrmann 
1649b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
1650b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
1651b1b813d4SDavid Herrmann 
1652b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
1653b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
1654b1b813d4SDavid Herrmann 
1655b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
1656b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
1657b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
1658b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
1659b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
1660b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
1661b1b813d4SDavid Herrmann 
1662b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1663b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
1664b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
1665b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
1666b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->le_scan, le_scan_work);
1667b1b813d4SDavid Herrmann 
1668b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
1669b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
1670b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
1671b1b813d4SDavid Herrmann 
16729be0dab7SDavid Herrmann 	skb_queue_head_init(&hdev->driver_init);
1673b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
1674b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
1675b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
1676b1b813d4SDavid Herrmann 
1677b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
1678b1b813d4SDavid Herrmann 
1679bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
1680b1b813d4SDavid Herrmann 
1681b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
1682b1b813d4SDavid Herrmann 	discovery_init(hdev);
1683b1b813d4SDavid Herrmann 	hci_conn_hash_init(hdev);
16849be0dab7SDavid Herrmann 
16859be0dab7SDavid Herrmann 	return hdev;
16869be0dab7SDavid Herrmann }
16879be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
16889be0dab7SDavid Herrmann 
16899be0dab7SDavid Herrmann /* Free HCI device */
16909be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
16919be0dab7SDavid Herrmann {
16929be0dab7SDavid Herrmann 	skb_queue_purge(&hdev->driver_init);
16939be0dab7SDavid Herrmann 
16949be0dab7SDavid Herrmann 	/* will free via device release */
16959be0dab7SDavid Herrmann 	put_device(&hdev->dev);
16969be0dab7SDavid Herrmann }
16979be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
16989be0dab7SDavid Herrmann 
16991da177e4SLinus Torvalds /* Register HCI device */
17001da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
17011da177e4SLinus Torvalds {
1702b1b813d4SDavid Herrmann 	int id, error;
17031da177e4SLinus Torvalds 
1704010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
17051da177e4SLinus Torvalds 		return -EINVAL;
17061da177e4SLinus Torvalds 
170708add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
170808add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
170908add513SMat Martineau 	 */
17103df92b31SSasha Levin 	switch (hdev->dev_type) {
17113df92b31SSasha Levin 	case HCI_BREDR:
17123df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
17131da177e4SLinus Torvalds 		break;
17143df92b31SSasha Levin 	case HCI_AMP:
17153df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
17163df92b31SSasha Levin 		break;
17173df92b31SSasha Levin 	default:
17183df92b31SSasha Levin 		return -EINVAL;
17191da177e4SLinus Torvalds 	}
17201da177e4SLinus Torvalds 
17213df92b31SSasha Levin 	if (id < 0)
17223df92b31SSasha Levin 		return id;
17233df92b31SSasha Levin 
17241da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
17251da177e4SLinus Torvalds 	hdev->id = id;
17262d8b3a11SAndrei Emeltchenko 
17272d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
17282d8b3a11SAndrei Emeltchenko 
17293df92b31SSasha Levin 	write_lock(&hci_dev_list_lock);
17303df92b31SSasha Levin 	list_add(&hdev->list, &hci_dev_list);
1731f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
17321da177e4SLinus Torvalds 
173332845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
173432845eb1SGustavo F. Padovan 					  WQ_MEM_RECLAIM, 1);
173533ca954dSDavid Herrmann 	if (!hdev->workqueue) {
173633ca954dSDavid Herrmann 		error = -ENOMEM;
173733ca954dSDavid Herrmann 		goto err;
173833ca954dSDavid Herrmann 	}
1739f48fd9c8SMarcel Holtmann 
174033ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
174133ca954dSDavid Herrmann 	if (error < 0)
174233ca954dSDavid Herrmann 		goto err_wqueue;
17431da177e4SLinus Torvalds 
1744611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1745a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
1746a8c5fb1aSGustavo Padovan 				    hdev);
1747611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1748611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
1749611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
1750611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
1751611b30f7SMarcel Holtmann 		}
1752611b30f7SMarcel Holtmann 	}
1753611b30f7SMarcel Holtmann 
1754a8b2d5c2SJohan Hedberg 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
1755a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
17567f971041SGustavo F. Padovan 	schedule_work(&hdev->power_on);
1757ab81cbf9SJohan Hedberg 
17581da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
1759dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
17601da177e4SLinus Torvalds 
17611da177e4SLinus Torvalds 	return id;
1762f48fd9c8SMarcel Holtmann 
176333ca954dSDavid Herrmann err_wqueue:
176433ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
176533ca954dSDavid Herrmann err:
17663df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
1767f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
1768f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
1769f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
1770f48fd9c8SMarcel Holtmann 
177133ca954dSDavid Herrmann 	return error;
17721da177e4SLinus Torvalds }
17731da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
17741da177e4SLinus Torvalds 
17751da177e4SLinus Torvalds /* Unregister HCI device */
177659735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
17771da177e4SLinus Torvalds {
17783df92b31SSasha Levin 	int i, id;
1779ef222013SMarcel Holtmann 
1780c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
17811da177e4SLinus Torvalds 
178294324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
178394324962SJohan Hovold 
17843df92b31SSasha Levin 	id = hdev->id;
17853df92b31SSasha Levin 
1786f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
17871da177e4SLinus Torvalds 	list_del(&hdev->list);
1788f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
17891da177e4SLinus Torvalds 
17901da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
17911da177e4SLinus Torvalds 
1792cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1793ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
1794ef222013SMarcel Holtmann 
1795ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
1796a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
179709fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1798744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
179909fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
180056e5cb86SJohan Hedberg 	}
1801ab81cbf9SJohan Hedberg 
18022e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
18032e58ef3eSJohan Hedberg 	 * pending list */
18042e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
18052e58ef3eSJohan Hedberg 
18061da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
18071da177e4SLinus Torvalds 
1808611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1809611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
1810611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
1811611b30f7SMarcel Holtmann 	}
1812611b30f7SMarcel Holtmann 
1813ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
1814147e2d59SDave Young 
1815f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
1816f48fd9c8SMarcel Holtmann 
181709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
1818e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
18192aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
182055ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
1821b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
18222763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
182309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
1824e2e0cacbSJohan Hedberg 
1825dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
18263df92b31SSasha Levin 
18273df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
18281da177e4SLinus Torvalds }
18291da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
18301da177e4SLinus Torvalds 
18311da177e4SLinus Torvalds /* Suspend HCI device */
18321da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
18331da177e4SLinus Torvalds {
18341da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
18351da177e4SLinus Torvalds 	return 0;
18361da177e4SLinus Torvalds }
18371da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
18381da177e4SLinus Torvalds 
18391da177e4SLinus Torvalds /* Resume HCI device */
18401da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
18411da177e4SLinus Torvalds {
18421da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
18431da177e4SLinus Torvalds 	return 0;
18441da177e4SLinus Torvalds }
18451da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
18461da177e4SLinus Torvalds 
184776bca880SMarcel Holtmann /* Receive frame from HCI drivers */
184876bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
184976bca880SMarcel Holtmann {
185076bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
185176bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
185276bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
185376bca880SMarcel Holtmann 		kfree_skb(skb);
185476bca880SMarcel Holtmann 		return -ENXIO;
185576bca880SMarcel Holtmann 	}
185676bca880SMarcel Holtmann 
185776bca880SMarcel Holtmann 	/* Incomming skb */
185876bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
185976bca880SMarcel Holtmann 
186076bca880SMarcel Holtmann 	/* Time stamp */
186176bca880SMarcel Holtmann 	__net_timestamp(skb);
186276bca880SMarcel Holtmann 
186376bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
1864b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
1865c78ae283SMarcel Holtmann 
186676bca880SMarcel Holtmann 	return 0;
186776bca880SMarcel Holtmann }
186876bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
186976bca880SMarcel Holtmann 
187033e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
18711e429f38SGustavo F. Padovan 			  int count, __u8 index)
187233e882a5SSuraj Sumangala {
187333e882a5SSuraj Sumangala 	int len = 0;
187433e882a5SSuraj Sumangala 	int hlen = 0;
187533e882a5SSuraj Sumangala 	int remain = count;
187633e882a5SSuraj Sumangala 	struct sk_buff *skb;
187733e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
187833e882a5SSuraj Sumangala 
187933e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
188033e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
188133e882a5SSuraj Sumangala 		return -EILSEQ;
188233e882a5SSuraj Sumangala 
188333e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
188433e882a5SSuraj Sumangala 
188533e882a5SSuraj Sumangala 	if (!skb) {
188633e882a5SSuraj Sumangala 		switch (type) {
188733e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
188833e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
188933e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
189033e882a5SSuraj Sumangala 			break;
189133e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
189233e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
189333e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
189433e882a5SSuraj Sumangala 			break;
189533e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
189633e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
189733e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
189833e882a5SSuraj Sumangala 			break;
189933e882a5SSuraj Sumangala 		}
190033e882a5SSuraj Sumangala 
19011e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
190233e882a5SSuraj Sumangala 		if (!skb)
190333e882a5SSuraj Sumangala 			return -ENOMEM;
190433e882a5SSuraj Sumangala 
190533e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
190633e882a5SSuraj Sumangala 		scb->expect = hlen;
190733e882a5SSuraj Sumangala 		scb->pkt_type = type;
190833e882a5SSuraj Sumangala 
190933e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
191033e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
191133e882a5SSuraj Sumangala 	}
191233e882a5SSuraj Sumangala 
191333e882a5SSuraj Sumangala 	while (count) {
191433e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
191589bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
191633e882a5SSuraj Sumangala 
191733e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
191833e882a5SSuraj Sumangala 
191933e882a5SSuraj Sumangala 		count -= len;
192033e882a5SSuraj Sumangala 		data += len;
192133e882a5SSuraj Sumangala 		scb->expect -= len;
192233e882a5SSuraj Sumangala 		remain = count;
192333e882a5SSuraj Sumangala 
192433e882a5SSuraj Sumangala 		switch (type) {
192533e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
192633e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
192733e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
192833e882a5SSuraj Sumangala 				scb->expect = h->plen;
192933e882a5SSuraj Sumangala 
193033e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
193133e882a5SSuraj Sumangala 					kfree_skb(skb);
193233e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
193333e882a5SSuraj Sumangala 					return -ENOMEM;
193433e882a5SSuraj Sumangala 				}
193533e882a5SSuraj Sumangala 			}
193633e882a5SSuraj Sumangala 			break;
193733e882a5SSuraj Sumangala 
193833e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
193933e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
194033e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
194133e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
194233e882a5SSuraj Sumangala 
194333e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
194433e882a5SSuraj Sumangala 					kfree_skb(skb);
194533e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
194633e882a5SSuraj Sumangala 					return -ENOMEM;
194733e882a5SSuraj Sumangala 				}
194833e882a5SSuraj Sumangala 			}
194933e882a5SSuraj Sumangala 			break;
195033e882a5SSuraj Sumangala 
195133e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
195233e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
195333e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
195433e882a5SSuraj Sumangala 				scb->expect = h->dlen;
195533e882a5SSuraj Sumangala 
195633e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
195733e882a5SSuraj Sumangala 					kfree_skb(skb);
195833e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
195933e882a5SSuraj Sumangala 					return -ENOMEM;
196033e882a5SSuraj Sumangala 				}
196133e882a5SSuraj Sumangala 			}
196233e882a5SSuraj Sumangala 			break;
196333e882a5SSuraj Sumangala 		}
196433e882a5SSuraj Sumangala 
196533e882a5SSuraj Sumangala 		if (scb->expect == 0) {
196633e882a5SSuraj Sumangala 			/* Complete frame */
196733e882a5SSuraj Sumangala 
196833e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
196933e882a5SSuraj Sumangala 			hci_recv_frame(skb);
197033e882a5SSuraj Sumangala 
197133e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
197233e882a5SSuraj Sumangala 			return remain;
197333e882a5SSuraj Sumangala 		}
197433e882a5SSuraj Sumangala 	}
197533e882a5SSuraj Sumangala 
197633e882a5SSuraj Sumangala 	return remain;
197733e882a5SSuraj Sumangala }
197833e882a5SSuraj Sumangala 
1979ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
1980ef222013SMarcel Holtmann {
1981f39a3c06SSuraj Sumangala 	int rem = 0;
1982f39a3c06SSuraj Sumangala 
1983ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
1984ef222013SMarcel Holtmann 		return -EILSEQ;
1985ef222013SMarcel Holtmann 
1986da5f6c37SGustavo F. Padovan 	while (count) {
19871e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
1988f39a3c06SSuraj Sumangala 		if (rem < 0)
1989f39a3c06SSuraj Sumangala 			return rem;
1990ef222013SMarcel Holtmann 
1991f39a3c06SSuraj Sumangala 		data += (count - rem);
1992f39a3c06SSuraj Sumangala 		count = rem;
1993f81c6224SJoe Perches 	}
1994ef222013SMarcel Holtmann 
1995f39a3c06SSuraj Sumangala 	return rem;
1996ef222013SMarcel Holtmann }
1997ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
1998ef222013SMarcel Holtmann 
199999811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
200099811510SSuraj Sumangala 
200199811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
200299811510SSuraj Sumangala {
200399811510SSuraj Sumangala 	int type;
200499811510SSuraj Sumangala 	int rem = 0;
200599811510SSuraj Sumangala 
2006da5f6c37SGustavo F. Padovan 	while (count) {
200799811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
200899811510SSuraj Sumangala 
200999811510SSuraj Sumangala 		if (!skb) {
201099811510SSuraj Sumangala 			struct { char type; } *pkt;
201199811510SSuraj Sumangala 
201299811510SSuraj Sumangala 			/* Start of the frame */
201399811510SSuraj Sumangala 			pkt = data;
201499811510SSuraj Sumangala 			type = pkt->type;
201599811510SSuraj Sumangala 
201699811510SSuraj Sumangala 			data++;
201799811510SSuraj Sumangala 			count--;
201899811510SSuraj Sumangala 		} else
201999811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
202099811510SSuraj Sumangala 
20211e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
20221e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
202399811510SSuraj Sumangala 		if (rem < 0)
202499811510SSuraj Sumangala 			return rem;
202599811510SSuraj Sumangala 
202699811510SSuraj Sumangala 		data += (count - rem);
202799811510SSuraj Sumangala 		count = rem;
2028f81c6224SJoe Perches 	}
202999811510SSuraj Sumangala 
203099811510SSuraj Sumangala 	return rem;
203199811510SSuraj Sumangala }
203299811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
203399811510SSuraj Sumangala 
20341da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
20351da177e4SLinus Torvalds 
20361da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
20371da177e4SLinus Torvalds {
20381da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
20391da177e4SLinus Torvalds 
2040f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
20411da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2042f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
20431da177e4SLinus Torvalds 
20441da177e4SLinus Torvalds 	return 0;
20451da177e4SLinus Torvalds }
20461da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
20471da177e4SLinus Torvalds 
20481da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
20491da177e4SLinus Torvalds {
20501da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
20511da177e4SLinus Torvalds 
2052f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
20531da177e4SLinus Torvalds 	list_del(&cb->list);
2054f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
20551da177e4SLinus Torvalds 
20561da177e4SLinus Torvalds 	return 0;
20571da177e4SLinus Torvalds }
20581da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
20591da177e4SLinus Torvalds 
20601da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
20611da177e4SLinus Torvalds {
20621da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
20631da177e4SLinus Torvalds 
20641da177e4SLinus Torvalds 	if (!hdev) {
20651da177e4SLinus Torvalds 		kfree_skb(skb);
20661da177e4SLinus Torvalds 		return -ENODEV;
20671da177e4SLinus Torvalds 	}
20681da177e4SLinus Torvalds 
20690d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
20701da177e4SLinus Torvalds 
20711da177e4SLinus Torvalds 	/* Time stamp */
2072a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
20731da177e4SLinus Torvalds 
2074cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2075cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2076cd82e61cSMarcel Holtmann 
2077cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2078cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2079470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
20801da177e4SLinus Torvalds 	}
20811da177e4SLinus Torvalds 
20821da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
20831da177e4SLinus Torvalds 	skb_orphan(skb);
20841da177e4SLinus Torvalds 
20851da177e4SLinus Torvalds 	return hdev->send(skb);
20861da177e4SLinus Torvalds }
20871da177e4SLinus Torvalds 
20881da177e4SLinus Torvalds /* Send HCI command */
2089a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
20901da177e4SLinus Torvalds {
20911da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
20921da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
20931da177e4SLinus Torvalds 	struct sk_buff *skb;
20941da177e4SLinus Torvalds 
2095a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
20961da177e4SLinus Torvalds 
20971da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
20981da177e4SLinus Torvalds 	if (!skb) {
2099ef222013SMarcel Holtmann 		BT_ERR("%s no memory for command", hdev->name);
21001da177e4SLinus Torvalds 		return -ENOMEM;
21011da177e4SLinus Torvalds 	}
21021da177e4SLinus Torvalds 
21031da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2104a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
21051da177e4SLinus Torvalds 	hdr->plen   = plen;
21061da177e4SLinus Torvalds 
21071da177e4SLinus Torvalds 	if (plen)
21081da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
21091da177e4SLinus Torvalds 
21101da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
21111da177e4SLinus Torvalds 
21120d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
21131da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2114c78ae283SMarcel Holtmann 
2115a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
2116a5040efaSJohan Hedberg 		hdev->init_last_cmd = opcode;
2117a5040efaSJohan Hedberg 
21181da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2119c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
21201da177e4SLinus Torvalds 
21211da177e4SLinus Torvalds 	return 0;
21221da177e4SLinus Torvalds }
21231da177e4SLinus Torvalds 
21241da177e4SLinus Torvalds /* Get data from the previously sent command */
2125a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
21261da177e4SLinus Torvalds {
21271da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
21281da177e4SLinus Torvalds 
21291da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
21301da177e4SLinus Torvalds 		return NULL;
21311da177e4SLinus Torvalds 
21321da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
21331da177e4SLinus Torvalds 
2134a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
21351da177e4SLinus Torvalds 		return NULL;
21361da177e4SLinus Torvalds 
2137a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x", hdev->name, opcode);
21381da177e4SLinus Torvalds 
21391da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
21401da177e4SLinus Torvalds }
21411da177e4SLinus Torvalds 
21421da177e4SLinus Torvalds /* Send ACL data */
21431da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
21441da177e4SLinus Torvalds {
21451da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
21461da177e4SLinus Torvalds 	int len = skb->len;
21471da177e4SLinus Torvalds 
2148badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2149badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
21509c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2151aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2152aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
21531da177e4SLinus Torvalds }
21541da177e4SLinus Torvalds 
215573d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
215673d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
21571da177e4SLinus Torvalds {
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;
2165087bfd99SGustavo Padovan 	hci_add_acl_hdr(skb, conn->handle, flags);
2166087bfd99SGustavo Padovan 
216770f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
216870f23020SAndrei Emeltchenko 	if (!list) {
21691da177e4SLinus Torvalds 		/* Non fragmented */
21701da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
21711da177e4SLinus Torvalds 
217273d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
21731da177e4SLinus Torvalds 	} else {
21741da177e4SLinus Torvalds 		/* Fragmented */
21751da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
21761da177e4SLinus Torvalds 
21771da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
21781da177e4SLinus Torvalds 
21791da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2180af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
21811da177e4SLinus Torvalds 
218273d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2183e702112fSAndrei Emeltchenko 
2184e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2185e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
21861da177e4SLinus Torvalds 		do {
21871da177e4SLinus Torvalds 			skb = list; list = list->next;
21881da177e4SLinus Torvalds 
21891da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
21900d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2191e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
21921da177e4SLinus Torvalds 
21931da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
21941da177e4SLinus Torvalds 
219573d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
21961da177e4SLinus Torvalds 		} while (list);
21971da177e4SLinus Torvalds 
2198af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
21991da177e4SLinus Torvalds 	}
220073d80debSLuiz Augusto von Dentz }
220173d80debSLuiz Augusto von Dentz 
220273d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
220373d80debSLuiz Augusto von Dentz {
220473d80debSLuiz Augusto von Dentz 	struct hci_conn *conn = chan->conn;
220573d80debSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
220673d80debSLuiz Augusto von Dentz 
220773d80debSLuiz Augusto von Dentz 	BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags);
220873d80debSLuiz Augusto von Dentz 
220973d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
221073d80debSLuiz Augusto von Dentz 
221173d80debSLuiz Augusto von Dentz 	hci_queue_acl(conn, &chan->data_q, skb, flags);
22121da177e4SLinus Torvalds 
22133eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
22141da177e4SLinus Torvalds }
22151da177e4SLinus Torvalds 
22161da177e4SLinus Torvalds /* Send SCO data */
22170d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
22181da177e4SLinus Torvalds {
22191da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
22201da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
22211da177e4SLinus Torvalds 
22221da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
22231da177e4SLinus Torvalds 
2224aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
22251da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
22261da177e4SLinus Torvalds 
2227badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2228badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
22299c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
22301da177e4SLinus Torvalds 
22311da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
22320d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2233c78ae283SMarcel Holtmann 
22341da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
22353eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
22361da177e4SLinus Torvalds }
22371da177e4SLinus Torvalds 
22381da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
22391da177e4SLinus Torvalds 
22401da177e4SLinus Torvalds /* HCI Connection scheduler */
22416039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
2242a8c5fb1aSGustavo Padovan 				     int *quote)
22431da177e4SLinus Torvalds {
22441da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
22458035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
2246abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
22471da177e4SLinus Torvalds 
22481da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
22491da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2250bf4c6325SGustavo F. Padovan 
2251bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2252bf4c6325SGustavo F. Padovan 
2253bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2254769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
22551da177e4SLinus Torvalds 			continue;
2256769be974SMarcel Holtmann 
2257769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2258769be974SMarcel Holtmann 			continue;
2259769be974SMarcel Holtmann 
22601da177e4SLinus Torvalds 		num++;
22611da177e4SLinus Torvalds 
22621da177e4SLinus Torvalds 		if (c->sent < min) {
22631da177e4SLinus Torvalds 			min  = c->sent;
22641da177e4SLinus Torvalds 			conn = c;
22651da177e4SLinus Torvalds 		}
226652087a79SLuiz Augusto von Dentz 
226752087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
226852087a79SLuiz Augusto von Dentz 			break;
22691da177e4SLinus Torvalds 	}
22701da177e4SLinus Torvalds 
2271bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2272bf4c6325SGustavo F. Padovan 
22731da177e4SLinus Torvalds 	if (conn) {
22746ed58ec5SVille Tervo 		int cnt, q;
22756ed58ec5SVille Tervo 
22766ed58ec5SVille Tervo 		switch (conn->type) {
22776ed58ec5SVille Tervo 		case ACL_LINK:
22786ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
22796ed58ec5SVille Tervo 			break;
22806ed58ec5SVille Tervo 		case SCO_LINK:
22816ed58ec5SVille Tervo 		case ESCO_LINK:
22826ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
22836ed58ec5SVille Tervo 			break;
22846ed58ec5SVille Tervo 		case LE_LINK:
22856ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
22866ed58ec5SVille Tervo 			break;
22876ed58ec5SVille Tervo 		default:
22886ed58ec5SVille Tervo 			cnt = 0;
22896ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
22906ed58ec5SVille Tervo 		}
22916ed58ec5SVille Tervo 
22926ed58ec5SVille Tervo 		q = cnt / num;
22931da177e4SLinus Torvalds 		*quote = q ? q : 1;
22941da177e4SLinus Torvalds 	} else
22951da177e4SLinus Torvalds 		*quote = 0;
22961da177e4SLinus Torvalds 
22971da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
22981da177e4SLinus Torvalds 	return conn;
22991da177e4SLinus Torvalds }
23001da177e4SLinus Torvalds 
23016039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
23021da177e4SLinus Torvalds {
23031da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
23041da177e4SLinus Torvalds 	struct hci_conn *c;
23051da177e4SLinus Torvalds 
2306bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
23071da177e4SLinus Torvalds 
2308bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2309bf4c6325SGustavo F. Padovan 
23101da177e4SLinus Torvalds 	/* Kill stalled connections */
2311bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2312bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
2313bae1f5d9SVille Tervo 			BT_ERR("%s killing stalled connection %s",
23141da177e4SLinus Torvalds 			       hdev->name, batostr(&c->dst));
23157490c6c2SAndrei Emeltchenko 			hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM);
23161da177e4SLinus Torvalds 		}
23171da177e4SLinus Torvalds 	}
2318bf4c6325SGustavo F. Padovan 
2319bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
23201da177e4SLinus Torvalds }
23211da177e4SLinus Torvalds 
23226039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
232373d80debSLuiz Augusto von Dentz 				      int *quote)
232473d80debSLuiz Augusto von Dentz {
232573d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
232673d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
2327abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
232873d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
232973d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
233073d80debSLuiz Augusto von Dentz 
233173d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
233273d80debSLuiz Augusto von Dentz 
2333bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2334bf4c6325SGustavo F. Padovan 
2335bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
233673d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
233773d80debSLuiz Augusto von Dentz 
233873d80debSLuiz Augusto von Dentz 		if (conn->type != type)
233973d80debSLuiz Augusto von Dentz 			continue;
234073d80debSLuiz Augusto von Dentz 
234173d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
234273d80debSLuiz Augusto von Dentz 			continue;
234373d80debSLuiz Augusto von Dentz 
234473d80debSLuiz Augusto von Dentz 		conn_num++;
234573d80debSLuiz Augusto von Dentz 
23468192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
234773d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
234873d80debSLuiz Augusto von Dentz 
234973d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
235073d80debSLuiz Augusto von Dentz 				continue;
235173d80debSLuiz Augusto von Dentz 
235273d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
235373d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
235473d80debSLuiz Augusto von Dentz 				continue;
235573d80debSLuiz Augusto von Dentz 
235673d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
235773d80debSLuiz Augusto von Dentz 				num = 0;
235873d80debSLuiz Augusto von Dentz 				min = ~0;
235973d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
236073d80debSLuiz Augusto von Dentz 			}
236173d80debSLuiz Augusto von Dentz 
236273d80debSLuiz Augusto von Dentz 			num++;
236373d80debSLuiz Augusto von Dentz 
236473d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
236573d80debSLuiz Augusto von Dentz 				min  = conn->sent;
236673d80debSLuiz Augusto von Dentz 				chan = tmp;
236773d80debSLuiz Augusto von Dentz 			}
236873d80debSLuiz Augusto von Dentz 		}
236973d80debSLuiz Augusto von Dentz 
237073d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
237173d80debSLuiz Augusto von Dentz 			break;
237273d80debSLuiz Augusto von Dentz 	}
237373d80debSLuiz Augusto von Dentz 
2374bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2375bf4c6325SGustavo F. Padovan 
237673d80debSLuiz Augusto von Dentz 	if (!chan)
237773d80debSLuiz Augusto von Dentz 		return NULL;
237873d80debSLuiz Augusto von Dentz 
237973d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
238073d80debSLuiz Augusto von Dentz 	case ACL_LINK:
238173d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
238273d80debSLuiz Augusto von Dentz 		break;
238373d80debSLuiz Augusto von Dentz 	case SCO_LINK:
238473d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
238573d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
238673d80debSLuiz Augusto von Dentz 		break;
238773d80debSLuiz Augusto von Dentz 	case LE_LINK:
238873d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
238973d80debSLuiz Augusto von Dentz 		break;
239073d80debSLuiz Augusto von Dentz 	default:
239173d80debSLuiz Augusto von Dentz 		cnt = 0;
239273d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
239373d80debSLuiz Augusto von Dentz 	}
239473d80debSLuiz Augusto von Dentz 
239573d80debSLuiz Augusto von Dentz 	q = cnt / num;
239673d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
239773d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
239873d80debSLuiz Augusto von Dentz 	return chan;
239973d80debSLuiz Augusto von Dentz }
240073d80debSLuiz Augusto von Dentz 
240102b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
240202b20f0bSLuiz Augusto von Dentz {
240302b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
240402b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
240502b20f0bSLuiz Augusto von Dentz 	int num = 0;
240602b20f0bSLuiz Augusto von Dentz 
240702b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
240802b20f0bSLuiz Augusto von Dentz 
2409bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2410bf4c6325SGustavo F. Padovan 
2411bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
241202b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
241302b20f0bSLuiz Augusto von Dentz 
241402b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
241502b20f0bSLuiz Augusto von Dentz 			continue;
241602b20f0bSLuiz Augusto von Dentz 
241702b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
241802b20f0bSLuiz Augusto von Dentz 			continue;
241902b20f0bSLuiz Augusto von Dentz 
242002b20f0bSLuiz Augusto von Dentz 		num++;
242102b20f0bSLuiz Augusto von Dentz 
24228192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
242302b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
242402b20f0bSLuiz Augusto von Dentz 
242502b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
242602b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
242702b20f0bSLuiz Augusto von Dentz 				continue;
242802b20f0bSLuiz Augusto von Dentz 			}
242902b20f0bSLuiz Augusto von Dentz 
243002b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
243102b20f0bSLuiz Augusto von Dentz 				continue;
243202b20f0bSLuiz Augusto von Dentz 
243302b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
243402b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
243502b20f0bSLuiz Augusto von Dentz 				continue;
243602b20f0bSLuiz Augusto von Dentz 
243702b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
243802b20f0bSLuiz Augusto von Dentz 
243902b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
244002b20f0bSLuiz Augusto von Dentz 			       skb->priority);
244102b20f0bSLuiz Augusto von Dentz 		}
244202b20f0bSLuiz Augusto von Dentz 
244302b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
244402b20f0bSLuiz Augusto von Dentz 			break;
244502b20f0bSLuiz Augusto von Dentz 	}
2446bf4c6325SGustavo F. Padovan 
2447bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2448bf4c6325SGustavo F. Padovan 
244902b20f0bSLuiz Augusto von Dentz }
245002b20f0bSLuiz Augusto von Dentz 
2451b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
2452b71d385aSAndrei Emeltchenko {
2453b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
2454b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
2455b71d385aSAndrei Emeltchenko }
2456b71d385aSAndrei Emeltchenko 
24576039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
24581da177e4SLinus Torvalds {
24591da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
24601da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
24611da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
246263d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
24635f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
2464bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
24651da177e4SLinus Torvalds 	}
246663d2bc1bSAndrei Emeltchenko }
24671da177e4SLinus Torvalds 
24686039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
246963d2bc1bSAndrei Emeltchenko {
247063d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
247163d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
247263d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
247363d2bc1bSAndrei Emeltchenko 	int quote;
247463d2bc1bSAndrei Emeltchenko 
247563d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
247604837f64SMarcel Holtmann 
247773d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
247873d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2479ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2480ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
248173d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
248273d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
248373d80debSLuiz Augusto von Dentz 
2484ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2485ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2486ec1cce24SLuiz Augusto von Dentz 				break;
2487ec1cce24SLuiz Augusto von Dentz 
2488ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2489ec1cce24SLuiz Augusto von Dentz 
249073d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
249173d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
249204837f64SMarcel Holtmann 
24931da177e4SLinus Torvalds 			hci_send_frame(skb);
24941da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
24951da177e4SLinus Torvalds 
24961da177e4SLinus Torvalds 			hdev->acl_cnt--;
249773d80debSLuiz Augusto von Dentz 			chan->sent++;
249873d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
24991da177e4SLinus Torvalds 		}
25001da177e4SLinus Torvalds 	}
250102b20f0bSLuiz Augusto von Dentz 
250202b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
250302b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
25041da177e4SLinus Torvalds }
25051da177e4SLinus Torvalds 
25066039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
2507b71d385aSAndrei Emeltchenko {
250863d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
2509b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
2510b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
2511b71d385aSAndrei Emeltchenko 	int quote;
2512b71d385aSAndrei Emeltchenko 
251363d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
2514b71d385aSAndrei Emeltchenko 
2515b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
2516b71d385aSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2517b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
2518b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
2519b71d385aSAndrei Emeltchenko 			int blocks;
2520b71d385aSAndrei Emeltchenko 
2521b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
2522b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
2523b71d385aSAndrei Emeltchenko 
2524b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
2525b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
2526b71d385aSAndrei Emeltchenko 				break;
2527b71d385aSAndrei Emeltchenko 
2528b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
2529b71d385aSAndrei Emeltchenko 
2530b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
2531b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
2532b71d385aSAndrei Emeltchenko 				return;
2533b71d385aSAndrei Emeltchenko 
2534b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
2535b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
2536b71d385aSAndrei Emeltchenko 
2537b71d385aSAndrei Emeltchenko 			hci_send_frame(skb);
2538b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
2539b71d385aSAndrei Emeltchenko 
2540b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
2541b71d385aSAndrei Emeltchenko 			quote -= blocks;
2542b71d385aSAndrei Emeltchenko 
2543b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
2544b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
2545b71d385aSAndrei Emeltchenko 		}
2546b71d385aSAndrei Emeltchenko 	}
2547b71d385aSAndrei Emeltchenko 
2548b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
2549b71d385aSAndrei Emeltchenko 		hci_prio_recalculate(hdev, ACL_LINK);
2550b71d385aSAndrei Emeltchenko }
2551b71d385aSAndrei Emeltchenko 
25526039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
2553b71d385aSAndrei Emeltchenko {
2554b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
2555b71d385aSAndrei Emeltchenko 
2556b71d385aSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK))
2557b71d385aSAndrei Emeltchenko 		return;
2558b71d385aSAndrei Emeltchenko 
2559b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
2560b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
2561b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
2562b71d385aSAndrei Emeltchenko 		break;
2563b71d385aSAndrei Emeltchenko 
2564b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
2565b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
2566b71d385aSAndrei Emeltchenko 		break;
2567b71d385aSAndrei Emeltchenko 	}
2568b71d385aSAndrei Emeltchenko }
2569b71d385aSAndrei Emeltchenko 
25701da177e4SLinus Torvalds /* Schedule SCO */
25716039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
25721da177e4SLinus Torvalds {
25731da177e4SLinus Torvalds 	struct hci_conn *conn;
25741da177e4SLinus Torvalds 	struct sk_buff *skb;
25751da177e4SLinus Torvalds 	int quote;
25761da177e4SLinus Torvalds 
25771da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
25781da177e4SLinus Torvalds 
257952087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
258052087a79SLuiz Augusto von Dentz 		return;
258152087a79SLuiz Augusto von Dentz 
25821da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
25831da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
25841da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
25851da177e4SLinus Torvalds 			hci_send_frame(skb);
25861da177e4SLinus Torvalds 
25871da177e4SLinus Torvalds 			conn->sent++;
25881da177e4SLinus Torvalds 			if (conn->sent == ~0)
25891da177e4SLinus Torvalds 				conn->sent = 0;
25901da177e4SLinus Torvalds 		}
25911da177e4SLinus Torvalds 	}
25921da177e4SLinus Torvalds }
25931da177e4SLinus Torvalds 
25946039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
2595b6a0dc82SMarcel Holtmann {
2596b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
2597b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
2598b6a0dc82SMarcel Holtmann 	int quote;
2599b6a0dc82SMarcel Holtmann 
2600b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2601b6a0dc82SMarcel Holtmann 
260252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
260352087a79SLuiz Augusto von Dentz 		return;
260452087a79SLuiz Augusto von Dentz 
26058fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
26068fc9ced3SGustavo Padovan 						     &quote))) {
2607b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
2608b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
2609b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
2610b6a0dc82SMarcel Holtmann 
2611b6a0dc82SMarcel Holtmann 			conn->sent++;
2612b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
2613b6a0dc82SMarcel Holtmann 				conn->sent = 0;
2614b6a0dc82SMarcel Holtmann 		}
2615b6a0dc82SMarcel Holtmann 	}
2616b6a0dc82SMarcel Holtmann }
2617b6a0dc82SMarcel Holtmann 
26186039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
26196ed58ec5SVille Tervo {
262073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
26216ed58ec5SVille Tervo 	struct sk_buff *skb;
262202b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
26236ed58ec5SVille Tervo 
26246ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
26256ed58ec5SVille Tervo 
262652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
262752087a79SLuiz Augusto von Dentz 		return;
262852087a79SLuiz Augusto von Dentz 
26296ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
26306ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
26316ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
2632bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
26336ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
2634bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
26356ed58ec5SVille Tervo 	}
26366ed58ec5SVille Tervo 
26376ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
263802b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
263973d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
2640ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2641ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
264273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
264373d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
26446ed58ec5SVille Tervo 
2645ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2646ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2647ec1cce24SLuiz Augusto von Dentz 				break;
2648ec1cce24SLuiz Augusto von Dentz 
2649ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2650ec1cce24SLuiz Augusto von Dentz 
26516ed58ec5SVille Tervo 			hci_send_frame(skb);
26526ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
26536ed58ec5SVille Tervo 
26546ed58ec5SVille Tervo 			cnt--;
265573d80debSLuiz Augusto von Dentz 			chan->sent++;
265673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
26576ed58ec5SVille Tervo 		}
26586ed58ec5SVille Tervo 	}
265973d80debSLuiz Augusto von Dentz 
26606ed58ec5SVille Tervo 	if (hdev->le_pkts)
26616ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
26626ed58ec5SVille Tervo 	else
26636ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
266402b20f0bSLuiz Augusto von Dentz 
266502b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
266602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
26676ed58ec5SVille Tervo }
26686ed58ec5SVille Tervo 
26693eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
26701da177e4SLinus Torvalds {
26713eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
26721da177e4SLinus Torvalds 	struct sk_buff *skb;
26731da177e4SLinus Torvalds 
26746ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
26756ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
26761da177e4SLinus Torvalds 
26771da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
26781da177e4SLinus Torvalds 
26791da177e4SLinus Torvalds 	hci_sched_acl(hdev);
26801da177e4SLinus Torvalds 
26811da177e4SLinus Torvalds 	hci_sched_sco(hdev);
26821da177e4SLinus Torvalds 
2683b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
2684b6a0dc82SMarcel Holtmann 
26856ed58ec5SVille Tervo 	hci_sched_le(hdev);
26866ed58ec5SVille Tervo 
26871da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
26881da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
26891da177e4SLinus Torvalds 		hci_send_frame(skb);
26901da177e4SLinus Torvalds }
26911da177e4SLinus Torvalds 
269225985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
26931da177e4SLinus Torvalds 
26941da177e4SLinus Torvalds /* ACL data packet */
26956039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
26961da177e4SLinus Torvalds {
26971da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
26981da177e4SLinus Torvalds 	struct hci_conn *conn;
26991da177e4SLinus Torvalds 	__u16 handle, flags;
27001da177e4SLinus Torvalds 
27011da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
27021da177e4SLinus Torvalds 
27031da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
27041da177e4SLinus Torvalds 	flags  = hci_flags(handle);
27051da177e4SLinus Torvalds 	handle = hci_handle(handle);
27061da177e4SLinus Torvalds 
2707a8c5fb1aSGustavo Padovan 	BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len,
2708a8c5fb1aSGustavo Padovan 	       handle, flags);
27091da177e4SLinus Torvalds 
27101da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
27111da177e4SLinus Torvalds 
27121da177e4SLinus Torvalds 	hci_dev_lock(hdev);
27131da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
27141da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
27151da177e4SLinus Torvalds 
27161da177e4SLinus Torvalds 	if (conn) {
271765983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
271804837f64SMarcel Holtmann 
2719671267bfSJohan Hedberg 		hci_dev_lock(hdev);
2720671267bfSJohan Hedberg 		if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
2721671267bfSJohan Hedberg 		    !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2722671267bfSJohan Hedberg 			mgmt_device_connected(hdev, &conn->dst, conn->type,
2723671267bfSJohan Hedberg 					      conn->dst_type, 0, NULL, 0,
2724671267bfSJohan Hedberg 					      conn->dev_class);
2725671267bfSJohan Hedberg 		hci_dev_unlock(hdev);
2726671267bfSJohan Hedberg 
27271da177e4SLinus Torvalds 		/* Send to upper protocol */
2728686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
27291da177e4SLinus Torvalds 		return;
27301da177e4SLinus Torvalds 	} else {
27311da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
27321da177e4SLinus Torvalds 		       hdev->name, handle);
27331da177e4SLinus Torvalds 	}
27341da177e4SLinus Torvalds 
27351da177e4SLinus Torvalds 	kfree_skb(skb);
27361da177e4SLinus Torvalds }
27371da177e4SLinus Torvalds 
27381da177e4SLinus Torvalds /* SCO data packet */
27396039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
27401da177e4SLinus Torvalds {
27411da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
27421da177e4SLinus Torvalds 	struct hci_conn *conn;
27431da177e4SLinus Torvalds 	__u16 handle;
27441da177e4SLinus Torvalds 
27451da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
27461da177e4SLinus Torvalds 
27471da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
27481da177e4SLinus Torvalds 
27491da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
27501da177e4SLinus Torvalds 
27511da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
27521da177e4SLinus Torvalds 
27531da177e4SLinus Torvalds 	hci_dev_lock(hdev);
27541da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
27551da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
27561da177e4SLinus Torvalds 
27571da177e4SLinus Torvalds 	if (conn) {
27581da177e4SLinus Torvalds 		/* Send to upper protocol */
2759686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
27601da177e4SLinus Torvalds 		return;
27611da177e4SLinus Torvalds 	} else {
27621da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
27631da177e4SLinus Torvalds 		       hdev->name, handle);
27641da177e4SLinus Torvalds 	}
27651da177e4SLinus Torvalds 
27661da177e4SLinus Torvalds 	kfree_skb(skb);
27671da177e4SLinus Torvalds }
27681da177e4SLinus Torvalds 
2769b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
27701da177e4SLinus Torvalds {
2771b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
27721da177e4SLinus Torvalds 	struct sk_buff *skb;
27731da177e4SLinus Torvalds 
27741da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
27751da177e4SLinus Torvalds 
27761da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
2777cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
2778cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
2779cd82e61cSMarcel Holtmann 
27801da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
27811da177e4SLinus Torvalds 			/* Send copy to the sockets */
2782470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
27831da177e4SLinus Torvalds 		}
27841da177e4SLinus Torvalds 
27851da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
27861da177e4SLinus Torvalds 			kfree_skb(skb);
27871da177e4SLinus Torvalds 			continue;
27881da177e4SLinus Torvalds 		}
27891da177e4SLinus Torvalds 
27901da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
27911da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
27920d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
27931da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
27941da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
27951da177e4SLinus Torvalds 				kfree_skb(skb);
27961da177e4SLinus Torvalds 				continue;
27973ff50b79SStephen Hemminger 			}
27981da177e4SLinus Torvalds 		}
27991da177e4SLinus Torvalds 
28001da177e4SLinus Torvalds 		/* Process frame */
28010d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
28021da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
2803b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
28041da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
28051da177e4SLinus Torvalds 			break;
28061da177e4SLinus Torvalds 
28071da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
28081da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
28091da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
28101da177e4SLinus Torvalds 			break;
28111da177e4SLinus Torvalds 
28121da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
28131da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
28141da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
28151da177e4SLinus Torvalds 			break;
28161da177e4SLinus Torvalds 
28171da177e4SLinus Torvalds 		default:
28181da177e4SLinus Torvalds 			kfree_skb(skb);
28191da177e4SLinus Torvalds 			break;
28201da177e4SLinus Torvalds 		}
28211da177e4SLinus Torvalds 	}
28221da177e4SLinus Torvalds }
28231da177e4SLinus Torvalds 
2824c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
28251da177e4SLinus Torvalds {
2826c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
28271da177e4SLinus Torvalds 	struct sk_buff *skb;
28281da177e4SLinus Torvalds 
28291da177e4SLinus Torvalds 	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
28301da177e4SLinus Torvalds 
28311da177e4SLinus Torvalds 	/* Send queued commands */
28325a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
28335a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
28345a08ecceSAndrei Emeltchenko 		if (!skb)
28355a08ecceSAndrei Emeltchenko 			return;
28365a08ecceSAndrei Emeltchenko 
28371da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
28381da177e4SLinus Torvalds 
283970f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
284070f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
28411da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
28421da177e4SLinus Torvalds 			hci_send_frame(skb);
28437bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
28447bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
28457bdb8a5cSSzymon Janc 			else
28466bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
28475f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
28481da177e4SLinus Torvalds 		} else {
28491da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
2850c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
28511da177e4SLinus Torvalds 		}
28521da177e4SLinus Torvalds 	}
28531da177e4SLinus Torvalds }
28542519a1fcSAndre Guedes 
28552519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
28562519a1fcSAndre Guedes {
28572519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
28582519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
28592519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
28602519a1fcSAndre Guedes 
28612519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
28622519a1fcSAndre Guedes 
28632519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
28642519a1fcSAndre Guedes 		return -EINPROGRESS;
28652519a1fcSAndre Guedes 
28664663262cSJohan Hedberg 	inquiry_cache_flush(hdev);
28674663262cSJohan Hedberg 
28682519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
28692519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
28702519a1fcSAndre Guedes 	cp.length  = length;
28712519a1fcSAndre Guedes 
28722519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
28732519a1fcSAndre Guedes }
2874023d5049SAndre Guedes 
2875023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
2876023d5049SAndre Guedes {
2877023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
2878023d5049SAndre Guedes 
2879023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
28807537e5c3SAndre Guedes 		return -EALREADY;
2881023d5049SAndre Guedes 
2882023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2883023d5049SAndre Guedes }
288431f7956cSAndre Guedes 
288531f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type)
288631f7956cSAndre Guedes {
288731f7956cSAndre Guedes 	switch (bdaddr_type) {
288831f7956cSAndre Guedes 	case BDADDR_LE_PUBLIC:
288931f7956cSAndre Guedes 		return ADDR_LE_DEV_PUBLIC;
289031f7956cSAndre Guedes 
289131f7956cSAndre Guedes 	default:
289231f7956cSAndre Guedes 		/* Fallback to LE Random address type */
289331f7956cSAndre Guedes 		return ADDR_LE_DEV_RANDOM;
289431f7956cSAndre Guedes 	}
289531f7956cSAndre Guedes }
2896