From 4d7936e8a5b1fa803f4a631d2da4a80fa4f0f37f Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Mon, 23 Jun 2025 20:31:16 +0800 Subject: Bluetooth: hci_sock: Reset cookie to zero in hci_sock_free_cookie() Reset cookie value to 0 instead of 0xffffffff in hci_sock_free_cookie() since: 0 : means cookie has not been assigned yet 0xffffffff: means cookie assignment failure Also fix generating cookie failure with usage shown below: hci_sock_gen_cookie(sk) // generate cookie hci_sock_free_cookie(sk) // free cookie hci_sock_gen_cookie(sk) // Can't generate cookie any more Signed-off-by: Zijun Hu Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/hci_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 428ee5c7de7e..fc866759910d 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -118,7 +118,7 @@ static void hci_sock_free_cookie(struct sock *sk) int id = hci_pi(sk)->cookie; if (id) { - hci_pi(sk)->cookie = 0xffffffff; + hci_pi(sk)->cookie = 0; ida_free(&sock_cookie_ida, id); } } -- cgit v1.2.3 From da0186f19a7433d3d5607b0f61e9a3de17d1f721 Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Mon, 23 Jun 2025 20:31:17 +0800 Subject: Bluetooth: hci_sync: Use bt_dev_err() to log error message in hci_update_event_filter_sync() Use bt_dev_err() instead of bt_dev_dbg() to log error message in hci_update_event_filter_sync(). Signed-off-by: Zijun Hu Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/hci_sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index 7938c004071c..956aea977f2a 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -6116,7 +6116,7 @@ static int hci_update_event_filter_sync(struct hci_dev *hdev) &b->bdaddr, HCI_CONN_SETUP_AUTO_ON); if (err) - bt_dev_dbg(hdev, "Failed to set event filter for %pMR", + bt_dev_err(hdev, "Failed to set event filter for %pMR", &b->bdaddr); else scan = SCAN_PAGE; -- cgit v1.2.3 From 88d6ba89d86404073dc3cb711203c02b0754b166 Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Mon, 23 Jun 2025 20:31:18 +0800 Subject: Bluetooth: hci_core: Eliminate an unnecessary goto label in hci_find_irk_by_addr() Eliminate an unnecessary goto label by using break instead of goto to exit the loop in hci_find_irk_by_addr(). Signed-off-by: Zijun Hu Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/hci_core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'net') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 441cb1700f99..f2fbe9c8e1be 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1256,12 +1256,10 @@ struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, if (addr_type == irk->addr_type && bacmp(bdaddr, &irk->bdaddr) == 0) { irk_to_return = irk; - goto done; + break; } } -done: - if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK, irk_to_return->val)) { bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR", -- cgit v1.2.3 From e44328c99be4fb2f6bcd6da42a9b9fa52c14bb05 Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Mon, 23 Jun 2025 20:31:19 +0800 Subject: Bluetooth: hci_event: Correct comment about HCI_EV_EXTENDED_INQUIRY_RESULT HCI_EV_EXTENDED_INQUIRY_RESULT's comment wrongly uses 0x2d as its event code. Use right 0x2f instead. Signed-off-by: Zijun Hu Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/hci_event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index cf4b30ac9e0e..f668bde007d4 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -7399,7 +7399,7 @@ static const struct hci_ev { /* [0x2c = HCI_EV_SYNC_CONN_COMPLETE] */ HCI_EV(HCI_EV_SYNC_CONN_COMPLETE, hci_sync_conn_complete_evt, sizeof(struct hci_ev_sync_conn_complete)), - /* [0x2d = HCI_EV_EXTENDED_INQUIRY_RESULT] */ + /* [0x2f = HCI_EV_EXTENDED_INQUIRY_RESULT] */ HCI_EV_VL(HCI_EV_EXTENDED_INQUIRY_RESULT, hci_extended_inquiry_result_evt, sizeof(struct hci_ev_ext_inquiry_result), HCI_MAX_EVENT_SIZE), -- cgit v1.2.3 From b2a5f2e1c127cb431df22e114998ff72eb4578c8 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Tue, 1 Jul 2025 15:56:22 +0800 Subject: Bluetooth: hci_event: Add support for handling LE BIG Sync Lost event When the BIS source stops, the controller sends an LE BIG Sync Lost event (subevent 0x1E). Currently, this event is not handled, causing the BIS stream to remain active in BlueZ and preventing recovery. Signed-off-by: Yang Li Signed-off-by: Luiz Augusto von Dentz --- include/net/bluetooth/hci.h | 6 ++++++ include/net/bluetooth/hci_core.h | 5 +++-- net/bluetooth/hci_conn.c | 3 ++- net/bluetooth/hci_event.c | 39 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 49 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index c79901f2dc2a..6213012610d7 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -2851,6 +2851,12 @@ struct hci_evt_le_big_sync_estabilished { __le16 bis[]; } __packed; +#define HCI_EVT_LE_BIG_SYNC_LOST 0x1e +struct hci_evt_le_big_sync_lost { + __u8 handle; + __u8 reason; +} __packed; + #define HCI_EVT_LE_BIG_INFO_ADV_REPORT 0x22 struct hci_evt_le_big_info_adv_report { __le16 sync_handle; diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 69f491399dac..1ef9279cfd6f 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1346,7 +1346,8 @@ hci_conn_hash_lookup_big_sync_pend(struct hci_dev *hdev, } static inline struct hci_conn * -hci_conn_hash_lookup_big_state(struct hci_dev *hdev, __u8 handle, __u16 state) +hci_conn_hash_lookup_big_state(struct hci_dev *hdev, __u8 handle, __u16 state, + __u8 role) { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_conn *c; @@ -1354,7 +1355,7 @@ hci_conn_hash_lookup_big_state(struct hci_dev *hdev, __u8 handle, __u16 state) rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (c->type != BIS_LINK || c->state != state) + if (c->type != BIS_LINK || c->state != state || c->role != role) continue; if (handle == c->iso_qos.bcast.big) { diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 4f379184df5b..f5cd935490ad 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -2146,7 +2146,8 @@ struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst, __u8 sid, struct hci_link *link; /* Look for any BIS that is open for rebinding */ - conn = hci_conn_hash_lookup_big_state(hdev, qos->bcast.big, BT_OPEN); + conn = hci_conn_hash_lookup_big_state(hdev, qos->bcast.big, BT_OPEN, + HCI_ROLE_MASTER); if (conn) { memcpy(qos, &conn->iso_qos, sizeof(*qos)); conn->state = BT_CONNECTED; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index f668bde007d4..fca58984ee4e 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -6876,7 +6876,8 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data, /* Connect all BISes that are bound to the BIG */ while ((conn = hci_conn_hash_lookup_big_state(hdev, ev->handle, - BT_BOUND))) { + BT_BOUND, + HCI_ROLE_MASTER))) { if (ev->status) { hci_connect_cfm(conn, ev->status); hci_conn_del(conn); @@ -6992,6 +6993,37 @@ unlock: hci_dev_unlock(hdev); } +static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data, + struct sk_buff *skb) +{ + struct hci_evt_le_big_sync_lost *ev = data; + struct hci_conn *bis, *conn; + + bt_dev_dbg(hdev, "big handle 0x%2.2x", ev->handle); + + hci_dev_lock(hdev); + + /* Delete the pa sync connection */ + bis = hci_conn_hash_lookup_pa_sync_big_handle(hdev, ev->handle); + if (bis) { + conn = hci_conn_hash_lookup_pa_sync_handle(hdev, + bis->sync_handle); + if (conn) + hci_conn_del(conn); + } + + /* Delete each bis connection */ + while ((bis = hci_conn_hash_lookup_big_state(hdev, ev->handle, + BT_CONNECTED, + HCI_ROLE_SLAVE))) { + clear_bit(HCI_CONN_BIG_SYNC, &bis->flags); + hci_disconn_cfm(bis, ev->reason); + hci_conn_del(bis); + } + + hci_dev_unlock(hdev); +} + static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data, struct sk_buff *skb) { @@ -7115,6 +7147,11 @@ static const struct hci_le_ev { hci_le_big_sync_established_evt, sizeof(struct hci_evt_le_big_sync_estabilished), HCI_MAX_EVENT_SIZE), + /* [0x1e = HCI_EVT_LE_BIG_SYNC_LOST] */ + HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_LOST, + hci_le_big_sync_lost_evt, + sizeof(struct hci_evt_le_big_sync_lost), + HCI_MAX_EVENT_SIZE), /* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */ HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT, hci_le_big_info_adv_report_evt, -- cgit v1.2.3 From be31d11ec9144f7f8f7fcbf84ba6971b664683f3 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Tue, 1 Jul 2025 16:47:26 +0800 Subject: Bluetooth: Fix spelling mistakes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correct the misspelling of “estabilished” in the code. Signed-off-by: Yang Li Signed-off-by: Luiz Augusto von Dentz --- include/net/bluetooth/hci.h | 2 +- net/bluetooth/hci_event.c | 16 ++++++++-------- net/bluetooth/iso.c | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 6213012610d7..94f365b75166 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -2837,7 +2837,7 @@ struct hci_evt_le_create_big_complete { } __packed; #define HCI_EVT_LE_BIG_SYNC_ESTABLISHED 0x1d -struct hci_evt_le_big_sync_estabilished { +struct hci_evt_le_big_sync_established { __u8 status; __u8 handle; __u8 latency[3]; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index fca58984ee4e..d44463e65194 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -6350,8 +6350,8 @@ static int hci_le_pa_term_sync(struct hci_dev *hdev, __le16 handle) return hci_send_cmd(hdev, HCI_OP_LE_PA_TERM_SYNC, sizeof(cp), &cp); } -static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, - struct sk_buff *skb) +static void hci_le_pa_sync_established_evt(struct hci_dev *hdev, void *data, + struct sk_buff *skb) { struct hci_ev_le_pa_sync_established *ev = data; int mask = hdev->link_mode; @@ -6681,8 +6681,8 @@ unlock: hci_dev_unlock(hdev); } -static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data, - struct sk_buff *skb) +static void hci_le_cis_established_evt(struct hci_dev *hdev, void *data, + struct sk_buff *skb) { struct hci_evt_le_cis_established *ev = data; struct hci_conn *conn; @@ -6910,7 +6910,7 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data, static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, struct sk_buff *skb) { - struct hci_evt_le_big_sync_estabilished *ev = data; + struct hci_evt_le_big_sync_established *ev = data; struct hci_conn *bis, *conn; int i; @@ -7121,7 +7121,7 @@ static const struct hci_le_ev { HCI_MAX_EVENT_SIZE), /* [0x0e = HCI_EV_LE_PA_SYNC_ESTABLISHED] */ HCI_LE_EV(HCI_EV_LE_PA_SYNC_ESTABLISHED, - hci_le_pa_sync_estabilished_evt, + hci_le_pa_sync_established_evt, sizeof(struct hci_ev_le_pa_sync_established)), /* [0x0f = HCI_EV_LE_PER_ADV_REPORT] */ HCI_LE_EV_VL(HCI_EV_LE_PER_ADV_REPORT, @@ -7132,7 +7132,7 @@ static const struct hci_le_ev { HCI_LE_EV(HCI_EV_LE_EXT_ADV_SET_TERM, hci_le_ext_adv_term_evt, sizeof(struct hci_evt_le_ext_adv_set_term)), /* [0x19 = HCI_EVT_LE_CIS_ESTABLISHED] */ - HCI_LE_EV(HCI_EVT_LE_CIS_ESTABLISHED, hci_le_cis_estabilished_evt, + HCI_LE_EV(HCI_EVT_LE_CIS_ESTABLISHED, hci_le_cis_established_evt, sizeof(struct hci_evt_le_cis_established)), /* [0x1a = HCI_EVT_LE_CIS_REQ] */ HCI_LE_EV(HCI_EVT_LE_CIS_REQ, hci_le_cis_req_evt, @@ -7145,7 +7145,7 @@ static const struct hci_le_ev { /* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABLISHED] */ HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABLISHED, hci_le_big_sync_established_evt, - sizeof(struct hci_evt_le_big_sync_estabilished), + sizeof(struct hci_evt_le_big_sync_established), HCI_MAX_EVENT_SIZE), /* [0x1e = HCI_EVT_LE_BIG_SYNC_LOST] */ HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_LOST, diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c index 34e89bb5f384..5e752950e266 100644 --- a/net/bluetooth/iso.c +++ b/net/bluetooth/iso.c @@ -1891,7 +1891,7 @@ static void iso_sock_ready(struct sock *sk) static bool iso_match_big(struct sock *sk, void *data) { - struct hci_evt_le_big_sync_estabilished *ev = data; + struct hci_evt_le_big_sync_established *ev = data; return ev->handle == iso_pi(sk)->qos.bcast.big; } @@ -1912,7 +1912,7 @@ static void iso_conn_ready(struct iso_conn *conn) { struct sock *parent = NULL; struct sock *sk = conn->sk; - struct hci_ev_le_big_sync_estabilished *ev = NULL; + struct hci_ev_le_big_sync_established *ev = NULL; struct hci_ev_le_pa_sync_established *ev2 = NULL; struct hci_ev_le_per_adv_report *ev3 = NULL; struct hci_conn *hcon; @@ -2023,7 +2023,7 @@ static void iso_conn_ready(struct iso_conn *conn) hci_conn_hold(hcon); iso_chan_add(conn, sk, parent); - if ((ev && ((struct hci_evt_le_big_sync_estabilished *)ev)->status) || + if ((ev && ((struct hci_evt_le_big_sync_established *)ev)->status) || (ev2 && ev2->status)) { /* Trigger error signal on child socket */ sk->sk_err = ECONNREFUSED; @@ -2082,7 +2082,7 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) * proceed to establishing a BIG sync: * * 1. HCI_EV_LE_PA_SYNC_ESTABLISHED: The socket may specify a specific - * SID to listen to and once sync is estabilished its handle needs to + * SID to listen to and once sync is established its handle needs to * be stored in iso_pi(sk)->sync_handle so it can be matched once * receiving the BIG Info. * 2. HCI_EVT_LE_BIG_INFO_ADV_REPORT: When connect_ind is triggered by a -- cgit v1.2.3 From 8074811359141e2f67eff9bce41a3e2ecae4ace9 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 3 Jul 2025 19:16:59 +0200 Subject: Bluetooth: aosp: Fix typo in comment Found by codespell. Signed-off-by: Bastien Nocera Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/aosp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/bluetooth/aosp.c b/net/bluetooth/aosp.c index 1d67836e95e1..59025771af53 100644 --- a/net/bluetooth/aosp.c +++ b/net/bluetooth/aosp.c @@ -70,7 +70,7 @@ void aosp_do_open(struct hci_dev *hdev) rp = (struct aosp_rp_le_get_vendor_capa *)skb->data; version_supported = le16_to_cpu(rp->version_supported); - /* AOSP displays the verion number like v0.98, v1.00, etc. */ + /* AOSP displays the version number like v0.98, v1.00, etc. */ bt_dev_info(hdev, "AOSP extensions version v%u.%02u", version_supported >> 8, version_supported & 0xff); -- cgit v1.2.3 From e6555fffd5189be7f1a3d936915660ee63c503da Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 3 Jul 2025 19:17:00 +0200 Subject: Bluetooth: RFCOMM: Fix typos in comments Found by codespell. Signed-off-by: Bastien Nocera Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/rfcomm/core.c | 3 ++- net/bluetooth/rfcomm/tty.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 3b8f39618d65..96250807b32b 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -1962,7 +1962,8 @@ static void rfcomm_accept_connection(struct rfcomm_session *s) int err; /* Fast check for a new connection. - * Avoids unnesesary socket allocations. */ + * Avoids unnecessary socket allocations. + */ if (list_empty(&bt_sk(sock->sk)->accept_q)) return; diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 21a5b5535ebc..58d1707f7daf 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -980,7 +980,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, baud = RFCOMM_RPN_BR_230400; break; default: - /* 9600 is standard accordinag to the RFCOMM specification */ + /* 9600 is standard according to the RFCOMM specification */ baud = RFCOMM_RPN_BR_9600; break; -- cgit v1.2.3 From 0e492dbaccda2807eae56274bc90839f41b332fd Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 3 Jul 2025 19:17:01 +0200 Subject: Bluetooth: Fix typos in comments Found by codespell. Signed-off-by: Bastien Nocera Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/hci_conn.c | 2 +- net/bluetooth/hci_event.c | 4 ++-- net/bluetooth/hci_sync.c | 2 +- net/bluetooth/lib.c | 2 +- net/bluetooth/smp.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'net') diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index f5cd935490ad..b2e09e7f70e1 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -814,7 +814,7 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *c * * Detects if there any BIS left connected in a BIG * broadcaster: Remove advertising instance and terminate BIG. - * broadcaster receiver: Teminate BIG sync and terminate PA sync. + * broadcaster receiver: Terminate BIG sync and terminate PA sync. */ static void bis_cleanup(struct hci_conn *conn) { diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d44463e65194..c0eb03e5cbf8 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -5717,7 +5717,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, conn->state = BT_CONFIG; /* Store current advertising instance as connection advertising instance - * when sotfware rotation is in use so it can be re-enabled when + * when software rotation is in use so it can be re-enabled when * disconnected. */ if (!ext_adv_capable(hdev)) @@ -7075,7 +7075,7 @@ unlock: /* Entries in this table shall have their position according to the subevent * opcode they handle so the use of the macros above is recommend since it does * attempt to initialize at its proper index using Designated Initializers that - * way events without a callback function can be ommited. + * way events without a callback function can be omitted. */ static const struct hci_le_ev { void (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb); diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index 956aea977f2a..e9df6502e58e 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -5677,7 +5677,7 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason) } /* Cleanup hci_conn object if it cannot be cancelled as it - * likelly means the controller and host stack are out of sync + * likely means the controller and host stack are out of sync * or in case of LE it was still scanning so it can be cleanup * safely. */ diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c index 43aa01fd07b9..305044a84478 100644 --- a/net/bluetooth/lib.c +++ b/net/bluetooth/lib.c @@ -54,7 +54,7 @@ EXPORT_SYMBOL(baswap); * bt_to_errno() - Bluetooth error codes to standard errno * @code: Bluetooth error code to be converted * - * This function takes a Bluetooth error code as input and convets + * This function takes a Bluetooth error code as input and converts * it to an equivalent Unix/standard errno value. * * Return: diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 8115d42fc15b..45512b2ba951 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -3189,7 +3189,7 @@ static void smp_ready_cb(struct l2cap_chan *chan) /* No need to call l2cap_chan_hold() here since we already own * the reference taken in smp_new_conn_cb(). This is just the * first time that we tie it to a specific pointer. The code in - * l2cap_core.c ensures that there's no risk this function wont + * l2cap_core.c ensures that there's no risk this function won't * get called if smp_new_conn_cb was previously called. */ conn->smp = chan; -- cgit v1.2.3 From 7565bc56598c3d135318f1bd76a0178dd3ea918f Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Mon, 14 Jul 2025 19:40:37 +0300 Subject: Bluetooth: ISO: add socket option to report packet seqnum via CMSG User applications need a way to track which ISO interval a given SDU belongs to, to properly detect packet loss. All controllers do not set timestamps, and it's not guaranteed user application receives all packet reports (small socket buffer, or controller doesn't send all reports like Intel AX210 is doing). Add socket option BT_PKT_SEQNUM that enables reporting of received packet ISO sequence number in BT_SCM_PKT_SEQNUM CMSG. Use BT_PKT_SEQNUM == 22 for the socket option, as 21 was used earlier for a removed experimental feature that never got into mainline. Signed-off-by: Pauli Virtanen Signed-off-by: Luiz Augusto von Dentz --- include/net/bluetooth/bluetooth.h | 11 ++++++++++- net/bluetooth/af_bluetooth.c | 7 +++++++ net/bluetooth/iso.c | 21 ++++++++++++++++++--- 3 files changed, 35 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 114299bd8b98..ada5b56a4413 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -244,6 +244,12 @@ struct bt_codecs { #define BT_ISO_BASE 20 +/* Socket option value 21 reserved */ + +#define BT_PKT_SEQNUM 22 + +#define BT_SCM_PKT_SEQNUM 0x05 + __printf(1, 2) void bt_info(const char *fmt, ...); __printf(1, 2) @@ -391,7 +397,8 @@ struct bt_sock { enum { BT_SK_DEFER_SETUP, BT_SK_SUSPEND, - BT_SK_PKT_STATUS + BT_SK_PKT_STATUS, + BT_SK_PKT_SEQNUM, }; struct bt_sock_list { @@ -475,6 +482,7 @@ struct bt_skb_cb { u8 pkt_type; u8 force_active; u16 expect; + u16 pkt_seqnum; u8 incoming:1; u8 pkt_status:2; union { @@ -488,6 +496,7 @@ struct bt_skb_cb { #define hci_skb_pkt_type(skb) bt_cb((skb))->pkt_type #define hci_skb_pkt_status(skb) bt_cb((skb))->pkt_status +#define hci_skb_pkt_seqnum(skb) bt_cb((skb))->pkt_seqnum #define hci_skb_expect(skb) bt_cb((skb))->expect #define hci_skb_opcode(skb) bt_cb((skb))->hci.opcode #define hci_skb_event(skb) bt_cb((skb))->hci.req_event diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index ee9bf84c88a7..2b94e2077203 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -364,6 +364,13 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, put_cmsg(msg, SOL_BLUETOOTH, BT_SCM_PKT_STATUS, sizeof(pkt_status), &pkt_status); } + + if (test_bit(BT_SK_PKT_SEQNUM, &bt_sk(sk)->flags)) { + u16 pkt_seqnum = hci_skb_pkt_seqnum(skb); + + put_cmsg(msg, SOL_BLUETOOTH, BT_SCM_PKT_SEQNUM, + sizeof(pkt_seqnum), &pkt_seqnum); + } } skb_free_datagram(sk, skb); diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c index 5e752950e266..2f229f2077e8 100644 --- a/net/bluetooth/iso.c +++ b/net/bluetooth/iso.c @@ -1687,6 +1687,17 @@ static int iso_sock_setsockopt(struct socket *sock, int level, int optname, clear_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags); break; + case BT_PKT_SEQNUM: + err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen); + if (err) + break; + + if (opt) + set_bit(BT_SK_PKT_SEQNUM, &bt_sk(sk)->flags); + else + clear_bit(BT_SK_PKT_SEQNUM, &bt_sk(sk)->flags); + break; + case BT_ISO_QOS: if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECT2 && @@ -2278,7 +2289,7 @@ static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason) void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) { struct iso_conn *conn = hcon->iso_data; - __u16 pb, ts, len; + __u16 pb, ts, len, sn; if (!conn) goto drop; @@ -2308,6 +2319,7 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) goto drop; } + sn = __le16_to_cpu(hdr->sn); len = __le16_to_cpu(hdr->slen); } else { struct hci_iso_data_hdr *hdr; @@ -2318,18 +2330,20 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) goto drop; } + sn = __le16_to_cpu(hdr->sn); len = __le16_to_cpu(hdr->slen); } flags = hci_iso_data_flags(len); len = hci_iso_data_len(len); - BT_DBG("Start: total len %d, frag len %d flags 0x%4.4x", len, - skb->len, flags); + BT_DBG("Start: total len %d, frag len %d flags 0x%4.4x sn %d", + len, skb->len, flags, sn); if (len == skb->len) { /* Complete frame received */ hci_skb_pkt_status(skb) = flags & 0x03; + hci_skb_pkt_seqnum(skb) = sn; iso_recv_frame(conn, skb); return; } @@ -2352,6 +2366,7 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) goto drop; hci_skb_pkt_status(conn->rx_skb) = flags & 0x03; + hci_skb_pkt_seqnum(conn->rx_skb) = sn; skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), skb->len); conn->rx_len = len - skb->len; -- cgit v1.2.3 From ef568ae04ead4d132481550fde36fcdd29a31b3b Mon Sep 17 00:00:00 2001 From: Yang Li Date: Mon, 7 Jul 2025 10:38:17 +0800 Subject: Bluetooth: ISO: Support SCM_TIMESTAMPING for ISO TS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User-space applications (e.g. PipeWire) depend on ISO-formatted timestamps for precise audio sync. The ISO ts is based on the controller’s clock domain, so hardware timestamping (hwtimestamp) must be used. Ref: Documentation/networking/timestamping.rst, section 3.1 Hardware Timestamping. Signed-off-by: Yang Li Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/iso.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c index 2f229f2077e8..2f45e46a9b6a 100644 --- a/net/bluetooth/iso.c +++ b/net/bluetooth/iso.c @@ -2289,6 +2289,7 @@ static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason) void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) { struct iso_conn *conn = hcon->iso_data; + struct skb_shared_hwtstamps *hwts; __u16 pb, ts, len, sn; if (!conn) @@ -2312,13 +2313,16 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) if (ts) { struct hci_iso_ts_data_hdr *hdr; - /* TODO: add timestamp to the packet? */ hdr = skb_pull_data(skb, HCI_ISO_TS_DATA_HDR_SIZE); if (!hdr) { BT_ERR("Frame is too short (len %d)", skb->len); goto drop; } + /* Record the timestamp to skb */ + hwts = skb_hwtstamps(skb); + hwts->hwtstamp = us_to_ktime(le32_to_cpu(hdr->ts)); + sn = __le16_to_cpu(hdr->sn); len = __le16_to_cpu(hdr->slen); } else { @@ -2370,6 +2374,13 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), skb->len); conn->rx_len = len - skb->len; + + /* Copy hw timestamp from skb to rx_skb if present */ + if (ts) { + hwts = skb_hwtstamps(conn->rx_skb); + hwts->hwtstamp = skb_hwtstamps(skb)->hwtstamp; + } + break; case ISO_CONT: -- cgit v1.2.3 From 7af4d7b53502286c6cf946d397ab183e76d14820 Mon Sep 17 00:00:00 2001 From: Ivan Pravdin Date: Thu, 17 Jul 2025 11:10:52 -0400 Subject: Bluetooth: hci_devcd_dump: fix out-of-bounds via dev_coredumpv Currently both dev_coredumpv and skb_put_data in hci_devcd_dump use hdev->dump.head. However, dev_coredumpv can free the buffer. From dev_coredumpm_timeout documentation, which is used by dev_coredumpv: > Creates a new device coredump for the given device. If a previous one hasn't > been read yet, the new coredump is discarded. The data lifetime is determined > by the device coredump framework and when it is no longer needed the @free > function will be called to free the data. If the data has not been read by the userspace yet, dev_coredumpv will discard new buffer, freeing hdev->dump.head. This leads to vmalloc-out-of-bounds error when skb_put_data tries to access hdev->dump.head. A crash report from syzbot illustrates this: ================================================================== BUG: KASAN: vmalloc-out-of-bounds in skb_put_data include/linux/skbuff.h:2752 [inline] BUG: KASAN: vmalloc-out-of-bounds in hci_devcd_dump+0x142/0x240 net/bluetooth/coredump.c:258 Read of size 140 at addr ffffc90004ed5000 by task kworker/u9:2/5844 CPU: 1 UID: 0 PID: 5844 Comm: kworker/u9:2 Not tainted 6.14.0-syzkaller-10892-g4e82c87058f4 #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025 Workqueue: hci0 hci_devcd_timeout Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:408 [inline] print_report+0xc3/0x670 mm/kasan/report.c:521 kasan_report+0xe0/0x110 mm/kasan/report.c:634 check_region_inline mm/kasan/generic.c:183 [inline] kasan_check_range+0xef/0x1a0 mm/kasan/generic.c:189 __asan_memcpy+0x23/0x60 mm/kasan/shadow.c:105 skb_put_data include/linux/skbuff.h:2752 [inline] hci_devcd_dump+0x142/0x240 net/bluetooth/coredump.c:258 hci_devcd_timeout+0xb5/0x2e0 net/bluetooth/coredump.c:413 process_one_work+0x9cc/0x1b70 kernel/workqueue.c:3238 process_scheduled_works kernel/workqueue.c:3319 [inline] worker_thread+0x6c8/0xf10 kernel/workqueue.c:3400 kthread+0x3c2/0x780 kernel/kthread.c:464 ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:153 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 The buggy address ffffc90004ed5000 belongs to a vmalloc virtual mapping Memory state around the buggy address: ffffc90004ed4f00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 ffffc90004ed4f80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 >ffffc90004ed5000: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 ^ ffffc90004ed5080: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 ffffc90004ed5100: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 ================================================================== To avoid this issue, reorder dev_coredumpv to be called after skb_put_data that does not free the data. Reported-by: syzbot+ac3c79181f6aecc5120c@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=ac3c79181f6aecc5120c Fixes: b257e02ecc46 ("HCI: coredump: Log devcd dumps into the monitor") Tested-by: syzbot+ac3c79181f6aecc5120c@syzkaller.appspotmail.com Signed-off-by: Ivan Pravdin Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/coredump.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/bluetooth/coredump.c b/net/bluetooth/coredump.c index 819eacb38762..720cb79adf96 100644 --- a/net/bluetooth/coredump.c +++ b/net/bluetooth/coredump.c @@ -249,15 +249,15 @@ static void hci_devcd_dump(struct hci_dev *hdev) size = hdev->dump.tail - hdev->dump.head; - /* Emit a devcoredump with the available data */ - dev_coredumpv(&hdev->dev, hdev->dump.head, size, GFP_KERNEL); - /* Send a copy to monitor as a diagnostic packet */ skb = bt_skb_alloc(size, GFP_ATOMIC); if (skb) { skb_put_data(skb, hdev->dump.head, size); hci_recv_diag(hdev, skb); } + + /* Emit a devcoredump with the available data */ + dev_coredumpv(&hdev->dev, hdev->dump.head, size, GFP_KERNEL); } static void hci_devcd_handle_pkt_complete(struct hci_dev *hdev, -- cgit v1.2.3 From 0cadf8534f2a727bc3a01e8c583b085d25963ee0 Mon Sep 17 00:00:00 2001 From: Chris Down Date: Mon, 21 Jul 2025 16:30:23 +0100 Subject: Bluetooth: hci_event: Mask data status from LE ext adv reports The Event_Type field in an LE Extended Advertising Report uses bits 5 and 6 for data status (e.g. truncation or fragmentation), not the PDU type itself. The ext_evt_type_to_legacy() function fails to mask these status bits before evaluation. This causes valid advertisements with status bits set (e.g. a truncated non-connectable advertisement, which ends up showing as PDU type 0x40) to be misclassified as unknown and subsequently dropped. This is okay for most checks which use bitwise AND on the relevant event type bits, but it doesn't work for non-connectable types, which are checked with '== LE_EXT_ADV_NON_CONN_IND' (that is, zero). In terms of behaviour, first the device sends a truncated report: > HCI Event: LE Meta Event (0x3e) plen 26 LE Extended Advertising Report (0x0d) Entry 0 Event type: 0x0040 Data status: Incomplete, data truncated, no more to come Address type: Random (0x01) Address: 1D:12:46:FA:F8:6E (Non-Resolvable) SID: 0x03 RSSI: -98 dBm (0x9e) Data length: 0x00 Then, a few seconds later, it sends the subsequent complete report: > HCI Event: LE Meta Event (0x3e) plen 122 LE Extended Advertising Report (0x0d) Entry 0 Event type: 0x0000 Data status: Complete Address type: Random (0x01) Address: 1D:12:46:FA:F8:6E (Non-Resolvable) SID: 0x03 RSSI: -97 dBm (0x9f) Data length: 0x60 Service Data: Google (0xfef3) Data[92]: ... These devices often send multiple truncated reports per second. This patch introduces a PDU type mask to ensure only the relevant bits are evaluated, allowing for the correct translation of all valid extended advertising packets. Fixes: b2cc9761f144 ("Bluetooth: Handle extended ADV PDU types") Signed-off-by: Chris Down Signed-off-by: Luiz Augusto von Dentz --- include/net/bluetooth/hci.h | 1 + net/bluetooth/hci_event.c | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 94f365b75166..e90a7b753926 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -2634,6 +2634,7 @@ struct hci_ev_le_conn_complete { #define LE_EXT_ADV_DIRECT_IND 0x0004 #define LE_EXT_ADV_SCAN_RSP 0x0008 #define LE_EXT_ADV_LEGACY_PDU 0x0010 +#define LE_EXT_ADV_DATA_STATUS_MASK 0x0060 #define LE_EXT_ADV_EVT_TYPE_MASK 0x007f #define ADDR_LE_DEV_PUBLIC 0x00 diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index c0eb03e5cbf8..b7b473473b70 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -6239,6 +6239,11 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data, static u8 ext_evt_type_to_legacy(struct hci_dev *hdev, u16 evt_type) { + u16 pdu_type = evt_type & ~LE_EXT_ADV_DATA_STATUS_MASK; + + if (!pdu_type) + return LE_ADV_NONCONN_IND; + if (evt_type & LE_EXT_ADV_LEGACY_PDU) { switch (evt_type) { case LE_LEGACY_ADV_IND: @@ -6270,8 +6275,7 @@ static u8 ext_evt_type_to_legacy(struct hci_dev *hdev, u16 evt_type) if (evt_type & LE_EXT_ADV_SCAN_IND) return LE_ADV_SCAN_IND; - if (evt_type == LE_EXT_ADV_NON_CONN_IND || - evt_type & LE_EXT_ADV_DIRECT_IND) + if (evt_type & LE_EXT_ADV_DIRECT_IND) return LE_ADV_NONCONN_IND; invalid: -- cgit v1.2.3 From a7bcffc673de219af2698fbb90627016233de67b Mon Sep 17 00:00:00 2001 From: Yang Li Date: Thu, 10 Jul 2025 18:52:47 +0800 Subject: Bluetooth: Add PA_LINK to distinguish BIG sync and PA sync connections Currently, BIS_LINK is used for both BIG sync and PA sync connections, which makes it impossible to distinguish them when searching for a PA sync connection. Adding PA_LINK will make the distinction clearer and simplify future extensions for PA-related features. Signed-off-by: Yang Li Signed-off-by: Luiz Augusto von Dentz --- include/net/bluetooth/hci.h | 1 + include/net/bluetooth/hci_core.h | 10 +++++++--- net/bluetooth/hci_conn.c | 14 +++++++++----- net/bluetooth/hci_core.c | 27 +++++++++++++++------------ net/bluetooth/hci_event.c | 7 ++++--- net/bluetooth/hci_sync.c | 10 +++++----- net/bluetooth/iso.c | 6 ++++-- net/bluetooth/mgmt.c | 1 + 8 files changed, 46 insertions(+), 30 deletions(-) (limited to 'net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index e90a7b753926..df1847b74e55 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -562,6 +562,7 @@ enum { #define LE_LINK 0x80 #define CIS_LINK 0x82 #define BIS_LINK 0x83 +#define PA_LINK 0x84 #define INVALID_LINK 0xff /* LMP features */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 3728495f0819..4dc11c66f7b8 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1015,6 +1015,7 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) break; case CIS_LINK: case BIS_LINK: + case PA_LINK: h->iso_num++; break; } @@ -1042,6 +1043,7 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) break; case CIS_LINK: case BIS_LINK: + case PA_LINK: h->iso_num--; break; } @@ -1060,6 +1062,7 @@ static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type) return h->sco_num; case CIS_LINK: case BIS_LINK: + case PA_LINK: return h->iso_num; default: return 0; @@ -1142,7 +1145,7 @@ hci_conn_hash_lookup_create_pa_sync(struct hci_dev *hdev) rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (c->type != BIS_LINK) + if (c->type != PA_LINK) continue; if (!test_bit(HCI_CONN_CREATE_PA_SYNC, &c->flags)) @@ -1337,7 +1340,7 @@ hci_conn_hash_lookup_big_sync_pend(struct hci_dev *hdev, rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (c->type != BIS_LINK) + if (c->type != PA_LINK) continue; if (handle == c->iso_qos.bcast.big && num_bis == c->num_bis) { @@ -1407,7 +1410,7 @@ hci_conn_hash_lookup_pa_sync_handle(struct hci_dev *hdev, __u16 sync_handle) rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if (c->type != BIS_LINK) + if (c->type != PA_LINK) continue; /* Ignore the listen hcon, we are looking @@ -2006,6 +2009,7 @@ static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, case CIS_LINK: case BIS_LINK: + case PA_LINK: return iso_connect_ind(hdev, bdaddr, flags); default: diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index b2e09e7f70e1..7d1e79f69cd1 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -785,7 +785,7 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *c d->sync_handle = conn->sync_handle; if (test_and_clear_bit(HCI_CONN_PA_SYNC, &conn->flags)) { - hci_conn_hash_list_flag(hdev, find_bis, BIS_LINK, + hci_conn_hash_list_flag(hdev, find_bis, PA_LINK, HCI_CONN_PA_SYNC, d); if (!d->count) @@ -914,6 +914,7 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t break; case CIS_LINK: case BIS_LINK: + case PA_LINK: if (hdev->iso_mtu) /* Dedicated ISO Buffer exists */ break; @@ -979,6 +980,7 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t break; case CIS_LINK: case BIS_LINK: + case PA_LINK: /* conn->src should reflect the local identity address */ hci_copy_identity_address(hdev, &conn->src, &conn->src_type); @@ -1033,7 +1035,6 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t } hci_conn_init_sysfs(conn); - return conn; } @@ -1077,6 +1078,7 @@ static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason) break; case CIS_LINK: case BIS_LINK: + case PA_LINK: if ((conn->state != BT_CONNECTED && !test_bit(HCI_CONN_CREATE_CIS, &conn->flags)) || test_bit(HCI_CONN_BIG_CREATED, &conn->flags)) @@ -1152,7 +1154,8 @@ void hci_conn_del(struct hci_conn *conn) } else { /* Unacked ISO frames */ if (conn->type == CIS_LINK || - conn->type == BIS_LINK) { + conn->type == BIS_LINK || + conn->type == PA_LINK) { if (hdev->iso_pkts) hdev->iso_cnt += conn->sent; else if (hdev->le_pkts) @@ -2081,7 +2084,7 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, bt_dev_dbg(hdev, "dst %pMR type %d sid %d", dst, dst_type, sid); - conn = hci_conn_add_unset(hdev, BIS_LINK, dst, HCI_ROLE_SLAVE); + conn = hci_conn_add_unset(hdev, PA_LINK, dst, HCI_ROLE_SLAVE); if (IS_ERR(conn)) return conn; @@ -2246,7 +2249,7 @@ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst, * the start periodic advertising and create BIG commands have * been queued */ - hci_conn_hash_list_state(hdev, bis_mark_per_adv, BIS_LINK, + hci_conn_hash_list_state(hdev, bis_mark_per_adv, PA_LINK, BT_BOUND, &data); /* Queue start periodic advertising and create BIG */ @@ -2980,6 +2983,7 @@ void hci_conn_tx_queue(struct hci_conn *conn, struct sk_buff *skb) switch (conn->type) { case CIS_LINK: case BIS_LINK: + case PA_LINK: case ACL_LINK: case LE_LINK: break; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index f2fbe9c8e1be..55e0722fd066 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2936,12 +2936,14 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) case HCI_ACLDATA_PKT: /* Detect if ISO packet has been sent as ACL */ if (hci_conn_num(hdev, CIS_LINK) || - hci_conn_num(hdev, BIS_LINK)) { + hci_conn_num(hdev, BIS_LINK) || + hci_conn_num(hdev, PA_LINK)) { __u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle); __u8 type; type = hci_conn_lookup_type(hdev, hci_handle(handle)); - if (type == CIS_LINK || type == BIS_LINK) + if (type == CIS_LINK || type == BIS_LINK || + type == PA_LINK) hci_skb_pkt_type(skb) = HCI_ISODATA_PKT; } break; @@ -3396,6 +3398,7 @@ static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote) break; case CIS_LINK: case BIS_LINK: + case PA_LINK: cnt = hdev->iso_mtu ? hdev->iso_cnt : hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; break; @@ -3409,7 +3412,7 @@ static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote) } static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, - __u8 type2, int *quote) + int *quote) { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_conn *conn = NULL, *c; @@ -3421,7 +3424,7 @@ static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, rcu_read_lock(); list_for_each_entry_rcu(c, &h->list, list) { - if ((c->type != type && c->type != type2) || + if (c->type != type || skb_queue_empty(&c->data_q)) continue; @@ -3625,7 +3628,7 @@ static void hci_sched_sco(struct hci_dev *hdev, __u8 type) else cnt = &hdev->sco_cnt; - while (*cnt && (conn = hci_low_sent(hdev, type, type, "e))) { + while (*cnt && (conn = hci_low_sent(hdev, type, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { BT_DBG("skb %p len %d", skb, skb->len); hci_send_conn_frame(hdev, conn, skb); @@ -3744,8 +3747,8 @@ static void hci_sched_le(struct hci_dev *hdev) hci_prio_recalculate(hdev, LE_LINK); } -/* Schedule CIS */ -static void hci_sched_iso(struct hci_dev *hdev) +/* Schedule iso */ +static void hci_sched_iso(struct hci_dev *hdev, __u8 type) { struct hci_conn *conn; struct sk_buff *skb; @@ -3753,14 +3756,12 @@ static void hci_sched_iso(struct hci_dev *hdev) BT_DBG("%s", hdev->name); - if (!hci_conn_num(hdev, CIS_LINK) && - !hci_conn_num(hdev, BIS_LINK)) + if (!hci_conn_num(hdev, type)) return; cnt = hdev->iso_pkts ? &hdev->iso_cnt : hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt; - while (*cnt && (conn = hci_low_sent(hdev, CIS_LINK, BIS_LINK, - "e))) { + while (*cnt && (conn = hci_low_sent(hdev, type, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { BT_DBG("skb %p len %d", skb, skb->len); hci_send_conn_frame(hdev, conn, skb); @@ -3785,7 +3786,9 @@ static void hci_tx_work(struct work_struct *work) /* Schedule queues and send stuff to HCI driver */ hci_sched_sco(hdev, SCO_LINK); hci_sched_sco(hdev, ESCO_LINK); - hci_sched_iso(hdev); + hci_sched_iso(hdev, CIS_LINK); + hci_sched_iso(hdev, BIS_LINK); + hci_sched_iso(hdev, PA_LINK); hci_sched_acl(hdev); hci_sched_le(hdev); } diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index b7b473473b70..8aa5039b975a 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -4432,6 +4432,7 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data, case CIS_LINK: case BIS_LINK: + case PA_LINK: if (hdev->iso_pkts) { hdev->iso_cnt += count; if (hdev->iso_cnt > hdev->iso_pkts) @@ -6381,7 +6382,7 @@ static void hci_le_pa_sync_established_evt(struct hci_dev *hdev, void *data, conn->sync_handle = le16_to_cpu(ev->handle); conn->sid = HCI_SID_INVALID; - mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, BIS_LINK, + mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, PA_LINK, &flags); if (!(mask & HCI_LM_ACCEPT)) { hci_le_pa_term_sync(hdev, ev->handle); @@ -6392,7 +6393,7 @@ static void hci_le_pa_sync_established_evt(struct hci_dev *hdev, void *data, goto unlock; /* Add connection to indicate PA sync event */ - pa_sync = hci_conn_add_unset(hdev, BIS_LINK, BDADDR_ANY, + pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY, HCI_ROLE_SLAVE); if (IS_ERR(pa_sync)) @@ -6423,7 +6424,7 @@ static void hci_le_per_adv_report_evt(struct hci_dev *hdev, void *data, hci_dev_lock(hdev); - mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, BIS_LINK, &flags); + mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, PA_LINK, &flags); if (!(mask & HCI_LM_ACCEPT)) goto unlock; diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index e9df6502e58e..2b4f21fbf9c1 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -2929,7 +2929,7 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type, if (sent) { struct hci_conn *conn; - conn = hci_conn_hash_lookup_ba(hdev, BIS_LINK, + conn = hci_conn_hash_lookup_ba(hdev, PA_LINK, &sent->bdaddr); if (conn) { struct bt_iso_qos *qos = &conn->iso_qos; @@ -5493,7 +5493,7 @@ static int hci_disconnect_sync(struct hci_dev *hdev, struct hci_conn *conn, { struct hci_cp_disconnect cp; - if (conn->type == BIS_LINK) { + if (conn->type == BIS_LINK || conn->type == PA_LINK) { /* This is a BIS connection, hci_conn_del will * do the necessary cleanup. */ @@ -5562,7 +5562,7 @@ static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn, return HCI_ERROR_LOCAL_HOST_TERM; } - if (conn->type == BIS_LINK) { + if (conn->type == BIS_LINK || conn->type == PA_LINK) { /* There is no way to cancel a BIS without terminating the BIG * which is done later on connection cleanup. */ @@ -5627,7 +5627,7 @@ static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, if (conn->type == CIS_LINK) return hci_le_reject_cis_sync(hdev, conn, reason); - if (conn->type == BIS_LINK) + if (conn->type == BIS_LINK || conn->type == PA_LINK) return -EINVAL; if (conn->type == SCO_LINK || conn->type == ESCO_LINK) @@ -6994,7 +6994,7 @@ static void create_pa_complete(struct hci_dev *hdev, void *data, int err) goto unlock; /* Add connection to indicate PA sync error */ - pa_sync = hci_conn_add_unset(hdev, BIS_LINK, BDADDR_ANY, + pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY, HCI_ROLE_SLAVE); if (IS_ERR(pa_sync)) diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c index 2f45e46a9b6a..7bd3aa0a6db9 100644 --- a/net/bluetooth/iso.c +++ b/net/bluetooth/iso.c @@ -2237,7 +2237,8 @@ done: static void iso_connect_cfm(struct hci_conn *hcon, __u8 status) { - if (hcon->type != CIS_LINK && hcon->type != BIS_LINK) { + if (hcon->type != CIS_LINK && hcon->type != BIS_LINK && + hcon->type != PA_LINK) { if (hcon->type != LE_LINK) return; @@ -2278,7 +2279,8 @@ static void iso_connect_cfm(struct hci_conn *hcon, __u8 status) static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason) { - if (hcon->type != CIS_LINK && hcon->type != BIS_LINK) + if (hcon->type != CIS_LINK && hcon->type != BIS_LINK && + hcon->type != PA_LINK) return; BT_DBG("hcon %p reason %d", hcon, reason); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 63dba0503653..1ce682038b51 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -3237,6 +3237,7 @@ static u8 link_to_bdaddr(u8 link_type, u8 addr_type) switch (link_type) { case CIS_LINK: case BIS_LINK: + case PA_LINK: case LE_LINK: switch (addr_type) { case ADDR_LE_DEV_PUBLIC: -- cgit v1.2.3