Ubuntu Wi-Fi 5GHz Issue on Raspberry Pi 5

Raspberry Pi 5

I normally install Ubuntu on my Raspberry Pi machines because I am comfortable with its ecosystem. Most of the time though, I have been using these boxes connected to my network via Ethernet.

Recently, I got a new Raspberry Pi 5, and as usual, I installed Ubuntu on it. This time I used the official HAT to install the OS on an NVMe drive. The Raspberry Pi imager tool does a great job of setting up the machine with Wi-Fi enabled. What I never paid attention to was how much the country setting in the options affects the Wi-Fi band.

After booting up the machine, I noticed that the Wi-Fi band was set to 2.4GHz. I found it odd. What followed was a lot of detail that, as usual, I wish I didn’t need to know, but now had to. :(

$ iwconfig wlan0
wlan0     IEEE 802.11  ESSID:"xxx"
          Mode:Managed  Frequency:2.462 GHz  Access Point: 60:22:32:xxx:xxx:xxx
          Bit Rate=72.2 Mb/s   Tx-Power=31 dBm
...

Turns out that the country setting affects what is called the regulatory domain (kernel.org) for the Wi-Fi configuration. This regulates the frequency bands that the wireless card can use.

You can see the wifi regulatory domain by running the following command: iw reg get.

Because I didn’t pay attention to the country setting, the first time it was mistakenly set to AE (United Arab Emirates). Because of this setting the kernel command line in Raspberry Pi bootloader was set to AE. I also saw that cloud-init configured netplan to set the AE regulatory domain on the wifi interface.

$ cat /mnt/cmdline.txt
console=serial0,115200 multipath=off dwc_otg.lpm_enable=0 console=tty1 root=LABEL=writable rootfstype=ext4 rootwait fixrtc cfg80211.ieee80211_regdom=AE

$ cat /etc/netplan/50-cloud-init.yaml
network:
  version: 2
  wifis:
    wlan0:
      optional: true
      dhcp4: true
      regulatory-domain: "AE"

This was preventing the wifi card from using the 5GHz band. I tried to change the country setting by running iw reg set CA (Canada), and even changed the kernel command line, but it didn’t work.

root@rpi3:~# iw reg get
global
country CA: DFS-FCC
	(2402 - 2472 @ 40), (N/A, 30), (N/A)
	(5150 - 5250 @ 80), (N/A, 23), (N/A), NO-OUTDOOR, AUTO-BW
	(5250 - 5350 @ 80), (N/A, 24), (0 ms), DFS, AUTO-BW
	(5470 - 5600 @ 80), (N/A, 24), (0 ms), DFS
	(5650 - 5730 @ 80), (N/A, 24), (0 ms), DFS
	(5735 - 5835 @ 80), (N/A, 30), (N/A)
	(5925 - 7125 @ 320), (N/A, 12), (N/A), NO-OUTDOOR

phy#0
country 99: DFS-UNSET
	(2402 - 2482 @ 40), (6, 20), (N/A)
	(2474 - 2494 @ 20), (6, 20), (N/A)
	(5140 - 5360 @ 160), (6, 20), (N/A)
	(5460 - 5860 @ 160), (6, 20), (N/A)

While the global setting was set to Canada, it is overridden by the country setting for the phy#0 interface - the country 99: DFS-UNSET setting.

According to the Linux kernel documentation on wireless regulatory processing rules:

Upon the initialization of the wireless core (cfg80211) a world regulatory domain (highly restrictive) will be set as the central regulatory domain. If you get a 00 country code it means you are world roaming.

World roaming means we cannot initiate radiation on certain channels given that certain countries may prohibit initiating radiation on some channels or may require DFS master support prior to initiating any radiation.

This means that unless the phy#0 interface is set to a country other than the world roaming (country “00” is world roaming; “99” means the driver couldn’t determine a country code and therefore similar behavior), the wifi card will not initiate radiation on the 5GHz band.

And why is the phy#0 interface set to the world roaming when the global setting is set to Canada? I spent a few hours scouring the internet for answers, but didn’t find anything at first. Then I found a post about a person who switched back from Ubuntu to the Raspberry Pi OS and the wifi started working. Turns out that the Raspberry Pi OS uses an updated firmware version which honors the global setting.

I could confirm this by checking the firmware version on the Raspberry Pi OS and Ubuntu.


$ # On Raspberry Pi

$ cat /lib/firmware/brcm/brcmfmac43455-sdio.bin | strings| grep -Eo "Version: \S+"
Version: 7.45.265
$ lsb_release -d
Description:	Debian GNU/Linux 13 (trixie)

$ # On Ubuntu

$ zstdcat /lib/firmware/brcm/brcmfmac43455-sdio.bin.zst | strings| grep -Eo "Version: \S+"
Version: 7.45.234
$ lsb_release -d
Description:	Ubuntu 24.04.3 LTS

For now, I will stick with the Raspberry Pi OS, till the firmware on Ubuntu releases catches up.

What an absolute waste of time otherwise, but learning about the logic around kernel wifi regulatory domain handling was fascinating.

tech
Integrating Homebrew bash completion on Linux with system completions Setting Up a Private Helm Chart Repository with Chartmuseum