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