xref: /linux/net/bluetooth/hci_conn.c (revision 84a4bb65)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
32d0a0346SRon Shaffer    Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
402171da6SIulia Tanasescu    Copyright 2023-2024 NXP
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 connection handling. */
271da177e4SLinus Torvalds 
288c520a59SGustavo Padovan #include <linux/export.h>
2923b9ceb7SMarcel Holtmann #include <linux/debugfs.h>
301da177e4SLinus Torvalds 
311da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
321da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
334bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h>
34eca0ae4aSLuiz Augusto von Dentz #include <net/bluetooth/iso.h>
35eca0ae4aSLuiz Augusto von Dentz #include <net/bluetooth/mgmt.h>
361da177e4SLinus Torvalds 
370857dd3bSJohan Hedberg #include "hci_request.h"
38ac4b7236SMarcel Holtmann #include "smp.h"
39eca0ae4aSLuiz Augusto von Dentz #include "eir.h"
407024728eSMarcel Holtmann 
412dea632fSFrédéric Dalleau struct sco_param {
422dea632fSFrédéric Dalleau 	u16 pkt_type;
432dea632fSFrédéric Dalleau 	u16 max_latency;
44c7da5797SJohan Hedberg 	u8  retrans_effort;
452dea632fSFrédéric Dalleau };
462dea632fSFrédéric Dalleau 
47e07a06b4SBrian Gix struct conn_handle_t {
48e07a06b4SBrian Gix 	struct hci_conn *conn;
49e07a06b4SBrian Gix 	__u16 handle;
50e07a06b4SBrian Gix };
51e07a06b4SBrian Gix 
5248e68ff5SBernhard Thaler static const struct sco_param esco_param_cvsd[] = {
53c7da5797SJohan Hedberg 	{ EDR_ESCO_MASK & ~ESCO_2EV3, 0x000a,	0x01 }, /* S3 */
54c7da5797SJohan Hedberg 	{ EDR_ESCO_MASK & ~ESCO_2EV3, 0x0007,	0x01 }, /* S2 */
55c7da5797SJohan Hedberg 	{ EDR_ESCO_MASK | ESCO_EV3,   0x0007,	0x01 }, /* S1 */
56c7da5797SJohan Hedberg 	{ EDR_ESCO_MASK | ESCO_HV3,   0xffff,	0x01 }, /* D1 */
57c7da5797SJohan Hedberg 	{ EDR_ESCO_MASK | ESCO_HV1,   0xffff,	0x01 }, /* D0 */
582dea632fSFrédéric Dalleau };
592dea632fSFrédéric Dalleau 
6048e68ff5SBernhard Thaler static const struct sco_param sco_param_cvsd[] = {
61c7da5797SJohan Hedberg 	{ EDR_ESCO_MASK | ESCO_HV3,   0xffff,	0xff }, /* D1 */
62c7da5797SJohan Hedberg 	{ EDR_ESCO_MASK | ESCO_HV1,   0xffff,	0xff }, /* D0 */
6348e68ff5SBernhard Thaler };
6448e68ff5SBernhard Thaler 
65565766b0SJohan Hedberg static const struct sco_param esco_param_msbc[] = {
66c7da5797SJohan Hedberg 	{ EDR_ESCO_MASK & ~ESCO_2EV3, 0x000d,	0x02 }, /* T2 */
67c7da5797SJohan Hedberg 	{ EDR_ESCO_MASK | ESCO_EV3,   0x0008,	0x02 }, /* T1 */
682dea632fSFrédéric Dalleau };
692dea632fSFrédéric Dalleau 
70f75113a2SJakub Pawlowski /* This function requires the caller holds hdev->lock */
hci_connect_le_scan_cleanup(struct hci_conn * conn,u8 status)71881559afSLuiz Augusto von Dentz void hci_connect_le_scan_cleanup(struct hci_conn *conn, u8 status)
72f75113a2SJakub Pawlowski {
73f75113a2SJakub Pawlowski 	struct hci_conn_params *params;
74b5c2b621SJohan Hedberg 	struct hci_dev *hdev = conn->hdev;
75f75113a2SJakub Pawlowski 	struct smp_irk *irk;
76f75113a2SJakub Pawlowski 	bdaddr_t *bdaddr;
77f75113a2SJakub Pawlowski 	u8 bdaddr_type;
78f75113a2SJakub Pawlowski 
79f75113a2SJakub Pawlowski 	bdaddr = &conn->dst;
80f75113a2SJakub Pawlowski 	bdaddr_type = conn->dst_type;
81f75113a2SJakub Pawlowski 
82f75113a2SJakub Pawlowski 	/* Check if we need to convert to identity address */
83b5c2b621SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
84f75113a2SJakub Pawlowski 	if (irk) {
85f75113a2SJakub Pawlowski 		bdaddr = &irk->bdaddr;
86f75113a2SJakub Pawlowski 		bdaddr_type = irk->addr_type;
87f75113a2SJakub Pawlowski 	}
88f75113a2SJakub Pawlowski 
8917bc08f0SJohan Hedberg 	params = hci_pend_le_action_lookup(&hdev->pend_le_conns, bdaddr,
9017bc08f0SJohan Hedberg 					   bdaddr_type);
9119cf60bfSLuiz Augusto von Dentz 	if (!params)
92f75113a2SJakub Pawlowski 		return;
93f75113a2SJakub Pawlowski 
9419cf60bfSLuiz Augusto von Dentz 	if (params->conn) {
9519cf60bfSLuiz Augusto von Dentz 		hci_conn_drop(params->conn);
9619cf60bfSLuiz Augusto von Dentz 		hci_conn_put(params->conn);
9719cf60bfSLuiz Augusto von Dentz 		params->conn = NULL;
9819cf60bfSLuiz Augusto von Dentz 	}
9919cf60bfSLuiz Augusto von Dentz 
10019cf60bfSLuiz Augusto von Dentz 	if (!params->explicit_connect)
10119cf60bfSLuiz Augusto von Dentz 		return;
10219cf60bfSLuiz Augusto von Dentz 
10319cf60bfSLuiz Augusto von Dentz 	/* If the status indicates successful cancellation of
10419cf60bfSLuiz Augusto von Dentz 	 * the attempt (i.e. Unknown Connection Id) there's no point of
10519cf60bfSLuiz Augusto von Dentz 	 * notifying failure since we'll go back to keep trying to
10619cf60bfSLuiz Augusto von Dentz 	 * connect. The only exception is explicit connect requests
10719cf60bfSLuiz Augusto von Dentz 	 * where a timeout + cancel does indicate an actual failure.
10819cf60bfSLuiz Augusto von Dentz 	 */
10919cf60bfSLuiz Augusto von Dentz 	if (status && status != HCI_ERROR_UNKNOWN_CONN_ID)
11019cf60bfSLuiz Augusto von Dentz 		mgmt_connect_failed(hdev, &conn->dst, conn->type,
11119cf60bfSLuiz Augusto von Dentz 				    conn->dst_type, status);
11219cf60bfSLuiz Augusto von Dentz 
113f75113a2SJakub Pawlowski 	/* The connection attempt was doing scan for new RPA, and is
114f75113a2SJakub Pawlowski 	 * in scan phase. If params are not associated with any other
115f75113a2SJakub Pawlowski 	 * autoconnect action, remove them completely. If they are, just unmark
116f75113a2SJakub Pawlowski 	 * them as waiting for connection, by clearing explicit_connect field.
117f75113a2SJakub Pawlowski 	 */
118f75113a2SJakub Pawlowski 	params->explicit_connect = false;
1199ad3e6ffSJohan Hedberg 
120195ef75eSPauli Virtanen 	hci_pend_le_list_del_init(params);
1219ad3e6ffSJohan Hedberg 
1229ad3e6ffSJohan Hedberg 	switch (params->auto_connect) {
1239ad3e6ffSJohan Hedberg 	case HCI_AUTO_CONN_EXPLICIT:
124b5c2b621SJohan Hedberg 		hci_conn_params_del(hdev, bdaddr, bdaddr_type);
1259ad3e6ffSJohan Hedberg 		/* return instead of break to avoid duplicate scan update */
1269ad3e6ffSJohan Hedberg 		return;
1279ad3e6ffSJohan Hedberg 	case HCI_AUTO_CONN_DIRECT:
1289ad3e6ffSJohan Hedberg 	case HCI_AUTO_CONN_ALWAYS:
129195ef75eSPauli Virtanen 		hci_pend_le_list_add(params, &hdev->pend_le_conns);
1309ad3e6ffSJohan Hedberg 		break;
1319ad3e6ffSJohan Hedberg 	case HCI_AUTO_CONN_REPORT:
132195ef75eSPauli Virtanen 		hci_pend_le_list_add(params, &hdev->pend_le_reports);
1339ad3e6ffSJohan Hedberg 		break;
1349ad3e6ffSJohan Hedberg 	default:
1359ad3e6ffSJohan Hedberg 		break;
136168b8a25SJakub Pawlowski 	}
1379ad3e6ffSJohan Hedberg 
1385bee2fd6SLuiz Augusto von Dentz 	hci_update_passive_scan(hdev);
139f75113a2SJakub Pawlowski }
140f75113a2SJakub Pawlowski 
hci_conn_cleanup(struct hci_conn * conn)141b958f9a3SJohan Hedberg static void hci_conn_cleanup(struct hci_conn *conn)
142b958f9a3SJohan Hedberg {
143b958f9a3SJohan Hedberg 	struct hci_dev *hdev = conn->hdev;
144b958f9a3SJohan Hedberg 
145b958f9a3SJohan Hedberg 	if (test_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags))
146b958f9a3SJohan Hedberg 		hci_conn_params_del(conn->hdev, &conn->dst, conn->dst_type);
147b958f9a3SJohan Hedberg 
148629f66aaSAlain Michaud 	if (test_and_clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
149629f66aaSAlain Michaud 		hci_remove_link_key(hdev, &conn->dst);
150629f66aaSAlain Michaud 
151b958f9a3SJohan Hedberg 	hci_chan_list_flush(conn);
152b958f9a3SJohan Hedberg 
153b958f9a3SJohan Hedberg 	hci_conn_hash_del(hdev, conn);
154b958f9a3SJohan Hedberg 
155181a42edSZiyang Xuan 	if (HCI_CONN_HANDLE_UNSET(conn->handle))
156181a42edSZiyang Xuan 		ida_free(&hdev->unset_handle_ida, conn->handle);
157181a42edSZiyang Xuan 
15826afbd82SLuiz Augusto von Dentz 	if (conn->cleanup)
15926afbd82SLuiz Augusto von Dentz 		conn->cleanup(conn);
16026afbd82SLuiz Augusto von Dentz 
1611f8330eaSSathish Narsimman 	if (conn->type == SCO_LINK || conn->type == ESCO_LINK) {
1621f8330eaSSathish Narsimman 		switch (conn->setting & SCO_AIRMODE_MASK) {
1631f8330eaSSathish Narsimman 		case SCO_AIRMODE_CVSD:
1641f8330eaSSathish Narsimman 		case SCO_AIRMODE_TRANSP:
1651f8330eaSSathish Narsimman 			if (hdev->notify)
1661f8330eaSSathish Narsimman 				hdev->notify(hdev, HCI_NOTIFY_DISABLE_SCO);
1671f8330eaSSathish Narsimman 			break;
1681f8330eaSSathish Narsimman 		}
1691f8330eaSSathish Narsimman 	} else {
170b958f9a3SJohan Hedberg 		if (hdev->notify)
171b958f9a3SJohan Hedberg 			hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
1721f8330eaSSathish Narsimman 	}
173b958f9a3SJohan Hedberg 
174b958f9a3SJohan Hedberg 	debugfs_remove_recursive(conn->debugfs);
175b958f9a3SJohan Hedberg 
176a85fb91eSZhengHan Wang 	hci_conn_del_sysfs(conn);
177b958f9a3SJohan Hedberg 
178a85fb91eSZhengHan Wang 	hci_dev_put(hdev);
179b958f9a3SJohan Hedberg }
180b958f9a3SJohan Hedberg 
hci_disconnect(struct hci_conn * conn,__u8 reason)181e3b679d5SJohan Hedberg int hci_disconnect(struct hci_conn *conn, __u8 reason)
1821da177e4SLinus Torvalds {
18338b3fef1SAndrei Emeltchenko 	BT_DBG("hcon %p", conn);
1841da177e4SLinus Torvalds 
18574be523cSArchie Pusaka 	/* When we are central of an established connection and it enters
186839035a7SJohan Hedberg 	 * the disconnect timeout, then go ahead and try to read the
187839035a7SJohan Hedberg 	 * current clock offset.  Processing of the result is done
188839035a7SJohan Hedberg 	 * within the event handling and hci_clock_offset_evt function.
189839035a7SJohan Hedberg 	 */
19088d07febSJohan Hedberg 	if (conn->type == ACL_LINK && conn->role == HCI_ROLE_MASTER &&
19188d07febSJohan Hedberg 	    (conn->state == BT_CONNECTED || conn->state == BT_CONFIG)) {
192839035a7SJohan Hedberg 		struct hci_dev *hdev = conn->hdev;
1934f639edeSFabian Frederick 		struct hci_cp_read_clock_offset clkoff_cp;
194839035a7SJohan Hedberg 
1954f639edeSFabian Frederick 		clkoff_cp.handle = cpu_to_le16(conn->handle);
1964f639edeSFabian Frederick 		hci_send_cmd(hdev, HCI_OP_READ_CLOCK_OFFSET, sizeof(clkoff_cp),
1974f639edeSFabian Frederick 			     &clkoff_cp);
198839035a7SJohan Hedberg 	}
199839035a7SJohan Hedberg 
20088d07febSJohan Hedberg 	return hci_abort_conn(conn, reason);
2011da177e4SLinus Torvalds }
2021da177e4SLinus Torvalds 
hci_add_sco(struct hci_conn * conn,__u16 handle)20357f5d0d1SVinicius Costa Gomes static void hci_add_sco(struct hci_conn *conn, __u16 handle)
2041da177e4SLinus Torvalds {
2051da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
2061da177e4SLinus Torvalds 	struct hci_cp_add_sco cp;
2071da177e4SLinus Torvalds 
20838b3fef1SAndrei Emeltchenko 	BT_DBG("hcon %p", conn);
2091da177e4SLinus Torvalds 
2101da177e4SLinus Torvalds 	conn->state = BT_CONNECT;
211a0c808b3SJohan Hedberg 	conn->out = true;
2121da177e4SLinus Torvalds 
213efc7688bSMarcel Holtmann 	conn->attempt++;
214efc7688bSMarcel Holtmann 
215aca3192cSYOSHIFUJI Hideaki 	cp.handle   = cpu_to_le16(handle);
216a8746417SMarcel Holtmann 	cp.pkt_type = cpu_to_le16(conn->pkt_type);
2171da177e4SLinus Torvalds 
218a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp);
2191da177e4SLinus Torvalds }
2201da177e4SLinus Torvalds 
find_next_esco_param(struct hci_conn * conn,const struct sco_param * esco_param,int size)2218b1c324cSYu Liu static bool find_next_esco_param(struct hci_conn *conn,
2228b1c324cSYu Liu 				 const struct sco_param *esco_param, int size)
2238b1c324cSYu Liu {
22406149746SLuiz Augusto von Dentz 	if (!conn->parent)
22506149746SLuiz Augusto von Dentz 		return false;
22606149746SLuiz Augusto von Dentz 
2278b1c324cSYu Liu 	for (; conn->attempt <= size; conn->attempt++) {
22806149746SLuiz Augusto von Dentz 		if (lmp_esco_2m_capable(conn->parent) ||
2298b1c324cSYu Liu 		    (esco_param[conn->attempt - 1].pkt_type & ESCO_2EV3))
2308b1c324cSYu Liu 			break;
2318b1c324cSYu Liu 		BT_DBG("hcon %p skipped attempt %d, eSCO 2M not supported",
2328b1c324cSYu Liu 		       conn, conn->attempt);
2338b1c324cSYu Liu 	}
2348b1c324cSYu Liu 
2358b1c324cSYu Liu 	return conn->attempt <= size;
2368b1c324cSYu Liu }
2378b1c324cSYu Liu 
configure_datapath_sync(struct hci_dev * hdev,struct bt_codec * codec)238e07a06b4SBrian Gix static int configure_datapath_sync(struct hci_dev *hdev, struct bt_codec *codec)
239b2af264aSKiran K {
240e07a06b4SBrian Gix 	int err;
241e07a06b4SBrian Gix 	__u8 vnd_len, *vnd_data = NULL;
242e07a06b4SBrian Gix 	struct hci_op_configure_data_path *cmd = NULL;
243e07a06b4SBrian Gix 
244d68d8a7aSZijun Hu 	/* Do not take below 2 checks as error since the 1st means user do not
245d68d8a7aSZijun Hu 	 * want to use HFP offload mode and the 2nd means the vendor controller
246d68d8a7aSZijun Hu 	 * do not need to send below HCI command for offload mode.
247d68d8a7aSZijun Hu 	 */
248132d0fd0SZijun Hu 	if (!codec->data_path || !hdev->get_codec_config_data)
249132d0fd0SZijun Hu 		return 0;
250132d0fd0SZijun Hu 
251e07a06b4SBrian Gix 	err = hdev->get_codec_config_data(hdev, ESCO_LINK, codec, &vnd_len,
252e07a06b4SBrian Gix 					  &vnd_data);
253e07a06b4SBrian Gix 	if (err < 0)
254e07a06b4SBrian Gix 		goto error;
255e07a06b4SBrian Gix 
256e07a06b4SBrian Gix 	cmd = kzalloc(sizeof(*cmd) + vnd_len, GFP_KERNEL);
257e07a06b4SBrian Gix 	if (!cmd) {
258e07a06b4SBrian Gix 		err = -ENOMEM;
259e07a06b4SBrian Gix 		goto error;
260e07a06b4SBrian Gix 	}
261e07a06b4SBrian Gix 
262e07a06b4SBrian Gix 	err = hdev->get_data_path_id(hdev, &cmd->data_path_id);
263e07a06b4SBrian Gix 	if (err < 0)
264e07a06b4SBrian Gix 		goto error;
265e07a06b4SBrian Gix 
266e07a06b4SBrian Gix 	cmd->vnd_len = vnd_len;
267e07a06b4SBrian Gix 	memcpy(cmd->vnd_data, vnd_data, vnd_len);
268e07a06b4SBrian Gix 
269e07a06b4SBrian Gix 	cmd->direction = 0x00;
270e07a06b4SBrian Gix 	__hci_cmd_sync_status(hdev, HCI_CONFIGURE_DATA_PATH,
271e07a06b4SBrian Gix 			      sizeof(*cmd) + vnd_len, cmd, HCI_CMD_TIMEOUT);
272e07a06b4SBrian Gix 
273e07a06b4SBrian Gix 	cmd->direction = 0x01;
274e07a06b4SBrian Gix 	err = __hci_cmd_sync_status(hdev, HCI_CONFIGURE_DATA_PATH,
275e07a06b4SBrian Gix 				    sizeof(*cmd) + vnd_len, cmd,
276e07a06b4SBrian Gix 				    HCI_CMD_TIMEOUT);
277e07a06b4SBrian Gix error:
278e07a06b4SBrian Gix 
279e07a06b4SBrian Gix 	kfree(cmd);
280e07a06b4SBrian Gix 	kfree(vnd_data);
281e07a06b4SBrian Gix 	return err;
282e07a06b4SBrian Gix }
283e07a06b4SBrian Gix 
hci_enhanced_setup_sync(struct hci_dev * hdev,void * data)284e07a06b4SBrian Gix static int hci_enhanced_setup_sync(struct hci_dev *hdev, void *data)
285e07a06b4SBrian Gix {
286e07a06b4SBrian Gix 	struct conn_handle_t *conn_handle = data;
287e07a06b4SBrian Gix 	struct hci_conn *conn = conn_handle->conn;
288e07a06b4SBrian Gix 	__u16 handle = conn_handle->handle;
289b2af264aSKiran K 	struct hci_cp_enhanced_setup_sync_conn cp;
290b2af264aSKiran K 	const struct sco_param *param;
291b2af264aSKiran K 
292e07a06b4SBrian Gix 	kfree(conn_handle);
293e07a06b4SBrian Gix 
294b2af264aSKiran K 	bt_dev_dbg(hdev, "hcon %p", conn);
295b2af264aSKiran K 
296e07a06b4SBrian Gix 	configure_datapath_sync(hdev, &conn->codec);
2979798fbdeSKiran K 
298b2af264aSKiran K 	conn->state = BT_CONNECT;
299b2af264aSKiran K 	conn->out = true;
300b2af264aSKiran K 
301b2af264aSKiran K 	conn->attempt++;
302b2af264aSKiran K 
303b2af264aSKiran K 	memset(&cp, 0x00, sizeof(cp));
304b2af264aSKiran K 
305b2af264aSKiran K 	cp.handle   = cpu_to_le16(handle);
306b2af264aSKiran K 
307b2af264aSKiran K 	cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
308b2af264aSKiran K 	cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
309b2af264aSKiran K 
310b2af264aSKiran K 	switch (conn->codec.id) {
311904c139aSKiran K 	case BT_CODEC_MSBC:
312904c139aSKiran K 		if (!find_next_esco_param(conn, esco_param_msbc,
313904c139aSKiran K 					  ARRAY_SIZE(esco_param_msbc)))
314e07a06b4SBrian Gix 			return -EINVAL;
315904c139aSKiran K 
316904c139aSKiran K 		param = &esco_param_msbc[conn->attempt - 1];
317904c139aSKiran K 		cp.tx_coding_format.id = 0x05;
318904c139aSKiran K 		cp.rx_coding_format.id = 0x05;
319904c139aSKiran K 		cp.tx_codec_frame_size = __cpu_to_le16(60);
320904c139aSKiran K 		cp.rx_codec_frame_size = __cpu_to_le16(60);
321904c139aSKiran K 		cp.in_bandwidth = __cpu_to_le32(32000);
322904c139aSKiran K 		cp.out_bandwidth = __cpu_to_le32(32000);
323904c139aSKiran K 		cp.in_coding_format.id = 0x04;
324904c139aSKiran K 		cp.out_coding_format.id = 0x04;
325904c139aSKiran K 		cp.in_coded_data_size = __cpu_to_le16(16);
326904c139aSKiran K 		cp.out_coded_data_size = __cpu_to_le16(16);
327904c139aSKiran K 		cp.in_pcm_data_format = 2;
328904c139aSKiran K 		cp.out_pcm_data_format = 2;
329904c139aSKiran K 		cp.in_pcm_sample_payload_msb_pos = 0;
330904c139aSKiran K 		cp.out_pcm_sample_payload_msb_pos = 0;
331904c139aSKiran K 		cp.in_data_path = conn->codec.data_path;
332904c139aSKiran K 		cp.out_data_path = conn->codec.data_path;
333904c139aSKiran K 		cp.in_transport_unit_size = 1;
334904c139aSKiran K 		cp.out_transport_unit_size = 1;
335904c139aSKiran K 		break;
336904c139aSKiran K 
337b2af264aSKiran K 	case BT_CODEC_TRANSPARENT:
338b2af264aSKiran K 		if (!find_next_esco_param(conn, esco_param_msbc,
339b2af264aSKiran K 					  ARRAY_SIZE(esco_param_msbc)))
340b2af264aSKiran K 			return false;
341b2af264aSKiran K 		param = &esco_param_msbc[conn->attempt - 1];
342b2af264aSKiran K 		cp.tx_coding_format.id = 0x03;
343b2af264aSKiran K 		cp.rx_coding_format.id = 0x03;
344b2af264aSKiran K 		cp.tx_codec_frame_size = __cpu_to_le16(60);
345b2af264aSKiran K 		cp.rx_codec_frame_size = __cpu_to_le16(60);
346b2af264aSKiran K 		cp.in_bandwidth = __cpu_to_le32(0x1f40);
347b2af264aSKiran K 		cp.out_bandwidth = __cpu_to_le32(0x1f40);
348b2af264aSKiran K 		cp.in_coding_format.id = 0x03;
349b2af264aSKiran K 		cp.out_coding_format.id = 0x03;
350b2af264aSKiran K 		cp.in_coded_data_size = __cpu_to_le16(16);
351b2af264aSKiran K 		cp.out_coded_data_size = __cpu_to_le16(16);
352b2af264aSKiran K 		cp.in_pcm_data_format = 2;
353b2af264aSKiran K 		cp.out_pcm_data_format = 2;
354b2af264aSKiran K 		cp.in_pcm_sample_payload_msb_pos = 0;
355b2af264aSKiran K 		cp.out_pcm_sample_payload_msb_pos = 0;
356b2af264aSKiran K 		cp.in_data_path = conn->codec.data_path;
357b2af264aSKiran K 		cp.out_data_path = conn->codec.data_path;
358b2af264aSKiran K 		cp.in_transport_unit_size = 1;
359b2af264aSKiran K 		cp.out_transport_unit_size = 1;
360b2af264aSKiran K 		break;
361b2af264aSKiran K 
362b2af264aSKiran K 	case BT_CODEC_CVSD:
36306149746SLuiz Augusto von Dentz 		if (conn->parent && lmp_esco_capable(conn->parent)) {
364b2af264aSKiran K 			if (!find_next_esco_param(conn, esco_param_cvsd,
365b2af264aSKiran K 						  ARRAY_SIZE(esco_param_cvsd)))
366e07a06b4SBrian Gix 				return -EINVAL;
367b2af264aSKiran K 			param = &esco_param_cvsd[conn->attempt - 1];
368b2af264aSKiran K 		} else {
369b2af264aSKiran K 			if (conn->attempt > ARRAY_SIZE(sco_param_cvsd))
370e07a06b4SBrian Gix 				return -EINVAL;
371b2af264aSKiran K 			param = &sco_param_cvsd[conn->attempt - 1];
372b2af264aSKiran K 		}
373b2af264aSKiran K 		cp.tx_coding_format.id = 2;
374b2af264aSKiran K 		cp.rx_coding_format.id = 2;
375b2af264aSKiran K 		cp.tx_codec_frame_size = __cpu_to_le16(60);
376b2af264aSKiran K 		cp.rx_codec_frame_size = __cpu_to_le16(60);
377b2af264aSKiran K 		cp.in_bandwidth = __cpu_to_le32(16000);
378b2af264aSKiran K 		cp.out_bandwidth = __cpu_to_le32(16000);
379b2af264aSKiran K 		cp.in_coding_format.id = 4;
380b2af264aSKiran K 		cp.out_coding_format.id = 4;
381b2af264aSKiran K 		cp.in_coded_data_size = __cpu_to_le16(16);
382b2af264aSKiran K 		cp.out_coded_data_size = __cpu_to_le16(16);
383b2af264aSKiran K 		cp.in_pcm_data_format = 2;
384b2af264aSKiran K 		cp.out_pcm_data_format = 2;
385b2af264aSKiran K 		cp.in_pcm_sample_payload_msb_pos = 0;
386b2af264aSKiran K 		cp.out_pcm_sample_payload_msb_pos = 0;
387b2af264aSKiran K 		cp.in_data_path = conn->codec.data_path;
388b2af264aSKiran K 		cp.out_data_path = conn->codec.data_path;
389b2af264aSKiran K 		cp.in_transport_unit_size = 16;
390b2af264aSKiran K 		cp.out_transport_unit_size = 16;
391b2af264aSKiran K 		break;
392b2af264aSKiran K 	default:
393e07a06b4SBrian Gix 		return -EINVAL;
394b2af264aSKiran K 	}
395b2af264aSKiran K 
396b2af264aSKiran K 	cp.retrans_effort = param->retrans_effort;
397b2af264aSKiran K 	cp.pkt_type = __cpu_to_le16(param->pkt_type);
398b2af264aSKiran K 	cp.max_latency = __cpu_to_le16(param->max_latency);
399b2af264aSKiran K 
400b2af264aSKiran K 	if (hci_send_cmd(hdev, HCI_OP_ENHANCED_SETUP_SYNC_CONN, sizeof(cp), &cp) < 0)
401e07a06b4SBrian Gix 		return -EIO;
402b2af264aSKiran K 
403e07a06b4SBrian Gix 	return 0;
404b2af264aSKiran K }
405b2af264aSKiran K 
hci_setup_sync_conn(struct hci_conn * conn,__u16 handle)406b2af264aSKiran K static bool hci_setup_sync_conn(struct hci_conn *conn, __u16 handle)
407b6a0dc82SMarcel Holtmann {
408b6a0dc82SMarcel Holtmann 	struct hci_dev *hdev = conn->hdev;
409b6a0dc82SMarcel Holtmann 	struct hci_cp_setup_sync_conn cp;
4102dea632fSFrédéric Dalleau 	const struct sco_param *param;
411b6a0dc82SMarcel Holtmann 
412b2af264aSKiran K 	bt_dev_dbg(hdev, "hcon %p", conn);
413b6a0dc82SMarcel Holtmann 
414b6a0dc82SMarcel Holtmann 	conn->state = BT_CONNECT;
415a0c808b3SJohan Hedberg 	conn->out = true;
416b6a0dc82SMarcel Holtmann 
417efc7688bSMarcel Holtmann 	conn->attempt++;
418efc7688bSMarcel Holtmann 
419b6a0dc82SMarcel Holtmann 	cp.handle   = cpu_to_le16(handle);
420b6a0dc82SMarcel Holtmann 
421dcf4adbfSJoe Perches 	cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
422dcf4adbfSJoe Perches 	cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
42310c62ddcSFrédéric Dalleau 	cp.voice_setting  = cpu_to_le16(conn->setting);
42410c62ddcSFrédéric Dalleau 
42510c62ddcSFrédéric Dalleau 	switch (conn->setting & SCO_AIRMODE_MASK) {
42610c62ddcSFrédéric Dalleau 	case SCO_AIRMODE_TRANSP:
4278b1c324cSYu Liu 		if (!find_next_esco_param(conn, esco_param_msbc,
4288b1c324cSYu Liu 					  ARRAY_SIZE(esco_param_msbc)))
4292dea632fSFrédéric Dalleau 			return false;
430565766b0SJohan Hedberg 		param = &esco_param_msbc[conn->attempt - 1];
43110c62ddcSFrédéric Dalleau 		break;
43210c62ddcSFrédéric Dalleau 	case SCO_AIRMODE_CVSD:
43306149746SLuiz Augusto von Dentz 		if (conn->parent && lmp_esco_capable(conn->parent)) {
4348b1c324cSYu Liu 			if (!find_next_esco_param(conn, esco_param_cvsd,
4358b1c324cSYu Liu 						  ARRAY_SIZE(esco_param_cvsd)))
4362dea632fSFrédéric Dalleau 				return false;
43748e68ff5SBernhard Thaler 			param = &esco_param_cvsd[conn->attempt - 1];
43848e68ff5SBernhard Thaler 		} else {
43948e68ff5SBernhard Thaler 			if (conn->attempt > ARRAY_SIZE(sco_param_cvsd))
44048e68ff5SBernhard Thaler 				return false;
4412dea632fSFrédéric Dalleau 			param = &sco_param_cvsd[conn->attempt - 1];
44248e68ff5SBernhard Thaler 		}
44310c62ddcSFrédéric Dalleau 		break;
4442dea632fSFrédéric Dalleau 	default:
4452dea632fSFrédéric Dalleau 		return false;
44610c62ddcSFrédéric Dalleau 	}
447b6a0dc82SMarcel Holtmann 
448c7da5797SJohan Hedberg 	cp.retrans_effort = param->retrans_effort;
4492dea632fSFrédéric Dalleau 	cp.pkt_type = __cpu_to_le16(param->pkt_type);
4502dea632fSFrédéric Dalleau 	cp.max_latency = __cpu_to_le16(param->max_latency);
4512dea632fSFrédéric Dalleau 
4522dea632fSFrédéric Dalleau 	if (hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp) < 0)
4532dea632fSFrédéric Dalleau 		return false;
4542dea632fSFrédéric Dalleau 
4552dea632fSFrédéric Dalleau 	return true;
456b6a0dc82SMarcel Holtmann }
457b6a0dc82SMarcel Holtmann 
hci_setup_sync(struct hci_conn * conn,__u16 handle)458b2af264aSKiran K bool hci_setup_sync(struct hci_conn *conn, __u16 handle)
459b2af264aSKiran K {
460e07a06b4SBrian Gix 	int result;
461e07a06b4SBrian Gix 	struct conn_handle_t *conn_handle;
462e07a06b4SBrian Gix 
463e07a06b4SBrian Gix 	if (enhanced_sync_conn_capable(conn->hdev)) {
464e07a06b4SBrian Gix 		conn_handle = kzalloc(sizeof(*conn_handle), GFP_KERNEL);
465e07a06b4SBrian Gix 
466e07a06b4SBrian Gix 		if (!conn_handle)
467e07a06b4SBrian Gix 			return false;
468e07a06b4SBrian Gix 
469e07a06b4SBrian Gix 		conn_handle->conn = conn;
470e07a06b4SBrian Gix 		conn_handle->handle = handle;
471e07a06b4SBrian Gix 		result = hci_cmd_sync_queue(conn->hdev, hci_enhanced_setup_sync,
472e07a06b4SBrian Gix 					    conn_handle, NULL);
473e07a06b4SBrian Gix 		if (result < 0)
474e07a06b4SBrian Gix 			kfree(conn_handle);
475e07a06b4SBrian Gix 
476e07a06b4SBrian Gix 		return result == 0;
477e07a06b4SBrian Gix 	}
478b2af264aSKiran K 
479b2af264aSKiran K 	return hci_setup_sync_conn(conn, handle);
480b2af264aSKiran K }
481b2af264aSKiran K 
hci_le_conn_update(struct hci_conn * conn,u16 min,u16 max,u16 latency,u16 to_multiplier)4827d6ca693SJohan Hedberg u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
4837d6ca693SJohan Hedberg 		      u16 to_multiplier)
4842ce603ebSClaudio Takahasi {
4852ce603ebSClaudio Takahasi 	struct hci_dev *hdev = conn->hdev;
486f044eb05SMarcel Holtmann 	struct hci_conn_params *params;
487f044eb05SMarcel Holtmann 	struct hci_cp_le_conn_update cp;
488f044eb05SMarcel Holtmann 
489f044eb05SMarcel Holtmann 	hci_dev_lock(hdev);
490f044eb05SMarcel Holtmann 
491f044eb05SMarcel Holtmann 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
492f044eb05SMarcel Holtmann 	if (params) {
493f044eb05SMarcel Holtmann 		params->conn_min_interval = min;
494f044eb05SMarcel Holtmann 		params->conn_max_interval = max;
495f044eb05SMarcel Holtmann 		params->conn_latency = latency;
496f044eb05SMarcel Holtmann 		params->supervision_timeout = to_multiplier;
497f044eb05SMarcel Holtmann 	}
498f044eb05SMarcel Holtmann 
499f044eb05SMarcel Holtmann 	hci_dev_unlock(hdev);
5002ce603ebSClaudio Takahasi 
5012ce603ebSClaudio Takahasi 	memset(&cp, 0, sizeof(cp));
5022ce603ebSClaudio Takahasi 	cp.handle		= cpu_to_le16(conn->handle);
5032ce603ebSClaudio Takahasi 	cp.conn_interval_min	= cpu_to_le16(min);
5042ce603ebSClaudio Takahasi 	cp.conn_interval_max	= cpu_to_le16(max);
5052ce603ebSClaudio Takahasi 	cp.conn_latency		= cpu_to_le16(latency);
5062ce603ebSClaudio Takahasi 	cp.supervision_timeout	= cpu_to_le16(to_multiplier);
507dcf4adbfSJoe Perches 	cp.min_ce_len		= cpu_to_le16(0x0000);
508dcf4adbfSJoe Perches 	cp.max_ce_len		= cpu_to_le16(0x0000);
5092ce603ebSClaudio Takahasi 
5102ce603ebSClaudio Takahasi 	hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp);
5117d6ca693SJohan Hedberg 
5127d6ca693SJohan Hedberg 	if (params)
5137d6ca693SJohan Hedberg 		return 0x01;
5147d6ca693SJohan Hedberg 
5157d6ca693SJohan Hedberg 	return 0x00;
5162ce603ebSClaudio Takahasi }
5172ce603ebSClaudio Takahasi 
hci_le_start_enc(struct hci_conn * conn,__le16 ediv,__le64 rand,__u8 ltk[16],__u8 key_size)518fe39c7b2SMarcel Holtmann void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
5198b76ce34SJohan Hedberg 		      __u8 ltk[16], __u8 key_size)
520a7a595f6SVinicius Costa Gomes {
521a7a595f6SVinicius Costa Gomes 	struct hci_dev *hdev = conn->hdev;
522a7a595f6SVinicius Costa Gomes 	struct hci_cp_le_start_enc cp;
523a7a595f6SVinicius Costa Gomes 
52438b3fef1SAndrei Emeltchenko 	BT_DBG("hcon %p", conn);
525a7a595f6SVinicius Costa Gomes 
526a7a595f6SVinicius Costa Gomes 	memset(&cp, 0, sizeof(cp));
527a7a595f6SVinicius Costa Gomes 
528a7a595f6SVinicius Costa Gomes 	cp.handle = cpu_to_le16(conn->handle);
529fe39c7b2SMarcel Holtmann 	cp.rand = rand;
530a7a595f6SVinicius Costa Gomes 	cp.ediv = ediv;
5318b76ce34SJohan Hedberg 	memcpy(cp.ltk, ltk, key_size);
532a7a595f6SVinicius Costa Gomes 
533a7a595f6SVinicius Costa Gomes 	hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp);
534a7a595f6SVinicius Costa Gomes }
535a7a595f6SVinicius Costa Gomes 
536e73439d8SMarcel Holtmann /* Device _must_ be locked */
hci_sco_setup(struct hci_conn * conn,__u8 status)537e73439d8SMarcel Holtmann void hci_sco_setup(struct hci_conn *conn, __u8 status)
538e73439d8SMarcel Holtmann {
53906149746SLuiz Augusto von Dentz 	struct hci_link *link;
540e73439d8SMarcel Holtmann 
54106149746SLuiz Augusto von Dentz 	link = list_first_entry_or_null(&conn->link_list, struct hci_link, list);
54206149746SLuiz Augusto von Dentz 	if (!link || !link->conn)
543e73439d8SMarcel Holtmann 		return;
544e73439d8SMarcel Holtmann 
54538b3fef1SAndrei Emeltchenko 	BT_DBG("hcon %p", conn);
54638b3fef1SAndrei Emeltchenko 
547e73439d8SMarcel Holtmann 	if (!status) {
548e73439d8SMarcel Holtmann 		if (lmp_esco_capable(conn->hdev))
54906149746SLuiz Augusto von Dentz 			hci_setup_sync(link->conn, conn->handle);
550e73439d8SMarcel Holtmann 		else
55106149746SLuiz Augusto von Dentz 			hci_add_sco(link->conn, conn->handle);
552e73439d8SMarcel Holtmann 	} else {
55306149746SLuiz Augusto von Dentz 		hci_connect_cfm(link->conn, status);
55406149746SLuiz Augusto von Dentz 		hci_conn_del(link->conn);
555e73439d8SMarcel Holtmann 	}
556e73439d8SMarcel Holtmann }
557e73439d8SMarcel Holtmann 
hci_conn_timeout(struct work_struct * work)55819c40e3bSGustavo F. Padovan static void hci_conn_timeout(struct work_struct *work)
5591da177e4SLinus Torvalds {
56019c40e3bSGustavo F. Padovan 	struct hci_conn *conn = container_of(work, struct hci_conn,
56119c40e3bSGustavo F. Padovan 					     disc_work.work);
5621d56dc4fSLukasz Rymanowski 	int refcnt = atomic_read(&conn->refcnt);
5631da177e4SLinus Torvalds 
56438b3fef1SAndrei Emeltchenko 	BT_DBG("hcon %p state %s", conn, state_to_string(conn->state));
5651da177e4SLinus Torvalds 
5661d56dc4fSLukasz Rymanowski 	WARN_ON(refcnt < 0);
5671d56dc4fSLukasz Rymanowski 
5681d56dc4fSLukasz Rymanowski 	/* FIXME: It was observed that in pairing failed scenario, refcnt
5691d56dc4fSLukasz Rymanowski 	 * drops below 0. Probably this is because l2cap_conn_del calls
5701d56dc4fSLukasz Rymanowski 	 * l2cap_chan_del for each channel, and inside l2cap_chan_del conn is
5711d56dc4fSLukasz Rymanowski 	 * dropped. After that loop hci_chan_del is called which also drops
5721d56dc4fSLukasz Rymanowski 	 * conn. For now make sure that ACL is alive if refcnt is higher then 0,
5731d56dc4fSLukasz Rymanowski 	 * otherwise drop it.
5741d56dc4fSLukasz Rymanowski 	 */
5751d56dc4fSLukasz Rymanowski 	if (refcnt > 0)
5761da177e4SLinus Torvalds 		return;
5771da177e4SLinus Torvalds 
57889e0ccc8SJohan Hedberg 	hci_abort_conn(conn, hci_proto_disconn_ind(conn));
5791da177e4SLinus Torvalds }
5801da177e4SLinus Torvalds 
581416dc94bSGustavo F. Padovan /* Enter sniff mode */
hci_conn_idle(struct work_struct * work)582a74a84f6SJohan Hedberg static void hci_conn_idle(struct work_struct *work)
583416dc94bSGustavo F. Padovan {
584a74a84f6SJohan Hedberg 	struct hci_conn *conn = container_of(work, struct hci_conn,
585a74a84f6SJohan Hedberg 					     idle_work.work);
586416dc94bSGustavo F. Padovan 	struct hci_dev *hdev = conn->hdev;
587416dc94bSGustavo F. Padovan 
58838b3fef1SAndrei Emeltchenko 	BT_DBG("hcon %p mode %d", conn, conn->mode);
589416dc94bSGustavo F. Padovan 
590416dc94bSGustavo F. Padovan 	if (!lmp_sniff_capable(hdev) || !lmp_sniff_capable(conn))
591416dc94bSGustavo F. Padovan 		return;
592416dc94bSGustavo F. Padovan 
593416dc94bSGustavo F. Padovan 	if (conn->mode != HCI_CM_ACTIVE || !(conn->link_policy & HCI_LP_SNIFF))
594416dc94bSGustavo F. Padovan 		return;
595416dc94bSGustavo F. Padovan 
596416dc94bSGustavo F. Padovan 	if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) {
597416dc94bSGustavo F. Padovan 		struct hci_cp_sniff_subrate cp;
598416dc94bSGustavo F. Padovan 		cp.handle             = cpu_to_le16(conn->handle);
599dcf4adbfSJoe Perches 		cp.max_latency        = cpu_to_le16(0);
600dcf4adbfSJoe Perches 		cp.min_remote_timeout = cpu_to_le16(0);
601dcf4adbfSJoe Perches 		cp.min_local_timeout  = cpu_to_le16(0);
602416dc94bSGustavo F. Padovan 		hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp);
603416dc94bSGustavo F. Padovan 	}
604416dc94bSGustavo F. Padovan 
60551a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
606416dc94bSGustavo F. Padovan 		struct hci_cp_sniff_mode cp;
607416dc94bSGustavo F. Padovan 		cp.handle       = cpu_to_le16(conn->handle);
608416dc94bSGustavo F. Padovan 		cp.max_interval = cpu_to_le16(hdev->sniff_max_interval);
609416dc94bSGustavo F. Padovan 		cp.min_interval = cpu_to_le16(hdev->sniff_min_interval);
610dcf4adbfSJoe Perches 		cp.attempt      = cpu_to_le16(4);
611dcf4adbfSJoe Perches 		cp.timeout      = cpu_to_le16(1);
612416dc94bSGustavo F. Padovan 		hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp);
613416dc94bSGustavo F. Padovan 	}
614416dc94bSGustavo F. Padovan }
615416dc94bSGustavo F. Padovan 
hci_conn_auto_accept(struct work_struct * work)6167bc18d9dSJohan Hedberg static void hci_conn_auto_accept(struct work_struct *work)
6179f61656aSJohan Hedberg {
6187bc18d9dSJohan Hedberg 	struct hci_conn *conn = container_of(work, struct hci_conn,
6197bc18d9dSJohan Hedberg 					     auto_accept_work.work);
6209f61656aSJohan Hedberg 
6217bc18d9dSJohan Hedberg 	hci_send_cmd(conn->hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst),
6229f61656aSJohan Hedberg 		     &conn->dst);
6239f61656aSJohan Hedberg }
6249f61656aSJohan Hedberg 
le_disable_advertising(struct hci_dev * hdev)625c3bed4deSSathish Narsimman static void le_disable_advertising(struct hci_dev *hdev)
626c3bed4deSSathish Narsimman {
627c3bed4deSSathish Narsimman 	if (ext_adv_capable(hdev)) {
628c3bed4deSSathish Narsimman 		struct hci_cp_le_set_ext_adv_enable cp;
629c3bed4deSSathish Narsimman 
630c3bed4deSSathish Narsimman 		cp.enable = 0x00;
631c3bed4deSSathish Narsimman 		cp.num_of_sets = 0x00;
632c3bed4deSSathish Narsimman 
633c3bed4deSSathish Narsimman 		hci_send_cmd(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE, sizeof(cp),
634c3bed4deSSathish Narsimman 			     &cp);
635c3bed4deSSathish Narsimman 	} else {
636c3bed4deSSathish Narsimman 		u8 enable = 0x00;
637c3bed4deSSathish Narsimman 		hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable),
638c3bed4deSSathish Narsimman 			     &enable);
639c3bed4deSSathish Narsimman 	}
640c3bed4deSSathish Narsimman }
641c3bed4deSSathish Narsimman 
le_conn_timeout(struct work_struct * work)6429489eca4SJohan Hedberg static void le_conn_timeout(struct work_struct *work)
6439489eca4SJohan Hedberg {
6449489eca4SJohan Hedberg 	struct hci_conn *conn = container_of(work, struct hci_conn,
6459489eca4SJohan Hedberg 					     le_conn_timeout.work);
6463c857757SJohan Hedberg 	struct hci_dev *hdev = conn->hdev;
6479489eca4SJohan Hedberg 
6489489eca4SJohan Hedberg 	BT_DBG("");
6499489eca4SJohan Hedberg 
6503c857757SJohan Hedberg 	/* We could end up here due to having done directed advertising,
6513c857757SJohan Hedberg 	 * so clean up the state if necessary. This should however only
6523c857757SJohan Hedberg 	 * happen with broken hardware or if low duty cycle was used
6533c857757SJohan Hedberg 	 * (which doesn't have a timeout of its own).
6543c857757SJohan Hedberg 	 */
6550b1db38cSJohan Hedberg 	if (conn->role == HCI_ROLE_SLAVE) {
656c3bed4deSSathish Narsimman 		/* Disable LE Advertising */
657c3bed4deSSathish Narsimman 		le_disable_advertising(hdev);
6589fa6b4cdSNiels Dossche 		hci_dev_lock(hdev);
6599b3628d7SLuiz Augusto von Dentz 		hci_conn_failed(conn, HCI_ERROR_ADVERTISING_TIMEOUT);
6609fa6b4cdSNiels Dossche 		hci_dev_unlock(hdev);
6613c857757SJohan Hedberg 		return;
6623c857757SJohan Hedberg 	}
6633c857757SJohan Hedberg 
66489e0ccc8SJohan Hedberg 	hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
6659489eca4SJohan Hedberg }
6669489eca4SJohan Hedberg 
667eca0ae4aSLuiz Augusto von Dentz struct iso_list_data {
668eca0ae4aSLuiz Augusto von Dentz 	union {
669eca0ae4aSLuiz Augusto von Dentz 		u8  cig;
670eca0ae4aSLuiz Augusto von Dentz 		u8  big;
671eca0ae4aSLuiz Augusto von Dentz 	};
672eca0ae4aSLuiz Augusto von Dentz 	union {
673eca0ae4aSLuiz Augusto von Dentz 		u8  cis;
674eca0ae4aSLuiz Augusto von Dentz 		u8  bis;
675eca0ae4aSLuiz Augusto von Dentz 		u16 sync_handle;
676eca0ae4aSLuiz Augusto von Dentz 	};
677eca0ae4aSLuiz Augusto von Dentz 	int count;
678a0bfde16SIulia Tanasescu 	bool big_term;
679fbdc4bc4SIulia Tanasescu 	bool pa_sync_term;
680f777d882SIulia Tanasescu 	bool big_sync_term;
681eca0ae4aSLuiz Augusto von Dentz };
682eca0ae4aSLuiz Augusto von Dentz 
bis_list(struct hci_conn * conn,void * data)683eca0ae4aSLuiz Augusto von Dentz static void bis_list(struct hci_conn *conn, void *data)
684eca0ae4aSLuiz Augusto von Dentz {
685eca0ae4aSLuiz Augusto von Dentz 	struct iso_list_data *d = data;
686eca0ae4aSLuiz Augusto von Dentz 
687eca0ae4aSLuiz Augusto von Dentz 	/* Skip if not broadcast/ANY address */
688eca0ae4aSLuiz Augusto von Dentz 	if (bacmp(&conn->dst, BDADDR_ANY))
689eca0ae4aSLuiz Augusto von Dentz 		return;
690eca0ae4aSLuiz Augusto von Dentz 
6910fe8c8d0SIulia Tanasescu 	if (d->big != conn->iso_qos.bcast.big || d->bis == BT_ISO_QOS_BIS_UNSET ||
6920fe8c8d0SIulia Tanasescu 	    d->bis != conn->iso_qos.bcast.bis)
693eca0ae4aSLuiz Augusto von Dentz 		return;
694eca0ae4aSLuiz Augusto von Dentz 
695eca0ae4aSLuiz Augusto von Dentz 	d->count++;
696eca0ae4aSLuiz Augusto von Dentz }
697eca0ae4aSLuiz Augusto von Dentz 
terminate_big_sync(struct hci_dev * hdev,void * data)698eca0ae4aSLuiz Augusto von Dentz static int terminate_big_sync(struct hci_dev *hdev, void *data)
699eca0ae4aSLuiz Augusto von Dentz {
700eca0ae4aSLuiz Augusto von Dentz 	struct iso_list_data *d = data;
701eca0ae4aSLuiz Augusto von Dentz 
702eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "big 0x%2.2x bis 0x%2.2x", d->big, d->bis);
703eca0ae4aSLuiz Augusto von Dentz 
704a254b90cSIulia Tanasescu 	hci_disable_per_advertising_sync(hdev, d->bis);
705eca0ae4aSLuiz Augusto von Dentz 	hci_remove_ext_adv_instance_sync(hdev, d->bis, NULL);
706eca0ae4aSLuiz Augusto von Dentz 
707a0bfde16SIulia Tanasescu 	/* Only terminate BIG if it has been created */
708a0bfde16SIulia Tanasescu 	if (!d->big_term)
709eca0ae4aSLuiz Augusto von Dentz 		return 0;
710eca0ae4aSLuiz Augusto von Dentz 
711eca0ae4aSLuiz Augusto von Dentz 	return hci_le_terminate_big_sync(hdev, d->big,
712eca0ae4aSLuiz Augusto von Dentz 					 HCI_ERROR_LOCAL_HOST_TERM);
713eca0ae4aSLuiz Augusto von Dentz }
714eca0ae4aSLuiz Augusto von Dentz 
terminate_big_destroy(struct hci_dev * hdev,void * data,int err)715eca0ae4aSLuiz Augusto von Dentz static void terminate_big_destroy(struct hci_dev *hdev, void *data, int err)
716eca0ae4aSLuiz Augusto von Dentz {
717eca0ae4aSLuiz Augusto von Dentz 	kfree(data);
718eca0ae4aSLuiz Augusto von Dentz }
719eca0ae4aSLuiz Augusto von Dentz 
hci_le_terminate_big(struct hci_dev * hdev,struct hci_conn * conn)720a0bfde16SIulia Tanasescu static int hci_le_terminate_big(struct hci_dev *hdev, struct hci_conn *conn)
721eca0ae4aSLuiz Augusto von Dentz {
722eca0ae4aSLuiz Augusto von Dentz 	struct iso_list_data *d;
7233aa21311SZhengchao Shao 	int ret;
724eca0ae4aSLuiz Augusto von Dentz 
725a0bfde16SIulia Tanasescu 	bt_dev_dbg(hdev, "big 0x%2.2x bis 0x%2.2x", conn->iso_qos.bcast.big,
726a0bfde16SIulia Tanasescu 		   conn->iso_qos.bcast.bis);
727eca0ae4aSLuiz Augusto von Dentz 
7283958e877SKang Minchul 	d = kzalloc(sizeof(*d), GFP_KERNEL);
729eca0ae4aSLuiz Augusto von Dentz 	if (!d)
730eca0ae4aSLuiz Augusto von Dentz 		return -ENOMEM;
731eca0ae4aSLuiz Augusto von Dentz 
732a0bfde16SIulia Tanasescu 	d->big = conn->iso_qos.bcast.big;
733a0bfde16SIulia Tanasescu 	d->bis = conn->iso_qos.bcast.bis;
734a0bfde16SIulia Tanasescu 	d->big_term = test_and_clear_bit(HCI_CONN_BIG_CREATED, &conn->flags);
735eca0ae4aSLuiz Augusto von Dentz 
7363aa21311SZhengchao Shao 	ret = hci_cmd_sync_queue(hdev, terminate_big_sync, d,
737eca0ae4aSLuiz Augusto von Dentz 				 terminate_big_destroy);
7383aa21311SZhengchao Shao 	if (ret)
7393aa21311SZhengchao Shao 		kfree(d);
7403aa21311SZhengchao Shao 
7413aa21311SZhengchao Shao 	return ret;
742eca0ae4aSLuiz Augusto von Dentz }
743eca0ae4aSLuiz Augusto von Dentz 
big_terminate_sync(struct hci_dev * hdev,void * data)744eca0ae4aSLuiz Augusto von Dentz static int big_terminate_sync(struct hci_dev *hdev, void *data)
745eca0ae4aSLuiz Augusto von Dentz {
746eca0ae4aSLuiz Augusto von Dentz 	struct iso_list_data *d = data;
747eca0ae4aSLuiz Augusto von Dentz 
748eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "big 0x%2.2x sync_handle 0x%4.4x", d->big,
749eca0ae4aSLuiz Augusto von Dentz 		   d->sync_handle);
750eca0ae4aSLuiz Augusto von Dentz 
751f777d882SIulia Tanasescu 	if (d->big_sync_term)
752eca0ae4aSLuiz Augusto von Dentz 		hci_le_big_terminate_sync(hdev, d->big);
753eca0ae4aSLuiz Augusto von Dentz 
754fbdc4bc4SIulia Tanasescu 	if (d->pa_sync_term)
755eca0ae4aSLuiz Augusto von Dentz 		return hci_le_pa_terminate_sync(hdev, d->sync_handle);
756fbdc4bc4SIulia Tanasescu 
757fbdc4bc4SIulia Tanasescu 	return 0;
758eca0ae4aSLuiz Augusto von Dentz }
759eca0ae4aSLuiz Augusto von Dentz 
find_bis(struct hci_conn * conn,void * data)760fcb89f12SIulia Tanasescu static void find_bis(struct hci_conn *conn, void *data)
761fcb89f12SIulia Tanasescu {
762fcb89f12SIulia Tanasescu 	struct iso_list_data *d = data;
763fcb89f12SIulia Tanasescu 
764fcb89f12SIulia Tanasescu 	/* Ignore if BIG doesn't match */
765fcb89f12SIulia Tanasescu 	if (d->big != conn->iso_qos.bcast.big)
766fcb89f12SIulia Tanasescu 		return;
767fcb89f12SIulia Tanasescu 
768fcb89f12SIulia Tanasescu 	d->count++;
769fcb89f12SIulia Tanasescu }
770fcb89f12SIulia Tanasescu 
hci_le_big_terminate(struct hci_dev * hdev,u8 big,struct hci_conn * conn)771f777d882SIulia Tanasescu static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *conn)
772eca0ae4aSLuiz Augusto von Dentz {
773eca0ae4aSLuiz Augusto von Dentz 	struct iso_list_data *d;
7743aa21311SZhengchao Shao 	int ret;
775eca0ae4aSLuiz Augusto von Dentz 
776f777d882SIulia Tanasescu 	bt_dev_dbg(hdev, "big 0x%2.2x sync_handle 0x%4.4x", big, conn->sync_handle);
777eca0ae4aSLuiz Augusto von Dentz 
7783958e877SKang Minchul 	d = kzalloc(sizeof(*d), GFP_KERNEL);
779eca0ae4aSLuiz Augusto von Dentz 	if (!d)
780eca0ae4aSLuiz Augusto von Dentz 		return -ENOMEM;
781eca0ae4aSLuiz Augusto von Dentz 
782fcb89f12SIulia Tanasescu 	memset(d, 0, sizeof(*d));
783eca0ae4aSLuiz Augusto von Dentz 	d->big = big;
784f777d882SIulia Tanasescu 	d->sync_handle = conn->sync_handle;
785fcb89f12SIulia Tanasescu 
786fcb89f12SIulia Tanasescu 	if (test_and_clear_bit(HCI_CONN_PA_SYNC, &conn->flags)) {
787fcb89f12SIulia Tanasescu 		hci_conn_hash_list_flag(hdev, find_bis, ISO_LINK,
788fcb89f12SIulia Tanasescu 					HCI_CONN_PA_SYNC, d);
789fcb89f12SIulia Tanasescu 
790fcb89f12SIulia Tanasescu 		if (!d->count)
791fcb89f12SIulia Tanasescu 			d->pa_sync_term = true;
792fcb89f12SIulia Tanasescu 
793fcb89f12SIulia Tanasescu 		d->count = 0;
794fcb89f12SIulia Tanasescu 	}
795fcb89f12SIulia Tanasescu 
796fcb89f12SIulia Tanasescu 	if (test_and_clear_bit(HCI_CONN_BIG_SYNC, &conn->flags)) {
797fcb89f12SIulia Tanasescu 		hci_conn_hash_list_flag(hdev, find_bis, ISO_LINK,
798fcb89f12SIulia Tanasescu 					HCI_CONN_BIG_SYNC, d);
799fcb89f12SIulia Tanasescu 
800fcb89f12SIulia Tanasescu 		if (!d->count)
801fcb89f12SIulia Tanasescu 			d->big_sync_term = true;
802fcb89f12SIulia Tanasescu 	}
803eca0ae4aSLuiz Augusto von Dentz 
8043aa21311SZhengchao Shao 	ret = hci_cmd_sync_queue(hdev, big_terminate_sync, d,
805eca0ae4aSLuiz Augusto von Dentz 				 terminate_big_destroy);
8063aa21311SZhengchao Shao 	if (ret)
8073aa21311SZhengchao Shao 		kfree(d);
8083aa21311SZhengchao Shao 
8093aa21311SZhengchao Shao 	return ret;
810eca0ae4aSLuiz Augusto von Dentz }
811eca0ae4aSLuiz Augusto von Dentz 
812eca0ae4aSLuiz Augusto von Dentz /* Cleanup BIS connection
813eca0ae4aSLuiz Augusto von Dentz  *
814eca0ae4aSLuiz Augusto von Dentz  * Detects if there any BIS left connected in a BIG
815eca0ae4aSLuiz Augusto von Dentz  * broadcaster: Remove advertising instance and terminate BIG.
816eca0ae4aSLuiz Augusto von Dentz  * broadcaster receiver: Teminate BIG sync and terminate PA sync.
817eca0ae4aSLuiz Augusto von Dentz  */
bis_cleanup(struct hci_conn * conn)818eca0ae4aSLuiz Augusto von Dentz static void bis_cleanup(struct hci_conn *conn)
819eca0ae4aSLuiz Augusto von Dentz {
820eca0ae4aSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
821a0bfde16SIulia Tanasescu 	struct hci_conn *bis;
822eca0ae4aSLuiz Augusto von Dentz 
823eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
824eca0ae4aSLuiz Augusto von Dentz 
825eca0ae4aSLuiz Augusto von Dentz 	if (conn->role == HCI_ROLE_MASTER) {
826eca0ae4aSLuiz Augusto von Dentz 		if (!test_and_clear_bit(HCI_CONN_PER_ADV, &conn->flags))
827eca0ae4aSLuiz Augusto von Dentz 			return;
828eca0ae4aSLuiz Augusto von Dentz 
829a0bfde16SIulia Tanasescu 		/* Check if ISO connection is a BIS and terminate advertising
830a0bfde16SIulia Tanasescu 		 * set and BIG if there are no other connections using it.
831a0bfde16SIulia Tanasescu 		 */
8326a42e9bfSIulia Tanasescu 		bis = hci_conn_hash_lookup_big(hdev, conn->iso_qos.bcast.big);
833a0bfde16SIulia Tanasescu 		if (bis)
834a0bfde16SIulia Tanasescu 			return;
835a0bfde16SIulia Tanasescu 
836a0bfde16SIulia Tanasescu 		hci_le_terminate_big(hdev, conn);
837eca0ae4aSLuiz Augusto von Dentz 	} else {
8380fe8c8d0SIulia Tanasescu 		hci_le_big_terminate(hdev, conn->iso_qos.bcast.big,
839f777d882SIulia Tanasescu 				     conn);
840eca0ae4aSLuiz Augusto von Dentz 	}
841eca0ae4aSLuiz Augusto von Dentz }
842eca0ae4aSLuiz Augusto von Dentz 
remove_cig_sync(struct hci_dev * hdev,void * data)843eca0ae4aSLuiz Augusto von Dentz static int remove_cig_sync(struct hci_dev *hdev, void *data)
844eca0ae4aSLuiz Augusto von Dentz {
845a1f6c3aeSLuiz Augusto von Dentz 	u8 handle = PTR_UINT(data);
846eca0ae4aSLuiz Augusto von Dentz 
847eca0ae4aSLuiz Augusto von Dentz 	return hci_le_remove_cig_sync(hdev, handle);
848eca0ae4aSLuiz Augusto von Dentz }
849eca0ae4aSLuiz Augusto von Dentz 
hci_le_remove_cig(struct hci_dev * hdev,u8 handle)850eca0ae4aSLuiz Augusto von Dentz static int hci_le_remove_cig(struct hci_dev *hdev, u8 handle)
851eca0ae4aSLuiz Augusto von Dentz {
852eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%2.2x", handle);
853eca0ae4aSLuiz Augusto von Dentz 
854a1f6c3aeSLuiz Augusto von Dentz 	return hci_cmd_sync_queue(hdev, remove_cig_sync, UINT_PTR(handle),
855a1f6c3aeSLuiz Augusto von Dentz 				  NULL);
856eca0ae4aSLuiz Augusto von Dentz }
857eca0ae4aSLuiz Augusto von Dentz 
find_cis(struct hci_conn * conn,void * data)858eca0ae4aSLuiz Augusto von Dentz static void find_cis(struct hci_conn *conn, void *data)
859eca0ae4aSLuiz Augusto von Dentz {
860eca0ae4aSLuiz Augusto von Dentz 	struct iso_list_data *d = data;
861eca0ae4aSLuiz Augusto von Dentz 
86231c5f916SPauli Virtanen 	/* Ignore broadcast or if CIG don't match */
86331c5f916SPauli Virtanen 	if (!bacmp(&conn->dst, BDADDR_ANY) || d->cig != conn->iso_qos.ucast.cig)
864eca0ae4aSLuiz Augusto von Dentz 		return;
865eca0ae4aSLuiz Augusto von Dentz 
866eca0ae4aSLuiz Augusto von Dentz 	d->count++;
867eca0ae4aSLuiz Augusto von Dentz }
868eca0ae4aSLuiz Augusto von Dentz 
869eca0ae4aSLuiz Augusto von Dentz /* Cleanup CIS connection:
870eca0ae4aSLuiz Augusto von Dentz  *
871eca0ae4aSLuiz Augusto von Dentz  * Detects if there any CIS left connected in a CIG and remove it.
872eca0ae4aSLuiz Augusto von Dentz  */
cis_cleanup(struct hci_conn * conn)873eca0ae4aSLuiz Augusto von Dentz static void cis_cleanup(struct hci_conn *conn)
874eca0ae4aSLuiz Augusto von Dentz {
875eca0ae4aSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
876eca0ae4aSLuiz Augusto von Dentz 	struct iso_list_data d;
877eca0ae4aSLuiz Augusto von Dentz 
87831c5f916SPauli Virtanen 	if (conn->iso_qos.ucast.cig == BT_ISO_QOS_CIG_UNSET)
87931c5f916SPauli Virtanen 		return;
88031c5f916SPauli Virtanen 
881eca0ae4aSLuiz Augusto von Dentz 	memset(&d, 0, sizeof(d));
8820fe8c8d0SIulia Tanasescu 	d.cig = conn->iso_qos.ucast.cig;
883eca0ae4aSLuiz Augusto von Dentz 
884eca0ae4aSLuiz Augusto von Dentz 	/* Check if ISO connection is a CIS and remove CIG if there are
885eca0ae4aSLuiz Augusto von Dentz 	 * no other connections using it.
886eca0ae4aSLuiz Augusto von Dentz 	 */
8876c242c64SPauli Virtanen 	hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, BT_BOUND, &d);
8886c242c64SPauli Virtanen 	hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, BT_CONNECT, &d);
889eca0ae4aSLuiz Augusto von Dentz 	hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, BT_CONNECTED, &d);
890eca0ae4aSLuiz Augusto von Dentz 	if (d.count)
891eca0ae4aSLuiz Augusto von Dentz 		return;
892eca0ae4aSLuiz Augusto von Dentz 
8930fe8c8d0SIulia Tanasescu 	hci_le_remove_cig(hdev, conn->iso_qos.ucast.cig);
894eca0ae4aSLuiz Augusto von Dentz }
895eca0ae4aSLuiz Augusto von Dentz 
hci_conn_hash_alloc_unset(struct hci_dev * hdev)896181a42edSZiyang Xuan static int hci_conn_hash_alloc_unset(struct hci_dev *hdev)
8979f78191cSLuiz Augusto von Dentz {
898181a42edSZiyang Xuan 	return ida_alloc_range(&hdev->unset_handle_ida, HCI_CONN_HANDLE_MAX + 1,
899181a42edSZiyang Xuan 			       U16_MAX, GFP_ATOMIC);
9009f78191cSLuiz Augusto von Dentz }
9019f78191cSLuiz Augusto von Dentz 
hci_conn_add(struct hci_dev * hdev,int type,bdaddr_t * dst,u8 role,u16 handle)902a5c4e309SJohan Hedberg struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
903181a42edSZiyang Xuan 			      u8 role, u16 handle)
9041da177e4SLinus Torvalds {
9051da177e4SLinus Torvalds 	struct hci_conn *conn;
9061da177e4SLinus Torvalds 
907a5b862c6SSungwoo Kim 	switch (type) {
908a5b862c6SSungwoo Kim 	case ACL_LINK:
909a5b862c6SSungwoo Kim 		if (!hdev->acl_mtu)
910a5b862c6SSungwoo Kim 			return ERR_PTR(-ECONNREFUSED);
911a5b862c6SSungwoo Kim 		break;
912a5b862c6SSungwoo Kim 	case ISO_LINK:
913a5b862c6SSungwoo Kim 		if (hdev->iso_mtu)
914a5b862c6SSungwoo Kim 			/* Dedicated ISO Buffer exists */
915a5b862c6SSungwoo Kim 			break;
916a5b862c6SSungwoo Kim 		fallthrough;
917a5b862c6SSungwoo Kim 	case LE_LINK:
918a5b862c6SSungwoo Kim 		if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
919a5b862c6SSungwoo Kim 			return ERR_PTR(-ECONNREFUSED);
920a5b862c6SSungwoo Kim 		if (!hdev->le_mtu && hdev->acl_mtu < HCI_MIN_LE_MTU)
921a5b862c6SSungwoo Kim 			return ERR_PTR(-ECONNREFUSED);
922a5b862c6SSungwoo Kim 		break;
923a5b862c6SSungwoo Kim 	case SCO_LINK:
924a5b862c6SSungwoo Kim 	case ESCO_LINK:
925a5b862c6SSungwoo Kim 		if (!hdev->sco_pkts)
926a5b862c6SSungwoo Kim 			/* Controller does not support SCO or eSCO over HCI */
927a5b862c6SSungwoo Kim 			return ERR_PTR(-ECONNREFUSED);
928a5b862c6SSungwoo Kim 		break;
929a5b862c6SSungwoo Kim 	default:
930a5b862c6SSungwoo Kim 		return ERR_PTR(-ECONNREFUSED);
931a5b862c6SSungwoo Kim 	}
932a5b862c6SSungwoo Kim 
933181a42edSZiyang Xuan 	bt_dev_dbg(hdev, "dst %pMR handle 0x%4.4x", dst, handle);
9341da177e4SLinus Torvalds 
93527f70f3eSJohan Hedberg 	conn = kzalloc(sizeof(*conn), GFP_KERNEL);
93604837f64SMarcel Holtmann 	if (!conn)
937a5b862c6SSungwoo Kim 		return ERR_PTR(-ENOMEM);
9381da177e4SLinus Torvalds 
9391da177e4SLinus Torvalds 	bacpy(&conn->dst, dst);
940662e8820SMarcel Holtmann 	bacpy(&conn->src, &hdev->bdaddr);
941181a42edSZiyang Xuan 	conn->handle = handle;
9421da177e4SLinus Torvalds 	conn->hdev  = hdev;
94304837f64SMarcel Holtmann 	conn->type  = type;
944a5c4e309SJohan Hedberg 	conn->role  = role;
94504837f64SMarcel Holtmann 	conn->mode  = HCI_CM_ACTIVE;
9461da177e4SLinus Torvalds 	conn->state = BT_OPEN;
94793f19c9fSAndrei Emeltchenko 	conn->auth_type = HCI_AT_GENERAL_BONDING;
94817fa4b9dSJohan Hedberg 	conn->io_capability = hdev->io_capability;
949a9583556SJohan Hedberg 	conn->remote_auth = 0xff;
95013d39315SWaldemar Rymarkiewicz 	conn->key_type = 0xff;
951ebf86aa3SJohan Hedberg 	conn->rssi = HCI_RSSI_INVALID;
9525a134faeSAndrzej Kaczmarek 	conn->tx_power = HCI_TX_POWER_INVALID;
953d0455ed9SAndrzej Kaczmarek 	conn->max_tx_power = HCI_TX_POWER_INVALID;
9541d11d70dSIulia Tanasescu 	conn->sync_handle = HCI_SYNC_HANDLE_INVALID;
9551da177e4SLinus Torvalds 
95658a681efSJohan Hedberg 	set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
957052b30b0SMarcel Holtmann 	conn->disc_timeout = HCI_DISCONN_TIMEOUT;
95804837f64SMarcel Holtmann 
959302975cbSSpoorthi Ravishankar Koppad 	/* Set Default Authenticated payload timeout to 30s */
960302975cbSSpoorthi Ravishankar Koppad 	conn->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT;
961302975cbSSpoorthi Ravishankar Koppad 
962a5c4e309SJohan Hedberg 	if (conn->role == HCI_ROLE_MASTER)
963a5c4e309SJohan Hedberg 		conn->out = true;
964a5c4e309SJohan Hedberg 
965a8746417SMarcel Holtmann 	switch (type) {
966a8746417SMarcel Holtmann 	case ACL_LINK:
967a8746417SMarcel Holtmann 		conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK;
968a5b862c6SSungwoo Kim 		conn->mtu = hdev->acl_mtu;
969a8746417SMarcel Holtmann 		break;
9709c84d1daSJohan Hedberg 	case LE_LINK:
971eca0ae4aSLuiz Augusto von Dentz 		/* conn->src should reflect the local identity address */
972eca0ae4aSLuiz Augusto von Dentz 		hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
973a5b862c6SSungwoo Kim 		conn->mtu = hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu;
974eca0ae4aSLuiz Augusto von Dentz 		break;
97526afbd82SLuiz Augusto von Dentz 	case ISO_LINK:
9769c84d1daSJohan Hedberg 		/* conn->src should reflect the local identity address */
9779c84d1daSJohan Hedberg 		hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
978eca0ae4aSLuiz Augusto von Dentz 
979eca0ae4aSLuiz Augusto von Dentz 		/* set proper cleanup function */
980eca0ae4aSLuiz Augusto von Dentz 		if (!bacmp(dst, BDADDR_ANY))
981eca0ae4aSLuiz Augusto von Dentz 			conn->cleanup = bis_cleanup;
982eca0ae4aSLuiz Augusto von Dentz 		else if (conn->role == HCI_ROLE_MASTER)
983eca0ae4aSLuiz Augusto von Dentz 			conn->cleanup = cis_cleanup;
984eca0ae4aSLuiz Augusto von Dentz 
985a5b862c6SSungwoo Kim 		conn->mtu = hdev->iso_mtu ? hdev->iso_mtu :
986a5b862c6SSungwoo Kim 			    hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu;
9879c84d1daSJohan Hedberg 		break;
988a8746417SMarcel Holtmann 	case SCO_LINK:
989a8746417SMarcel Holtmann 		if (lmp_esco_capable(hdev))
990efc7688bSMarcel Holtmann 			conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
991efc7688bSMarcel Holtmann 					(hdev->esco_type & EDR_ESCO_MASK);
992a8746417SMarcel Holtmann 		else
993a8746417SMarcel Holtmann 			conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK;
994a5b862c6SSungwoo Kim 
995a5b862c6SSungwoo Kim 		conn->mtu = hdev->sco_mtu;
996a8746417SMarcel Holtmann 		break;
997a8746417SMarcel Holtmann 	case ESCO_LINK:
998efc7688bSMarcel Holtmann 		conn->pkt_type = hdev->esco_type & ~EDR_ESCO_MASK;
999a5b862c6SSungwoo Kim 		conn->mtu = hdev->sco_mtu;
1000a8746417SMarcel Holtmann 		break;
1001a8746417SMarcel Holtmann 	}
1002a8746417SMarcel Holtmann 
10031da177e4SLinus Torvalds 	skb_queue_head_init(&conn->data_q);
100404837f64SMarcel Holtmann 
100570c1f20bSMarcel Holtmann 	INIT_LIST_HEAD(&conn->chan_list);
100606149746SLuiz Augusto von Dentz 	INIT_LIST_HEAD(&conn->link_list);
100773d80debSLuiz Augusto von Dentz 
100819c40e3bSGustavo F. Padovan 	INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout);
10097bc18d9dSJohan Hedberg 	INIT_DELAYED_WORK(&conn->auto_accept_work, hci_conn_auto_accept);
1010a74a84f6SJohan Hedberg 	INIT_DELAYED_WORK(&conn->idle_work, hci_conn_idle);
10119489eca4SJohan Hedberg 	INIT_DELAYED_WORK(&conn->le_conn_timeout, le_conn_timeout);
10121da177e4SLinus Torvalds 
10131da177e4SLinus Torvalds 	atomic_set(&conn->refcnt, 0);
10141da177e4SLinus Torvalds 
10151da177e4SLinus Torvalds 	hci_dev_hold(hdev);
10161da177e4SLinus Torvalds 
10171da177e4SLinus Torvalds 	hci_conn_hash_add(hdev, conn);
10181f8330eaSSathish Narsimman 
10191f8330eaSSathish Narsimman 	/* The SCO and eSCO connections will only be notified when their
10201f8330eaSSathish Narsimman 	 * setup has been completed. This is different to ACL links which
10211f8330eaSSathish Narsimman 	 * can be notified right away.
10221f8330eaSSathish Narsimman 	 */
10231f8330eaSSathish Narsimman 	if (conn->type != SCO_LINK && conn->type != ESCO_LINK) {
10243c54711cSGustavo F. Padovan 		if (hdev->notify)
10251da177e4SLinus Torvalds 			hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
10261f8330eaSSathish Narsimman 	}
10271da177e4SLinus Torvalds 
1028a67e899cSMarcel Holtmann 	hci_conn_init_sysfs(conn);
1029a67e899cSMarcel Holtmann 
10301da177e4SLinus Torvalds 	return conn;
10311da177e4SLinus Torvalds }
10321da177e4SLinus Torvalds 
hci_conn_add_unset(struct hci_dev * hdev,int type,bdaddr_t * dst,u8 role)1033181a42edSZiyang Xuan struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type,
1034181a42edSZiyang Xuan 				    bdaddr_t *dst, u8 role)
1035181a42edSZiyang Xuan {
1036181a42edSZiyang Xuan 	int handle;
1037181a42edSZiyang Xuan 
1038181a42edSZiyang Xuan 	bt_dev_dbg(hdev, "dst %pMR", dst);
1039181a42edSZiyang Xuan 
1040181a42edSZiyang Xuan 	handle = hci_conn_hash_alloc_unset(hdev);
1041181a42edSZiyang Xuan 	if (unlikely(handle < 0))
1042a5b862c6SSungwoo Kim 		return ERR_PTR(-ECONNREFUSED);
1043181a42edSZiyang Xuan 
1044181a42edSZiyang Xuan 	return hci_conn_add(hdev, type, dst, role, handle);
1045181a42edSZiyang Xuan }
1046181a42edSZiyang Xuan 
hci_conn_cleanup_child(struct hci_conn * conn,u8 reason)10473344d318SPauli Virtanen static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason)
10483344d318SPauli Virtanen {
10493344d318SPauli Virtanen 	if (!reason)
10503344d318SPauli Virtanen 		reason = HCI_ERROR_REMOTE_USER_TERM;
10513344d318SPauli Virtanen 
10523344d318SPauli Virtanen 	/* Due to race, SCO/ISO conn might be not established yet at this point,
10533344d318SPauli Virtanen 	 * and nothing else will clean it up. In other cases it is done via HCI
10543344d318SPauli Virtanen 	 * events.
10553344d318SPauli Virtanen 	 */
10563344d318SPauli Virtanen 	switch (conn->type) {
10573344d318SPauli Virtanen 	case SCO_LINK:
10583344d318SPauli Virtanen 	case ESCO_LINK:
10593344d318SPauli Virtanen 		if (HCI_CONN_HANDLE_UNSET(conn->handle))
10603344d318SPauli Virtanen 			hci_conn_failed(conn, reason);
10613344d318SPauli Virtanen 		break;
10623344d318SPauli Virtanen 	case ISO_LINK:
1063fa224d0cSIulia Tanasescu 		if ((conn->state != BT_CONNECTED &&
1064fa224d0cSIulia Tanasescu 		    !test_bit(HCI_CONN_CREATE_CIS, &conn->flags)) ||
1065fa224d0cSIulia Tanasescu 		    test_bit(HCI_CONN_BIG_CREATED, &conn->flags))
10663344d318SPauli Virtanen 			hci_conn_failed(conn, reason);
10673344d318SPauli Virtanen 		break;
10683344d318SPauli Virtanen 	}
10693344d318SPauli Virtanen }
10703344d318SPauli Virtanen 
hci_conn_unlink(struct hci_conn * conn)107106149746SLuiz Augusto von Dentz static void hci_conn_unlink(struct hci_conn *conn)
10725dc7d23eSLuiz Augusto von Dentz {
107306149746SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
10745dc7d23eSLuiz Augusto von Dentz 
107506149746SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "hcon %p", conn);
107606149746SLuiz Augusto von Dentz 
107706149746SLuiz Augusto von Dentz 	if (!conn->parent) {
107806149746SLuiz Augusto von Dentz 		struct hci_link *link, *t;
107906149746SLuiz Augusto von Dentz 
1080ca1fd42eSRuihan Li 		list_for_each_entry_safe(link, t, &conn->link_list, list) {
1081ca1fd42eSRuihan Li 			struct hci_conn *child = link->conn;
1082ca1fd42eSRuihan Li 
1083ca1fd42eSRuihan Li 			hci_conn_unlink(child);
1084ca1fd42eSRuihan Li 
1085a2ac591cSRuihan Li 			/* If hdev is down it means
1086a2ac591cSRuihan Li 			 * hci_dev_close_sync/hci_conn_hash_flush is in progress
1087a2ac591cSRuihan Li 			 * and links don't need to be cleanup as all connections
1088a2ac591cSRuihan Li 			 * would be cleanup.
1089a2ac591cSRuihan Li 			 */
1090a2ac591cSRuihan Li 			if (!test_bit(HCI_UP, &hdev->flags))
1091a2ac591cSRuihan Li 				continue;
1092a2ac591cSRuihan Li 
10933344d318SPauli Virtanen 			hci_conn_cleanup_child(child, conn->abort_reason);
1094ca1fd42eSRuihan Li 		}
109506149746SLuiz Augusto von Dentz 
109606149746SLuiz Augusto von Dentz 		return;
109706149746SLuiz Augusto von Dentz 	}
109806149746SLuiz Augusto von Dentz 
109906149746SLuiz Augusto von Dentz 	if (!conn->link)
110006149746SLuiz Augusto von Dentz 		return;
110106149746SLuiz Augusto von Dentz 
110206149746SLuiz Augusto von Dentz 	list_del_rcu(&conn->link->list);
110306149746SLuiz Augusto von Dentz 	synchronize_rcu();
110406149746SLuiz Augusto von Dentz 
1105a2904d28SRuihan Li 	hci_conn_drop(conn->parent);
11062910431aSRuihan Li 	hci_conn_put(conn->parent);
11072910431aSRuihan Li 	conn->parent = NULL;
11082910431aSRuihan Li 
110906149746SLuiz Augusto von Dentz 	kfree(conn->link);
11105dc7d23eSLuiz Augusto von Dentz 	conn->link = NULL;
11115dc7d23eSLuiz Augusto von Dentz }
11125dc7d23eSLuiz Augusto von Dentz 
hci_conn_del(struct hci_conn * conn)1113a2ac591cSRuihan Li void hci_conn_del(struct hci_conn *conn)
11141da177e4SLinus Torvalds {
11151da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
11161da177e4SLinus Torvalds 
111738b3fef1SAndrei Emeltchenko 	BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle);
11181da177e4SLinus Torvalds 
1119a2904d28SRuihan Li 	hci_conn_unlink(conn);
1120a2904d28SRuihan Li 
112119c40e3bSGustavo F. Padovan 	cancel_delayed_work_sync(&conn->disc_work);
11227bc18d9dSJohan Hedberg 	cancel_delayed_work_sync(&conn->auto_accept_work);
1123a74a84f6SJohan Hedberg 	cancel_delayed_work_sync(&conn->idle_work);
11249f61656aSJohan Hedberg 
11255b7f9909SMarcel Holtmann 	if (conn->type == ACL_LINK) {
11261da177e4SLinus Torvalds 		/* Unacked frames */
11271da177e4SLinus Torvalds 		hdev->acl_cnt += conn->sent;
11286ed58ec5SVille Tervo 	} else if (conn->type == LE_LINK) {
1129980ffc0aSJohan Hedberg 		cancel_delayed_work(&conn->le_conn_timeout);
11309489eca4SJohan Hedberg 
11316ed58ec5SVille Tervo 		if (hdev->le_pkts)
11326ed58ec5SVille Tervo 			hdev->le_cnt += conn->sent;
11336ed58ec5SVille Tervo 		else
11346ed58ec5SVille Tervo 			hdev->acl_cnt += conn->sent;
11355b7f9909SMarcel Holtmann 	} else {
11365638d9eaSLuiz Augusto von Dentz 		/* Unacked ISO frames */
11375638d9eaSLuiz Augusto von Dentz 		if (conn->type == ISO_LINK) {
11385638d9eaSLuiz Augusto von Dentz 			if (hdev->iso_pkts)
11395638d9eaSLuiz Augusto von Dentz 				hdev->iso_cnt += conn->sent;
11405638d9eaSLuiz Augusto von Dentz 			else if (hdev->le_pkts)
11415638d9eaSLuiz Augusto von Dentz 				hdev->le_cnt += conn->sent;
11425638d9eaSLuiz Augusto von Dentz 			else
11435638d9eaSLuiz Augusto von Dentz 				hdev->acl_cnt += conn->sent;
11445638d9eaSLuiz Augusto von Dentz 		}
11451da177e4SLinus Torvalds 	}
11461da177e4SLinus Torvalds 
11471da177e4SLinus Torvalds 	skb_queue_purge(&conn->data_q);
11481da177e4SLinus Torvalds 
1149b958f9a3SJohan Hedberg 	/* Remove the connection from the list and cleanup its remaining
1150b958f9a3SJohan Hedberg 	 * state. This is a separate function since for some cases like
1151b958f9a3SJohan Hedberg 	 * BT_CONNECT_SCAN we *only* want the cleanup part without the
1152b958f9a3SJohan Hedberg 	 * rest of hci_conn_del.
1153b958f9a3SJohan Hedberg 	 */
1154b958f9a3SJohan Hedberg 	hci_conn_cleanup(conn);
1155881559afSLuiz Augusto von Dentz 
1156881559afSLuiz Augusto von Dentz 	/* Dequeue callbacks using connection pointer as data */
1157881559afSLuiz Augusto von Dentz 	hci_cmd_sync_dequeue(hdev, NULL, conn, NULL);
11581da177e4SLinus Torvalds }
11591da177e4SLinus Torvalds 
hci_get_route(bdaddr_t * dst,bdaddr_t * src,uint8_t src_type)116039385cb5SJohan Hedberg struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src, uint8_t src_type)
11611da177e4SLinus Torvalds {
11621da177e4SLinus Torvalds 	int use_src = bacmp(src, BDADDR_ANY);
11638035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
11641da177e4SLinus Torvalds 
11656ed93dc6SAndrei Emeltchenko 	BT_DBG("%pMR -> %pMR", src, dst);
11661da177e4SLinus Torvalds 
1167f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
11681da177e4SLinus Torvalds 
11698035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
11708fc9ced3SGustavo Padovan 		if (!test_bit(HCI_UP, &d->flags) ||
1171*84a4bb65SLuiz Augusto von Dentz 		    hci_dev_test_flag(d, HCI_USER_CHANNEL))
11721da177e4SLinus Torvalds 			continue;
11731da177e4SLinus Torvalds 
11741da177e4SLinus Torvalds 		/* Simple routing:
11751da177e4SLinus Torvalds 		 *   No source address - find interface with bdaddr != dst
11761da177e4SLinus Torvalds 		 *   Source address    - find interface with bdaddr == src
11771da177e4SLinus Torvalds 		 */
11781da177e4SLinus Torvalds 
11791da177e4SLinus Torvalds 		if (use_src) {
118039385cb5SJohan Hedberg 			bdaddr_t id_addr;
118139385cb5SJohan Hedberg 			u8 id_addr_type;
118239385cb5SJohan Hedberg 
118339385cb5SJohan Hedberg 			if (src_type == BDADDR_BREDR) {
118439385cb5SJohan Hedberg 				if (!lmp_bredr_capable(d))
118539385cb5SJohan Hedberg 					continue;
118639385cb5SJohan Hedberg 				bacpy(&id_addr, &d->bdaddr);
118739385cb5SJohan Hedberg 				id_addr_type = BDADDR_BREDR;
118839385cb5SJohan Hedberg 			} else {
118939385cb5SJohan Hedberg 				if (!lmp_le_capable(d))
119039385cb5SJohan Hedberg 					continue;
119139385cb5SJohan Hedberg 
119239385cb5SJohan Hedberg 				hci_copy_identity_address(d, &id_addr,
119339385cb5SJohan Hedberg 							  &id_addr_type);
119439385cb5SJohan Hedberg 
119539385cb5SJohan Hedberg 				/* Convert from HCI to three-value type */
119639385cb5SJohan Hedberg 				if (id_addr_type == ADDR_LE_DEV_PUBLIC)
119739385cb5SJohan Hedberg 					id_addr_type = BDADDR_LE_PUBLIC;
119839385cb5SJohan Hedberg 				else
119939385cb5SJohan Hedberg 					id_addr_type = BDADDR_LE_RANDOM;
120039385cb5SJohan Hedberg 			}
120139385cb5SJohan Hedberg 
120239385cb5SJohan Hedberg 			if (!bacmp(&id_addr, src) && id_addr_type == src_type) {
12031da177e4SLinus Torvalds 				hdev = d; break;
12041da177e4SLinus Torvalds 			}
12051da177e4SLinus Torvalds 		} else {
12061da177e4SLinus Torvalds 			if (bacmp(&d->bdaddr, dst)) {
12071da177e4SLinus Torvalds 				hdev = d; break;
12081da177e4SLinus Torvalds 			}
12091da177e4SLinus Torvalds 		}
12101da177e4SLinus Torvalds 	}
12111da177e4SLinus Torvalds 
12121da177e4SLinus Torvalds 	if (hdev)
12131da177e4SLinus Torvalds 		hdev = hci_dev_hold(hdev);
12141da177e4SLinus Torvalds 
1215f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
12161da177e4SLinus Torvalds 	return hdev;
12171da177e4SLinus Torvalds }
12181da177e4SLinus Torvalds EXPORT_SYMBOL(hci_get_route);
12191da177e4SLinus Torvalds 
12209bb3c01fSAndre Guedes /* This function requires the caller holds hdev->lock */
hci_le_conn_failed(struct hci_conn * conn,u8 status)12219b3628d7SLuiz Augusto von Dentz static void hci_le_conn_failed(struct hci_conn *conn, u8 status)
12229bb3c01fSAndre Guedes {
12239bb3c01fSAndre Guedes 	struct hci_dev *hdev = conn->hdev;
1224f161dd41SJohan Hedberg 
122519cf60bfSLuiz Augusto von Dentz 	hci_connect_le_scan_cleanup(conn, status);
12263c857757SJohan Hedberg 
1227abfeea47SLuiz Augusto von Dentz 	/* Enable advertising in case this was a failed connection
12283c857757SJohan Hedberg 	 * attempt as a peripheral.
12293c857757SJohan Hedberg 	 */
1230abfeea47SLuiz Augusto von Dentz 	hci_enable_advertising(hdev);
12319bb3c01fSAndre Guedes }
12329bb3c01fSAndre Guedes 
12339b3628d7SLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */
hci_conn_failed(struct hci_conn * conn,u8 status)12349b3628d7SLuiz Augusto von Dentz void hci_conn_failed(struct hci_conn *conn, u8 status)
12359b3628d7SLuiz Augusto von Dentz {
12369b3628d7SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
12379b3628d7SLuiz Augusto von Dentz 
12389b3628d7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
12399b3628d7SLuiz Augusto von Dentz 
12409b3628d7SLuiz Augusto von Dentz 	switch (conn->type) {
12419b3628d7SLuiz Augusto von Dentz 	case LE_LINK:
12429b3628d7SLuiz Augusto von Dentz 		hci_le_conn_failed(conn, status);
12439b3628d7SLuiz Augusto von Dentz 		break;
12449b3628d7SLuiz Augusto von Dentz 	case ACL_LINK:
12459b3628d7SLuiz Augusto von Dentz 		mgmt_connect_failed(hdev, &conn->dst, conn->type,
12469b3628d7SLuiz Augusto von Dentz 				    conn->dst_type, status);
12479b3628d7SLuiz Augusto von Dentz 		break;
12489b3628d7SLuiz Augusto von Dentz 	}
12499b3628d7SLuiz Augusto von Dentz 
1250a254b90cSIulia Tanasescu 	/* In case of BIG/PA sync failed, clear conn flags so that
1251a254b90cSIulia Tanasescu 	 * the conns will be correctly cleaned up by ISO layer
1252a254b90cSIulia Tanasescu 	 */
1253a254b90cSIulia Tanasescu 	test_and_clear_bit(HCI_CONN_BIG_SYNC_FAILED, &conn->flags);
1254a254b90cSIulia Tanasescu 	test_and_clear_bit(HCI_CONN_PA_SYNC_FAILED, &conn->flags);
1255a254b90cSIulia Tanasescu 
12569b3628d7SLuiz Augusto von Dentz 	conn->state = BT_CLOSED;
12579b3628d7SLuiz Augusto von Dentz 	hci_connect_cfm(conn, status);
12589b3628d7SLuiz Augusto von Dentz 	hci_conn_del(conn);
12599b3628d7SLuiz Augusto von Dentz }
12609b3628d7SLuiz Augusto von Dentz 
126116e3b642SLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */
hci_conn_set_handle(struct hci_conn * conn,u16 handle)126216e3b642SLuiz Augusto von Dentz u8 hci_conn_set_handle(struct hci_conn *conn, u16 handle)
126316e3b642SLuiz Augusto von Dentz {
126416e3b642SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
126516e3b642SLuiz Augusto von Dentz 
126616e3b642SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "hcon %p handle 0x%4.4x", conn, handle);
126716e3b642SLuiz Augusto von Dentz 
126816e3b642SLuiz Augusto von Dentz 	if (conn->handle == handle)
126916e3b642SLuiz Augusto von Dentz 		return 0;
127016e3b642SLuiz Augusto von Dentz 
127116e3b642SLuiz Augusto von Dentz 	if (handle > HCI_CONN_HANDLE_MAX) {
127216e3b642SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x",
127316e3b642SLuiz Augusto von Dentz 			   handle, HCI_CONN_HANDLE_MAX);
127416e3b642SLuiz Augusto von Dentz 		return HCI_ERROR_INVALID_PARAMETERS;
127516e3b642SLuiz Augusto von Dentz 	}
127616e3b642SLuiz Augusto von Dentz 
127716e3b642SLuiz Augusto von Dentz 	/* If abort_reason has been sent it means the connection is being
127816e3b642SLuiz Augusto von Dentz 	 * aborted and the handle shall not be changed.
127916e3b642SLuiz Augusto von Dentz 	 */
128016e3b642SLuiz Augusto von Dentz 	if (conn->abort_reason)
128116e3b642SLuiz Augusto von Dentz 		return conn->abort_reason;
128216e3b642SLuiz Augusto von Dentz 
1283181a42edSZiyang Xuan 	if (HCI_CONN_HANDLE_UNSET(conn->handle))
1284181a42edSZiyang Xuan 		ida_free(&hdev->unset_handle_ida, conn->handle);
1285181a42edSZiyang Xuan 
128616e3b642SLuiz Augusto von Dentz 	conn->handle = handle;
128716e3b642SLuiz Augusto von Dentz 
128816e3b642SLuiz Augusto von Dentz 	return 0;
128916e3b642SLuiz Augusto von Dentz }
129016e3b642SLuiz Augusto von Dentz 
hci_connect_le(struct hci_dev * hdev,bdaddr_t * dst,u8 dst_type,bool dst_resolved,u8 sec_level,u16 conn_timeout,u8 role,u8 phy,u8 sec_phy)129104a6c589SAndre Guedes struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
1292d850bf08SLuiz Augusto von Dentz 				u8 dst_type, bool dst_resolved, u8 sec_level,
12932e7ed5f5SLuiz Augusto von Dentz 				u16 conn_timeout, u8 role, u8 phy, u8 sec_phy)
12941da177e4SLinus Torvalds {
1295e2caced4SJohan Hedberg 	struct hci_conn *conn;
12961ebfcc1fSJohan Hedberg 	struct smp_irk *irk;
12971d399ae5SAndre Guedes 	int err;
12981da177e4SLinus Torvalds 
1299152d386eSLukasz Rymanowski 	/* Let's make sure that le is enabled.*/
1300d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
1301152d386eSLukasz Rymanowski 		if (lmp_le_capable(hdev))
1302152d386eSLukasz Rymanowski 			return ERR_PTR(-ECONNREFUSED);
1303152d386eSLukasz Rymanowski 
1304152d386eSLukasz Rymanowski 		return ERR_PTR(-EOPNOTSUPP);
1305152d386eSLukasz Rymanowski 	}
1306152d386eSLukasz Rymanowski 
1307658aead9SJohan Hedberg 	/* Since the controller supports only one LE connection attempt at a
1308658aead9SJohan Hedberg 	 * time, we return -EBUSY if there is any connection attempt running.
1309658aead9SJohan Hedberg 	 */
1310658aead9SJohan Hedberg 	if (hci_lookup_le_connect(hdev))
1311658aead9SJohan Hedberg 		return ERR_PTR(-EBUSY);
1312658aead9SJohan Hedberg 
1313e2caced4SJohan Hedberg 	/* If there's already a connection object but it's not in
1314e2caced4SJohan Hedberg 	 * scanning state it means it must already be established, in
1315e2caced4SJohan Hedberg 	 * which case we can't do anything else except report a failure
1316e2caced4SJohan Hedberg 	 * to connect.
1317620ad521SAndre Guedes 	 */
13189d4c1cc1SJohan Hedberg 	conn = hci_conn_hash_lookup_le(hdev, dst, dst_type);
1319e2caced4SJohan Hedberg 	if (conn && !test_bit(HCI_CONN_SCANNING, &conn->flags)) {
1320e2caced4SJohan Hedberg 		return ERR_PTR(-EBUSY);
132128a667c9SJakub Pawlowski 	}
1322620ad521SAndre Guedes 
1323d850bf08SLuiz Augusto von Dentz 	/* Check if the destination address has been resolved by the controller
1324d850bf08SLuiz Augusto von Dentz 	 * since if it did then the identity address shall be used.
1325d850bf08SLuiz Augusto von Dentz 	 */
1326d850bf08SLuiz Augusto von Dentz 	if (!dst_resolved) {
1327edb4b466SMarcel Holtmann 		/* When given an identity address with existing identity
1328edb4b466SMarcel Holtmann 		 * resolving key, the connection needs to be established
1329edb4b466SMarcel Holtmann 		 * to a resolvable random address.
1330edb4b466SMarcel Holtmann 		 *
1331edb4b466SMarcel Holtmann 		 * Storing the resolvable random address is required here
1332edb4b466SMarcel Holtmann 		 * to handle connection failures. The address will later
1333edb4b466SMarcel Holtmann 		 * be resolved back into the original identity address
1334edb4b466SMarcel Holtmann 		 * from the connect request.
1335edb4b466SMarcel Holtmann 		 */
13361ebfcc1fSJohan Hedberg 		irk = hci_find_irk_by_addr(hdev, dst, dst_type);
13371ebfcc1fSJohan Hedberg 		if (irk && bacmp(&irk->rpa, BDADDR_ANY)) {
13381ebfcc1fSJohan Hedberg 			dst = &irk->rpa;
13391ebfcc1fSJohan Hedberg 			dst_type = ADDR_LE_DEV_RANDOM;
13401ebfcc1fSJohan Hedberg 		}
1341d850bf08SLuiz Augusto von Dentz 	}
13421ebfcc1fSJohan Hedberg 
1343e2caced4SJohan Hedberg 	if (conn) {
134428a667c9SJakub Pawlowski 		bacpy(&conn->dst, dst);
134528a667c9SJakub Pawlowski 	} else {
1346181a42edSZiyang Xuan 		conn = hci_conn_add_unset(hdev, LE_LINK, dst, role);
1347a5b862c6SSungwoo Kim 		if (IS_ERR(conn))
1348a5b862c6SSungwoo Kim 			return conn;
1349e2caced4SJohan Hedberg 		hci_conn_hold(conn);
1350e2caced4SJohan Hedberg 		conn->pending_sec_level = sec_level;
1351e2caced4SJohan Hedberg 	}
1352893d6751SAndre Guedes 
13531ebfcc1fSJohan Hedberg 	conn->dst_type = dst_type;
135446a190cbSAndre Guedes 	conn->sec_level = BT_SECURITY_LOW;
135509ae260bSJohan Hedberg 	conn->conn_timeout = conn_timeout;
13562e7ed5f5SLuiz Augusto von Dentz 	conn->le_adv_phy = phy;
13572e7ed5f5SLuiz Augusto von Dentz 	conn->le_adv_sec_phy = sec_phy;
13584292f1f3SAndre Guedes 
1359881559afSLuiz Augusto von Dentz 	err = hci_connect_le_sync(hdev, conn);
13602acf3d90SAndre Guedes 	if (err) {
13612acf3d90SAndre Guedes 		hci_conn_del(conn);
13621d399ae5SAndre Guedes 		return ERR_PTR(err);
13632acf3d90SAndre Guedes 	}
13649f0caeb1SVinicius Costa Gomes 
1365f1e5d547SAndre Guedes 	return conn;
1366fcd89c09SVille Tervo }
1367fcd89c09SVille Tervo 
is_connected(struct hci_dev * hdev,bdaddr_t * addr,u8 type)1368f75113a2SJakub Pawlowski static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type)
1369f75113a2SJakub Pawlowski {
1370f75113a2SJakub Pawlowski 	struct hci_conn *conn;
1371f75113a2SJakub Pawlowski 
13729d4c1cc1SJohan Hedberg 	conn = hci_conn_hash_lookup_le(hdev, addr, type);
1373f75113a2SJakub Pawlowski 	if (!conn)
1374f75113a2SJakub Pawlowski 		return false;
1375f75113a2SJakub Pawlowski 
1376f75113a2SJakub Pawlowski 	if (conn->state != BT_CONNECTED)
1377f75113a2SJakub Pawlowski 		return false;
1378f75113a2SJakub Pawlowski 
1379f75113a2SJakub Pawlowski 	return true;
1380f75113a2SJakub Pawlowski }
1381f75113a2SJakub Pawlowski 
1382f75113a2SJakub Pawlowski /* This function requires the caller holds hdev->lock */
hci_explicit_conn_params_set(struct hci_dev * hdev,bdaddr_t * addr,u8 addr_type)138384235d22SJohan Hedberg static int hci_explicit_conn_params_set(struct hci_dev *hdev,
1384f75113a2SJakub Pawlowski 					bdaddr_t *addr, u8 addr_type)
1385f75113a2SJakub Pawlowski {
1386f75113a2SJakub Pawlowski 	struct hci_conn_params *params;
1387f75113a2SJakub Pawlowski 
1388f75113a2SJakub Pawlowski 	if (is_connected(hdev, addr, addr_type))
1389f75113a2SJakub Pawlowski 		return -EISCONN;
1390f75113a2SJakub Pawlowski 
13915157b8a5SJakub Pawlowski 	params = hci_conn_params_lookup(hdev, addr, addr_type);
13925157b8a5SJakub Pawlowski 	if (!params) {
1393f75113a2SJakub Pawlowski 		params = hci_conn_params_add(hdev, addr, addr_type);
1394f75113a2SJakub Pawlowski 		if (!params)
13955157b8a5SJakub Pawlowski 			return -ENOMEM;
1396f75113a2SJakub Pawlowski 
13975157b8a5SJakub Pawlowski 		/* If we created new params, mark them to be deleted in
13985157b8a5SJakub Pawlowski 		 * hci_connect_le_scan_cleanup. It's different case than
13995157b8a5SJakub Pawlowski 		 * existing disabled params, those will stay after cleanup.
1400f75113a2SJakub Pawlowski 		 */
14015157b8a5SJakub Pawlowski 		params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
14025157b8a5SJakub Pawlowski 	}
14035157b8a5SJakub Pawlowski 
14045157b8a5SJakub Pawlowski 	/* We're trying to connect, so make sure params are at pend_le_conns */
140549c50922SJohan Hedberg 	if (params->auto_connect == HCI_AUTO_CONN_DISABLED ||
14065157b8a5SJakub Pawlowski 	    params->auto_connect == HCI_AUTO_CONN_REPORT ||
14075157b8a5SJakub Pawlowski 	    params->auto_connect == HCI_AUTO_CONN_EXPLICIT) {
1408195ef75eSPauli Virtanen 		hci_pend_le_list_del_init(params);
1409195ef75eSPauli Virtanen 		hci_pend_le_list_add(params, &hdev->pend_le_conns);
1410f75113a2SJakub Pawlowski 	}
1411f75113a2SJakub Pawlowski 
1412f75113a2SJakub Pawlowski 	params->explicit_connect = true;
1413f75113a2SJakub Pawlowski 
1414f75113a2SJakub Pawlowski 	BT_DBG("addr %pMR (type %u) auto_connect %u", addr, addr_type,
1415f75113a2SJakub Pawlowski 	       params->auto_connect);
1416f75113a2SJakub Pawlowski 
1417f75113a2SJakub Pawlowski 	return 0;
1418f75113a2SJakub Pawlowski }
1419f75113a2SJakub Pawlowski 
qos_set_big(struct hci_dev * hdev,struct bt_iso_qos * qos)1420eca0ae4aSLuiz Augusto von Dentz static int qos_set_big(struct hci_dev *hdev, struct bt_iso_qos *qos)
1421eca0ae4aSLuiz Augusto von Dentz {
14226a42e9bfSIulia Tanasescu 	struct hci_conn *conn;
14236a42e9bfSIulia Tanasescu 	u8  big;
1424eca0ae4aSLuiz Augusto von Dentz 
1425eca0ae4aSLuiz Augusto von Dentz 	/* Allocate a BIG if not set */
14260fe8c8d0SIulia Tanasescu 	if (qos->bcast.big == BT_ISO_QOS_BIG_UNSET) {
14276a42e9bfSIulia Tanasescu 		for (big = 0x00; big < 0xef; big++) {
1428eca0ae4aSLuiz Augusto von Dentz 
14296a42e9bfSIulia Tanasescu 			conn = hci_conn_hash_lookup_big(hdev, big);
14306a42e9bfSIulia Tanasescu 			if (!conn)
1431eca0ae4aSLuiz Augusto von Dentz 				break;
1432eca0ae4aSLuiz Augusto von Dentz 		}
1433eca0ae4aSLuiz Augusto von Dentz 
14346a42e9bfSIulia Tanasescu 		if (big == 0xef)
1435eca0ae4aSLuiz Augusto von Dentz 			return -EADDRNOTAVAIL;
1436eca0ae4aSLuiz Augusto von Dentz 
1437eca0ae4aSLuiz Augusto von Dentz 		/* Update BIG */
14386a42e9bfSIulia Tanasescu 		qos->bcast.big = big;
1439eca0ae4aSLuiz Augusto von Dentz 	}
1440eca0ae4aSLuiz Augusto von Dentz 
1441eca0ae4aSLuiz Augusto von Dentz 	return 0;
1442eca0ae4aSLuiz Augusto von Dentz }
1443eca0ae4aSLuiz Augusto von Dentz 
qos_set_bis(struct hci_dev * hdev,struct bt_iso_qos * qos)1444eca0ae4aSLuiz Augusto von Dentz static int qos_set_bis(struct hci_dev *hdev, struct bt_iso_qos *qos)
1445eca0ae4aSLuiz Augusto von Dentz {
14466a42e9bfSIulia Tanasescu 	struct hci_conn *conn;
14476a42e9bfSIulia Tanasescu 	u8  bis;
1448eca0ae4aSLuiz Augusto von Dentz 
1449eca0ae4aSLuiz Augusto von Dentz 	/* Allocate BIS if not set */
14500fe8c8d0SIulia Tanasescu 	if (qos->bcast.bis == BT_ISO_QOS_BIS_UNSET) {
145171b7bb48SIulia Tanasescu 		if (qos->bcast.big != BT_ISO_QOS_BIG_UNSET) {
145271b7bb48SIulia Tanasescu 			conn = hci_conn_hash_lookup_big(hdev, qos->bcast.big);
145371b7bb48SIulia Tanasescu 
145471b7bb48SIulia Tanasescu 			if (conn) {
145571b7bb48SIulia Tanasescu 				/* If the BIG handle is already matched to an advertising
145671b7bb48SIulia Tanasescu 				 * handle, do not allocate a new one.
145771b7bb48SIulia Tanasescu 				 */
145871b7bb48SIulia Tanasescu 				qos->bcast.bis = conn->iso_qos.bcast.bis;
145971b7bb48SIulia Tanasescu 				return 0;
146071b7bb48SIulia Tanasescu 			}
146171b7bb48SIulia Tanasescu 		}
146271b7bb48SIulia Tanasescu 
1463eca0ae4aSLuiz Augusto von Dentz 		/* Find an unused adv set to advertise BIS, skip instance 0x00
1464eca0ae4aSLuiz Augusto von Dentz 		 * since it is reserved as general purpose set.
1465eca0ae4aSLuiz Augusto von Dentz 		 */
14666a42e9bfSIulia Tanasescu 		for (bis = 0x01; bis < hdev->le_num_of_adv_sets;
14676a42e9bfSIulia Tanasescu 		     bis++) {
1468eca0ae4aSLuiz Augusto von Dentz 
14696a42e9bfSIulia Tanasescu 			conn = hci_conn_hash_lookup_bis(hdev, BDADDR_ANY, bis);
14706a42e9bfSIulia Tanasescu 			if (!conn)
1471eca0ae4aSLuiz Augusto von Dentz 				break;
1472eca0ae4aSLuiz Augusto von Dentz 		}
1473eca0ae4aSLuiz Augusto von Dentz 
14746a42e9bfSIulia Tanasescu 		if (bis == hdev->le_num_of_adv_sets)
1475eca0ae4aSLuiz Augusto von Dentz 			return -EADDRNOTAVAIL;
1476eca0ae4aSLuiz Augusto von Dentz 
1477eca0ae4aSLuiz Augusto von Dentz 		/* Update BIS */
14786a42e9bfSIulia Tanasescu 		qos->bcast.bis = bis;
1479eca0ae4aSLuiz Augusto von Dentz 	}
1480eca0ae4aSLuiz Augusto von Dentz 
1481eca0ae4aSLuiz Augusto von Dentz 	return 0;
1482eca0ae4aSLuiz Augusto von Dentz }
1483eca0ae4aSLuiz Augusto von Dentz 
1484eca0ae4aSLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */
hci_add_bis(struct hci_dev * hdev,bdaddr_t * dst,struct bt_iso_qos * qos,__u8 base_len,__u8 * base)1485eca0ae4aSLuiz Augusto von Dentz static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst,
1486a0bfde16SIulia Tanasescu 				    struct bt_iso_qos *qos, __u8 base_len,
1487a0bfde16SIulia Tanasescu 				    __u8 *base)
1488eca0ae4aSLuiz Augusto von Dentz {
1489eca0ae4aSLuiz Augusto von Dentz 	struct hci_conn *conn;
1490eca0ae4aSLuiz Augusto von Dentz 	int err;
1491eca0ae4aSLuiz Augusto von Dentz 
1492eca0ae4aSLuiz Augusto von Dentz 	/* Let's make sure that le is enabled.*/
1493eca0ae4aSLuiz Augusto von Dentz 	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
1494eca0ae4aSLuiz Augusto von Dentz 		if (lmp_le_capable(hdev))
1495eca0ae4aSLuiz Augusto von Dentz 			return ERR_PTR(-ECONNREFUSED);
1496eca0ae4aSLuiz Augusto von Dentz 		return ERR_PTR(-EOPNOTSUPP);
1497eca0ae4aSLuiz Augusto von Dentz 	}
1498eca0ae4aSLuiz Augusto von Dentz 
1499eca0ae4aSLuiz Augusto von Dentz 	err = qos_set_big(hdev, qos);
1500eca0ae4aSLuiz Augusto von Dentz 	if (err)
1501eca0ae4aSLuiz Augusto von Dentz 		return ERR_PTR(err);
1502eca0ae4aSLuiz Augusto von Dentz 
1503eca0ae4aSLuiz Augusto von Dentz 	err = qos_set_bis(hdev, qos);
1504eca0ae4aSLuiz Augusto von Dentz 	if (err)
1505eca0ae4aSLuiz Augusto von Dentz 		return ERR_PTR(err);
1506eca0ae4aSLuiz Augusto von Dentz 
1507a0bfde16SIulia Tanasescu 	/* Check if the LE Create BIG command has already been sent */
1508a0bfde16SIulia Tanasescu 	conn = hci_conn_hash_lookup_per_adv_bis(hdev, dst, qos->bcast.big,
1509a0bfde16SIulia Tanasescu 						qos->bcast.big);
1510a0bfde16SIulia Tanasescu 	if (conn)
1511eca0ae4aSLuiz Augusto von Dentz 		return ERR_PTR(-EADDRINUSE);
1512eca0ae4aSLuiz Augusto von Dentz 
1513a0bfde16SIulia Tanasescu 	/* Check BIS settings against other bound BISes, since all
1514a0bfde16SIulia Tanasescu 	 * BISes in a BIG must have the same value for all parameters
1515a0bfde16SIulia Tanasescu 	 */
15166a42e9bfSIulia Tanasescu 	conn = hci_conn_hash_lookup_big(hdev, qos->bcast.big);
1517a0bfde16SIulia Tanasescu 
1518a0bfde16SIulia Tanasescu 	if (conn && (memcmp(qos, &conn->iso_qos, sizeof(*qos)) ||
1519a0bfde16SIulia Tanasescu 		     base_len != conn->le_per_adv_data_len ||
1520a0bfde16SIulia Tanasescu 		     memcmp(conn->le_per_adv_data, base, base_len)))
1521eca0ae4aSLuiz Augusto von Dentz 		return ERR_PTR(-EADDRINUSE);
1522eca0ae4aSLuiz Augusto von Dentz 
1523181a42edSZiyang Xuan 	conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER);
1524a5b862c6SSungwoo Kim 	if (IS_ERR(conn))
1525a5b862c6SSungwoo Kim 		return conn;
1526eca0ae4aSLuiz Augusto von Dentz 
1527eca0ae4aSLuiz Augusto von Dentz 	conn->state = BT_CONNECT;
1528eca0ae4aSLuiz Augusto von Dentz 
1529eca0ae4aSLuiz Augusto von Dentz 	hci_conn_hold(conn);
1530eca0ae4aSLuiz Augusto von Dentz 	return conn;
1531eca0ae4aSLuiz Augusto von Dentz }
1532eca0ae4aSLuiz Augusto von Dentz 
1533f75113a2SJakub Pawlowski /* This function requires the caller holds hdev->lock */
hci_connect_le_scan(struct hci_dev * hdev,bdaddr_t * dst,u8 dst_type,u8 sec_level,u16 conn_timeout,enum conn_reasons conn_reason)1534f75113a2SJakub Pawlowski struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
1535f75113a2SJakub Pawlowski 				     u8 dst_type, u8 sec_level,
153676b13996SManish Mandlik 				     u16 conn_timeout,
153776b13996SManish Mandlik 				     enum conn_reasons conn_reason)
1538f75113a2SJakub Pawlowski {
1539f75113a2SJakub Pawlowski 	struct hci_conn *conn;
1540f75113a2SJakub Pawlowski 
1541f75113a2SJakub Pawlowski 	/* Let's make sure that le is enabled.*/
1542f75113a2SJakub Pawlowski 	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
1543f75113a2SJakub Pawlowski 		if (lmp_le_capable(hdev))
1544f75113a2SJakub Pawlowski 			return ERR_PTR(-ECONNREFUSED);
1545f75113a2SJakub Pawlowski 
1546f75113a2SJakub Pawlowski 		return ERR_PTR(-EOPNOTSUPP);
1547f75113a2SJakub Pawlowski 	}
1548f75113a2SJakub Pawlowski 
1549f75113a2SJakub Pawlowski 	/* Some devices send ATT messages as soon as the physical link is
1550f75113a2SJakub Pawlowski 	 * established. To be able to handle these ATT messages, the user-
1551f75113a2SJakub Pawlowski 	 * space first establishes the connection and then starts the pairing
1552f75113a2SJakub Pawlowski 	 * process.
1553f75113a2SJakub Pawlowski 	 *
1554f75113a2SJakub Pawlowski 	 * So if a hci_conn object already exists for the following connection
1555f75113a2SJakub Pawlowski 	 * attempt, we simply update pending_sec_level and auth_type fields
1556f75113a2SJakub Pawlowski 	 * and return the object found.
1557f75113a2SJakub Pawlowski 	 */
15589d4c1cc1SJohan Hedberg 	conn = hci_conn_hash_lookup_le(hdev, dst, dst_type);
1559f75113a2SJakub Pawlowski 	if (conn) {
1560f75113a2SJakub Pawlowski 		if (conn->pending_sec_level < sec_level)
1561f75113a2SJakub Pawlowski 			conn->pending_sec_level = sec_level;
1562f75113a2SJakub Pawlowski 		goto done;
1563f75113a2SJakub Pawlowski 	}
1564f75113a2SJakub Pawlowski 
1565f75113a2SJakub Pawlowski 	BT_DBG("requesting refresh of dst_addr");
1566f75113a2SJakub Pawlowski 
1567181a42edSZiyang Xuan 	conn = hci_conn_add_unset(hdev, LE_LINK, dst, HCI_ROLE_MASTER);
1568a5b862c6SSungwoo Kim 	if (IS_ERR(conn))
1569a5b862c6SSungwoo Kim 		return conn;
1570f75113a2SJakub Pawlowski 
1571d088337cSNavid Emamdoost 	if (hci_explicit_conn_params_set(hdev, dst, dst_type) < 0) {
1572d088337cSNavid Emamdoost 		hci_conn_del(conn);
1573f75113a2SJakub Pawlowski 		return ERR_PTR(-EBUSY);
1574d088337cSNavid Emamdoost 	}
1575f75113a2SJakub Pawlowski 
1576f75113a2SJakub Pawlowski 	conn->state = BT_CONNECT;
1577f75113a2SJakub Pawlowski 	set_bit(HCI_CONN_SCANNING, &conn->flags);
1578f75113a2SJakub Pawlowski 	conn->dst_type = dst_type;
1579f75113a2SJakub Pawlowski 	conn->sec_level = BT_SECURITY_LOW;
1580f75113a2SJakub Pawlowski 	conn->pending_sec_level = sec_level;
1581f75113a2SJakub Pawlowski 	conn->conn_timeout = conn_timeout;
158276b13996SManish Mandlik 	conn->conn_reason = conn_reason;
1583f75113a2SJakub Pawlowski 
15845bee2fd6SLuiz Augusto von Dentz 	hci_update_passive_scan(hdev);
158584235d22SJohan Hedberg 
1586f75113a2SJakub Pawlowski done:
1587f75113a2SJakub Pawlowski 	hci_conn_hold(conn);
1588f75113a2SJakub Pawlowski 	return conn;
1589f75113a2SJakub Pawlowski }
1590f75113a2SJakub Pawlowski 
hci_connect_acl(struct hci_dev * hdev,bdaddr_t * dst,u8 sec_level,u8 auth_type,enum conn_reasons conn_reason,u16 timeout)159104a6c589SAndre Guedes struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
159276b13996SManish Mandlik 				 u8 sec_level, u8 auth_type,
1593bf98feeaSLuiz Augusto von Dentz 				 enum conn_reasons conn_reason, u16 timeout)
1594d04aef4cSVinicius Costa Gomes {
1595d04aef4cSVinicius Costa Gomes 	struct hci_conn *acl;
1596d04aef4cSVinicius Costa Gomes 
1597d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
1598c411110eSLukasz Rymanowski 		if (lmp_bredr_capable(hdev))
1599c411110eSLukasz Rymanowski 			return ERR_PTR(-ECONNREFUSED);
1600c411110eSLukasz Rymanowski 
1601beb19e4cSJohan Hedberg 		return ERR_PTR(-EOPNOTSUPP);
1602c411110eSLukasz Rymanowski 	}
160356f87901SJohan Hedberg 
16041ffc6f8cSLee, Chun-Yi 	/* Reject outgoing connection to device with same BD ADDR against
16051ffc6f8cSLee, Chun-Yi 	 * CVE-2020-26555
16061ffc6f8cSLee, Chun-Yi 	 */
16071ffc6f8cSLee, Chun-Yi 	if (!bacmp(&hdev->bdaddr, dst)) {
16081ffc6f8cSLee, Chun-Yi 		bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n",
16091ffc6f8cSLee, Chun-Yi 			   dst);
16101ffc6f8cSLee, Chun-Yi 		return ERR_PTR(-ECONNREFUSED);
16111ffc6f8cSLee, Chun-Yi 	}
16121ffc6f8cSLee, Chun-Yi 
161370f23020SAndrei Emeltchenko 	acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
161470f23020SAndrei Emeltchenko 	if (!acl) {
1615181a42edSZiyang Xuan 		acl = hci_conn_add_unset(hdev, ACL_LINK, dst, HCI_ROLE_MASTER);
1616a5b862c6SSungwoo Kim 		if (IS_ERR(acl))
1617a5b862c6SSungwoo Kim 			return acl;
16181da177e4SLinus Torvalds 	}
16191da177e4SLinus Torvalds 
16201da177e4SLinus Torvalds 	hci_conn_hold(acl);
16211da177e4SLinus Torvalds 
162276b13996SManish Mandlik 	acl->conn_reason = conn_reason;
162309ab6f4cSMarcel Holtmann 	if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
162445340097SJonas Dreßler 		int err;
162545340097SJonas Dreßler 
1626765c2a96SJohan Hedberg 		acl->sec_level = BT_SECURITY_LOW;
1627765c2a96SJohan Hedberg 		acl->pending_sec_level = sec_level;
162809ab6f4cSMarcel Holtmann 		acl->auth_type = auth_type;
1629bf98feeaSLuiz Augusto von Dentz 		acl->conn_timeout = timeout;
163045340097SJonas Dreßler 
16315f641f03SLuiz Augusto von Dentz 		err = hci_connect_acl_sync(hdev, acl);
163245340097SJonas Dreßler 		if (err) {
163345340097SJonas Dreßler 			hci_conn_del(acl);
163445340097SJonas Dreßler 			return ERR_PTR(err);
163545340097SJonas Dreßler 		}
163609ab6f4cSMarcel Holtmann 	}
16371da177e4SLinus Torvalds 
1638db474275SVinicius Costa Gomes 	return acl;
1639db474275SVinicius Costa Gomes }
1640db474275SVinicius Costa Gomes 
hci_conn_link(struct hci_conn * parent,struct hci_conn * conn)164106149746SLuiz Augusto von Dentz static struct hci_link *hci_conn_link(struct hci_conn *parent,
164206149746SLuiz Augusto von Dentz 				      struct hci_conn *conn)
164306149746SLuiz Augusto von Dentz {
164406149746SLuiz Augusto von Dentz 	struct hci_dev *hdev = parent->hdev;
164506149746SLuiz Augusto von Dentz 	struct hci_link *link;
164606149746SLuiz Augusto von Dentz 
164706149746SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "parent %p hcon %p", parent, conn);
164806149746SLuiz Augusto von Dentz 
164906149746SLuiz Augusto von Dentz 	if (conn->link)
165006149746SLuiz Augusto von Dentz 		return conn->link;
165106149746SLuiz Augusto von Dentz 
165206149746SLuiz Augusto von Dentz 	if (conn->parent)
165306149746SLuiz Augusto von Dentz 		return NULL;
165406149746SLuiz Augusto von Dentz 
165506149746SLuiz Augusto von Dentz 	link = kzalloc(sizeof(*link), GFP_KERNEL);
165606149746SLuiz Augusto von Dentz 	if (!link)
165706149746SLuiz Augusto von Dentz 		return NULL;
165806149746SLuiz Augusto von Dentz 
165906149746SLuiz Augusto von Dentz 	link->conn = hci_conn_hold(conn);
166006149746SLuiz Augusto von Dentz 	conn->link = link;
166106149746SLuiz Augusto von Dentz 	conn->parent = hci_conn_get(parent);
166206149746SLuiz Augusto von Dentz 
166306149746SLuiz Augusto von Dentz 	/* Use list_add_tail_rcu append to the list */
166406149746SLuiz Augusto von Dentz 	list_add_tail_rcu(&link->list, &parent->link_list);
166506149746SLuiz Augusto von Dentz 
166606149746SLuiz Augusto von Dentz 	return link;
166706149746SLuiz Augusto von Dentz }
166806149746SLuiz Augusto von Dentz 
hci_connect_sco(struct hci_dev * hdev,int type,bdaddr_t * dst,__u16 setting,struct bt_codec * codec,u16 timeout)166910c62ddcSFrédéric Dalleau struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
1670bf98feeaSLuiz Augusto von Dentz 				 __u16 setting, struct bt_codec *codec,
1671bf98feeaSLuiz Augusto von Dentz 				 u16 timeout)
1672db474275SVinicius Costa Gomes {
1673db474275SVinicius Costa Gomes 	struct hci_conn *acl;
1674db474275SVinicius Costa Gomes 	struct hci_conn *sco;
167506149746SLuiz Augusto von Dentz 	struct hci_link *link;
1676db474275SVinicius Costa Gomes 
167776b13996SManish Mandlik 	acl = hci_connect_acl(hdev, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING,
1678bf98feeaSLuiz Augusto von Dentz 			      CONN_REASON_SCO_CONNECT, timeout);
1679db474275SVinicius Costa Gomes 	if (IS_ERR(acl))
16805b7f9909SMarcel Holtmann 		return acl;
16811da177e4SLinus Torvalds 
168270f23020SAndrei Emeltchenko 	sco = hci_conn_hash_lookup_ba(hdev, type, dst);
168370f23020SAndrei Emeltchenko 	if (!sco) {
1684181a42edSZiyang Xuan 		sco = hci_conn_add_unset(hdev, type, dst, HCI_ROLE_MASTER);
1685a5b862c6SSungwoo Kim 		if (IS_ERR(sco)) {
168676a68ba0SDavid Herrmann 			hci_conn_drop(acl);
1687a5b862c6SSungwoo Kim 			return sco;
16881da177e4SLinus Torvalds 		}
16891da177e4SLinus Torvalds 	}
16905b7f9909SMarcel Holtmann 
169106149746SLuiz Augusto von Dentz 	link = hci_conn_link(acl, sco);
169206149746SLuiz Augusto von Dentz 	if (!link) {
169306149746SLuiz Augusto von Dentz 		hci_conn_drop(acl);
169406149746SLuiz Augusto von Dentz 		hci_conn_drop(sco);
1695b4066eb0SSiddh Raman Pant 		return ERR_PTR(-ENOLINK);
169606149746SLuiz Augusto von Dentz 	}
16971da177e4SLinus Torvalds 
169810c62ddcSFrédéric Dalleau 	sco->setting = setting;
1699b2af264aSKiran K 	sco->codec = *codec;
170010c62ddcSFrédéric Dalleau 
17011da177e4SLinus Torvalds 	if (acl->state == BT_CONNECTED &&
1702b6a0dc82SMarcel Holtmann 	    (sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
170358a681efSJohan Hedberg 		set_bit(HCI_CONN_POWER_SAVE, &acl->flags);
170414b12d0bSJaikumar Ganesh 		hci_conn_enter_active_mode(acl, BT_POWER_FORCE_ACTIVE_ON);
1705c390216bSNick Pelly 
170651a8efd7SJohan Hedberg 		if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->flags)) {
1707e73439d8SMarcel Holtmann 			/* defer SCO setup until mode change completed */
170851a8efd7SJohan Hedberg 			set_bit(HCI_CONN_SCO_SETUP_PEND, &acl->flags);
1709e73439d8SMarcel Holtmann 			return sco;
1710e73439d8SMarcel Holtmann 		}
1711e73439d8SMarcel Holtmann 
1712e73439d8SMarcel Holtmann 		hci_sco_setup(acl, 0x00);
1713b6a0dc82SMarcel Holtmann 	}
17141da177e4SLinus Torvalds 
17151da177e4SLinus Torvalds 	return sco;
17161da177e4SLinus Torvalds }
17171da177e4SLinus Torvalds 
hci_le_create_big(struct hci_conn * conn,struct bt_iso_qos * qos)1718eca0ae4aSLuiz Augusto von Dentz static int hci_le_create_big(struct hci_conn *conn, struct bt_iso_qos *qos)
1719eca0ae4aSLuiz Augusto von Dentz {
1720eca0ae4aSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
1721eca0ae4aSLuiz Augusto von Dentz 	struct hci_cp_le_create_big cp;
1722a0bfde16SIulia Tanasescu 	struct iso_list_data data;
1723eca0ae4aSLuiz Augusto von Dentz 
1724eca0ae4aSLuiz Augusto von Dentz 	memset(&cp, 0, sizeof(cp));
1725eca0ae4aSLuiz Augusto von Dentz 
1726a0bfde16SIulia Tanasescu 	data.big = qos->bcast.big;
1727a0bfde16SIulia Tanasescu 	data.bis = qos->bcast.bis;
1728a0bfde16SIulia Tanasescu 	data.count = 0;
1729a0bfde16SIulia Tanasescu 
1730a0bfde16SIulia Tanasescu 	/* Create a BIS for each bound connection */
1731a0bfde16SIulia Tanasescu 	hci_conn_hash_list_state(hdev, bis_list, ISO_LINK,
1732a0bfde16SIulia Tanasescu 				 BT_BOUND, &data);
1733a0bfde16SIulia Tanasescu 
17340fe8c8d0SIulia Tanasescu 	cp.handle = qos->bcast.big;
17350fe8c8d0SIulia Tanasescu 	cp.adv_handle = qos->bcast.bis;
1736a0bfde16SIulia Tanasescu 	cp.num_bis  = data.count;
17370fe8c8d0SIulia Tanasescu 	hci_cpu_to_le24(qos->bcast.out.interval, cp.bis.sdu_interval);
17380fe8c8d0SIulia Tanasescu 	cp.bis.sdu = cpu_to_le16(qos->bcast.out.sdu);
17390fe8c8d0SIulia Tanasescu 	cp.bis.latency =  cpu_to_le16(qos->bcast.out.latency);
17400fe8c8d0SIulia Tanasescu 	cp.bis.rtn  = qos->bcast.out.rtn;
17410fe8c8d0SIulia Tanasescu 	cp.bis.phy  = qos->bcast.out.phy;
17420fe8c8d0SIulia Tanasescu 	cp.bis.packing = qos->bcast.packing;
17430fe8c8d0SIulia Tanasescu 	cp.bis.framing = qos->bcast.framing;
17440fe8c8d0SIulia Tanasescu 	cp.bis.encryption = qos->bcast.encryption;
17450fe8c8d0SIulia Tanasescu 	memcpy(cp.bis.bcode, qos->bcast.bcode, sizeof(cp.bis.bcode));
1746eca0ae4aSLuiz Augusto von Dentz 
1747eca0ae4aSLuiz Augusto von Dentz 	return hci_send_cmd(hdev, HCI_OP_LE_CREATE_BIG, sizeof(cp), &cp);
1748eca0ae4aSLuiz Augusto von Dentz }
1749eca0ae4aSLuiz Augusto von Dentz 
set_cig_params_sync(struct hci_dev * hdev,void * data)17506b9545dcSPauli Virtanen static int set_cig_params_sync(struct hci_dev *hdev, void *data)
17516b9545dcSPauli Virtanen {
1752ea9e148cSGustavo A. R. Silva 	DEFINE_FLEX(struct hci_cp_le_set_cig_params, pdu, cis, num_cis, 0x1f);
1753a1f6c3aeSLuiz Augusto von Dentz 	u8 cig_id = PTR_UINT(data);
1754a0912892SLuiz Augusto von Dentz 	struct hci_conn *conn;
1755a0912892SLuiz Augusto von Dentz 	struct bt_iso_qos *qos;
1756ea9e148cSGustavo A. R. Silva 	u8 aux_num_cis = 0;
1757a0912892SLuiz Augusto von Dentz 	u8 cis_id;
17586b9545dcSPauli Virtanen 
1759a0912892SLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_cig(hdev, cig_id);
1760a0912892SLuiz Augusto von Dentz 	if (!conn)
1761a0912892SLuiz Augusto von Dentz 		return 0;
1762a0912892SLuiz Augusto von Dentz 
1763a0912892SLuiz Augusto von Dentz 	qos = &conn->iso_qos;
1764ea9e148cSGustavo A. R. Silva 	pdu->cig_id = cig_id;
1765ea9e148cSGustavo A. R. Silva 	hci_cpu_to_le24(qos->ucast.out.interval, pdu->c_interval);
1766ea9e148cSGustavo A. R. Silva 	hci_cpu_to_le24(qos->ucast.in.interval, pdu->p_interval);
1767ea9e148cSGustavo A. R. Silva 	pdu->sca = qos->ucast.sca;
1768ea9e148cSGustavo A. R. Silva 	pdu->packing = qos->ucast.packing;
1769ea9e148cSGustavo A. R. Silva 	pdu->framing = qos->ucast.framing;
1770ea9e148cSGustavo A. R. Silva 	pdu->c_latency = cpu_to_le16(qos->ucast.out.latency);
1771ea9e148cSGustavo A. R. Silva 	pdu->p_latency = cpu_to_le16(qos->ucast.in.latency);
1772a0912892SLuiz Augusto von Dentz 
1773a0912892SLuiz Augusto von Dentz 	/* Reprogram all CIS(s) with the same CIG, valid range are:
1774a0912892SLuiz Augusto von Dentz 	 * num_cis: 0x00 to 0x1F
1775a0912892SLuiz Augusto von Dentz 	 * cis_id: 0x00 to 0xEF
1776a0912892SLuiz Augusto von Dentz 	 */
1777a0912892SLuiz Augusto von Dentz 	for (cis_id = 0x00; cis_id < 0xf0 &&
1778ea9e148cSGustavo A. R. Silva 	     aux_num_cis < pdu->num_cis; cis_id++) {
1779a0912892SLuiz Augusto von Dentz 		struct hci_cis_params *cis;
1780a0912892SLuiz Augusto von Dentz 
1781a0912892SLuiz Augusto von Dentz 		conn = hci_conn_hash_lookup_cis(hdev, NULL, 0, cig_id, cis_id);
1782a0912892SLuiz Augusto von Dentz 		if (!conn)
1783a0912892SLuiz Augusto von Dentz 			continue;
1784a0912892SLuiz Augusto von Dentz 
1785a0912892SLuiz Augusto von Dentz 		qos = &conn->iso_qos;
1786a0912892SLuiz Augusto von Dentz 
1787ea9e148cSGustavo A. R. Silva 		cis = &pdu->cis[aux_num_cis++];
1788a0912892SLuiz Augusto von Dentz 		cis->cis_id = cis_id;
1789a0912892SLuiz Augusto von Dentz 		cis->c_sdu  = cpu_to_le16(conn->iso_qos.ucast.out.sdu);
1790a0912892SLuiz Augusto von Dentz 		cis->p_sdu  = cpu_to_le16(conn->iso_qos.ucast.in.sdu);
1791a0912892SLuiz Augusto von Dentz 		cis->c_phy  = qos->ucast.out.phy ? qos->ucast.out.phy :
1792a0912892SLuiz Augusto von Dentz 			      qos->ucast.in.phy;
1793a0912892SLuiz Augusto von Dentz 		cis->p_phy  = qos->ucast.in.phy ? qos->ucast.in.phy :
1794a0912892SLuiz Augusto von Dentz 			      qos->ucast.out.phy;
1795a0912892SLuiz Augusto von Dentz 		cis->c_rtn  = qos->ucast.out.rtn;
1796a0912892SLuiz Augusto von Dentz 		cis->p_rtn  = qos->ucast.in.rtn;
1797a0912892SLuiz Augusto von Dentz 	}
1798ea9e148cSGustavo A. R. Silva 	pdu->num_cis = aux_num_cis;
1799a0912892SLuiz Augusto von Dentz 
1800ea9e148cSGustavo A. R. Silva 	if (!pdu->num_cis)
1801a0912892SLuiz Augusto von Dentz 		return 0;
1802a0912892SLuiz Augusto von Dentz 
1803a0912892SLuiz Augusto von Dentz 	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_CIG_PARAMS,
1804ea9e148cSGustavo A. R. Silva 				     struct_size(pdu, cis, pdu->num_cis),
1805ea9e148cSGustavo A. R. Silva 				     pdu, HCI_CMD_TIMEOUT);
18066b9545dcSPauli Virtanen }
18076b9545dcSPauli Virtanen 
hci_le_set_cig_params(struct hci_conn * conn,struct bt_iso_qos * qos)180826afbd82SLuiz Augusto von Dentz static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos)
180926afbd82SLuiz Augusto von Dentz {
181026afbd82SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
181126afbd82SLuiz Augusto von Dentz 	struct iso_list_data data;
181226afbd82SLuiz Augusto von Dentz 
181326afbd82SLuiz Augusto von Dentz 	memset(&data, 0, sizeof(data));
181426afbd82SLuiz Augusto von Dentz 
1815e6a7a46bSPauli Virtanen 	/* Allocate first still reconfigurable CIG if not set */
18160fe8c8d0SIulia Tanasescu 	if (qos->ucast.cig == BT_ISO_QOS_CIG_UNSET) {
1817e6a7a46bSPauli Virtanen 		for (data.cig = 0x00; data.cig < 0xf0; data.cig++) {
181826afbd82SLuiz Augusto von Dentz 			data.count = 0;
181926afbd82SLuiz Augusto von Dentz 
1820e6a7a46bSPauli Virtanen 			hci_conn_hash_list_state(hdev, find_cis, ISO_LINK,
1821e6a7a46bSPauli Virtanen 						 BT_CONNECT, &data);
182226afbd82SLuiz Augusto von Dentz 			if (data.count)
182326afbd82SLuiz Augusto von Dentz 				continue;
182426afbd82SLuiz Augusto von Dentz 
1825e6a7a46bSPauli Virtanen 			hci_conn_hash_list_state(hdev, find_cis, ISO_LINK,
182626afbd82SLuiz Augusto von Dentz 						 BT_CONNECTED, &data);
182726afbd82SLuiz Augusto von Dentz 			if (!data.count)
182826afbd82SLuiz Augusto von Dentz 				break;
182926afbd82SLuiz Augusto von Dentz 		}
183026afbd82SLuiz Augusto von Dentz 
1831e6a7a46bSPauli Virtanen 		if (data.cig == 0xf0)
183226afbd82SLuiz Augusto von Dentz 			return false;
183326afbd82SLuiz Augusto von Dentz 
183426afbd82SLuiz Augusto von Dentz 		/* Update CIG */
18350fe8c8d0SIulia Tanasescu 		qos->ucast.cig = data.cig;
183626afbd82SLuiz Augusto von Dentz 	}
183726afbd82SLuiz Augusto von Dentz 
18380fe8c8d0SIulia Tanasescu 	if (qos->ucast.cis != BT_ISO_QOS_CIS_UNSET) {
1839a0912892SLuiz Augusto von Dentz 		if (hci_conn_hash_lookup_cis(hdev, NULL, 0, qos->ucast.cig,
1840a0912892SLuiz Augusto von Dentz 					     qos->ucast.cis))
184126afbd82SLuiz Augusto von Dentz 			return false;
1842a0912892SLuiz Augusto von Dentz 		goto done;
184326afbd82SLuiz Augusto von Dentz 	}
184426afbd82SLuiz Augusto von Dentz 
1845a0912892SLuiz Augusto von Dentz 	/* Allocate first available CIS if not set */
1846a0912892SLuiz Augusto von Dentz 	for (data.cig = qos->ucast.cig, data.cis = 0x00; data.cis < 0xf0;
1847a0912892SLuiz Augusto von Dentz 	     data.cis++) {
1848a0912892SLuiz Augusto von Dentz 		if (!hci_conn_hash_lookup_cis(hdev, NULL, 0, data.cig,
1849a0912892SLuiz Augusto von Dentz 					      data.cis)) {
185026afbd82SLuiz Augusto von Dentz 			/* Update CIS */
18510fe8c8d0SIulia Tanasescu 			qos->ucast.cis = data.cis;
1852a0912892SLuiz Augusto von Dentz 			break;
185326afbd82SLuiz Augusto von Dentz 		}
185426afbd82SLuiz Augusto von Dentz 	}
185526afbd82SLuiz Augusto von Dentz 
1856a0912892SLuiz Augusto von Dentz 	if (qos->ucast.cis == BT_ISO_QOS_CIS_UNSET)
185726afbd82SLuiz Augusto von Dentz 		return false;
185826afbd82SLuiz Augusto von Dentz 
1859a0912892SLuiz Augusto von Dentz done:
1860a0912892SLuiz Augusto von Dentz 	if (hci_cmd_sync_queue(hdev, set_cig_params_sync,
1861a1f6c3aeSLuiz Augusto von Dentz 			       UINT_PTR(qos->ucast.cig), NULL) < 0)
186226afbd82SLuiz Augusto von Dentz 		return false;
186326afbd82SLuiz Augusto von Dentz 
186426afbd82SLuiz Augusto von Dentz 	return true;
186526afbd82SLuiz Augusto von Dentz }
186626afbd82SLuiz Augusto von Dentz 
hci_bind_cis(struct hci_dev * hdev,bdaddr_t * dst,__u8 dst_type,struct bt_iso_qos * qos)186726afbd82SLuiz Augusto von Dentz struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst,
186826afbd82SLuiz Augusto von Dentz 			      __u8 dst_type, struct bt_iso_qos *qos)
186926afbd82SLuiz Augusto von Dentz {
187026afbd82SLuiz Augusto von Dentz 	struct hci_conn *cis;
187126afbd82SLuiz Augusto von Dentz 
1872c14516faSLuiz Augusto von Dentz 	cis = hci_conn_hash_lookup_cis(hdev, dst, dst_type, qos->ucast.cig,
1873c14516faSLuiz Augusto von Dentz 				       qos->ucast.cis);
187426afbd82SLuiz Augusto von Dentz 	if (!cis) {
1875181a42edSZiyang Xuan 		cis = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER);
1876a5b862c6SSungwoo Kim 		if (IS_ERR(cis))
1877a5b862c6SSungwoo Kim 			return cis;
187826afbd82SLuiz Augusto von Dentz 		cis->cleanup = cis_cleanup;
1879b36a234dSPauli Virtanen 		cis->dst_type = dst_type;
1880b5793de3SPauli Virtanen 		cis->iso_qos.ucast.cig = BT_ISO_QOS_CIG_UNSET;
1881b5793de3SPauli Virtanen 		cis->iso_qos.ucast.cis = BT_ISO_QOS_CIS_UNSET;
188226afbd82SLuiz Augusto von Dentz 	}
188326afbd82SLuiz Augusto von Dentz 
188426afbd82SLuiz Augusto von Dentz 	if (cis->state == BT_CONNECTED)
188526afbd82SLuiz Augusto von Dentz 		return cis;
188626afbd82SLuiz Augusto von Dentz 
188726afbd82SLuiz Augusto von Dentz 	/* Check if CIS has been set and the settings matches */
188826afbd82SLuiz Augusto von Dentz 	if (cis->state == BT_BOUND &&
188926afbd82SLuiz Augusto von Dentz 	    !memcmp(&cis->iso_qos, qos, sizeof(*qos)))
189026afbd82SLuiz Augusto von Dentz 		return cis;
189126afbd82SLuiz Augusto von Dentz 
189226afbd82SLuiz Augusto von Dentz 	/* Update LINK PHYs according to QoS preference */
18930fe8c8d0SIulia Tanasescu 	cis->le_tx_phy = qos->ucast.out.phy;
18940fe8c8d0SIulia Tanasescu 	cis->le_rx_phy = qos->ucast.in.phy;
189526afbd82SLuiz Augusto von Dentz 
189626afbd82SLuiz Augusto von Dentz 	/* If output interval is not set use the input interval as it cannot be
189726afbd82SLuiz Augusto von Dentz 	 * 0x000000.
189826afbd82SLuiz Augusto von Dentz 	 */
18990fe8c8d0SIulia Tanasescu 	if (!qos->ucast.out.interval)
19000fe8c8d0SIulia Tanasescu 		qos->ucast.out.interval = qos->ucast.in.interval;
190126afbd82SLuiz Augusto von Dentz 
190226afbd82SLuiz Augusto von Dentz 	/* If input interval is not set use the output interval as it cannot be
190326afbd82SLuiz Augusto von Dentz 	 * 0x000000.
190426afbd82SLuiz Augusto von Dentz 	 */
19050fe8c8d0SIulia Tanasescu 	if (!qos->ucast.in.interval)
19060fe8c8d0SIulia Tanasescu 		qos->ucast.in.interval = qos->ucast.out.interval;
190726afbd82SLuiz Augusto von Dentz 
190826afbd82SLuiz Augusto von Dentz 	/* If output latency is not set use the input latency as it cannot be
190926afbd82SLuiz Augusto von Dentz 	 * 0x0000.
191026afbd82SLuiz Augusto von Dentz 	 */
19110fe8c8d0SIulia Tanasescu 	if (!qos->ucast.out.latency)
19120fe8c8d0SIulia Tanasescu 		qos->ucast.out.latency = qos->ucast.in.latency;
191326afbd82SLuiz Augusto von Dentz 
191426afbd82SLuiz Augusto von Dentz 	/* If input latency is not set use the output latency as it cannot be
191526afbd82SLuiz Augusto von Dentz 	 * 0x0000.
191626afbd82SLuiz Augusto von Dentz 	 */
19170fe8c8d0SIulia Tanasescu 	if (!qos->ucast.in.latency)
19180fe8c8d0SIulia Tanasescu 		qos->ucast.in.latency = qos->ucast.out.latency;
191926afbd82SLuiz Augusto von Dentz 
192026afbd82SLuiz Augusto von Dentz 	if (!hci_le_set_cig_params(cis, qos)) {
192126afbd82SLuiz Augusto von Dentz 		hci_conn_drop(cis);
192226afbd82SLuiz Augusto von Dentz 		return ERR_PTR(-EINVAL);
192326afbd82SLuiz Augusto von Dentz 	}
192426afbd82SLuiz Augusto von Dentz 
192569997d50SPauli Virtanen 	hci_conn_hold(cis);
192669997d50SPauli Virtanen 
192726afbd82SLuiz Augusto von Dentz 	cis->iso_qos = *qos;
192826afbd82SLuiz Augusto von Dentz 	cis->state = BT_BOUND;
192926afbd82SLuiz Augusto von Dentz 
193026afbd82SLuiz Augusto von Dentz 	return cis;
193126afbd82SLuiz Augusto von Dentz }
193226afbd82SLuiz Augusto von Dentz 
hci_iso_setup_path(struct hci_conn * conn)193326afbd82SLuiz Augusto von Dentz bool hci_iso_setup_path(struct hci_conn *conn)
193426afbd82SLuiz Augusto von Dentz {
193526afbd82SLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
193626afbd82SLuiz Augusto von Dentz 	struct hci_cp_le_setup_iso_path cmd;
193726afbd82SLuiz Augusto von Dentz 
193826afbd82SLuiz Augusto von Dentz 	memset(&cmd, 0, sizeof(cmd));
193926afbd82SLuiz Augusto von Dentz 
19400fe8c8d0SIulia Tanasescu 	if (conn->iso_qos.ucast.out.sdu) {
194126afbd82SLuiz Augusto von Dentz 		cmd.handle = cpu_to_le16(conn->handle);
194226afbd82SLuiz Augusto von Dentz 		cmd.direction = 0x00; /* Input (Host to Controller) */
194326afbd82SLuiz Augusto von Dentz 		cmd.path = 0x00; /* HCI path if enabled */
194426afbd82SLuiz Augusto von Dentz 		cmd.codec = 0x03; /* Transparent Data */
194526afbd82SLuiz Augusto von Dentz 
194626afbd82SLuiz Augusto von Dentz 		if (hci_send_cmd(hdev, HCI_OP_LE_SETUP_ISO_PATH, sizeof(cmd),
194726afbd82SLuiz Augusto von Dentz 				 &cmd) < 0)
194826afbd82SLuiz Augusto von Dentz 			return false;
194926afbd82SLuiz Augusto von Dentz 	}
195026afbd82SLuiz Augusto von Dentz 
19510fe8c8d0SIulia Tanasescu 	if (conn->iso_qos.ucast.in.sdu) {
195226afbd82SLuiz Augusto von Dentz 		cmd.handle = cpu_to_le16(conn->handle);
195326afbd82SLuiz Augusto von Dentz 		cmd.direction = 0x01; /* Output (Controller to Host) */
195426afbd82SLuiz Augusto von Dentz 		cmd.path = 0x00; /* HCI path if enabled */
195526afbd82SLuiz Augusto von Dentz 		cmd.codec = 0x03; /* Transparent Data */
195626afbd82SLuiz Augusto von Dentz 
195726afbd82SLuiz Augusto von Dentz 		if (hci_send_cmd(hdev, HCI_OP_LE_SETUP_ISO_PATH, sizeof(cmd),
195826afbd82SLuiz Augusto von Dentz 				 &cmd) < 0)
195926afbd82SLuiz Augusto von Dentz 			return false;
196026afbd82SLuiz Augusto von Dentz 	}
196126afbd82SLuiz Augusto von Dentz 
196226afbd82SLuiz Augusto von Dentz 	return true;
196326afbd82SLuiz Augusto von Dentz }
196426afbd82SLuiz Augusto von Dentz 
hci_conn_check_create_cis(struct hci_conn * conn)19657f74563eSPauli Virtanen int hci_conn_check_create_cis(struct hci_conn *conn)
19667f74563eSPauli Virtanen {
19677f74563eSPauli Virtanen 	if (conn->type != ISO_LINK || !bacmp(&conn->dst, BDADDR_ANY))
19687f74563eSPauli Virtanen 		return -EINVAL;
19697f74563eSPauli Virtanen 
19707f74563eSPauli Virtanen 	if (!conn->parent || conn->parent->state != BT_CONNECTED ||
19719f78191cSLuiz Augusto von Dentz 	    conn->state != BT_CONNECT || HCI_CONN_HANDLE_UNSET(conn->handle))
19727f74563eSPauli Virtanen 		return 1;
19737f74563eSPauli Virtanen 
19747f74563eSPauli Virtanen 	return 0;
19757f74563eSPauli Virtanen }
19767f74563eSPauli Virtanen 
hci_create_cis_sync(struct hci_dev * hdev,void * data)197726afbd82SLuiz Augusto von Dentz static int hci_create_cis_sync(struct hci_dev *hdev, void *data)
197826afbd82SLuiz Augusto von Dentz {
19797f74563eSPauli Virtanen 	return hci_le_create_cis_sync(hdev);
198026afbd82SLuiz Augusto von Dentz }
198126afbd82SLuiz Augusto von Dentz 
hci_le_create_cis_pending(struct hci_dev * hdev)19827f74563eSPauli Virtanen int hci_le_create_cis_pending(struct hci_dev *hdev)
198326afbd82SLuiz Augusto von Dentz {
19847f74563eSPauli Virtanen 	struct hci_conn *conn;
19857f74563eSPauli Virtanen 	bool pending = false;
198626afbd82SLuiz Augusto von Dentz 
19877f74563eSPauli Virtanen 	rcu_read_lock();
198806149746SLuiz Augusto von Dentz 
19897f74563eSPauli Virtanen 	list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
19907f74563eSPauli Virtanen 		if (test_bit(HCI_CONN_CREATE_CIS, &conn->flags)) {
19917f74563eSPauli Virtanen 			rcu_read_unlock();
19927f74563eSPauli Virtanen 			return -EBUSY;
199306149746SLuiz Augusto von Dentz 		}
199406149746SLuiz Augusto von Dentz 
19957f74563eSPauli Virtanen 		if (!hci_conn_check_create_cis(conn))
19967f74563eSPauli Virtanen 			pending = true;
199726afbd82SLuiz Augusto von Dentz 	}
199826afbd82SLuiz Augusto von Dentz 
19997f74563eSPauli Virtanen 	rcu_read_unlock();
20007f74563eSPauli Virtanen 
20017f74563eSPauli Virtanen 	if (!pending)
200226afbd82SLuiz Augusto von Dentz 		return 0;
200326afbd82SLuiz Augusto von Dentz 
200426afbd82SLuiz Augusto von Dentz 	/* Queue Create CIS */
20057f74563eSPauli Virtanen 	return hci_cmd_sync_queue(hdev, hci_create_cis_sync, NULL, NULL);
200626afbd82SLuiz Augusto von Dentz }
200726afbd82SLuiz Augusto von Dentz 
hci_iso_qos_setup(struct hci_dev * hdev,struct hci_conn * conn,struct bt_iso_io_qos * qos,__u8 phy)200826afbd82SLuiz Augusto von Dentz static void hci_iso_qos_setup(struct hci_dev *hdev, struct hci_conn *conn,
200926afbd82SLuiz Augusto von Dentz 			      struct bt_iso_io_qos *qos, __u8 phy)
201026afbd82SLuiz Augusto von Dentz {
201126afbd82SLuiz Augusto von Dentz 	/* Only set MTU if PHY is enabled */
2012a5b862c6SSungwoo Kim 	if (!qos->sdu && qos->phy)
2013a5b862c6SSungwoo Kim 		qos->sdu = conn->mtu;
201426afbd82SLuiz Augusto von Dentz 
201526afbd82SLuiz Augusto von Dentz 	/* Use the same PHY as ACL if set to any */
201626afbd82SLuiz Augusto von Dentz 	if (qos->phy == BT_ISO_PHY_ANY)
201726afbd82SLuiz Augusto von Dentz 		qos->phy = phy;
201826afbd82SLuiz Augusto von Dentz 
201926afbd82SLuiz Augusto von Dentz 	/* Use LE ACL connection interval if not set */
202026afbd82SLuiz Augusto von Dentz 	if (!qos->interval)
202126afbd82SLuiz Augusto von Dentz 		/* ACL interval unit in 1.25 ms to us */
202226afbd82SLuiz Augusto von Dentz 		qos->interval = conn->le_conn_interval * 1250;
202326afbd82SLuiz Augusto von Dentz 
202426afbd82SLuiz Augusto von Dentz 	/* Use LE ACL connection latency if not set */
202526afbd82SLuiz Augusto von Dentz 	if (!qos->latency)
202626afbd82SLuiz Augusto von Dentz 		qos->latency = conn->le_conn_latency;
202726afbd82SLuiz Augusto von Dentz }
202826afbd82SLuiz Augusto von Dentz 
create_big_sync(struct hci_dev * hdev,void * data)2029eca0ae4aSLuiz Augusto von Dentz static int create_big_sync(struct hci_dev *hdev, void *data)
2030eca0ae4aSLuiz Augusto von Dentz {
2031eca0ae4aSLuiz Augusto von Dentz 	struct hci_conn *conn = data;
2032eca0ae4aSLuiz Augusto von Dentz 	struct bt_iso_qos *qos = &conn->iso_qos;
2033eca0ae4aSLuiz Augusto von Dentz 	u16 interval, sync_interval = 0;
2034eca0ae4aSLuiz Augusto von Dentz 	u32 flags = 0;
2035eca0ae4aSLuiz Augusto von Dentz 	int err;
2036eca0ae4aSLuiz Augusto von Dentz 
20370fe8c8d0SIulia Tanasescu 	if (qos->bcast.out.phy == 0x02)
2038eca0ae4aSLuiz Augusto von Dentz 		flags |= MGMT_ADV_FLAG_SEC_2M;
2039eca0ae4aSLuiz Augusto von Dentz 
2040eca0ae4aSLuiz Augusto von Dentz 	/* Align intervals */
204114f0dcecSLuiz Augusto von Dentz 	interval = (qos->bcast.out.interval / 1250) * qos->bcast.sync_factor;
2042eca0ae4aSLuiz Augusto von Dentz 
20430fe8c8d0SIulia Tanasescu 	if (qos->bcast.bis)
204414f0dcecSLuiz Augusto von Dentz 		sync_interval = interval * 4;
2045eca0ae4aSLuiz Augusto von Dentz 
20460fe8c8d0SIulia Tanasescu 	err = hci_start_per_adv_sync(hdev, qos->bcast.bis, conn->le_per_adv_data_len,
2047eca0ae4aSLuiz Augusto von Dentz 				     conn->le_per_adv_data, flags, interval,
2048eca0ae4aSLuiz Augusto von Dentz 				     interval, sync_interval);
2049eca0ae4aSLuiz Augusto von Dentz 	if (err)
2050eca0ae4aSLuiz Augusto von Dentz 		return err;
2051eca0ae4aSLuiz Augusto von Dentz 
2052eca0ae4aSLuiz Augusto von Dentz 	return hci_le_create_big(conn, &conn->iso_qos);
2053eca0ae4aSLuiz Augusto von Dentz }
2054eca0ae4aSLuiz Augusto von Dentz 
create_pa_complete(struct hci_dev * hdev,void * data,int err)2055eca0ae4aSLuiz Augusto von Dentz static void create_pa_complete(struct hci_dev *hdev, void *data, int err)
2056eca0ae4aSLuiz Augusto von Dentz {
2057eca0ae4aSLuiz Augusto von Dentz 	struct hci_cp_le_pa_create_sync *cp = data;
2058eca0ae4aSLuiz Augusto von Dentz 
2059eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
2060eca0ae4aSLuiz Augusto von Dentz 
2061eca0ae4aSLuiz Augusto von Dentz 	if (err)
2062eca0ae4aSLuiz Augusto von Dentz 		bt_dev_err(hdev, "Unable to create PA: %d", err);
2063eca0ae4aSLuiz Augusto von Dentz 
2064eca0ae4aSLuiz Augusto von Dentz 	kfree(cp);
2065eca0ae4aSLuiz Augusto von Dentz }
2066eca0ae4aSLuiz Augusto von Dentz 
create_pa_sync(struct hci_dev * hdev,void * data)2067eca0ae4aSLuiz Augusto von Dentz static int create_pa_sync(struct hci_dev *hdev, void *data)
2068eca0ae4aSLuiz Augusto von Dentz {
2069eca0ae4aSLuiz Augusto von Dentz 	struct hci_cp_le_pa_create_sync *cp = data;
2070eca0ae4aSLuiz Augusto von Dentz 	int err;
2071eca0ae4aSLuiz Augusto von Dentz 
2072eca0ae4aSLuiz Augusto von Dentz 	err = __hci_cmd_sync_status(hdev, HCI_OP_LE_PA_CREATE_SYNC,
2073eca0ae4aSLuiz Augusto von Dentz 				    sizeof(*cp), cp, HCI_CMD_TIMEOUT);
2074eca0ae4aSLuiz Augusto von Dentz 	if (err) {
2075eca0ae4aSLuiz Augusto von Dentz 		hci_dev_clear_flag(hdev, HCI_PA_SYNC);
2076eca0ae4aSLuiz Augusto von Dentz 		return err;
2077eca0ae4aSLuiz Augusto von Dentz 	}
2078eca0ae4aSLuiz Augusto von Dentz 
2079eca0ae4aSLuiz Augusto von Dentz 	return hci_update_passive_scan_sync(hdev);
2080eca0ae4aSLuiz Augusto von Dentz }
2081eca0ae4aSLuiz Augusto von Dentz 
hci_pa_create_sync(struct hci_dev * hdev,bdaddr_t * dst,__u8 dst_type,__u8 sid,struct bt_iso_qos * qos)208202171da6SIulia Tanasescu struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
208302171da6SIulia Tanasescu 				    __u8 dst_type, __u8 sid,
208402171da6SIulia Tanasescu 				    struct bt_iso_qos *qos)
2085eca0ae4aSLuiz Augusto von Dentz {
2086eca0ae4aSLuiz Augusto von Dentz 	struct hci_cp_le_pa_create_sync *cp;
208702171da6SIulia Tanasescu 	struct hci_conn *conn;
208802171da6SIulia Tanasescu 	int err;
2089eca0ae4aSLuiz Augusto von Dentz 
2090eca0ae4aSLuiz Augusto von Dentz 	if (hci_dev_test_and_set_flag(hdev, HCI_PA_SYNC))
209102171da6SIulia Tanasescu 		return ERR_PTR(-EBUSY);
209202171da6SIulia Tanasescu 
209302171da6SIulia Tanasescu 	conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_SLAVE);
2094a5b862c6SSungwoo Kim 	if (IS_ERR(conn))
2095a5b862c6SSungwoo Kim 		return conn;
209602171da6SIulia Tanasescu 
209702171da6SIulia Tanasescu 	conn->iso_qos = *qos;
209802171da6SIulia Tanasescu 	conn->state = BT_LISTEN;
209902171da6SIulia Tanasescu 
210002171da6SIulia Tanasescu 	hci_conn_hold(conn);
2101eca0ae4aSLuiz Augusto von Dentz 
210237224a29SJiapeng Chong 	cp = kzalloc(sizeof(*cp), GFP_KERNEL);
2103eca0ae4aSLuiz Augusto von Dentz 	if (!cp) {
2104eca0ae4aSLuiz Augusto von Dentz 		hci_dev_clear_flag(hdev, HCI_PA_SYNC);
210502171da6SIulia Tanasescu 		hci_conn_drop(conn);
210602171da6SIulia Tanasescu 		return ERR_PTR(-ENOMEM);
2107eca0ae4aSLuiz Augusto von Dentz 	}
2108eca0ae4aSLuiz Augusto von Dentz 
21090fe8c8d0SIulia Tanasescu 	cp->options = qos->bcast.options;
2110eca0ae4aSLuiz Augusto von Dentz 	cp->sid = sid;
2111eca0ae4aSLuiz Augusto von Dentz 	cp->addr_type = dst_type;
2112eca0ae4aSLuiz Augusto von Dentz 	bacpy(&cp->addr, dst);
21130fe8c8d0SIulia Tanasescu 	cp->skip = cpu_to_le16(qos->bcast.skip);
21140fe8c8d0SIulia Tanasescu 	cp->sync_timeout = cpu_to_le16(qos->bcast.sync_timeout);
21150fe8c8d0SIulia Tanasescu 	cp->sync_cte_type = qos->bcast.sync_cte_type;
2116eca0ae4aSLuiz Augusto von Dentz 
2117eca0ae4aSLuiz Augusto von Dentz 	/* Queue start pa_create_sync and scan */
211802171da6SIulia Tanasescu 	err = hci_cmd_sync_queue(hdev, create_pa_sync, cp, create_pa_complete);
211902171da6SIulia Tanasescu 	if (err < 0) {
212002171da6SIulia Tanasescu 		hci_conn_drop(conn);
212102171da6SIulia Tanasescu 		kfree(cp);
212202171da6SIulia Tanasescu 		return ERR_PTR(err);
212302171da6SIulia Tanasescu 	}
212402171da6SIulia Tanasescu 
212502171da6SIulia Tanasescu 	return conn;
2126eca0ae4aSLuiz Augusto von Dentz }
2127eca0ae4aSLuiz Augusto von Dentz 
hci_le_big_create_sync(struct hci_dev * hdev,struct hci_conn * hcon,struct bt_iso_qos * qos,__u16 sync_handle,__u8 num_bis,__u8 bis[])2128fbdc4bc4SIulia Tanasescu int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
2129fbdc4bc4SIulia Tanasescu 			   struct bt_iso_qos *qos,
2130eca0ae4aSLuiz Augusto von Dentz 			   __u16 sync_handle, __u8 num_bis, __u8 bis[])
2131eca0ae4aSLuiz Augusto von Dentz {
2132c90748b8SGustavo A. R. Silva 	DEFINE_FLEX(struct hci_cp_le_big_create_sync, pdu, bis, num_bis, 0x11);
2133eca0ae4aSLuiz Augusto von Dentz 	int err;
2134eca0ae4aSLuiz Augusto von Dentz 
2135c90748b8SGustavo A. R. Silva 	if (num_bis < 0x01 || num_bis > pdu->num_bis)
2136eca0ae4aSLuiz Augusto von Dentz 		return -EINVAL;
2137eca0ae4aSLuiz Augusto von Dentz 
2138eca0ae4aSLuiz Augusto von Dentz 	err = qos_set_big(hdev, qos);
2139eca0ae4aSLuiz Augusto von Dentz 	if (err)
2140eca0ae4aSLuiz Augusto von Dentz 		return err;
2141eca0ae4aSLuiz Augusto von Dentz 
2142fbdc4bc4SIulia Tanasescu 	if (hcon)
2143fbdc4bc4SIulia Tanasescu 		hcon->iso_qos.bcast.big = qos->bcast.big;
2144fbdc4bc4SIulia Tanasescu 
2145c90748b8SGustavo A. R. Silva 	pdu->handle = qos->bcast.big;
2146c90748b8SGustavo A. R. Silva 	pdu->sync_handle = cpu_to_le16(sync_handle);
2147c90748b8SGustavo A. R. Silva 	pdu->encryption = qos->bcast.encryption;
2148c90748b8SGustavo A. R. Silva 	memcpy(pdu->bcode, qos->bcast.bcode, sizeof(pdu->bcode));
2149c90748b8SGustavo A. R. Silva 	pdu->mse = qos->bcast.mse;
2150c90748b8SGustavo A. R. Silva 	pdu->timeout = cpu_to_le16(qos->bcast.timeout);
2151c90748b8SGustavo A. R. Silva 	pdu->num_bis = num_bis;
2152c90748b8SGustavo A. R. Silva 	memcpy(pdu->bis, bis, num_bis);
2153eca0ae4aSLuiz Augusto von Dentz 
2154eca0ae4aSLuiz Augusto von Dentz 	return hci_send_cmd(hdev, HCI_OP_LE_BIG_CREATE_SYNC,
2155d6bb8782SGustavo A. R. Silva 			    struct_size(pdu, bis, num_bis), pdu);
2156eca0ae4aSLuiz Augusto von Dentz }
2157eca0ae4aSLuiz Augusto von Dentz 
create_big_complete(struct hci_dev * hdev,void * data,int err)2158eca0ae4aSLuiz Augusto von Dentz static void create_big_complete(struct hci_dev *hdev, void *data, int err)
2159eca0ae4aSLuiz Augusto von Dentz {
2160eca0ae4aSLuiz Augusto von Dentz 	struct hci_conn *conn = data;
2161eca0ae4aSLuiz Augusto von Dentz 
2162eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
2163eca0ae4aSLuiz Augusto von Dentz 
2164eca0ae4aSLuiz Augusto von Dentz 	if (err) {
2165eca0ae4aSLuiz Augusto von Dentz 		bt_dev_err(hdev, "Unable to create BIG: %d", err);
2166eca0ae4aSLuiz Augusto von Dentz 		hci_connect_cfm(conn, err);
2167eca0ae4aSLuiz Augusto von Dentz 		hci_conn_del(conn);
2168eca0ae4aSLuiz Augusto von Dentz 	}
2169eca0ae4aSLuiz Augusto von Dentz }
2170eca0ae4aSLuiz Augusto von Dentz 
hci_bind_bis(struct hci_dev * hdev,bdaddr_t * dst,struct bt_iso_qos * qos,__u8 base_len,__u8 * base)2171a0bfde16SIulia Tanasescu struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst,
2172a0bfde16SIulia Tanasescu 			      struct bt_iso_qos *qos,
2173a0bfde16SIulia Tanasescu 			      __u8 base_len, __u8 *base)
2174a0bfde16SIulia Tanasescu {
2175a0bfde16SIulia Tanasescu 	struct hci_conn *conn;
2176fa224d0cSIulia Tanasescu 	struct hci_conn *parent;
2177a0bfde16SIulia Tanasescu 	__u8 eir[HCI_MAX_PER_AD_LENGTH];
2178fa224d0cSIulia Tanasescu 	struct hci_link *link;
2179fa224d0cSIulia Tanasescu 
2180fa224d0cSIulia Tanasescu 	/* Look for any BIS that is open for rebinding */
2181fa224d0cSIulia Tanasescu 	conn = hci_conn_hash_lookup_big_state(hdev, qos->bcast.big, BT_OPEN);
2182fa224d0cSIulia Tanasescu 	if (conn) {
2183fa224d0cSIulia Tanasescu 		memcpy(qos, &conn->iso_qos, sizeof(*qos));
2184fa224d0cSIulia Tanasescu 		conn->state = BT_CONNECTED;
2185fa224d0cSIulia Tanasescu 		return conn;
2186fa224d0cSIulia Tanasescu 	}
2187a0bfde16SIulia Tanasescu 
2188a0bfde16SIulia Tanasescu 	if (base_len && base)
2189a0bfde16SIulia Tanasescu 		base_len = eir_append_service_data(eir, 0,  0x1851,
2190a0bfde16SIulia Tanasescu 						   base, base_len);
2191a0bfde16SIulia Tanasescu 
2192a0bfde16SIulia Tanasescu 	/* We need hci_conn object using the BDADDR_ANY as dst */
2193a0bfde16SIulia Tanasescu 	conn = hci_add_bis(hdev, dst, qos, base_len, eir);
2194a0bfde16SIulia Tanasescu 	if (IS_ERR(conn))
2195a0bfde16SIulia Tanasescu 		return conn;
2196a0bfde16SIulia Tanasescu 
2197a0bfde16SIulia Tanasescu 	/* Update LINK PHYs according to QoS preference */
2198a0bfde16SIulia Tanasescu 	conn->le_tx_phy = qos->bcast.out.phy;
2199a0bfde16SIulia Tanasescu 	conn->le_tx_phy = qos->bcast.out.phy;
2200a0bfde16SIulia Tanasescu 
2201a0bfde16SIulia Tanasescu 	/* Add Basic Announcement into Peridic Adv Data if BASE is set */
2202a0bfde16SIulia Tanasescu 	if (base_len && base) {
2203a0bfde16SIulia Tanasescu 		memcpy(conn->le_per_adv_data,  eir, sizeof(eir));
2204a0bfde16SIulia Tanasescu 		conn->le_per_adv_data_len = base_len;
2205a0bfde16SIulia Tanasescu 	}
2206a0bfde16SIulia Tanasescu 
2207a0bfde16SIulia Tanasescu 	hci_iso_qos_setup(hdev, conn, &qos->bcast.out,
2208a0bfde16SIulia Tanasescu 			  conn->le_tx_phy ? conn->le_tx_phy :
2209a0bfde16SIulia Tanasescu 			  hdev->le_tx_def_phys);
2210a0bfde16SIulia Tanasescu 
2211a0bfde16SIulia Tanasescu 	conn->iso_qos = *qos;
2212a0bfde16SIulia Tanasescu 	conn->state = BT_BOUND;
2213a0bfde16SIulia Tanasescu 
2214fa224d0cSIulia Tanasescu 	/* Link BISes together */
2215fa224d0cSIulia Tanasescu 	parent = hci_conn_hash_lookup_big(hdev,
2216fa224d0cSIulia Tanasescu 					  conn->iso_qos.bcast.big);
2217fa224d0cSIulia Tanasescu 	if (parent && parent != conn) {
2218fa224d0cSIulia Tanasescu 		link = hci_conn_link(parent, conn);
2219fa224d0cSIulia Tanasescu 		if (!link) {
2220fa224d0cSIulia Tanasescu 			hci_conn_drop(conn);
2221fa224d0cSIulia Tanasescu 			return ERR_PTR(-ENOLINK);
2222fa224d0cSIulia Tanasescu 		}
2223fa224d0cSIulia Tanasescu 
2224fa224d0cSIulia Tanasescu 		/* Link takes the refcount */
2225fa224d0cSIulia Tanasescu 		hci_conn_drop(conn);
2226fa224d0cSIulia Tanasescu 	}
2227fa224d0cSIulia Tanasescu 
2228a0bfde16SIulia Tanasescu 	return conn;
2229a0bfde16SIulia Tanasescu }
2230a0bfde16SIulia Tanasescu 
bis_mark_per_adv(struct hci_conn * conn,void * data)2231a0bfde16SIulia Tanasescu static void bis_mark_per_adv(struct hci_conn *conn, void *data)
2232a0bfde16SIulia Tanasescu {
2233a0bfde16SIulia Tanasescu 	struct iso_list_data *d = data;
2234a0bfde16SIulia Tanasescu 
2235a0bfde16SIulia Tanasescu 	/* Skip if not broadcast/ANY address */
2236a0bfde16SIulia Tanasescu 	if (bacmp(&conn->dst, BDADDR_ANY))
2237a0bfde16SIulia Tanasescu 		return;
2238a0bfde16SIulia Tanasescu 
2239a0bfde16SIulia Tanasescu 	if (d->big != conn->iso_qos.bcast.big ||
2240a0bfde16SIulia Tanasescu 	    d->bis == BT_ISO_QOS_BIS_UNSET ||
2241a0bfde16SIulia Tanasescu 	    d->bis != conn->iso_qos.bcast.bis)
2242a0bfde16SIulia Tanasescu 		return;
2243a0bfde16SIulia Tanasescu 
2244a0bfde16SIulia Tanasescu 	set_bit(HCI_CONN_PER_ADV, &conn->flags);
2245a0bfde16SIulia Tanasescu }
2246a0bfde16SIulia Tanasescu 
hci_connect_bis(struct hci_dev * hdev,bdaddr_t * dst,__u8 dst_type,struct bt_iso_qos * qos,__u8 base_len,__u8 * base)2247eca0ae4aSLuiz Augusto von Dentz struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
2248eca0ae4aSLuiz Augusto von Dentz 				 __u8 dst_type, struct bt_iso_qos *qos,
2249eca0ae4aSLuiz Augusto von Dentz 				 __u8 base_len, __u8 *base)
2250eca0ae4aSLuiz Augusto von Dentz {
2251eca0ae4aSLuiz Augusto von Dentz 	struct hci_conn *conn;
2252eca0ae4aSLuiz Augusto von Dentz 	int err;
2253a0bfde16SIulia Tanasescu 	struct iso_list_data data;
2254eca0ae4aSLuiz Augusto von Dentz 
2255a0bfde16SIulia Tanasescu 	conn = hci_bind_bis(hdev, dst, qos, base_len, base);
2256eca0ae4aSLuiz Augusto von Dentz 	if (IS_ERR(conn))
2257eca0ae4aSLuiz Augusto von Dentz 		return conn;
2258eca0ae4aSLuiz Augusto von Dentz 
2259fa224d0cSIulia Tanasescu 	if (conn->state == BT_CONNECTED)
2260fa224d0cSIulia Tanasescu 		return conn;
2261fa224d0cSIulia Tanasescu 
2262a0bfde16SIulia Tanasescu 	data.big = qos->bcast.big;
2263a0bfde16SIulia Tanasescu 	data.bis = qos->bcast.bis;
2264eca0ae4aSLuiz Augusto von Dentz 
2265a0bfde16SIulia Tanasescu 	/* Set HCI_CONN_PER_ADV for all bound connections, to mark that
2266a0bfde16SIulia Tanasescu 	 * the start periodic advertising and create BIG commands have
2267a0bfde16SIulia Tanasescu 	 * been queued
2268a0bfde16SIulia Tanasescu 	 */
2269a0bfde16SIulia Tanasescu 	hci_conn_hash_list_state(hdev, bis_mark_per_adv, ISO_LINK,
2270a0bfde16SIulia Tanasescu 				 BT_BOUND, &data);
2271eca0ae4aSLuiz Augusto von Dentz 
2272eca0ae4aSLuiz Augusto von Dentz 	/* Queue start periodic advertising and create BIG */
2273eca0ae4aSLuiz Augusto von Dentz 	err = hci_cmd_sync_queue(hdev, create_big_sync, conn,
2274eca0ae4aSLuiz Augusto von Dentz 				 create_big_complete);
2275eca0ae4aSLuiz Augusto von Dentz 	if (err < 0) {
2276eca0ae4aSLuiz Augusto von Dentz 		hci_conn_drop(conn);
2277eca0ae4aSLuiz Augusto von Dentz 		return ERR_PTR(err);
2278eca0ae4aSLuiz Augusto von Dentz 	}
2279eca0ae4aSLuiz Augusto von Dentz 
2280eca0ae4aSLuiz Augusto von Dentz 	return conn;
2281eca0ae4aSLuiz Augusto von Dentz }
2282eca0ae4aSLuiz Augusto von Dentz 
hci_connect_cis(struct hci_dev * hdev,bdaddr_t * dst,__u8 dst_type,struct bt_iso_qos * qos)228326afbd82SLuiz Augusto von Dentz struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst,
228426afbd82SLuiz Augusto von Dentz 				 __u8 dst_type, struct bt_iso_qos *qos)
228526afbd82SLuiz Augusto von Dentz {
228626afbd82SLuiz Augusto von Dentz 	struct hci_conn *le;
228726afbd82SLuiz Augusto von Dentz 	struct hci_conn *cis;
228806149746SLuiz Augusto von Dentz 	struct hci_link *link;
228926afbd82SLuiz Augusto von Dentz 
229026afbd82SLuiz Augusto von Dentz 	if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
229126afbd82SLuiz Augusto von Dentz 		le = hci_connect_le(hdev, dst, dst_type, false,
229226afbd82SLuiz Augusto von Dentz 				    BT_SECURITY_LOW,
229326afbd82SLuiz Augusto von Dentz 				    HCI_LE_CONN_TIMEOUT,
22942e7ed5f5SLuiz Augusto von Dentz 				    HCI_ROLE_SLAVE, 0, 0);
229526afbd82SLuiz Augusto von Dentz 	else
229626afbd82SLuiz Augusto von Dentz 		le = hci_connect_le_scan(hdev, dst, dst_type,
229726afbd82SLuiz Augusto von Dentz 					 BT_SECURITY_LOW,
229826afbd82SLuiz Augusto von Dentz 					 HCI_LE_CONN_TIMEOUT,
229926afbd82SLuiz Augusto von Dentz 					 CONN_REASON_ISO_CONNECT);
230026afbd82SLuiz Augusto von Dentz 	if (IS_ERR(le))
230126afbd82SLuiz Augusto von Dentz 		return le;
230226afbd82SLuiz Augusto von Dentz 
23030fe8c8d0SIulia Tanasescu 	hci_iso_qos_setup(hdev, le, &qos->ucast.out,
230426afbd82SLuiz Augusto von Dentz 			  le->le_tx_phy ? le->le_tx_phy : hdev->le_tx_def_phys);
23050fe8c8d0SIulia Tanasescu 	hci_iso_qos_setup(hdev, le, &qos->ucast.in,
230626afbd82SLuiz Augusto von Dentz 			  le->le_rx_phy ? le->le_rx_phy : hdev->le_rx_def_phys);
230726afbd82SLuiz Augusto von Dentz 
230826afbd82SLuiz Augusto von Dentz 	cis = hci_bind_cis(hdev, dst, dst_type, qos);
230926afbd82SLuiz Augusto von Dentz 	if (IS_ERR(cis)) {
231026afbd82SLuiz Augusto von Dentz 		hci_conn_drop(le);
231126afbd82SLuiz Augusto von Dentz 		return cis;
231226afbd82SLuiz Augusto von Dentz 	}
231326afbd82SLuiz Augusto von Dentz 
231406149746SLuiz Augusto von Dentz 	link = hci_conn_link(le, cis);
231506149746SLuiz Augusto von Dentz 	if (!link) {
231606149746SLuiz Augusto von Dentz 		hci_conn_drop(le);
231706149746SLuiz Augusto von Dentz 		hci_conn_drop(cis);
2318b4066eb0SSiddh Raman Pant 		return ERR_PTR(-ENOLINK);
231906149746SLuiz Augusto von Dentz 	}
232026afbd82SLuiz Augusto von Dentz 
232169997d50SPauli Virtanen 	/* Link takes the refcount */
232269997d50SPauli Virtanen 	hci_conn_drop(cis);
232369997d50SPauli Virtanen 
23247f74563eSPauli Virtanen 	cis->state = BT_CONNECT;
23257f74563eSPauli Virtanen 
23267f74563eSPauli Virtanen 	hci_le_create_cis_pending(hdev);
232726afbd82SLuiz Augusto von Dentz 
232826afbd82SLuiz Augusto von Dentz 	return cis;
232926afbd82SLuiz Augusto von Dentz }
233026afbd82SLuiz Augusto von Dentz 
2331e7c29cb1SMarcel Holtmann /* Check link security requirement */
hci_conn_check_link_mode(struct hci_conn * conn)2332e7c29cb1SMarcel Holtmann int hci_conn_check_link_mode(struct hci_conn *conn)
2333e7c29cb1SMarcel Holtmann {
233438b3fef1SAndrei Emeltchenko 	BT_DBG("hcon %p", conn);
2335e7c29cb1SMarcel Holtmann 
233640b552aaSMarcel Holtmann 	/* In Secure Connections Only mode, it is required that Secure
233740b552aaSMarcel Holtmann 	 * Connections is used and the link is encrypted with AES-CCM
233840b552aaSMarcel Holtmann 	 * using a P-256 authenticated combination key.
233940b552aaSMarcel Holtmann 	 */
2340d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(conn->hdev, HCI_SC_ONLY)) {
234140b552aaSMarcel Holtmann 		if (!hci_conn_sc_enabled(conn) ||
234240b552aaSMarcel Holtmann 		    !test_bit(HCI_CONN_AES_CCM, &conn->flags) ||
234340b552aaSMarcel Holtmann 		    conn->key_type != HCI_LK_AUTH_COMBINATION_P256)
234440b552aaSMarcel Holtmann 			return 0;
234540b552aaSMarcel Holtmann 	}
234640b552aaSMarcel Holtmann 
23478746f135SLuiz Augusto von Dentz 	 /* AES encryption is required for Level 4:
23488746f135SLuiz Augusto von Dentz 	  *
23498746f135SLuiz Augusto von Dentz 	  * BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 3, Part C
23508746f135SLuiz Augusto von Dentz 	  * page 1319:
23518746f135SLuiz Augusto von Dentz 	  *
23528746f135SLuiz Augusto von Dentz 	  * 128-bit equivalent strength for link and encryption keys
23538746f135SLuiz Augusto von Dentz 	  * required using FIPS approved algorithms (E0 not allowed,
23548746f135SLuiz Augusto von Dentz 	  * SAFER+ not allowed, and P-192 not allowed; encryption key
23558746f135SLuiz Augusto von Dentz 	  * not shortened)
23568746f135SLuiz Augusto von Dentz 	  */
23578746f135SLuiz Augusto von Dentz 	if (conn->sec_level == BT_SECURITY_FIPS &&
23588746f135SLuiz Augusto von Dentz 	    !test_bit(HCI_CONN_AES_CCM, &conn->flags)) {
23598746f135SLuiz Augusto von Dentz 		bt_dev_err(conn->hdev,
23608746f135SLuiz Augusto von Dentz 			   "Invalid security: Missing AES-CCM usage");
23618746f135SLuiz Augusto von Dentz 		return 0;
23628746f135SLuiz Augusto von Dentz 	}
23638746f135SLuiz Augusto von Dentz 
23644dae2798SJohan Hedberg 	if (hci_conn_ssp_enabled(conn) &&
23654dae2798SJohan Hedberg 	    !test_bit(HCI_CONN_ENCRYPT, &conn->flags))
2366e7c29cb1SMarcel Holtmann 		return 0;
2367e7c29cb1SMarcel Holtmann 
2368e7c29cb1SMarcel Holtmann 	return 1;
2369e7c29cb1SMarcel Holtmann }
2370e7c29cb1SMarcel Holtmann 
23711da177e4SLinus Torvalds /* Authenticate remote device */
hci_conn_auth(struct hci_conn * conn,__u8 sec_level,__u8 auth_type)23720684e5f9SMarcel Holtmann static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
23731da177e4SLinus Torvalds {
237438b3fef1SAndrei Emeltchenko 	BT_DBG("hcon %p", conn);
23751da177e4SLinus Torvalds 
2376765c2a96SJohan Hedberg 	if (conn->pending_sec_level > sec_level)
2377765c2a96SJohan Hedberg 		sec_level = conn->pending_sec_level;
2378765c2a96SJohan Hedberg 
237996a31833SMarcel Holtmann 	if (sec_level > conn->sec_level)
2380765c2a96SJohan Hedberg 		conn->pending_sec_level = sec_level;
23814dae2798SJohan Hedberg 	else if (test_bit(HCI_CONN_AUTH, &conn->flags))
23821da177e4SLinus Torvalds 		return 1;
23831da177e4SLinus Torvalds 
238465cf686eSJohan Hedberg 	/* Make sure we preserve an existing MITM requirement*/
238565cf686eSJohan Hedberg 	auth_type |= (conn->auth_type & 0x01);
238665cf686eSJohan Hedberg 
238796a31833SMarcel Holtmann 	conn->auth_type = auth_type;
238896a31833SMarcel Holtmann 
238951a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
23901da177e4SLinus Torvalds 		struct hci_cp_auth_requested cp;
2391b7d05badSPeter Hurley 
2392aca3192cSYOSHIFUJI Hideaki 		cp.handle = cpu_to_le16(conn->handle);
239340be492fSMarcel Holtmann 		hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
239440be492fSMarcel Holtmann 			     sizeof(cp), &cp);
239509da1f34SJohan Hedberg 
2396d03376c1SLuiz Augusto von Dentz 		/* Set the ENCRYPT_PEND to trigger encryption after
2397d03376c1SLuiz Augusto von Dentz 		 * authentication.
239809da1f34SJohan Hedberg 		 */
2399d03376c1SLuiz Augusto von Dentz 		if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
240009da1f34SJohan Hedberg 			set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
24011da177e4SLinus Torvalds 	}
24028c1b2355SMarcel Holtmann 
24031da177e4SLinus Torvalds 	return 0;
24041da177e4SLinus Torvalds }
24051da177e4SLinus Torvalds 
2406bb6d6895SRandy Dunlap /* Encrypt the link */
hci_conn_encrypt(struct hci_conn * conn)240713d39315SWaldemar Rymarkiewicz static void hci_conn_encrypt(struct hci_conn *conn)
240813d39315SWaldemar Rymarkiewicz {
240938b3fef1SAndrei Emeltchenko 	BT_DBG("hcon %p", conn);
241013d39315SWaldemar Rymarkiewicz 
241151a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
241213d39315SWaldemar Rymarkiewicz 		struct hci_cp_set_conn_encrypt cp;
241313d39315SWaldemar Rymarkiewicz 		cp.handle  = cpu_to_le16(conn->handle);
241413d39315SWaldemar Rymarkiewicz 		cp.encrypt = 0x01;
241513d39315SWaldemar Rymarkiewicz 		hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
241613d39315SWaldemar Rymarkiewicz 			     &cp);
241713d39315SWaldemar Rymarkiewicz 	}
241813d39315SWaldemar Rymarkiewicz }
241913d39315SWaldemar Rymarkiewicz 
24208c1b2355SMarcel Holtmann /* Enable security */
hci_conn_security(struct hci_conn * conn,__u8 sec_level,__u8 auth_type,bool initiator)2421e7cafc45SJohan Hedberg int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type,
2422e7cafc45SJohan Hedberg 		      bool initiator)
24231da177e4SLinus Torvalds {
242438b3fef1SAndrei Emeltchenko 	BT_DBG("hcon %p", conn);
24251da177e4SLinus Torvalds 
2426d8343f12SVinicius Costa Gomes 	if (conn->type == LE_LINK)
2427d8343f12SVinicius Costa Gomes 		return smp_conn_security(conn, sec_level);
2428d8343f12SVinicius Costa Gomes 
242913d39315SWaldemar Rymarkiewicz 	/* For sdp we don't need the link key. */
24308c1b2355SMarcel Holtmann 	if (sec_level == BT_SECURITY_SDP)
24318c1b2355SMarcel Holtmann 		return 1;
24328c1b2355SMarcel Holtmann 
243313d39315SWaldemar Rymarkiewicz 	/* For non 2.1 devices and low security level we don't need the link
243413d39315SWaldemar Rymarkiewicz 	   key. */
2435aa64a8b5SJohan Hedberg 	if (sec_level == BT_SECURITY_LOW && !hci_conn_ssp_enabled(conn))
24368c1b2355SMarcel Holtmann 		return 1;
24378c1b2355SMarcel Holtmann 
243813d39315SWaldemar Rymarkiewicz 	/* For other security levels we need the link key. */
24394dae2798SJohan Hedberg 	if (!test_bit(HCI_CONN_AUTH, &conn->flags))
244013d39315SWaldemar Rymarkiewicz 		goto auth;
24411da177e4SLinus Torvalds 
24421d8e8014SYing Hsu 	switch (conn->key_type) {
24431d8e8014SYing Hsu 	case HCI_LK_AUTH_COMBINATION_P256:
24441d8e8014SYing Hsu 		/* An authenticated FIPS approved combination key has
24451d8e8014SYing Hsu 		 * sufficient security for security level 4 or lower.
24461d8e8014SYing Hsu 		 */
24471d8e8014SYing Hsu 		if (sec_level <= BT_SECURITY_FIPS)
24487b5a9241SMarcel Holtmann 			goto encrypt;
24491d8e8014SYing Hsu 		break;
24501d8e8014SYing Hsu 	case HCI_LK_AUTH_COMBINATION_P192:
24517b5a9241SMarcel Holtmann 		/* An authenticated combination key has sufficient security for
24521d8e8014SYing Hsu 		 * security level 3 or lower.
24531d8e8014SYing Hsu 		 */
24541d8e8014SYing Hsu 		if (sec_level <= BT_SECURITY_HIGH)
245513d39315SWaldemar Rymarkiewicz 			goto encrypt;
24561d8e8014SYing Hsu 		break;
24571d8e8014SYing Hsu 	case HCI_LK_UNAUTH_COMBINATION_P192:
24581d8e8014SYing Hsu 	case HCI_LK_UNAUTH_COMBINATION_P256:
24591d8e8014SYing Hsu 		/* An unauthenticated combination key has sufficient security
24601d8e8014SYing Hsu 		 * for security level 2 or lower.
24611d8e8014SYing Hsu 		 */
24621d8e8014SYing Hsu 		if (sec_level <= BT_SECURITY_MEDIUM)
246313d39315SWaldemar Rymarkiewicz 			goto encrypt;
24641d8e8014SYing Hsu 		break;
24651d8e8014SYing Hsu 	case HCI_LK_COMBINATION:
24661d8e8014SYing Hsu 		/* A combination key has always sufficient security for the
24671d8e8014SYing Hsu 		 * security levels 2 or lower. High security level requires the
24681d8e8014SYing Hsu 		 * combination key is generated using maximum PIN code length
24691d8e8014SYing Hsu 		 * (16). For pre 2.1 units.
24701d8e8014SYing Hsu 		 */
24711d8e8014SYing Hsu 		if (sec_level <= BT_SECURITY_MEDIUM || conn->pin_length == 16)
247213d39315SWaldemar Rymarkiewicz 			goto encrypt;
24731d8e8014SYing Hsu 		break;
24741d8e8014SYing Hsu 	default:
24751d8e8014SYing Hsu 		break;
24761d8e8014SYing Hsu 	}
247713d39315SWaldemar Rymarkiewicz 
247813d39315SWaldemar Rymarkiewicz auth:
247951a8efd7SJohan Hedberg 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
24801da177e4SLinus Torvalds 		return 0;
24811da177e4SLinus Torvalds 
2482977f8fceSJohan Hedberg 	if (initiator)
2483977f8fceSJohan Hedberg 		set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
2484977f8fceSJohan Hedberg 
24856fdf658cSLuiz Augusto von Dentz 	if (!hci_conn_auth(conn, sec_level, auth_type))
248613d39315SWaldemar Rymarkiewicz 		return 0;
24878c1b2355SMarcel Holtmann 
248813d39315SWaldemar Rymarkiewicz encrypt:
2489693cd8ceSMarcel Holtmann 	if (test_bit(HCI_CONN_ENCRYPT, &conn->flags)) {
2490693cd8ceSMarcel Holtmann 		/* Ensure that the encryption key size has been read,
2491693cd8ceSMarcel Holtmann 		 * otherwise stall the upper layer responses.
2492693cd8ceSMarcel Holtmann 		 */
2493693cd8ceSMarcel Holtmann 		if (!conn->enc_key_size)
2494693cd8ceSMarcel Holtmann 			return 0;
2495693cd8ceSMarcel Holtmann 
2496693cd8ceSMarcel Holtmann 		/* Nothing else needed, all requirements are met */
249713d39315SWaldemar Rymarkiewicz 		return 1;
2498693cd8ceSMarcel Holtmann 	}
249913d39315SWaldemar Rymarkiewicz 
250013d39315SWaldemar Rymarkiewicz 	hci_conn_encrypt(conn);
25011da177e4SLinus Torvalds 	return 0;
25021da177e4SLinus Torvalds }
25038c1b2355SMarcel Holtmann EXPORT_SYMBOL(hci_conn_security);
25041da177e4SLinus Torvalds 
2505b3b1b061SWaldemar Rymarkiewicz /* Check secure link requirement */
hci_conn_check_secure(struct hci_conn * conn,__u8 sec_level)2506b3b1b061SWaldemar Rymarkiewicz int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level)
2507b3b1b061SWaldemar Rymarkiewicz {
250838b3fef1SAndrei Emeltchenko 	BT_DBG("hcon %p", conn);
2509b3b1b061SWaldemar Rymarkiewicz 
25109cb2e030SMarcel Holtmann 	/* Accept if non-secure or higher security level is required */
25119cb2e030SMarcel Holtmann 	if (sec_level != BT_SECURITY_HIGH && sec_level != BT_SECURITY_FIPS)
2512b3b1b061SWaldemar Rymarkiewicz 		return 1;
2513b3b1b061SWaldemar Rymarkiewicz 
25149cb2e030SMarcel Holtmann 	/* Accept if secure or higher security level is already present */
25159cb2e030SMarcel Holtmann 	if (conn->sec_level == BT_SECURITY_HIGH ||
25169cb2e030SMarcel Holtmann 	    conn->sec_level == BT_SECURITY_FIPS)
25179cb2e030SMarcel Holtmann 		return 1;
25189cb2e030SMarcel Holtmann 
25199cb2e030SMarcel Holtmann 	/* Reject not secure link */
25209cb2e030SMarcel Holtmann 	return 0;
2521b3b1b061SWaldemar Rymarkiewicz }
2522b3b1b061SWaldemar Rymarkiewicz EXPORT_SYMBOL(hci_conn_check_secure);
2523b3b1b061SWaldemar Rymarkiewicz 
25241da177e4SLinus Torvalds /* Switch role */
hci_conn_switch_role(struct hci_conn * conn,__u8 role)25258c1b2355SMarcel Holtmann int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
25261da177e4SLinus Torvalds {
252738b3fef1SAndrei Emeltchenko 	BT_DBG("hcon %p", conn);
25281da177e4SLinus Torvalds 
252940bef302SJohan Hedberg 	if (role == conn->role)
25301da177e4SLinus Torvalds 		return 1;
25311da177e4SLinus Torvalds 
253251a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->flags)) {
25331da177e4SLinus Torvalds 		struct hci_cp_switch_role cp;
25341da177e4SLinus Torvalds 		bacpy(&cp.bdaddr, &conn->dst);
25351da177e4SLinus Torvalds 		cp.role = role;
2536a9de9248SMarcel Holtmann 		hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp);
25371da177e4SLinus Torvalds 	}
25388c1b2355SMarcel Holtmann 
25391da177e4SLinus Torvalds 	return 0;
25401da177e4SLinus Torvalds }
25411da177e4SLinus Torvalds EXPORT_SYMBOL(hci_conn_switch_role);
25421da177e4SLinus Torvalds 
254304837f64SMarcel Holtmann /* Enter active mode */
hci_conn_enter_active_mode(struct hci_conn * conn,__u8 force_active)254414b12d0bSJaikumar Ganesh void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active)
254504837f64SMarcel Holtmann {
254604837f64SMarcel Holtmann 	struct hci_dev *hdev = conn->hdev;
254704837f64SMarcel Holtmann 
254838b3fef1SAndrei Emeltchenko 	BT_DBG("hcon %p mode %d", conn, conn->mode);
254904837f64SMarcel Holtmann 
255014b12d0bSJaikumar Ganesh 	if (conn->mode != HCI_CM_SNIFF)
255114b12d0bSJaikumar Ganesh 		goto timer;
255214b12d0bSJaikumar Ganesh 
255358a681efSJohan Hedberg 	if (!test_bit(HCI_CONN_POWER_SAVE, &conn->flags) && !force_active)
255404837f64SMarcel Holtmann 		goto timer;
255504837f64SMarcel Holtmann 
255651a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
255704837f64SMarcel Holtmann 		struct hci_cp_exit_sniff_mode cp;
2558aca3192cSYOSHIFUJI Hideaki 		cp.handle = cpu_to_le16(conn->handle);
2559a9de9248SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_EXIT_SNIFF_MODE, sizeof(cp), &cp);
256004837f64SMarcel Holtmann 	}
256104837f64SMarcel Holtmann 
256204837f64SMarcel Holtmann timer:
256304837f64SMarcel Holtmann 	if (hdev->idle_timeout > 0)
2564a74a84f6SJohan Hedberg 		queue_delayed_work(hdev->workqueue, &conn->idle_work,
2565a74a84f6SJohan Hedberg 				   msecs_to_jiffies(hdev->idle_timeout));
256604837f64SMarcel Holtmann }
256704837f64SMarcel Holtmann 
25681da177e4SLinus Torvalds /* Drop all connection on the device */
hci_conn_hash_flush(struct hci_dev * hdev)25691da177e4SLinus Torvalds void hci_conn_hash_flush(struct hci_dev *hdev)
25701da177e4SLinus Torvalds {
2571a2ac591cSRuihan Li 	struct list_head *head = &hdev->conn_hash.list;
2572a2ac591cSRuihan Li 	struct hci_conn *conn;
25731da177e4SLinus Torvalds 
25741da177e4SLinus Torvalds 	BT_DBG("hdev %s", hdev->name);
25751da177e4SLinus Torvalds 
2576a2ac591cSRuihan Li 	/* We should not traverse the list here, because hci_conn_del
2577a2ac591cSRuihan Li 	 * can remove extra links, which may cause the list traversal
2578a2ac591cSRuihan Li 	 * to hit items that have already been released.
2579a2ac591cSRuihan Li 	 */
2580a2ac591cSRuihan Li 	while ((conn = list_first_entry_or_null(head,
2581a2ac591cSRuihan Li 						struct hci_conn,
2582a2ac591cSRuihan Li 						list)) != NULL) {
2583a2ac591cSRuihan Li 		conn->state = BT_CLOSED;
2584a2ac591cSRuihan Li 		hci_disconn_cfm(conn, HCI_ERROR_LOCAL_HOST_TERM);
2585a2ac591cSRuihan Li 		hci_conn_del(conn);
25861da177e4SLinus Torvalds 	}
25871da177e4SLinus Torvalds }
25881da177e4SLinus Torvalds 
get_link_mode(struct hci_conn * conn)25894dae2798SJohan Hedberg static u32 get_link_mode(struct hci_conn *conn)
25904dae2798SJohan Hedberg {
25914dae2798SJohan Hedberg 	u32 link_mode = 0;
25924dae2798SJohan Hedberg 
259340bef302SJohan Hedberg 	if (conn->role == HCI_ROLE_MASTER)
25944dae2798SJohan Hedberg 		link_mode |= HCI_LM_MASTER;
25954dae2798SJohan Hedberg 
25964dae2798SJohan Hedberg 	if (test_bit(HCI_CONN_ENCRYPT, &conn->flags))
25974dae2798SJohan Hedberg 		link_mode |= HCI_LM_ENCRYPT;
25984dae2798SJohan Hedberg 
25994dae2798SJohan Hedberg 	if (test_bit(HCI_CONN_AUTH, &conn->flags))
26004dae2798SJohan Hedberg 		link_mode |= HCI_LM_AUTH;
26014dae2798SJohan Hedberg 
26024dae2798SJohan Hedberg 	if (test_bit(HCI_CONN_SECURE, &conn->flags))
26034dae2798SJohan Hedberg 		link_mode |= HCI_LM_SECURE;
26044dae2798SJohan Hedberg 
26054dae2798SJohan Hedberg 	if (test_bit(HCI_CONN_FIPS, &conn->flags))
26064dae2798SJohan Hedberg 		link_mode |= HCI_LM_FIPS;
26074dae2798SJohan Hedberg 
26084dae2798SJohan Hedberg 	return link_mode;
26094dae2798SJohan Hedberg }
26104dae2798SJohan Hedberg 
hci_get_conn_list(void __user * arg)26111da177e4SLinus Torvalds int hci_get_conn_list(void __user *arg)
26121da177e4SLinus Torvalds {
2613fc5fef61SGustavo Padovan 	struct hci_conn *c;
26141da177e4SLinus Torvalds 	struct hci_conn_list_req req, *cl;
26151da177e4SLinus Torvalds 	struct hci_conn_info *ci;
26161da177e4SLinus Torvalds 	struct hci_dev *hdev;
26171da177e4SLinus Torvalds 	int n = 0, size, err;
26181da177e4SLinus Torvalds 
26191da177e4SLinus Torvalds 	if (copy_from_user(&req, arg, sizeof(req)))
26201da177e4SLinus Torvalds 		return -EFAULT;
26211da177e4SLinus Torvalds 
26221da177e4SLinus Torvalds 	if (!req.conn_num || req.conn_num > (PAGE_SIZE * 2) / sizeof(*ci))
26231da177e4SLinus Torvalds 		return -EINVAL;
26241da177e4SLinus Torvalds 
26251da177e4SLinus Torvalds 	size = sizeof(req) + req.conn_num * sizeof(*ci);
26261da177e4SLinus Torvalds 
262770f23020SAndrei Emeltchenko 	cl = kmalloc(size, GFP_KERNEL);
262870f23020SAndrei Emeltchenko 	if (!cl)
26291da177e4SLinus Torvalds 		return -ENOMEM;
26301da177e4SLinus Torvalds 
263170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(req.dev_id);
263270f23020SAndrei Emeltchenko 	if (!hdev) {
26331da177e4SLinus Torvalds 		kfree(cl);
26341da177e4SLinus Torvalds 		return -ENODEV;
26351da177e4SLinus Torvalds 	}
26361da177e4SLinus Torvalds 
26371da177e4SLinus Torvalds 	ci = cl->conn_info;
26381da177e4SLinus Torvalds 
263909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
26408035ded4SLuiz Augusto von Dentz 	list_for_each_entry(c, &hdev->conn_hash.list, list) {
26411da177e4SLinus Torvalds 		bacpy(&(ci + n)->bdaddr, &c->dst);
26421da177e4SLinus Torvalds 		(ci + n)->handle = c->handle;
26431da177e4SLinus Torvalds 		(ci + n)->type  = c->type;
26441da177e4SLinus Torvalds 		(ci + n)->out   = c->out;
26451da177e4SLinus Torvalds 		(ci + n)->state = c->state;
26464dae2798SJohan Hedberg 		(ci + n)->link_mode = get_link_mode(c);
26471da177e4SLinus Torvalds 		if (++n >= req.conn_num)
26481da177e4SLinus Torvalds 			break;
26491da177e4SLinus Torvalds 	}
265009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
26511da177e4SLinus Torvalds 
26521da177e4SLinus Torvalds 	cl->dev_id = hdev->id;
26531da177e4SLinus Torvalds 	cl->conn_num = n;
26541da177e4SLinus Torvalds 	size = sizeof(req) + n * sizeof(*ci);
26551da177e4SLinus Torvalds 
26561da177e4SLinus Torvalds 	hci_dev_put(hdev);
26571da177e4SLinus Torvalds 
26581da177e4SLinus Torvalds 	err = copy_to_user(arg, cl, size);
26591da177e4SLinus Torvalds 	kfree(cl);
26601da177e4SLinus Torvalds 
26611da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
26621da177e4SLinus Torvalds }
26631da177e4SLinus Torvalds 
hci_get_conn_info(struct hci_dev * hdev,void __user * arg)26641da177e4SLinus Torvalds int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
26651da177e4SLinus Torvalds {
26661da177e4SLinus Torvalds 	struct hci_conn_info_req req;
26671da177e4SLinus Torvalds 	struct hci_conn_info ci;
26681da177e4SLinus Torvalds 	struct hci_conn *conn;
26691da177e4SLinus Torvalds 	char __user *ptr = arg + sizeof(req);
26701da177e4SLinus Torvalds 
26711da177e4SLinus Torvalds 	if (copy_from_user(&req, arg, sizeof(req)))
26721da177e4SLinus Torvalds 		return -EFAULT;
26731da177e4SLinus Torvalds 
267409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
26751da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
26761da177e4SLinus Torvalds 	if (conn) {
26771da177e4SLinus Torvalds 		bacpy(&ci.bdaddr, &conn->dst);
26781da177e4SLinus Torvalds 		ci.handle = conn->handle;
26791da177e4SLinus Torvalds 		ci.type  = conn->type;
26801da177e4SLinus Torvalds 		ci.out   = conn->out;
26811da177e4SLinus Torvalds 		ci.state = conn->state;
26824dae2798SJohan Hedberg 		ci.link_mode = get_link_mode(conn);
26831da177e4SLinus Torvalds 	}
268409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
26851da177e4SLinus Torvalds 
26861da177e4SLinus Torvalds 	if (!conn)
26871da177e4SLinus Torvalds 		return -ENOENT;
26881da177e4SLinus Torvalds 
26891da177e4SLinus Torvalds 	return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0;
26901da177e4SLinus Torvalds }
269140be492fSMarcel Holtmann 
hci_get_auth_info(struct hci_dev * hdev,void __user * arg)269240be492fSMarcel Holtmann int hci_get_auth_info(struct hci_dev *hdev, void __user *arg)
269340be492fSMarcel Holtmann {
269440be492fSMarcel Holtmann 	struct hci_auth_info_req req;
269540be492fSMarcel Holtmann 	struct hci_conn *conn;
269640be492fSMarcel Holtmann 
269740be492fSMarcel Holtmann 	if (copy_from_user(&req, arg, sizeof(req)))
269840be492fSMarcel Holtmann 		return -EFAULT;
269940be492fSMarcel Holtmann 
270009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
270140be492fSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr);
270240be492fSMarcel Holtmann 	if (conn)
270340be492fSMarcel Holtmann 		req.type = conn->auth_type;
270409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
270540be492fSMarcel Holtmann 
270640be492fSMarcel Holtmann 	if (!conn)
270740be492fSMarcel Holtmann 		return -ENOENT;
270840be492fSMarcel Holtmann 
270940be492fSMarcel Holtmann 	return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0;
271040be492fSMarcel Holtmann }
271173d80debSLuiz Augusto von Dentz 
hci_chan_create(struct hci_conn * conn)271273d80debSLuiz Augusto von Dentz struct hci_chan *hci_chan_create(struct hci_conn *conn)
271373d80debSLuiz Augusto von Dentz {
271473d80debSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
271573d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
271673d80debSLuiz Augusto von Dentz 
271738b3fef1SAndrei Emeltchenko 	BT_DBG("%s hcon %p", hdev->name, conn);
271873d80debSLuiz Augusto von Dentz 
2719f94b665dSJohan Hedberg 	if (test_bit(HCI_CONN_DROP, &conn->flags)) {
2720f94b665dSJohan Hedberg 		BT_DBG("Refusing to create new hci_chan");
2721f94b665dSJohan Hedberg 		return NULL;
2722f94b665dSJohan Hedberg 	}
2723f94b665dSJohan Hedberg 
272427f70f3eSJohan Hedberg 	chan = kzalloc(sizeof(*chan), GFP_KERNEL);
272573d80debSLuiz Augusto von Dentz 	if (!chan)
272673d80debSLuiz Augusto von Dentz 		return NULL;
272773d80debSLuiz Augusto von Dentz 
27286c388d32SJohan Hedberg 	chan->conn = hci_conn_get(conn);
272973d80debSLuiz Augusto von Dentz 	skb_queue_head_init(&chan->data_q);
2730168df8e5SMat Martineau 	chan->state = BT_CONNECTED;
273173d80debSLuiz Augusto von Dentz 
27328192edefSGustavo F. Padovan 	list_add_rcu(&chan->list, &conn->chan_list);
273373d80debSLuiz Augusto von Dentz 
273473d80debSLuiz Augusto von Dentz 	return chan;
273573d80debSLuiz Augusto von Dentz }
273673d80debSLuiz Augusto von Dentz 
hci_chan_del(struct hci_chan * chan)27379472007cSAndrei Emeltchenko void hci_chan_del(struct hci_chan *chan)
273873d80debSLuiz Augusto von Dentz {
273973d80debSLuiz Augusto von Dentz 	struct hci_conn *conn = chan->conn;
274073d80debSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
274173d80debSLuiz Augusto von Dentz 
274238b3fef1SAndrei Emeltchenko 	BT_DBG("%s hcon %p chan %p", hdev->name, conn, chan);
274373d80debSLuiz Augusto von Dentz 
27448192edefSGustavo F. Padovan 	list_del_rcu(&chan->list);
27458192edefSGustavo F. Padovan 
27468192edefSGustavo F. Padovan 	synchronize_rcu();
274773d80debSLuiz Augusto von Dentz 
2748bcbb655aSJohan Hedberg 	/* Prevent new hci_chan's to be created for this hci_conn */
2749f94b665dSJohan Hedberg 	set_bit(HCI_CONN_DROP, &conn->flags);
2750b3ff670aSJohan Hedberg 
27516c388d32SJohan Hedberg 	hci_conn_put(conn);
2752e9b02748SAndrei Emeltchenko 
275373d80debSLuiz Augusto von Dentz 	skb_queue_purge(&chan->data_q);
275473d80debSLuiz Augusto von Dentz 	kfree(chan);
275573d80debSLuiz Augusto von Dentz }
275673d80debSLuiz Augusto von Dentz 
hci_chan_list_flush(struct hci_conn * conn)27572c33c06aSGustavo F. Padovan void hci_chan_list_flush(struct hci_conn *conn)
275873d80debSLuiz Augusto von Dentz {
27592a5a5ec6SAndrei Emeltchenko 	struct hci_chan *chan, *n;
276073d80debSLuiz Augusto von Dentz 
276138b3fef1SAndrei Emeltchenko 	BT_DBG("hcon %p", conn);
276273d80debSLuiz Augusto von Dentz 
27632a5a5ec6SAndrei Emeltchenko 	list_for_each_entry_safe(chan, n, &conn->chan_list, list)
276473d80debSLuiz Augusto von Dentz 		hci_chan_del(chan);
276573d80debSLuiz Augusto von Dentz }
276642c4e53eSAndrei Emeltchenko 
__hci_chan_lookup_handle(struct hci_conn * hcon,__u16 handle)276742c4e53eSAndrei Emeltchenko static struct hci_chan *__hci_chan_lookup_handle(struct hci_conn *hcon,
276842c4e53eSAndrei Emeltchenko 						 __u16 handle)
276942c4e53eSAndrei Emeltchenko {
277042c4e53eSAndrei Emeltchenko 	struct hci_chan *hchan;
277142c4e53eSAndrei Emeltchenko 
277242c4e53eSAndrei Emeltchenko 	list_for_each_entry(hchan, &hcon->chan_list, list) {
277342c4e53eSAndrei Emeltchenko 		if (hchan->handle == handle)
277442c4e53eSAndrei Emeltchenko 			return hchan;
277542c4e53eSAndrei Emeltchenko 	}
277642c4e53eSAndrei Emeltchenko 
277742c4e53eSAndrei Emeltchenko 	return NULL;
277842c4e53eSAndrei Emeltchenko }
277942c4e53eSAndrei Emeltchenko 
hci_chan_lookup_handle(struct hci_dev * hdev,__u16 handle)278042c4e53eSAndrei Emeltchenko struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle)
278142c4e53eSAndrei Emeltchenko {
278242c4e53eSAndrei Emeltchenko 	struct hci_conn_hash *h = &hdev->conn_hash;
278342c4e53eSAndrei Emeltchenko 	struct hci_conn *hcon;
278442c4e53eSAndrei Emeltchenko 	struct hci_chan *hchan = NULL;
278542c4e53eSAndrei Emeltchenko 
278642c4e53eSAndrei Emeltchenko 	rcu_read_lock();
278742c4e53eSAndrei Emeltchenko 
278842c4e53eSAndrei Emeltchenko 	list_for_each_entry_rcu(hcon, &h->list, list) {
278942c4e53eSAndrei Emeltchenko 		hchan = __hci_chan_lookup_handle(hcon, handle);
279042c4e53eSAndrei Emeltchenko 		if (hchan)
279142c4e53eSAndrei Emeltchenko 			break;
279242c4e53eSAndrei Emeltchenko 	}
279342c4e53eSAndrei Emeltchenko 
279442c4e53eSAndrei Emeltchenko 	rcu_read_unlock();
279542c4e53eSAndrei Emeltchenko 
279642c4e53eSAndrei Emeltchenko 	return hchan;
279742c4e53eSAndrei Emeltchenko }
2798eab2404bSLuiz Augusto von Dentz 
hci_conn_get_phy(struct hci_conn * conn)2799eab2404bSLuiz Augusto von Dentz u32 hci_conn_get_phy(struct hci_conn *conn)
2800eab2404bSLuiz Augusto von Dentz {
2801eab2404bSLuiz Augusto von Dentz 	u32 phys = 0;
2802eab2404bSLuiz Augusto von Dentz 
2803eab2404bSLuiz Augusto von Dentz 	/* BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 2, Part B page 471:
2804eab2404bSLuiz Augusto von Dentz 	 * Table 6.2: Packets defined for synchronous, asynchronous, and
28056397729bSArchie Pusaka 	 * CPB logical transport types.
2806eab2404bSLuiz Augusto von Dentz 	 */
2807eab2404bSLuiz Augusto von Dentz 	switch (conn->type) {
2808eab2404bSLuiz Augusto von Dentz 	case SCO_LINK:
2809eab2404bSLuiz Augusto von Dentz 		/* SCO logical transport (1 Mb/s):
2810eab2404bSLuiz Augusto von Dentz 		 * HV1, HV2, HV3 and DV.
2811eab2404bSLuiz Augusto von Dentz 		 */
2812eab2404bSLuiz Augusto von Dentz 		phys |= BT_PHY_BR_1M_1SLOT;
2813eab2404bSLuiz Augusto von Dentz 
2814eab2404bSLuiz Augusto von Dentz 		break;
2815eab2404bSLuiz Augusto von Dentz 
2816eab2404bSLuiz Augusto von Dentz 	case ACL_LINK:
2817eab2404bSLuiz Augusto von Dentz 		/* ACL logical transport (1 Mb/s) ptt=0:
2818eab2404bSLuiz Augusto von Dentz 		 * DH1, DM3, DH3, DM5 and DH5.
2819eab2404bSLuiz Augusto von Dentz 		 */
2820eab2404bSLuiz Augusto von Dentz 		phys |= BT_PHY_BR_1M_1SLOT;
2821eab2404bSLuiz Augusto von Dentz 
2822eab2404bSLuiz Augusto von Dentz 		if (conn->pkt_type & (HCI_DM3 | HCI_DH3))
2823eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_BR_1M_3SLOT;
2824eab2404bSLuiz Augusto von Dentz 
2825eab2404bSLuiz Augusto von Dentz 		if (conn->pkt_type & (HCI_DM5 | HCI_DH5))
2826eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_BR_1M_5SLOT;
2827eab2404bSLuiz Augusto von Dentz 
2828eab2404bSLuiz Augusto von Dentz 		/* ACL logical transport (2 Mb/s) ptt=1:
2829eab2404bSLuiz Augusto von Dentz 		 * 2-DH1, 2-DH3 and 2-DH5.
2830eab2404bSLuiz Augusto von Dentz 		 */
2831eab2404bSLuiz Augusto von Dentz 		if (!(conn->pkt_type & HCI_2DH1))
2832eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_EDR_2M_1SLOT;
2833eab2404bSLuiz Augusto von Dentz 
2834eab2404bSLuiz Augusto von Dentz 		if (!(conn->pkt_type & HCI_2DH3))
2835eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_EDR_2M_3SLOT;
2836eab2404bSLuiz Augusto von Dentz 
2837eab2404bSLuiz Augusto von Dentz 		if (!(conn->pkt_type & HCI_2DH5))
2838eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_EDR_2M_5SLOT;
2839eab2404bSLuiz Augusto von Dentz 
2840eab2404bSLuiz Augusto von Dentz 		/* ACL logical transport (3 Mb/s) ptt=1:
2841eab2404bSLuiz Augusto von Dentz 		 * 3-DH1, 3-DH3 and 3-DH5.
2842eab2404bSLuiz Augusto von Dentz 		 */
2843eab2404bSLuiz Augusto von Dentz 		if (!(conn->pkt_type & HCI_3DH1))
2844eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_EDR_3M_1SLOT;
2845eab2404bSLuiz Augusto von Dentz 
2846eab2404bSLuiz Augusto von Dentz 		if (!(conn->pkt_type & HCI_3DH3))
2847eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_EDR_3M_3SLOT;
2848eab2404bSLuiz Augusto von Dentz 
2849eab2404bSLuiz Augusto von Dentz 		if (!(conn->pkt_type & HCI_3DH5))
2850eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_EDR_3M_5SLOT;
2851eab2404bSLuiz Augusto von Dentz 
2852eab2404bSLuiz Augusto von Dentz 		break;
2853eab2404bSLuiz Augusto von Dentz 
2854eab2404bSLuiz Augusto von Dentz 	case ESCO_LINK:
2855eab2404bSLuiz Augusto von Dentz 		/* eSCO logical transport (1 Mb/s): EV3, EV4 and EV5 */
2856eab2404bSLuiz Augusto von Dentz 		phys |= BT_PHY_BR_1M_1SLOT;
2857eab2404bSLuiz Augusto von Dentz 
2858eab2404bSLuiz Augusto von Dentz 		if (!(conn->pkt_type & (ESCO_EV4 | ESCO_EV5)))
2859eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_BR_1M_3SLOT;
2860eab2404bSLuiz Augusto von Dentz 
2861eab2404bSLuiz Augusto von Dentz 		/* eSCO logical transport (2 Mb/s): 2-EV3, 2-EV5 */
2862eab2404bSLuiz Augusto von Dentz 		if (!(conn->pkt_type & ESCO_2EV3))
2863eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_EDR_2M_1SLOT;
2864eab2404bSLuiz Augusto von Dentz 
2865eab2404bSLuiz Augusto von Dentz 		if (!(conn->pkt_type & ESCO_2EV5))
2866eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_EDR_2M_3SLOT;
2867eab2404bSLuiz Augusto von Dentz 
2868eab2404bSLuiz Augusto von Dentz 		/* eSCO logical transport (3 Mb/s): 3-EV3, 3-EV5 */
2869eab2404bSLuiz Augusto von Dentz 		if (!(conn->pkt_type & ESCO_3EV3))
2870eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_EDR_3M_1SLOT;
2871eab2404bSLuiz Augusto von Dentz 
2872eab2404bSLuiz Augusto von Dentz 		if (!(conn->pkt_type & ESCO_3EV5))
2873eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_EDR_3M_3SLOT;
2874eab2404bSLuiz Augusto von Dentz 
2875eab2404bSLuiz Augusto von Dentz 		break;
2876eab2404bSLuiz Augusto von Dentz 
2877eab2404bSLuiz Augusto von Dentz 	case LE_LINK:
2878eab2404bSLuiz Augusto von Dentz 		if (conn->le_tx_phy & HCI_LE_SET_PHY_1M)
2879eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_LE_1M_TX;
2880eab2404bSLuiz Augusto von Dentz 
2881eab2404bSLuiz Augusto von Dentz 		if (conn->le_rx_phy & HCI_LE_SET_PHY_1M)
2882eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_LE_1M_RX;
2883eab2404bSLuiz Augusto von Dentz 
2884eab2404bSLuiz Augusto von Dentz 		if (conn->le_tx_phy & HCI_LE_SET_PHY_2M)
2885eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_LE_2M_TX;
2886eab2404bSLuiz Augusto von Dentz 
2887eab2404bSLuiz Augusto von Dentz 		if (conn->le_rx_phy & HCI_LE_SET_PHY_2M)
2888eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_LE_2M_RX;
2889eab2404bSLuiz Augusto von Dentz 
2890eab2404bSLuiz Augusto von Dentz 		if (conn->le_tx_phy & HCI_LE_SET_PHY_CODED)
2891eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_LE_CODED_TX;
2892eab2404bSLuiz Augusto von Dentz 
2893eab2404bSLuiz Augusto von Dentz 		if (conn->le_rx_phy & HCI_LE_SET_PHY_CODED)
2894eab2404bSLuiz Augusto von Dentz 			phys |= BT_PHY_LE_CODED_RX;
2895eab2404bSLuiz Augusto von Dentz 
2896eab2404bSLuiz Augusto von Dentz 		break;
2897eab2404bSLuiz Augusto von Dentz 	}
2898eab2404bSLuiz Augusto von Dentz 
2899eab2404bSLuiz Augusto von Dentz 	return phys;
2900eab2404bSLuiz Augusto von Dentz }
29011a942de0SBrian Gix 
abort_conn_sync(struct hci_dev * hdev,void * data)2902a13f316eSLuiz Augusto von Dentz static int abort_conn_sync(struct hci_dev *hdev, void *data)
29031a942de0SBrian Gix {
2904881559afSLuiz Augusto von Dentz 	struct hci_conn *conn = data;
29051a942de0SBrian Gix 
2906881559afSLuiz Augusto von Dentz 	if (!hci_conn_valid(hdev, conn))
2907881559afSLuiz Augusto von Dentz 		return -ECANCELED;
2908b62e7220SLuiz Augusto von Dentz 
2909a13f316eSLuiz Augusto von Dentz 	return hci_abort_conn_sync(hdev, conn, conn->abort_reason);
29101a942de0SBrian Gix }
29111a942de0SBrian Gix 
hci_abort_conn(struct hci_conn * conn,u8 reason)2912a13f316eSLuiz Augusto von Dentz int hci_abort_conn(struct hci_conn *conn, u8 reason)
2913a13f316eSLuiz Augusto von Dentz {
2914a13f316eSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
29151a942de0SBrian Gix 
2916a13f316eSLuiz Augusto von Dentz 	/* If abort_reason has already been set it means the connection is
2917a13f316eSLuiz Augusto von Dentz 	 * already being aborted so don't attempt to overwrite it.
29181a942de0SBrian Gix 	 */
2919a13f316eSLuiz Augusto von Dentz 	if (conn->abort_reason)
2920a13f316eSLuiz Augusto von Dentz 		return 0;
29211a942de0SBrian Gix 
2922a13f316eSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%2.2x reason 0x%2.2x", conn->handle, reason);
2923a13f316eSLuiz Augusto von Dentz 
2924a13f316eSLuiz Augusto von Dentz 	conn->abort_reason = reason;
2925a13f316eSLuiz Augusto von Dentz 
2926a13f316eSLuiz Augusto von Dentz 	/* If the connection is pending check the command opcode since that
2927a13f316eSLuiz Augusto von Dentz 	 * might be blocking on hci_cmd_sync_work while waiting its respective
2928a13f316eSLuiz Augusto von Dentz 	 * event so we need to hci_cmd_sync_cancel to cancel it.
292904a51d61SLuiz Augusto von Dentz 	 *
293004a51d61SLuiz Augusto von Dentz 	 * hci_connect_le serializes the connection attempts so only one
293104a51d61SLuiz Augusto von Dentz 	 * connection can be in BT_CONNECT at time.
2932a13f316eSLuiz Augusto von Dentz 	 */
2933a13f316eSLuiz Augusto von Dentz 	if (conn->state == BT_CONNECT && hdev->req_status == HCI_REQ_PEND) {
2934a13f316eSLuiz Augusto von Dentz 		switch (hci_skb_event(hdev->sent_cmd)) {
29355f641f03SLuiz Augusto von Dentz 		case HCI_EV_CONN_COMPLETE:
2936a13f316eSLuiz Augusto von Dentz 		case HCI_EV_LE_CONN_COMPLETE:
2937a13f316eSLuiz Augusto von Dentz 		case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
2938a13f316eSLuiz Augusto von Dentz 		case HCI_EVT_LE_CIS_ESTABLISHED:
29392615fd9aSLuiz Augusto von Dentz 			hci_cmd_sync_cancel(hdev, ECANCELED);
29401a942de0SBrian Gix 			break;
29411a942de0SBrian Gix 		}
2942881559afSLuiz Augusto von Dentz 	/* Cancel connect attempt if still queued/pending */
2943881559afSLuiz Augusto von Dentz 	} else if (!hci_cancel_connect_sync(hdev, conn)) {
2944881559afSLuiz Augusto von Dentz 		return 0;
2945a13f316eSLuiz Augusto von Dentz 	}
29461a942de0SBrian Gix 
2947881559afSLuiz Augusto von Dentz 	return hci_cmd_sync_queue_once(hdev, abort_conn_sync, conn, NULL);
29481a942de0SBrian Gix }
2949