Linux is Friendly - Recovering from Missing Firmware


Occasionally, we folks using Linux find our selves in situations where things break; our computers do not function as intended. In my scenario, I was out on business in another country, and my WiFi device was simply not showing up after a reboot.
I know a lot of people (I was one of them), who at first impulse would want to re-install their operating system to fix something of this sort. Fixing something of this sort is a lot easier than one might think. The purpose of this blog is to illustrate how user friendly, easy and instructive Linux is.
Error messages are your friend
You typed that command, run that python or bash script, started compiling that code - and……ERROR - we’ve all faced this. The terminal spewing out line after line of debugging messages almost like the devil himself cursing humanity in unholy tongues. Our first impulse is fight or flight - yes, when I started using *nix systems - specifically programming them, there were times when error messages made me freeze up and do irrational things. For eg.
Missing Library - no sweat - nuke the OS, start over.
Type mismatch - no sweat, toss the machine in the furnace, get a new one
Kernel panic - no sweat, turn up the cooking gas, blow up the house, leave family……..start life over
Life changed for me when I started to actually read the error messages. Lo and behold - they were not unholy tongues spoken by a mysterious evil overlord inside my computer - they were actually super user friendly messages, written by programmers - telling you exactly what to do.
Back to the story
Now that I’m a lot older, I stayed calm. Here is how I got out of my situation.
WiFi Adapter not working - foreign country. First step…diagnose things. Below we can see that there is no wireless adapter at all.
┌─[apocalypse0@darkmatter]─[~]
└──╼ $ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: ovs-system: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether b2:2c:24:2d:3b:ee brd ff:ff:ff:ff:ff:ff
3: mzbr: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether d2:b5:68:27:9e:4b brd ff:ff:ff:ff:ff:ff
4: dmzbr: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 5a:06:a5:7a:2d:48 brd ff:ff:ff:ff:ff:ff
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:f5:2b:b1:4d brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
6: br-b4dcd604c9ec: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:f0:37:01:95 brd ff:ff:ff:ff:ff:ff
inet 172.19.0.1/16 brd 172.19.255.255 scope global br-b4dcd604c9ec
valid_lft forever preferred_lft forever
inet6 fe80::42:f0ff:fe37:195/64 scope link
valid_lft forever preferred_lft forever
┌─[root@darkmatter]─[~]
└──╼ #lspci -vnn -k | grep -A 10 -i network
00:14.3 Network controller [0280]: Intel Corporation Comet Lake PCH CNVi WiFi [8086:06f0]
Subsystem: Intel Corporation Comet Lake PCH CNVi WiFi [8086:0070]
Flags: fast devsel, IRQ 16, IOMMU group 6
Memory at 604111c000 (64-bit, non-prefetchable) [size=16K]
Capabilities: [c8] Power Management version 3
Capabilities: [d0] MSI: Enable- Count=1/1 Maskable- 64bit+
Capabilities: [40] Express Root Complex Integrated Endpoint, MSI 00
Capabilities: [80] MSI-X: Enable- Count=16 Masked-
Capabilities: [100] Latency Tolerance Reporting
Capabilities: [164] Vendor Specific Information: ID=0010 Rev=0 Len=014 <?>
Kernel modules: iwlwifi, wl
Great - we now know our chipset, the drivers and modules responsible. Let’s now take a look at dmesg
for any potential issues
┌─[root@darkmatter]─[~]
└──╼ #dmesg | grep -i iwlwifi
[ 11.235547] iwlwifi 0000:00:14.3: enabling device (0000 -> 0002)
[ 11.248125] iwlwifi 0000:00:14.3: Detected crf-id 0x3617, cnv-id 0x20000302 wfpm id 0x80000000
[ 11.248161] iwlwifi 0000:00:14.3: PCI dev 06f0/0070, rev=0x351, rfid=0x10a100
[ 11.248175] iwlwifi 0000:00:14.3: Detected Intel(R) Wi-Fi 6 AX201 160MHz
[ 11.248978] iwlwifi 0000:00:14.3: firmware: failed to load iwlwifi-QuZ-a0-hr-b0-77.ucode (-2)
[ 11.249028] iwlwifi 0000:00:14.3: firmware: failed to load iwlwifi-QuZ-a0-hr-b0-77.ucode (-2)
[ 11.249036] iwlwifi 0000:00:14.3: Direct firmware load for iwlwifi-QuZ-a0-hr-b0-77.ucode failed with error -2
[ 11.249049] iwlwifi 0000:00:14.3: no suitable firmware found!
[ 11.249060] iwlwifi 0000:00:14.3: iwlwifi-QuZ-a0-hr-b0-77 is required
[ 11.249070] iwlwifi 0000:00:14.3: check git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
[ 11.572733] Modules linked in: wl(POE+) intel_pmc_core_pltdrv(-) snd_sof snd_sof_utils snd_soc_hdac_hda x86_pkg_temp_thermal intel_powerclamp snd_soc_acpi_intel_match snd_soc_acpi soundwire_bus coretemp kvm_intel snd_soc_avs uvcvideo snd_soc_hda_codec snd_hda_ext_core snd_intel_dspcfg videobuf2_vmalloc btusb snd_intel_sdw_acpi uvc btrtl kvm videobuf2_memops snd_soc_core videobuf2_v4l2 mei_hdcp mei_wdt mei_pxp intel_rapl_msr btintel snd_ctl_led snd_compress rapl videodev btbcm processor_thermal_device_pci_legacy snd_pcm_dmaengine iwlwifi btmtk rmi_smbus(+) iTCO_wdt snd_hda_codec intel_cstate videobuf2_common processor_thermal_device bluetooth snd_hda_core processor_thermal_wt_hint intel_uncore intel_pmc_bxt think_lmi(+) mc pcspkr snd_hwdep processor_thermal_rfim intel_wmi_thunderbolt rmi_core firmware_attributes_class cfg80211 wmi_bmof snd_pcm thinkpad_acpi iTCO_vendor_support watchdog mei_me ee1004 processor_thermal_rapl intel_rapl_common snd_timer ucsi_acpi nvram processor_thermal_wt_req mei sparse_keymap
Great - we see that there is a missing file, and we know where we should download it - all of it is there
Let’s sort it out . I used my mobile with USB tethering to get access to the internet.
wget https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/iwlwifi-QuZ-a0-hr-b0-77.ucode -O /lib/firmware/iwlwifi-QuZ-a0-hr-b0-77.ucode
Now let’s load it up
modprobe -r iwlwifi
modprobe iwlwifi
That’s it - all works.
┌─[✗]─[root@darkmatter]─[/etc/modprobe.d]
└──╼ #ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ovs-system: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether b2:2c:24:2d:3b:ee brd ff:ff:ff:ff:ff:ff
3: mzbr: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether d2:b5:68:27:9e:4b brd ff:ff:ff:ff:ff:ff
4: dmzbr: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 5a:06:a5:7a:2d:48 brd ff:ff:ff:ff:ff:ff
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
link/ether 02:42:f5:2b:b1:4d brd ff:ff:ff:ff:ff:ff
6: br-b4dcd604c9ec: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
link/ether 02:42:f0:37:01:95 brd ff:ff:ff:ff:ff:ff
9: enx3c18a0562589: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether 3c:18:a0:56:25:89 brd ff:ff:ff:ff:ff:ff
10: wlp0s20f3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
link/ether 20:1e:88:1b:41:21 brd ff:ff:ff:ff:ff:ff
The main thing is to keep calm and read the error messages.
Subscribe to my newsletter
Read articles from Karan Sajnani directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Karan Sajnani
Karan Sajnani
Hacker, creator, musician, martial artist, western classical guitar player, motorcyclist, performer, yoga practitioner.