Adventures in WiFi, FreeBSD Edition

Posted on Wed 23 August 2017 in technology

In Which I Make a Poor Purchase

My recent relocation from Doha to Las Vegas sans computer gear has meant that I have had to build out my Las Vegas home's wifi infrastructure from scratch. I ordered a TP-LINK TL-WDN4800 off Newegg, and thought I would be off to the races.

# sysctl net.interfaces.wlan


I'm not sure what the folks over at (who bought the same card and are apparently running 10.3-RELEASE) did, but dmesg showed the following error for me on 11.1-RELEASE:

ar9300_attach: calling ar9300_hw_attach
ar9300_hw_attach: calling ar9300_eeprom_attach
ar9300_flash_map: unimplemented for now
Restoring Cal data from DRAM
Restoring Cal data from EEPROM
ar9300_hw_attach: ar9300_eeprom_attach returned 0
ath0: ath_getchannels: unable to collect channel list from hal, status 12
device_attach: ath0 attach returned 22

According to this comment on PR 194336, the failure to attach occurs due to the card reporting being in the Canadian regulatory domain, and support not being availble in the AR9300 driver for said regulatory domain.

Once More Down the Rabbit Hole

First of all, why is Newegg selling Canadian hardware in the US?

Second of all, shit.

Back to the PR, this comment indicates that a fix was committed to -CURRENT in 2016 and that it works, but that it had not yet made it into any production release. I'll have more to say on this in a moment, but first let's walk through actually fixing the problem at hand: we need to recompile our kernel with the fix.

I could track 11-stable, but I want to stay as close as possible to the current -RELEASE so that future security updates are as predictable as possible from a feature-set perspective. In light of this requirement, we check out the 11.1-RELEASE branch:

# svnlite checkout /usr/src

We then merge r306323 (which contains the wifi driver fix) into our local source tree:

# cd /usr/src/head/sys/dev/ath
# svnlite merge -r 305614:306323 .

r305614 is the last revision for directory sys/dev/ath in the 11-STABLE branch, from which the 11.1-RELEASE branch was originally cut. We would like our mergeset to include any changes to the directory between this initial revision and the fix eventually committed in r306323.

Create a custom build configuration and kick off a build:

# cd /usr/src/sys/amd64/conf
# make buildkernel KERNCONF=ARCBSD

The last command will take a while to execute. Go get a cup of tea. If there are compile errors, you fucked up the SVN merge. Revert changes to the tree and try the merge again:

# cd /usr/src
# svnlite revert --recursive .

Once the build is done, reboot and check that the system is, in fact, using the new kernel:

# uname -a
FreeBSD 11.1-RELEASE-p1 FreeBSD 11.1-RELEASE-p1 #0 r322740M: Mon Aug 21 08:19:33 UTC 2017  amd64

More importantly, check that the system can see the wifi card:

# sysctl net.wlan.devices
net.wlan.devices: ath0

We can now follow the FreeBSD handbook and use hostapd to set up a wireless access point.

And They Lived Happily Ever After

Except not really. Now that I am running a custom kernel, I can now longer use freebsd-update to update this machine. I am doomed to keep recompiling custom kernels with patches every time there is a security update to 11.1-RELEASE. This is work I wouldn't have to do if the FreeBSD developers merged what they built into extant production releases instead of saying "it's fixed in -CURRENT" and leaving users to flounder.

John Kozubic said this much more eloquently than I ever can in this measured, trenchant post on freebsd-hackers a few years ago. As time goes by and I deploy more and more FreeBSD servers to production, this line from the post rings so very true: FreeBSD is becoming an operating system by, and for, FreeBSD developers. The rest of us, trying to get work done, necessarily suffer from this lack of focus.

More on Hackernews here and again here.