Help patching kernel's bluetooth driver for a Macbook 12"

I was trying to apply this patch to the current nixos kernel inspired by this post.

Patching, building and loading the module works perfectly, but I don’t see that support for Broadcom is being loaded when the hci_uart module is being loaded, so I suspect that the Kernel flags are not what I expect. Is there a way to explicitly set kernel flags using the approach that I took to build the driver?

configuration.nix

let
  hci_uart-kernel-module = pkgs.callPackage ./hci_uart.nix { inherit (config.boot.kernelPackages) kernel; };
  patched = hci_uart-kernel-module.overrideAttrs (prev: {
      patches = [ ./hci_bcm.patch ./Makefile.patch ];
  });
in
{
...
boot.extraModulePackages = [
    (lib.hiPrio patched)
  ];

hci_uart.nix

{ stdenv, lib, kernel }:

let
  modPath = "drivers/bluetooth";
  modDestDir = "$out/lib/modules/${kernel.modDirVersion}/kernel/${modPath}";

in stdenv.mkDerivation rec {
  name = "hci_uart-${kernel.version}";
  inherit (kernel) src version;

  postPatch = ''
    cd ${modPath}
  '';

  nativeBuildInputs = kernel.moduleBuildDependencies;

  makeFlags = kernel.makeFlags ++ [
    "-C ${kernel.dev}/lib/modules/${kernel.modDirVersion}/build"
    "M=$(PWD)"
    "modules"
  ];

  enableParallelBuilding = true;

  installPhase = ''
    runHook preInstall

    mkdir -p ${modDestDir}
    find . -name '*.ko' -exec cp --parents '{}' ${modDestDir} \;
    find ${modDestDir} -name '*.ko' -exec xz -f '{}' \;

    runHook postInstall
  '';

  meta = with lib; {
    description = "MacBook bluetooth drivers";
    inherit (kernel.meta) license platforms;
  };
}

PS: I tested the same patch a few days ago on Arch, so the driver should work for my Macbook.

Looking at the build logs i see that hci_bcm which is the file I am patching is not being built.

patching file drivers/bluetooth/Makefile
Running phase: updateAutotoolsGnuConfigScriptsPhase
Running phase: configurePhase
no configure script, doing nothing
Running phase: buildPhase
build flags: -j4 SHELL=/nix/store/7dpxg7ki7g8ynkdwcqf493p2x8divb4i-bash-5.2-p15/bin/bash O=\$\(buildRoot\) CC=/nix/store/vylmp73qymnv4siaqn1kl2hghj07hrj8-gcc-wrapper-12.3.0/bin/cc HOSTCC=/nix/store/vylmp73qymnv4siaqn1kl2hghj07hrj8-gcc-wrapper-12.3.0/bin/cc HOSTLD=/nix/store/qcg3rpl1l103zb1xfsw40wm9j5hzrp7y-binutils-wrapper-2.40/bin/ld ARCH=x86_64 -C /nix/store/kpwm0vhi68njzhcqfbym2jj4jp9h740x-linux-6.1.76-dev/lib/modules/6.1.76/build M=\$\(PWD\) modules
  CC [M]  /build/linux-6.1.76/drivers/bluetooth/hci_ldisc.o
  CC [M]  /build/linux-6.1.76/drivers/bluetooth/hci_serdev.o
  CC [M]  /build/linux-6.1.76/drivers/bluetooth/hci_h4.o
  CC [M]  /build/linux-6.1.76/drivers/bluetooth/hci_bcsp.o
  CC [M]  /build/linux-6.1.76/drivers/bluetooth/hci_ll.o
  CC [M]  /build/linux-6.1.76/drivers/bluetooth/hci_qca.o
  LD [M]  /build/linux-6.1.76/drivers/bluetooth/hci_uart.o
  MODPOST /build/linux-6.1.76/drivers/bluetooth/Module.symvers
  CC [M]  /build/linux-6.1.76/drivers/bluetooth/hci_uart.mod.o
  LD [M]  /build/linux-6.1.76/drivers/bluetooth/hci_uart.ko
  BTF [M] /build/linux-6.1.76/drivers/bluetooth/hci_uart.ko
Skipping BTF generation for /build/linux-6.1.76/drivers/bluetooth/hci_uart.ko due to unavailability of vmlinux
Running phase: installPhase
Running phase: fixupPhase

My guess is that I need a way to define CONFIG_BT_HCIUART_BCM y before building the kernel module. Any idea how I can achieve this?

When I add the flag as:

  boot.kernelPatches = [ {
        name = "bcm-config";
        patch = null;
        extraConfig = ''
                CONFIG_BT_HCIUART_BCM y
              '';
        } ];

I get the error:

GOT: make: Leaving directory '/build/linux-6.1.76'
error: unused option: CONFIG_BT_HCIUART_BCM

… so that’s probably not the way

If I pass the config like:

  boot.kernelPatches = [ {
        name = "bcm-config";
        patch = null;
        extraConfig = ''
                BT_HCIUART_BCM y
              '';
        } ];

it starts compiling the whole kernel, but that’s quite expensive in terms of resources for a fanless MacBook, so it would be great if someone could point out to me how to pass it only for small module compilation.

@florin-pop were you ever able to figure this out?

No, every time there’s a kernel update it compiles the entire kernel, it’s quite annoying as it takes 2-3hrs, but bluetooth works. I guess the default kernel doesn’t have broadcom driver support and maybe that’s why just compiling the driver didn’t work.