Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Bluetooth: Broadcom controllers of the Apple T2 Macs
@ 2026-11-04 15:15 Andre Eikmeyer
  2026-11-04 15:15 ` [PATCH 1/4] Bluetooth: btbcm: raise ACL priority on Apple Broadcom controllers Andre Eikmeyer
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Andre Eikmeyer @ 2026-11-04 15:15 UTC (permalink / raw)
  To: marcel, luiz.dentz
  Cc: linux-bluetooth, linux-kernel, sven, j, neal, asahi,
	linux-arm-kernel, 66ton99, josemiguelo.ochoa, aditya.garg,
	Andre Eikmeyer

Hello everyone,

This series is for the Broadcom Bluetooth controllers of the Apple T2
Macs, the BCM4364 over UART (hci_bcm) and the BCM4377 over PCIe
(hci_bcm4377).

  1    raise ACL priority on Apple Broadcom controllers
  2    clear vendor bits in LE advertising report types
  3    Revert "Bluetooth: hci_event: strip Broadcom vendor bits from
       legacy adv report type"
  4    set the strict duplicate filter quirk on Apple Broadcom controllers

Patch 2 and 3 belong together. Commit 88397423671f ("Bluetooth:
hci_event: strip Broadcom vendor bits from legacy adv report type") in
bluetooth-next masks the event type of legacy LE Advertising Reports for
every controller with manufacturer 15. The controllers known to set these
bits are the ones of the T2 Macs. Aditya Garg asked about this on the
list:

  https://lore.kernel.org/linux-bluetooth/F4853998-F2A8-4AFE-99EA-544657EAB0E8@linux.dev/

Masking the type to its low nibble goes back to a t2linux patch by Jose
Miguel Ochoa. Patch 2 clears the bits in the two drivers of these
controllers before the event reaches the core, and patch 3 reverts the
check in hci_event.c. Patch 2 comes first, so every commit in between
keeps the reports.

Patch 1 builds on a vendor command the Android Broadcom vendor library
uses, 0xfc57, to keep A2DP from dropping out while WLAN runs on 2.4 GHz.
Patch 4 sets the strict duplicate filter quirk in both drivers, so a
discovery reports changed advertisement data before its next cycle.

The KaiT2en community, about 280 members, runs these patches with its
kernels. Users reported them working on the MacBookPro15,1, 15,2, 15,3,
15,4, 16,1, 16,4, MacBookAir9,1 and iMac20,1, and nobody reported a
regression.

Andre Eikmeyer (4):
  Bluetooth: btbcm: raise ACL priority on Apple Broadcom controllers
  Bluetooth: btbcm: clear vendor bits in LE advertising report types
  Revert "Bluetooth: hci_event: strip Broadcom vendor bits from legacy
    adv report type"
  Bluetooth: set the strict duplicate filter quirk on Apple Broadcom
    controllers

 drivers/bluetooth/Kconfig       |   1 +
 drivers/bluetooth/btbcm.c       | 102 ++++++++++++++++++++++++++++++++
 drivers/bluetooth/btbcm.h       |  12 ++++
 drivers/bluetooth/hci_bcm.c     |  28 ++++++++-
 drivers/bluetooth/hci_bcm4377.c |   9 +++
 net/bluetooth/hci_event.c       |  11 ----
 6 files changed, 149 insertions(+), 14 deletions(-)


base-commit: 3f425f95ba3923d605f6a8b382e8fcdc59d479db


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/4] Bluetooth: btbcm: raise ACL priority on Apple Broadcom controllers
  2026-11-04 15:15 [PATCH 0/4] Bluetooth: Broadcom controllers of the Apple T2 Macs Andre Eikmeyer
@ 2026-11-04 15:15 ` Andre Eikmeyer
  2026-11-04 15:15 ` [PATCH 2/4] Bluetooth: btbcm: clear vendor bits in LE advertising report types Andre Eikmeyer
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Andre Eikmeyer @ 2026-11-04 15:15 UTC (permalink / raw)
  To: marcel, luiz.dentz
  Cc: linux-bluetooth, linux-kernel, sven, j, neal, asahi,
	linux-arm-kernel, 66ton99, josemiguelo.ochoa, aditya.garg,
	Andre Eikmeyer, Yossef Osman

On the MacBookPro15,1 (BCM4364B0 over UART) A2DP audio drops out as
soon as WLAN runs on 2.4 GHz with traffic. The host keeps the eight ACL
buffers of the controller filled, but the controller holds single ACL
packets for 160-200 ms, so the sink runs dry.

Sending the Broadcom vendor command 0xfc57 (HCI_BRCM_SET_ACL_PRIORITY,
handle and priority, as used by the Android Broadcom vendor library) with
priority high for the audio link stops the dropouts. Setting it back to
normal brings them back right away. The BCM4377 of the MacBookAir9,1
accepts the command as well.

Raise the priority for every BR/EDR ACL link once its Connection Complete
event arrives. This covers audio as well as HID links. hci_bcm does this
on Apple machines only, hci_bcm4377 always, since it only runs on Apple
machines. The PCIe driver receives events in hard interrupt context, so
the command is queued from a work item.

Tested-by: Yossef Osman <Yossef.Osman@proton.me>
Tested-by: Aditya Garg <aditya.garg@linux.dev>
Signed-off-by: Andre Eikmeyer <dev@deq.rocks>
---
 drivers/bluetooth/Kconfig       |  1 +
 drivers/bluetooth/btbcm.c       | 72 +++++++++++++++++++++++++++++++++
 drivers/bluetooth/btbcm.h       |  7 ++++
 drivers/bluetooth/hci_bcm.c     | 18 ++++++++-
 drivers/bluetooth/hci_bcm4377.c |  3 ++
 5 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index b18482b5677..3e2426abdff 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -318,6 +318,7 @@ config BT_HCIBCM4377
 	tristate "HCI BCM4377/4378/4387/4388 PCIe driver"
 	depends on PCI
 	select FW_LOADER
+	select BT_BCM
 	help
 	  Support for Broadcom BCM4377/4378/4387/4388 Bluetooth chipsets
 	  attached via PCIe. These are usually found in Apple machines.
diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
index 065536d4ec7..0facfe62333 100644
--- a/drivers/bluetooth/btbcm.c
+++ b/drivers/bluetooth/btbcm.c
@@ -210,6 +210,78 @@ int btbcm_write_pcm_int_params(struct hci_dev *hdev,
 }
 EXPORT_SYMBOL_GPL(btbcm_write_pcm_int_params);
 
+#define BCM_SET_ACL_PRIORITY	0xfc57
+#define BCM_ACL_PRIORITY_HIGH	0x01
+
+struct bcm_set_acl_priority {
+	__le16	handle;
+	u8	priority;
+} __packed;
+
+struct btbcm_acl_priority_work {
+	struct work_struct	work;
+	struct hci_dev		*hdev;
+	u16			handle;
+};
+
+static int btbcm_set_acl_priority_sync(struct hci_dev *hdev, void *data)
+{
+	struct bcm_set_acl_priority cp;
+	int err;
+
+	cp.handle = cpu_to_le16(PTR_UINT(data));
+	cp.priority = BCM_ACL_PRIORITY_HIGH;
+
+	err = __hci_cmd_sync_status(hdev, BCM_SET_ACL_PRIORITY, sizeof(cp),
+				    &cp, HCI_CMD_TIMEOUT);
+	if (err)
+		bt_dev_warn(hdev, "BCM: setting ACL priority for handle 0x%4.4x failed (%d)",
+			    le16_to_cpu(cp.handle), err);
+	return err;
+}
+
+static void btbcm_acl_priority_work(struct work_struct *work)
+{
+	struct btbcm_acl_priority_work *w =
+		container_of(work, struct btbcm_acl_priority_work, work);
+
+	hci_cmd_sync_queue(w->hdev, btbcm_set_acl_priority_sync,
+			   UINT_PTR(w->handle), NULL);
+	hci_dev_put(w->hdev);
+	kfree(w);
+}
+
+/* Give every BR/EDR ACL link high priority in the controller as soon as it
+ * is connected. Without it the BCM4364 coexistence arbitration lets 2.4 GHz
+ * WLAN traffic delay ACL packets by up to 200 ms, which drops A2DP audio.
+ * Called with each received event, also from atomic context.
+ */
+void btbcm_set_acl_priority_on_connect(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_event_hdr *hdr = (void *)skb->data;
+	struct hci_ev_conn_complete *ev;
+	struct btbcm_acl_priority_work *w;
+
+	if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT ||
+	    skb->len < sizeof(*hdr) + sizeof(*ev) ||
+	    hdr->evt != HCI_EV_CONN_COMPLETE)
+		return;
+
+	ev = (void *)(skb->data + sizeof(*hdr));
+	if (ev->status || ev->link_type != ACL_LINK)
+		return;
+
+	w = kzalloc_obj(*w, GFP_ATOMIC);
+	if (!w)
+		return;
+
+	INIT_WORK(&w->work, btbcm_acl_priority_work);
+	w->hdev = hci_dev_hold(hdev);
+	w->handle = __le16_to_cpu(ev->handle);
+	queue_work(system_dfl_wq, &w->work);
+}
+EXPORT_SYMBOL_GPL(btbcm_set_acl_priority_on_connect);
+
 int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
 {
 	const struct hci_command_hdr *cmd;
diff --git a/drivers/bluetooth/btbcm.h b/drivers/bluetooth/btbcm.h
index b4cb24231a2..a4d47b242e9 100644
--- a/drivers/bluetooth/btbcm.h
+++ b/drivers/bluetooth/btbcm.h
@@ -59,6 +59,8 @@ int btbcm_read_pcm_int_params(struct hci_dev *hdev,
 int btbcm_write_pcm_int_params(struct hci_dev *hdev,
 			       const struct bcm_set_pcm_int_params *params);
 
+void btbcm_set_acl_priority_on_connect(struct hci_dev *hdev, struct sk_buff *skb);
+
 int btbcm_setup_patchram(struct hci_dev *hdev);
 int btbcm_setup_apple(struct hci_dev *hdev);
 
@@ -94,6 +96,11 @@ static inline int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw
 	return -EOPNOTSUPP;
 }
 
+static inline void btbcm_set_acl_priority_on_connect(struct hci_dev *hdev,
+						     struct sk_buff *skb)
+{
+}
+
 static inline int btbcm_setup_patchram(struct hci_dev *hdev)
 {
 	return 0;
diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index e70b9f3fd96..cf4f1455cf9 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -147,6 +147,7 @@ struct bcm_device {
 	bool			drive_rts_on_open;
 	bool			no_uart_clock_set;
 	bool			use_autobaud_mode;
+	bool			acl_priority;
 	u8			pcm_int_params[5];
 	u32			max_autobaud_speed;
 };
@@ -680,10 +681,21 @@ static int bcm_setup(struct hci_uart *hu)
 	.lsize = 0, \
 	.maxlen = BCM_TYPE52_SIZE
 
+static int bcm_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_uart *hu = hci_get_drvdata(hdev);
+	struct bcm_data *bcm = hu->priv;
+
+	if (bcm->dev && bcm->dev->acl_priority)
+		btbcm_set_acl_priority_on_connect(hdev, skb);
+
+	return hci_recv_frame(hdev, skb);
+}
+
 static const struct h4_recv_pkt bcm_recv_pkts[] = {
 	{ H4_RECV_ACL,      .recv = hci_recv_frame },
 	{ H4_RECV_SCO,      .recv = hci_recv_frame },
-	{ H4_RECV_EVENT,    .recv = hci_recv_frame },
+	{ H4_RECV_EVENT,    .recv = bcm_recv_event },
 	{ H4_RECV_ISO,      .recv = hci_recv_frame },
 	{ BCM_RECV_LM_DIAG, .recv = hci_recv_diag  },
 	{ BCM_RECV_NULL,    .recv = hci_recv_diag  },
@@ -1086,8 +1098,10 @@ static int bcm_get_resources(struct bcm_device *dev)
 
 	dev->name = dev_name(dev->dev);
 
-	if (x86_apple_machine && !bcm_apple_get_resources(dev))
+	if (x86_apple_machine && !bcm_apple_get_resources(dev)) {
+		dev->acl_priority = true;
 		return 0;
+	}
 
 	dev->txco_clk = bcm_get_txco(dev->dev);
 	if (IS_ERR(dev->txco_clk))
diff --git a/drivers/bluetooth/hci_bcm4377.c b/drivers/bluetooth/hci_bcm4377.c
index 66d49b47154..30fcadfae3f 100644
--- a/drivers/bluetooth/hci_bcm4377.c
+++ b/drivers/bluetooth/hci_bcm4377.c
@@ -22,6 +22,8 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
+#include "btbcm.h"
+
 enum bcm4377_chip {
 	BCM4377 = 0,
 	BCM4378,
@@ -689,6 +691,7 @@ static void bcm4377_handle_event(struct bcm4377_data *bcm4377,
 
 	memcpy(skb_put(skb, len), payload, len);
 	hci_skb_pkt_type(skb) = type;
+	btbcm_set_acl_priority_on_connect(bcm4377->hdev, skb);
 	hci_recv_frame(bcm4377->hdev, skb);
 
 out:


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/4] Bluetooth: btbcm: clear vendor bits in LE advertising report types
  2026-11-04 15:15 [PATCH 0/4] Bluetooth: Broadcom controllers of the Apple T2 Macs Andre Eikmeyer
  2026-11-04 15:15 ` [PATCH 1/4] Bluetooth: btbcm: raise ACL priority on Apple Broadcom controllers Andre Eikmeyer
@ 2026-11-04 15:15 ` Andre Eikmeyer
  2026-11-04 15:24   ` Luiz Augusto von Dentz
  2026-11-04 15:16 ` [PATCH 3/4] Revert "Bluetooth: hci_event: strip Broadcom vendor bits from legacy adv report type" Andre Eikmeyer
  2026-11-04 15:16 ` [PATCH 4/4] Bluetooth: set the strict duplicate filter quirk on Apple Broadcom controllers Andre Eikmeyer
  3 siblings, 1 reply; 10+ messages in thread
From: Andre Eikmeyer @ 2026-11-04 15:15 UTC (permalink / raw)
  To: marcel, luiz.dentz
  Cc: linux-bluetooth, linux-kernel, sven, j, neal, asahi,
	linux-arm-kernel, 66ton99, josemiguelo.ochoa, aditya.garg,
	Andre Eikmeyer, Yossef Osman

The BCM4364B0 of the MacBookPro15,1 (UART) and the BCM4377 of the
MacBookAir9,1 (PCIe) set bits 4, 5 and 7 of the event type in LE
Advertising Report events. btmon on the 15,1 shows types 0x10, 0x13,
0x14, 0x20, 0x23, 0x24, 0x93 and 0xa0 next to plain 0x00, 0x03 and 0x04,
the same advertiser shows up as 0x13, 0x23 and 0x03. The kernel log of
the 9,1 lists 0x10 to 0x24 and 0x80, 0x83, 0x90, 0x93, 0xa0, 0xa3.
process_adv_report() drops every type above 0x04 with "Unknown
advertising packet type", so most advertisements never reach the host.
An AirDrop sender was reported as 0x23, 0x23 and 0x13 and only the
fourth report, 0x03, reached BlueZ 32 s after the first one.

Add btbcm_fixup_le_adv_report(), which clears the bits above the type,
and call it from hci_bcm on Apple machines and from hci_bcm4377 before
the event goes to the core.

Suggested-by: Jose Miguel Ochoa <josemiguelo.ochoa@gmail.com>
Tested-by: Yossef Osman <Yossef.Osman@proton.me>
Tested-by: Aditya Garg <aditya.garg@linux.dev>
Signed-off-by: Andre Eikmeyer <dev@deq.rocks>
---
 drivers/bluetooth/btbcm.c       | 30 ++++++++++++++++++++++++++++++
 drivers/bluetooth/btbcm.h       |  5 +++++
 drivers/bluetooth/hci_bcm.c     |  5 +++++
 drivers/bluetooth/hci_bcm4377.c |  1 +
 4 files changed, 41 insertions(+)

diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
index 0facfe62333..527a5c75fd6 100644
--- a/drivers/bluetooth/btbcm.c
+++ b/drivers/bluetooth/btbcm.c
@@ -282,6 +282,36 @@ void btbcm_set_acl_priority_on_connect(struct hci_dev *hdev, struct sk_buff *skb
 }
 EXPORT_SYMBOL_GPL(btbcm_set_acl_priority_on_connect);
 
+/* The BCM4364 and BCM4377 of the T2 Macs set bits above the event type of LE
+ * Advertising Reports, 0x13 and 0x23 for ADV_NONCONN_IND for example. The
+ * core drops reports of unknown types, so clear them.
+ */
+void btbcm_fixup_le_adv_report(struct sk_buff *skb)
+{
+	struct hci_event_hdr *hdr = (void *)skb->data;
+	struct hci_ev_le_advertising_info *info;
+	u8 *p, *end;
+	u8 num;
+
+	if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT ||
+	    skb->len < HCI_EVENT_HDR_SIZE + 2 || hdr->evt != HCI_EV_LE_META)
+		return;
+
+	p = skb->data + HCI_EVENT_HDR_SIZE;
+	if (p[0] != HCI_EV_LE_ADVERTISING_REPORT)
+		return;
+
+	num = p[1];
+	p += 2;
+	end = skb->data + skb->len;
+	while (num-- && p + sizeof(*info) + 1 <= end) {
+		info = (void *)p;
+		info->type &= 0x0f;
+		p += sizeof(*info) + info->length + 1;
+	}
+}
+EXPORT_SYMBOL_GPL(btbcm_fixup_le_adv_report);
+
 int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
 {
 	const struct hci_command_hdr *cmd;
diff --git a/drivers/bluetooth/btbcm.h b/drivers/bluetooth/btbcm.h
index a4d47b242e9..56936e64b5f 100644
--- a/drivers/bluetooth/btbcm.h
+++ b/drivers/bluetooth/btbcm.h
@@ -60,6 +60,7 @@ int btbcm_write_pcm_int_params(struct hci_dev *hdev,
 			       const struct bcm_set_pcm_int_params *params);
 
 void btbcm_set_acl_priority_on_connect(struct hci_dev *hdev, struct sk_buff *skb);
+void btbcm_fixup_le_adv_report(struct sk_buff *skb);
 
 int btbcm_setup_patchram(struct hci_dev *hdev);
 int btbcm_setup_apple(struct hci_dev *hdev);
@@ -101,6 +102,10 @@ static inline void btbcm_set_acl_priority_on_connect(struct hci_dev *hdev,
 {
 }
 
+static inline void btbcm_fixup_le_adv_report(struct sk_buff *skb)
+{
+}
+
 static inline int btbcm_setup_patchram(struct hci_dev *hdev)
 {
 	return 0;
diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index cf4f1455cf9..1ae9619ee1e 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -148,6 +148,7 @@ struct bcm_device {
 	bool			no_uart_clock_set;
 	bool			use_autobaud_mode;
 	bool			acl_priority;
+	bool			adv_type_fixup;
 	u8			pcm_int_params[5];
 	u32			max_autobaud_speed;
 };
@@ -686,6 +687,9 @@ static int bcm_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
 	struct hci_uart *hu = hci_get_drvdata(hdev);
 	struct bcm_data *bcm = hu->priv;
 
+	if (bcm->dev && bcm->dev->adv_type_fixup)
+		btbcm_fixup_le_adv_report(skb);
+
 	if (bcm->dev && bcm->dev->acl_priority)
 		btbcm_set_acl_priority_on_connect(hdev, skb);
 
@@ -1100,6 +1104,7 @@ static int bcm_get_resources(struct bcm_device *dev)
 
 	if (x86_apple_machine && !bcm_apple_get_resources(dev)) {
 		dev->acl_priority = true;
+		dev->adv_type_fixup = true;
 		return 0;
 	}
 
diff --git a/drivers/bluetooth/hci_bcm4377.c b/drivers/bluetooth/hci_bcm4377.c
index 30fcadfae3f..8d99a7a8f76 100644
--- a/drivers/bluetooth/hci_bcm4377.c
+++ b/drivers/bluetooth/hci_bcm4377.c
@@ -691,6 +691,7 @@ static void bcm4377_handle_event(struct bcm4377_data *bcm4377,
 
 	memcpy(skb_put(skb, len), payload, len);
 	hci_skb_pkt_type(skb) = type;
+	btbcm_fixup_le_adv_report(skb);
 	btbcm_set_acl_priority_on_connect(bcm4377->hdev, skb);
 	hci_recv_frame(bcm4377->hdev, skb);
 


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/4] Revert "Bluetooth: hci_event: strip Broadcom vendor bits from legacy adv report type"
  2026-11-04 15:15 [PATCH 0/4] Bluetooth: Broadcom controllers of the Apple T2 Macs Andre Eikmeyer
  2026-11-04 15:15 ` [PATCH 1/4] Bluetooth: btbcm: raise ACL priority on Apple Broadcom controllers Andre Eikmeyer
  2026-11-04 15:15 ` [PATCH 2/4] Bluetooth: btbcm: clear vendor bits in LE advertising report types Andre Eikmeyer
@ 2026-11-04 15:16 ` Andre Eikmeyer
  2026-11-04 15:16 ` [PATCH 4/4] Bluetooth: set the strict duplicate filter quirk on Apple Broadcom controllers Andre Eikmeyer
  3 siblings, 0 replies; 10+ messages in thread
From: Andre Eikmeyer @ 2026-11-04 15:16 UTC (permalink / raw)
  To: marcel, luiz.dentz
  Cc: linux-bluetooth, linux-kernel, sven, j, neal, asahi,
	linux-arm-kernel, 66ton99, josemiguelo.ochoa, aditya.garg,
	Andre Eikmeyer, Yossef Osman

This reverts commit 88397423671f2b54119a6162a1834d207dcf1a81.

The commit clears the upper bits of the legacy LE Advertising Report
event type for every controller with manufacturer 15, Broadcom. The
reports of these bits, in its own commit message and here, all come
from the Broadcom controllers of the Apple T2 Macs.

The previous patch clears the bits in hci_bcm on Apple machines and in
hci_bcm4377, the drivers of these controllers, before the event reaches
the core. That makes the check in hci_le_adv_report_evt() redundant
for them.

Tested-by: Yossef Osman <Yossef.Osman@proton.me>
Tested-by: Aditya Garg <aditya.garg@linux.dev>
Signed-off-by: Andre Eikmeyer <dev@deq.rocks>
---
 net/bluetooth/hci_event.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 736dd2f741e..0675c224f6c 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -6683,17 +6683,6 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data,
 
 		hci_store_wake_reason(hdev, &info->bdaddr, info->bdaddr_type);
 
-		/* Broadcom ROM firmware (BCM4364B3 on Apple T2 Macs, no
-		 * patchram) sets vendor bits in the legacy Event_Type.
-		 */
-		if (hdev->manufacturer == 15 && info->type > LE_ADV_SCAN_RSP) {
-			/* 0x0f masks out upper vendor bits (0x10, 0x20, 0x80),
-			 * extracting the standard legacy advertising type
-			 * (0x00-0x04) stored in the low nibble (bits 0-3).
-			 */
-			info->type &= 0x0f;
-		}
-
 		if (info->length <= max_adv_len(hdev)) {
 			rssi = info->data[info->length];
 			process_adv_report(hdev, info->type, &info->bdaddr,


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/4] Bluetooth: set the strict duplicate filter quirk on Apple Broadcom controllers
  2026-11-04 15:15 [PATCH 0/4] Bluetooth: Broadcom controllers of the Apple T2 Macs Andre Eikmeyer
                   ` (2 preceding siblings ...)
  2026-11-04 15:16 ` [PATCH 3/4] Revert "Bluetooth: hci_event: strip Broadcom vendor bits from legacy adv report type" Andre Eikmeyer
@ 2026-11-04 15:16 ` Andre Eikmeyer
  3 siblings, 0 replies; 10+ messages in thread
From: Andre Eikmeyer @ 2026-11-04 15:16 UTC (permalink / raw)
  To: marcel, luiz.dentz
  Cc: linux-bluetooth, linux-kernel, sven, j, neal, asahi,
	linux-arm-kernel, 66ton99, josemiguelo.ochoa, aditya.garg,
	Andre Eikmeyer, Yossef Osman

btbcm_finalize() sets HCI_QUIRK_STRICT_DUPLICATE_FILTER, but bcm_setup()
returns before it when no patch file was loaded. The MacBookPro15,1 has
none for its BCM4364B0 ("BCM: firmware Patch file not found").
hci_bcm4377 does not use btbcm_finalize() and never sets the quirk. A
service discovery then scans with "Filter duplicates: Enabled", and the
controller reports an address once per discovery cycle of about 10.7 s.
A Mac that changed its advertisement data on the same address was
reported 6 s after the change, at the next cycle.

Set the quirk in hci_bcm on that path and in hci_bcm4377.

Tested-by: Yossef Osman <Yossef.Osman@proton.me>
Tested-by: Aditya Garg <aditya.garg@linux.dev>
Signed-off-by: Andre Eikmeyer <dev@deq.rocks>
---
 drivers/bluetooth/hci_bcm.c     | 5 ++++-
 drivers/bluetooth/hci_bcm4377.c | 5 +++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index 1ae9619ee1e..ee077c8502d 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -597,8 +597,11 @@ static int bcm_setup(struct hci_uart *hu)
 	if (err)
 		return err;
 
-	if (!fw_load_done)
+	if (!fw_load_done) {
+		/* btbcm_finalize() sets this after loading a patch file */
+		hci_set_quirk(hu->hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER);
 		return 0;
+	}
 
 	/* Init speed if any */
 	if (bcm->dev && bcm->dev->init_speed)
diff --git a/drivers/bluetooth/hci_bcm4377.c b/drivers/bluetooth/hci_bcm4377.c
index 8d99a7a8f76..7105372898d 100644
--- a/drivers/bluetooth/hci_bcm4377.c
+++ b/drivers/bluetooth/hci_bcm4377.c
@@ -2392,6 +2392,11 @@ static int bcm4377_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	hdev->set_bdaddr = bcm4377_hci_set_bdaddr;
 	hdev->setup = bcm4377_hci_setup;
 
+	/* The controller reports an address once per scan with duplicate
+	 * filtering, also after its advertisement data changed.
+	 */
+	hci_set_quirk(hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER);
+
 	if (bcm4377->hw->broken_mws_transport_config)
 		hci_set_quirk(hdev, HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG);
 	if (bcm4377->hw->broken_ext_scan)


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/4] Bluetooth: btbcm: clear vendor bits in LE advertising report types
  2026-11-04 15:15 ` [PATCH 2/4] Bluetooth: btbcm: clear vendor bits in LE advertising report types Andre Eikmeyer
@ 2026-11-04 15:24   ` Luiz Augusto von Dentz
  2026-11-04 15:34     ` Aditya Garg
  2026-11-04 15:46     ` André Eikmeyer
  0 siblings, 2 replies; 10+ messages in thread
From: Luiz Augusto von Dentz @ 2026-11-04 15:24 UTC (permalink / raw)
  To: Andre Eikmeyer
  Cc: marcel, linux-bluetooth, linux-kernel, sven, j, neal, asahi,
	linux-arm-kernel, 66ton99, josemiguelo.ochoa, aditya.garg,
	Yossef Osman

Hi Andre,

On Wed, Nov 4, 2026 at 10:16 AM Andre Eikmeyer <dev@deq.rocks> wrote:
>
> The BCM4364B0 of the MacBookPro15,1 (UART) and the BCM4377 of the
> MacBookAir9,1 (PCIe) set bits 4, 5 and 7 of the event type in LE
> Advertising Report events. btmon on the 15,1 shows types 0x10, 0x13,
> 0x14, 0x20, 0x23, 0x24, 0x93 and 0xa0 next to plain 0x00, 0x03 and 0x04,
> the same advertiser shows up as 0x13, 0x23 and 0x03. The kernel log of
> the 9,1 lists 0x10 to 0x24 and 0x80, 0x83, 0x90, 0x93, 0xa0, 0xa3.
> process_adv_report() drops every type above 0x04 with "Unknown
> advertising packet type", so most advertisements never reach the host.
> An AirDrop sender was reported as 0x23, 0x23 and 0x13 and only the
> fourth report, 0x03, reached BlueZ 32 s after the first one.
>
> Add btbcm_fixup_le_adv_report(), which clears the bits above the type,
> and call it from hci_bcm on Apple machines and from hci_bcm4377 before
> the event goes to the core.
>
> Suggested-by: Jose Miguel Ochoa <josemiguelo.ochoa@gmail.com>
> Tested-by: Yossef Osman <Yossef.Osman@proton.me>
> Tested-by: Aditya Garg <aditya.garg@linux.dev>
> Signed-off-by: Andre Eikmeyer <dev@deq.rocks>
> ---
>  drivers/bluetooth/btbcm.c       | 30 ++++++++++++++++++++++++++++++
>  drivers/bluetooth/btbcm.h       |  5 +++++
>  drivers/bluetooth/hci_bcm.c     |  5 +++++
>  drivers/bluetooth/hci_bcm4377.c |  1 +
>  4 files changed, 41 insertions(+)
>
> diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
> index 0facfe62333..527a5c75fd6 100644
> --- a/drivers/bluetooth/btbcm.c
> +++ b/drivers/bluetooth/btbcm.c
> @@ -282,6 +282,36 @@ void btbcm_set_acl_priority_on_connect(struct hci_dev *hdev, struct sk_buff *skb
>  }
>  EXPORT_SYMBOL_GPL(btbcm_set_acl_priority_on_connect);
>
> +/* The BCM4364 and BCM4377 of the T2 Macs set bits above the event type of LE
> + * Advertising Reports, 0x13 and 0x23 for ADV_NONCONN_IND for example. The
> + * core drops reports of unknown types, so clear them.
> + */
> +void btbcm_fixup_le_adv_report(struct sk_buff *skb)
> +{
> +       struct hci_event_hdr *hdr = (void *)skb->data;
> +       struct hci_ev_le_advertising_info *info;
> +       u8 *p, *end;
> +       u8 num;
> +
> +       if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT ||
> +           skb->len < HCI_EVENT_HDR_SIZE + 2 || hdr->evt != HCI_EV_LE_META)
> +               return;
> +
> +       p = skb->data + HCI_EVENT_HDR_SIZE;
> +       if (p[0] != HCI_EV_LE_ADVERTISING_REPORT)
> +               return;
> +
> +       num = p[1];
> +       p += 2;
> +       end = skb->data + skb->len;
> +       while (num-- && p + sizeof(*info) + 1 <= end) {
> +               info = (void *)p;
> +               info->type &= 0x0f;
> +               p += sizeof(*info) + info->length + 1;
> +       }
> +}
> +EXPORT_SYMBOL_GPL(btbcm_fixup_le_adv_report);

I don't think I agree with this being cleaner then doing at
hci_event.though; not only is it more code but it also walks the
packet which is inefficient and may have security implications as
well.

>  int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
>  {
>         const struct hci_command_hdr *cmd;
> diff --git a/drivers/bluetooth/btbcm.h b/drivers/bluetooth/btbcm.h
> index a4d47b242e9..56936e64b5f 100644
> --- a/drivers/bluetooth/btbcm.h
> +++ b/drivers/bluetooth/btbcm.h
> @@ -60,6 +60,7 @@ int btbcm_write_pcm_int_params(struct hci_dev *hdev,
>                                const struct bcm_set_pcm_int_params *params);
>
>  void btbcm_set_acl_priority_on_connect(struct hci_dev *hdev, struct sk_buff *skb);
> +void btbcm_fixup_le_adv_report(struct sk_buff *skb);
>
>  int btbcm_setup_patchram(struct hci_dev *hdev);
>  int btbcm_setup_apple(struct hci_dev *hdev);
> @@ -101,6 +102,10 @@ static inline void btbcm_set_acl_priority_on_connect(struct hci_dev *hdev,
>  {
>  }
>
> +static inline void btbcm_fixup_le_adv_report(struct sk_buff *skb)
> +{
> +}
> +
>  static inline int btbcm_setup_patchram(struct hci_dev *hdev)
>  {
>         return 0;
> diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
> index cf4f1455cf9..1ae9619ee1e 100644
> --- a/drivers/bluetooth/hci_bcm.c
> +++ b/drivers/bluetooth/hci_bcm.c
> @@ -148,6 +148,7 @@ struct bcm_device {
>         bool                    no_uart_clock_set;
>         bool                    use_autobaud_mode;
>         bool                    acl_priority;
> +       bool                    adv_type_fixup;
>         u8                      pcm_int_params[5];
>         u32                     max_autobaud_speed;
>  };
> @@ -686,6 +687,9 @@ static int bcm_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
>         struct hci_uart *hu = hci_get_drvdata(hdev);
>         struct bcm_data *bcm = hu->priv;
>
> +       if (bcm->dev && bcm->dev->adv_type_fixup)
> +               btbcm_fixup_le_adv_report(skb);
> +
>         if (bcm->dev && bcm->dev->acl_priority)
>                 btbcm_set_acl_priority_on_connect(hdev, skb);
>
> @@ -1100,6 +1104,7 @@ static int bcm_get_resources(struct bcm_device *dev)
>
>         if (x86_apple_machine && !bcm_apple_get_resources(dev)) {
>                 dev->acl_priority = true;
> +               dev->adv_type_fixup = true;
>                 return 0;
>         }
>
> diff --git a/drivers/bluetooth/hci_bcm4377.c b/drivers/bluetooth/hci_bcm4377.c
> index 30fcadfae3f..8d99a7a8f76 100644
> --- a/drivers/bluetooth/hci_bcm4377.c
> +++ b/drivers/bluetooth/hci_bcm4377.c
> @@ -691,6 +691,7 @@ static void bcm4377_handle_event(struct bcm4377_data *bcm4377,
>
>         memcpy(skb_put(skb, len), payload, len);
>         hci_skb_pkt_type(skb) = type;
> +       btbcm_fixup_le_adv_report(skb);
>         btbcm_set_acl_priority_on_connect(bcm4377->hdev, skb);
>         hci_recv_frame(bcm4377->hdev, skb);
>


-- 
Luiz Augusto von Dentz


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/4] Bluetooth: btbcm: clear vendor bits in LE advertising report types
  2026-11-04 15:24   ` Luiz Augusto von Dentz
@ 2026-11-04 15:34     ` Aditya Garg
  2026-11-04 15:46     ` André Eikmeyer
  1 sibling, 0 replies; 10+ messages in thread
From: Aditya Garg @ 2026-11-04 15:34 UTC (permalink / raw)
  To: Luiz Augusto von Dentz
  Cc: Andre Eikmeyer, marcel, linux-bluetooth, linux-kernel, sven, j,
	neal, asahi, linux-arm-kernel, 66ton99, josemiguelo.ochoa,
	Yossef Osman


> On 4 Nov 2026, at 8:55 PM, Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote:
> 
> Hi Andre,
> 
>> On Wed, Nov 4, 2026 at 10:16 AM Andre Eikmeyer <dev@deq.rocks> wrote:
>> 
>> The BCM4364B0 of the MacBookPro15,1 (UART) and the BCM4377 of the
>> MacBookAir9,1 (PCIe) set bits 4, 5 and 7 of the event type in LE
>> Advertising Report events. btmon on the 15,1 shows types 0x10, 0x13,
>> 0x14, 0x20, 0x23, 0x24, 0x93 and 0xa0 next to plain 0x00, 0x03 and 0x04,
>> the same advertiser shows up as 0x13, 0x23 and 0x03. The kernel log of
>> the 9,1 lists 0x10 to 0x24 and 0x80, 0x83, 0x90, 0x93, 0xa0, 0xa3.
>> process_adv_report() drops every type above 0x04 with "Unknown
>> advertising packet type", so most advertisements never reach the host.
>> An AirDrop sender was reported as 0x23, 0x23 and 0x13 and only the
>> fourth report, 0x03, reached BlueZ 32 s after the first one.
>> 
>> Add btbcm_fixup_le_adv_report(), which clears the bits above the type,
>> and call it from hci_bcm on Apple machines and from hci_bcm4377 before
>> the event goes to the core.
>> 
>> Suggested-by: Jose Miguel Ochoa <josemiguelo.ochoa@gmail.com>
>> Tested-by: Yossef Osman <Yossef.Osman@proton.me>
>> Tested-by: Aditya Garg <aditya.garg@linux.dev>
>> Signed-off-by: Andre Eikmeyer <dev@deq.rocks>
>> ---
>> drivers/bluetooth/btbcm.c       | 30 ++++++++++++++++++++++++++++++
>> drivers/bluetooth/btbcm.h       |  5 +++++
>> drivers/bluetooth/hci_bcm.c     |  5 +++++
>> drivers/bluetooth/hci_bcm4377.c |  1 +
>> 4 files changed, 41 insertions(+)
>> 
>> diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
>> index 0facfe62333..527a5c75fd6 100644
>> --- a/drivers/bluetooth/btbcm.c
>> +++ b/drivers/bluetooth/btbcm.c
>> @@ -282,6 +282,36 @@ void btbcm_set_acl_priority_on_connect(struct hci_dev *hdev, struct sk_buff *skb
>> }
>> EXPORT_SYMBOL_GPL(btbcm_set_acl_priority_on_connect);
>> 
>> +/* The BCM4364 and BCM4377 of the T2 Macs set bits above the event type of LE
>> + * Advertising Reports, 0x13 and 0x23 for ADV_NONCONN_IND for example. The
>> + * core drops reports of unknown types, so clear them.
>> + */
>> +void btbcm_fixup_le_adv_report(struct sk_buff *skb)
>> +{
>> +       struct hci_event_hdr *hdr = (void *)skb->data;
>> +       struct hci_ev_le_advertising_info *info;
>> +       u8 *p, *end;
>> +       u8 num;
>> +
>> +       if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT ||
>> +           skb->len < HCI_EVENT_HDR_SIZE + 2 || hdr->evt != HCI_EV_LE_META)
>> +               return;
>> +
>> +       p = skb->data + HCI_EVENT_HDR_SIZE;
>> +       if (p[0] != HCI_EV_LE_ADVERTISING_REPORT)
>> +               return;
>> +
>> +       num = p[1];
>> +       p += 2;
>> +       end = skb->data + skb->len;
>> +       while (num-- && p + sizeof(*info) + 1 <= end) {
>> +               info = (void *)p;
>> +               info->type &= 0x0f;
>> +               p += sizeof(*info) + info->length + 1;
>> +       }
>> +}
>> +EXPORT_SYMBOL_GPL(btbcm_fixup_le_adv_report);
> 
> I don't think I agree with this being cleaner then doing at
> hci_event.though; not only is it more code but it also walks the
> packet which is inefficient and may have security implications as
> well.

The hci_event patch makes it apply for all Broadcom chips. The author who sent that patch themselves use a T2 Mac. I doubt all Broadcom chips need this because there have been no bug reports from normal PCs.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/4] Bluetooth: btbcm: clear vendor bits in LE advertising report types
  2026-11-04 15:24   ` Luiz Augusto von Dentz
  2026-11-04 15:34     ` Aditya Garg
@ 2026-11-04 15:46     ` André Eikmeyer
  2026-11-04 16:29       ` Luiz Augusto von Dentz
  1 sibling, 1 reply; 10+ messages in thread
From: André Eikmeyer @ 2026-11-04 15:46 UTC (permalink / raw)
  To: Luiz Augusto von Dentz
  Cc: marcel, linux-bluetooth, linux-kernel, sven, j, neal, asahi,
	linux-arm-kernel, 66ton99, josemiguelo.ochoa, aditya.garg,
	Yossef Osman

On Wed, 4 Nov 2026 10:24:47 -0500
Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote:

> I don't think I agree with this being cleaner then doing at
> hci_event.though; not only is it more code but it also walks the
> packet which is inefficient and may have security implications as
> well.

You are right, the driver should not parse the event a second time.

What I would like to keep is limiting the mask to the controllers that
set these bits, as hci_bcm4377 already does with
HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY:

- add HCI_QUIRK_FIXUP_LE_ADV_REPORT_TYPE
- set it in hci_bcm on Apple machines and in hci_bcm4377
- test the quirk in hci_le_adv_report_evt() instead of the
  manufacturer, keeping the mask from 88397423671f

That drops patch 2 and replaces the revert in patch 3. Would that work
for you? Then I would send a v2 along these lines, with patch 1 and 4
unchanged.

Thanks,
Andre


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/4] Bluetooth: btbcm: clear vendor bits in LE advertising report types
  2026-11-04 15:46     ` André Eikmeyer
@ 2026-11-04 16:29       ` Luiz Augusto von Dentz
  2026-11-04 16:47         ` André Eikmeyer
  0 siblings, 1 reply; 10+ messages in thread
From: Luiz Augusto von Dentz @ 2026-11-04 16:29 UTC (permalink / raw)
  To: André Eikmeyer
  Cc: marcel, linux-bluetooth, linux-kernel, sven, j, neal, asahi,
	linux-arm-kernel, 66ton99, josemiguelo.ochoa, aditya.garg,
	Yossef Osman

Hi Andre,

On Wed, Nov 4, 2026 at 10:46 AM André Eikmeyer <dev@deq.rocks> wrote:
>
> On Wed, 4 Nov 2026 10:24:47 -0500
> Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote:
>
> > I don't think I agree with this being cleaner then doing at
> > hci_event.though; not only is it more code but it also walks the
> > packet which is inefficient and may have security implications as
> > well.
>
> You are right, the driver should not parse the event a second time.
>
> What I would like to keep is limiting the mask to the controllers that
> set these bits, as hci_bcm4377 already does with
> HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY:
>
> - add HCI_QUIRK_FIXUP_LE_ADV_REPORT_TYPE
> - set it in hci_bcm on Apple machines and in hci_bcm4377
> - test the quirk in hci_le_adv_report_evt() instead of the
>   manufacturer, keeping the mask from 88397423671f
>
> That drops patch 2 and replaces the revert in patch 3. Would that work
> for you? Then I would send a v2 along these lines, with patch 1 and 4
> unchanged.

Yes that would work. That said, I don't think it is worth adding a
quirk for this. Masking the reserved bits shouldn't cause any side
effects afaik, well except if those bits are later adopted by
Bluetooth SIG. Then these controllers would become
non-compliant—though they already are, as the bits are reserved and
not in use. In that case we would probably require a quirk to avoid a
conflict. So, is that what you are trying to fix?


-- 
Luiz Augusto von Dentz


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/4] Bluetooth: btbcm: clear vendor bits in LE advertising report types
  2026-11-04 16:29       ` Luiz Augusto von Dentz
@ 2026-11-04 16:47         ` André Eikmeyer
  0 siblings, 0 replies; 10+ messages in thread
From: André Eikmeyer @ 2026-11-04 16:47 UTC (permalink / raw)
  To: Luiz Augusto von Dentz
  Cc: marcel, linux-bluetooth, linux-kernel, sven, j, neal, asahi,
	linux-arm-kernel, 66ton99, josemiguelo.ochoa, aditya.garg,
	Yossef Osman

On Wed, 4 Nov 2026 11:29:11 -0500
Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote:

> Yes that would work. That said, I don't think it is worth adding a
> quirk for this. Masking the reserved bits shouldn't cause any side
> effects afaik, well except if those bits are later adopted by
> Bluetooth SIG. Then these controllers would become
> non-compliant—though they already are, as the bits are reserved and
> not in use. In that case we would probably require a quirk to avoid a
> conflict. So, is that what you are trying to fix?

No, nothing concrete beyond the scope, and I agree it is harmless as
long as the bits stay reserved. We only put it in the drivers because
our downstream ships driver modules through DKMS and not bluetooth.ko,
which let many users test it quickly. Let's keep 88397423671f as it
is then. I'll drop patch 2 and 3 and send a v2 with patch 1 and 4.


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-11-04 16:47 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-04 15:15 [PATCH 0/4] Bluetooth: Broadcom controllers of the Apple T2 Macs Andre Eikmeyer
2026-11-04 15:15 ` [PATCH 1/4] Bluetooth: btbcm: raise ACL priority on Apple Broadcom controllers Andre Eikmeyer
2026-11-04 15:15 ` [PATCH 2/4] Bluetooth: btbcm: clear vendor bits in LE advertising report types Andre Eikmeyer
2026-11-04 15:24   ` Luiz Augusto von Dentz
2026-11-04 15:34     ` Aditya Garg
2026-11-04 15:46     ` André Eikmeyer
2026-11-04 16:29       ` Luiz Augusto von Dentz
2026-11-04 16:47         ` André Eikmeyer
2026-11-04 15:16 ` [PATCH 3/4] Revert "Bluetooth: hci_event: strip Broadcom vendor bits from legacy adv report type" Andre Eikmeyer
2026-11-04 15:16 ` [PATCH 4/4] Bluetooth: set the strict duplicate filter quirk on Apple Broadcom controllers Andre Eikmeyer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox