xref: /openbmc/linux/net/bluetooth/hci_core.c (revision f1550478)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
4590051deSGustavo F. Padovan    Copyright (C) 2011 ProFUSION Embedded Systems
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds    published by the Free Software Foundation;
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds /* Bluetooth HCI core. */
271da177e4SLinus Torvalds 
288c520a59SGustavo Padovan #include <linux/export.h>
293df92b31SSasha Levin #include <linux/idr.h>
301da177e4SLinus Torvalds 
31611b30f7SMarcel Holtmann #include <linux/rfkill.h>
321da177e4SLinus Torvalds 
331da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
341da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
351da177e4SLinus Torvalds 
36b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
37c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
383eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
391da177e4SLinus Torvalds 
401da177e4SLinus Torvalds /* HCI device list */
411da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
421da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
431da177e4SLinus Torvalds 
441da177e4SLinus Torvalds /* HCI callback list */
451da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
461da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
471da177e4SLinus Torvalds 
483df92b31SSasha Levin /* HCI ID Numbering */
493df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
503df92b31SSasha Levin 
511da177e4SLinus Torvalds /* ---- HCI notifications ---- */
521da177e4SLinus Torvalds 
536516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
541da177e4SLinus Torvalds {
55040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
561da177e4SLinus Torvalds }
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds /* ---- HCI requests ---- */
591da177e4SLinus Torvalds 
6023bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
611da177e4SLinus Torvalds {
62f0e09510SAndrei Emeltchenko 	BT_DBG("%s command 0x%4.4x result 0x%2.2x", hdev->name, cmd, result);
6323bb5763SJohan Hedberg 
64a5040efaSJohan Hedberg 	/* If this is the init phase check if the completed command matches
65a5040efaSJohan Hedberg 	 * the last init command, and if not just return.
66a5040efaSJohan Hedberg 	 */
6775fb0e32SJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) {
6875fb0e32SJohan Hedberg 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
691036b890SAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
7075fb0e32SJohan Hedberg 		struct sk_buff *skb;
7175fb0e32SJohan Hedberg 
7275fb0e32SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
7375fb0e32SJohan Hedberg 		 * reset complete event during init and any pending
7475fb0e32SJohan Hedberg 		 * command will never be completed. In such a case we
7575fb0e32SJohan Hedberg 		 * need to resend whatever was the last sent
7675fb0e32SJohan Hedberg 		 * command.
7775fb0e32SJohan Hedberg 		 */
7875fb0e32SJohan Hedberg 
791036b890SAndrei Emeltchenko 		if (cmd != HCI_OP_RESET || opcode == HCI_OP_RESET)
8023bb5763SJohan Hedberg 			return;
811da177e4SLinus Torvalds 
8275fb0e32SJohan Hedberg 		skb = skb_clone(hdev->sent_cmd, GFP_ATOMIC);
8375fb0e32SJohan Hedberg 		if (skb) {
8475fb0e32SJohan Hedberg 			skb_queue_head(&hdev->cmd_q, skb);
8575fb0e32SJohan Hedberg 			queue_work(hdev->workqueue, &hdev->cmd_work);
8675fb0e32SJohan Hedberg 		}
8775fb0e32SJohan Hedberg 
8875fb0e32SJohan Hedberg 		return;
8975fb0e32SJohan Hedberg 	}
9075fb0e32SJohan Hedberg 
911da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
921da177e4SLinus Torvalds 		hdev->req_result = result;
931da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
941da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
951da177e4SLinus Torvalds 	}
961da177e4SLinus Torvalds }
971da177e4SLinus Torvalds 
981da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
991da177e4SLinus Torvalds {
1001da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
1011da177e4SLinus Torvalds 
1021da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1031da177e4SLinus Torvalds 		hdev->req_result = err;
1041da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
1051da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1061da177e4SLinus Torvalds 	}
1071da177e4SLinus Torvalds }
1081da177e4SLinus Torvalds 
1091da177e4SLinus Torvalds /* Execute request and wait for completion. */
110a8c5fb1aSGustavo Padovan static int __hci_request(struct hci_dev *hdev,
111a8c5fb1aSGustavo Padovan 			 void (*req)(struct hci_dev *hdev, unsigned long opt),
1121da177e4SLinus Torvalds 			 unsigned long opt, __u32 timeout)
1131da177e4SLinus Torvalds {
1141da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
1151da177e4SLinus Torvalds 	int err = 0;
1161da177e4SLinus Torvalds 
1171da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
1181da177e4SLinus Torvalds 
1191da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
1201da177e4SLinus Torvalds 
1211da177e4SLinus Torvalds 	add_wait_queue(&hdev->req_wait_q, &wait);
1221da177e4SLinus Torvalds 	set_current_state(TASK_INTERRUPTIBLE);
1231da177e4SLinus Torvalds 
1241da177e4SLinus Torvalds 	req(hdev, opt);
1251da177e4SLinus Torvalds 	schedule_timeout(timeout);
1261da177e4SLinus Torvalds 
1271da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
1281da177e4SLinus Torvalds 
1291da177e4SLinus Torvalds 	if (signal_pending(current))
1301da177e4SLinus Torvalds 		return -EINTR;
1311da177e4SLinus Torvalds 
1321da177e4SLinus Torvalds 	switch (hdev->req_status) {
1331da177e4SLinus Torvalds 	case HCI_REQ_DONE:
134e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
1351da177e4SLinus Torvalds 		break;
1361da177e4SLinus Torvalds 
1371da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
1381da177e4SLinus Torvalds 		err = -hdev->req_result;
1391da177e4SLinus Torvalds 		break;
1401da177e4SLinus Torvalds 
1411da177e4SLinus Torvalds 	default:
1421da177e4SLinus Torvalds 		err = -ETIMEDOUT;
1431da177e4SLinus Torvalds 		break;
1443ff50b79SStephen Hemminger 	}
1451da177e4SLinus Torvalds 
146a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
1471da177e4SLinus Torvalds 
1481da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
1491da177e4SLinus Torvalds 
1501da177e4SLinus Torvalds 	return err;
1511da177e4SLinus Torvalds }
1521da177e4SLinus Torvalds 
1536039aa73SGustavo Padovan static int hci_request(struct hci_dev *hdev,
1546039aa73SGustavo Padovan 		       void (*req)(struct hci_dev *hdev, unsigned long opt),
1551da177e4SLinus Torvalds 		       unsigned long opt, __u32 timeout)
1561da177e4SLinus Torvalds {
1571da177e4SLinus Torvalds 	int ret;
1581da177e4SLinus Torvalds 
1597c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
1607c6a329eSMarcel Holtmann 		return -ENETDOWN;
1617c6a329eSMarcel Holtmann 
1621da177e4SLinus Torvalds 	/* Serialize all requests */
1631da177e4SLinus Torvalds 	hci_req_lock(hdev);
1641da177e4SLinus Torvalds 	ret = __hci_request(hdev, req, opt, timeout);
1651da177e4SLinus Torvalds 	hci_req_unlock(hdev);
1661da177e4SLinus Torvalds 
1671da177e4SLinus Torvalds 	return ret;
1681da177e4SLinus Torvalds }
1691da177e4SLinus Torvalds 
1701da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
1711da177e4SLinus Torvalds {
1721da177e4SLinus Torvalds 	BT_DBG("%s %ld", hdev->name, opt);
1731da177e4SLinus Torvalds 
1741da177e4SLinus Torvalds 	/* Reset device */
175f630cf0dSGustavo F. Padovan 	set_bit(HCI_RESET, &hdev->flags);
176a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
1771da177e4SLinus Torvalds }
1781da177e4SLinus Torvalds 
179e61ef499SAndrei Emeltchenko static void bredr_init(struct hci_dev *hdev)
1801da177e4SLinus Torvalds {
1812455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
1822455a3eaSAndrei Emeltchenko 
1831da177e4SLinus Torvalds 	/* Read Local Supported Features */
184a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
1851da177e4SLinus Torvalds 
1861143e5a6SMarcel Holtmann 	/* Read Local Version */
187a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
1881da177e4SLinus Torvalds }
1891da177e4SLinus Torvalds 
190e61ef499SAndrei Emeltchenko static void amp_init(struct hci_dev *hdev)
191e61ef499SAndrei Emeltchenko {
1922455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
1932455a3eaSAndrei Emeltchenko 
194e61ef499SAndrei Emeltchenko 	/* Read Local Version */
195e61ef499SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
1966bcbc489SAndrei Emeltchenko 
1976bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
1986bcbc489SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
199e71dfabaSAndrei Emeltchenko 
200e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
201e71dfabaSAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
202e61ef499SAndrei Emeltchenko }
203e61ef499SAndrei Emeltchenko 
204e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
205e61ef499SAndrei Emeltchenko {
206e61ef499SAndrei Emeltchenko 	struct sk_buff *skb;
207e61ef499SAndrei Emeltchenko 
208e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
209e61ef499SAndrei Emeltchenko 
210e61ef499SAndrei Emeltchenko 	/* Driver initialization */
211e61ef499SAndrei Emeltchenko 
212e61ef499SAndrei Emeltchenko 	/* Special commands */
213e61ef499SAndrei Emeltchenko 	while ((skb = skb_dequeue(&hdev->driver_init))) {
214e61ef499SAndrei Emeltchenko 		bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
215e61ef499SAndrei Emeltchenko 		skb->dev = (void *) hdev;
216e61ef499SAndrei Emeltchenko 
217e61ef499SAndrei Emeltchenko 		skb_queue_tail(&hdev->cmd_q, skb);
218e61ef499SAndrei Emeltchenko 		queue_work(hdev->workqueue, &hdev->cmd_work);
219e61ef499SAndrei Emeltchenko 	}
220e61ef499SAndrei Emeltchenko 	skb_queue_purge(&hdev->driver_init);
221e61ef499SAndrei Emeltchenko 
22211778716SAndrei Emeltchenko 	/* Reset */
22311778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
22411778716SAndrei Emeltchenko 		hci_reset_req(hdev, 0);
22511778716SAndrei Emeltchenko 
226e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
227e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
228e61ef499SAndrei Emeltchenko 		bredr_init(hdev);
229e61ef499SAndrei Emeltchenko 		break;
230e61ef499SAndrei Emeltchenko 
231e61ef499SAndrei Emeltchenko 	case HCI_AMP:
232e61ef499SAndrei Emeltchenko 		amp_init(hdev);
233e61ef499SAndrei Emeltchenko 		break;
234e61ef499SAndrei Emeltchenko 
235e61ef499SAndrei Emeltchenko 	default:
236e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
237e61ef499SAndrei Emeltchenko 		break;
238e61ef499SAndrei Emeltchenko 	}
239e61ef499SAndrei Emeltchenko }
240e61ef499SAndrei Emeltchenko 
2411da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
2421da177e4SLinus Torvalds {
2431da177e4SLinus Torvalds 	__u8 scan = opt;
2441da177e4SLinus Torvalds 
2451da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, scan);
2461da177e4SLinus Torvalds 
2471da177e4SLinus Torvalds 	/* Inquiry and Page scans */
248a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
2491da177e4SLinus Torvalds }
2501da177e4SLinus Torvalds 
2511da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
2521da177e4SLinus Torvalds {
2531da177e4SLinus Torvalds 	__u8 auth = opt;
2541da177e4SLinus Torvalds 
2551da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, auth);
2561da177e4SLinus Torvalds 
2571da177e4SLinus Torvalds 	/* Authentication */
258a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
2591da177e4SLinus Torvalds }
2601da177e4SLinus Torvalds 
2611da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
2621da177e4SLinus Torvalds {
2631da177e4SLinus Torvalds 	__u8 encrypt = opt;
2641da177e4SLinus Torvalds 
2651da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, encrypt);
2661da177e4SLinus Torvalds 
267e4e8e37cSMarcel Holtmann 	/* Encryption */
268a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
2691da177e4SLinus Torvalds }
2701da177e4SLinus Torvalds 
271e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt)
272e4e8e37cSMarcel Holtmann {
273e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
274e4e8e37cSMarcel Holtmann 
275a418b893SMarcel Holtmann 	BT_DBG("%s %x", hdev->name, policy);
276e4e8e37cSMarcel Holtmann 
277e4e8e37cSMarcel Holtmann 	/* Default link policy */
278e4e8e37cSMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
279e4e8e37cSMarcel Holtmann }
280e4e8e37cSMarcel Holtmann 
2811da177e4SLinus Torvalds /* Get HCI device by index.
2821da177e4SLinus Torvalds  * Device is held on return. */
2831da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
2841da177e4SLinus Torvalds {
2858035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
2861da177e4SLinus Torvalds 
2871da177e4SLinus Torvalds 	BT_DBG("%d", index);
2881da177e4SLinus Torvalds 
2891da177e4SLinus Torvalds 	if (index < 0)
2901da177e4SLinus Torvalds 		return NULL;
2911da177e4SLinus Torvalds 
2921da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
2938035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
2941da177e4SLinus Torvalds 		if (d->id == index) {
2951da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
2961da177e4SLinus Torvalds 			break;
2971da177e4SLinus Torvalds 		}
2981da177e4SLinus Torvalds 	}
2991da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
3001da177e4SLinus Torvalds 	return hdev;
3011da177e4SLinus Torvalds }
3021da177e4SLinus Torvalds 
3031da177e4SLinus Torvalds /* ---- Inquiry support ---- */
304ff9ef578SJohan Hedberg 
30530dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
30630dc78e1SJohan Hedberg {
30730dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
30830dc78e1SJohan Hedberg 
3096fbe195dSAndre Guedes 	switch (discov->state) {
310343f935bSAndre Guedes 	case DISCOVERY_FINDING:
3116fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
31230dc78e1SJohan Hedberg 		return true;
31330dc78e1SJohan Hedberg 
3146fbe195dSAndre Guedes 	default:
31530dc78e1SJohan Hedberg 		return false;
31630dc78e1SJohan Hedberg 	}
3176fbe195dSAndre Guedes }
31830dc78e1SJohan Hedberg 
319ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
320ff9ef578SJohan Hedberg {
321ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
322ff9ef578SJohan Hedberg 
323ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
324ff9ef578SJohan Hedberg 		return;
325ff9ef578SJohan Hedberg 
326ff9ef578SJohan Hedberg 	switch (state) {
327ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
3287b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
329ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
330ff9ef578SJohan Hedberg 		break;
331ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
332ff9ef578SJohan Hedberg 		break;
333343f935bSAndre Guedes 	case DISCOVERY_FINDING:
334ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
335ff9ef578SJohan Hedberg 		break;
33630dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
33730dc78e1SJohan Hedberg 		break;
338ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
339ff9ef578SJohan Hedberg 		break;
340ff9ef578SJohan Hedberg 	}
341ff9ef578SJohan Hedberg 
342ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
343ff9ef578SJohan Hedberg }
344ff9ef578SJohan Hedberg 
3451da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
3461da177e4SLinus Torvalds {
34730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
348b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
3491da177e4SLinus Torvalds 
350561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
351561aafbcSJohan Hedberg 		list_del(&p->all);
352b57c1a56SJohan Hedberg 		kfree(p);
3531da177e4SLinus Torvalds 	}
354561aafbcSJohan Hedberg 
355561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
356561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
3571da177e4SLinus Torvalds }
3581da177e4SLinus Torvalds 
359a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
360a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
3611da177e4SLinus Torvalds {
36230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
3631da177e4SLinus Torvalds 	struct inquiry_entry *e;
3641da177e4SLinus Torvalds 
3656ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
3661da177e4SLinus Torvalds 
367561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
3681da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
3691da177e4SLinus Torvalds 			return e;
3701da177e4SLinus Torvalds 	}
3711da177e4SLinus Torvalds 
372b57c1a56SJohan Hedberg 	return NULL;
373b57c1a56SJohan Hedberg }
374b57c1a56SJohan Hedberg 
375561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
376561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
377561aafbcSJohan Hedberg {
37830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
379561aafbcSJohan Hedberg 	struct inquiry_entry *e;
380561aafbcSJohan Hedberg 
3816ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
382561aafbcSJohan Hedberg 
383561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
384561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
385561aafbcSJohan Hedberg 			return e;
386561aafbcSJohan Hedberg 	}
387561aafbcSJohan Hedberg 
388561aafbcSJohan Hedberg 	return NULL;
389561aafbcSJohan Hedberg }
390561aafbcSJohan Hedberg 
39130dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
39230dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
39330dc78e1SJohan Hedberg 						       int state)
39430dc78e1SJohan Hedberg {
39530dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
39630dc78e1SJohan Hedberg 	struct inquiry_entry *e;
39730dc78e1SJohan Hedberg 
3986ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
39930dc78e1SJohan Hedberg 
40030dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
40130dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
40230dc78e1SJohan Hedberg 			return e;
40330dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
40430dc78e1SJohan Hedberg 			return e;
40530dc78e1SJohan Hedberg 	}
40630dc78e1SJohan Hedberg 
40730dc78e1SJohan Hedberg 	return NULL;
40830dc78e1SJohan Hedberg }
40930dc78e1SJohan Hedberg 
410a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
411a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
412a3d4e20aSJohan Hedberg {
413a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
414a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
415a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
416a3d4e20aSJohan Hedberg 
417a3d4e20aSJohan Hedberg 	list_del(&ie->list);
418a3d4e20aSJohan Hedberg 
419a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
420a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
421a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
422a3d4e20aSJohan Hedberg 			break;
423a3d4e20aSJohan Hedberg 		pos = &p->list;
424a3d4e20aSJohan Hedberg 	}
425a3d4e20aSJohan Hedberg 
426a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
427a3d4e20aSJohan Hedberg }
428a3d4e20aSJohan Hedberg 
4293175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
430388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
4311da177e4SLinus Torvalds {
43230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
43370f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
4341da177e4SLinus Torvalds 
4356ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
4361da177e4SLinus Torvalds 
437388fc8faSJohan Hedberg 	if (ssp)
438388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
439388fc8faSJohan Hedberg 
44070f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
441a3d4e20aSJohan Hedberg 	if (ie) {
442388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
443388fc8faSJohan Hedberg 			*ssp = true;
444388fc8faSJohan Hedberg 
445a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
446a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
447a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
448a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
449a3d4e20aSJohan Hedberg 		}
450a3d4e20aSJohan Hedberg 
451561aafbcSJohan Hedberg 		goto update;
452a3d4e20aSJohan Hedberg 	}
453561aafbcSJohan Hedberg 
4541da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
45570f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
45670f23020SAndrei Emeltchenko 	if (!ie)
4573175405bSJohan Hedberg 		return false;
45870f23020SAndrei Emeltchenko 
459561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
460561aafbcSJohan Hedberg 
461561aafbcSJohan Hedberg 	if (name_known) {
462561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
463561aafbcSJohan Hedberg 	} else {
464561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
465561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
466561aafbcSJohan Hedberg 	}
467561aafbcSJohan Hedberg 
468561aafbcSJohan Hedberg update:
469561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
470561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
471561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
472561aafbcSJohan Hedberg 		list_del(&ie->list);
4731da177e4SLinus Torvalds 	}
4741da177e4SLinus Torvalds 
47570f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
47670f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
4771da177e4SLinus Torvalds 	cache->timestamp = jiffies;
4783175405bSJohan Hedberg 
4793175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
4803175405bSJohan Hedberg 		return false;
4813175405bSJohan Hedberg 
4823175405bSJohan Hedberg 	return true;
4831da177e4SLinus Torvalds }
4841da177e4SLinus Torvalds 
4851da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
4861da177e4SLinus Torvalds {
48730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
4881da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
4891da177e4SLinus Torvalds 	struct inquiry_entry *e;
4901da177e4SLinus Torvalds 	int copied = 0;
4911da177e4SLinus Torvalds 
492561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
4931da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
494b57c1a56SJohan Hedberg 
495b57c1a56SJohan Hedberg 		if (copied >= num)
496b57c1a56SJohan Hedberg 			break;
497b57c1a56SJohan Hedberg 
4981da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
4991da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
5001da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
5011da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
5021da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
5031da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
504b57c1a56SJohan Hedberg 
5051da177e4SLinus Torvalds 		info++;
506b57c1a56SJohan Hedberg 		copied++;
5071da177e4SLinus Torvalds 	}
5081da177e4SLinus Torvalds 
5091da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
5101da177e4SLinus Torvalds 	return copied;
5111da177e4SLinus Torvalds }
5121da177e4SLinus Torvalds 
5131da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
5141da177e4SLinus Torvalds {
5151da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
5161da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
5171da177e4SLinus Torvalds 
5181da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
5191da177e4SLinus Torvalds 
5201da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
5211da177e4SLinus Torvalds 		return;
5221da177e4SLinus Torvalds 
5231da177e4SLinus Torvalds 	/* Start Inquiry */
5241da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
5251da177e4SLinus Torvalds 	cp.length  = ir->length;
5261da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
527a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
5281da177e4SLinus Torvalds }
5291da177e4SLinus Torvalds 
5301da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
5311da177e4SLinus Torvalds {
5321da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
5331da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
5341da177e4SLinus Torvalds 	struct hci_dev *hdev;
5351da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
5361da177e4SLinus Torvalds 	long timeo;
5371da177e4SLinus Torvalds 	__u8 *buf;
5381da177e4SLinus Torvalds 
5391da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
5401da177e4SLinus Torvalds 		return -EFAULT;
5411da177e4SLinus Torvalds 
5425a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
5435a08ecceSAndrei Emeltchenko 	if (!hdev)
5441da177e4SLinus Torvalds 		return -ENODEV;
5451da177e4SLinus Torvalds 
54609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5471da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
548a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
5491da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
5501da177e4SLinus Torvalds 		do_inquiry = 1;
5511da177e4SLinus Torvalds 	}
55209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
5531da177e4SLinus Torvalds 
55404837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
55570f23020SAndrei Emeltchenko 
55670f23020SAndrei Emeltchenko 	if (do_inquiry) {
55770f23020SAndrei Emeltchenko 		err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
55870f23020SAndrei Emeltchenko 		if (err < 0)
5591da177e4SLinus Torvalds 			goto done;
56070f23020SAndrei Emeltchenko 	}
5611da177e4SLinus Torvalds 
5628fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
5638fc9ced3SGustavo Padovan 	 * 255 entries
5648fc9ced3SGustavo Padovan 	 */
5651da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
5661da177e4SLinus Torvalds 
5671da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
5681da177e4SLinus Torvalds 	 * copy it to the user space.
5691da177e4SLinus Torvalds 	 */
57070f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
57170f23020SAndrei Emeltchenko 	if (!buf) {
5721da177e4SLinus Torvalds 		err = -ENOMEM;
5731da177e4SLinus Torvalds 		goto done;
5741da177e4SLinus Torvalds 	}
5751da177e4SLinus Torvalds 
57609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5771da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
57809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
5791da177e4SLinus Torvalds 
5801da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
5811da177e4SLinus Torvalds 
5821da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
5831da177e4SLinus Torvalds 		ptr += sizeof(ir);
5841da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
5851da177e4SLinus Torvalds 				 ir.num_rsp))
5861da177e4SLinus Torvalds 			err = -EFAULT;
5871da177e4SLinus Torvalds 	} else
5881da177e4SLinus Torvalds 		err = -EFAULT;
5891da177e4SLinus Torvalds 
5901da177e4SLinus Torvalds 	kfree(buf);
5911da177e4SLinus Torvalds 
5921da177e4SLinus Torvalds done:
5931da177e4SLinus Torvalds 	hci_dev_put(hdev);
5941da177e4SLinus Torvalds 	return err;
5951da177e4SLinus Torvalds }
5961da177e4SLinus Torvalds 
5971da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
5981da177e4SLinus Torvalds 
5991da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
6001da177e4SLinus Torvalds {
6011da177e4SLinus Torvalds 	struct hci_dev *hdev;
6021da177e4SLinus Torvalds 	int ret = 0;
6031da177e4SLinus Torvalds 
6045a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
6055a08ecceSAndrei Emeltchenko 	if (!hdev)
6061da177e4SLinus Torvalds 		return -ENODEV;
6071da177e4SLinus Torvalds 
6081da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
6091da177e4SLinus Torvalds 
6101da177e4SLinus Torvalds 	hci_req_lock(hdev);
6111da177e4SLinus Torvalds 
61294324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
61394324962SJohan Hovold 		ret = -ENODEV;
61494324962SJohan Hovold 		goto done;
61594324962SJohan Hovold 	}
61694324962SJohan Hovold 
617611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
618611b30f7SMarcel Holtmann 		ret = -ERFKILL;
619611b30f7SMarcel Holtmann 		goto done;
620611b30f7SMarcel Holtmann 	}
621611b30f7SMarcel Holtmann 
6221da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
6231da177e4SLinus Torvalds 		ret = -EALREADY;
6241da177e4SLinus Torvalds 		goto done;
6251da177e4SLinus Torvalds 	}
6261da177e4SLinus Torvalds 
6271da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
6281da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
6291da177e4SLinus Torvalds 
63007e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
63107e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
63207e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
633943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
634943da25dSMarcel Holtmann 
6351da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
6361da177e4SLinus Torvalds 		ret = -EIO;
6371da177e4SLinus Torvalds 		goto done;
6381da177e4SLinus Torvalds 	}
6391da177e4SLinus Torvalds 
6401da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
6411da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
6421da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
643a5040efaSJohan Hedberg 		hdev->init_last_cmd = 0;
6441da177e4SLinus Torvalds 
6455f246e89SAndrei Emeltchenko 		ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
6461da177e4SLinus Torvalds 
6471da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
6481da177e4SLinus Torvalds 	}
6491da177e4SLinus Torvalds 
6501da177e4SLinus Torvalds 	if (!ret) {
6511da177e4SLinus Torvalds 		hci_dev_hold(hdev);
6521da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
6531da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
654bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
655bb4b2a9aSAndrei Emeltchenko 		    mgmt_valid_hdev(hdev)) {
65609fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
657744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
65809fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
65956e5cb86SJohan Hedberg 		}
6601da177e4SLinus Torvalds 	} else {
6611da177e4SLinus Torvalds 		/* Init failed, cleanup */
6623eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
663c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
664b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
6651da177e4SLinus Torvalds 
6661da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
6671da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
6681da177e4SLinus Torvalds 
6691da177e4SLinus Torvalds 		if (hdev->flush)
6701da177e4SLinus Torvalds 			hdev->flush(hdev);
6711da177e4SLinus Torvalds 
6721da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
6731da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
6741da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
6751da177e4SLinus Torvalds 		}
6761da177e4SLinus Torvalds 
6771da177e4SLinus Torvalds 		hdev->close(hdev);
6781da177e4SLinus Torvalds 		hdev->flags = 0;
6791da177e4SLinus Torvalds 	}
6801da177e4SLinus Torvalds 
6811da177e4SLinus Torvalds done:
6821da177e4SLinus Torvalds 	hci_req_unlock(hdev);
6831da177e4SLinus Torvalds 	hci_dev_put(hdev);
6841da177e4SLinus Torvalds 	return ret;
6851da177e4SLinus Torvalds }
6861da177e4SLinus Torvalds 
6871da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
6881da177e4SLinus Torvalds {
6891da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
6901da177e4SLinus Torvalds 
69128b75a89SAndre Guedes 	cancel_work_sync(&hdev->le_scan);
69228b75a89SAndre Guedes 
69378c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
69478c04c0bSVinicius Costa Gomes 
6951da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
6961da177e4SLinus Torvalds 	hci_req_lock(hdev);
6971da177e4SLinus Torvalds 
6981da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
699b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7001da177e4SLinus Torvalds 		hci_req_unlock(hdev);
7011da177e4SLinus Torvalds 		return 0;
7021da177e4SLinus Torvalds 	}
7031da177e4SLinus Torvalds 
7043eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
7053eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
706b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
7071da177e4SLinus Torvalds 
70816ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
709e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
71016ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
7115e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
71216ab91abSJohan Hedberg 	}
71316ab91abSJohan Hedberg 
714a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
7157d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
7167d78525dSJohan Hedberg 
7177ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
7187ba8b4beSAndre Guedes 
71909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
7201da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
7211da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
72209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7231da177e4SLinus Torvalds 
7241da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
7251da177e4SLinus Torvalds 
7261da177e4SLinus Torvalds 	if (hdev->flush)
7271da177e4SLinus Torvalds 		hdev->flush(hdev);
7281da177e4SLinus Torvalds 
7291da177e4SLinus Torvalds 	/* Reset device */
7301da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7311da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
7328af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
733a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
7341da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
7355f246e89SAndrei Emeltchenko 		__hci_request(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
7361da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
7371da177e4SLinus Torvalds 	}
7381da177e4SLinus Torvalds 
739c347b765SGustavo F. Padovan 	/* flush cmd  work */
740c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
7411da177e4SLinus Torvalds 
7421da177e4SLinus Torvalds 	/* Drop queues */
7431da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
7441da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7451da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
7461da177e4SLinus Torvalds 
7471da177e4SLinus Torvalds 	/* Drop last sent command */
7481da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
749b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7501da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
7511da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
7521da177e4SLinus Torvalds 	}
7531da177e4SLinus Torvalds 
7541da177e4SLinus Torvalds 	/* After this point our queues are empty
7551da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
7561da177e4SLinus Torvalds 	hdev->close(hdev);
7571da177e4SLinus Torvalds 
758bb4b2a9aSAndrei Emeltchenko 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
759bb4b2a9aSAndrei Emeltchenko 	    mgmt_valid_hdev(hdev)) {
76009fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
761744cf19eSJohan Hedberg 		mgmt_powered(hdev, 0);
76209fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
7638ee56540SMarcel Holtmann 	}
7645add6af8SJohan Hedberg 
7651da177e4SLinus Torvalds 	/* Clear flags */
7661da177e4SLinus Torvalds 	hdev->flags = 0;
7671da177e4SLinus Torvalds 
768e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
76909b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
770e59fda8dSJohan Hedberg 
7711da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7721da177e4SLinus Torvalds 
7731da177e4SLinus Torvalds 	hci_dev_put(hdev);
7741da177e4SLinus Torvalds 	return 0;
7751da177e4SLinus Torvalds }
7761da177e4SLinus Torvalds 
7771da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
7781da177e4SLinus Torvalds {
7791da177e4SLinus Torvalds 	struct hci_dev *hdev;
7801da177e4SLinus Torvalds 	int err;
7811da177e4SLinus Torvalds 
78270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
78370f23020SAndrei Emeltchenko 	if (!hdev)
7841da177e4SLinus Torvalds 		return -ENODEV;
7858ee56540SMarcel Holtmann 
7868ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
7878ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
7888ee56540SMarcel Holtmann 
7891da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
7908ee56540SMarcel Holtmann 
7911da177e4SLinus Torvalds 	hci_dev_put(hdev);
7921da177e4SLinus Torvalds 	return err;
7931da177e4SLinus Torvalds }
7941da177e4SLinus Torvalds 
7951da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
7961da177e4SLinus Torvalds {
7971da177e4SLinus Torvalds 	struct hci_dev *hdev;
7981da177e4SLinus Torvalds 	int ret = 0;
7991da177e4SLinus Torvalds 
80070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
80170f23020SAndrei Emeltchenko 	if (!hdev)
8021da177e4SLinus Torvalds 		return -ENODEV;
8031da177e4SLinus Torvalds 
8041da177e4SLinus Torvalds 	hci_req_lock(hdev);
8051da177e4SLinus Torvalds 
8061da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
8071da177e4SLinus Torvalds 		goto done;
8081da177e4SLinus Torvalds 
8091da177e4SLinus Torvalds 	/* Drop queues */
8101da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
8111da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
8121da177e4SLinus Torvalds 
81309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
8141da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
8151da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
81609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
8171da177e4SLinus Torvalds 
8181da177e4SLinus Torvalds 	if (hdev->flush)
8191da177e4SLinus Torvalds 		hdev->flush(hdev);
8201da177e4SLinus Torvalds 
8211da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
8226ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
8231da177e4SLinus Torvalds 
8241da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
8255f246e89SAndrei Emeltchenko 		ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
8261da177e4SLinus Torvalds 
8271da177e4SLinus Torvalds done:
8281da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8291da177e4SLinus Torvalds 	hci_dev_put(hdev);
8301da177e4SLinus Torvalds 	return ret;
8311da177e4SLinus Torvalds }
8321da177e4SLinus Torvalds 
8331da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
8341da177e4SLinus Torvalds {
8351da177e4SLinus Torvalds 	struct hci_dev *hdev;
8361da177e4SLinus Torvalds 	int ret = 0;
8371da177e4SLinus Torvalds 
83870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
83970f23020SAndrei Emeltchenko 	if (!hdev)
8401da177e4SLinus Torvalds 		return -ENODEV;
8411da177e4SLinus Torvalds 
8421da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
8431da177e4SLinus Torvalds 
8441da177e4SLinus Torvalds 	hci_dev_put(hdev);
8451da177e4SLinus Torvalds 
8461da177e4SLinus Torvalds 	return ret;
8471da177e4SLinus Torvalds }
8481da177e4SLinus Torvalds 
8491da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
8501da177e4SLinus Torvalds {
8511da177e4SLinus Torvalds 	struct hci_dev *hdev;
8521da177e4SLinus Torvalds 	struct hci_dev_req dr;
8531da177e4SLinus Torvalds 	int err = 0;
8541da177e4SLinus Torvalds 
8551da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
8561da177e4SLinus Torvalds 		return -EFAULT;
8571da177e4SLinus Torvalds 
85870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
85970f23020SAndrei Emeltchenko 	if (!hdev)
8601da177e4SLinus Torvalds 		return -ENODEV;
8611da177e4SLinus Torvalds 
8621da177e4SLinus Torvalds 	switch (cmd) {
8631da177e4SLinus Torvalds 	case HCISETAUTH:
86404837f64SMarcel Holtmann 		err = hci_request(hdev, hci_auth_req, dr.dev_opt,
8655f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
8661da177e4SLinus Torvalds 		break;
8671da177e4SLinus Torvalds 
8681da177e4SLinus Torvalds 	case HCISETENCRYPT:
8691da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
8701da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
8711da177e4SLinus Torvalds 			break;
8721da177e4SLinus Torvalds 		}
8731da177e4SLinus Torvalds 
8741da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
8751da177e4SLinus Torvalds 			/* Auth must be enabled first */
87604837f64SMarcel Holtmann 			err = hci_request(hdev, hci_auth_req, dr.dev_opt,
8775f246e89SAndrei Emeltchenko 					  HCI_INIT_TIMEOUT);
8781da177e4SLinus Torvalds 			if (err)
8791da177e4SLinus Torvalds 				break;
8801da177e4SLinus Torvalds 		}
8811da177e4SLinus Torvalds 
88204837f64SMarcel Holtmann 		err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
8835f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
8841da177e4SLinus Torvalds 		break;
8851da177e4SLinus Torvalds 
8861da177e4SLinus Torvalds 	case HCISETSCAN:
88704837f64SMarcel Holtmann 		err = hci_request(hdev, hci_scan_req, dr.dev_opt,
8885f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
8891da177e4SLinus Torvalds 		break;
8901da177e4SLinus Torvalds 
8911da177e4SLinus Torvalds 	case HCISETLINKPOL:
892e4e8e37cSMarcel Holtmann 		err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
8935f246e89SAndrei Emeltchenko 				  HCI_INIT_TIMEOUT);
8941da177e4SLinus Torvalds 		break;
8951da177e4SLinus Torvalds 
8961da177e4SLinus Torvalds 	case HCISETLINKMODE:
897e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
898e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
899e4e8e37cSMarcel Holtmann 		break;
900e4e8e37cSMarcel Holtmann 
901e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
902e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
9031da177e4SLinus Torvalds 		break;
9041da177e4SLinus Torvalds 
9051da177e4SLinus Torvalds 	case HCISETACLMTU:
9061da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
9071da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
9081da177e4SLinus Torvalds 		break;
9091da177e4SLinus Torvalds 
9101da177e4SLinus Torvalds 	case HCISETSCOMTU:
9111da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
9121da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
9131da177e4SLinus Torvalds 		break;
9141da177e4SLinus Torvalds 
9151da177e4SLinus Torvalds 	default:
9161da177e4SLinus Torvalds 		err = -EINVAL;
9171da177e4SLinus Torvalds 		break;
9181da177e4SLinus Torvalds 	}
919e4e8e37cSMarcel Holtmann 
9201da177e4SLinus Torvalds 	hci_dev_put(hdev);
9211da177e4SLinus Torvalds 	return err;
9221da177e4SLinus Torvalds }
9231da177e4SLinus Torvalds 
9241da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
9251da177e4SLinus Torvalds {
9268035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
9271da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
9281da177e4SLinus Torvalds 	struct hci_dev_req *dr;
9291da177e4SLinus Torvalds 	int n = 0, size, err;
9301da177e4SLinus Torvalds 	__u16 dev_num;
9311da177e4SLinus Torvalds 
9321da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
9331da177e4SLinus Torvalds 		return -EFAULT;
9341da177e4SLinus Torvalds 
9351da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
9361da177e4SLinus Torvalds 		return -EINVAL;
9371da177e4SLinus Torvalds 
9381da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
9391da177e4SLinus Torvalds 
94070f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
94170f23020SAndrei Emeltchenko 	if (!dl)
9421da177e4SLinus Torvalds 		return -ENOMEM;
9431da177e4SLinus Torvalds 
9441da177e4SLinus Torvalds 	dr = dl->dev_req;
9451da177e4SLinus Torvalds 
946f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
9478035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
948a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
949e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
950c542a06cSJohan Hedberg 
951a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
952a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
953c542a06cSJohan Hedberg 
9541da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
9551da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
956c542a06cSJohan Hedberg 
9571da177e4SLinus Torvalds 		if (++n >= dev_num)
9581da177e4SLinus Torvalds 			break;
9591da177e4SLinus Torvalds 	}
960f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
9611da177e4SLinus Torvalds 
9621da177e4SLinus Torvalds 	dl->dev_num = n;
9631da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
9641da177e4SLinus Torvalds 
9651da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
9661da177e4SLinus Torvalds 	kfree(dl);
9671da177e4SLinus Torvalds 
9681da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
9691da177e4SLinus Torvalds }
9701da177e4SLinus Torvalds 
9711da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
9721da177e4SLinus Torvalds {
9731da177e4SLinus Torvalds 	struct hci_dev *hdev;
9741da177e4SLinus Torvalds 	struct hci_dev_info di;
9751da177e4SLinus Torvalds 	int err = 0;
9761da177e4SLinus Torvalds 
9771da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
9781da177e4SLinus Torvalds 		return -EFAULT;
9791da177e4SLinus Torvalds 
98070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
98170f23020SAndrei Emeltchenko 	if (!hdev)
9821da177e4SLinus Torvalds 		return -ENODEV;
9831da177e4SLinus Torvalds 
984a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
9853243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
986ab81cbf9SJohan Hedberg 
987a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
988a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
989c542a06cSJohan Hedberg 
9901da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
9911da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
992943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
9931da177e4SLinus Torvalds 	di.flags    = hdev->flags;
9941da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
995572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
9961da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
9971da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
9981da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
9991da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
1000572c7f84SJohan Hedberg 	} else {
1001572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
1002572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
1003572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
1004572c7f84SJohan Hedberg 		di.sco_pkts = 0;
1005572c7f84SJohan Hedberg 	}
10061da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
10071da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
10081da177e4SLinus Torvalds 
10091da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
10101da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
10111da177e4SLinus Torvalds 
10121da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
10131da177e4SLinus Torvalds 		err = -EFAULT;
10141da177e4SLinus Torvalds 
10151da177e4SLinus Torvalds 	hci_dev_put(hdev);
10161da177e4SLinus Torvalds 
10171da177e4SLinus Torvalds 	return err;
10181da177e4SLinus Torvalds }
10191da177e4SLinus Torvalds 
10201da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
10211da177e4SLinus Torvalds 
1022611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1023611b30f7SMarcel Holtmann {
1024611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1025611b30f7SMarcel Holtmann 
1026611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1027611b30f7SMarcel Holtmann 
1028611b30f7SMarcel Holtmann 	if (!blocked)
1029611b30f7SMarcel Holtmann 		return 0;
1030611b30f7SMarcel Holtmann 
1031611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1032611b30f7SMarcel Holtmann 
1033611b30f7SMarcel Holtmann 	return 0;
1034611b30f7SMarcel Holtmann }
1035611b30f7SMarcel Holtmann 
1036611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1037611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1038611b30f7SMarcel Holtmann };
1039611b30f7SMarcel Holtmann 
1040ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1041ab81cbf9SJohan Hedberg {
1042ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
1043ab81cbf9SJohan Hedberg 
1044ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1045ab81cbf9SJohan Hedberg 
1046ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
1047ab81cbf9SJohan Hedberg 		return;
1048ab81cbf9SJohan Hedberg 
1049a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
10509345d40cSAndrei Emeltchenko 		schedule_delayed_work(&hdev->power_off, HCI_AUTO_OFF_TIMEOUT);
1051ab81cbf9SJohan Hedberg 
1052a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1053744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1054ab81cbf9SJohan Hedberg }
1055ab81cbf9SJohan Hedberg 
1056ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1057ab81cbf9SJohan Hedberg {
10583243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
10593243553fSJohan Hedberg 					    power_off.work);
1060ab81cbf9SJohan Hedberg 
1061ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1062ab81cbf9SJohan Hedberg 
10638ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1064ab81cbf9SJohan Hedberg }
1065ab81cbf9SJohan Hedberg 
106616ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
106716ab91abSJohan Hedberg {
106816ab91abSJohan Hedberg 	struct hci_dev *hdev;
106916ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
107016ab91abSJohan Hedberg 
107116ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
107216ab91abSJohan Hedberg 
107316ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
107416ab91abSJohan Hedberg 
107509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
107616ab91abSJohan Hedberg 
107716ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
107816ab91abSJohan Hedberg 
107916ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
108016ab91abSJohan Hedberg 
108109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
108216ab91abSJohan Hedberg }
108316ab91abSJohan Hedberg 
10842aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
10852aeb9a1aSJohan Hedberg {
10862aeb9a1aSJohan Hedberg 	struct list_head *p, *n;
10872aeb9a1aSJohan Hedberg 
10882aeb9a1aSJohan Hedberg 	list_for_each_safe(p, n, &hdev->uuids) {
10892aeb9a1aSJohan Hedberg 		struct bt_uuid *uuid;
10902aeb9a1aSJohan Hedberg 
10912aeb9a1aSJohan Hedberg 		uuid = list_entry(p, struct bt_uuid, list);
10922aeb9a1aSJohan Hedberg 
10932aeb9a1aSJohan Hedberg 		list_del(p);
10942aeb9a1aSJohan Hedberg 		kfree(uuid);
10952aeb9a1aSJohan Hedberg 	}
10962aeb9a1aSJohan Hedberg 
10972aeb9a1aSJohan Hedberg 	return 0;
10982aeb9a1aSJohan Hedberg }
10992aeb9a1aSJohan Hedberg 
110055ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
110155ed8ca1SJohan Hedberg {
110255ed8ca1SJohan Hedberg 	struct list_head *p, *n;
110355ed8ca1SJohan Hedberg 
110455ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
110555ed8ca1SJohan Hedberg 		struct link_key *key;
110655ed8ca1SJohan Hedberg 
110755ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
110855ed8ca1SJohan Hedberg 
110955ed8ca1SJohan Hedberg 		list_del(p);
111055ed8ca1SJohan Hedberg 		kfree(key);
111155ed8ca1SJohan Hedberg 	}
111255ed8ca1SJohan Hedberg 
111355ed8ca1SJohan Hedberg 	return 0;
111455ed8ca1SJohan Hedberg }
111555ed8ca1SJohan Hedberg 
1116b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1117b899efafSVinicius Costa Gomes {
1118b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1119b899efafSVinicius Costa Gomes 
1120b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1121b899efafSVinicius Costa Gomes 		list_del(&k->list);
1122b899efafSVinicius Costa Gomes 		kfree(k);
1123b899efafSVinicius Costa Gomes 	}
1124b899efafSVinicius Costa Gomes 
1125b899efafSVinicius Costa Gomes 	return 0;
1126b899efafSVinicius Costa Gomes }
1127b899efafSVinicius Costa Gomes 
112855ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
112955ed8ca1SJohan Hedberg {
113055ed8ca1SJohan Hedberg 	struct link_key *k;
113155ed8ca1SJohan Hedberg 
11328035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
113355ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
113455ed8ca1SJohan Hedberg 			return k;
113555ed8ca1SJohan Hedberg 
113655ed8ca1SJohan Hedberg 	return NULL;
113755ed8ca1SJohan Hedberg }
113855ed8ca1SJohan Hedberg 
1139745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1140d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1141d25e28abSJohan Hedberg {
1142d25e28abSJohan Hedberg 	/* Legacy key */
1143d25e28abSJohan Hedberg 	if (key_type < 0x03)
1144745c0ce3SVishal Agarwal 		return true;
1145d25e28abSJohan Hedberg 
1146d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1147d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1148745c0ce3SVishal Agarwal 		return false;
1149d25e28abSJohan Hedberg 
1150d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1151d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1152745c0ce3SVishal Agarwal 		return false;
1153d25e28abSJohan Hedberg 
1154d25e28abSJohan Hedberg 	/* Security mode 3 case */
1155d25e28abSJohan Hedberg 	if (!conn)
1156745c0ce3SVishal Agarwal 		return true;
1157d25e28abSJohan Hedberg 
1158d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1159d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1160745c0ce3SVishal Agarwal 		return true;
1161d25e28abSJohan Hedberg 
1162d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1163d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1164745c0ce3SVishal Agarwal 		return true;
1165d25e28abSJohan Hedberg 
1166d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1167d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1168745c0ce3SVishal Agarwal 		return true;
1169d25e28abSJohan Hedberg 
1170d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1171d25e28abSJohan Hedberg 	 * persistently */
1172745c0ce3SVishal Agarwal 	return false;
1173d25e28abSJohan Hedberg }
1174d25e28abSJohan Hedberg 
1175c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
117675d262c2SVinicius Costa Gomes {
1177c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
117875d262c2SVinicius Costa Gomes 
1179c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1180c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1181c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
118275d262c2SVinicius Costa Gomes 			continue;
118375d262c2SVinicius Costa Gomes 
118475d262c2SVinicius Costa Gomes 		return k;
118575d262c2SVinicius Costa Gomes 	}
118675d262c2SVinicius Costa Gomes 
118775d262c2SVinicius Costa Gomes 	return NULL;
118875d262c2SVinicius Costa Gomes }
118975d262c2SVinicius Costa Gomes 
1190c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1191c9839a11SVinicius Costa Gomes 				     u8 addr_type)
119275d262c2SVinicius Costa Gomes {
1193c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
119475d262c2SVinicius Costa Gomes 
1195c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1196c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1197c9839a11SVinicius Costa Gomes 		    bacmp(bdaddr, &k->bdaddr) == 0)
119875d262c2SVinicius Costa Gomes 			return k;
119975d262c2SVinicius Costa Gomes 
120075d262c2SVinicius Costa Gomes 	return NULL;
120175d262c2SVinicius Costa Gomes }
120275d262c2SVinicius Costa Gomes 
1203d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1204d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
120555ed8ca1SJohan Hedberg {
120655ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1207745c0ce3SVishal Agarwal 	u8 old_key_type;
1208745c0ce3SVishal Agarwal 	bool persistent;
120955ed8ca1SJohan Hedberg 
121055ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
121155ed8ca1SJohan Hedberg 	if (old_key) {
121255ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
121355ed8ca1SJohan Hedberg 		key = old_key;
121455ed8ca1SJohan Hedberg 	} else {
121512adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
121655ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
121755ed8ca1SJohan Hedberg 		if (!key)
121855ed8ca1SJohan Hedberg 			return -ENOMEM;
121955ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
122055ed8ca1SJohan Hedberg 	}
122155ed8ca1SJohan Hedberg 
12226ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
122355ed8ca1SJohan Hedberg 
1224d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1225d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1226d25e28abSJohan Hedberg 	 * previous key */
1227d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1228a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1229d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1230655fe6ecSJohan Hedberg 		if (conn)
1231655fe6ecSJohan Hedberg 			conn->key_type = type;
1232655fe6ecSJohan Hedberg 	}
1233d25e28abSJohan Hedberg 
123455ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
12359b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
123655ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
123755ed8ca1SJohan Hedberg 
1238b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
123955ed8ca1SJohan Hedberg 		key->type = old_key_type;
12404748fed2SJohan Hedberg 	else
12414748fed2SJohan Hedberg 		key->type = type;
12424748fed2SJohan Hedberg 
12434df378a1SJohan Hedberg 	if (!new_key)
12444df378a1SJohan Hedberg 		return 0;
12454df378a1SJohan Hedberg 
12464df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
12474df378a1SJohan Hedberg 
1248744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
12494df378a1SJohan Hedberg 
12506ec5bcadSVishal Agarwal 	if (conn)
12516ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
125255ed8ca1SJohan Hedberg 
125355ed8ca1SJohan Hedberg 	return 0;
125455ed8ca1SJohan Hedberg }
125555ed8ca1SJohan Hedberg 
1256c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
12579a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
125804124681SGustavo F. Padovan 		ediv, u8 rand[8])
125975d262c2SVinicius Costa Gomes {
1260c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
126175d262c2SVinicius Costa Gomes 
1262c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1263c9839a11SVinicius Costa Gomes 		return 0;
126475d262c2SVinicius Costa Gomes 
1265c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1266c9839a11SVinicius Costa Gomes 	if (old_key)
126775d262c2SVinicius Costa Gomes 		key = old_key;
1268c9839a11SVinicius Costa Gomes 	else {
1269c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
127075d262c2SVinicius Costa Gomes 		if (!key)
127175d262c2SVinicius Costa Gomes 			return -ENOMEM;
1272c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
127375d262c2SVinicius Costa Gomes 	}
127475d262c2SVinicius Costa Gomes 
127575d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1276c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1277c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1278c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1279c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1280c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1281c9839a11SVinicius Costa Gomes 	key->type = type;
1282c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
128375d262c2SVinicius Costa Gomes 
1284c9839a11SVinicius Costa Gomes 	if (!new_key)
1285c9839a11SVinicius Costa Gomes 		return 0;
128675d262c2SVinicius Costa Gomes 
1287261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1288261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1289261cc5aaSVinicius Costa Gomes 
129075d262c2SVinicius Costa Gomes 	return 0;
129175d262c2SVinicius Costa Gomes }
129275d262c2SVinicius Costa Gomes 
129355ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
129455ed8ca1SJohan Hedberg {
129555ed8ca1SJohan Hedberg 	struct link_key *key;
129655ed8ca1SJohan Hedberg 
129755ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
129855ed8ca1SJohan Hedberg 	if (!key)
129955ed8ca1SJohan Hedberg 		return -ENOENT;
130055ed8ca1SJohan Hedberg 
13016ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
130255ed8ca1SJohan Hedberg 
130355ed8ca1SJohan Hedberg 	list_del(&key->list);
130455ed8ca1SJohan Hedberg 	kfree(key);
130555ed8ca1SJohan Hedberg 
130655ed8ca1SJohan Hedberg 	return 0;
130755ed8ca1SJohan Hedberg }
130855ed8ca1SJohan Hedberg 
1309b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1310b899efafSVinicius Costa Gomes {
1311b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1312b899efafSVinicius Costa Gomes 
1313b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1314b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1315b899efafSVinicius Costa Gomes 			continue;
1316b899efafSVinicius Costa Gomes 
13176ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1318b899efafSVinicius Costa Gomes 
1319b899efafSVinicius Costa Gomes 		list_del(&k->list);
1320b899efafSVinicius Costa Gomes 		kfree(k);
1321b899efafSVinicius Costa Gomes 	}
1322b899efafSVinicius Costa Gomes 
1323b899efafSVinicius Costa Gomes 	return 0;
1324b899efafSVinicius Costa Gomes }
1325b899efafSVinicius Costa Gomes 
13266bd32326SVille Tervo /* HCI command timer function */
1327bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
13286bd32326SVille Tervo {
13296bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
13306bd32326SVille Tervo 
1331bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
1332bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
1333bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
1334bda4f23aSAndrei Emeltchenko 
1335bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
1336bda4f23aSAndrei Emeltchenko 	} else {
13376bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
1338bda4f23aSAndrei Emeltchenko 	}
1339bda4f23aSAndrei Emeltchenko 
13406bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1341c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
13426bd32326SVille Tervo }
13436bd32326SVille Tervo 
13442763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
13452763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
13462763eda6SSzymon Janc {
13472763eda6SSzymon Janc 	struct oob_data *data;
13482763eda6SSzymon Janc 
13492763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
13502763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
13512763eda6SSzymon Janc 			return data;
13522763eda6SSzymon Janc 
13532763eda6SSzymon Janc 	return NULL;
13542763eda6SSzymon Janc }
13552763eda6SSzymon Janc 
13562763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
13572763eda6SSzymon Janc {
13582763eda6SSzymon Janc 	struct oob_data *data;
13592763eda6SSzymon Janc 
13602763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
13612763eda6SSzymon Janc 	if (!data)
13622763eda6SSzymon Janc 		return -ENOENT;
13632763eda6SSzymon Janc 
13646ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
13652763eda6SSzymon Janc 
13662763eda6SSzymon Janc 	list_del(&data->list);
13672763eda6SSzymon Janc 	kfree(data);
13682763eda6SSzymon Janc 
13692763eda6SSzymon Janc 	return 0;
13702763eda6SSzymon Janc }
13712763eda6SSzymon Janc 
13722763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
13732763eda6SSzymon Janc {
13742763eda6SSzymon Janc 	struct oob_data *data, *n;
13752763eda6SSzymon Janc 
13762763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
13772763eda6SSzymon Janc 		list_del(&data->list);
13782763eda6SSzymon Janc 		kfree(data);
13792763eda6SSzymon Janc 	}
13802763eda6SSzymon Janc 
13812763eda6SSzymon Janc 	return 0;
13822763eda6SSzymon Janc }
13832763eda6SSzymon Janc 
13842763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
13852763eda6SSzymon Janc 			    u8 *randomizer)
13862763eda6SSzymon Janc {
13872763eda6SSzymon Janc 	struct oob_data *data;
13882763eda6SSzymon Janc 
13892763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
13902763eda6SSzymon Janc 
13912763eda6SSzymon Janc 	if (!data) {
13922763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
13932763eda6SSzymon Janc 		if (!data)
13942763eda6SSzymon Janc 			return -ENOMEM;
13952763eda6SSzymon Janc 
13962763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
13972763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
13982763eda6SSzymon Janc 	}
13992763eda6SSzymon Janc 
14002763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
14012763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
14022763eda6SSzymon Janc 
14036ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
14042763eda6SSzymon Janc 
14052763eda6SSzymon Janc 	return 0;
14062763eda6SSzymon Janc }
14072763eda6SSzymon Janc 
140804124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
1409b2a66aadSAntti Julku {
1410b2a66aadSAntti Julku 	struct bdaddr_list *b;
1411b2a66aadSAntti Julku 
14128035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1413b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1414b2a66aadSAntti Julku 			return b;
1415b2a66aadSAntti Julku 
1416b2a66aadSAntti Julku 	return NULL;
1417b2a66aadSAntti Julku }
1418b2a66aadSAntti Julku 
1419b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1420b2a66aadSAntti Julku {
1421b2a66aadSAntti Julku 	struct list_head *p, *n;
1422b2a66aadSAntti Julku 
1423b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1424b2a66aadSAntti Julku 		struct bdaddr_list *b;
1425b2a66aadSAntti Julku 
1426b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1427b2a66aadSAntti Julku 
1428b2a66aadSAntti Julku 		list_del(p);
1429b2a66aadSAntti Julku 		kfree(b);
1430b2a66aadSAntti Julku 	}
1431b2a66aadSAntti Julku 
1432b2a66aadSAntti Julku 	return 0;
1433b2a66aadSAntti Julku }
1434b2a66aadSAntti Julku 
143588c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1436b2a66aadSAntti Julku {
1437b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1438b2a66aadSAntti Julku 
1439b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1440b2a66aadSAntti Julku 		return -EBADF;
1441b2a66aadSAntti Julku 
14425e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
14435e762444SAntti Julku 		return -EEXIST;
1444b2a66aadSAntti Julku 
1445b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
14465e762444SAntti Julku 	if (!entry)
14475e762444SAntti Julku 		return -ENOMEM;
1448b2a66aadSAntti Julku 
1449b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1450b2a66aadSAntti Julku 
1451b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1452b2a66aadSAntti Julku 
145388c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
1454b2a66aadSAntti Julku }
1455b2a66aadSAntti Julku 
145688c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1457b2a66aadSAntti Julku {
1458b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1459b2a66aadSAntti Julku 
14601ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
14615e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1462b2a66aadSAntti Julku 
1463b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
14641ec918ceSSzymon Janc 	if (!entry)
14655e762444SAntti Julku 		return -ENOENT;
1466b2a66aadSAntti Julku 
1467b2a66aadSAntti Julku 	list_del(&entry->list);
1468b2a66aadSAntti Julku 	kfree(entry);
1469b2a66aadSAntti Julku 
147088c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
1471b2a66aadSAntti Julku }
1472b2a66aadSAntti Julku 
14737ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt)
14747ba8b4beSAndre Guedes {
14757ba8b4beSAndre Guedes 	struct le_scan_params *param =  (struct le_scan_params *) opt;
14767ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_param cp;
14777ba8b4beSAndre Guedes 
14787ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
14797ba8b4beSAndre Guedes 	cp.type = param->type;
14807ba8b4beSAndre Guedes 	cp.interval = cpu_to_le16(param->interval);
14817ba8b4beSAndre Guedes 	cp.window = cpu_to_le16(param->window);
14827ba8b4beSAndre Guedes 
14837ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
14847ba8b4beSAndre Guedes }
14857ba8b4beSAndre Guedes 
14867ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt)
14877ba8b4beSAndre Guedes {
14887ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
14897ba8b4beSAndre Guedes 
14907ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
14917ba8b4beSAndre Guedes 	cp.enable = 1;
14920431a43cSAndre Guedes 	cp.filter_dup = 1;
14937ba8b4beSAndre Guedes 
14947ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
14957ba8b4beSAndre Guedes }
14967ba8b4beSAndre Guedes 
14977ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
14987ba8b4beSAndre Guedes 			  u16 window, int timeout)
14997ba8b4beSAndre Guedes {
15007ba8b4beSAndre Guedes 	long timeo = msecs_to_jiffies(3000);
15017ba8b4beSAndre Guedes 	struct le_scan_params param;
15027ba8b4beSAndre Guedes 	int err;
15037ba8b4beSAndre Guedes 
15047ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
15057ba8b4beSAndre Guedes 
15067ba8b4beSAndre Guedes 	if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
15077ba8b4beSAndre Guedes 		return -EINPROGRESS;
15087ba8b4beSAndre Guedes 
15097ba8b4beSAndre Guedes 	param.type = type;
15107ba8b4beSAndre Guedes 	param.interval = interval;
15117ba8b4beSAndre Guedes 	param.window = window;
15127ba8b4beSAndre Guedes 
15137ba8b4beSAndre Guedes 	hci_req_lock(hdev);
15147ba8b4beSAndre Guedes 
15157ba8b4beSAndre Guedes 	err = __hci_request(hdev, le_scan_param_req, (unsigned long) &param,
15167ba8b4beSAndre Guedes 			    timeo);
15177ba8b4beSAndre Guedes 	if (!err)
15187ba8b4beSAndre Guedes 		err = __hci_request(hdev, le_scan_enable_req, 0, timeo);
15197ba8b4beSAndre Guedes 
15207ba8b4beSAndre Guedes 	hci_req_unlock(hdev);
15217ba8b4beSAndre Guedes 
15227ba8b4beSAndre Guedes 	if (err < 0)
15237ba8b4beSAndre Guedes 		return err;
15247ba8b4beSAndre Guedes 
15257ba8b4beSAndre Guedes 	schedule_delayed_work(&hdev->le_scan_disable,
15267ba8b4beSAndre Guedes 			      msecs_to_jiffies(timeout));
15277ba8b4beSAndre Guedes 
15287ba8b4beSAndre Guedes 	return 0;
15297ba8b4beSAndre Guedes }
15307ba8b4beSAndre Guedes 
15317dbfac1dSAndre Guedes int hci_cancel_le_scan(struct hci_dev *hdev)
15327dbfac1dSAndre Guedes {
15337dbfac1dSAndre Guedes 	BT_DBG("%s", hdev->name);
15347dbfac1dSAndre Guedes 
15357dbfac1dSAndre Guedes 	if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
15367dbfac1dSAndre Guedes 		return -EALREADY;
15377dbfac1dSAndre Guedes 
15387dbfac1dSAndre Guedes 	if (cancel_delayed_work(&hdev->le_scan_disable)) {
15397dbfac1dSAndre Guedes 		struct hci_cp_le_set_scan_enable cp;
15407dbfac1dSAndre Guedes 
15417dbfac1dSAndre Guedes 		/* Send HCI command to disable LE Scan */
15427dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
15437dbfac1dSAndre Guedes 		hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
15447dbfac1dSAndre Guedes 	}
15457dbfac1dSAndre Guedes 
15467dbfac1dSAndre Guedes 	return 0;
15477dbfac1dSAndre Guedes }
15487dbfac1dSAndre Guedes 
15497ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
15507ba8b4beSAndre Guedes {
15517ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
15527ba8b4beSAndre Guedes 					    le_scan_disable.work);
15537ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
15547ba8b4beSAndre Guedes 
15557ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
15567ba8b4beSAndre Guedes 
15577ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
15587ba8b4beSAndre Guedes 
15597ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
15607ba8b4beSAndre Guedes }
15617ba8b4beSAndre Guedes 
156228b75a89SAndre Guedes static void le_scan_work(struct work_struct *work)
156328b75a89SAndre Guedes {
156428b75a89SAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
156528b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
156628b75a89SAndre Guedes 
156728b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
156828b75a89SAndre Guedes 
156904124681SGustavo F. Padovan 	hci_do_le_scan(hdev, param->type, param->interval, param->window,
157004124681SGustavo F. Padovan 		       param->timeout);
157128b75a89SAndre Guedes }
157228b75a89SAndre Guedes 
157328b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
157428b75a89SAndre Guedes 		int timeout)
157528b75a89SAndre Guedes {
157628b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
157728b75a89SAndre Guedes 
157828b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
157928b75a89SAndre Guedes 
1580*f1550478SJohan Hedberg 	if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
1581*f1550478SJohan Hedberg 		return -ENOTSUPP;
1582*f1550478SJohan Hedberg 
158328b75a89SAndre Guedes 	if (work_busy(&hdev->le_scan))
158428b75a89SAndre Guedes 		return -EINPROGRESS;
158528b75a89SAndre Guedes 
158628b75a89SAndre Guedes 	param->type = type;
158728b75a89SAndre Guedes 	param->interval = interval;
158828b75a89SAndre Guedes 	param->window = window;
158928b75a89SAndre Guedes 	param->timeout = timeout;
159028b75a89SAndre Guedes 
159128b75a89SAndre Guedes 	queue_work(system_long_wq, &hdev->le_scan);
159228b75a89SAndre Guedes 
159328b75a89SAndre Guedes 	return 0;
159428b75a89SAndre Guedes }
159528b75a89SAndre Guedes 
15969be0dab7SDavid Herrmann /* Alloc HCI device */
15979be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
15989be0dab7SDavid Herrmann {
15999be0dab7SDavid Herrmann 	struct hci_dev *hdev;
16009be0dab7SDavid Herrmann 
16019be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
16029be0dab7SDavid Herrmann 	if (!hdev)
16039be0dab7SDavid Herrmann 		return NULL;
16049be0dab7SDavid Herrmann 
1605b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
1606b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
1607b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
1608b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03; /* No Input No Output */
1609b1b813d4SDavid Herrmann 
1610b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
1611b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
1612b1b813d4SDavid Herrmann 
1613b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
1614b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
1615b1b813d4SDavid Herrmann 
1616b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
1617b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
1618b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
1619b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
1620b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
1621b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
16226b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
1623b1b813d4SDavid Herrmann 
1624b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1625b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
1626b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
1627b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
1628b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->le_scan, le_scan_work);
1629b1b813d4SDavid Herrmann 
1630b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
1631b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
1632b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
1633b1b813d4SDavid Herrmann 
16349be0dab7SDavid Herrmann 	skb_queue_head_init(&hdev->driver_init);
1635b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
1636b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
1637b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
1638b1b813d4SDavid Herrmann 
1639b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
1640b1b813d4SDavid Herrmann 
1641bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
1642b1b813d4SDavid Herrmann 
1643b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
1644b1b813d4SDavid Herrmann 	discovery_init(hdev);
16459be0dab7SDavid Herrmann 
16469be0dab7SDavid Herrmann 	return hdev;
16479be0dab7SDavid Herrmann }
16489be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
16499be0dab7SDavid Herrmann 
16509be0dab7SDavid Herrmann /* Free HCI device */
16519be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
16529be0dab7SDavid Herrmann {
16539be0dab7SDavid Herrmann 	skb_queue_purge(&hdev->driver_init);
16549be0dab7SDavid Herrmann 
16559be0dab7SDavid Herrmann 	/* will free via device release */
16569be0dab7SDavid Herrmann 	put_device(&hdev->dev);
16579be0dab7SDavid Herrmann }
16589be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
16599be0dab7SDavid Herrmann 
16601da177e4SLinus Torvalds /* Register HCI device */
16611da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
16621da177e4SLinus Torvalds {
1663b1b813d4SDavid Herrmann 	int id, error;
16641da177e4SLinus Torvalds 
1665010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
16661da177e4SLinus Torvalds 		return -EINVAL;
16671da177e4SLinus Torvalds 
166808add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
166908add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
167008add513SMat Martineau 	 */
16713df92b31SSasha Levin 	switch (hdev->dev_type) {
16723df92b31SSasha Levin 	case HCI_BREDR:
16733df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
16741da177e4SLinus Torvalds 		break;
16753df92b31SSasha Levin 	case HCI_AMP:
16763df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
16773df92b31SSasha Levin 		break;
16783df92b31SSasha Levin 	default:
16793df92b31SSasha Levin 		return -EINVAL;
16801da177e4SLinus Torvalds 	}
16811da177e4SLinus Torvalds 
16823df92b31SSasha Levin 	if (id < 0)
16833df92b31SSasha Levin 		return id;
16843df92b31SSasha Levin 
16851da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
16861da177e4SLinus Torvalds 	hdev->id = id;
16872d8b3a11SAndrei Emeltchenko 
16882d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
16892d8b3a11SAndrei Emeltchenko 
16903df92b31SSasha Levin 	write_lock(&hci_dev_list_lock);
16913df92b31SSasha Levin 	list_add(&hdev->list, &hci_dev_list);
1692f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
16931da177e4SLinus Torvalds 
169432845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
169532845eb1SGustavo F. Padovan 					  WQ_MEM_RECLAIM, 1);
169633ca954dSDavid Herrmann 	if (!hdev->workqueue) {
169733ca954dSDavid Herrmann 		error = -ENOMEM;
169833ca954dSDavid Herrmann 		goto err;
169933ca954dSDavid Herrmann 	}
1700f48fd9c8SMarcel Holtmann 
170133ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
170233ca954dSDavid Herrmann 	if (error < 0)
170333ca954dSDavid Herrmann 		goto err_wqueue;
17041da177e4SLinus Torvalds 
1705611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1706a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
1707a8c5fb1aSGustavo Padovan 				    hdev);
1708611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1709611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
1710611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
1711611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
1712611b30f7SMarcel Holtmann 		}
1713611b30f7SMarcel Holtmann 	}
1714611b30f7SMarcel Holtmann 
1715a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
1716ce2be9acSAndrei Emeltchenko 
1717ce2be9acSAndrei Emeltchenko 	if (hdev->dev_type != HCI_AMP)
1718ce2be9acSAndrei Emeltchenko 		set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
1719ce2be9acSAndrei Emeltchenko 
17207f971041SGustavo F. Padovan 	schedule_work(&hdev->power_on);
1721ab81cbf9SJohan Hedberg 
17221da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
1723dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
17241da177e4SLinus Torvalds 
17251da177e4SLinus Torvalds 	return id;
1726f48fd9c8SMarcel Holtmann 
172733ca954dSDavid Herrmann err_wqueue:
172833ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
172933ca954dSDavid Herrmann err:
17303df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
1731f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
1732f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
1733f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
1734f48fd9c8SMarcel Holtmann 
173533ca954dSDavid Herrmann 	return error;
17361da177e4SLinus Torvalds }
17371da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
17381da177e4SLinus Torvalds 
17391da177e4SLinus Torvalds /* Unregister HCI device */
174059735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
17411da177e4SLinus Torvalds {
17423df92b31SSasha Levin 	int i, id;
1743ef222013SMarcel Holtmann 
1744c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
17451da177e4SLinus Torvalds 
174694324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
174794324962SJohan Hovold 
17483df92b31SSasha Levin 	id = hdev->id;
17493df92b31SSasha Levin 
1750f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
17511da177e4SLinus Torvalds 	list_del(&hdev->list);
1752f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
17531da177e4SLinus Torvalds 
17541da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
17551da177e4SLinus Torvalds 
1756cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1757ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
1758ef222013SMarcel Holtmann 
1759ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
1760a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
176109fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1762744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
176309fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
176456e5cb86SJohan Hedberg 	}
1765ab81cbf9SJohan Hedberg 
17662e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
17672e58ef3eSJohan Hedberg 	 * pending list */
17682e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
17692e58ef3eSJohan Hedberg 
17701da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
17711da177e4SLinus Torvalds 
1772611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1773611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
1774611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
1775611b30f7SMarcel Holtmann 	}
1776611b30f7SMarcel Holtmann 
1777ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
1778147e2d59SDave Young 
1779f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
1780f48fd9c8SMarcel Holtmann 
178109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
1782e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
17832aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
178455ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
1785b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
17862763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
178709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
1788e2e0cacbSJohan Hedberg 
1789dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
17903df92b31SSasha Levin 
17913df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
17921da177e4SLinus Torvalds }
17931da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
17941da177e4SLinus Torvalds 
17951da177e4SLinus Torvalds /* Suspend HCI device */
17961da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
17971da177e4SLinus Torvalds {
17981da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
17991da177e4SLinus Torvalds 	return 0;
18001da177e4SLinus Torvalds }
18011da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
18021da177e4SLinus Torvalds 
18031da177e4SLinus Torvalds /* Resume HCI device */
18041da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
18051da177e4SLinus Torvalds {
18061da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
18071da177e4SLinus Torvalds 	return 0;
18081da177e4SLinus Torvalds }
18091da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
18101da177e4SLinus Torvalds 
181176bca880SMarcel Holtmann /* Receive frame from HCI drivers */
181276bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
181376bca880SMarcel Holtmann {
181476bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
181576bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
181676bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
181776bca880SMarcel Holtmann 		kfree_skb(skb);
181876bca880SMarcel Holtmann 		return -ENXIO;
181976bca880SMarcel Holtmann 	}
182076bca880SMarcel Holtmann 
182176bca880SMarcel Holtmann 	/* Incomming skb */
182276bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
182376bca880SMarcel Holtmann 
182476bca880SMarcel Holtmann 	/* Time stamp */
182576bca880SMarcel Holtmann 	__net_timestamp(skb);
182676bca880SMarcel Holtmann 
182776bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
1828b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
1829c78ae283SMarcel Holtmann 
183076bca880SMarcel Holtmann 	return 0;
183176bca880SMarcel Holtmann }
183276bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
183376bca880SMarcel Holtmann 
183433e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
18351e429f38SGustavo F. Padovan 			  int count, __u8 index)
183633e882a5SSuraj Sumangala {
183733e882a5SSuraj Sumangala 	int len = 0;
183833e882a5SSuraj Sumangala 	int hlen = 0;
183933e882a5SSuraj Sumangala 	int remain = count;
184033e882a5SSuraj Sumangala 	struct sk_buff *skb;
184133e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
184233e882a5SSuraj Sumangala 
184333e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
184433e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
184533e882a5SSuraj Sumangala 		return -EILSEQ;
184633e882a5SSuraj Sumangala 
184733e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
184833e882a5SSuraj Sumangala 
184933e882a5SSuraj Sumangala 	if (!skb) {
185033e882a5SSuraj Sumangala 		switch (type) {
185133e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
185233e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
185333e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
185433e882a5SSuraj Sumangala 			break;
185533e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
185633e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
185733e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
185833e882a5SSuraj Sumangala 			break;
185933e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
186033e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
186133e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
186233e882a5SSuraj Sumangala 			break;
186333e882a5SSuraj Sumangala 		}
186433e882a5SSuraj Sumangala 
18651e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
186633e882a5SSuraj Sumangala 		if (!skb)
186733e882a5SSuraj Sumangala 			return -ENOMEM;
186833e882a5SSuraj Sumangala 
186933e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
187033e882a5SSuraj Sumangala 		scb->expect = hlen;
187133e882a5SSuraj Sumangala 		scb->pkt_type = type;
187233e882a5SSuraj Sumangala 
187333e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
187433e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
187533e882a5SSuraj Sumangala 	}
187633e882a5SSuraj Sumangala 
187733e882a5SSuraj Sumangala 	while (count) {
187833e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
187989bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
188033e882a5SSuraj Sumangala 
188133e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
188233e882a5SSuraj Sumangala 
188333e882a5SSuraj Sumangala 		count -= len;
188433e882a5SSuraj Sumangala 		data += len;
188533e882a5SSuraj Sumangala 		scb->expect -= len;
188633e882a5SSuraj Sumangala 		remain = count;
188733e882a5SSuraj Sumangala 
188833e882a5SSuraj Sumangala 		switch (type) {
188933e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
189033e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
189133e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
189233e882a5SSuraj Sumangala 				scb->expect = h->plen;
189333e882a5SSuraj Sumangala 
189433e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
189533e882a5SSuraj Sumangala 					kfree_skb(skb);
189633e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
189733e882a5SSuraj Sumangala 					return -ENOMEM;
189833e882a5SSuraj Sumangala 				}
189933e882a5SSuraj Sumangala 			}
190033e882a5SSuraj Sumangala 			break;
190133e882a5SSuraj Sumangala 
190233e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
190333e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
190433e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
190533e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
190633e882a5SSuraj Sumangala 
190733e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
190833e882a5SSuraj Sumangala 					kfree_skb(skb);
190933e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
191033e882a5SSuraj Sumangala 					return -ENOMEM;
191133e882a5SSuraj Sumangala 				}
191233e882a5SSuraj Sumangala 			}
191333e882a5SSuraj Sumangala 			break;
191433e882a5SSuraj Sumangala 
191533e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
191633e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
191733e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
191833e882a5SSuraj Sumangala 				scb->expect = h->dlen;
191933e882a5SSuraj Sumangala 
192033e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
192133e882a5SSuraj Sumangala 					kfree_skb(skb);
192233e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
192333e882a5SSuraj Sumangala 					return -ENOMEM;
192433e882a5SSuraj Sumangala 				}
192533e882a5SSuraj Sumangala 			}
192633e882a5SSuraj Sumangala 			break;
192733e882a5SSuraj Sumangala 		}
192833e882a5SSuraj Sumangala 
192933e882a5SSuraj Sumangala 		if (scb->expect == 0) {
193033e882a5SSuraj Sumangala 			/* Complete frame */
193133e882a5SSuraj Sumangala 
193233e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
193333e882a5SSuraj Sumangala 			hci_recv_frame(skb);
193433e882a5SSuraj Sumangala 
193533e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
193633e882a5SSuraj Sumangala 			return remain;
193733e882a5SSuraj Sumangala 		}
193833e882a5SSuraj Sumangala 	}
193933e882a5SSuraj Sumangala 
194033e882a5SSuraj Sumangala 	return remain;
194133e882a5SSuraj Sumangala }
194233e882a5SSuraj Sumangala 
1943ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
1944ef222013SMarcel Holtmann {
1945f39a3c06SSuraj Sumangala 	int rem = 0;
1946f39a3c06SSuraj Sumangala 
1947ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
1948ef222013SMarcel Holtmann 		return -EILSEQ;
1949ef222013SMarcel Holtmann 
1950da5f6c37SGustavo F. Padovan 	while (count) {
19511e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
1952f39a3c06SSuraj Sumangala 		if (rem < 0)
1953f39a3c06SSuraj Sumangala 			return rem;
1954ef222013SMarcel Holtmann 
1955f39a3c06SSuraj Sumangala 		data += (count - rem);
1956f39a3c06SSuraj Sumangala 		count = rem;
1957f81c6224SJoe Perches 	}
1958ef222013SMarcel Holtmann 
1959f39a3c06SSuraj Sumangala 	return rem;
1960ef222013SMarcel Holtmann }
1961ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
1962ef222013SMarcel Holtmann 
196399811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
196499811510SSuraj Sumangala 
196599811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
196699811510SSuraj Sumangala {
196799811510SSuraj Sumangala 	int type;
196899811510SSuraj Sumangala 	int rem = 0;
196999811510SSuraj Sumangala 
1970da5f6c37SGustavo F. Padovan 	while (count) {
197199811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
197299811510SSuraj Sumangala 
197399811510SSuraj Sumangala 		if (!skb) {
197499811510SSuraj Sumangala 			struct { char type; } *pkt;
197599811510SSuraj Sumangala 
197699811510SSuraj Sumangala 			/* Start of the frame */
197799811510SSuraj Sumangala 			pkt = data;
197899811510SSuraj Sumangala 			type = pkt->type;
197999811510SSuraj Sumangala 
198099811510SSuraj Sumangala 			data++;
198199811510SSuraj Sumangala 			count--;
198299811510SSuraj Sumangala 		} else
198399811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
198499811510SSuraj Sumangala 
19851e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
19861e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
198799811510SSuraj Sumangala 		if (rem < 0)
198899811510SSuraj Sumangala 			return rem;
198999811510SSuraj Sumangala 
199099811510SSuraj Sumangala 		data += (count - rem);
199199811510SSuraj Sumangala 		count = rem;
1992f81c6224SJoe Perches 	}
199399811510SSuraj Sumangala 
199499811510SSuraj Sumangala 	return rem;
199599811510SSuraj Sumangala }
199699811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
199799811510SSuraj Sumangala 
19981da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
19991da177e4SLinus Torvalds 
20001da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
20011da177e4SLinus Torvalds {
20021da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
20031da177e4SLinus Torvalds 
2004f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
20051da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2006f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
20071da177e4SLinus Torvalds 
20081da177e4SLinus Torvalds 	return 0;
20091da177e4SLinus Torvalds }
20101da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
20111da177e4SLinus Torvalds 
20121da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
20131da177e4SLinus Torvalds {
20141da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
20151da177e4SLinus Torvalds 
2016f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
20171da177e4SLinus Torvalds 	list_del(&cb->list);
2018f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
20191da177e4SLinus Torvalds 
20201da177e4SLinus Torvalds 	return 0;
20211da177e4SLinus Torvalds }
20221da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
20231da177e4SLinus Torvalds 
20241da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
20251da177e4SLinus Torvalds {
20261da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
20271da177e4SLinus Torvalds 
20281da177e4SLinus Torvalds 	if (!hdev) {
20291da177e4SLinus Torvalds 		kfree_skb(skb);
20301da177e4SLinus Torvalds 		return -ENODEV;
20311da177e4SLinus Torvalds 	}
20321da177e4SLinus Torvalds 
20330d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
20341da177e4SLinus Torvalds 
20351da177e4SLinus Torvalds 	/* Time stamp */
2036a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
20371da177e4SLinus Torvalds 
2038cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2039cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2040cd82e61cSMarcel Holtmann 
2041cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2042cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2043470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
20441da177e4SLinus Torvalds 	}
20451da177e4SLinus Torvalds 
20461da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
20471da177e4SLinus Torvalds 	skb_orphan(skb);
20481da177e4SLinus Torvalds 
20491da177e4SLinus Torvalds 	return hdev->send(skb);
20501da177e4SLinus Torvalds }
20511da177e4SLinus Torvalds 
20521da177e4SLinus Torvalds /* Send HCI command */
2053a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
20541da177e4SLinus Torvalds {
20551da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
20561da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
20571da177e4SLinus Torvalds 	struct sk_buff *skb;
20581da177e4SLinus Torvalds 
2059f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
20601da177e4SLinus Torvalds 
20611da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
20621da177e4SLinus Torvalds 	if (!skb) {
2063ef222013SMarcel Holtmann 		BT_ERR("%s no memory for command", hdev->name);
20641da177e4SLinus Torvalds 		return -ENOMEM;
20651da177e4SLinus Torvalds 	}
20661da177e4SLinus Torvalds 
20671da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2068a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
20691da177e4SLinus Torvalds 	hdr->plen   = plen;
20701da177e4SLinus Torvalds 
20711da177e4SLinus Torvalds 	if (plen)
20721da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
20731da177e4SLinus Torvalds 
20741da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
20751da177e4SLinus Torvalds 
20760d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
20771da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2078c78ae283SMarcel Holtmann 
2079a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
2080a5040efaSJohan Hedberg 		hdev->init_last_cmd = opcode;
2081a5040efaSJohan Hedberg 
20821da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2083c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
20841da177e4SLinus Torvalds 
20851da177e4SLinus Torvalds 	return 0;
20861da177e4SLinus Torvalds }
20871da177e4SLinus Torvalds 
20881da177e4SLinus Torvalds /* Get data from the previously sent command */
2089a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
20901da177e4SLinus Torvalds {
20911da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
20921da177e4SLinus Torvalds 
20931da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
20941da177e4SLinus Torvalds 		return NULL;
20951da177e4SLinus Torvalds 
20961da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
20971da177e4SLinus Torvalds 
2098a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
20991da177e4SLinus Torvalds 		return NULL;
21001da177e4SLinus Torvalds 
2101f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
21021da177e4SLinus Torvalds 
21031da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
21041da177e4SLinus Torvalds }
21051da177e4SLinus Torvalds 
21061da177e4SLinus Torvalds /* Send ACL data */
21071da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
21081da177e4SLinus Torvalds {
21091da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
21101da177e4SLinus Torvalds 	int len = skb->len;
21111da177e4SLinus Torvalds 
2112badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2113badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
21149c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2115aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2116aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
21171da177e4SLinus Torvalds }
21181da177e4SLinus Torvalds 
2119ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
212073d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
21211da177e4SLinus Torvalds {
2122ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
21231da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
21241da177e4SLinus Torvalds 	struct sk_buff *list;
21251da177e4SLinus Torvalds 
2126087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
2127087bfd99SGustavo Padovan 	skb->data_len = 0;
2128087bfd99SGustavo Padovan 
2129087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2130204a6e54SAndrei Emeltchenko 
2131204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
2132204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
2133087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
2134204a6e54SAndrei Emeltchenko 		break;
2135204a6e54SAndrei Emeltchenko 	case HCI_AMP:
2136204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
2137204a6e54SAndrei Emeltchenko 		break;
2138204a6e54SAndrei Emeltchenko 	default:
2139204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2140204a6e54SAndrei Emeltchenko 		return;
2141204a6e54SAndrei Emeltchenko 	}
2142087bfd99SGustavo Padovan 
214370f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
214470f23020SAndrei Emeltchenko 	if (!list) {
21451da177e4SLinus Torvalds 		/* Non fragmented */
21461da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
21471da177e4SLinus Torvalds 
214873d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
21491da177e4SLinus Torvalds 	} else {
21501da177e4SLinus Torvalds 		/* Fragmented */
21511da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
21521da177e4SLinus Torvalds 
21531da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
21541da177e4SLinus Torvalds 
21551da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2156af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
21571da177e4SLinus Torvalds 
215873d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2159e702112fSAndrei Emeltchenko 
2160e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2161e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
21621da177e4SLinus Torvalds 		do {
21631da177e4SLinus Torvalds 			skb = list; list = list->next;
21641da177e4SLinus Torvalds 
21651da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
21660d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2167e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
21681da177e4SLinus Torvalds 
21691da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
21701da177e4SLinus Torvalds 
217173d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
21721da177e4SLinus Torvalds 		} while (list);
21731da177e4SLinus Torvalds 
2174af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
21751da177e4SLinus Torvalds 	}
217673d80debSLuiz Augusto von Dentz }
217773d80debSLuiz Augusto von Dentz 
217873d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
217973d80debSLuiz Augusto von Dentz {
2180ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
218173d80debSLuiz Augusto von Dentz 
2182f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
218373d80debSLuiz Augusto von Dentz 
218473d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
218573d80debSLuiz Augusto von Dentz 
2186ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
21871da177e4SLinus Torvalds 
21883eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
21891da177e4SLinus Torvalds }
21901da177e4SLinus Torvalds 
21911da177e4SLinus Torvalds /* Send SCO data */
21920d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
21931da177e4SLinus Torvalds {
21941da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
21951da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
21961da177e4SLinus Torvalds 
21971da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
21981da177e4SLinus Torvalds 
2199aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
22001da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
22011da177e4SLinus Torvalds 
2202badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2203badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
22049c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
22051da177e4SLinus Torvalds 
22061da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
22070d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2208c78ae283SMarcel Holtmann 
22091da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
22103eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
22111da177e4SLinus Torvalds }
22121da177e4SLinus Torvalds 
22131da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
22141da177e4SLinus Torvalds 
22151da177e4SLinus Torvalds /* HCI Connection scheduler */
22166039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
2217a8c5fb1aSGustavo Padovan 				     int *quote)
22181da177e4SLinus Torvalds {
22191da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
22208035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
2221abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
22221da177e4SLinus Torvalds 
22231da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
22241da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2225bf4c6325SGustavo F. Padovan 
2226bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2227bf4c6325SGustavo F. Padovan 
2228bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2229769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
22301da177e4SLinus Torvalds 			continue;
2231769be974SMarcel Holtmann 
2232769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2233769be974SMarcel Holtmann 			continue;
2234769be974SMarcel Holtmann 
22351da177e4SLinus Torvalds 		num++;
22361da177e4SLinus Torvalds 
22371da177e4SLinus Torvalds 		if (c->sent < min) {
22381da177e4SLinus Torvalds 			min  = c->sent;
22391da177e4SLinus Torvalds 			conn = c;
22401da177e4SLinus Torvalds 		}
224152087a79SLuiz Augusto von Dentz 
224252087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
224352087a79SLuiz Augusto von Dentz 			break;
22441da177e4SLinus Torvalds 	}
22451da177e4SLinus Torvalds 
2246bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2247bf4c6325SGustavo F. Padovan 
22481da177e4SLinus Torvalds 	if (conn) {
22496ed58ec5SVille Tervo 		int cnt, q;
22506ed58ec5SVille Tervo 
22516ed58ec5SVille Tervo 		switch (conn->type) {
22526ed58ec5SVille Tervo 		case ACL_LINK:
22536ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
22546ed58ec5SVille Tervo 			break;
22556ed58ec5SVille Tervo 		case SCO_LINK:
22566ed58ec5SVille Tervo 		case ESCO_LINK:
22576ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
22586ed58ec5SVille Tervo 			break;
22596ed58ec5SVille Tervo 		case LE_LINK:
22606ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
22616ed58ec5SVille Tervo 			break;
22626ed58ec5SVille Tervo 		default:
22636ed58ec5SVille Tervo 			cnt = 0;
22646ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
22656ed58ec5SVille Tervo 		}
22666ed58ec5SVille Tervo 
22676ed58ec5SVille Tervo 		q = cnt / num;
22681da177e4SLinus Torvalds 		*quote = q ? q : 1;
22691da177e4SLinus Torvalds 	} else
22701da177e4SLinus Torvalds 		*quote = 0;
22711da177e4SLinus Torvalds 
22721da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
22731da177e4SLinus Torvalds 	return conn;
22741da177e4SLinus Torvalds }
22751da177e4SLinus Torvalds 
22766039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
22771da177e4SLinus Torvalds {
22781da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
22791da177e4SLinus Torvalds 	struct hci_conn *c;
22801da177e4SLinus Torvalds 
2281bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
22821da177e4SLinus Torvalds 
2283bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2284bf4c6325SGustavo F. Padovan 
22851da177e4SLinus Torvalds 	/* Kill stalled connections */
2286bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2287bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
22886ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
22896ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
22907490c6c2SAndrei Emeltchenko 			hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM);
22911da177e4SLinus Torvalds 		}
22921da177e4SLinus Torvalds 	}
2293bf4c6325SGustavo F. Padovan 
2294bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
22951da177e4SLinus Torvalds }
22961da177e4SLinus Torvalds 
22976039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
229873d80debSLuiz Augusto von Dentz 				      int *quote)
229973d80debSLuiz Augusto von Dentz {
230073d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
230173d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
2302abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
230373d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
230473d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
230573d80debSLuiz Augusto von Dentz 
230673d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
230773d80debSLuiz Augusto von Dentz 
2308bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2309bf4c6325SGustavo F. Padovan 
2310bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
231173d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
231273d80debSLuiz Augusto von Dentz 
231373d80debSLuiz Augusto von Dentz 		if (conn->type != type)
231473d80debSLuiz Augusto von Dentz 			continue;
231573d80debSLuiz Augusto von Dentz 
231673d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
231773d80debSLuiz Augusto von Dentz 			continue;
231873d80debSLuiz Augusto von Dentz 
231973d80debSLuiz Augusto von Dentz 		conn_num++;
232073d80debSLuiz Augusto von Dentz 
23218192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
232273d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
232373d80debSLuiz Augusto von Dentz 
232473d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
232573d80debSLuiz Augusto von Dentz 				continue;
232673d80debSLuiz Augusto von Dentz 
232773d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
232873d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
232973d80debSLuiz Augusto von Dentz 				continue;
233073d80debSLuiz Augusto von Dentz 
233173d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
233273d80debSLuiz Augusto von Dentz 				num = 0;
233373d80debSLuiz Augusto von Dentz 				min = ~0;
233473d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
233573d80debSLuiz Augusto von Dentz 			}
233673d80debSLuiz Augusto von Dentz 
233773d80debSLuiz Augusto von Dentz 			num++;
233873d80debSLuiz Augusto von Dentz 
233973d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
234073d80debSLuiz Augusto von Dentz 				min  = conn->sent;
234173d80debSLuiz Augusto von Dentz 				chan = tmp;
234273d80debSLuiz Augusto von Dentz 			}
234373d80debSLuiz Augusto von Dentz 		}
234473d80debSLuiz Augusto von Dentz 
234573d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
234673d80debSLuiz Augusto von Dentz 			break;
234773d80debSLuiz Augusto von Dentz 	}
234873d80debSLuiz Augusto von Dentz 
2349bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2350bf4c6325SGustavo F. Padovan 
235173d80debSLuiz Augusto von Dentz 	if (!chan)
235273d80debSLuiz Augusto von Dentz 		return NULL;
235373d80debSLuiz Augusto von Dentz 
235473d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
235573d80debSLuiz Augusto von Dentz 	case ACL_LINK:
235673d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
235773d80debSLuiz Augusto von Dentz 		break;
2358bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
2359bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
2360bd1eb66bSAndrei Emeltchenko 		break;
236173d80debSLuiz Augusto von Dentz 	case SCO_LINK:
236273d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
236373d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
236473d80debSLuiz Augusto von Dentz 		break;
236573d80debSLuiz Augusto von Dentz 	case LE_LINK:
236673d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
236773d80debSLuiz Augusto von Dentz 		break;
236873d80debSLuiz Augusto von Dentz 	default:
236973d80debSLuiz Augusto von Dentz 		cnt = 0;
237073d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
237173d80debSLuiz Augusto von Dentz 	}
237273d80debSLuiz Augusto von Dentz 
237373d80debSLuiz Augusto von Dentz 	q = cnt / num;
237473d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
237573d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
237673d80debSLuiz Augusto von Dentz 	return chan;
237773d80debSLuiz Augusto von Dentz }
237873d80debSLuiz Augusto von Dentz 
237902b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
238002b20f0bSLuiz Augusto von Dentz {
238102b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
238202b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
238302b20f0bSLuiz Augusto von Dentz 	int num = 0;
238402b20f0bSLuiz Augusto von Dentz 
238502b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
238602b20f0bSLuiz Augusto von Dentz 
2387bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2388bf4c6325SGustavo F. Padovan 
2389bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
239002b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
239102b20f0bSLuiz Augusto von Dentz 
239202b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
239302b20f0bSLuiz Augusto von Dentz 			continue;
239402b20f0bSLuiz Augusto von Dentz 
239502b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
239602b20f0bSLuiz Augusto von Dentz 			continue;
239702b20f0bSLuiz Augusto von Dentz 
239802b20f0bSLuiz Augusto von Dentz 		num++;
239902b20f0bSLuiz Augusto von Dentz 
24008192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
240102b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
240202b20f0bSLuiz Augusto von Dentz 
240302b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
240402b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
240502b20f0bSLuiz Augusto von Dentz 				continue;
240602b20f0bSLuiz Augusto von Dentz 			}
240702b20f0bSLuiz Augusto von Dentz 
240802b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
240902b20f0bSLuiz Augusto von Dentz 				continue;
241002b20f0bSLuiz Augusto von Dentz 
241102b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
241202b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
241302b20f0bSLuiz Augusto von Dentz 				continue;
241402b20f0bSLuiz Augusto von Dentz 
241502b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
241602b20f0bSLuiz Augusto von Dentz 
241702b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
241802b20f0bSLuiz Augusto von Dentz 			       skb->priority);
241902b20f0bSLuiz Augusto von Dentz 		}
242002b20f0bSLuiz Augusto von Dentz 
242102b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
242202b20f0bSLuiz Augusto von Dentz 			break;
242302b20f0bSLuiz Augusto von Dentz 	}
2424bf4c6325SGustavo F. Padovan 
2425bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2426bf4c6325SGustavo F. Padovan 
242702b20f0bSLuiz Augusto von Dentz }
242802b20f0bSLuiz Augusto von Dentz 
2429b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
2430b71d385aSAndrei Emeltchenko {
2431b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
2432b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
2433b71d385aSAndrei Emeltchenko }
2434b71d385aSAndrei Emeltchenko 
24356039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
24361da177e4SLinus Torvalds {
24371da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
24381da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
24391da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
244063d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
24415f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
2442bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
24431da177e4SLinus Torvalds 	}
244463d2bc1bSAndrei Emeltchenko }
24451da177e4SLinus Torvalds 
24466039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
244763d2bc1bSAndrei Emeltchenko {
244863d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
244963d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
245063d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
245163d2bc1bSAndrei Emeltchenko 	int quote;
245263d2bc1bSAndrei Emeltchenko 
245363d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
245404837f64SMarcel Holtmann 
245573d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
245673d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2457ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2458ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
245973d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
246073d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
246173d80debSLuiz Augusto von Dentz 
2462ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2463ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2464ec1cce24SLuiz Augusto von Dentz 				break;
2465ec1cce24SLuiz Augusto von Dentz 
2466ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2467ec1cce24SLuiz Augusto von Dentz 
246873d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
246973d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
247004837f64SMarcel Holtmann 
24711da177e4SLinus Torvalds 			hci_send_frame(skb);
24721da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
24731da177e4SLinus Torvalds 
24741da177e4SLinus Torvalds 			hdev->acl_cnt--;
247573d80debSLuiz Augusto von Dentz 			chan->sent++;
247673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
24771da177e4SLinus Torvalds 		}
24781da177e4SLinus Torvalds 	}
247902b20f0bSLuiz Augusto von Dentz 
248002b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
248102b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
24821da177e4SLinus Torvalds }
24831da177e4SLinus Torvalds 
24846039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
2485b71d385aSAndrei Emeltchenko {
248663d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
2487b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
2488b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
2489b71d385aSAndrei Emeltchenko 	int quote;
2490bd1eb66bSAndrei Emeltchenko 	u8 type;
2491b71d385aSAndrei Emeltchenko 
249263d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
2493b71d385aSAndrei Emeltchenko 
2494bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
2495bd1eb66bSAndrei Emeltchenko 
2496bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
2497bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
2498bd1eb66bSAndrei Emeltchenko 	else
2499bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
2500bd1eb66bSAndrei Emeltchenko 
2501b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
2502bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
2503b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
2504b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
2505b71d385aSAndrei Emeltchenko 			int blocks;
2506b71d385aSAndrei Emeltchenko 
2507b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
2508b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
2509b71d385aSAndrei Emeltchenko 
2510b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
2511b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
2512b71d385aSAndrei Emeltchenko 				break;
2513b71d385aSAndrei Emeltchenko 
2514b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
2515b71d385aSAndrei Emeltchenko 
2516b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
2517b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
2518b71d385aSAndrei Emeltchenko 				return;
2519b71d385aSAndrei Emeltchenko 
2520b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
2521b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
2522b71d385aSAndrei Emeltchenko 
2523b71d385aSAndrei Emeltchenko 			hci_send_frame(skb);
2524b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
2525b71d385aSAndrei Emeltchenko 
2526b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
2527b71d385aSAndrei Emeltchenko 			quote -= blocks;
2528b71d385aSAndrei Emeltchenko 
2529b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
2530b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
2531b71d385aSAndrei Emeltchenko 		}
2532b71d385aSAndrei Emeltchenko 	}
2533b71d385aSAndrei Emeltchenko 
2534b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
2535bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
2536b71d385aSAndrei Emeltchenko }
2537b71d385aSAndrei Emeltchenko 
25386039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
2539b71d385aSAndrei Emeltchenko {
2540b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
2541b71d385aSAndrei Emeltchenko 
2542bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
2543bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
2544bd1eb66bSAndrei Emeltchenko 		return;
2545bd1eb66bSAndrei Emeltchenko 
2546bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
2547bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
2548b71d385aSAndrei Emeltchenko 		return;
2549b71d385aSAndrei Emeltchenko 
2550b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
2551b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
2552b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
2553b71d385aSAndrei Emeltchenko 		break;
2554b71d385aSAndrei Emeltchenko 
2555b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
2556b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
2557b71d385aSAndrei Emeltchenko 		break;
2558b71d385aSAndrei Emeltchenko 	}
2559b71d385aSAndrei Emeltchenko }
2560b71d385aSAndrei Emeltchenko 
25611da177e4SLinus Torvalds /* Schedule SCO */
25626039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
25631da177e4SLinus Torvalds {
25641da177e4SLinus Torvalds 	struct hci_conn *conn;
25651da177e4SLinus Torvalds 	struct sk_buff *skb;
25661da177e4SLinus Torvalds 	int quote;
25671da177e4SLinus Torvalds 
25681da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
25691da177e4SLinus Torvalds 
257052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
257152087a79SLuiz Augusto von Dentz 		return;
257252087a79SLuiz Augusto von Dentz 
25731da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
25741da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
25751da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
25761da177e4SLinus Torvalds 			hci_send_frame(skb);
25771da177e4SLinus Torvalds 
25781da177e4SLinus Torvalds 			conn->sent++;
25791da177e4SLinus Torvalds 			if (conn->sent == ~0)
25801da177e4SLinus Torvalds 				conn->sent = 0;
25811da177e4SLinus Torvalds 		}
25821da177e4SLinus Torvalds 	}
25831da177e4SLinus Torvalds }
25841da177e4SLinus Torvalds 
25856039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
2586b6a0dc82SMarcel Holtmann {
2587b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
2588b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
2589b6a0dc82SMarcel Holtmann 	int quote;
2590b6a0dc82SMarcel Holtmann 
2591b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2592b6a0dc82SMarcel Holtmann 
259352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
259452087a79SLuiz Augusto von Dentz 		return;
259552087a79SLuiz Augusto von Dentz 
25968fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
25978fc9ced3SGustavo Padovan 						     &quote))) {
2598b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
2599b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
2600b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
2601b6a0dc82SMarcel Holtmann 
2602b6a0dc82SMarcel Holtmann 			conn->sent++;
2603b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
2604b6a0dc82SMarcel Holtmann 				conn->sent = 0;
2605b6a0dc82SMarcel Holtmann 		}
2606b6a0dc82SMarcel Holtmann 	}
2607b6a0dc82SMarcel Holtmann }
2608b6a0dc82SMarcel Holtmann 
26096039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
26106ed58ec5SVille Tervo {
261173d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
26126ed58ec5SVille Tervo 	struct sk_buff *skb;
261302b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
26146ed58ec5SVille Tervo 
26156ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
26166ed58ec5SVille Tervo 
261752087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
261852087a79SLuiz Augusto von Dentz 		return;
261952087a79SLuiz Augusto von Dentz 
26206ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
26216ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
26226ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
2623bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
26246ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
2625bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
26266ed58ec5SVille Tervo 	}
26276ed58ec5SVille Tervo 
26286ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
262902b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
263073d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
2631ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2632ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
263373d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
263473d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
26356ed58ec5SVille Tervo 
2636ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2637ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2638ec1cce24SLuiz Augusto von Dentz 				break;
2639ec1cce24SLuiz Augusto von Dentz 
2640ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2641ec1cce24SLuiz Augusto von Dentz 
26426ed58ec5SVille Tervo 			hci_send_frame(skb);
26436ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
26446ed58ec5SVille Tervo 
26456ed58ec5SVille Tervo 			cnt--;
264673d80debSLuiz Augusto von Dentz 			chan->sent++;
264773d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
26486ed58ec5SVille Tervo 		}
26496ed58ec5SVille Tervo 	}
265073d80debSLuiz Augusto von Dentz 
26516ed58ec5SVille Tervo 	if (hdev->le_pkts)
26526ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
26536ed58ec5SVille Tervo 	else
26546ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
265502b20f0bSLuiz Augusto von Dentz 
265602b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
265702b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
26586ed58ec5SVille Tervo }
26596ed58ec5SVille Tervo 
26603eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
26611da177e4SLinus Torvalds {
26623eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
26631da177e4SLinus Torvalds 	struct sk_buff *skb;
26641da177e4SLinus Torvalds 
26656ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
26666ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
26671da177e4SLinus Torvalds 
26681da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
26691da177e4SLinus Torvalds 
26701da177e4SLinus Torvalds 	hci_sched_acl(hdev);
26711da177e4SLinus Torvalds 
26721da177e4SLinus Torvalds 	hci_sched_sco(hdev);
26731da177e4SLinus Torvalds 
2674b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
2675b6a0dc82SMarcel Holtmann 
26766ed58ec5SVille Tervo 	hci_sched_le(hdev);
26776ed58ec5SVille Tervo 
26781da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
26791da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
26801da177e4SLinus Torvalds 		hci_send_frame(skb);
26811da177e4SLinus Torvalds }
26821da177e4SLinus Torvalds 
268325985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
26841da177e4SLinus Torvalds 
26851da177e4SLinus Torvalds /* ACL data packet */
26866039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
26871da177e4SLinus Torvalds {
26881da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
26891da177e4SLinus Torvalds 	struct hci_conn *conn;
26901da177e4SLinus Torvalds 	__u16 handle, flags;
26911da177e4SLinus Torvalds 
26921da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
26931da177e4SLinus Torvalds 
26941da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
26951da177e4SLinus Torvalds 	flags  = hci_flags(handle);
26961da177e4SLinus Torvalds 	handle = hci_handle(handle);
26971da177e4SLinus Torvalds 
2698f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
2699a8c5fb1aSGustavo Padovan 	       handle, flags);
27001da177e4SLinus Torvalds 
27011da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
27021da177e4SLinus Torvalds 
27031da177e4SLinus Torvalds 	hci_dev_lock(hdev);
27041da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
27051da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
27061da177e4SLinus Torvalds 
27071da177e4SLinus Torvalds 	if (conn) {
270865983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
270904837f64SMarcel Holtmann 
2710671267bfSJohan Hedberg 		hci_dev_lock(hdev);
2711671267bfSJohan Hedberg 		if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
2712671267bfSJohan Hedberg 		    !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2713671267bfSJohan Hedberg 			mgmt_device_connected(hdev, &conn->dst, conn->type,
2714671267bfSJohan Hedberg 					      conn->dst_type, 0, NULL, 0,
2715671267bfSJohan Hedberg 					      conn->dev_class);
2716671267bfSJohan Hedberg 		hci_dev_unlock(hdev);
2717671267bfSJohan Hedberg 
27181da177e4SLinus Torvalds 		/* Send to upper protocol */
2719686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
27201da177e4SLinus Torvalds 		return;
27211da177e4SLinus Torvalds 	} else {
27221da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
27231da177e4SLinus Torvalds 		       hdev->name, handle);
27241da177e4SLinus Torvalds 	}
27251da177e4SLinus Torvalds 
27261da177e4SLinus Torvalds 	kfree_skb(skb);
27271da177e4SLinus Torvalds }
27281da177e4SLinus Torvalds 
27291da177e4SLinus Torvalds /* SCO data packet */
27306039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
27311da177e4SLinus Torvalds {
27321da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
27331da177e4SLinus Torvalds 	struct hci_conn *conn;
27341da177e4SLinus Torvalds 	__u16 handle;
27351da177e4SLinus Torvalds 
27361da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
27371da177e4SLinus Torvalds 
27381da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
27391da177e4SLinus Torvalds 
2740f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
27411da177e4SLinus Torvalds 
27421da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
27431da177e4SLinus Torvalds 
27441da177e4SLinus Torvalds 	hci_dev_lock(hdev);
27451da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
27461da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
27471da177e4SLinus Torvalds 
27481da177e4SLinus Torvalds 	if (conn) {
27491da177e4SLinus Torvalds 		/* Send to upper protocol */
2750686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
27511da177e4SLinus Torvalds 		return;
27521da177e4SLinus Torvalds 	} else {
27531da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
27541da177e4SLinus Torvalds 		       hdev->name, handle);
27551da177e4SLinus Torvalds 	}
27561da177e4SLinus Torvalds 
27571da177e4SLinus Torvalds 	kfree_skb(skb);
27581da177e4SLinus Torvalds }
27591da177e4SLinus Torvalds 
2760b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
27611da177e4SLinus Torvalds {
2762b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
27631da177e4SLinus Torvalds 	struct sk_buff *skb;
27641da177e4SLinus Torvalds 
27651da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
27661da177e4SLinus Torvalds 
27671da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
2768cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
2769cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
2770cd82e61cSMarcel Holtmann 
27711da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
27721da177e4SLinus Torvalds 			/* Send copy to the sockets */
2773470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
27741da177e4SLinus Torvalds 		}
27751da177e4SLinus Torvalds 
27761da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
27771da177e4SLinus Torvalds 			kfree_skb(skb);
27781da177e4SLinus Torvalds 			continue;
27791da177e4SLinus Torvalds 		}
27801da177e4SLinus Torvalds 
27811da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
27821da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
27830d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
27841da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
27851da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
27861da177e4SLinus Torvalds 				kfree_skb(skb);
27871da177e4SLinus Torvalds 				continue;
27883ff50b79SStephen Hemminger 			}
27891da177e4SLinus Torvalds 		}
27901da177e4SLinus Torvalds 
27911da177e4SLinus Torvalds 		/* Process frame */
27920d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
27931da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
2794b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
27951da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
27961da177e4SLinus Torvalds 			break;
27971da177e4SLinus Torvalds 
27981da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
27991da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
28001da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
28011da177e4SLinus Torvalds 			break;
28021da177e4SLinus Torvalds 
28031da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
28041da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
28051da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
28061da177e4SLinus Torvalds 			break;
28071da177e4SLinus Torvalds 
28081da177e4SLinus Torvalds 		default:
28091da177e4SLinus Torvalds 			kfree_skb(skb);
28101da177e4SLinus Torvalds 			break;
28111da177e4SLinus Torvalds 		}
28121da177e4SLinus Torvalds 	}
28131da177e4SLinus Torvalds }
28141da177e4SLinus Torvalds 
2815c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
28161da177e4SLinus Torvalds {
2817c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
28181da177e4SLinus Torvalds 	struct sk_buff *skb;
28191da177e4SLinus Torvalds 
28202104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
28212104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
28221da177e4SLinus Torvalds 
28231da177e4SLinus Torvalds 	/* Send queued commands */
28245a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
28255a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
28265a08ecceSAndrei Emeltchenko 		if (!skb)
28275a08ecceSAndrei Emeltchenko 			return;
28285a08ecceSAndrei Emeltchenko 
28291da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
28301da177e4SLinus Torvalds 
283170f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
283270f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
28331da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
28341da177e4SLinus Torvalds 			hci_send_frame(skb);
28357bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
28367bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
28377bdb8a5cSSzymon Janc 			else
28386bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
28395f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
28401da177e4SLinus Torvalds 		} else {
28411da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
2842c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
28431da177e4SLinus Torvalds 		}
28441da177e4SLinus Torvalds 	}
28451da177e4SLinus Torvalds }
28462519a1fcSAndre Guedes 
28472519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
28482519a1fcSAndre Guedes {
28492519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
28502519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
28512519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
28522519a1fcSAndre Guedes 
28532519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
28542519a1fcSAndre Guedes 
28552519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
28562519a1fcSAndre Guedes 		return -EINPROGRESS;
28572519a1fcSAndre Guedes 
28584663262cSJohan Hedberg 	inquiry_cache_flush(hdev);
28594663262cSJohan Hedberg 
28602519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
28612519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
28622519a1fcSAndre Guedes 	cp.length  = length;
28632519a1fcSAndre Guedes 
28642519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
28652519a1fcSAndre Guedes }
2866023d5049SAndre Guedes 
2867023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
2868023d5049SAndre Guedes {
2869023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
2870023d5049SAndre Guedes 
2871023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
28727537e5c3SAndre Guedes 		return -EALREADY;
2873023d5049SAndre Guedes 
2874023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2875023d5049SAndre Guedes }
287631f7956cSAndre Guedes 
287731f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type)
287831f7956cSAndre Guedes {
287931f7956cSAndre Guedes 	switch (bdaddr_type) {
288031f7956cSAndre Guedes 	case BDADDR_LE_PUBLIC:
288131f7956cSAndre Guedes 		return ADDR_LE_DEV_PUBLIC;
288231f7956cSAndre Guedes 
288331f7956cSAndre Guedes 	default:
288431f7956cSAndre Guedes 		/* Fallback to LE Random address type */
288531f7956cSAndre Guedes 		return ADDR_LE_DEV_RANDOM;
288631f7956cSAndre Guedes 	}
288731f7956cSAndre Guedes }
2888