TL;DR: switch your
sys-net’s kernel to
6.2.7 (don’t forget
CONFIG_RTW89_8852BE=m) and stick
rtw89/rtw8852b_fw.bin from the latest linux-firmware (upstream, not packaged yet) in
/lib/firmware. have fun.
The Lenovo 21A2 (ThinkBook 14 G3) ships with a Wi-Fi card that did not work for me out of the box, but with some fiddling I found a kernel/firmware combination that does work. If your device is not a Lenovo 21A2, but you’re in a similar situation, these instructions may or may not do anything for you.
At the time of writing, the necessary kernel version is not packaged, so you will need to build Linux from source—which requires a decent amount of command-line work. I also assume you have Internet connectivity, despite your Wi-Fi card not working: you need to be able to install packages and download kernel sources and a firmware blob. The 21A2’s Ethernet port works out of the box; I used that. If that’s not an option, you may be able to use Bluetooth or USB to get a connection.
I found a lot of references to DKMS and out-of-tree drivers (often random GitHub repositories), but I did not end up needing them. Besides Qubes packages, this guide uses only code available from kernel.org.
The 21A2’s Wi-Fi card’s model number is
02HK704. I don’t remember if that piece of information ended up being useful, but I do remember that it was hard to find. Even with the card fully working,
lspci and friends don’t show the exact model, just that it’s Realtek.
Before starting, save any work and stop your qubes. Since this involves replacing
sys-net, any qube that has a net qube assigned will be stopped in the process of carrying out these steps. If you want to leave certain qubes running, that’s fine; just make sure to unset the net qube for each of them (and reset it at the end).
qui-domains menu will refuse to stop a qube that’s providing something to other qubes. I kept the Qubes Manager open and used it to start and stop qubes: it will prompt you for confirmation, then stop the qube along with anything that’s using it.
- Create a new standalone qube. I named mine
sys-net-custom. Change its settings to the same as your existing
sys-net. In particular:
- net qube: (none)
- provides network access: true
- include in memory balancing: false
- virtualization mode: HVM
- devices: (whatever your network cards are—the 21A2 has two, labeled “Ethernet controller” and “Network controller”)
Optional: change the color of
sys-net-customand then change it back, to get the servicevm icon. (For some reason
qvm-prefsdoesn’t let you set the
icon, but Qubes Manager will do it if you use it to change the color.)
In a fresh dispVM, download, configure, build, and install the kernel (version 6.2.7). Exactly how to do this is well-covered by other guides (for example KernelBuild - Linux Kernel Newbies). I’ll just add that you can get the running kernel’s config from
/proc/config.gzas an alternative to searching
/boot. Make sure to turn on support for the Wi-Fi card (which is the entire point!). The option name is
RTW89_8852BE. If you’re using the menu configurator, it’s under Device Drivers → Network device support → Wireless LAN → Realtek devices
→ Realtek 802.11ax wireless chips support → Realtek 8852BE PCI wireless network (Wi-Fi 6) adapter.
Once installed in the dispVM, copy the compressed kernel image and the modules to dom0. The next step expects to find them in dom0’s
In dom0, run
sudo qubes-prepare-vm-kernel 6.2.7-1.qubes.fc32.x86_64. If all has gone well, the new kernel should now be listed in qube settings!
Open the settings for
sys-net-customand set its kernel to the new one.
sys-netif it was running and start
Download the firmware image from https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/rtw89/rtw8852b_fw.bin?id=bcdcfbc, copy it to
sys-net-custom, and place it in
/lib/firmware/rtw89. I deleted the
rtw8852b_fw.bin.xzthat was there to make sure Linux didn’t try to load the old/non-working version.
Reload the module in
sudo modprobe -r rtw89_8852be rtw89_8852b && sudo modprobe rtw89_8852be), then restart NetworkManager. I didn’t need to reboot the qube, but that should also work.
At this point, NetworkManager recognized the card, and I was able to pick my Wi-Fi network from the list and access the Internet. Hopefully the same goes for you!
A couple more things:
Set the original
sys-netnot to start on boot (it can’t run at the same time as
sys-net-custombecause they claim the same PCI devices). I set
sys-net-customnot to start on boot either, since it will be started automatically because of
sys-firewall(which starts on boot).
Default Qubes policies designate
sys-netfor downloading updates, even if the default NetVM is something else. In dom0, add a policy to override this; for example:
dom0 $ cat /etc/qubes/policy.d/20-sys-net-custom.policy qubes.UpdatesProxy * @type:TemplateVM @default allow target=sys-net-custom
- Make sure to keep a copy of the firmware saved outside of where it’s installed, so that you can restore it in case an update clobbers it, without needing an Internet connection.
Collected resources that I found particularly useful:
- Linux kernel build : Perform "make localmodconfig" non-interactive way - Stack Overflow
- KernelBuild - Linux Kernel Newbies (except that I downloaded a tarball instead of cloning the whole kernel repository—the tarballs are only about 150M and the git clone took much longer for me)
- Managing qube kernels | Qubes OS (official resource)
- More complete (slightly) instructions for compiling a custom kernel (primarily the “Conjectured procedure” section)
qubes-prepare-vm-kernelsource code (it’s a script; you can just read it)
- New binary rtw8852b_fw.bin not loading firmware not recognized (for the idea to try other firmware versions when the Wi-Fi card still didn’t work after updating the kernel)
P.S. I’ll submit a normal HCL report for the 21A2 after I’ve used it for a week or so.