* [PATCH bluetooth] Bluetooth: eir: Fix stack OOB write in eir_create_adv_data()
From: Xiang Mei @ 2026-06-01 16:22 UTC (permalink / raw)
To: linux-bluetooth
Cc: Marcel Holtmann, Luiz Augusto von Dentz, Weiming Shi,
linux-kernel, Xiang Mei
From: Weiming Shi <bestswngs@gmail.com>
eir_create_adv_data() builds the advertising data into a fixed-size
buffer of "size" bytes (31 for the legacy path in hci_set_adv_data_sync()).
It may prepend a 3-byte "Flags" AD structure, but the per-instance
advertising data is then copied without checking that it still fits:
skip_flags:
if (adv) {
memcpy(ptr, adv->adv_data, adv->adv_data_len);
The "Flags" structure is added whenever BR/EDR is disabled
(LE_AD_NO_BREDR), which is the normal state for an LE-only controller.
However, the mgmt length validator tlv_data_max_len() only reserves
those 3 bytes when the user-supplied adv_flags carries a managed-flags
bit (DISCOV / LIMITED_DISCOV / MANAGED_FLAGS). Adding an instance with
flags == 0 reserves nothing, so adv_data_len is accepted up to the full
buffer size. At advertise time the 3 flag bytes are still prepended,
and the subsequent memcpy() writes 3 + adv_data_len bytes into the
size-byte buffer, overflowing it by the attacker-controlled tail of
adv_data:
BUG: KASAN: stack-out-of-bounds in eir_create_adv_data (net/bluetooth/eir.c:302)
Write of size 31 at addr ffff88800b7e7bac by task kworker/u9:0/51
Workqueue: hci0 hci_cmd_sync_work
__asan_memcpy (mm/kasan/shadow.c:106)
eir_create_adv_data (net/bluetooth/eir.c:302)
hci_update_adv_data_sync (net/bluetooth/hci_sync.c:1689)
hci_schedule_adv_instance_sync (net/bluetooth/hci_sync.c:2015)
hci_cmd_sync_work (net/bluetooth/hci_sync.c:332)
This frame has 1 object:
[32, 64) 'cp'
The inconsistency dates back to when the managed "Flags" field was first
added to the Add Advertising path: the prepended LE_AD_NO_BREDR flag does
not depend on the user-supplied adv_flags, but tlv_data_is_valid() only
reserved room when MGMT_ADV_FLAG_DISCOV was set. Commit 47c03902269a
("Bluetooth: eir: Fix possible crashes on eir_create_adv_data") later
added the "size" argument and bounds-checked the "Flags" and "Tx Power"
AD structures, but left this copy unguarded. Guard it the same way so
the data is only copied when it fits.
The bug is reachable by a local user with CAP_NET_ADMIN that owns an
LE-only controller using the legacy advertising path.
Fixes: b44133ff03be ("Bluetooth: Support the "discoverable" adv flag")
Reported-by: Xiang Mei <xmei5@asu.edu>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
net/bluetooth/eir.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bluetooth/eir.c b/net/bluetooth/eir.c
index 3f72111ba651..e574f8f61e16 100644
--- a/net/bluetooth/eir.c
+++ b/net/bluetooth/eir.c
@@ -297,7 +297,7 @@ u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr, u8 size)
}
skip_flags:
- if (adv) {
+ if (adv && ad_len + adv->adv_data_len <= size) {
memcpy(ptr, adv->adv_data, adv->adv_data_len);
ad_len += adv->adv_data_len;
ptr += adv->adv_data_len;
--
2.43.0
^ permalink raw reply related
* Re: [PATCH net-next v2 0/6] Bluetooth: convert remaining bluetooth socket families to getsockopt_iter
From: Breno Leitao @ 2026-06-01 14:21 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: Marcel Holtmann, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Shuah Khan, linux-bluetooth,
linux-kernel, netdev, linux-kselftest
In-Reply-To: <CABBYNZ+nvtMHcU9but5VEG891vyO=K0MF3OAGofANxzdLVmw-g@mail.gmail.com>
Hello Luiz,
On Thu, May 14, 2026 at 01:51:16PM -0400, Luiz Augusto von Dentz wrote:
> On Tue, May 12, 2026 at 7:12 AM Breno Leitao <leitao@debian.org> wrote:
> >
> > Continue the conversion to .getsockopt_iter for the Bluetooth socket
> > families: hci_sock, ISO, RFCOMM, SCO and L2CAP. The first patch is a
> > small precursor that fixes a long-standing 1-byte put_user write in
> > hci_sock_getsockopt_old() so the subsequent conversion stays mechanical.
> >
> > The riskiest change in this series is the SCO BT_CODEC conversion: it
> > is the only one that drops an open-coded ptr cursor in favour of
> > relying on iter_out advancing naturally on every copy_to_iter() call.
> > Every other socket option is a near-mechanical s/copy_to_user/
> > copy_to_iter/ rewrite, but BT_CODEC walks a variable-length list of
> > codecs + capabilities and previously tracked its own write offset by
> > hand. Getting the cursor semantics wrong here would silently truncate
> > or misalign user-visible codec data.
> >
> > For more context about the motivation for this change, please check
> > commit 67fab22a7ad ("net: add getsockopt_iter callback to proto_ops")
> >
> > Signed-off-by: Breno Leitao <leitao@debian.org>
> > ---
> > Changes in v2:
> > - rebase the tree on top of bluetooth-next.
> > - Remove the selftest, which was mixing network and bluetooth together.
> > - Link to v1: https://patch.msgid.link/20260511-getsock_three-v1-0-1461fa8786ab@debian.org
> >
> > To: Marcel Holtmann <marcel@holtmann.org>
> > To: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
> > Cc: linux-bluetooth@vger.kernel.org
> > Cc: linux-kernel@vger.kernel.org
> >
> > ---
> > Breno Leitao (6):
> > Bluetooth: hci_sock: write the full optval for getsockopt
> > Bluetooth: hci_sock: convert to getsockopt_iter
> > Bluetooth: ISO: convert to getsockopt_iter
> > Bluetooth: RFCOMM: convert to getsockopt_iter
> > Bluetooth: L2CAP: convert to getsockopt_iter
> > Bluetooth: SCO: convert to getsockopt_iter
> >
> > net/bluetooth/hci_sock.c | 26 +++++++++++--------
> > net/bluetooth/iso.c | 27 ++++++++++----------
> > net/bluetooth/l2cap_sock.c | 61 +++++++++++++++++++++++++++------------------
> > net/bluetooth/rfcomm/sock.c | 30 ++++++++++++----------
> > net/bluetooth/sco.c | 59 ++++++++++++++++++++++---------------------
> > 5 files changed, 114 insertions(+), 89 deletions(-)
> > ---
> > base-commit: c2f0079e8c42fd6814c8d6b1491e3ce0a0e3b3fa
> > change-id: 20260511-getsock_three-d0d7f1b2629e
> >
> > Best regards,
> > --
> > Breno Leitao <leitao@debian.org>
>
> There are some comments from sashiko on this:
>
> https://sashiko.dev/#/patchset/20260512-getsock_three-v2-0-30b7b22ef14c%40debian.org
>
> Now Im not sure the truncating is actually used by our tools, but that
> sounds like it could break userspace if we don't check properly, or
> have you already done this for other socket families and it was
> considered to be ok?
You're right — to clarify, the patch changes behavior when the user
provides a short optlen, preventing the overflow that existed before:
- Old code: put_user(opt, (u32 __user *)optval) unconditionally
writes sizeof(*ptr) bytes regardless of optlen, so optlen < 4
would overflow the user buffer and return 0.
- New code: copy_to_iter() respects the optlen boundary, eliminating
the overflow — but now a short buffer fails the strict length check
and returns -EFAULT instead of 0.
I don't believe any legitimate userspace relies on the old overflow
behavior, though there's a theoretical risk of breakage. I'm not deeply
familiar with the Bluetooth ecosystem specifically, but, I would prefer to
avoid the buffer overflow in such case.
I've addressed a similar issue in another subsystem recently:
https://lore.kernel.org/all/20260521-fix_llc-v2-1-ab44cc09179c@debian.org/
Anyway, let me know if you need me to change it.
--breno
^ permalink raw reply
* [PATCH v7 1/1] Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_new_connection_cb()
From: Siwei Zhang @ 2026-06-01 14:03 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz; +Cc: linux-bluetooth, Siwei Zhang
In-Reply-To: <20260601140444.1676239-1-oss@fourdim.xyz>
l2cap_sock_new_connection_cb() accesses l2cap_pi(sk)->chan after
release_sock(parent). Once the parent lock is released, the child
socket sk can be freed by another task.
Allocate the channel outside the func to prevent this.
Fixes: 8ffb929098a5 ("Bluetooth: Remove parent socket usage from l2cap_core.c")
Cc: stable@kernel.org
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
---
include/net/bluetooth/l2cap.h | 8 +++--
net/bluetooth/6lowpan.c | 32 +++++++++++--------
net/bluetooth/l2cap_core.c | 60 ++++++++++++++++++++++++++---------
net/bluetooth/l2cap_sock.c | 48 ++++++++++++++++------------
net/bluetooth/smp.c | 18 +++++------
5 files changed, 106 insertions(+), 60 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 5172afee5494..f7a11e6431f0 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -619,7 +619,8 @@ struct l2cap_chan {
struct l2cap_ops {
char *name;
- struct l2cap_chan *(*new_connection) (struct l2cap_chan *chan);
+ int (*new_connection)(struct l2cap_chan *chan,
+ struct l2cap_chan *new_chan);
int (*recv) (struct l2cap_chan * chan,
struct sk_buff *skb);
void (*teardown) (struct l2cap_chan *chan, int err);
@@ -883,9 +884,10 @@ static inline __u16 __next_seq(struct l2cap_chan *chan, __u16 seq)
return (seq + 1) % (chan->tx_win_max + 1);
}
-static inline struct l2cap_chan *l2cap_chan_no_new_connection(struct l2cap_chan *chan)
+static inline int l2cap_chan_no_new_connection(struct l2cap_chan *chan,
+ struct l2cap_chan *new_chan)
{
- return NULL;
+ return -EOPNOTSUPP;
}
static inline int l2cap_chan_no_recv(struct l2cap_chan *chan, struct sk_buff *skb)
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 23a229ab6a33..284eefb73e94 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -622,6 +622,15 @@ static bool is_bt_6lowpan(struct hci_conn *hcon)
return true;
}
+static void chan_init(struct l2cap_chan *chan)
+{
+ l2cap_chan_set_defaults(chan);
+
+ chan->chan_type = L2CAP_CHAN_CONN_ORIENTED;
+ chan->mode = L2CAP_MODE_LE_FLOWCTL;
+ chan->imtu = 1280;
+}
+
static struct l2cap_chan *chan_create(void)
{
struct l2cap_chan *chan;
@@ -630,11 +639,7 @@ static struct l2cap_chan *chan_create(void)
if (!chan)
return NULL;
- l2cap_chan_set_defaults(chan);
-
- chan->chan_type = L2CAP_CHAN_CONN_ORIENTED;
- chan->mode = L2CAP_MODE_LE_FLOWCTL;
- chan->imtu = 1280;
+ chan_init(chan);
return chan;
}
@@ -743,19 +748,20 @@ static inline void chan_ready_cb(struct l2cap_chan *chan)
ifup(dev->netdev);
}
-static inline struct l2cap_chan *chan_new_conn_cb(struct l2cap_chan *pchan)
+static inline int chan_new_conn_cb(struct l2cap_chan *pchan,
+ struct l2cap_chan *chan)
{
- struct l2cap_chan *chan;
-
- chan = chan_create();
- if (!chan)
- return NULL;
-
+ chan_init(chan);
chan->ops = pchan->ops;
+ /* Take a reference to match the put in chan_close_cb(). The caller
+ * drops its own local reference after __l2cap_chan_add().
+ */
+ l2cap_chan_hold(chan);
+
BT_DBG("chan %p pchan %p", chan, pchan);
- return chan;
+ return 0;
}
static void unregister_dev(struct lowpan_btle_dev *dev)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index fdccd62ccca8..3edf6680899e 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4005,6 +4005,36 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn,
return 0;
}
+/* Allocate and initialise a channel for an incoming connection. The returned
+ * channel carries the caller's local reference, which must be dropped once
+ * __l2cap_chan_add() has pinned it via the conn list.
+ */
+static struct l2cap_chan *l2cap_new_connection(struct l2cap_chan *pchan)
+{
+ struct l2cap_chan *chan;
+
+ chan = l2cap_chan_create();
+ if (!chan)
+ return NULL;
+
+ if (pchan->ops->new_connection(pchan, chan) < 0) {
+ l2cap_chan_put(chan);
+ return NULL;
+ }
+
+ return chan;
+}
+
+/* Link a channel from l2cap_new_connection() into conn and release the local
+ * reference it carried. __l2cap_chan_add() pins the channel via the conn list,
+ * so it remains valid after this returns.
+ */
+static void l2cap_chan_add_new(struct l2cap_conn *conn, struct l2cap_chan *chan)
+{
+ __l2cap_chan_add(conn, chan);
+ l2cap_chan_put(chan);
+}
+
static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
u8 *data, u8 rsp_code)
{
@@ -4051,7 +4081,7 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
goto response;
}
- chan = pchan->ops->new_connection(pchan);
+ chan = l2cap_new_connection(pchan);
if (!chan)
goto response;
@@ -4069,7 +4099,7 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
chan->psm = psm;
chan->dcid = scid;
- __l2cap_chan_add(conn, chan);
+ l2cap_chan_add_new(conn, chan);
dcid = chan->scid;
@@ -4881,6 +4911,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
struct l2cap_le_conn_rsp rsp;
struct l2cap_chan *chan, *pchan;
u16 dcid, scid, credits, mtu, mps;
+ u16 rsp_mtu, rsp_mps;
__le16 psm;
u8 result;
@@ -4893,6 +4924,8 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
psm = req->psm;
dcid = 0;
credits = 0;
+ rsp_mtu = 0;
+ rsp_mps = 0;
if (mtu < 23 || mps < 23)
return -EPROTO;
@@ -4953,7 +4986,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
goto response_unlock;
}
- chan = pchan->ops->new_connection(pchan);
+ chan = l2cap_new_connection(pchan);
if (!chan) {
result = L2CAP_CR_LE_NO_MEM;
goto response_unlock;
@@ -4968,12 +5001,14 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
chan->omtu = mtu;
chan->remote_mps = mps;
- __l2cap_chan_add(conn, chan);
+ l2cap_chan_add_new(conn, chan);
l2cap_le_flowctl_init(chan, __le16_to_cpu(req->credits));
dcid = chan->scid;
credits = chan->rx_credits;
+ rsp_mtu = chan->imtu;
+ rsp_mps = chan->mps;
__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
@@ -5001,13 +5036,8 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
return 0;
response:
- if (chan) {
- rsp.mtu = cpu_to_le16(chan->imtu);
- rsp.mps = cpu_to_le16(chan->mps);
- } else {
- rsp.mtu = 0;
- rsp.mps = 0;
- }
+ rsp.mtu = cpu_to_le16(rsp_mtu);
+ rsp.mps = cpu_to_le16(rsp_mps);
rsp.dcid = cpu_to_le16(dcid);
rsp.credits = cpu_to_le16(credits);
@@ -5177,7 +5207,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
continue;
}
- chan = pchan->ops->new_connection(pchan);
+ chan = l2cap_new_connection(pchan);
if (!chan) {
result = L2CAP_CR_LE_NO_MEM;
continue;
@@ -5192,7 +5222,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
chan->omtu = mtu;
chan->remote_mps = mps;
- __l2cap_chan_add(conn, chan);
+ l2cap_chan_add_new(conn, chan);
l2cap_ecred_init(chan, __le16_to_cpu(req->credits));
@@ -7399,14 +7429,14 @@ static void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
goto next;
l2cap_chan_lock(pchan);
- chan = pchan->ops->new_connection(pchan);
+ chan = l2cap_new_connection(pchan);
if (chan) {
bacpy(&chan->src, &hcon->src);
bacpy(&chan->dst, &hcon->dst);
chan->src_type = bdaddr_src_type(hcon);
chan->dst_type = dst_type;
- __l2cap_chan_add(conn, chan);
+ l2cap_chan_add_new(conn, chan);
}
l2cap_chan_unlock(pchan);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index dede550d6031..598f24c8f704 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -46,7 +46,8 @@ static struct bt_sock_list l2cap_sk_list = {
static const struct proto_ops l2cap_sock_ops;
static void l2cap_sock_init(struct sock *sk, struct sock *parent);
static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
- int proto, gfp_t prio, int kern);
+ int proto, gfp_t prio, int kern,
+ struct l2cap_chan *chan);
static void l2cap_sock_cleanup_listen(struct sock *parent);
bool l2cap_is_socket(struct socket *sock)
@@ -1507,12 +1508,13 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
}
}
-static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
+static int l2cap_sock_new_connection_cb(struct l2cap_chan *chan,
+ struct l2cap_chan *new_chan)
{
struct sock *sk, *parent = chan->data;
if (!parent)
- return NULL;
+ return -EINVAL;
lock_sock(parent);
@@ -1520,15 +1522,15 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
if (sk_acceptq_is_full(parent)) {
BT_DBG("backlog full %d", parent->sk_ack_backlog);
release_sock(parent);
- return NULL;
+ return -ENOBUFS;
}
sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
- GFP_ATOMIC, 0);
+ GFP_ATOMIC, 0, new_chan);
if (!sk) {
release_sock(parent);
- return NULL;
- }
+ return -ENOMEM;
+ }
bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
@@ -1538,7 +1540,7 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
release_sock(parent);
- return l2cap_pi(sk)->chan;
+ return 0;
}
static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
@@ -1939,10 +1941,10 @@ static struct proto l2cap_proto = {
};
static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
- int proto, gfp_t prio, int kern)
+ int proto, gfp_t prio, int kern,
+ struct l2cap_chan *chan)
{
struct sock *sk;
- struct l2cap_chan *chan;
sk = bt_sock_alloc(net, sock, &l2cap_proto, proto, prio, kern);
if (!sk)
@@ -1953,14 +1955,11 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
INIT_LIST_HEAD(&l2cap_pi(sk)->rx_busy);
- chan = l2cap_chan_create();
- if (!chan) {
- sk_free(sk);
- if (sock)
- sock->sk = NULL;
- return NULL;
- }
-
+ /* The sock owns two refs on chan, matching the puts in
+ * l2cap_sock_kill() and l2cap_sock_destruct(). The caller keeps
+ * its own ref independent of these.
+ */
+ l2cap_chan_hold(chan);
l2cap_chan_hold(chan);
l2cap_pi(sk)->chan = chan;
@@ -1972,6 +1971,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
struct sock *sk;
+ struct l2cap_chan *chan;
BT_DBG("sock %p", sock);
@@ -1986,10 +1986,18 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
sock->ops = &l2cap_sock_ops;
- sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern);
- if (!sk)
+ chan = l2cap_chan_create();
+ if (!chan)
return -ENOMEM;
+ sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern, chan);
+ if (!sk) {
+ l2cap_chan_put(chan);
+ return -ENOMEM;
+ }
+ /* Sock has taken its own refs on chan; drop the chan_create() ref. */
+ l2cap_chan_put(chan);
+
l2cap_sock_init(sk, NULL);
bt_sock_link(&l2cap_sk_list, sk);
return 0;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 1739c1989dbd..887a2fc34391 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -3204,16 +3204,11 @@ static const struct l2cap_ops smp_chan_ops = {
.get_sndtimeo = l2cap_chan_no_get_sndtimeo,
};
-static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
+static inline int smp_new_conn_cb(struct l2cap_chan *pchan,
+ struct l2cap_chan *chan)
{
- struct l2cap_chan *chan;
-
BT_DBG("pchan %p", pchan);
- chan = l2cap_chan_create();
- if (!chan)
- return NULL;
-
chan->chan_type = pchan->chan_type;
chan->ops = &smp_chan_ops;
chan->scid = pchan->scid;
@@ -3229,9 +3224,14 @@ static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
*/
atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
- BT_DBG("created chan %p", chan);
+ /* Take a reference to match the put in smp_teardown_cb(). The caller
+ * drops its own local reference after __l2cap_chan_add().
+ */
+ l2cap_chan_hold(chan);
- return chan;
+ BT_DBG("initialised chan %p", chan);
+
+ return 0;
}
static const struct l2cap_ops smp_root_chan_ops = {
--
2.54.0
^ permalink raw reply related
* [PATCH v7 0/1] Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_new_connection_cb()
From: Siwei Zhang @ 2026-06-01 14:03 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz; +Cc: linux-bluetooth, Siwei Zhang
Compared to v2, addresses comments on https://sashiko.dev/#/patchset/20260415204842.2363950-1-oss%40fourdim.xyz .
Compared to v3, rebase against bluetooth-next.
Compared to v4, allocate the channel outside the function and pass it in as an argument to avoid the use-after-free.
Compared to v5, extract the channel init to a separate function.
Compared to v6, balance puts and holds on chans.
Siwei Zhang (1):
Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_new_connection_cb()
include/net/bluetooth/l2cap.h | 8 +++--
net/bluetooth/6lowpan.c | 32 +++++++++++--------
net/bluetooth/l2cap_core.c | 60 ++++++++++++++++++++++++++---------
net/bluetooth/l2cap_sock.c | 48 ++++++++++++++++------------
net/bluetooth/smp.c | 18 +++++------
5 files changed, 106 insertions(+), 60 deletions(-)
--
2.54.0
^ permalink raw reply
* Re: [PATCH 2/7] wifi: ath11k: enable support for WCN6851
From: Jeff Johnson @ 2026-06-01 13:54 UTC (permalink / raw)
To: Dmitry Baryshkov, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas,
Konrad Dybcio, Qiang Yu, Jeff Johnson, Liam Girdwood, Mark Brown,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski,
Marcel Holtmann, Luiz Augusto von Dentz, Balakrishna Godavarthi,
Rocky Liao, Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-pci, linux-kernel, linux-wireless, ath11k,
devicetree, Bartosz Golaszewski, linux-bluetooth
In-Reply-To: <20260601-sm8350-wifi-v1-2-242917d88031@oss.qualcomm.com>
On 6/1/2026 2:46 AM, Dmitry Baryshkov wrote:
> The WCN6851, found e.g. on SM8350 platforms, is an earlier version of
> WCN6855 platform. It identifies itself as hw1.1. Copy WCN6855 hw 2.0
> configuration to support hw1.1 version.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
> drivers/net/wireless/ath/ath11k/core.c | 92 ++++++++++++++++++++++++++++++++++
> drivers/net/wireless/ath/ath11k/core.h | 1 +
> drivers/net/wireless/ath/ath11k/mhi.c | 1 +
> drivers/net/wireless/ath/ath11k/pci.c | 9 ++++
> drivers/net/wireless/ath/ath11k/pcic.c | 11 ++++
> 5 files changed, 114 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
> index 3f6f4db5b7ee..7e997016cf6e 100644
> --- a/drivers/net/wireless/ath/ath11k/core.c
> +++ b/drivers/net/wireless/ath/ath11k/core.c
> @@ -393,6 +393,98 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
> .cfr_num_stream_bufs = 0,
> .cfr_stream_buf_size = 0,
> },
> + {
> + .name = "wcn6855 hw1.1",
> + .hw_rev = ATH11K_HW_WCN6855_HW11,
> + .fw = {
> + .dir = "WCN6855/hw1.1",
> + .board_size = 256 * 1024,
> + .cal_offset = 128 * 1024,
> + },
...> + .num_vdevs = 2 + 1,
this value is being modified to 4 in:
https://msgid.link/20260525020711.2590815-1-wei.zhang@oss.qualcomm.com
It is merging into ath-next today and should reach linux-next very soon.
/jeff
^ permalink raw reply
* Re: [PATCH BlueZ v2 0/2] advertising: add property with advertisement Instance
From: patchwork-bot+bluetooth @ 2026-06-01 13:50 UTC (permalink / raw)
To: Michal Dzik; +Cc: linux-bluetooth
In-Reply-To: <20260531101754.3325247-1-michal.dzik@streamunlimited.com>
Hello:
This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Sun, 31 May 2026 12:17:52 +0200 you wrote:
> I renamed Identifier to Instance and added support in client
>
> Michal Dzik (2):
> advertising: add property with advertisement Instance
> client: add advertisement instance support
>
> client/advertising.c | 38 +++++++++++++++++++++++++++++++
> client/advertising.h | 1 +
> client/main.c | 7 ++++++
> doc/org.bluez.LEAdvertisement.rst | 6 +++++
> src/advertising.c | 13 ++++++++++-
> 5 files changed, 64 insertions(+), 1 deletion(-)
Here is the summary with links:
- [BlueZ,v2,1/2] advertising: add property with advertisement Instance
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=b55c0559bda8
- [BlueZ,v2,2/2] client: add advertisement instance support
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=e2874db00a40
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH] Bluetooth: hci_sync: fix simultaneous discovery stuck in FINDING
From: Luiz Augusto von Dentz @ 2026-06-01 13:32 UTC (permalink / raw)
To: Jiajia Liu; +Cc: Marcel Holtmann, Brian Gix, linux-bluetooth, linux-kernel
In-Reply-To: <20260601012620.11764-1-liujiajia@kylinos.cn>
Hi Jiajia,
On Sun, May 31, 2026 at 9:26 PM Jiajia Liu <liujiajia@kylinos.cn> wrote:
>
> When hci_inquiry_complete_evt is called between le_scan_disable and
> le_set_scan_enable_complete and no remote name needs to be resolved,
> the interleaved discovery with SIMULTANEOUS quirk gets stuck in
> DISCOVERY_FINDING. le_set_scan_enable_complete does not check inquiry
> state. No one sets DISCOVERY_STOPPED in this process.
>
> < HCI Command: LE Set Extended Scan Enable #1764 [hci0] 608.610392
> Extended scan: Disabled (0x00)
> Filter duplicates: Disabled (0x00)
> Duration: 0 msec (0x0000)
> Period: 0.00 sec (0x0000)
> > HCI Event: Inquiry Complete (0x01) #1765 [hci0] 608.610548
> Status: Success (0x00)
> > HCI Event: Command Complete (0x0e) #1766 [hci0] 608.611589
> LE Set Extended Scan Enable (0x08|0x0042) ncmd 2
> Status: Success (0x00)
This isn't enough, though, where are the MGMT commands?
> Add scan_disable_complete to check state and stop discovery if stuck.
> Tested with bluetooth AX201 (8087:0026) in Dell Vostro 13 laptop.
>
> [4517.963204] hci0: state 0 -> 1
> [4518.096858] hci0: state 1 -> 2
> [4528.353765] hci0: state 2 -> 0
> [4528.353776] hci0: state finding to stopped
> [4533.966844] hci0: state 0 -> 1
> [4534.097702] hci0: state 1 -> 2
> [4544.478600] hci0: state 2 -> 0
>
> Fixes: 8ffde2a73f2c ("Bluetooth: Convert le_scan_disable timeout to hci_sync")
> Signed-off-by: Jiajia Liu <liujiajia@kylinos.cn>
> ---
> net/bluetooth/hci_sync.c | 25 ++++++++++++++++++++++++-
> 1 file changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
> index aff8562a8690..4cb1c82cc3f0 100644
> --- a/net/bluetooth/hci_sync.c
> +++ b/net/bluetooth/hci_sync.c
> @@ -361,6 +361,28 @@ static int interleaved_inquiry_sync(struct hci_dev *hdev, void *data)
> return hci_inquiry_sync(hdev, DISCOV_INTERLEAVED_INQUIRY_LEN, 0);
> }
>
> +static void scan_disable_complete(struct hci_dev *hdev, void *data, int err)
> +{
> + if (err)
> + return;
> +
> + hci_dev_lock(hdev);
> +
> + if (hdev->discovery.type != DISCOV_TYPE_INTERLEAVED)
> + goto unlock;
> +
> + if (hci_test_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY)) {
> + if (!test_bit(HCI_INQUIRY, &hdev->flags) &&
> + hdev->discovery.state == DISCOVERY_FINDING) {
> + hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
> + bt_dev_dbg(hdev, "state finding to stopped");
hci_discovery_set_state already prints the state so printing it again
is probably unnecessary. Also, this probably needs to be handled via
hci_event.c since it is not necessarily le_scan_disable that would
cause scan to be disabled, hci_scan_disable_sync can cause it as well.
> + }
> + }
> +
> +unlock:
> + hci_dev_unlock(hdev);
> +}
> +
> static void le_scan_disable(struct work_struct *work)
> {
> struct hci_dev *hdev = container_of(work, struct hci_dev,
> @@ -373,7 +395,8 @@ static void le_scan_disable(struct work_struct *work)
> if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
> goto _return;
>
> - status = hci_cmd_sync_queue(hdev, scan_disable_sync, NULL, NULL);
> + status = hci_cmd_sync_queue(hdev, scan_disable_sync, NULL,
> + scan_disable_complete);
> if (status) {
> bt_dev_err(hdev, "failed to disable LE scan: %d", status);
> goto _return;
> --
> 2.53.0
>
--
Luiz Augusto von Dentz
^ permalink raw reply
* RE: Bluetooth: Fix data-races in SCO/ISO connect paths
From: bluez.test.bot @ 2026-06-01 12:49 UTC (permalink / raw)
To: linux-bluetooth, suunj1331
In-Reply-To: <20260601111908.232707-2-suunj1331@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1096 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1103971
---Test result---
Test Summary:
CheckPatch PASS 1.45 seconds
VerifyFixes PASS 0.13 seconds
VerifySignedoff PASS 0.13 seconds
GitLint PASS 0.65 seconds
SubjectPrefix PASS 0.25 seconds
BuildKernel PASS 25.56 seconds
CheckAllWarning PASS 28.06 seconds
CheckSparse PASS 26.62 seconds
BuildKernel32 PASS 24.57 seconds
TestRunnerSetup PASS 524.16 seconds
TestRunner_iso-tester PASS 79.34 seconds
TestRunner_sco-tester PASS 32.06 seconds
IncrementalBuild PASS 26.22 seconds
https://github.com/bluez/bluetooth-next/pull/265
---
Regards,
Linux Bluetooth
^ permalink raw reply
* RE: Bluetooth: hci_qca: fix NULL pointer dereferences for non-serdev devices
From: bluez.test.bot @ 2026-06-01 12:48 UTC (permalink / raw)
To: linux-bluetooth, zijun.hu
In-Reply-To: <20260601-fix_none_serdev-v1-1-8d0497ba83b0@oss.qualcomm.com>
[-- Attachment #1: Type: text/plain, Size: 1532 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1103979
---Test result---
Test Summary:
CheckPatch PASS 1.39 seconds
VerifyFixes PASS 0.13 seconds
VerifySignedoff PASS 0.13 seconds
GitLint FAIL 0.64 seconds
SubjectPrefix PASS 0.24 seconds
BuildKernel PASS 26.00 seconds
CheckAllWarning PASS 29.06 seconds
CheckSparse PASS 27.65 seconds
BuildKernel32 PASS 25.56 seconds
TestRunnerSetup PASS 563.62 seconds
IncrementalBuild PASS 29.33 seconds
Details
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[1/2] Bluetooth: hci_qca: fix NULL pointer dereference in qca_setup() for non-serdev device
1: T1 Title exceeds max length (91>80): "[1/2] Bluetooth: hci_qca: fix NULL pointer dereference in qca_setup() for non-serdev device"
[2/2] Bluetooth: hci_qca: fix NULL pointer dereference in qca_dmp_hdr() for non-serdev device
1: T1 Title exceeds max length (93>80): "[2/2] Bluetooth: hci_qca: fix NULL pointer dereference in qca_dmp_hdr() for non-serdev device"
https://github.com/bluez/bluetooth-next/pull/266
---
Regards,
Linux Bluetooth
^ permalink raw reply
* RE: [v1] Bluetooth: btintel_pcie: Fix null pointer dereference in remove
From: bluez.test.bot @ 2026-06-01 12:47 UTC (permalink / raw)
To: linux-bluetooth, chandrashekar.devegowda
In-Reply-To: <20260601102612.2164388-1-chandrashekar.devegowda@intel.com>
[-- Attachment #1: Type: text/plain, Size: 988 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1103946
---Test result---
Test Summary:
CheckPatch PASS 0.68 seconds
VerifyFixes PASS 0.12 seconds
VerifySignedoff PASS 0.11 seconds
GitLint PASS 0.29 seconds
SubjectPrefix PASS 0.11 seconds
BuildKernel PASS 26.41 seconds
CheckAllWarning PASS 28.96 seconds
CheckSparse PASS 27.71 seconds
BuildKernel32 PASS 25.65 seconds
TestRunnerSetup PASS 568.66 seconds
IncrementalBuild PASS 24.69 seconds
https://github.com/bluez/bluetooth-next/pull/264
---
Regards,
Linux Bluetooth
^ permalink raw reply
* [PATCH v2] bluetooth: btintel: Add Bluetooth SAR revision 2 support
From: Kiran K @ 2026-06-01 12:48 UTC (permalink / raw)
To: linux-bluetooth
Cc: ravishankar.srivatsa, chethan.tumkur.narayan, Kiran K, Ravindra
BRDS revision 2 introduces per-chain (Chain A and Chain B) TX power
limits across five sub-bands (2.4G, 5.2G, 5.8/5.9G, 6G-low, 6G-high),
replacing the single-chain per-modulation model of revisions 0 and 1.
- Add btintel_set_sar_rev2() which sends the full Rev2 DDC sequence:
0x019e inc-power-mode enable flag (1 byte)
0x0311 2.4 GHz sub-band limits (2 bytes)
0x0312 5.2 GHz sub-band limits (2 bytes)
0x0313 5.8/5.9 GHz sub-band limits (2 bytes)
0x0314 5.8/5.9 GHz sub-band limits again (2 bytes, duplicate FW reg)
0x0315 6 GHz low sub-band limits (2 bytes)
0x0316 6 GHz high sub-band limits (2 bytes)
followed by the SAR-init-complete command (0xfe25).
logs from dmesg when BTSAR2 is enabled in Coreboot/BIOS:
Bluetooth: hci0: BT SAR Rev2: revision=2 bt_sar_bios=1 inc_power_mode=1
Bluetooth: hci0: BT SAR Rev2 Chain A: 2g4=76 5g2=0 5g8_5g9=0 6g1=0 6g3=0
Bluetooth: hci0: BT SAR Rev2 Chain B: 2g4=102 5g2=0 5g8_5g9=0 6g1=0 6g3=0
Signed-off-by: Ravindra <ravindra@intel.com>
Signed-off-by: Kiran K <kiran.k@intel.com>
---
changes in v2:
- Update commit message to include logs
- Validate the ACPI types/size before accessing.
drivers/bluetooth/btintel.c | 195 +++++++++++++++++++++++++++++++++++-
drivers/bluetooth/btintel.h | 18 ++++
2 files changed, 212 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index 5e9cac090bd8..3f6e5285c780 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -51,6 +51,7 @@ enum {
#define BTINTEL_BT_DOMAIN 0x12
#define BTINTEL_SAR_LEGACY 0
#define BTINTEL_SAR_INC_PWR 1
+#define BTINTEL_SAR_REV2 2
#define BTINTEL_SAR_INC_PWR_SUPPORTED 0
#define CMD_WRITE_BOOT_PARAMS 0xfc0e
@@ -3104,6 +3105,111 @@ static int btintel_set_mutual_sar(struct hci_dev *hdev, struct btintel_sar_inc_p
return 0;
}
+/* btintel_send_sar_rev2_band - send DDC command for one Rev2 sub-band
+ *
+ * Each DDC 0x0311-0x0316 carries 2 bytes: [ChainA_value, ChainB_value].
+ * cmd->len = 4 (2 id + 2 data)
+ * HCI total = 5 bytes (1 len + 4)
+ */
+static int btintel_send_sar_rev2_band(struct hci_dev *hdev,
+ struct btintel_cp_ddc_write *cmd,
+ u16 id, u8 chain_a, u8 chain_b)
+{
+ cmd->len = 4;
+ cmd->id = cpu_to_le16(id);
+ cmd->data[0] = chain_a;
+ cmd->data[1] = chain_b;
+ return btintel_send_sar_ddc(hdev, cmd, 5);
+}
+
+static int btintel_set_sar_rev2(struct hci_dev *hdev,
+ struct btintel_sar_rev2 *sar)
+{
+ struct btintel_cp_ddc_write *cmd;
+ struct sk_buff *skb;
+ u8 buffer[64];
+ u8 enable;
+ int ret;
+
+ cmd = (void *)buffer;
+
+ /* DDC 0x019e: enable/disable increased power mode SAR (1 byte) */
+ cmd->len = 3;
+ cmd->id = cpu_to_le16(0x019e);
+ cmd->data[0] = (sar->inc_power_mode == BTINTEL_SAR_INC_PWR_SUPPORTED) ?
+ 0x01 : 0x00;
+ ret = btintel_send_sar_ddc(hdev, cmd, 4);
+ if (ret)
+ return ret;
+
+ /* DDC 0x0311-0x0316: per sub-band ChainA + ChainB limits */
+ ret = btintel_send_sar_rev2_band(hdev, cmd, 0x0311,
+ sar->chain_a.subband_2g4,
+ sar->chain_b.subband_2g4);
+ if (ret)
+ return ret;
+
+ ret = btintel_send_sar_rev2_band(hdev, cmd, 0x0312,
+ sar->chain_a.subband_5g2,
+ sar->chain_b.subband_5g2);
+ if (ret)
+ return ret;
+
+ /* 0x0313 and 0x0314 both carry the 5G8/5G9 value */
+ ret = btintel_send_sar_rev2_band(hdev, cmd, 0x0313,
+ sar->chain_a.subband_5g8_5g9,
+ sar->chain_b.subband_5g8_5g9);
+ if (ret)
+ return ret;
+
+ ret = btintel_send_sar_rev2_band(hdev, cmd, 0x0314,
+ sar->chain_a.subband_5g8_5g9,
+ sar->chain_b.subband_5g8_5g9);
+ if (ret)
+ return ret;
+
+ ret = btintel_send_sar_rev2_band(hdev, cmd, 0x0315,
+ sar->chain_a.subband_6g1,
+ sar->chain_b.subband_6g1);
+ if (ret)
+ return ret;
+
+ ret = btintel_send_sar_rev2_band(hdev, cmd, 0x0316,
+ sar->chain_a.subband_6g3,
+ sar->chain_b.subband_6g3);
+ if (ret)
+ return ret;
+
+ /* Notify firmware that SAR initialisation is complete */
+ enable = 0x01;
+ skb = __hci_cmd_sync(hdev, 0xfe25, sizeof(enable), &enable, HCI_CMD_TIMEOUT);
+ if (IS_ERR(skb)) {
+ bt_dev_warn(hdev, "Failed to send Intel SAR Rev2 Enable (%ld)",
+ PTR_ERR(skb));
+ return PTR_ERR(skb);
+ }
+
+ kfree_skb(skb);
+ return 0;
+}
+
+static int btintel_sar_rev2_send_to_device(struct hci_dev *hdev,
+ struct btintel_sar_rev2 *sar,
+ struct intel_version_tlv *ver)
+{
+ u16 cnvi = ver->cnvi_top & 0xfff;
+ u16 cnvr = ver->cnvr_top & 0xfff;
+
+ if (cnvi < BTINTEL_CNVI_BLAZARI || cnvr != BTINTEL_CNVR_WHP2) {
+ bt_dev_dbg(hdev, "BT SAR Rev2 not supported on this platform (cnvi=0x%x cnvr=0x%x)",
+ cnvi, cnvr);
+ return -EOPNOTSUPP;
+ }
+
+ bt_dev_info(hdev, "Applying Bluetooth SAR Rev2");
+ return btintel_set_sar_rev2(hdev, sar);
+}
+
static int btintel_sar_send_to_device(struct hci_dev *hdev, struct btintel_sar_inc_pwr *sar,
struct intel_version_tlv *ver)
{
@@ -3130,6 +3236,7 @@ static int btintel_acpi_set_sar(struct hci_dev *hdev, struct intel_version_tlv *
{
union acpi_object *bt_pkg, *buffer = NULL;
struct btintel_sar_inc_pwr sar;
+ struct btintel_sar_rev2 sar_rev2;
acpi_status status;
u8 revision;
int ret;
@@ -3150,14 +3257,100 @@ static int btintel_acpi_set_sar(struct hci_dev *hdev, struct intel_version_tlv *
goto error;
}
+ if (buffer->package.elements[0].type != ACPI_TYPE_INTEGER) {
+ bt_dev_warn(hdev, "BT_SAR: unexpected ACPI type for revision field");
+ ret = -EINVAL;
+ goto error;
+ }
+
revision = buffer->package.elements[0].integer.value;
- if (revision > BTINTEL_SAR_INC_PWR) {
+ if (revision > BTINTEL_SAR_REV2) {
bt_dev_dbg(hdev, "BT_SAR: revision: 0x%2.2x not supported", revision);
ret = -EOPNOTSUPP;
goto error;
}
+ if (revision == BTINTEL_SAR_REV2 && bt_pkg->package.count == 13) {
+ /* Element layout: 0 = revision, 1 = bt_sar_bios (u32),
+ * 2 = inc_power_mode (u32), 3..12 = per-chain sub-band
+ * limits (u8 each). Validate each ACPI element is an
+ * integer and fits its destination width before we read
+ * the union; otherwise we could misinterpret string
+ * lengths or buffer pointers as TX power limits, or
+ * silently truncate out-of-range BIOS values into a
+ * regulatory-critical sub-band field.
+ */
+ static const u64 rev2_max[13] = {
+ U8_MAX, /* revision */
+ U32_MAX, U32_MAX, /* bt_sar_bios, inc_power_mode */
+ U8_MAX, U8_MAX, U8_MAX, U8_MAX, U8_MAX, /* chain A */
+ U8_MAX, U8_MAX, U8_MAX, U8_MAX, U8_MAX, /* chain B */
+ };
+ union acpi_object *e;
+ int i;
+
+ for (i = 0; i < 13; i++) {
+ e = &bt_pkg->package.elements[i];
+ if (e->type != ACPI_TYPE_INTEGER) {
+ bt_dev_warn(hdev, "BT SAR Rev2: unexpected ACPI type at element %d",
+ i);
+ ret = -EINVAL;
+ goto error;
+ }
+ if (e->integer.value > rev2_max[i]) {
+ bt_dev_warn(hdev, "BT SAR Rev2: element %d value 0x%llx out of range",
+ i, e->integer.value);
+ ret = -ERANGE;
+ goto error;
+ }
+ }
+
+ memset(&sar_rev2, 0, sizeof(sar_rev2));
+ sar_rev2.revision = revision;
+ sar_rev2.bt_sar_bios = bt_pkg->package.elements[1].integer.value;
+ sar_rev2.inc_power_mode = bt_pkg->package.elements[2].integer.value;
+
+ sar_rev2.chain_a.subband_2g4 = bt_pkg->package.elements[3].integer.value;
+ sar_rev2.chain_a.subband_5g2 = bt_pkg->package.elements[4].integer.value;
+ sar_rev2.chain_a.subband_5g8_5g9 = bt_pkg->package.elements[5].integer.value;
+ sar_rev2.chain_a.subband_6g1 = bt_pkg->package.elements[6].integer.value;
+ sar_rev2.chain_a.subband_6g3 = bt_pkg->package.elements[7].integer.value;
+
+ sar_rev2.chain_b.subband_2g4 = bt_pkg->package.elements[8].integer.value;
+ sar_rev2.chain_b.subband_5g2 = bt_pkg->package.elements[9].integer.value;
+ sar_rev2.chain_b.subband_5g8_5g9 = bt_pkg->package.elements[10].integer.value;
+ sar_rev2.chain_b.subband_6g1 = bt_pkg->package.elements[11].integer.value;
+ sar_rev2.chain_b.subband_6g3 = bt_pkg->package.elements[12].integer.value;
+
+ bt_dev_dbg(hdev, "BT SAR Rev2: revision=%u bt_sar_bios=%u inc_power_mode=%u",
+ sar_rev2.revision, sar_rev2.bt_sar_bios, sar_rev2.inc_power_mode);
+ bt_dev_dbg(hdev, "BT SAR Rev2 Chain A: 2g4=%u 5g2=%u 5g8_5g9=%u 6g1=%u 6g3=%u",
+ sar_rev2.chain_a.subband_2g4, sar_rev2.chain_a.subband_5g2,
+ sar_rev2.chain_a.subband_5g8_5g9, sar_rev2.chain_a.subband_6g1,
+ sar_rev2.chain_a.subband_6g3);
+ bt_dev_dbg(hdev, "BT SAR Rev2 Chain B: 2g4=%u 5g2=%u 5g8_5g9=%u 6g1=%u 6g3=%u",
+ sar_rev2.chain_b.subband_2g4, sar_rev2.chain_b.subband_5g2,
+ sar_rev2.chain_b.subband_5g8_5g9, sar_rev2.chain_b.subband_6g1,
+ sar_rev2.chain_b.subband_6g3);
+
+ if (sar_rev2.bt_sar_bios != 1) {
+ bt_dev_info(hdev, "Bluetooth SAR Rev2 is not enabled");
+ ret = -EOPNOTSUPP;
+ goto error;
+ }
+
+ ret = btintel_sar_rev2_send_to_device(hdev, &sar_rev2, ver);
+ goto error;
+ }
+
+ if (revision == BTINTEL_SAR_REV2) {
+ bt_dev_warn(hdev, "BT SAR Rev2: unexpected ACPI package count %d (expected 13)",
+ bt_pkg->package.count);
+ ret = -EINVAL;
+ goto error;
+ }
+
memset(&sar, 0, sizeof(sar));
if (revision == BTINTEL_SAR_LEGACY && bt_pkg->package.count == 8) {
diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h
index 70d812ad36a2..3b5a228ca3c0 100644
--- a/drivers/bluetooth/btintel.h
+++ b/drivers/bluetooth/btintel.h
@@ -64,6 +64,7 @@ struct intel_tlv {
/* CNVR */
#define BTINTEL_CNVR_FMP2 0x910
+#define BTINTEL_CNVR_WHP2 0xA10 /* Whale Peak2 - Panther Lake */
#define BTINTEL_IMG_BOOTLOADER 0x01 /* Bootloader image */
#define BTINTEL_IMG_IML 0x02 /* Intermediate image */
@@ -202,6 +203,23 @@ struct btintel_sar_inc_pwr {
u8 le_lr;
};
+/* Bluetooth SAR feature (BRDS), Revision 2 - per-chain sub-band power limits */
+struct btintel_sar_band_limits {
+ u8 subband_2g4;
+ u8 subband_5g2;
+ u8 subband_5g8_5g9;
+ u8 subband_6g1;
+ u8 subband_6g3;
+};
+
+struct btintel_sar_rev2 {
+ u8 revision;
+ u32 bt_sar_bios; /* 1: BIOS-managed SAR enabled */
+ u32 inc_power_mode; /* 0: supported, 1: disabled */
+ struct btintel_sar_band_limits chain_a;
+ struct btintel_sar_band_limits chain_b;
+};
+
#define INTEL_HW_PLATFORM(cnvx_bt) ((u8)(((cnvx_bt) & 0x0000ff00) >> 8))
#define INTEL_HW_VARIANT(cnvx_bt) ((u8)(((cnvx_bt) & 0x003f0000) >> 16))
#define INTEL_CNVX_TOP_TYPE(cnvx_top) ((cnvx_top) & 0x00000fff)
--
2.54.0
^ permalink raw reply related
* RE: arm64: dts: qcom: enable WiFi/BT on SM8350 HDK
From: bluez.test.bot @ 2026-06-01 12:22 UTC (permalink / raw)
To: linux-bluetooth, dmitry.baryshkov
In-Reply-To: <20260601-sm8350-wifi-v1-1-242917d88031@oss.qualcomm.com>
[-- Attachment #1: Type: text/plain, Size: 579 bytes --]
This is an automated email and please do not reply to this email.
Dear Submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
While preparing the CI tests, the patches you submitted couldn't be applied to the current HEAD of the repository.
----- Output -----
error: patch failed: drivers/pci/controller/dwc/pcie-qcom.c:1907
error: drivers/pci/controller/dwc/pcie-qcom.c: patch does not apply
hint: Use 'git am --show-current-patch' to see the failed patch
Please resolve the issue and submit the patches again.
---
Regards,
Linux Bluetooth
^ permalink raw reply
* [PATCH 2/2] Bluetooth: hci_qca: fix NULL pointer dereference in qca_dmp_hdr() for non-serdev device
From: Zijun Hu @ 2026-06-01 11:30 UTC (permalink / raw)
To: Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
Mengshi Wu, Dmitry Baryshkov, Sai Teja Aluvala
Cc: Zijun Hu, Luiz Augusto von Dentz, Bartosz Golaszewski,
linux-arm-msm, linux-bluetooth, linux-kernel, Zijun Hu
In-Reply-To: <20260601-fix_none_serdev-v1-0-8d0497ba83b0@oss.qualcomm.com>
hu->serdev is NULL for hci_uart attached via non-serdev paths, but
qca_dmp_hdr() unconditionally dereferences hu->serdev->dev.driver->name,
causing a NULL pointer dereference.
Fix by guarding the dereference with a NULL check and falling back to
"hci_ldisc_qca" for the non-serdev case.
Fixes: 06d3fdfcdf5c ("Bluetooth: hci_qca: Add qcom devcoredump support")
Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com>
---
drivers/bluetooth/hci_qca.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index cc7b34a61fa7..244447195619 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1028,7 +1028,7 @@ static void qca_dmp_hdr(struct hci_dev *hdev, struct sk_buff *skb)
skb_put_data(skb, buf, strlen(buf));
snprintf(buf, sizeof(buf), "Driver: %s\n",
- hu->serdev->dev.driver->name);
+ hu->serdev ? hu->serdev->dev.driver->name : "hci_ldisc_qca");
skb_put_data(skb, buf, strlen(buf));
}
--
2.34.1
^ permalink raw reply related
* [PATCH 1/2] Bluetooth: hci_qca: fix NULL pointer dereference in qca_setup() for non-serdev device
From: Zijun Hu @ 2026-06-01 11:30 UTC (permalink / raw)
To: Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
Mengshi Wu, Dmitry Baryshkov, Sai Teja Aluvala
Cc: Zijun Hu, Luiz Augusto von Dentz, Bartosz Golaszewski,
linux-arm-msm, linux-bluetooth, linux-kernel, Zijun Hu
In-Reply-To: <20260601-fix_none_serdev-v1-0-8d0497ba83b0@oss.qualcomm.com>
hu->serdev is NULL for hci_uart attached via non-serdev paths, but
qca_setup() unconditionally calls serdev_device_get_drvdata(hu->serdev)
and dereferences the result, causing a NULL pointer dereference.
Fix by guarding the dereference with a NULL check, consistent with the
rest of qca_setup().
Fixes: 22d893eec0d5 ("Bluetooth: hci_qca: Refactor HFP hardware offload capability handling")
Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com>
---
drivers/bluetooth/hci_qca.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 34500137df2c..cc7b34a61fa7 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1916,9 +1916,12 @@ static int qca_setup(struct hci_uart *hu)
const char *rampatch_name = qca_get_rampatch_name(hu);
int ret;
struct qca_btsoc_version ver;
- struct qca_serdev *qcadev = serdev_device_get_drvdata(hu->serdev);
+ struct qca_serdev *qcadev = NULL;
const char *soc_name;
+ if (hu->serdev)
+ qcadev = serdev_device_get_drvdata(hu->serdev);
+
ret = qca_check_speeds(hu);
if (ret)
return ret;
@@ -1980,7 +1983,7 @@ static int qca_setup(struct hci_uart *hu)
case QCA_WCN6750:
case QCA_WCN6855:
case QCA_WCN7850:
- if (qcadev->bdaddr_property_broken)
+ if (qcadev && qcadev->bdaddr_property_broken)
hci_set_quirk(hdev, HCI_QUIRK_BDADDR_PROPERTY_BROKEN);
hci_set_aosp_capable(hdev);
@@ -2073,7 +2076,7 @@ static int qca_setup(struct hci_uart *hu)
else
hu->hdev->set_bdaddr = qca_set_bdaddr;
- if (qcadev->support_hfp_hw_offload)
+ if (qcadev && qcadev->support_hfp_hw_offload)
qca_configure_hfp_offload(hdev);
qca->fw_version = le16_to_cpu(ver.patch_ver);
--
2.34.1
^ permalink raw reply related
* [PATCH 0/2] Bluetooth: hci_qca: fix NULL pointer dereferences for non-serdev devices
From: Zijun Hu @ 2026-06-01 11:30 UTC (permalink / raw)
To: Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
Mengshi Wu, Dmitry Baryshkov, Sai Teja Aluvala
Cc: Zijun Hu, Luiz Augusto von Dentz, Bartosz Golaszewski,
linux-arm-msm, linux-bluetooth, linux-kernel, Zijun Hu
When a QCA controller is attached via a non-serdev path (e.g. hci_uart
line discipline), hu->serdev is NULL. A couple of code paths dereference
it unconditionally, leading to NULL pointer dereferences.
This series fixes two such cases:
- qca_setup() dereferences the result of
serdev_device_get_drvdata(hu->serdev).
- qca_dmp_hdr() dereferences hu->serdev->dev.driver->name.
Both are fixed by guarding the dereference with a NULL check.
Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com>
---
Zijun Hu (2):
Bluetooth: hci_qca: fix NULL pointer dereference in qca_setup() for non-serdev device
Bluetooth: hci_qca: fix NULL pointer dereference in qca_dmp_hdr() for non-serdev device
drivers/bluetooth/hci_qca.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
---
base-commit: 379b101059b44f64f6c5c022724f880a68fed15b
change-id: 20260601-fix_none_serdev-5f0635c21681
Best regards,
--
Zijun Hu <zijun.hu@oss.qualcomm.com>
^ permalink raw reply
* [PATCH v2 2/2] Bluetooth: SCO: Fix data-race on sco_pi fields in sco_connect
From: SeungJu Cheon @ 2026-06-01 11:19 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: linux-bluetooth, linux-kernel, me, skhan, linux-kernel-mentees,
SeungJu Cheon
In-Reply-To: <20260601111908.232707-1-suunj1331@gmail.com>
sco_sock_connect() copies the destination address into sco_pi(sk)->dst
under lock_sock(), then releases the lock and calls sco_connect(),
which reads dst, src, setting, and codec without holding lock_sock() in
hci_get_route() and hci_connect_sco().
These fields may be modified concurrently by connect(), bind(), or
setsockopt() on the same socket, resulting in data-races reported by
KCSAN.
Fix this by snapshotting dst, src, setting, and codec under lock_sock()
at the start of sco_connect() before passing them to hci_get_route()
and hci_connect_sco().
BUG: KCSAN: data-race in memcmp+0x45/0xb0
race at unknown origin, with read to 0xffff88800e6b0dd0 of 1 bytes
by task 315 on cpu 0:
memcmp+0x45/0xb0
hci_connect_acl+0x1b7/0x6b0
hci_connect_sco+0x4d/0xb30
sco_sock_connect+0x27b/0xd60
__sys_connect_file+0xbd/0xe0
__sys_connect+0xe0/0x110
__x64_sys_connect+0x40/0x50
x64_sys_call+0xcad/0x1c60
do_syscall_64+0x133/0x590
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Fixes: 9a8ec9e8ebb5 ("Bluetooth: SCO: Fix possible circular locking dependency on sco_connect_cfm")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
---
net/bluetooth/sco.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index f1799c6a6f87..140869e5b2df 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -312,11 +312,21 @@ static int sco_connect(struct sock *sk)
struct sco_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
+ bdaddr_t src, dst;
+ struct bt_codec codec;
+ __u16 setting;
int err, type;
- BT_DBG("%pMR -> %pMR", &sco_pi(sk)->src, &sco_pi(sk)->dst);
+ lock_sock(sk);
+ bacpy(&src, &sco_pi(sk)->src);
+ bacpy(&dst, &sco_pi(sk)->dst);
+ setting = sco_pi(sk)->setting;
+ codec = sco_pi(sk)->codec;
+ release_sock(sk);
+
+ BT_DBG("%pMR -> %pMR", &src, &dst);
- hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src, BDADDR_BREDR);
+ hdev = hci_get_route(&dst, &src, BDADDR_BREDR);
if (!hdev)
return -EHOSTUNREACH;
@@ -327,7 +337,7 @@ static int sco_connect(struct sock *sk)
else
type = SCO_LINK;
- switch (sco_pi(sk)->setting & SCO_AIRMODE_MASK) {
+ switch (setting & SCO_AIRMODE_MASK) {
case SCO_AIRMODE_TRANSP:
if (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev)) {
err = -EOPNOTSUPP;
@@ -336,8 +346,8 @@ static int sco_connect(struct sock *sk)
break;
}
- hcon = hci_connect_sco(hdev, type, &sco_pi(sk)->dst,
- sco_pi(sk)->setting, &sco_pi(sk)->codec,
+ hcon = hci_connect_sco(hdev, type, &dst,
+ setting, &codec,
READ_ONCE(sk->sk_sndtimeo));
if (IS_ERR(hcon)) {
err = PTR_ERR(hcon);
--
2.52.0
^ permalink raw reply related
* [PATCH v2 1/2] Bluetooth: ISO: Fix data-race on iso_pi fields in hci_get_route calls
From: SeungJu Cheon @ 2026-06-01 11:19 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: linux-bluetooth, linux-kernel, me, skhan, linux-kernel-mentees,
SeungJu Cheon
In-Reply-To: <20260601111908.232707-1-suunj1331@gmail.com>
iso_connect_bis(), iso_connect_cis(), iso_listen_bis(), and
iso_conn_big_sync() call hci_get_route() using iso_pi(sk)->dst,
iso_pi(sk)->src, and iso_pi(sk)->src_type without holding lock_sock().
These fields may be modified concurrently by connect() or setsockopt()
on the same socket, resulting in data-races reported by KCSAN.
Fix this by snapshotting the required fields under lock_sock() before
calling hci_get_route().
BUG: KCSAN: data-race in memcmp+0x45/0xb0
race at unknown origin, with read to 0xffff8880122135cf of 1 bytes
by task 333 on cpu 1:
memcmp+0x45/0xb0
hci_get_route+0x27e/0x490
iso_connect_cis+0x4c/0xa10
iso_sock_connect+0x60e/0xb30
__sys_connect_file+0xbd/0xe0
__sys_connect+0xe0/0x110
__x64_sys_connect+0x40/0x50
x64_sys_call+0xcad/0x1c60
do_syscall_64+0x133/0x590
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
---
net/bluetooth/iso.c | 60 +++++++++++++++++++++++++++++++++------------
1 file changed, 44 insertions(+), 16 deletions(-)
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index d7af617cda45..b4196ccaf766 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -337,12 +337,20 @@ static int iso_connect_bis(struct sock *sk)
struct iso_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
+ bdaddr_t src, dst;
+ u8 src_type, bc_sid;
int err;
- BT_DBG("%pMR (SID 0x%2.2x)", &iso_pi(sk)->src, iso_pi(sk)->bc_sid);
+ lock_sock(sk);
+ bacpy(&src, &iso_pi(sk)->src);
+ bacpy(&dst, &iso_pi(sk)->dst);
+ src_type = iso_pi(sk)->src_type;
+ bc_sid = iso_pi(sk)->bc_sid;
+ release_sock(sk);
- hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
- iso_pi(sk)->src_type);
+ BT_DBG("%pMR (SID 0x%2.2x)", &src, bc_sid);
+
+ hdev = hci_get_route(&dst, &src, src_type);
if (!hdev)
return -EHOSTUNREACH;
@@ -430,12 +438,19 @@ static int iso_connect_cis(struct sock *sk)
struct iso_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
+ bdaddr_t src, dst;
+ u8 src_type;
int err;
- BT_DBG("%pMR -> %pMR", &iso_pi(sk)->src, &iso_pi(sk)->dst);
+ lock_sock(sk);
+ bacpy(&src, &iso_pi(sk)->src);
+ bacpy(&dst, &iso_pi(sk)->dst);
+ src_type = iso_pi(sk)->src_type;
+ release_sock(sk);
+
+ BT_DBG("%pMR -> %pMR", &src, &dst);
- hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
- iso_pi(sk)->src_type);
+ hdev = hci_get_route(&dst, &src, src_type);
if (!hdev)
return -EHOSTUNREACH;
@@ -1208,18 +1223,25 @@ static int iso_sock_connect(struct socket *sock, struct sockaddr_unsized *addr,
static int iso_listen_bis(struct sock *sk)
{
- struct hci_dev *hdev;
- int err = 0;
struct iso_conn *conn;
struct hci_conn *hcon;
+ struct hci_dev *hdev;
+ bdaddr_t src, dst;
+ u8 src_type, bc_sid;
+ int err = 0;
+
+ lock_sock(sk);
+ bacpy(&src, &iso_pi(sk)->src);
+ bacpy(&dst, &iso_pi(sk)->dst);
+ src_type = iso_pi(sk)->src_type;
+ bc_sid = iso_pi(sk)->bc_sid;
+ release_sock(sk);
- BT_DBG("%pMR -> %pMR (SID 0x%2.2x)", &iso_pi(sk)->src,
- &iso_pi(sk)->dst, iso_pi(sk)->bc_sid);
+ BT_DBG("%pMR -> %pMR (SID 0x%2.2x)", &src, &dst, bc_sid);
write_lock(&iso_sk_list.lock);
- if (__iso_get_sock_listen_by_sid(&iso_pi(sk)->src, &iso_pi(sk)->dst,
- iso_pi(sk)->bc_sid))
+ if (__iso_get_sock_listen_by_sid(&src, &dst, bc_sid))
err = -EADDRINUSE;
write_unlock(&iso_sk_list.lock);
@@ -1227,8 +1249,7 @@ static int iso_listen_bis(struct sock *sk)
if (err)
return err;
- hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
- iso_pi(sk)->src_type);
+ hdev = hci_get_route(&dst, &src, src_type);
if (!hdev)
return -EHOSTUNREACH;
@@ -1564,9 +1585,16 @@ static void iso_conn_big_sync(struct sock *sk)
{
int err;
struct hci_dev *hdev;
+ bdaddr_t src, dst;
+ u8 src_type;
+
+ lock_sock(sk);
+ bacpy(&src, &iso_pi(sk)->src);
+ bacpy(&dst, &iso_pi(sk)->dst);
+ src_type = iso_pi(sk)->src_type;
+ release_sock(sk);
- hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
- iso_pi(sk)->src_type);
+ hdev = hci_get_route(&dst, &src, src_type);
if (!hdev)
return;
--
2.52.0
^ permalink raw reply related
* [PATCH v2 0/2] Bluetooth: Fix data-races in SCO/ISO connect paths
From: SeungJu Cheon @ 2026-06-01 11:19 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: linux-bluetooth, linux-kernel, me, skhan, linux-kernel-mentees,
SeungJu Cheon
The connect paths read socket address and config fields without
lock_sock() and pass them to hci_get_route() and hci_connect_*(),
while connect()/bind()/setsockopt() can update them concurrently.
Patch 1 covers ISO (iso_connect_bis/cis, iso_listen_bis,
iso_conn_big_sync), patch 2 covers SCO (sco_connect).
The added lock_sock() sections are reached with the lock not held and
released before hci_get_route()/hci_dev_lock(), so no recursive locking
or new lock ordering is introduced.
Tested on KCSAN + PROVE_LOCKING with VHCI reproducers on the SCO and
ISO CIS connect paths; the hci_get_route() race no longer reproduces
and no lockdep splat is seen.
Changes in v2:
- ISO: cache bc_sid too, and pass cached src/dst/bc_sid to
__iso_get_sock_listen_by_sid() in iso_listen_bis() (missed in v1)
- ISO: use cached bc_sid in BT_DBG() in iso_connect_bis()
- SCO: also snapshot src, setting and codec; v1 only did dst
- reword: the fix stops torn reads, it does not close the TOCTOU window
- fix the SCO Fixes: tag title
SeungJu Cheon (2):
Bluetooth: ISO: Fix data-race on iso_pi fields in hci_get_route calls
Bluetooth: SCO: Fix data-race on sco_pi fields in sco_connect
net/bluetooth/iso.c | 60 +++++++++++++++++++++++++++++++++------------
net/bluetooth/sco.c | 20 +++++++++++----
2 files changed, 59 insertions(+), 21 deletions(-)
--
2.52.0
^ permalink raw reply
* [PATCH v1] Bluetooth: btintel_pcie: Fix null pointer dereference in remove
From: Chandrashekar Devegowda @ 2026-06-01 10:26 UTC (permalink / raw)
To: linux-bluetooth
Cc: linux-pci, bhelgaas, ravishankar.srivatsa, chethan.tumkur.narayan,
Chandrashekar Devegowda
Add a NULL check for pci_get_drvdata() in btintel_pcie_remove() to
prevent a null pointer dereference. This can occur when
btintel_pcie_remove() is called concurrently from the PLDR
device_reprobe path on another CPU, after pci_set_drvdata(pdev, NULL)
has already been executed.
Fixes: 8c0693e29dba ("Bluetooth: btintel_pcie: Support Product level reset")
Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
---
drivers/bluetooth/btintel_pcie.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index eba563b66090..eeaefffaaf6b 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -2694,6 +2694,10 @@ static void btintel_pcie_remove(struct pci_dev *pdev)
struct btintel_pcie_data *data;
data = pci_get_drvdata(pdev);
+ if (!data) {
+ BT_WARN("PCI driver data is NULL, aborting remove");
+ return;
+ }
/* Cancel pending reset work. Skip only when remove() is called from
* within the reset work itself (PLDR device_reprobe path) to avoid
--
2.43.0
^ permalink raw reply related
* Re: [PATCH 4/4] Bluetooth: qca: combine NVM and calibration data for QCC2072
From: Yepuri Siddu @ 2026-06-01 9:58 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
Konrad Dybcio, Balakrishna Godavarthi, Rocky Liao, quic_mohamull,
quic_hbandi, rahul.samana, harshitha.reddy, dishank.garg,
linux-arm-msm, linux-bluetooth, linux-kernel
In-Reply-To: <ungiyrkfjmykhm65ttfchad7oxgx3d5mf6frj2xnq7mdudq6tw@hqwq5ms3553w>
On 6/1/2026 3:20 PM, Dmitry Baryshkov wrote:
> On Fri, May 29, 2026 at 11:34:31PM +0530, Yepuri Siddu wrote:
>> QCC2072 requires the NVM and calibration data to be delivered to the
>> controller bundled together in an outer TLV of type 4. After loading
>> the NVM file, load the calibration file (qca/ornbcscal<ver>.bin) and
>> combine both into a single buffer with the outer TLV header before
>> passing it to qca_tlv_check_data().
>>
>> The outer TLV header encodes the combined payload length in the high
>> 24 bits and type 4 in the low 8 bits of the type_len field.
>>
>> If the calibration file is unavailable, fall back to downloading the
>> NVM alone.
>>
>> Signed-off-by: Yepuri Siddu <yepuri.siddu@oss.qualcomm.com>
>> ---
>> drivers/bluetooth/btqca.c | 47 +++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 47 insertions(+)
>
> This is only patch 4/4. For the future submissions please make sure that
> you submit the whole set of patches as a single thread. Or, if it was
> really supposed to be a single patch, make sure that you generate your
> patches correctly. The general suggestion now is to use the b4 tool to
> maintain your patches as it significantly automates and simplifies the
> workflow.
>
>
Noted, will ensure all patches are submitted as a single thread in v2,
and will look into using the b4 tool to streamline the workflow.
--
Best regards,
Siddu
^ permalink raw reply
* Re: [PATCH 4/4] Bluetooth: qca: combine NVM and calibration data for QCC2072
From: Dmitry Baryshkov @ 2026-06-01 9:50 UTC (permalink / raw)
To: Yepuri Siddu
Cc: Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
Konrad Dybcio, Balakrishna Godavarthi, Rocky Liao, quic_mohamull,
quic_hbandi, rahul.samana, harshitha.reddy, dishank.garg,
linux-arm-msm, linux-bluetooth, linux-kernel
In-Reply-To: <20260529180431.3373856-1-yepuri.siddu@oss.qualcomm.com>
On Fri, May 29, 2026 at 11:34:31PM +0530, Yepuri Siddu wrote:
> QCC2072 requires the NVM and calibration data to be delivered to the
> controller bundled together in an outer TLV of type 4. After loading
> the NVM file, load the calibration file (qca/ornbcscal<ver>.bin) and
> combine both into a single buffer with the outer TLV header before
> passing it to qca_tlv_check_data().
>
> The outer TLV header encodes the combined payload length in the high
> 24 bits and type 4 in the low 8 bits of the type_len field.
>
> If the calibration file is unavailable, fall back to downloading the
> NVM alone.
>
> Signed-off-by: Yepuri Siddu <yepuri.siddu@oss.qualcomm.com>
> ---
> drivers/bluetooth/btqca.c | 47 +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 47 insertions(+)
This is only patch 4/4. For the future submissions please make sure that
you submit the whole set of patches as a single thread. Or, if it was
really supposed to be a single patch, make sure that you generate your
patches correctly. The general suggestion now is to use the b4 tool to
maintain your patches as it significantly automates and simplifies the
workflow.
--
With best wishes
Dmitry
^ permalink raw reply
* [PATCH 7/7] arm64: dts: qcom: sm8350-hdk: describe WiFi/BT chip
From: Dmitry Baryshkov @ 2026-06-01 9:46 UTC (permalink / raw)
To: Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas,
Konrad Dybcio, Qiang Yu, Jeff Johnson, Liam Girdwood, Mark Brown,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski,
Marcel Holtmann, Luiz Augusto von Dentz, Balakrishna Godavarthi,
Rocky Liao, Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-pci, linux-kernel, linux-wireless, ath11k,
devicetree, Bartosz Golaszewski, linux-bluetooth
In-Reply-To: <20260601-sm8350-wifi-v1-0-242917d88031@oss.qualcomm.com>
The SM8350 HDK has onboard WiFi/BT chip, WCN6851. It is an earlier
version of well-known WCN6855 WiFI/BT SoC. Describe the PMU, BT and WiFI
parts of the device.
The firmware isn't (yet) available as a part of linux-firmware, so it
was verified with the firmware files from the vendor-supplied package
(wcn prefix was applied to Bluetooth firmware files to make them follow
upstream driver changes, vendor provided hpbtfw10.tlv and hpnv10.b06).
Bluetooth: hci0: QCA Product ID :0x00000013
Bluetooth: hci0: QCA SOC Version :0x400c0110
Bluetooth: hci0: QCA ROM Version :0x00000100
Bluetooth: hci0: QCA Patch Version:0x00001017
Bluetooth: hci0: QCA controller version 0x01100100
Bluetooth: hci0: QCA Downloading qca/wcnhpbtfw10.tlv
Bluetooth: hci0: QCA Downloading qca/wcnhpnv10.b06
Bluetooth: hci0: QCA setup on UART is completed
Bluetooth: hci0: HFP non-HCI data transport is supported
ath11k_pci 0000:01:00.0: BAR 0 [mem 0x60400000-0x605fffff 64bit]: assigned
ath11k_pci 0000:01:00.0: MSI vectors: 32
ath11k_pci 0000:01:00.0: wcn6855 hw1.1
mhi mhi0: Requested to power ON
mhi mhi0: Power on setup success
mhi mhi0: Wait for device to enter SBL or Mission mode
ath11k_pci 0000:01:00.0: chip_id 0x0 chip_family 0xb board_id 0x6 soc_id 0x400c0110
ath11k_pci 0000:01:00.0: fw_version 0x110c80c8 fw_build_timestamp 2021-05-25 21:43 fw_build_id WLAN.HSP.1.1.c3-00200-QCAHSPSWPL_V1_V2_SILICONZ-1
ath11k_pci 0000:01:00.0 wlp1s0: renamed from wlan0
For the reference, the driver looks for the board data for
bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=0108,qmi-chip-id=0,qmi-board-id=6,variant=QC_8350_HDK
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/sm8350-hdk.dts | 126 ++++++++++++++++++++++++++++++++
1 file changed, 126 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
index 4973a3eb11b5..8e35216e4272 100644
--- a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
+++ b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
@@ -115,6 +115,70 @@ lt9611_3v3: lt9611-3v3-regulator {
regulator-boot-on;
regulator-always-on;
};
+
+ wcn6855-pmu {
+ compatible = "qcom,wcn6851-pmu", "qcom,wcn6855-pmu";
+
+ pinctrl-0 = <&bt_en>, <&wlan_en>, <&swctrl>;
+ pinctrl-names = "default";
+
+ wlan-enable-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>;
+ bt-enable-gpios = <&tlmm 65 GPIO_ACTIVE_HIGH>;
+ swctrl-gpios = <&tlmm 153 GPIO_ACTIVE_HIGH>;
+
+ vddio-supply = <&vreg_s10b_1p8>;
+ vddaon-supply = <&vreg_s11b_0p95>;
+ vddpmu-supply = <&vreg_s11b_0p95>;
+ vddpmumx-supply = <&vreg_s2e_0p85>;
+ vddpmucx-supply = <&vreg_s11b_0p95>;
+ vddrfa0p95-supply = <&vreg_s11b_0p95>;
+ vddrfa1p3-supply = <&vreg_s12b_1p25>;
+ vddrfa1p9-supply = <&vreg_s1c_1p86>;
+ vddpcie1p3-supply = <&vreg_s12b_1p25>;
+ vddpcie1p9-supply = <&vreg_s1c_1p86>;
+
+ regulators {
+ vreg_pmu_rfa_cmn_0p8: ldo0 {
+ regulator-name = "vreg_pmu_rfa_cmn_0p8";
+ };
+
+ vreg_pmu_aon_0p8: ldo1 {
+ regulator-name = "vreg_pmu_aon_0p8";
+ };
+
+ vreg_pmu_wlcx_0p8: ldo2 {
+ regulator-name = "vreg_pmu_wlcx_0p8";
+ };
+
+ vreg_pmu_wlmx_0p8: ldo3 {
+ regulator-name = "vreg_pmu_wlmx_0p8";
+ };
+
+ vreg_pmu_btcmx_0p8: ldo4 {
+ regulator-name = "vreg_pmu_btcmx_0p8";
+ };
+
+ vreg_pmu_pcie_1p8: ldo5 {
+ regulator-name = "vreg_pmu_pcie_1p8";
+ };
+
+ vreg_pmu_pcie_0p9: ldo6 {
+ regulator-name = "vreg_pmu_pcie_0p9";
+ };
+
+ vreg_pmu_rfa_0p8: ldo7 {
+ regulator-name = "vreg_pmu_rfa_0p8";
+ };
+
+ vreg_pmu_rfa_1p2: ldo8 {
+ regulator-name = "vreg_pmu_rfa_1p2";
+ };
+
+ vreg_pmu_rfa_1p7: ldo9 {
+ regulator-name = "vreg_pmu_rfa_1p7";
+ };
+ };
+ };
};
&adsp {
@@ -373,6 +437,13 @@ vreg_l7e_2p8: ldo7 {
regulator-name = "vreg_l7e_2p8";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
+
+ /*
+ * This is used by the RF front-end for which there is
+ * no way to represent it in DT (yet?).
+ */
+ regulator-boot-on;
+ regulator-always-on;
};
};
};
@@ -499,6 +570,23 @@ &pcie0 {
&pcie0_port0 {
reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
+
+ wifi@0 {
+ compatible = "pci17cb,1103";
+ reg = <0x10000 0x0 0x0 0x0 0x0>;
+
+ vddrfacmn-supply = <&vreg_pmu_rfa_cmn_0p8>;
+ vddaon-supply = <&vreg_pmu_aon_0p8>;
+ vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
+ vddwlmx-supply = <&vreg_pmu_wlmx_0p8>;
+ vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>;
+ vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>;
+ vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+ vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+ vddrfa1p8-supply = <&vreg_pmu_rfa_1p7>;
+
+ qcom,calibration-variant = "QC_8350_HDK";
+ };
};
&pcie0_phy {
@@ -763,6 +851,20 @@ &tlmm {
"HST_WLAN_UART_TX",
"HST_WLAN_UART_RX";
+ wlan_en: wlan-en-state {
+ pins = "gpio64";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
+ bt_en: bt-en-state {
+ pins = "gpio65";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
pcie0_default_state: pcie0-default-state {
perst-pins {
pins = "gpio94";
@@ -815,12 +917,36 @@ sdc2_card_det_n: sd-card-det-n-state {
drive-strength = <2>;
bias-pull-up;
};
+
+ swctrl: swctrl-state {
+ pins = "gpio153";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ };
};
&uart2 {
status = "okay";
};
+&uart18 {
+ status = "okay";
+
+ bluetooth {
+ compatible = "qcom,wcn6851-bt", "qcom,wcn6855-bt";
+
+ vddrfacmn-supply = <&vreg_pmu_rfa_cmn_0p8>;
+ vddaon-supply = <&vreg_pmu_aon_0p8>;
+ vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
+ vddwlmx-supply = <&vreg_pmu_wlmx_0p8>;
+ vddbtcmx-supply = <&vreg_pmu_btcmx_0p8>;
+ vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+ vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+ vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>;
+ };
+};
+
&ufs_mem_hc {
status = "okay";
--
2.47.3
^ permalink raw reply related
* [PATCH 6/7] arm64: dts: qcom: sm8350: modernize PCIe entries
From: Dmitry Baryshkov @ 2026-06-01 9:46 UTC (permalink / raw)
To: Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas,
Konrad Dybcio, Qiang Yu, Jeff Johnson, Liam Girdwood, Mark Brown,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski,
Marcel Holtmann, Luiz Augusto von Dentz, Balakrishna Godavarthi,
Rocky Liao, Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-pci, linux-kernel, linux-wireless, ath11k,
devicetree, Bartosz Golaszewski, linux-bluetooth
In-Reply-To: <20260601-sm8350-wifi-v1-0-242917d88031@oss.qualcomm.com>
The recent suggestion is to have PERST# / WAKE pins and PHYs in the PCIe
port rather than RC device. The kernel recently started warning about
the older style of DT. Modernize DT for SM8350 platform by moving the
entries under the root port device node.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/sm8350-hdk.dts | 18 +++++++++++-------
arch/arm64/boot/dts/qcom/sm8350.dtsi | 12 ++++--------
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
index 5f975d009465..4973a3eb11b5 100644
--- a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
+++ b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
@@ -493,12 +493,14 @@ &pcie0 {
pinctrl-names = "default";
pinctrl-0 = <&pcie0_default_state>;
- perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
- wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
-
status = "okay";
};
+&pcie0_port0 {
+ reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
+};
+
&pcie0_phy {
vdda-phy-supply = <&vreg_l5b_0p88>;
vdda-pll-supply = <&vreg_l6b_1p2>;
@@ -507,15 +509,17 @@ &pcie0_phy {
};
&pcie1 {
- perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>;
- wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>;
-
- pinctrl-names = "default";
pinctrl-0 = <&pcie1_default_state>;
+ pinctrl-names = "default";
status = "okay";
};
+&pcie1_port0 {
+ reset-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>;
+};
+
&pcie1_phy {
status = "okay";
vdda-phy-supply = <&vreg_l5b_0p88>;
diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
index eb2a795d8edb..136daa444865 100644
--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
@@ -1583,12 +1583,9 @@ pcie0: pcie@1c00000 {
power-domains = <&gcc PCIE_0_GDSC>;
- phys = <&pcie0_phy>;
- phy-names = "pciephy";
-
status = "disabled";
- pcie@0 {
+ pcie0_port0: pcie@0 {
device_type = "pci";
reg = <0x0 0x0 0x0 0x0 0x0>;
bus-range = <0x01 0xff>;
@@ -1596,6 +1593,7 @@ pcie@0 {
#address-cells = <3>;
#size-cells = <2>;
ranges;
+ phys = <&pcie0_phy>;
};
};
@@ -1692,12 +1690,9 @@ pcie1: pcie@1c08000 {
power-domains = <&gcc PCIE_1_GDSC>;
- phys = <&pcie1_phy>;
- phy-names = "pciephy";
-
status = "disabled";
- pcie@0 {
+ pcie1_port0: pcie@0 {
device_type = "pci";
reg = <0x0 0x0 0x0 0x0 0x0>;
bus-range = <0x01 0xff>;
@@ -1705,6 +1700,7 @@ pcie@0 {
#address-cells = <3>;
#size-cells = <2>;
ranges;
+ phys = <&pcie1_phy>;
};
};
--
2.47.3
^ permalink raw reply related
* [PATCH 5/7] arm64: dts: qcom: sm8350: expand UART18 to 4 pins config
From: Dmitry Baryshkov @ 2026-06-01 9:46 UTC (permalink / raw)
To: Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas,
Konrad Dybcio, Qiang Yu, Jeff Johnson, Liam Girdwood, Mark Brown,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski,
Marcel Holtmann, Luiz Augusto von Dentz, Balakrishna Godavarthi,
Rocky Liao, Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-pci, linux-kernel, linux-wireless, ath11k,
devicetree, Bartosz Golaszewski, linux-bluetooth
In-Reply-To: <20260601-sm8350-wifi-v1-0-242917d88031@oss.qualcomm.com>
On SM8350 platforms the primary use of UART18 is a 4-pin UART (targeting
Bluetooth or other similar applications). Add all 4 pins to the default
pinctrl entry for the UART.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
index c830953156ec..eb2a795d8edb 100644
--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
@@ -3309,7 +3309,7 @@ qup_uart6_default: qup-uart6-default-state {
};
qup_uart18_default: qup-uart18-default-state {
- pins = "gpio68", "gpio69";
+ pins = "gpio68", "gpio69", "gpio70", "gpio71";
function = "qup18";
drive-strength = <2>;
bias-disable;
--
2.47.3
^ permalink raw reply related
* [PATCH 4/7] dt-bindings: bluetooth: qcom,wcn6855-bt: document WCN6851
From: Dmitry Baryshkov @ 2026-06-01 9:46 UTC (permalink / raw)
To: Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas,
Konrad Dybcio, Qiang Yu, Jeff Johnson, Liam Girdwood, Mark Brown,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski,
Marcel Holtmann, Luiz Augusto von Dentz, Balakrishna Godavarthi,
Rocky Liao, Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-pci, linux-kernel, linux-wireless, ath11k,
devicetree, Bartosz Golaszewski, linux-bluetooth
In-Reply-To: <20260601-sm8350-wifi-v1-0-242917d88031@oss.qualcomm.com>
WCN6851 is an earlier version of WCN6855 WiFi/BT chip, compatible with
it. Add a device-specific compat string with the fallback to WCN6855
one.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
.../devicetree/bindings/net/bluetooth/qcom,wcn6855-bt.yaml | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/bluetooth/qcom,wcn6855-bt.yaml b/Documentation/devicetree/bindings/net/bluetooth/qcom,wcn6855-bt.yaml
index 0beda26ae8bb..ec766f40a042 100644
--- a/Documentation/devicetree/bindings/net/bluetooth/qcom,wcn6855-bt.yaml
+++ b/Documentation/devicetree/bindings/net/bluetooth/qcom,wcn6855-bt.yaml
@@ -13,8 +13,12 @@ maintainers:
properties:
compatible:
- enum:
- - qcom,wcn6855-bt
+ oneOf:
+ - items:
+ - const: qcom,wcn6851-bt
+ - const: qcom,wcn6855-bt
+ - enum:
+ - qcom,wcn6855-bt
enable-gpios:
maxItems: 1
--
2.47.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox