xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 8c520a59)
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>
291da177e4SLinus Torvalds 
30611b30f7SMarcel Holtmann #include <linux/rfkill.h>
311da177e4SLinus Torvalds 
321da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
331da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
341da177e4SLinus Torvalds 
35ab81cbf9SJohan Hedberg #define AUTO_OFF_TIMEOUT 2000
36ab81cbf9SJohan Hedberg 
37b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
38c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
393eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
401da177e4SLinus Torvalds 
411da177e4SLinus Torvalds /* HCI device list */
421da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
431da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
441da177e4SLinus Torvalds 
451da177e4SLinus Torvalds /* HCI callback list */
461da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
471da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
481da177e4SLinus Torvalds 
491da177e4SLinus Torvalds /* ---- HCI notifications ---- */
501da177e4SLinus Torvalds 
516516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
521da177e4SLinus Torvalds {
53040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
541da177e4SLinus Torvalds }
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds /* ---- HCI requests ---- */
571da177e4SLinus Torvalds 
5823bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
591da177e4SLinus Torvalds {
6023bb5763SJohan Hedberg 	BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result);
6123bb5763SJohan Hedberg 
62a5040efaSJohan Hedberg 	/* If this is the init phase check if the completed command matches
63a5040efaSJohan Hedberg 	 * the last init command, and if not just return.
64a5040efaSJohan Hedberg 	 */
6575fb0e32SJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) {
6675fb0e32SJohan Hedberg 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
671036b890SAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
6875fb0e32SJohan Hedberg 		struct sk_buff *skb;
6975fb0e32SJohan Hedberg 
7075fb0e32SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
7175fb0e32SJohan Hedberg 		 * reset complete event during init and any pending
7275fb0e32SJohan Hedberg 		 * command will never be completed. In such a case we
7375fb0e32SJohan Hedberg 		 * need to resend whatever was the last sent
7475fb0e32SJohan Hedberg 		 * command.
7575fb0e32SJohan Hedberg 		 */
7675fb0e32SJohan Hedberg 
771036b890SAndrei Emeltchenko 		if (cmd != HCI_OP_RESET || opcode == HCI_OP_RESET)
7823bb5763SJohan Hedberg 			return;
791da177e4SLinus Torvalds 
8075fb0e32SJohan Hedberg 		skb = skb_clone(hdev->sent_cmd, GFP_ATOMIC);
8175fb0e32SJohan Hedberg 		if (skb) {
8275fb0e32SJohan Hedberg 			skb_queue_head(&hdev->cmd_q, skb);
8375fb0e32SJohan Hedberg 			queue_work(hdev->workqueue, &hdev->cmd_work);
8475fb0e32SJohan Hedberg 		}
8575fb0e32SJohan Hedberg 
8675fb0e32SJohan Hedberg 		return;
8775fb0e32SJohan Hedberg 	}
8875fb0e32SJohan Hedberg 
891da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
901da177e4SLinus Torvalds 		hdev->req_result = result;
911da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
921da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
931da177e4SLinus Torvalds 	}
941da177e4SLinus Torvalds }
951da177e4SLinus Torvalds 
961da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
971da177e4SLinus Torvalds {
981da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
991da177e4SLinus Torvalds 
1001da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1011da177e4SLinus Torvalds 		hdev->req_result = err;
1021da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
1031da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1041da177e4SLinus Torvalds 	}
1051da177e4SLinus Torvalds }
1061da177e4SLinus Torvalds 
1071da177e4SLinus Torvalds /* Execute request and wait for completion. */
108a8c5fb1aSGustavo Padovan static int __hci_request(struct hci_dev *hdev,
109a8c5fb1aSGustavo Padovan 			 void (*req)(struct hci_dev *hdev, unsigned long opt),
1101da177e4SLinus Torvalds 			 unsigned long opt, __u32 timeout)
1111da177e4SLinus Torvalds {
1121da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
1131da177e4SLinus Torvalds 	int err = 0;
1141da177e4SLinus Torvalds 
1151da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
1161da177e4SLinus Torvalds 
1171da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
1181da177e4SLinus Torvalds 
1191da177e4SLinus Torvalds 	add_wait_queue(&hdev->req_wait_q, &wait);
1201da177e4SLinus Torvalds 	set_current_state(TASK_INTERRUPTIBLE);
1211da177e4SLinus Torvalds 
1221da177e4SLinus Torvalds 	req(hdev, opt);
1231da177e4SLinus Torvalds 	schedule_timeout(timeout);
1241da177e4SLinus Torvalds 
1251da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
1261da177e4SLinus Torvalds 
1271da177e4SLinus Torvalds 	if (signal_pending(current))
1281da177e4SLinus Torvalds 		return -EINTR;
1291da177e4SLinus Torvalds 
1301da177e4SLinus Torvalds 	switch (hdev->req_status) {
1311da177e4SLinus Torvalds 	case HCI_REQ_DONE:
132e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
1331da177e4SLinus Torvalds 		break;
1341da177e4SLinus Torvalds 
1351da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
1361da177e4SLinus Torvalds 		err = -hdev->req_result;
1371da177e4SLinus Torvalds 		break;
1381da177e4SLinus Torvalds 
1391da177e4SLinus Torvalds 	default:
1401da177e4SLinus Torvalds 		err = -ETIMEDOUT;
1411da177e4SLinus Torvalds 		break;
1423ff50b79SStephen Hemminger 	}
1431da177e4SLinus Torvalds 
144a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
1451da177e4SLinus Torvalds 
1461da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
1471da177e4SLinus Torvalds 
1481da177e4SLinus Torvalds 	return err;
1491da177e4SLinus Torvalds }
1501da177e4SLinus Torvalds 
1516039aa73SGustavo Padovan static int hci_request(struct hci_dev *hdev,
1526039aa73SGustavo Padovan 		       void (*req)(struct hci_dev *hdev, unsigned long opt),
1531da177e4SLinus Torvalds 		       unsigned long opt, __u32 timeout)
1541da177e4SLinus Torvalds {
1551da177e4SLinus Torvalds 	int ret;
1561da177e4SLinus Torvalds 
1577c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
1587c6a329eSMarcel Holtmann 		return -ENETDOWN;
1597c6a329eSMarcel Holtmann 
1601da177e4SLinus Torvalds 	/* Serialize all requests */
1611da177e4SLinus Torvalds 	hci_req_lock(hdev);
1621da177e4SLinus Torvalds 	ret = __hci_request(hdev, req, opt, timeout);
1631da177e4SLinus Torvalds 	hci_req_unlock(hdev);
1641da177e4SLinus Torvalds 
1651da177e4SLinus Torvalds 	return ret;
1661da177e4SLinus Torvalds }
1671da177e4SLinus Torvalds 
1681da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
1691da177e4SLinus Torvalds {
1701da177e4SLinus Torvalds 	BT_DBG("%s %ld", hdev->name, opt);
1711da177e4SLinus Torvalds 
1721da177e4SLinus Torvalds 	/* Reset device */
173f630cf0dSGustavo F. Padovan 	set_bit(HCI_RESET, &hdev->flags);
174a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
1751da177e4SLinus Torvalds }
1761da177e4SLinus Torvalds 
177e61ef499SAndrei Emeltchenko static void bredr_init(struct hci_dev *hdev)
1781da177e4SLinus Torvalds {
179b0916ea0SJohan Hedberg 	struct hci_cp_delete_stored_link_key cp;
1801ebb9252SMarcel Holtmann 	__le16 param;
18189f2783dSMarcel Holtmann 	__u8 flt_type;
1821da177e4SLinus Torvalds 
1832455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
1842455a3eaSAndrei Emeltchenko 
1851da177e4SLinus Torvalds 	/* Mandatory initialization */
1861da177e4SLinus Torvalds 
1871da177e4SLinus Torvalds 	/* Reset */
188a6c511c6SSzymon Janc 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
189f630cf0dSGustavo F. Padovan 		set_bit(HCI_RESET, &hdev->flags);
190a9de9248SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
191f630cf0dSGustavo F. Padovan 	}
1921da177e4SLinus Torvalds 
1931da177e4SLinus Torvalds 	/* Read Local Supported Features */
194a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
1951da177e4SLinus Torvalds 
1961143e5a6SMarcel Holtmann 	/* Read Local Version */
197a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
1981143e5a6SMarcel Holtmann 
1991da177e4SLinus Torvalds 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
200a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
2011da177e4SLinus Torvalds 
2021da177e4SLinus Torvalds 	/* Read BD Address */
203a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
204a9de9248SMarcel Holtmann 
205a9de9248SMarcel Holtmann 	/* Read Class of Device */
206a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
207a9de9248SMarcel Holtmann 
208a9de9248SMarcel Holtmann 	/* Read Local Name */
209a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
2101da177e4SLinus Torvalds 
2111da177e4SLinus Torvalds 	/* Read Voice Setting */
212a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
2131da177e4SLinus Torvalds 
2141da177e4SLinus Torvalds 	/* Optional initialization */
2151da177e4SLinus Torvalds 
2161da177e4SLinus Torvalds 	/* Clear Event Filters */
21789f2783dSMarcel Holtmann 	flt_type = HCI_FLT_CLEAR_ALL;
218a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
2191da177e4SLinus Torvalds 
2201da177e4SLinus Torvalds 	/* Connection accept timeout ~20 secs */
221aca3192cSYOSHIFUJI Hideaki 	param = cpu_to_le16(0x7d00);
222a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
223b0916ea0SJohan Hedberg 
224b0916ea0SJohan Hedberg 	bacpy(&cp.bdaddr, BDADDR_ANY);
225b0916ea0SJohan Hedberg 	cp.delete_all = 1;
226b0916ea0SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
2271da177e4SLinus Torvalds }
2281da177e4SLinus Torvalds 
229e61ef499SAndrei Emeltchenko static void amp_init(struct hci_dev *hdev)
230e61ef499SAndrei Emeltchenko {
2312455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
2322455a3eaSAndrei Emeltchenko 
233e61ef499SAndrei Emeltchenko 	/* Reset */
234e61ef499SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
235e61ef499SAndrei Emeltchenko 
236e61ef499SAndrei Emeltchenko 	/* Read Local Version */
237e61ef499SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2386bcbc489SAndrei Emeltchenko 
2396bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
2406bcbc489SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
241e61ef499SAndrei Emeltchenko }
242e61ef499SAndrei Emeltchenko 
243e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
244e61ef499SAndrei Emeltchenko {
245e61ef499SAndrei Emeltchenko 	struct sk_buff *skb;
246e61ef499SAndrei Emeltchenko 
247e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
248e61ef499SAndrei Emeltchenko 
249e61ef499SAndrei Emeltchenko 	/* Driver initialization */
250e61ef499SAndrei Emeltchenko 
251e61ef499SAndrei Emeltchenko 	/* Special commands */
252e61ef499SAndrei Emeltchenko 	while ((skb = skb_dequeue(&hdev->driver_init))) {
253e61ef499SAndrei Emeltchenko 		bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
254e61ef499SAndrei Emeltchenko 		skb->dev = (void *) hdev;
255e61ef499SAndrei Emeltchenko 
256e61ef499SAndrei Emeltchenko 		skb_queue_tail(&hdev->cmd_q, skb);
257e61ef499SAndrei Emeltchenko 		queue_work(hdev->workqueue, &hdev->cmd_work);
258e61ef499SAndrei Emeltchenko 	}
259e61ef499SAndrei Emeltchenko 	skb_queue_purge(&hdev->driver_init);
260e61ef499SAndrei Emeltchenko 
261e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
262e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
263e61ef499SAndrei Emeltchenko 		bredr_init(hdev);
264e61ef499SAndrei Emeltchenko 		break;
265e61ef499SAndrei Emeltchenko 
266e61ef499SAndrei Emeltchenko 	case HCI_AMP:
267e61ef499SAndrei Emeltchenko 		amp_init(hdev);
268e61ef499SAndrei Emeltchenko 		break;
269e61ef499SAndrei Emeltchenko 
270e61ef499SAndrei Emeltchenko 	default:
271e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
272e61ef499SAndrei Emeltchenko 		break;
273e61ef499SAndrei Emeltchenko 	}
274e61ef499SAndrei Emeltchenko 
275e61ef499SAndrei Emeltchenko }
276e61ef499SAndrei Emeltchenko 
2776ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
2786ed58ec5SVille Tervo {
2796ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
2806ed58ec5SVille Tervo 
2816ed58ec5SVille Tervo 	/* Read LE buffer size */
2826ed58ec5SVille Tervo 	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
2836ed58ec5SVille Tervo }
2846ed58ec5SVille Tervo 
2851da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
2861da177e4SLinus Torvalds {
2871da177e4SLinus Torvalds 	__u8 scan = opt;
2881da177e4SLinus Torvalds 
2891da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, scan);
2901da177e4SLinus Torvalds 
2911da177e4SLinus Torvalds 	/* Inquiry and Page scans */
292a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
2931da177e4SLinus Torvalds }
2941da177e4SLinus Torvalds 
2951da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
2961da177e4SLinus Torvalds {
2971da177e4SLinus Torvalds 	__u8 auth = opt;
2981da177e4SLinus Torvalds 
2991da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, auth);
3001da177e4SLinus Torvalds 
3011da177e4SLinus Torvalds 	/* Authentication */
302a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
3031da177e4SLinus Torvalds }
3041da177e4SLinus Torvalds 
3051da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
3061da177e4SLinus Torvalds {
3071da177e4SLinus Torvalds 	__u8 encrypt = opt;
3081da177e4SLinus Torvalds 
3091da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, encrypt);
3101da177e4SLinus Torvalds 
311e4e8e37cSMarcel Holtmann 	/* Encryption */
312a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
3131da177e4SLinus Torvalds }
3141da177e4SLinus Torvalds 
315e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt)
316e4e8e37cSMarcel Holtmann {
317e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
318e4e8e37cSMarcel Holtmann 
319a418b893SMarcel Holtmann 	BT_DBG("%s %x", hdev->name, policy);
320e4e8e37cSMarcel Holtmann 
321e4e8e37cSMarcel Holtmann 	/* Default link policy */
322e4e8e37cSMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
323e4e8e37cSMarcel Holtmann }
324e4e8e37cSMarcel Holtmann 
3251da177e4SLinus Torvalds /* Get HCI device by index.
3261da177e4SLinus Torvalds  * Device is held on return. */
3271da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
3281da177e4SLinus Torvalds {
3298035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
3301da177e4SLinus Torvalds 
3311da177e4SLinus Torvalds 	BT_DBG("%d", index);
3321da177e4SLinus Torvalds 
3331da177e4SLinus Torvalds 	if (index < 0)
3341da177e4SLinus Torvalds 		return NULL;
3351da177e4SLinus Torvalds 
3361da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
3378035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
3381da177e4SLinus Torvalds 		if (d->id == index) {
3391da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
3401da177e4SLinus Torvalds 			break;
3411da177e4SLinus Torvalds 		}
3421da177e4SLinus Torvalds 	}
3431da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
3441da177e4SLinus Torvalds 	return hdev;
3451da177e4SLinus Torvalds }
3461da177e4SLinus Torvalds 
3471da177e4SLinus Torvalds /* ---- Inquiry support ---- */
348ff9ef578SJohan Hedberg 
34930dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
35030dc78e1SJohan Hedberg {
35130dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
35230dc78e1SJohan Hedberg 
3536fbe195dSAndre Guedes 	switch (discov->state) {
354343f935bSAndre Guedes 	case DISCOVERY_FINDING:
3556fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
35630dc78e1SJohan Hedberg 		return true;
35730dc78e1SJohan Hedberg 
3586fbe195dSAndre Guedes 	default:
35930dc78e1SJohan Hedberg 		return false;
36030dc78e1SJohan Hedberg 	}
3616fbe195dSAndre Guedes }
36230dc78e1SJohan Hedberg 
363ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
364ff9ef578SJohan Hedberg {
365ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
366ff9ef578SJohan Hedberg 
367ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
368ff9ef578SJohan Hedberg 		return;
369ff9ef578SJohan Hedberg 
370ff9ef578SJohan Hedberg 	switch (state) {
371ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
3727b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
373ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
374ff9ef578SJohan Hedberg 		break;
375ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
376ff9ef578SJohan Hedberg 		break;
377343f935bSAndre Guedes 	case DISCOVERY_FINDING:
378ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
379ff9ef578SJohan Hedberg 		break;
38030dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
38130dc78e1SJohan Hedberg 		break;
382ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
383ff9ef578SJohan Hedberg 		break;
384ff9ef578SJohan Hedberg 	}
385ff9ef578SJohan Hedberg 
386ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
387ff9ef578SJohan Hedberg }
388ff9ef578SJohan Hedberg 
3891da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
3901da177e4SLinus Torvalds {
39130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
392b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
3931da177e4SLinus Torvalds 
394561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
395561aafbcSJohan Hedberg 		list_del(&p->all);
396b57c1a56SJohan Hedberg 		kfree(p);
3971da177e4SLinus Torvalds 	}
398561aafbcSJohan Hedberg 
399561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
400561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
4011da177e4SLinus Torvalds }
4021da177e4SLinus Torvalds 
403a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
404a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
4051da177e4SLinus Torvalds {
40630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
4071da177e4SLinus Torvalds 	struct inquiry_entry *e;
4081da177e4SLinus Torvalds 
4091da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
4101da177e4SLinus Torvalds 
411561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
4121da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
4131da177e4SLinus Torvalds 			return e;
4141da177e4SLinus Torvalds 	}
4151da177e4SLinus Torvalds 
416b57c1a56SJohan Hedberg 	return NULL;
417b57c1a56SJohan Hedberg }
418b57c1a56SJohan Hedberg 
419561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
420561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
421561aafbcSJohan Hedberg {
42230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
423561aafbcSJohan Hedberg 	struct inquiry_entry *e;
424561aafbcSJohan Hedberg 
425561aafbcSJohan Hedberg 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
426561aafbcSJohan Hedberg 
427561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
428561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
429561aafbcSJohan Hedberg 			return e;
430561aafbcSJohan Hedberg 	}
431561aafbcSJohan Hedberg 
432561aafbcSJohan Hedberg 	return NULL;
433561aafbcSJohan Hedberg }
434561aafbcSJohan Hedberg 
43530dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
43630dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
43730dc78e1SJohan Hedberg 						       int state)
43830dc78e1SJohan Hedberg {
43930dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
44030dc78e1SJohan Hedberg 	struct inquiry_entry *e;
44130dc78e1SJohan Hedberg 
44230dc78e1SJohan Hedberg 	BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state);
44330dc78e1SJohan Hedberg 
44430dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
44530dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
44630dc78e1SJohan Hedberg 			return e;
44730dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
44830dc78e1SJohan Hedberg 			return e;
44930dc78e1SJohan Hedberg 	}
45030dc78e1SJohan Hedberg 
45130dc78e1SJohan Hedberg 	return NULL;
45230dc78e1SJohan Hedberg }
45330dc78e1SJohan Hedberg 
454a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
455a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
456a3d4e20aSJohan Hedberg {
457a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
458a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
459a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
460a3d4e20aSJohan Hedberg 
461a3d4e20aSJohan Hedberg 	list_del(&ie->list);
462a3d4e20aSJohan Hedberg 
463a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
464a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
465a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
466a3d4e20aSJohan Hedberg 			break;
467a3d4e20aSJohan Hedberg 		pos = &p->list;
468a3d4e20aSJohan Hedberg 	}
469a3d4e20aSJohan Hedberg 
470a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
471a3d4e20aSJohan Hedberg }
472a3d4e20aSJohan Hedberg 
4733175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
474388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
4751da177e4SLinus Torvalds {
47630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
47770f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
4781da177e4SLinus Torvalds 
4791da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
4801da177e4SLinus Torvalds 
481388fc8faSJohan Hedberg 	if (ssp)
482388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
483388fc8faSJohan Hedberg 
48470f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
485a3d4e20aSJohan Hedberg 	if (ie) {
486388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
487388fc8faSJohan Hedberg 			*ssp = true;
488388fc8faSJohan Hedberg 
489a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
490a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
491a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
492a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
493a3d4e20aSJohan Hedberg 		}
494a3d4e20aSJohan Hedberg 
495561aafbcSJohan Hedberg 		goto update;
496a3d4e20aSJohan Hedberg 	}
497561aafbcSJohan Hedberg 
4981da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
49970f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
50070f23020SAndrei Emeltchenko 	if (!ie)
5013175405bSJohan Hedberg 		return false;
50270f23020SAndrei Emeltchenko 
503561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
504561aafbcSJohan Hedberg 
505561aafbcSJohan Hedberg 	if (name_known) {
506561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
507561aafbcSJohan Hedberg 	} else {
508561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
509561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
510561aafbcSJohan Hedberg 	}
511561aafbcSJohan Hedberg 
512561aafbcSJohan Hedberg update:
513561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
514561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
515561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
516561aafbcSJohan Hedberg 		list_del(&ie->list);
5171da177e4SLinus Torvalds 	}
5181da177e4SLinus Torvalds 
51970f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
52070f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
5211da177e4SLinus Torvalds 	cache->timestamp = jiffies;
5223175405bSJohan Hedberg 
5233175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
5243175405bSJohan Hedberg 		return false;
5253175405bSJohan Hedberg 
5263175405bSJohan Hedberg 	return true;
5271da177e4SLinus Torvalds }
5281da177e4SLinus Torvalds 
5291da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
5301da177e4SLinus Torvalds {
53130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
5321da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
5331da177e4SLinus Torvalds 	struct inquiry_entry *e;
5341da177e4SLinus Torvalds 	int copied = 0;
5351da177e4SLinus Torvalds 
536561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
5371da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
538b57c1a56SJohan Hedberg 
539b57c1a56SJohan Hedberg 		if (copied >= num)
540b57c1a56SJohan Hedberg 			break;
541b57c1a56SJohan Hedberg 
5421da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
5431da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
5441da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
5451da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
5461da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
5471da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
548b57c1a56SJohan Hedberg 
5491da177e4SLinus Torvalds 		info++;
550b57c1a56SJohan Hedberg 		copied++;
5511da177e4SLinus Torvalds 	}
5521da177e4SLinus Torvalds 
5531da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
5541da177e4SLinus Torvalds 	return copied;
5551da177e4SLinus Torvalds }
5561da177e4SLinus Torvalds 
5571da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
5581da177e4SLinus Torvalds {
5591da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
5601da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
5611da177e4SLinus Torvalds 
5621da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
5631da177e4SLinus Torvalds 
5641da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
5651da177e4SLinus Torvalds 		return;
5661da177e4SLinus Torvalds 
5671da177e4SLinus Torvalds 	/* Start Inquiry */
5681da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
5691da177e4SLinus Torvalds 	cp.length  = ir->length;
5701da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
571a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
5721da177e4SLinus Torvalds }
5731da177e4SLinus Torvalds 
5741da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
5751da177e4SLinus Torvalds {
5761da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
5771da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
5781da177e4SLinus Torvalds 	struct hci_dev *hdev;
5791da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
5801da177e4SLinus Torvalds 	long timeo;
5811da177e4SLinus Torvalds 	__u8 *buf;
5821da177e4SLinus Torvalds 
5831da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
5841da177e4SLinus Torvalds 		return -EFAULT;
5851da177e4SLinus Torvalds 
5865a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
5875a08ecceSAndrei Emeltchenko 	if (!hdev)
5881da177e4SLinus Torvalds 		return -ENODEV;
5891da177e4SLinus Torvalds 
59009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5911da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
592a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
5931da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
5941da177e4SLinus Torvalds 		do_inquiry = 1;
5951da177e4SLinus Torvalds 	}
59609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
5971da177e4SLinus Torvalds 
59804837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
59970f23020SAndrei Emeltchenko 
60070f23020SAndrei Emeltchenko 	if (do_inquiry) {
60170f23020SAndrei Emeltchenko 		err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
60270f23020SAndrei Emeltchenko 		if (err < 0)
6031da177e4SLinus Torvalds 			goto done;
60470f23020SAndrei Emeltchenko 	}
6051da177e4SLinus Torvalds 
6068fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
6078fc9ced3SGustavo Padovan 	 * 255 entries
6088fc9ced3SGustavo Padovan 	 */
6091da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
6101da177e4SLinus Torvalds 
6111da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
6121da177e4SLinus Torvalds 	 * copy it to the user space.
6131da177e4SLinus Torvalds 	 */
61470f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
61570f23020SAndrei Emeltchenko 	if (!buf) {
6161da177e4SLinus Torvalds 		err = -ENOMEM;
6171da177e4SLinus Torvalds 		goto done;
6181da177e4SLinus Torvalds 	}
6191da177e4SLinus Torvalds 
62009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6211da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
62209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6231da177e4SLinus Torvalds 
6241da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
6251da177e4SLinus Torvalds 
6261da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
6271da177e4SLinus Torvalds 		ptr += sizeof(ir);
6281da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
6291da177e4SLinus Torvalds 				 ir.num_rsp))
6301da177e4SLinus Torvalds 			err = -EFAULT;
6311da177e4SLinus Torvalds 	} else
6321da177e4SLinus Torvalds 		err = -EFAULT;
6331da177e4SLinus Torvalds 
6341da177e4SLinus Torvalds 	kfree(buf);
6351da177e4SLinus Torvalds 
6361da177e4SLinus Torvalds done:
6371da177e4SLinus Torvalds 	hci_dev_put(hdev);
6381da177e4SLinus Torvalds 	return err;
6391da177e4SLinus Torvalds }
6401da177e4SLinus Torvalds 
6411da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
6421da177e4SLinus Torvalds 
6431da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
6441da177e4SLinus Torvalds {
6451da177e4SLinus Torvalds 	struct hci_dev *hdev;
6461da177e4SLinus Torvalds 	int ret = 0;
6471da177e4SLinus Torvalds 
6485a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
6495a08ecceSAndrei Emeltchenko 	if (!hdev)
6501da177e4SLinus Torvalds 		return -ENODEV;
6511da177e4SLinus Torvalds 
6521da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
6531da177e4SLinus Torvalds 
6541da177e4SLinus Torvalds 	hci_req_lock(hdev);
6551da177e4SLinus Torvalds 
65694324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
65794324962SJohan Hovold 		ret = -ENODEV;
65894324962SJohan Hovold 		goto done;
65994324962SJohan Hovold 	}
66094324962SJohan Hovold 
661611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
662611b30f7SMarcel Holtmann 		ret = -ERFKILL;
663611b30f7SMarcel Holtmann 		goto done;
664611b30f7SMarcel Holtmann 	}
665611b30f7SMarcel Holtmann 
6661da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
6671da177e4SLinus Torvalds 		ret = -EALREADY;
6681da177e4SLinus Torvalds 		goto done;
6691da177e4SLinus Torvalds 	}
6701da177e4SLinus Torvalds 
6711da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
6721da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
6731da177e4SLinus Torvalds 
67407e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
67507e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
67607e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
677943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
678943da25dSMarcel Holtmann 
6791da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
6801da177e4SLinus Torvalds 		ret = -EIO;
6811da177e4SLinus Torvalds 		goto done;
6821da177e4SLinus Torvalds 	}
6831da177e4SLinus Torvalds 
6841da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
6851da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
6861da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
687a5040efaSJohan Hedberg 		hdev->init_last_cmd = 0;
6881da177e4SLinus Torvalds 
68904837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_init_req, 0,
69004837f64SMarcel Holtmann 				    msecs_to_jiffies(HCI_INIT_TIMEOUT));
6911da177e4SLinus Torvalds 
692eead27daSAndre Guedes 		if (lmp_host_le_capable(hdev))
6936ed58ec5SVille Tervo 			ret = __hci_request(hdev, hci_le_init_req, 0,
6946ed58ec5SVille Tervo 					    msecs_to_jiffies(HCI_INIT_TIMEOUT));
6956ed58ec5SVille Tervo 
6961da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
6971da177e4SLinus Torvalds 	}
6981da177e4SLinus Torvalds 
6991da177e4SLinus Torvalds 	if (!ret) {
7001da177e4SLinus Torvalds 		hci_dev_hold(hdev);
7011da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
7021da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
703a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
70409fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
705744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
70609fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
70756e5cb86SJohan Hedberg 		}
7081da177e4SLinus Torvalds 	} else {
7091da177e4SLinus Torvalds 		/* Init failed, cleanup */
7103eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
711c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
712b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
7131da177e4SLinus Torvalds 
7141da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
7151da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
7161da177e4SLinus Torvalds 
7171da177e4SLinus Torvalds 		if (hdev->flush)
7181da177e4SLinus Torvalds 			hdev->flush(hdev);
7191da177e4SLinus Torvalds 
7201da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
7211da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
7221da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
7231da177e4SLinus Torvalds 		}
7241da177e4SLinus Torvalds 
7251da177e4SLinus Torvalds 		hdev->close(hdev);
7261da177e4SLinus Torvalds 		hdev->flags = 0;
7271da177e4SLinus Torvalds 	}
7281da177e4SLinus Torvalds 
7291da177e4SLinus Torvalds done:
7301da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7311da177e4SLinus Torvalds 	hci_dev_put(hdev);
7321da177e4SLinus Torvalds 	return ret;
7331da177e4SLinus Torvalds }
7341da177e4SLinus Torvalds 
7351da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
7361da177e4SLinus Torvalds {
7371da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
7381da177e4SLinus Torvalds 
73928b75a89SAndre Guedes 	cancel_work_sync(&hdev->le_scan);
74028b75a89SAndre Guedes 
7411da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
7421da177e4SLinus Torvalds 	hci_req_lock(hdev);
7431da177e4SLinus Torvalds 
7441da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
745b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7461da177e4SLinus Torvalds 		hci_req_unlock(hdev);
7471da177e4SLinus Torvalds 		return 0;
7481da177e4SLinus Torvalds 	}
7491da177e4SLinus Torvalds 
7503eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
7513eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
752b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
7531da177e4SLinus Torvalds 
75416ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
755e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
75616ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
7575e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
75816ab91abSJohan Hedberg 	}
75916ab91abSJohan Hedberg 
760a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
7617d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
7627d78525dSJohan Hedberg 
7637ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
7647ba8b4beSAndre Guedes 
76509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
7661da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
7671da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
76809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7691da177e4SLinus Torvalds 
7701da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
7711da177e4SLinus Torvalds 
7721da177e4SLinus Torvalds 	if (hdev->flush)
7731da177e4SLinus Torvalds 		hdev->flush(hdev);
7741da177e4SLinus Torvalds 
7751da177e4SLinus Torvalds 	/* Reset device */
7761da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7771da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
7788af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
779a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
7801da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
78104837f64SMarcel Holtmann 		__hci_request(hdev, hci_reset_req, 0,
782cad44c2bSGustavo F. Padovan 			      msecs_to_jiffies(250));
7831da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
7841da177e4SLinus Torvalds 	}
7851da177e4SLinus Torvalds 
786c347b765SGustavo F. Padovan 	/* flush cmd  work */
787c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
7881da177e4SLinus Torvalds 
7891da177e4SLinus Torvalds 	/* Drop queues */
7901da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
7911da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7921da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
7931da177e4SLinus Torvalds 
7941da177e4SLinus Torvalds 	/* Drop last sent command */
7951da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
796b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7971da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
7981da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
7991da177e4SLinus Torvalds 	}
8001da177e4SLinus Torvalds 
8011da177e4SLinus Torvalds 	/* After this point our queues are empty
8021da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
8031da177e4SLinus Torvalds 	hdev->close(hdev);
8041da177e4SLinus Torvalds 
8058ee56540SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
80609fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
807744cf19eSJohan Hedberg 		mgmt_powered(hdev, 0);
80809fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
8098ee56540SMarcel Holtmann 	}
8105add6af8SJohan Hedberg 
8111da177e4SLinus Torvalds 	/* Clear flags */
8121da177e4SLinus Torvalds 	hdev->flags = 0;
8131da177e4SLinus Torvalds 
814e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
81509b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
816e59fda8dSJohan Hedberg 
8171da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8181da177e4SLinus Torvalds 
8191da177e4SLinus Torvalds 	hci_dev_put(hdev);
8201da177e4SLinus Torvalds 	return 0;
8211da177e4SLinus Torvalds }
8221da177e4SLinus Torvalds 
8231da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
8241da177e4SLinus Torvalds {
8251da177e4SLinus Torvalds 	struct hci_dev *hdev;
8261da177e4SLinus Torvalds 	int err;
8271da177e4SLinus Torvalds 
82870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
82970f23020SAndrei Emeltchenko 	if (!hdev)
8301da177e4SLinus Torvalds 		return -ENODEV;
8318ee56540SMarcel Holtmann 
8328ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
8338ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
8348ee56540SMarcel Holtmann 
8351da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
8368ee56540SMarcel Holtmann 
8371da177e4SLinus Torvalds 	hci_dev_put(hdev);
8381da177e4SLinus Torvalds 	return err;
8391da177e4SLinus Torvalds }
8401da177e4SLinus Torvalds 
8411da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
8421da177e4SLinus Torvalds {
8431da177e4SLinus Torvalds 	struct hci_dev *hdev;
8441da177e4SLinus Torvalds 	int ret = 0;
8451da177e4SLinus Torvalds 
84670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
84770f23020SAndrei Emeltchenko 	if (!hdev)
8481da177e4SLinus Torvalds 		return -ENODEV;
8491da177e4SLinus Torvalds 
8501da177e4SLinus Torvalds 	hci_req_lock(hdev);
8511da177e4SLinus Torvalds 
8521da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
8531da177e4SLinus Torvalds 		goto done;
8541da177e4SLinus Torvalds 
8551da177e4SLinus Torvalds 	/* Drop queues */
8561da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
8571da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
8581da177e4SLinus Torvalds 
85909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
8601da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
8611da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
86209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
8631da177e4SLinus Torvalds 
8641da177e4SLinus Torvalds 	if (hdev->flush)
8651da177e4SLinus Torvalds 		hdev->flush(hdev);
8661da177e4SLinus Torvalds 
8671da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
8686ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
8691da177e4SLinus Torvalds 
8701da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
87104837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_reset_req, 0,
87204837f64SMarcel Holtmann 				    msecs_to_jiffies(HCI_INIT_TIMEOUT));
8731da177e4SLinus Torvalds 
8741da177e4SLinus Torvalds done:
8751da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8761da177e4SLinus Torvalds 	hci_dev_put(hdev);
8771da177e4SLinus Torvalds 	return ret;
8781da177e4SLinus Torvalds }
8791da177e4SLinus Torvalds 
8801da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
8811da177e4SLinus Torvalds {
8821da177e4SLinus Torvalds 	struct hci_dev *hdev;
8831da177e4SLinus Torvalds 	int ret = 0;
8841da177e4SLinus Torvalds 
88570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
88670f23020SAndrei Emeltchenko 	if (!hdev)
8871da177e4SLinus Torvalds 		return -ENODEV;
8881da177e4SLinus Torvalds 
8891da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
8901da177e4SLinus Torvalds 
8911da177e4SLinus Torvalds 	hci_dev_put(hdev);
8921da177e4SLinus Torvalds 
8931da177e4SLinus Torvalds 	return ret;
8941da177e4SLinus Torvalds }
8951da177e4SLinus Torvalds 
8961da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
8971da177e4SLinus Torvalds {
8981da177e4SLinus Torvalds 	struct hci_dev *hdev;
8991da177e4SLinus Torvalds 	struct hci_dev_req dr;
9001da177e4SLinus Torvalds 	int err = 0;
9011da177e4SLinus Torvalds 
9021da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
9031da177e4SLinus Torvalds 		return -EFAULT;
9041da177e4SLinus Torvalds 
90570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
90670f23020SAndrei Emeltchenko 	if (!hdev)
9071da177e4SLinus Torvalds 		return -ENODEV;
9081da177e4SLinus Torvalds 
9091da177e4SLinus Torvalds 	switch (cmd) {
9101da177e4SLinus Torvalds 	case HCISETAUTH:
91104837f64SMarcel Holtmann 		err = hci_request(hdev, hci_auth_req, dr.dev_opt,
91204837f64SMarcel Holtmann 				  msecs_to_jiffies(HCI_INIT_TIMEOUT));
9131da177e4SLinus Torvalds 		break;
9141da177e4SLinus Torvalds 
9151da177e4SLinus Torvalds 	case HCISETENCRYPT:
9161da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
9171da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
9181da177e4SLinus Torvalds 			break;
9191da177e4SLinus Torvalds 		}
9201da177e4SLinus Torvalds 
9211da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
9221da177e4SLinus Torvalds 			/* Auth must be enabled first */
92304837f64SMarcel Holtmann 			err = hci_request(hdev, hci_auth_req, dr.dev_opt,
92404837f64SMarcel Holtmann 					  msecs_to_jiffies(HCI_INIT_TIMEOUT));
9251da177e4SLinus Torvalds 			if (err)
9261da177e4SLinus Torvalds 				break;
9271da177e4SLinus Torvalds 		}
9281da177e4SLinus Torvalds 
92904837f64SMarcel Holtmann 		err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
93004837f64SMarcel Holtmann 				  msecs_to_jiffies(HCI_INIT_TIMEOUT));
9311da177e4SLinus Torvalds 		break;
9321da177e4SLinus Torvalds 
9331da177e4SLinus Torvalds 	case HCISETSCAN:
93404837f64SMarcel Holtmann 		err = hci_request(hdev, hci_scan_req, dr.dev_opt,
93504837f64SMarcel Holtmann 				  msecs_to_jiffies(HCI_INIT_TIMEOUT));
9361da177e4SLinus Torvalds 		break;
9371da177e4SLinus Torvalds 
9381da177e4SLinus Torvalds 	case HCISETLINKPOL:
939e4e8e37cSMarcel Holtmann 		err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
940e4e8e37cSMarcel Holtmann 				  msecs_to_jiffies(HCI_INIT_TIMEOUT));
9411da177e4SLinus Torvalds 		break;
9421da177e4SLinus Torvalds 
9431da177e4SLinus Torvalds 	case HCISETLINKMODE:
944e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
945e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
946e4e8e37cSMarcel Holtmann 		break;
947e4e8e37cSMarcel Holtmann 
948e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
949e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
9501da177e4SLinus Torvalds 		break;
9511da177e4SLinus Torvalds 
9521da177e4SLinus Torvalds 	case HCISETACLMTU:
9531da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
9541da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
9551da177e4SLinus Torvalds 		break;
9561da177e4SLinus Torvalds 
9571da177e4SLinus Torvalds 	case HCISETSCOMTU:
9581da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
9591da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
9601da177e4SLinus Torvalds 		break;
9611da177e4SLinus Torvalds 
9621da177e4SLinus Torvalds 	default:
9631da177e4SLinus Torvalds 		err = -EINVAL;
9641da177e4SLinus Torvalds 		break;
9651da177e4SLinus Torvalds 	}
966e4e8e37cSMarcel Holtmann 
9671da177e4SLinus Torvalds 	hci_dev_put(hdev);
9681da177e4SLinus Torvalds 	return err;
9691da177e4SLinus Torvalds }
9701da177e4SLinus Torvalds 
9711da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
9721da177e4SLinus Torvalds {
9738035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
9741da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
9751da177e4SLinus Torvalds 	struct hci_dev_req *dr;
9761da177e4SLinus Torvalds 	int n = 0, size, err;
9771da177e4SLinus Torvalds 	__u16 dev_num;
9781da177e4SLinus Torvalds 
9791da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
9801da177e4SLinus Torvalds 		return -EFAULT;
9811da177e4SLinus Torvalds 
9821da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
9831da177e4SLinus Torvalds 		return -EINVAL;
9841da177e4SLinus Torvalds 
9851da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
9861da177e4SLinus Torvalds 
98770f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
98870f23020SAndrei Emeltchenko 	if (!dl)
9891da177e4SLinus Torvalds 		return -ENOMEM;
9901da177e4SLinus Torvalds 
9911da177e4SLinus Torvalds 	dr = dl->dev_req;
9921da177e4SLinus Torvalds 
993f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
9948035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
995a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
996e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
997c542a06cSJohan Hedberg 
998a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
999a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1000c542a06cSJohan Hedberg 
10011da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
10021da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
1003c542a06cSJohan Hedberg 
10041da177e4SLinus Torvalds 		if (++n >= dev_num)
10051da177e4SLinus Torvalds 			break;
10061da177e4SLinus Torvalds 	}
1007f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
10081da177e4SLinus Torvalds 
10091da177e4SLinus Torvalds 	dl->dev_num = n;
10101da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
10111da177e4SLinus Torvalds 
10121da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
10131da177e4SLinus Torvalds 	kfree(dl);
10141da177e4SLinus Torvalds 
10151da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
10161da177e4SLinus Torvalds }
10171da177e4SLinus Torvalds 
10181da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
10191da177e4SLinus Torvalds {
10201da177e4SLinus Torvalds 	struct hci_dev *hdev;
10211da177e4SLinus Torvalds 	struct hci_dev_info di;
10221da177e4SLinus Torvalds 	int err = 0;
10231da177e4SLinus Torvalds 
10241da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
10251da177e4SLinus Torvalds 		return -EFAULT;
10261da177e4SLinus Torvalds 
102770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
102870f23020SAndrei Emeltchenko 	if (!hdev)
10291da177e4SLinus Torvalds 		return -ENODEV;
10301da177e4SLinus Torvalds 
1031a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
10323243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1033ab81cbf9SJohan Hedberg 
1034a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1035a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1036c542a06cSJohan Hedberg 
10371da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
10381da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
1039943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
10401da177e4SLinus Torvalds 	di.flags    = hdev->flags;
10411da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
10421da177e4SLinus Torvalds 	di.acl_mtu  = hdev->acl_mtu;
10431da177e4SLinus Torvalds 	di.acl_pkts = hdev->acl_pkts;
10441da177e4SLinus Torvalds 	di.sco_mtu  = hdev->sco_mtu;
10451da177e4SLinus Torvalds 	di.sco_pkts = hdev->sco_pkts;
10461da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
10471da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
10481da177e4SLinus Torvalds 
10491da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
10501da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
10511da177e4SLinus Torvalds 
10521da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
10531da177e4SLinus Torvalds 		err = -EFAULT;
10541da177e4SLinus Torvalds 
10551da177e4SLinus Torvalds 	hci_dev_put(hdev);
10561da177e4SLinus Torvalds 
10571da177e4SLinus Torvalds 	return err;
10581da177e4SLinus Torvalds }
10591da177e4SLinus Torvalds 
10601da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
10611da177e4SLinus Torvalds 
1062611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1063611b30f7SMarcel Holtmann {
1064611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1065611b30f7SMarcel Holtmann 
1066611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1067611b30f7SMarcel Holtmann 
1068611b30f7SMarcel Holtmann 	if (!blocked)
1069611b30f7SMarcel Holtmann 		return 0;
1070611b30f7SMarcel Holtmann 
1071611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1072611b30f7SMarcel Holtmann 
1073611b30f7SMarcel Holtmann 	return 0;
1074611b30f7SMarcel Holtmann }
1075611b30f7SMarcel Holtmann 
1076611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1077611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1078611b30f7SMarcel Holtmann };
1079611b30f7SMarcel Holtmann 
1080ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1081ab81cbf9SJohan Hedberg {
1082ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
1083ab81cbf9SJohan Hedberg 
1084ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1085ab81cbf9SJohan Hedberg 
1086ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
1087ab81cbf9SJohan Hedberg 		return;
1088ab81cbf9SJohan Hedberg 
1089a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
109080b7ab33SGustavo F. Padovan 		schedule_delayed_work(&hdev->power_off,
10913243553fSJohan Hedberg 				      msecs_to_jiffies(AUTO_OFF_TIMEOUT));
1092ab81cbf9SJohan Hedberg 
1093a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1094744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1095ab81cbf9SJohan Hedberg }
1096ab81cbf9SJohan Hedberg 
1097ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1098ab81cbf9SJohan Hedberg {
10993243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
11003243553fSJohan Hedberg 					    power_off.work);
1101ab81cbf9SJohan Hedberg 
1102ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1103ab81cbf9SJohan Hedberg 
11048ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1105ab81cbf9SJohan Hedberg }
1106ab81cbf9SJohan Hedberg 
110716ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
110816ab91abSJohan Hedberg {
110916ab91abSJohan Hedberg 	struct hci_dev *hdev;
111016ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
111116ab91abSJohan Hedberg 
111216ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
111316ab91abSJohan Hedberg 
111416ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
111516ab91abSJohan Hedberg 
111609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
111716ab91abSJohan Hedberg 
111816ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
111916ab91abSJohan Hedberg 
112016ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
112116ab91abSJohan Hedberg 
112209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
112316ab91abSJohan Hedberg }
112416ab91abSJohan Hedberg 
11252aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
11262aeb9a1aSJohan Hedberg {
11272aeb9a1aSJohan Hedberg 	struct list_head *p, *n;
11282aeb9a1aSJohan Hedberg 
11292aeb9a1aSJohan Hedberg 	list_for_each_safe(p, n, &hdev->uuids) {
11302aeb9a1aSJohan Hedberg 		struct bt_uuid *uuid;
11312aeb9a1aSJohan Hedberg 
11322aeb9a1aSJohan Hedberg 		uuid = list_entry(p, struct bt_uuid, list);
11332aeb9a1aSJohan Hedberg 
11342aeb9a1aSJohan Hedberg 		list_del(p);
11352aeb9a1aSJohan Hedberg 		kfree(uuid);
11362aeb9a1aSJohan Hedberg 	}
11372aeb9a1aSJohan Hedberg 
11382aeb9a1aSJohan Hedberg 	return 0;
11392aeb9a1aSJohan Hedberg }
11402aeb9a1aSJohan Hedberg 
114155ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
114255ed8ca1SJohan Hedberg {
114355ed8ca1SJohan Hedberg 	struct list_head *p, *n;
114455ed8ca1SJohan Hedberg 
114555ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
114655ed8ca1SJohan Hedberg 		struct link_key *key;
114755ed8ca1SJohan Hedberg 
114855ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
114955ed8ca1SJohan Hedberg 
115055ed8ca1SJohan Hedberg 		list_del(p);
115155ed8ca1SJohan Hedberg 		kfree(key);
115255ed8ca1SJohan Hedberg 	}
115355ed8ca1SJohan Hedberg 
115455ed8ca1SJohan Hedberg 	return 0;
115555ed8ca1SJohan Hedberg }
115655ed8ca1SJohan Hedberg 
1157b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1158b899efafSVinicius Costa Gomes {
1159b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1160b899efafSVinicius Costa Gomes 
1161b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1162b899efafSVinicius Costa Gomes 		list_del(&k->list);
1163b899efafSVinicius Costa Gomes 		kfree(k);
1164b899efafSVinicius Costa Gomes 	}
1165b899efafSVinicius Costa Gomes 
1166b899efafSVinicius Costa Gomes 	return 0;
1167b899efafSVinicius Costa Gomes }
1168b899efafSVinicius Costa Gomes 
116955ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
117055ed8ca1SJohan Hedberg {
117155ed8ca1SJohan Hedberg 	struct link_key *k;
117255ed8ca1SJohan Hedberg 
11738035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
117455ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
117555ed8ca1SJohan Hedberg 			return k;
117655ed8ca1SJohan Hedberg 
117755ed8ca1SJohan Hedberg 	return NULL;
117855ed8ca1SJohan Hedberg }
117955ed8ca1SJohan Hedberg 
1180745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1181d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
1182d25e28abSJohan Hedberg {
1183d25e28abSJohan Hedberg 	/* Legacy key */
1184d25e28abSJohan Hedberg 	if (key_type < 0x03)
1185745c0ce3SVishal Agarwal 		return true;
1186d25e28abSJohan Hedberg 
1187d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1188d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1189745c0ce3SVishal Agarwal 		return false;
1190d25e28abSJohan Hedberg 
1191d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1192d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1193745c0ce3SVishal Agarwal 		return false;
1194d25e28abSJohan Hedberg 
1195d25e28abSJohan Hedberg 	/* Security mode 3 case */
1196d25e28abSJohan Hedberg 	if (!conn)
1197745c0ce3SVishal Agarwal 		return true;
1198d25e28abSJohan Hedberg 
1199d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1200d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1201745c0ce3SVishal Agarwal 		return true;
1202d25e28abSJohan Hedberg 
1203d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1204d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1205745c0ce3SVishal Agarwal 		return true;
1206d25e28abSJohan Hedberg 
1207d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1208d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1209745c0ce3SVishal Agarwal 		return true;
1210d25e28abSJohan Hedberg 
1211d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1212d25e28abSJohan Hedberg 	 * persistently */
1213745c0ce3SVishal Agarwal 	return false;
1214d25e28abSJohan Hedberg }
1215d25e28abSJohan Hedberg 
1216c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
121775d262c2SVinicius Costa Gomes {
1218c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
121975d262c2SVinicius Costa Gomes 
1220c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1221c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1222c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
122375d262c2SVinicius Costa Gomes 			continue;
122475d262c2SVinicius Costa Gomes 
122575d262c2SVinicius Costa Gomes 		return k;
122675d262c2SVinicius Costa Gomes 	}
122775d262c2SVinicius Costa Gomes 
122875d262c2SVinicius Costa Gomes 	return NULL;
122975d262c2SVinicius Costa Gomes }
123075d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk);
123175d262c2SVinicius Costa Gomes 
1232c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1233c9839a11SVinicius Costa Gomes 				     u8 addr_type)
123475d262c2SVinicius Costa Gomes {
1235c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
123675d262c2SVinicius Costa Gomes 
1237c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1238c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1239c9839a11SVinicius Costa Gomes 		    bacmp(bdaddr, &k->bdaddr) == 0)
124075d262c2SVinicius Costa Gomes 			return k;
124175d262c2SVinicius Costa Gomes 
124275d262c2SVinicius Costa Gomes 	return NULL;
124375d262c2SVinicius Costa Gomes }
1244c9839a11SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk_by_addr);
124575d262c2SVinicius Costa Gomes 
1246d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1247d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
124855ed8ca1SJohan Hedberg {
124955ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1250745c0ce3SVishal Agarwal 	u8 old_key_type;
1251745c0ce3SVishal Agarwal 	bool persistent;
125255ed8ca1SJohan Hedberg 
125355ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
125455ed8ca1SJohan Hedberg 	if (old_key) {
125555ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
125655ed8ca1SJohan Hedberg 		key = old_key;
125755ed8ca1SJohan Hedberg 	} else {
125812adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
125955ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
126055ed8ca1SJohan Hedberg 		if (!key)
126155ed8ca1SJohan Hedberg 			return -ENOMEM;
126255ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
126355ed8ca1SJohan Hedberg 	}
126455ed8ca1SJohan Hedberg 
126555ed8ca1SJohan Hedberg 	BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
126655ed8ca1SJohan Hedberg 
1267d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1268d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1269d25e28abSJohan Hedberg 	 * previous key */
1270d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1271a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1272d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1273655fe6ecSJohan Hedberg 		if (conn)
1274655fe6ecSJohan Hedberg 			conn->key_type = type;
1275655fe6ecSJohan Hedberg 	}
1276d25e28abSJohan Hedberg 
127755ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
12789b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
127955ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
128055ed8ca1SJohan Hedberg 
1281b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
128255ed8ca1SJohan Hedberg 		key->type = old_key_type;
12834748fed2SJohan Hedberg 	else
12844748fed2SJohan Hedberg 		key->type = type;
12854748fed2SJohan Hedberg 
12864df378a1SJohan Hedberg 	if (!new_key)
12874df378a1SJohan Hedberg 		return 0;
12884df378a1SJohan Hedberg 
12894df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
12904df378a1SJohan Hedberg 
1291744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
12924df378a1SJohan Hedberg 
12936ec5bcadSVishal Agarwal 	if (conn)
12946ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
129555ed8ca1SJohan Hedberg 
129655ed8ca1SJohan Hedberg 	return 0;
129755ed8ca1SJohan Hedberg }
129855ed8ca1SJohan Hedberg 
1299c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
13009a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
130104124681SGustavo F. Padovan 		ediv, u8 rand[8])
130275d262c2SVinicius Costa Gomes {
1303c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
130475d262c2SVinicius Costa Gomes 
1305c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1306c9839a11SVinicius Costa Gomes 		return 0;
130775d262c2SVinicius Costa Gomes 
1308c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1309c9839a11SVinicius Costa Gomes 	if (old_key)
131075d262c2SVinicius Costa Gomes 		key = old_key;
1311c9839a11SVinicius Costa Gomes 	else {
1312c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
131375d262c2SVinicius Costa Gomes 		if (!key)
131475d262c2SVinicius Costa Gomes 			return -ENOMEM;
1315c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
131675d262c2SVinicius Costa Gomes 	}
131775d262c2SVinicius Costa Gomes 
131875d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1319c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1320c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1321c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1322c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1323c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1324c9839a11SVinicius Costa Gomes 	key->type = type;
1325c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
132675d262c2SVinicius Costa Gomes 
1327c9839a11SVinicius Costa Gomes 	if (!new_key)
1328c9839a11SVinicius Costa Gomes 		return 0;
132975d262c2SVinicius Costa Gomes 
1330261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1331261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1332261cc5aaSVinicius Costa Gomes 
133375d262c2SVinicius Costa Gomes 	return 0;
133475d262c2SVinicius Costa Gomes }
133575d262c2SVinicius Costa Gomes 
133655ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
133755ed8ca1SJohan Hedberg {
133855ed8ca1SJohan Hedberg 	struct link_key *key;
133955ed8ca1SJohan Hedberg 
134055ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
134155ed8ca1SJohan Hedberg 	if (!key)
134255ed8ca1SJohan Hedberg 		return -ENOENT;
134355ed8ca1SJohan Hedberg 
134455ed8ca1SJohan Hedberg 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
134555ed8ca1SJohan Hedberg 
134655ed8ca1SJohan Hedberg 	list_del(&key->list);
134755ed8ca1SJohan Hedberg 	kfree(key);
134855ed8ca1SJohan Hedberg 
134955ed8ca1SJohan Hedberg 	return 0;
135055ed8ca1SJohan Hedberg }
135155ed8ca1SJohan Hedberg 
1352b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1353b899efafSVinicius Costa Gomes {
1354b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1355b899efafSVinicius Costa Gomes 
1356b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1357b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1358b899efafSVinicius Costa Gomes 			continue;
1359b899efafSVinicius Costa Gomes 
1360b899efafSVinicius Costa Gomes 		BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
1361b899efafSVinicius Costa Gomes 
1362b899efafSVinicius Costa Gomes 		list_del(&k->list);
1363b899efafSVinicius Costa Gomes 		kfree(k);
1364b899efafSVinicius Costa Gomes 	}
1365b899efafSVinicius Costa Gomes 
1366b899efafSVinicius Costa Gomes 	return 0;
1367b899efafSVinicius Costa Gomes }
1368b899efafSVinicius Costa Gomes 
13696bd32326SVille Tervo /* HCI command timer function */
13706bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg)
13716bd32326SVille Tervo {
13726bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
13736bd32326SVille Tervo 
13746bd32326SVille Tervo 	BT_ERR("%s command tx timeout", hdev->name);
13756bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1376c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
13776bd32326SVille Tervo }
13786bd32326SVille Tervo 
13792763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
13802763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
13812763eda6SSzymon Janc {
13822763eda6SSzymon Janc 	struct oob_data *data;
13832763eda6SSzymon Janc 
13842763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
13852763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
13862763eda6SSzymon Janc 			return data;
13872763eda6SSzymon Janc 
13882763eda6SSzymon Janc 	return NULL;
13892763eda6SSzymon Janc }
13902763eda6SSzymon Janc 
13912763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
13922763eda6SSzymon Janc {
13932763eda6SSzymon Janc 	struct oob_data *data;
13942763eda6SSzymon Janc 
13952763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
13962763eda6SSzymon Janc 	if (!data)
13972763eda6SSzymon Janc 		return -ENOENT;
13982763eda6SSzymon Janc 
13992763eda6SSzymon Janc 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
14002763eda6SSzymon Janc 
14012763eda6SSzymon Janc 	list_del(&data->list);
14022763eda6SSzymon Janc 	kfree(data);
14032763eda6SSzymon Janc 
14042763eda6SSzymon Janc 	return 0;
14052763eda6SSzymon Janc }
14062763eda6SSzymon Janc 
14072763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
14082763eda6SSzymon Janc {
14092763eda6SSzymon Janc 	struct oob_data *data, *n;
14102763eda6SSzymon Janc 
14112763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
14122763eda6SSzymon Janc 		list_del(&data->list);
14132763eda6SSzymon Janc 		kfree(data);
14142763eda6SSzymon Janc 	}
14152763eda6SSzymon Janc 
14162763eda6SSzymon Janc 	return 0;
14172763eda6SSzymon Janc }
14182763eda6SSzymon Janc 
14192763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
14202763eda6SSzymon Janc 			    u8 *randomizer)
14212763eda6SSzymon Janc {
14222763eda6SSzymon Janc 	struct oob_data *data;
14232763eda6SSzymon Janc 
14242763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
14252763eda6SSzymon Janc 
14262763eda6SSzymon Janc 	if (!data) {
14272763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
14282763eda6SSzymon Janc 		if (!data)
14292763eda6SSzymon Janc 			return -ENOMEM;
14302763eda6SSzymon Janc 
14312763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
14322763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
14332763eda6SSzymon Janc 	}
14342763eda6SSzymon Janc 
14352763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
14362763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
14372763eda6SSzymon Janc 
14382763eda6SSzymon Janc 	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
14392763eda6SSzymon Janc 
14402763eda6SSzymon Janc 	return 0;
14412763eda6SSzymon Janc }
14422763eda6SSzymon Janc 
144304124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
1444b2a66aadSAntti Julku {
1445b2a66aadSAntti Julku 	struct bdaddr_list *b;
1446b2a66aadSAntti Julku 
14478035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1448b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1449b2a66aadSAntti Julku 			return b;
1450b2a66aadSAntti Julku 
1451b2a66aadSAntti Julku 	return NULL;
1452b2a66aadSAntti Julku }
1453b2a66aadSAntti Julku 
1454b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1455b2a66aadSAntti Julku {
1456b2a66aadSAntti Julku 	struct list_head *p, *n;
1457b2a66aadSAntti Julku 
1458b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1459b2a66aadSAntti Julku 		struct bdaddr_list *b;
1460b2a66aadSAntti Julku 
1461b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1462b2a66aadSAntti Julku 
1463b2a66aadSAntti Julku 		list_del(p);
1464b2a66aadSAntti Julku 		kfree(b);
1465b2a66aadSAntti Julku 	}
1466b2a66aadSAntti Julku 
1467b2a66aadSAntti Julku 	return 0;
1468b2a66aadSAntti Julku }
1469b2a66aadSAntti Julku 
147088c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1471b2a66aadSAntti Julku {
1472b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1473b2a66aadSAntti Julku 
1474b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1475b2a66aadSAntti Julku 		return -EBADF;
1476b2a66aadSAntti Julku 
14775e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
14785e762444SAntti Julku 		return -EEXIST;
1479b2a66aadSAntti Julku 
1480b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
14815e762444SAntti Julku 	if (!entry)
14825e762444SAntti Julku 		return -ENOMEM;
1483b2a66aadSAntti Julku 
1484b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1485b2a66aadSAntti Julku 
1486b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1487b2a66aadSAntti Julku 
148888c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
1489b2a66aadSAntti Julku }
1490b2a66aadSAntti Julku 
149188c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1492b2a66aadSAntti Julku {
1493b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1494b2a66aadSAntti Julku 
14951ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
14965e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1497b2a66aadSAntti Julku 
1498b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
14991ec918ceSSzymon Janc 	if (!entry)
15005e762444SAntti Julku 		return -ENOENT;
1501b2a66aadSAntti Julku 
1502b2a66aadSAntti Julku 	list_del(&entry->list);
1503b2a66aadSAntti Julku 	kfree(entry);
1504b2a66aadSAntti Julku 
150588c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
1506b2a66aadSAntti Julku }
1507b2a66aadSAntti Julku 
15087ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt)
15097ba8b4beSAndre Guedes {
15107ba8b4beSAndre Guedes 	struct le_scan_params *param =  (struct le_scan_params *) opt;
15117ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_param cp;
15127ba8b4beSAndre Guedes 
15137ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
15147ba8b4beSAndre Guedes 	cp.type = param->type;
15157ba8b4beSAndre Guedes 	cp.interval = cpu_to_le16(param->interval);
15167ba8b4beSAndre Guedes 	cp.window = cpu_to_le16(param->window);
15177ba8b4beSAndre Guedes 
15187ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
15197ba8b4beSAndre Guedes }
15207ba8b4beSAndre Guedes 
15217ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt)
15227ba8b4beSAndre Guedes {
15237ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
15247ba8b4beSAndre Guedes 
15257ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
15267ba8b4beSAndre Guedes 	cp.enable = 1;
15277ba8b4beSAndre Guedes 
15287ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
15297ba8b4beSAndre Guedes }
15307ba8b4beSAndre Guedes 
15317ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
15327ba8b4beSAndre Guedes 			  u16 window, int timeout)
15337ba8b4beSAndre Guedes {
15347ba8b4beSAndre Guedes 	long timeo = msecs_to_jiffies(3000);
15357ba8b4beSAndre Guedes 	struct le_scan_params param;
15367ba8b4beSAndre Guedes 	int err;
15377ba8b4beSAndre Guedes 
15387ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
15397ba8b4beSAndre Guedes 
15407ba8b4beSAndre Guedes 	if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
15417ba8b4beSAndre Guedes 		return -EINPROGRESS;
15427ba8b4beSAndre Guedes 
15437ba8b4beSAndre Guedes 	param.type = type;
15447ba8b4beSAndre Guedes 	param.interval = interval;
15457ba8b4beSAndre Guedes 	param.window = window;
15467ba8b4beSAndre Guedes 
15477ba8b4beSAndre Guedes 	hci_req_lock(hdev);
15487ba8b4beSAndre Guedes 
15497ba8b4beSAndre Guedes 	err = __hci_request(hdev, le_scan_param_req, (unsigned long) &param,
15507ba8b4beSAndre Guedes 			    timeo);
15517ba8b4beSAndre Guedes 	if (!err)
15527ba8b4beSAndre Guedes 		err = __hci_request(hdev, le_scan_enable_req, 0, timeo);
15537ba8b4beSAndre Guedes 
15547ba8b4beSAndre Guedes 	hci_req_unlock(hdev);
15557ba8b4beSAndre Guedes 
15567ba8b4beSAndre Guedes 	if (err < 0)
15577ba8b4beSAndre Guedes 		return err;
15587ba8b4beSAndre Guedes 
15597ba8b4beSAndre Guedes 	schedule_delayed_work(&hdev->le_scan_disable,
15607ba8b4beSAndre Guedes 			      msecs_to_jiffies(timeout));
15617ba8b4beSAndre Guedes 
15627ba8b4beSAndre Guedes 	return 0;
15637ba8b4beSAndre Guedes }
15647ba8b4beSAndre Guedes 
15657dbfac1dSAndre Guedes int hci_cancel_le_scan(struct hci_dev *hdev)
15667dbfac1dSAndre Guedes {
15677dbfac1dSAndre Guedes 	BT_DBG("%s", hdev->name);
15687dbfac1dSAndre Guedes 
15697dbfac1dSAndre Guedes 	if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
15707dbfac1dSAndre Guedes 		return -EALREADY;
15717dbfac1dSAndre Guedes 
15727dbfac1dSAndre Guedes 	if (cancel_delayed_work(&hdev->le_scan_disable)) {
15737dbfac1dSAndre Guedes 		struct hci_cp_le_set_scan_enable cp;
15747dbfac1dSAndre Guedes 
15757dbfac1dSAndre Guedes 		/* Send HCI command to disable LE Scan */
15767dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
15777dbfac1dSAndre Guedes 		hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
15787dbfac1dSAndre Guedes 	}
15797dbfac1dSAndre Guedes 
15807dbfac1dSAndre Guedes 	return 0;
15817dbfac1dSAndre Guedes }
15827dbfac1dSAndre Guedes 
15837ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
15847ba8b4beSAndre Guedes {
15857ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
15867ba8b4beSAndre Guedes 					    le_scan_disable.work);
15877ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
15887ba8b4beSAndre Guedes 
15897ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
15907ba8b4beSAndre Guedes 
15917ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
15927ba8b4beSAndre Guedes 
15937ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
15947ba8b4beSAndre Guedes }
15957ba8b4beSAndre Guedes 
159628b75a89SAndre Guedes static void le_scan_work(struct work_struct *work)
159728b75a89SAndre Guedes {
159828b75a89SAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
159928b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
160028b75a89SAndre Guedes 
160128b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
160228b75a89SAndre Guedes 
160304124681SGustavo F. Padovan 	hci_do_le_scan(hdev, param->type, param->interval, param->window,
160404124681SGustavo F. Padovan 		       param->timeout);
160528b75a89SAndre Guedes }
160628b75a89SAndre Guedes 
160728b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
160828b75a89SAndre Guedes 		int timeout)
160928b75a89SAndre Guedes {
161028b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
161128b75a89SAndre Guedes 
161228b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
161328b75a89SAndre Guedes 
161428b75a89SAndre Guedes 	if (work_busy(&hdev->le_scan))
161528b75a89SAndre Guedes 		return -EINPROGRESS;
161628b75a89SAndre Guedes 
161728b75a89SAndre Guedes 	param->type = type;
161828b75a89SAndre Guedes 	param->interval = interval;
161928b75a89SAndre Guedes 	param->window = window;
162028b75a89SAndre Guedes 	param->timeout = timeout;
162128b75a89SAndre Guedes 
162228b75a89SAndre Guedes 	queue_work(system_long_wq, &hdev->le_scan);
162328b75a89SAndre Guedes 
162428b75a89SAndre Guedes 	return 0;
162528b75a89SAndre Guedes }
162628b75a89SAndre Guedes 
16279be0dab7SDavid Herrmann /* Alloc HCI device */
16289be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
16299be0dab7SDavid Herrmann {
16309be0dab7SDavid Herrmann 	struct hci_dev *hdev;
16319be0dab7SDavid Herrmann 
16329be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
16339be0dab7SDavid Herrmann 	if (!hdev)
16349be0dab7SDavid Herrmann 		return NULL;
16359be0dab7SDavid Herrmann 
1636b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
1637b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
1638b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
1639b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03; /* No Input No Output */
1640b1b813d4SDavid Herrmann 
1641b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
1642b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
1643b1b813d4SDavid Herrmann 
1644b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
1645b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
1646b1b813d4SDavid Herrmann 
1647b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
1648b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
1649b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
1650b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
1651b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
1652b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
1653b1b813d4SDavid Herrmann 
1654b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1655b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
1656b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
1657b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
1658b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->le_scan, le_scan_work);
1659b1b813d4SDavid Herrmann 
1660b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
1661b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
1662b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
1663b1b813d4SDavid Herrmann 
16649be0dab7SDavid Herrmann 	skb_queue_head_init(&hdev->driver_init);
1665b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
1666b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
1667b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
1668b1b813d4SDavid Herrmann 
1669b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
1670b1b813d4SDavid Herrmann 
1671b1b813d4SDavid Herrmann 	setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);
1672b1b813d4SDavid Herrmann 
1673b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
1674b1b813d4SDavid Herrmann 	discovery_init(hdev);
1675b1b813d4SDavid Herrmann 	hci_conn_hash_init(hdev);
16769be0dab7SDavid Herrmann 
16779be0dab7SDavid Herrmann 	return hdev;
16789be0dab7SDavid Herrmann }
16799be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
16809be0dab7SDavid Herrmann 
16819be0dab7SDavid Herrmann /* Free HCI device */
16829be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
16839be0dab7SDavid Herrmann {
16849be0dab7SDavid Herrmann 	skb_queue_purge(&hdev->driver_init);
16859be0dab7SDavid Herrmann 
16869be0dab7SDavid Herrmann 	/* will free via device release */
16879be0dab7SDavid Herrmann 	put_device(&hdev->dev);
16889be0dab7SDavid Herrmann }
16899be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
16909be0dab7SDavid Herrmann 
16911da177e4SLinus Torvalds /* Register HCI device */
16921da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
16931da177e4SLinus Torvalds {
1694fc50744cSUlisses Furquim 	struct list_head *head, *p;
1695b1b813d4SDavid Herrmann 	int id, error;
16961da177e4SLinus Torvalds 
1697010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
16981da177e4SLinus Torvalds 		return -EINVAL;
16991da177e4SLinus Torvalds 
1700fc50744cSUlisses Furquim 	write_lock(&hci_dev_list_lock);
1701fc50744cSUlisses Furquim 
170208add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
170308add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
170408add513SMat Martineau 	 */
170508add513SMat Martineau 	id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
1706fc50744cSUlisses Furquim 	head = &hci_dev_list;
17071da177e4SLinus Torvalds 
17081da177e4SLinus Torvalds 	/* Find first available device id */
17091da177e4SLinus Torvalds 	list_for_each(p, &hci_dev_list) {
1710fc50744cSUlisses Furquim 		int nid = list_entry(p, struct hci_dev, list)->id;
1711fc50744cSUlisses Furquim 		if (nid > id)
17121da177e4SLinus Torvalds 			break;
1713fc50744cSUlisses Furquim 		if (nid == id)
1714fc50744cSUlisses Furquim 			id++;
1715fc50744cSUlisses Furquim 		head = p;
17161da177e4SLinus Torvalds 	}
17171da177e4SLinus Torvalds 
17181da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
17191da177e4SLinus Torvalds 	hdev->id = id;
17202d8b3a11SAndrei Emeltchenko 
17212d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
17222d8b3a11SAndrei Emeltchenko 
1723fc50744cSUlisses Furquim 	list_add(&hdev->list, head);
17241da177e4SLinus Torvalds 
1725f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
17261da177e4SLinus Torvalds 
172732845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
172832845eb1SGustavo F. Padovan 					  WQ_MEM_RECLAIM, 1);
172933ca954dSDavid Herrmann 	if (!hdev->workqueue) {
173033ca954dSDavid Herrmann 		error = -ENOMEM;
173133ca954dSDavid Herrmann 		goto err;
173233ca954dSDavid Herrmann 	}
1733f48fd9c8SMarcel Holtmann 
173433ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
173533ca954dSDavid Herrmann 	if (error < 0)
173633ca954dSDavid Herrmann 		goto err_wqueue;
17371da177e4SLinus Torvalds 
1738611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1739a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
1740a8c5fb1aSGustavo Padovan 				    hdev);
1741611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1742611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
1743611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
1744611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
1745611b30f7SMarcel Holtmann 		}
1746611b30f7SMarcel Holtmann 	}
1747611b30f7SMarcel Holtmann 
1748a8b2d5c2SJohan Hedberg 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
1749a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
17507f971041SGustavo F. Padovan 	schedule_work(&hdev->power_on);
1751ab81cbf9SJohan Hedberg 
17521da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
1753dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
17541da177e4SLinus Torvalds 
17551da177e4SLinus Torvalds 	return id;
1756f48fd9c8SMarcel Holtmann 
175733ca954dSDavid Herrmann err_wqueue:
175833ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
175933ca954dSDavid Herrmann err:
1760f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
1761f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
1762f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
1763f48fd9c8SMarcel Holtmann 
176433ca954dSDavid Herrmann 	return error;
17651da177e4SLinus Torvalds }
17661da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
17671da177e4SLinus Torvalds 
17681da177e4SLinus Torvalds /* Unregister HCI device */
176959735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
17701da177e4SLinus Torvalds {
1771ef222013SMarcel Holtmann 	int i;
1772ef222013SMarcel Holtmann 
1773c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
17741da177e4SLinus Torvalds 
177594324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
177694324962SJohan Hovold 
1777f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
17781da177e4SLinus Torvalds 	list_del(&hdev->list);
1779f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
17801da177e4SLinus Torvalds 
17811da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
17821da177e4SLinus Torvalds 
1783cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1784ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
1785ef222013SMarcel Holtmann 
1786ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
1787a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
178809fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1789744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
179009fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
179156e5cb86SJohan Hedberg 	}
1792ab81cbf9SJohan Hedberg 
17932e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
17942e58ef3eSJohan Hedberg 	 * pending list */
17952e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
17962e58ef3eSJohan Hedberg 
17971da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
17981da177e4SLinus Torvalds 
1799611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1800611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
1801611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
1802611b30f7SMarcel Holtmann 	}
1803611b30f7SMarcel Holtmann 
1804ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
1805147e2d59SDave Young 
1806f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
1807f48fd9c8SMarcel Holtmann 
180809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
1809e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
18102aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
181155ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
1812b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
18132763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
181409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
1815e2e0cacbSJohan Hedberg 
1816dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
18171da177e4SLinus Torvalds }
18181da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
18191da177e4SLinus Torvalds 
18201da177e4SLinus Torvalds /* Suspend HCI device */
18211da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
18221da177e4SLinus Torvalds {
18231da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
18241da177e4SLinus Torvalds 	return 0;
18251da177e4SLinus Torvalds }
18261da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
18271da177e4SLinus Torvalds 
18281da177e4SLinus Torvalds /* Resume HCI device */
18291da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
18301da177e4SLinus Torvalds {
18311da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
18321da177e4SLinus Torvalds 	return 0;
18331da177e4SLinus Torvalds }
18341da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
18351da177e4SLinus Torvalds 
183676bca880SMarcel Holtmann /* Receive frame from HCI drivers */
183776bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
183876bca880SMarcel Holtmann {
183976bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
184076bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
184176bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
184276bca880SMarcel Holtmann 		kfree_skb(skb);
184376bca880SMarcel Holtmann 		return -ENXIO;
184476bca880SMarcel Holtmann 	}
184576bca880SMarcel Holtmann 
184676bca880SMarcel Holtmann 	/* Incomming skb */
184776bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
184876bca880SMarcel Holtmann 
184976bca880SMarcel Holtmann 	/* Time stamp */
185076bca880SMarcel Holtmann 	__net_timestamp(skb);
185176bca880SMarcel Holtmann 
185276bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
1853b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
1854c78ae283SMarcel Holtmann 
185576bca880SMarcel Holtmann 	return 0;
185676bca880SMarcel Holtmann }
185776bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
185876bca880SMarcel Holtmann 
185933e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
18601e429f38SGustavo F. Padovan 			  int count, __u8 index)
186133e882a5SSuraj Sumangala {
186233e882a5SSuraj Sumangala 	int len = 0;
186333e882a5SSuraj Sumangala 	int hlen = 0;
186433e882a5SSuraj Sumangala 	int remain = count;
186533e882a5SSuraj Sumangala 	struct sk_buff *skb;
186633e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
186733e882a5SSuraj Sumangala 
186833e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
186933e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
187033e882a5SSuraj Sumangala 		return -EILSEQ;
187133e882a5SSuraj Sumangala 
187233e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
187333e882a5SSuraj Sumangala 
187433e882a5SSuraj Sumangala 	if (!skb) {
187533e882a5SSuraj Sumangala 		switch (type) {
187633e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
187733e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
187833e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
187933e882a5SSuraj Sumangala 			break;
188033e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
188133e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
188233e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
188333e882a5SSuraj Sumangala 			break;
188433e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
188533e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
188633e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
188733e882a5SSuraj Sumangala 			break;
188833e882a5SSuraj Sumangala 		}
188933e882a5SSuraj Sumangala 
18901e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
189133e882a5SSuraj Sumangala 		if (!skb)
189233e882a5SSuraj Sumangala 			return -ENOMEM;
189333e882a5SSuraj Sumangala 
189433e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
189533e882a5SSuraj Sumangala 		scb->expect = hlen;
189633e882a5SSuraj Sumangala 		scb->pkt_type = type;
189733e882a5SSuraj Sumangala 
189833e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
189933e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
190033e882a5SSuraj Sumangala 	}
190133e882a5SSuraj Sumangala 
190233e882a5SSuraj Sumangala 	while (count) {
190333e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
190489bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
190533e882a5SSuraj Sumangala 
190633e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
190733e882a5SSuraj Sumangala 
190833e882a5SSuraj Sumangala 		count -= len;
190933e882a5SSuraj Sumangala 		data += len;
191033e882a5SSuraj Sumangala 		scb->expect -= len;
191133e882a5SSuraj Sumangala 		remain = count;
191233e882a5SSuraj Sumangala 
191333e882a5SSuraj Sumangala 		switch (type) {
191433e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
191533e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
191633e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
191733e882a5SSuraj Sumangala 				scb->expect = h->plen;
191833e882a5SSuraj Sumangala 
191933e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
192033e882a5SSuraj Sumangala 					kfree_skb(skb);
192133e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
192233e882a5SSuraj Sumangala 					return -ENOMEM;
192333e882a5SSuraj Sumangala 				}
192433e882a5SSuraj Sumangala 			}
192533e882a5SSuraj Sumangala 			break;
192633e882a5SSuraj Sumangala 
192733e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
192833e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
192933e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
193033e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
193133e882a5SSuraj Sumangala 
193233e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
193333e882a5SSuraj Sumangala 					kfree_skb(skb);
193433e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
193533e882a5SSuraj Sumangala 					return -ENOMEM;
193633e882a5SSuraj Sumangala 				}
193733e882a5SSuraj Sumangala 			}
193833e882a5SSuraj Sumangala 			break;
193933e882a5SSuraj Sumangala 
194033e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
194133e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
194233e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
194333e882a5SSuraj Sumangala 				scb->expect = h->dlen;
194433e882a5SSuraj Sumangala 
194533e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
194633e882a5SSuraj Sumangala 					kfree_skb(skb);
194733e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
194833e882a5SSuraj Sumangala 					return -ENOMEM;
194933e882a5SSuraj Sumangala 				}
195033e882a5SSuraj Sumangala 			}
195133e882a5SSuraj Sumangala 			break;
195233e882a5SSuraj Sumangala 		}
195333e882a5SSuraj Sumangala 
195433e882a5SSuraj Sumangala 		if (scb->expect == 0) {
195533e882a5SSuraj Sumangala 			/* Complete frame */
195633e882a5SSuraj Sumangala 
195733e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
195833e882a5SSuraj Sumangala 			hci_recv_frame(skb);
195933e882a5SSuraj Sumangala 
196033e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
196133e882a5SSuraj Sumangala 			return remain;
196233e882a5SSuraj Sumangala 		}
196333e882a5SSuraj Sumangala 	}
196433e882a5SSuraj Sumangala 
196533e882a5SSuraj Sumangala 	return remain;
196633e882a5SSuraj Sumangala }
196733e882a5SSuraj Sumangala 
1968ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
1969ef222013SMarcel Holtmann {
1970f39a3c06SSuraj Sumangala 	int rem = 0;
1971f39a3c06SSuraj Sumangala 
1972ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
1973ef222013SMarcel Holtmann 		return -EILSEQ;
1974ef222013SMarcel Holtmann 
1975da5f6c37SGustavo F. Padovan 	while (count) {
19761e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
1977f39a3c06SSuraj Sumangala 		if (rem < 0)
1978f39a3c06SSuraj Sumangala 			return rem;
1979ef222013SMarcel Holtmann 
1980f39a3c06SSuraj Sumangala 		data += (count - rem);
1981f39a3c06SSuraj Sumangala 		count = rem;
1982f81c6224SJoe Perches 	}
1983ef222013SMarcel Holtmann 
1984f39a3c06SSuraj Sumangala 	return rem;
1985ef222013SMarcel Holtmann }
1986ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
1987ef222013SMarcel Holtmann 
198899811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
198999811510SSuraj Sumangala 
199099811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
199199811510SSuraj Sumangala {
199299811510SSuraj Sumangala 	int type;
199399811510SSuraj Sumangala 	int rem = 0;
199499811510SSuraj Sumangala 
1995da5f6c37SGustavo F. Padovan 	while (count) {
199699811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
199799811510SSuraj Sumangala 
199899811510SSuraj Sumangala 		if (!skb) {
199999811510SSuraj Sumangala 			struct { char type; } *pkt;
200099811510SSuraj Sumangala 
200199811510SSuraj Sumangala 			/* Start of the frame */
200299811510SSuraj Sumangala 			pkt = data;
200399811510SSuraj Sumangala 			type = pkt->type;
200499811510SSuraj Sumangala 
200599811510SSuraj Sumangala 			data++;
200699811510SSuraj Sumangala 			count--;
200799811510SSuraj Sumangala 		} else
200899811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
200999811510SSuraj Sumangala 
20101e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
20111e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
201299811510SSuraj Sumangala 		if (rem < 0)
201399811510SSuraj Sumangala 			return rem;
201499811510SSuraj Sumangala 
201599811510SSuraj Sumangala 		data += (count - rem);
201699811510SSuraj Sumangala 		count = rem;
2017f81c6224SJoe Perches 	}
201899811510SSuraj Sumangala 
201999811510SSuraj Sumangala 	return rem;
202099811510SSuraj Sumangala }
202199811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
202299811510SSuraj Sumangala 
20231da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
20241da177e4SLinus Torvalds 
20251da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
20261da177e4SLinus Torvalds {
20271da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
20281da177e4SLinus Torvalds 
2029f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
20301da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2031f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
20321da177e4SLinus Torvalds 
20331da177e4SLinus Torvalds 	return 0;
20341da177e4SLinus Torvalds }
20351da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
20361da177e4SLinus Torvalds 
20371da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
20381da177e4SLinus Torvalds {
20391da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
20401da177e4SLinus Torvalds 
2041f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
20421da177e4SLinus Torvalds 	list_del(&cb->list);
2043f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
20441da177e4SLinus Torvalds 
20451da177e4SLinus Torvalds 	return 0;
20461da177e4SLinus Torvalds }
20471da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
20481da177e4SLinus Torvalds 
20491da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
20501da177e4SLinus Torvalds {
20511da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
20521da177e4SLinus Torvalds 
20531da177e4SLinus Torvalds 	if (!hdev) {
20541da177e4SLinus Torvalds 		kfree_skb(skb);
20551da177e4SLinus Torvalds 		return -ENODEV;
20561da177e4SLinus Torvalds 	}
20571da177e4SLinus Torvalds 
20580d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
20591da177e4SLinus Torvalds 
20601da177e4SLinus Torvalds 	/* Time stamp */
2061a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
20621da177e4SLinus Torvalds 
2063cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2064cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2065cd82e61cSMarcel Holtmann 
2066cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2067cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2068470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
20691da177e4SLinus Torvalds 	}
20701da177e4SLinus Torvalds 
20711da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
20721da177e4SLinus Torvalds 	skb_orphan(skb);
20731da177e4SLinus Torvalds 
20741da177e4SLinus Torvalds 	return hdev->send(skb);
20751da177e4SLinus Torvalds }
20761da177e4SLinus Torvalds 
20771da177e4SLinus Torvalds /* Send HCI command */
2078a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
20791da177e4SLinus Torvalds {
20801da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
20811da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
20821da177e4SLinus Torvalds 	struct sk_buff *skb;
20831da177e4SLinus Torvalds 
2084a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
20851da177e4SLinus Torvalds 
20861da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
20871da177e4SLinus Torvalds 	if (!skb) {
2088ef222013SMarcel Holtmann 		BT_ERR("%s no memory for command", hdev->name);
20891da177e4SLinus Torvalds 		return -ENOMEM;
20901da177e4SLinus Torvalds 	}
20911da177e4SLinus Torvalds 
20921da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2093a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
20941da177e4SLinus Torvalds 	hdr->plen   = plen;
20951da177e4SLinus Torvalds 
20961da177e4SLinus Torvalds 	if (plen)
20971da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
20981da177e4SLinus Torvalds 
20991da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
21001da177e4SLinus Torvalds 
21010d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
21021da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2103c78ae283SMarcel Holtmann 
2104a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
2105a5040efaSJohan Hedberg 		hdev->init_last_cmd = opcode;
2106a5040efaSJohan Hedberg 
21071da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2108c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
21091da177e4SLinus Torvalds 
21101da177e4SLinus Torvalds 	return 0;
21111da177e4SLinus Torvalds }
21121da177e4SLinus Torvalds 
21131da177e4SLinus Torvalds /* Get data from the previously sent command */
2114a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
21151da177e4SLinus Torvalds {
21161da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
21171da177e4SLinus Torvalds 
21181da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
21191da177e4SLinus Torvalds 		return NULL;
21201da177e4SLinus Torvalds 
21211da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
21221da177e4SLinus Torvalds 
2123a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
21241da177e4SLinus Torvalds 		return NULL;
21251da177e4SLinus Torvalds 
2126a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x", hdev->name, opcode);
21271da177e4SLinus Torvalds 
21281da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
21291da177e4SLinus Torvalds }
21301da177e4SLinus Torvalds 
21311da177e4SLinus Torvalds /* Send ACL data */
21321da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
21331da177e4SLinus Torvalds {
21341da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
21351da177e4SLinus Torvalds 	int len = skb->len;
21361da177e4SLinus Torvalds 
2137badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2138badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
21399c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2140aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2141aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
21421da177e4SLinus Torvalds }
21431da177e4SLinus Torvalds 
214473d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
214573d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
21461da177e4SLinus Torvalds {
21471da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
21481da177e4SLinus Torvalds 	struct sk_buff *list;
21491da177e4SLinus Torvalds 
2150087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
2151087bfd99SGustavo Padovan 	skb->data_len = 0;
2152087bfd99SGustavo Padovan 
2153087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2154087bfd99SGustavo Padovan 	hci_add_acl_hdr(skb, conn->handle, flags);
2155087bfd99SGustavo Padovan 
215670f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
215770f23020SAndrei Emeltchenko 	if (!list) {
21581da177e4SLinus Torvalds 		/* Non fragmented */
21591da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
21601da177e4SLinus Torvalds 
216173d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
21621da177e4SLinus Torvalds 	} else {
21631da177e4SLinus Torvalds 		/* Fragmented */
21641da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
21651da177e4SLinus Torvalds 
21661da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
21671da177e4SLinus Torvalds 
21681da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2169af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
21701da177e4SLinus Torvalds 
217173d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2172e702112fSAndrei Emeltchenko 
2173e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2174e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
21751da177e4SLinus Torvalds 		do {
21761da177e4SLinus Torvalds 			skb = list; list = list->next;
21771da177e4SLinus Torvalds 
21781da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
21790d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2180e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
21811da177e4SLinus Torvalds 
21821da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
21831da177e4SLinus Torvalds 
218473d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
21851da177e4SLinus Torvalds 		} while (list);
21861da177e4SLinus Torvalds 
2187af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
21881da177e4SLinus Torvalds 	}
218973d80debSLuiz Augusto von Dentz }
219073d80debSLuiz Augusto von Dentz 
219173d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
219273d80debSLuiz Augusto von Dentz {
219373d80debSLuiz Augusto von Dentz 	struct hci_conn *conn = chan->conn;
219473d80debSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
219573d80debSLuiz Augusto von Dentz 
219673d80debSLuiz Augusto von Dentz 	BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags);
219773d80debSLuiz Augusto von Dentz 
219873d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
219973d80debSLuiz Augusto von Dentz 
220073d80debSLuiz Augusto von Dentz 	hci_queue_acl(conn, &chan->data_q, skb, flags);
22011da177e4SLinus Torvalds 
22023eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
22031da177e4SLinus Torvalds }
22041da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl);
22051da177e4SLinus Torvalds 
22061da177e4SLinus Torvalds /* Send SCO data */
22070d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
22081da177e4SLinus Torvalds {
22091da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
22101da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
22111da177e4SLinus Torvalds 
22121da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
22131da177e4SLinus Torvalds 
2214aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
22151da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
22161da177e4SLinus Torvalds 
2217badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2218badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
22199c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
22201da177e4SLinus Torvalds 
22211da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
22220d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2223c78ae283SMarcel Holtmann 
22241da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
22253eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
22261da177e4SLinus Torvalds }
22271da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco);
22281da177e4SLinus Torvalds 
22291da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
22301da177e4SLinus Torvalds 
22311da177e4SLinus Torvalds /* HCI Connection scheduler */
22326039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
2233a8c5fb1aSGustavo Padovan 				     int *quote)
22341da177e4SLinus Torvalds {
22351da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
22368035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
2237abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
22381da177e4SLinus Torvalds 
22391da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
22401da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2241bf4c6325SGustavo F. Padovan 
2242bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2243bf4c6325SGustavo F. Padovan 
2244bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2245769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
22461da177e4SLinus Torvalds 			continue;
2247769be974SMarcel Holtmann 
2248769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2249769be974SMarcel Holtmann 			continue;
2250769be974SMarcel Holtmann 
22511da177e4SLinus Torvalds 		num++;
22521da177e4SLinus Torvalds 
22531da177e4SLinus Torvalds 		if (c->sent < min) {
22541da177e4SLinus Torvalds 			min  = c->sent;
22551da177e4SLinus Torvalds 			conn = c;
22561da177e4SLinus Torvalds 		}
225752087a79SLuiz Augusto von Dentz 
225852087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
225952087a79SLuiz Augusto von Dentz 			break;
22601da177e4SLinus Torvalds 	}
22611da177e4SLinus Torvalds 
2262bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2263bf4c6325SGustavo F. Padovan 
22641da177e4SLinus Torvalds 	if (conn) {
22656ed58ec5SVille Tervo 		int cnt, q;
22666ed58ec5SVille Tervo 
22676ed58ec5SVille Tervo 		switch (conn->type) {
22686ed58ec5SVille Tervo 		case ACL_LINK:
22696ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
22706ed58ec5SVille Tervo 			break;
22716ed58ec5SVille Tervo 		case SCO_LINK:
22726ed58ec5SVille Tervo 		case ESCO_LINK:
22736ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
22746ed58ec5SVille Tervo 			break;
22756ed58ec5SVille Tervo 		case LE_LINK:
22766ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
22776ed58ec5SVille Tervo 			break;
22786ed58ec5SVille Tervo 		default:
22796ed58ec5SVille Tervo 			cnt = 0;
22806ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
22816ed58ec5SVille Tervo 		}
22826ed58ec5SVille Tervo 
22836ed58ec5SVille Tervo 		q = cnt / num;
22841da177e4SLinus Torvalds 		*quote = q ? q : 1;
22851da177e4SLinus Torvalds 	} else
22861da177e4SLinus Torvalds 		*quote = 0;
22871da177e4SLinus Torvalds 
22881da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
22891da177e4SLinus Torvalds 	return conn;
22901da177e4SLinus Torvalds }
22911da177e4SLinus Torvalds 
22926039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
22931da177e4SLinus Torvalds {
22941da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
22951da177e4SLinus Torvalds 	struct hci_conn *c;
22961da177e4SLinus Torvalds 
2297bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
22981da177e4SLinus Torvalds 
2299bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2300bf4c6325SGustavo F. Padovan 
23011da177e4SLinus Torvalds 	/* Kill stalled connections */
2302bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2303bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
2304bae1f5d9SVille Tervo 			BT_ERR("%s killing stalled connection %s",
23051da177e4SLinus Torvalds 			       hdev->name, batostr(&c->dst));
23061da177e4SLinus Torvalds 			hci_acl_disconn(c, 0x13);
23071da177e4SLinus Torvalds 		}
23081da177e4SLinus Torvalds 	}
2309bf4c6325SGustavo F. Padovan 
2310bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
23111da177e4SLinus Torvalds }
23121da177e4SLinus Torvalds 
23136039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
231473d80debSLuiz Augusto von Dentz 				      int *quote)
231573d80debSLuiz Augusto von Dentz {
231673d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
231773d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
2318abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
231973d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
232073d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
232173d80debSLuiz Augusto von Dentz 
232273d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
232373d80debSLuiz Augusto von Dentz 
2324bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2325bf4c6325SGustavo F. Padovan 
2326bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
232773d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
232873d80debSLuiz Augusto von Dentz 
232973d80debSLuiz Augusto von Dentz 		if (conn->type != type)
233073d80debSLuiz Augusto von Dentz 			continue;
233173d80debSLuiz Augusto von Dentz 
233273d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
233373d80debSLuiz Augusto von Dentz 			continue;
233473d80debSLuiz Augusto von Dentz 
233573d80debSLuiz Augusto von Dentz 		conn_num++;
233673d80debSLuiz Augusto von Dentz 
23378192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
233873d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
233973d80debSLuiz Augusto von Dentz 
234073d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
234173d80debSLuiz Augusto von Dentz 				continue;
234273d80debSLuiz Augusto von Dentz 
234373d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
234473d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
234573d80debSLuiz Augusto von Dentz 				continue;
234673d80debSLuiz Augusto von Dentz 
234773d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
234873d80debSLuiz Augusto von Dentz 				num = 0;
234973d80debSLuiz Augusto von Dentz 				min = ~0;
235073d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
235173d80debSLuiz Augusto von Dentz 			}
235273d80debSLuiz Augusto von Dentz 
235373d80debSLuiz Augusto von Dentz 			num++;
235473d80debSLuiz Augusto von Dentz 
235573d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
235673d80debSLuiz Augusto von Dentz 				min  = conn->sent;
235773d80debSLuiz Augusto von Dentz 				chan = tmp;
235873d80debSLuiz Augusto von Dentz 			}
235973d80debSLuiz Augusto von Dentz 		}
236073d80debSLuiz Augusto von Dentz 
236173d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
236273d80debSLuiz Augusto von Dentz 			break;
236373d80debSLuiz Augusto von Dentz 	}
236473d80debSLuiz Augusto von Dentz 
2365bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2366bf4c6325SGustavo F. Padovan 
236773d80debSLuiz Augusto von Dentz 	if (!chan)
236873d80debSLuiz Augusto von Dentz 		return NULL;
236973d80debSLuiz Augusto von Dentz 
237073d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
237173d80debSLuiz Augusto von Dentz 	case ACL_LINK:
237273d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
237373d80debSLuiz Augusto von Dentz 		break;
237473d80debSLuiz Augusto von Dentz 	case SCO_LINK:
237573d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
237673d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
237773d80debSLuiz Augusto von Dentz 		break;
237873d80debSLuiz Augusto von Dentz 	case LE_LINK:
237973d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
238073d80debSLuiz Augusto von Dentz 		break;
238173d80debSLuiz Augusto von Dentz 	default:
238273d80debSLuiz Augusto von Dentz 		cnt = 0;
238373d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
238473d80debSLuiz Augusto von Dentz 	}
238573d80debSLuiz Augusto von Dentz 
238673d80debSLuiz Augusto von Dentz 	q = cnt / num;
238773d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
238873d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
238973d80debSLuiz Augusto von Dentz 	return chan;
239073d80debSLuiz Augusto von Dentz }
239173d80debSLuiz Augusto von Dentz 
239202b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
239302b20f0bSLuiz Augusto von Dentz {
239402b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
239502b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
239602b20f0bSLuiz Augusto von Dentz 	int num = 0;
239702b20f0bSLuiz Augusto von Dentz 
239802b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
239902b20f0bSLuiz Augusto von Dentz 
2400bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2401bf4c6325SGustavo F. Padovan 
2402bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
240302b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
240402b20f0bSLuiz Augusto von Dentz 
240502b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
240602b20f0bSLuiz Augusto von Dentz 			continue;
240702b20f0bSLuiz Augusto von Dentz 
240802b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
240902b20f0bSLuiz Augusto von Dentz 			continue;
241002b20f0bSLuiz Augusto von Dentz 
241102b20f0bSLuiz Augusto von Dentz 		num++;
241202b20f0bSLuiz Augusto von Dentz 
24138192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
241402b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
241502b20f0bSLuiz Augusto von Dentz 
241602b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
241702b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
241802b20f0bSLuiz Augusto von Dentz 				continue;
241902b20f0bSLuiz Augusto von Dentz 			}
242002b20f0bSLuiz Augusto von Dentz 
242102b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
242202b20f0bSLuiz Augusto von Dentz 				continue;
242302b20f0bSLuiz Augusto von Dentz 
242402b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
242502b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
242602b20f0bSLuiz Augusto von Dentz 				continue;
242702b20f0bSLuiz Augusto von Dentz 
242802b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
242902b20f0bSLuiz Augusto von Dentz 
243002b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
243102b20f0bSLuiz Augusto von Dentz 			       skb->priority);
243202b20f0bSLuiz Augusto von Dentz 		}
243302b20f0bSLuiz Augusto von Dentz 
243402b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
243502b20f0bSLuiz Augusto von Dentz 			break;
243602b20f0bSLuiz Augusto von Dentz 	}
2437bf4c6325SGustavo F. Padovan 
2438bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2439bf4c6325SGustavo F. Padovan 
244002b20f0bSLuiz Augusto von Dentz }
244102b20f0bSLuiz Augusto von Dentz 
2442b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
2443b71d385aSAndrei Emeltchenko {
2444b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
2445b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
2446b71d385aSAndrei Emeltchenko }
2447b71d385aSAndrei Emeltchenko 
24486039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
24491da177e4SLinus Torvalds {
24501da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
24511da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
24521da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
245363d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
2454cc48dc0aSAndrei Emeltchenko 				       msecs_to_jiffies(HCI_ACL_TX_TIMEOUT)))
2455bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
24561da177e4SLinus Torvalds 	}
245763d2bc1bSAndrei Emeltchenko }
24581da177e4SLinus Torvalds 
24596039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
246063d2bc1bSAndrei Emeltchenko {
246163d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
246263d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
246363d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
246463d2bc1bSAndrei Emeltchenko 	int quote;
246563d2bc1bSAndrei Emeltchenko 
246663d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
246704837f64SMarcel Holtmann 
246873d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
246973d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2470ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2471ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
247273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
247373d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
247473d80debSLuiz Augusto von Dentz 
2475ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2476ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2477ec1cce24SLuiz Augusto von Dentz 				break;
2478ec1cce24SLuiz Augusto von Dentz 
2479ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2480ec1cce24SLuiz Augusto von Dentz 
248173d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
248273d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
248304837f64SMarcel Holtmann 
24841da177e4SLinus Torvalds 			hci_send_frame(skb);
24851da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
24861da177e4SLinus Torvalds 
24871da177e4SLinus Torvalds 			hdev->acl_cnt--;
248873d80debSLuiz Augusto von Dentz 			chan->sent++;
248973d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
24901da177e4SLinus Torvalds 		}
24911da177e4SLinus Torvalds 	}
249202b20f0bSLuiz Augusto von Dentz 
249302b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
249402b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
24951da177e4SLinus Torvalds }
24961da177e4SLinus Torvalds 
24976039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
2498b71d385aSAndrei Emeltchenko {
249963d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
2500b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
2501b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
2502b71d385aSAndrei Emeltchenko 	int quote;
2503b71d385aSAndrei Emeltchenko 
250463d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
2505b71d385aSAndrei Emeltchenko 
2506b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
2507b71d385aSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2508b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
2509b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
2510b71d385aSAndrei Emeltchenko 			int blocks;
2511b71d385aSAndrei Emeltchenko 
2512b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
2513b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
2514b71d385aSAndrei Emeltchenko 
2515b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
2516b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
2517b71d385aSAndrei Emeltchenko 				break;
2518b71d385aSAndrei Emeltchenko 
2519b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
2520b71d385aSAndrei Emeltchenko 
2521b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
2522b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
2523b71d385aSAndrei Emeltchenko 				return;
2524b71d385aSAndrei Emeltchenko 
2525b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
2526b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
2527b71d385aSAndrei Emeltchenko 
2528b71d385aSAndrei Emeltchenko 			hci_send_frame(skb);
2529b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
2530b71d385aSAndrei Emeltchenko 
2531b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
2532b71d385aSAndrei Emeltchenko 			quote -= blocks;
2533b71d385aSAndrei Emeltchenko 
2534b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
2535b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
2536b71d385aSAndrei Emeltchenko 		}
2537b71d385aSAndrei Emeltchenko 	}
2538b71d385aSAndrei Emeltchenko 
2539b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
2540b71d385aSAndrei Emeltchenko 		hci_prio_recalculate(hdev, ACL_LINK);
2541b71d385aSAndrei Emeltchenko }
2542b71d385aSAndrei Emeltchenko 
25436039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
2544b71d385aSAndrei Emeltchenko {
2545b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
2546b71d385aSAndrei Emeltchenko 
2547b71d385aSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK))
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 
2698a8c5fb1aSGustavo Padovan 	BT_DBG("%s len %d handle 0x%x flags 0x%x", 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 
27401da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x", 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 
28201da177e4SLinus Torvalds 	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
28211da177e4SLinus Torvalds 
28221da177e4SLinus Torvalds 	/* Send queued commands */
28235a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
28245a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
28255a08ecceSAndrei Emeltchenko 		if (!skb)
28265a08ecceSAndrei Emeltchenko 			return;
28275a08ecceSAndrei Emeltchenko 
28281da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
28291da177e4SLinus Torvalds 
283070f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
283170f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
28321da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
28331da177e4SLinus Torvalds 			hci_send_frame(skb);
28347bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
28357bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
28367bdb8a5cSSzymon Janc 			else
28376bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
28386bd32326SVille Tervo 				  jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
28391da177e4SLinus Torvalds 		} else {
28401da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
2841c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
28421da177e4SLinus Torvalds 		}
28431da177e4SLinus Torvalds 	}
28441da177e4SLinus Torvalds }
28452519a1fcSAndre Guedes 
28462519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
28472519a1fcSAndre Guedes {
28482519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
28492519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
28502519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
28512519a1fcSAndre Guedes 
28522519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
28532519a1fcSAndre Guedes 
28542519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
28552519a1fcSAndre Guedes 		return -EINPROGRESS;
28562519a1fcSAndre Guedes 
28574663262cSJohan Hedberg 	inquiry_cache_flush(hdev);
28584663262cSJohan Hedberg 
28592519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
28602519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
28612519a1fcSAndre Guedes 	cp.length  = length;
28622519a1fcSAndre Guedes 
28632519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
28642519a1fcSAndre Guedes }
2865023d5049SAndre Guedes 
2866023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
2867023d5049SAndre Guedes {
2868023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
2869023d5049SAndre Guedes 
2870023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
28717537e5c3SAndre Guedes 		return -EALREADY;
2872023d5049SAndre Guedes 
2873023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2874023d5049SAndre Guedes }
287531f7956cSAndre Guedes 
287631f7956cSAndre Guedes u8 bdaddr_to_le(u8 bdaddr_type)
287731f7956cSAndre Guedes {
287831f7956cSAndre Guedes 	switch (bdaddr_type) {
287931f7956cSAndre Guedes 	case BDADDR_LE_PUBLIC:
288031f7956cSAndre Guedes 		return ADDR_LE_DEV_PUBLIC;
288131f7956cSAndre Guedes 
288231f7956cSAndre Guedes 	default:
288331f7956cSAndre Guedes 		/* Fallback to LE Random address type */
288431f7956cSAndre Guedes 		return ADDR_LE_DEV_RANDOM;
288531f7956cSAndre Guedes 	}
288631f7956cSAndre Guedes }
2887