Context
I’m currently attempting to get Bluetooth working on my Dell XPS 13 9310.
The connectivity chip inside my particular device is the QCA6390, responsible for both wifi and bluetooth. While the wifi driver is still a work-in-progress, there are reports of Linux users having their bluetooth “just work” without any modifications.
E.g. the Arch wiki lists bluetooth working via btusb
, and users have mentioned bluetooth working on Ubuntu without any extra configuration required. My aim is to get this working on NixOS and complete my nixos-hardware
PR.
Kernel Config
One Ubuntu user kindly shared their dmesg
output here, demonstrating loading of the btqca
and bluetooth
modules, neither of which I see when running lsmod
locally. This lead me to suspect a difference in kernel configuration. After doing some digging into the Arch and Debian default kernel configs and comparing them, I added the following patch and extra modules:
# Extra config required for Bluetooth.
{
name = "enable-qca6390-bluetooth";
patch = null;
extraConfig = ''
BT_QCA m
BT_HCIBTUSB m
BT_HCIBTUSB_AUTOSUSPEND y
BT_HCIUART m
BT_HCIUART_QCA y
'';
}
];
# Enable some extra kernel modules for QCA6390 bluetooth.
kernelModules = [ "btqca" "btusb" "hci_qca" "hci_uart" ];
I can now see the Bluetooth modules being loaded in my dmesg:
[mindtree@mindtree:~]$ dmesg | grep -i bluetooth
[ 3.599287] Bluetooth: Core ver 2.22
[ 3.599301] Bluetooth: HCI device and connection manager initialized
[ 3.599304] Bluetooth: HCI socket layer initialized
[ 3.599306] Bluetooth: L2CAP socket layer initialized
[ 3.599309] Bluetooth: SCO socket layer initialized
[ 3.619715] Bluetooth: HCI UART driver ver 2.3
[ 3.619717] Bluetooth: HCI UART protocol H4 registered
[ 3.619717] Bluetooth: HCI UART protocol BCSP registered
[ 3.619725] Bluetooth: HCI UART protocol LL registered
[ 3.619729] Bluetooth: HCI UART protocol QCA registered
[ 48.990643] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[ 48.990649] Bluetooth: BNEP socket layer initialized
However, at this point I was still missing the firmware that was showing up in the other user’s log:
[ 2.416321] Bluetooth: hci0: setting up ROME/QCA6390
[ 2.420348] Bluetooth: hci0: Frame reassembly failed (-84)
...
[ 2.756645] Bluetooth: hci0: QCA Product ID :0x00000010
[ 2.756647] Bluetooth: hci0: QCA SOC Version :0x400a0200
[ 2.756647] Bluetooth: hci0: QCA ROM Version :0x00000200
[ 2.756648] Bluetooth: hci0: QCA Patch Version:0x00000d2b
[ 2.756650] Bluetooth: hci0: QCA controller version 0x02000200
[ 2.756651] Bluetooth: hci0: QCA Downloading qca/htbtfw20.tlv
[ 3.584055] Bluetooth: hci0: QCA Downloading qca/htnv20.bin
[ 3.777754] Bluetooth: hci0: QCA setup on UART is completed
The Firmware
I located the QCA6390 firmware in the linux-firmware
repo here. Judging by the user’s output, it seems I specifically needed htbtfw20.tlv
and htnv20.bin
.
The problem is that I’m unsure exactly how to install this firmware. I’ve made an attempt to create a nix derivation for this firmware here, mostly based on copying how the wifi firmware is installed (see here), but for the most part this has been a wild guess.
Since including this in my nix configuration with the following, I haven’t noticed any difference in my dmesg output, and Bluetooth hasn’t magically started working.
nixpkgs.overlays = [(final: previous: {
qca6390-bt-firmware = final.callPackage ./qca6390-bt-firmware.nix {};
})];
hardware.firmware = lib.mkBefore [
# Firmware for the AX500 bluetooth.
pkgs.qca6390-bt-firmware
];
Questions
- Am I missing a step required in order to get this Bluetooth firmware to load?
- Is there a short-hand in nix for installing firmware from the kernel.org’s
linux-firmware
repository?
Any advice or ideas would be greatly appreciated!
Extra Info
I’m using the 5.10-rc4
version of the kernel in order to pull in some patches required to get wifi working. I’m using the unstable nixos channel for nixpkgs.