mbox series

[0/5] Broadcom/Apple Bluetooth driver for Apple Silicon

Message ID 20220801103633.27772-1-sven@svenpeter.dev
Headers show
Series Broadcom/Apple Bluetooth driver for Apple Silicon | expand

Message

Sven Peter Aug. 1, 2022, 10:36 a.m. UTC
Hi,

This series adds support for the Broadcom 4377/4378/4387 PCIe Bluetooth
controllers found in some Apple x86 and all Apple M1/M2 machines.
These are part of the Bluetooth/WiFi module connected via PCIe which exposes
two functions.

Unlike regular Broadcom chips attached over UART or SDIO these no longer
support the usual patchram / minidriver firmware loading. Instead the
firmware is just directly mapped to the PCIe device and then booted.
In general the entire PCIe configuration space is similar to brcmfmac (or the
Android downstream bcmdhd driver). There are not many similarities with UART
Broadcom devices.


The firmware naming itself is a bit annoying but similar to the WiFi
function / brcmfmac: We need the chip id (e.g. 4377), the chip stepping
(e.g. b3), the module name (e.g. apple,atlantisb) and the antenna vendor (e.g.
m for Murata) to select the correct firmware file.

For 4377 so far only one board type exists and unlike WiFi there's no ACPI
companion from which we could get it. It's just hardcoded in the driver for
now but if you prefer I could also use DMI matching to get it.

For 4378/4387 found in Apple Silicon machines we store the board name and some
calibration data in the device tree. Unlike 4377 they also need the BD address
to be manually configured. I've added a generic Bluetooth controller binding to
replace bluetooth.txt for that.

The other parameters can be read from the OTP exposed in one of the BARs.

We unfortunately can't distribute the firmware itself but we can extract it from
the official macOS update packages Apple distributes. Our installer for
M1/M2 extracts the latest firmware and prepares it for Linux (and BSD)
automatically [1].

These chips use a protocol called "Converged IPC" based on shared memory
to transport messages to and from the host. It's unclear if this is all
Broadcom or a collaboration between Broadcom and Apple since some strings
in the debug output of macOS call the protocol "Apple Converged IPC" instead.

Once the chips have been booted and set up correctly the HCI packets themselves
are simply transported using ring buffers. Two quirks are required though:

	- BCM4377 claims to support extended scanning but then doesn't implement
	  the commands. The first quirk just disables it.

	- BCM4378/4387 use the upper byte of the event type field in the
	  LE Extended Advertising Report to store the channel on which the
	  frame was received. It's unclear if this is intentional or a bug
	  in the firmware. Usually these bits are reserved and should be set
	  to zero and the quirk just masks them to ensure the rest of the stack
	  can handle the packets.


This has been tested by quite a few people on various M1/M2 machines and a few
people with x86 T2 machines.
So far we only know that WiFi/Bluetooth coexistence is not working yet, but that
needs to be configured inside brcmfmac as far as we can tell.

There was also a single report on a T2 macbook where brcmfmac didn't work when
it was loaded before this driver but I haven't been able to investigate this in
detail. Other people reported no such issues and either way this driver
won't change much even if this issue was confirmed.



Best,


Sven


[1] https://github.com/AsahiLinux/asahi-installer/blob/main/asahi_firmware/bluetooth.py

Sven Peter (5):
  dt-bindings: net: Add generic Bluetooth controller
  dt-bindings: net: Add Broadcom BCM4377 family PCI Bluetooth
  Bluetooth: hci_event: Add quirk to ignore byte in LE Extended Adv
    Report
  Bluetooth: Add quirk to disable extended scanning
  Bluetooth: hci_bcm4377: Add new driver for BCM4377 PCI boards

 .../bindings/net/bluetooth-controller.yaml    |   30 +
 .../devicetree/bindings/net/bluetooth.txt     |    6 +-
 .../bindings/net/brcm,bcm4377-bluetooth.yaml  |   77 +
 MAINTAINERS                                   |    2 +
 drivers/bluetooth/Kconfig                     |   12 +
 drivers/bluetooth/Makefile                    |    1 +
 drivers/bluetooth/hci_bcm4377.c               | 2466 +++++++++++++++++
 include/net/bluetooth/hci.h                   |   21 +
 include/net/bluetooth/hci_core.h              |    4 +-
 net/bluetooth/hci_event.c                     |    4 +
 10 files changed, 2617 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/bluetooth-controller.yaml
 create mode 100644 Documentation/devicetree/bindings/net/brcm,bcm4377-bluetooth.yaml
 create mode 100644 drivers/bluetooth/hci_bcm4377.c

Comments

Sven Peter Aug. 1, 2022, 5:35 p.m. UTC | #1
Hi,

On Mon, Aug 1, 2022, at 17:23, Rob Herring wrote:
> On Mon, Aug 01, 2022 at 12:36:29PM +0200, Sven Peter wrote:
>> Bluetooth controllers share the common local-bd-address property.
>> Add a generic YAML schema to replace bluetooth.txt for those.
>> 
>> Signed-off-by: Sven Peter <sven@svenpeter.dev>
>> ---
>> I hope it's fine to list the current Bluetooth maintainers in here
>> as well.
>> 
>>  .../bindings/net/bluetooth-controller.yaml    | 30 +++++++++++++++++++
>>  .../devicetree/bindings/net/bluetooth.txt     |  6 +---
>>  2 files changed, 31 insertions(+), 5 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/net/bluetooth-controller.yaml
>> 
>> diff --git a/Documentation/devicetree/bindings/net/bluetooth-controller.yaml b/Documentation/devicetree/bindings/net/bluetooth-controller.yaml
>> new file mode 100644
>> index 000000000000..0ea8a20e30f9
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/net/bluetooth-controller.yaml
>> @@ -0,0 +1,30 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/net/bluetooth-controller.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Bluetooth Controller Generic Binding
>> +
>> +maintainers:
>> +  - Marcel Holtmann <marcel@holtmann.org>
>> +  - Johan Hedberg <johan.hedberg@gmail.com>
>> +  - Luiz Augusto von Dentz <luiz.dentz@gmail.com>
>> +
>> +properties:
>> +  $nodename:
>> +    pattern: "^bluetooth(@.*)?$"
>> +
>> +  local-bd-address:
>> +    $ref: /schemas/types.yaml#/definitions/uint8-array
>> +    minItems: 6
>> +    maxItems: 6
>> +    description:
>> +      Specifies the BD address that was uniquely assigned to the Bluetooth
>> +      device. Formatted with least significant byte first (little-endian), e.g.
>> +      in order to assign the address 00:11:22:33:44:55 this property must have
>> +      the value [55 44 33 22 11 00].
>> +
>> +additionalProperties: true
>> +
>> +...
>> diff --git a/Documentation/devicetree/bindings/net/bluetooth.txt b/Documentation/devicetree/bindings/net/bluetooth.txt
>> index 94797df751b8..3cb5a7b8e5ad 100644
>> --- a/Documentation/devicetree/bindings/net/bluetooth.txt
>> +++ b/Documentation/devicetree/bindings/net/bluetooth.txt
>> @@ -1,5 +1 @@
>> -The following properties are common to the Bluetooth controllers:
>> -
>> -- local-bd-address: array of 6 bytes, specifies the BD address that was
>> -  uniquely assigned to the Bluetooth device, formatted with least significant
>> -  byte first (little-endian).
>> +This file has been moved to bluetooth-controller.yaml.
>
> There's one reference to bluetooth.txt. Update it and remove this file.

Sure, I've just checked and found Documentation/devicetree/bindings/soc/qcom/qcom,wcnss.yaml
and Documentation/devicetree/bindings/net/qualcomm-bluetooth.yaml and will
update both for v2 and remove bluetooth.txt.


Thanks,


Sven