michael orlitzky

Thinkpad X61s ath5k rfkill issues

posted 2012-06-02; updated 2021-08-02

Update 2021-08-02
Now that I know what to look for, I see that a lot of other people have reported this bug. It' not going to get fixed a decade after the hardware was relevant, but the good news is that—it turns out—you can work around the issue without patching. The ath5k module supports an (undocumented, ha ha) option that will prevent it from fucking with your hardware rfkill switch entirely. Just add options ath5k no_hw_rfkill_switch=1 to your /etc/modprobe.d/ath5k.conf or whatever and reload the module.

The Problem

The Thinkpad X61s has an AR5212 802.11 a/b/g wireless NIC, and its in-kernel driver is ath5k. It can also use the MadWifi drivers, which offer some kind of improvement over the in-kernel ones (in theory).

ath5k

However, at least on the Thinkpad X61s, the ath5k drivers don't work. Whenever your association with an access point is lost, the NIC throws itself into “hard blocked” mode, and won't come out:

root # rfkill list

0: phy0: Wireless LAN

Soft blocked: no

Hard blocked: yes

You can't fix this because it isn't really hard blocked. So, you can't,

  1. Switch networks
  2. Suspend/Resume
  3. Lose your connection due to interference
  4. etc.

But, the ath5k drivers at least suspend/resume correctly (in that your machine does not crash).

MadWifi

The MadWifi drivers have their own problems.

First, they don't suspend/resume correctly. You can work around this with a script that removes/adds the module pre/post-suspend, but that's stupid.

Second, they aren't in the kernel tree, and don't always compile against the latest kernel. So, if you install a new kernel, you'll usually reboot to find that you're fucked and have no way to unfuck yourself, what with no network card and all.

The Fix

We can simply disable the rfkill crap in the ath5k driver. Here's a patch (ath5k-rfkill.patch):

--- a/drivers/net/wireless/ath/ath5k/rfkill.c	2012-05-28 21:16:04.000000000 -0400
+++ b/drivers/net/wireless/ath/ath5k/rfkill.c	2012-05-28 21:17:17.000000000 -0400
@@ -66,10 +66,8 @@
 static bool
 ath5k_is_rfkill_set(struct ath5k_hw *ah)
 {
-	/* configuring GPIO for input for some reason disables rfkill */
-	/*ath5k_hw_set_gpio_input(ah, ah->rf_kill.gpio);*/
-	return ath5k_hw_get_gpio(ah, ah->rf_kill.gpio) ==
-							ah->rf_kill.polarity;
+        /* Hard code this to work around a stupid bug. */
+        return 0;
 }
 
 static void

I know what you're thinking: if I have to patch the kernel every upgrade, isn't that as annoying as upgrading MadWifi? Nope.

  1. This patch is much more likely to compile against new kernels.
  2. You can have portage automatically patch the kernel, by placing the patch file in /etc/portage/patches/sys-kernel/gentoo-sources.
  3. If the patch fails, so will the kernel build. So you won't boot up to find your network card missing.