Querying the State of a Hardware WiFi Switch with RF-Kill
The laptop that I’m writing this post from has a really annoying strip of touch-response buttons above the keyboard that control things like volume and whether or not the wifi card is on. By touch-response, I mean that the buttons don’t require a finger press, but rather just a touch of the finger. As such, they provide no haptic feedback, so it’s hard to tell whether or not they work except by surveying the results of your efforts in the operating system.
The WiFi button in particular has go to be the worst of these buttons. On Windows, it glows a lovely blue colour when activated, and an angry red colour when disabled. This directly maps to whether or not my physical wireless network interface is enabled or disabled, and is a helpful indicator. Under Linux Mint 12 however, the “button” is always red, which makes it a less than helpful way to diagnose the occasional network drop.
Lately, I’ve been having trouble getting the wifi to reconnect after one of these drops. To troubleshoot, I would open up the Network Settings panel in Mint, which looks something like this:
The only problem with this window is that the ON/OFF slider that controls the state of the network interface would refuse to work. If I drag it to the ON position, it would just bounce back to OFF without changing the actual state of the card.
In the past, this behaviour has really frustrated me, driving me so far as to reboot the machine in Windows, re-activate the physical interface, and then switch back to Mint to continue doing whatever it was that I was doing in the first place. Tonight, I decided to investigate.
I started out with my old friend iwconfig:
jonf@jonf-mint ~ $ sudo iwconfig
lo no wireless extensions.
eth0 no wireless extensions.
wlan0 IEEE 802.11abgn ESSID:off/any
Mode:Managed Access Point: Not-Associated Tx-Power=off
Retry long limit:7 RTS thr:off Fragment thr:off
As you can see, the wireless interface is listed, but it appears to be powered off. I was able to confirm this by issuing the iwlist command, which is supposed to spit out a list of nearby wireless networks:
jonf@jonf-mint ~ $ sudo iwlist wlan0 scanning
wlan0 Interface doesn’t support scanning : Network is down
Again, you can see that the interface is not reacting as one might expect it to. Next, I attempted to enable the interface using the ifconfig command:
jonf@jonf-mint ~ $ sudo ifconfig wlan0 up
SIOCSIFFLAGS: Operation not possible due to RF-kill
Ah-ha! A clue! Apparently, something called rfkill was preventing the interface from coming online. It turns out that rfkill is a handy little tool that allows you to query the state of the hardware buttons (and other physical interfaces) on your machine. You can see a list of all of these interfaces by issuing the command rfkill list:
jonf@jonf-mint ~ $ rfkill list
0: phy0: Wireless LAN
Soft blocked: no
Hard blocked: yes
1: hp-wifi: Wireless LAN
Soft blocked: no
Hard blocked: yes
Interestingly enough, it looks like my wireless interface has been turned off by a hardware switch, which is what I had suspected all along. The next thing that I tried was the rfkill event command, which tails the list of hardware interface events. Using this tool, you can see the effect of pressing the physical switches and buttons on the chasis of your machine:
jonf@jonf-mint ~ $ rfkill event
1349740501.558614: idx 0 type 1 op 2 soft 0 hard 0
1349740505.153269: idx 0 type 1 op 2 soft 0 hard 1
1349740505.354608: idx 1 type 1 op 2 soft 0 hard 1
1349740511.030642: idx 1 type 1 op 2 soft 0 hard 0
1349740515.558615: idx 0 type 1 op 2 soft 0 hard 0
Each of the lines that the tool spits out shows a single event. In my case, it shows the button that controls the wireless interface switching the hard block setting (physical on/off) from 0 to 1 and back.
After watching this output while pressing the button a few times, I realized that the button does actually work, but that when the interface is turned on, it can take upwards of 5 seconds for the machine to notice it, connect to my home wireless, and get an ip address via DHCP. In the intervening time, I had typically become frustrated and pressed the button a few more times, trying to get it to do something. Instead, I now know that I have to press the button exactly once and then wait for it to take effect.
I stand by the fact that this is a piss-poor design, but hey, what do I know? I’m not a UX engineer for HP. At least it’s working again, and I am reconnected to my sweet sweet internet.
On my home media server, I am running Ubuntu 12.04
Check out my profile for more information.