FreeBSD 12.0: Enabling Wi-Fi on ThinkPad X230

FreeBSD 12.0: Enabling Wi-Fi on ThinkPad X230

The rant

Recently I just got my new laptop, ThinkPad X230 from 2012. Actually, this is my first non-Apple laptop, so I decided to try FreeBSD on it. My other laptops feature Apple’s secure boot chips T1 and T2 which will prevent booting into OSes other than macOS and Windows, so this is the first time I got to try Linux or BSDs on my own laptop computer. Upon receiving the machine I installed Manjaro i3 and MX Linux right away, as those are my main Linux desktop daily drivers. Days after, I decided to run some flavor of BSD on this nicely boxy, underrated machine. Just for fun.

How to get WiFi working on FreeBSD on ThinkPad X230 with Intel Centrino Advanced-N 6025 network card.

During FreeBSD installation you should be prompted to configure IPv4 and IPv6 for your network interfaces. I have never successfully configured any wireless interfaces with this menu during installation, be it on my 2013 iMac or on this Lenovo machine, so I ‘kinda’ expected it to fail and just connect the laptop via Ethernet first to configure em0 to fetch and install FreeBSD patches with freebsd-update. You don’t need Ethernet in order to get WiFi working, just finish the installation normally without configuring wlan0 and reboot. Yes, we will manually configure the WiFi to work after we reboot into our freshly installed FreeBSD 12.0.

Note: Upon successful boot, if there is no internet connection and if you set ntpd to ‘enabled’ during installation, then the ntpd daemon will complain a lot and mess up with your serial console output, so I recommend not to enable ntpd yet before you setup your wireless networking. You can always enable ntpd later as easily as by adding an entry in /etc/rc.conf file or issuing sysrc command.

Step 1)

Upon reboot, check your network interface cards by issuing (as root):

# sysctl net.wlan.devices

This should return iwn0, which is for the Intel Centrino Advanced-N 6025 in our X230. Take note and proceed.

Step 2)

Now that we know which device will be our wlan0 interface, we will edit the /etc/rc.conf file so that FreeBSD knows iwn0 is wlan0, and set the correct regulation for our wireless connection (check your own country code and regulatory domain, for example FCC for US, ETSI for UK, APAC for TH), and that after the handshake we would like to use DHCP. (You can explicitly choose static IP but for the sake of simplicity and just trying to connect I will go for DHCP. If you choose to go static, provide your inet, subnet, and default gateway addresses.)

# [ /etc/rc.conf ]
wlans_iwn0="wlan0"
create_args_wlan0="country TH regdomain APAC"
ifconfig_wlan0="WPA SYNCDHCP"

Step 3)

Now that we know the device, add the following entries to /boot/loader.conf file to tell FreeBSD to load the relevant wireless networking modules (we actually won’t need to tell it to load the drivers or firmware because it is usually loaded for us, but I’ll just leave them commented out here in case it’s useful for other people):

# [ /boot/loader.conf ]
#if_iwn_load="YES"
#iwn6000fw_load="YES"
#iwn6000g2afw_load="YES"
#iwn6000g2bfw_load="YES"
#iwn6050fw_load="YES"
wlan_scan_ap_load="YES"
wlan_scan_sta_load="YES"
wlan_wep_load="YES"
wlan_ccmp_load="YES"
wlan_tkip_load="YES"

Step 4)

We’re almost done, except that we have not yet populated our WPA configuration file with our SSID (Wi Fi name) and PSK (pre-shared key or your typical WiFi password). Now add the following entry to /etc/wpa_supplicant.conf:

# [ /etc/wpa_supplicant.conf ]
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=wheel
network={
    ssid="YOURWIFI"
    scan_ssid=1
    psk="YOURPASSWORD"
}

Reboot now, the splash screen should tell us if iwn0 is already loaded or not, if not and connection failed, try adding the lines with driver loading statements from Step 3 to /boot/loader.conf and reboot and see if it works. If iwn0 is loaded but there is no wlan0 carrier anyway, try editing /etc/wpa_supplicant.conf and /etc/rc.conf and reload netif by issuing (as root):

# service netif restart

Unrelated: How to dualboot UEFI FreeBSD and Linux with one EFI partition using GRUB2

The FreeBSD installer has guided steps so the installation was easy and smooth, except the disk partition part where I decided not to create a EFI partition which ‘FreeBSD required to boot’ because I hate having 2 EFI partitions on the same disk. Sure enough after the installation I could not boot into FreeBSD. The solution here is to use Linux on my machine to copy BOOTx64.efi from the live USB to the existing EFI partition on my machine, in my case it is (when mounted under /boot/efi) conveniently located at /boot/efi/EFI/FreeBSD/BOOTx64.efi. Then I edited the 40_custom file in /etc/grub.d (on my Manjaro root, as grub was installed with Manjaro) to look something like:

# [ /etc/grub.d/40_custom ]
menuentry "FreeBSD" --class freebsd --class bsd --class os {
    insmod bsd
    insmod ufs2
    chainloader (hd0,gpt4)/EFI/FreeBSD/BOOTx64.efi
}
# FreeBSD was installed without explicit own EFI partition, so I copied the bootloader file BOOTx64.efi from FreeBSD live USB's EFI partition to the main disk's existing EFI partition (/dev/sda4 or hd0,gpt4)

Then, update grub configuration file with:

$ sudo update-grub

grub should detect FreeBSD installation as ‘unknown Linux distrobution’. Then reboot, and your grub menu should now present you with an entry for FreeBSD.

Note: This is my first ‘serious’ FreeBSD installation, but despite all the hassles, thanks to very nice documentation and support from the FreeBSD community, I have had a very good time learning and tweaking my system to boot and get WiFi working. I remembered it being much worse with Linux where official documentation from the distros suck, but with FreeBSD, reading the FreeBSD documentation and handbook is very fun, cohesive, challenging and educating. This is what prompted me to write this piece, just in case someone with a X230 had non-working WiFi out-of-the-box and was looking for help. Hope this helps!