Wifi UI Part 0

Work on the Android wireless driver is stalled for now as kvalo is rebasing the patches. I believe the next step will be to take the platform code, which I have temporarily built into a module called msm_wifi¸ and turn it into a platform rfkill device. Or something like that — this is what he and I came up with at the wireless summit. Then there’s an annoying stack trace because free_irq() happens in common code, but sdio irqs are somewhat different so that needs to be pushed down into the interface layer.

Meanwhile, my project for the weekend was to get wl12xx integrated into the UI. This is an area that is likely to change anyway, so I didn’t want to spend a lot of time to do the whole thing properly, but I did want to get the plumbing pieces done correctly, which means libnl-tiny plus wpa_supplicant with netlink (-Dnl80211) support. As it turned out, this was a somewhat frustrating ordeal of mismatching wpa_s and libnl versions and general cross compiling headaches, so I didn’t finish this yet.

I did, however, also try the wext driver with wpa_s which I already compiled using the Android port. There are a few special commands that the Android UI sends to the wpa_s control interface, so I stubbed out a few of those in the wext driver. Then I moved wlan.ko out of the way, replacing it with msm_wifi (the hardware library inserts the wlan.ko module when you enable wireless through the UI). With these changes, wl12xx initializes when you click the checkbox, but wpa_supplicant gets confused somehow so there’s still a little work to be done here. I suppose I should just patch some of the library code to know about the other driver in order to reduce the number of hacks needed to get it started.

ath5k performance history

I was curious how well ath5k has been improving since its release, so I hacked up a little script to associate and do five minute iperf runs from /etc/rc.local. Looks pretty good so far (w-t is wireless-testing plus 5 or 6 extra patches I have brewing). The script is pretty kludgy, but may form the basis for some automatic build/regression testing in the future.
ath5k iperf chart

Kernel 2.6.30

Linux kernel 2.6.30 is out, featuring the best mainline support for ath5k yet. I recommend if you do use wireless with 2.6.30 (or .29), that you also grab this patch which fixes a nasty memory corruption issue. That one haunted me for months but it was a great feeling to finally nail it down. Of course the fix turned out to be quite simple. It should be hitting stable in short order.

What to look for in 2.6.31:

  • AP mode (finally!)
  • better transmission power settings
  • enhanced support for regulatory domains
  • rfkill support

There are still a couple of bugs in AP mode and rfkill, but hopefully they’ll get ironed out in the next two weeks or so. It’s too early to make predictions for 2.6.32, but improved power saving is a possibility, and of course lots of bug fixes. I also hope to set up some automated testing now that I have more than one piece of hardware (thanks Luis!) and will be interested in seeing performance statistics since ath5k was introduced.

Next week, Ange and I will be heading off to Berlin, where I’ll be attending the Linux Wireless Mini-summit at FUDCon for a couple of days, and after that we’ll be staying a few days for vacation. I’m sure to return with a head full of ideas about 802.11 networking, and a belly full of beer and sausage.

wl12xx howto

So, wl12xx definitely works including transmission, but I still haven’t fixed the rough edges in the driver. However, I did bother to make a semi-permanent writeup on how to build and use wl12xx on the G1 as it currently stands. I hope to clean up the warts and submit the patchset next week. Meanwhile, I have a lot of ath5k bugs to work on. Enough for today though.

First scan

Success! Scanning with wl12xx on my ADP1 works. I’ll post more later but here’s a teaser. That’s a real SSID, however apt.

# ./iwlist wlan0 scan
wlan0     Scan completed :
          Cell 01 - Address: 00:0F:B5:63:30:4E
                    Frequency:2.462 GHz (Channel 11)
                    Quality=14/70  Signal level=-96 dBm
                    Encryption key:on
                    Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 18 Mb/s
                              24 Mb/s; 36 Mb/s; 54 Mb/s
                    Bit Rates:6 Mb/s; 9 Mb/s; 12 Mb/s; 48 Mb/s
                    Extra: Last beacon: 160ms ago
                    (Unknown Wireless Token 0x8C05)

wl12xx update

I won’t claim success until I actually transfer data, but so far, it looks like wl12xx SDIO support is baked:

[  111.247063] cfg80211: Using static regulatory domain info
[  111.253472] cfg80211: Regulatory domain: US
[  111.262810] 	(start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
[  111.271568] 	(2402000 KHz - 2472000 KHz @ 40000 KHz), (600 mBi, 2700 mBm)
[  111.279472] 	(5170000 KHz - 5190000 KHz @ 40000 KHz), (600 mBi, 2300 mBm)
[  111.287254] 	(5190000 KHz - 5210000 KHz @ 40000 KHz), (600 mBi, 2300 mBm)
[  111.294975] 	(5210000 KHz - 5230000 KHz @ 40000 KHz), (600 mBi, 2300 mBm)
[  111.302482] 	(5230000 KHz - 5330000 KHz @ 40000 KHz), (600 mBi, 2300 mBm)
[  111.310264] 	(5735000 KHz - 5835000 KHz @ 40000 KHz), (600 mBi, 3000 mBm)
[  111.317894] cfg80211: Calling CRDA for country: US
[  112.684807] lib80211: common routines for IEEE802.11 drivers
[  112.690972] lib80211_crypt: registered algorithm 'NULL'
[  112.744713] lib80211_crypt: registered algorithm 'TKIP'
[  112.787467] lib80211_crypt: registered algorithm 'WEP'
[  112.845267] lib80211_crypt: registered algorithm 'CCMP'
[  113.251671] wl12xx: registering driver
[  113.256462] wifi_probe
[  113.259208] trout_wifi_power: 1
[  113.569452] trout_wifi_reset: 0
[  113.623681] trout_wifi_set_carddetect: 1
[  113.628290] mmc0: card_present 1
[  113.631921] mmc0: Slot status change detected (0 -> 1)
[  113.653283] mmc0: Command timeout
[  113.664788] mmc0: card claims to support voltages below the defined range. These will be ignored.
[  113.678429] mmc0: SDIO card claims to support the incompletely defined 'low voltage range'. This will be ignored.
[  113.692773] mmc0: new SDIO card at address 0001
[  113.702813] wl12xx: in probe
[  113.728844] phy0: Selected rate control algorithm 'minstrel'
[  113.738915] wl12xx: loaded
[  113.743919] wl12xx: initialized

Unfortunately, I can’t really test it yet because the wpa_supplicant already on the phone doesn’t support -Dwext or -Dnl80211, and there are no wireless-tools. So I need to cross-compile those before attempting to associate. In the meantime, here’s a very rough patch that implements the goods from wireless-testing wl12xx. I need to work on read() and write() – right now they are a copy of what is in the google driver because it appears the host driver has issues with RW_EXTENDED. I don’t believe the readb/writeb fallbacks should be strictly necessary. Ditto with the platform code, that needs a slightly better solution.

wl12xx merged

commit 00d8979d598d5461a06d800c779f15e03888d9d8
Author: Kalle Valo 
Date:   Wed Apr 29 23:33:31 2009 +0300

    wl12xx: add driver

    wl12xx is a driver for TI wl1251 802.11 chipset designed for embedded
    devices, supporting both SDIO and SPI busses. Currently the driver
    supports only SPI. Adding support 1253 (the 5 GHz version) should be
    relatively easy. More information here:


    (Collapsed original sequence of pre-merge patches into single commit for
    initial merge. -- JWL)

    Signed-off-by: Kalle Valo 
    Signed-off-by: Bob Copeland 
    Signed-off-by: John W. Linville 

Hooray, wl12xx is now in wireless-testing! As the commit log states, SDIO support isn’t there yet, because I haven’t written it yet. Well, I wrote some of it, but nothing worth even compile-testing yet.

As for the Android itself, I bought a snazzy serial breakout board for the phone so now I can do some real work on it. It works just fine with screen(1) as the terminal program.

Also, I solved the problem with booting: apparently the init program for 2.6.25 doesn’t work with 2.6.27 — when I put my own compiled init in the initramfs, everything mounted fine. The input devices now do not work, but I suspect it’s just a difference in paths and that an upgrade to 1.5 userland will fix all of that.


I was in fact wrong that my self-compiled android kernels weren’t booting — they were. But they do fail somewhere in init:. Unfortunately, when you boot the phone, you don’t have any idea why it fails because there’s no console by default. It would’ve been a lot easier to see this if I had a serial cable, but I did finally remember that I could use fbcon with the smallest font and CONFIG_PRINTK_DELAY to see the messages scroll by. And so now I see the problem:

init: Unable to open persistent property directory /data/property errno: 2
init: cannot find '/system/bin/sh', disabling 'console'
init: cannot find '/system/bin/servicemanager', disabling 'servicemanager'

Obviously, the init script can’t mount the mtd partitions, despite the partition tables being successfully probed at start and my having yaffs2 built-in. Oh well, at least now I have a direction to start debugging.

The 2.6.25 branch of the msm tree, incidentally, works fine with the stock initrd and userland, but who wants such an old kernel? Oh, and I changed my bootup logo to a shiny Tux instead of the default robot. “Android isn’t Linux” indeed.


The Android source code includes at least two ARM sub-architectures in their kernel tree. The one actually used on the G1 hardware is derived from the Qualcomm MSM machine type, at least part of which is in the mainline. Then there is “goldfish,” which appears to be just a pseudo machine used only for the emulator. While I haven’t had a lot of success with the MSM stuff booting on the phone so far, building the emulator kernel is not too hard once you know where to look:

# get the MSM specific tree.
# You don't really need it but might as
# well grab both up front into the same git repo.
$ git clone git://android.git.kernel.org/kernel/msm.git msm
$ cd msm

# also grab the common one for emulator target and check it out
$ git remote add common git://android.git.kernel.org/kernel/common.git
$ git fetch common
$ git checkout -b goldfish common/android-goldfish-2.6.27

$ cat <<_EOM >make-arm.sh
#! /bin/bash

# I use the codesourcery toolchain
PATH="$XGCC/arm-2008q3/bin/:$PATH" make ARCH=arm CROSS_COMPILE=arm-none-eabi- "$@"

$ chmod 755 make-arm.sh
$ ./make-arm.sh goldfish_defconfig
$ ./make-arm.sh

Now the emulator can be run with something like:

$ export ANDROID_PRODUCT_OUT=`/bin/pwd`/out/target/product/dream
$ emulator -verbose -show-kernel -kernel msm/arch/arm/boot/zImage

2.6.30 preview

Now that Linux 2.6.29 just went out the door, here’s what I have prepared for 2.6.30 in the wireless arena. Of note, mac80211 now has suspend/resume support so a lot of nasty hacks in the drivers can go away. Most of the rest is just bug fixes, some of them for panics and soft lockups.

The work I’m excited about this week is scheduled for 2.6.31 — we extracted a bunch of ath9k regulatory infrastructure into a common module that all of the Atheros drivers (including the new ar9170) will use. This is the first step in getting a lot of that common code into a library. Hooray! Also Nick has some great improvements to the RF stuff queued up, so the driver is behaving much better.

Bob Copeland (29):
      ath5k: support LEDs on Acer Aspire One netbook
      ath5k: fix off-by-one in gpio checks
      mac80211: document return codes from ops callbacks
      ath5k: fix bf->skb==NULL panic in ath5k_tasklet_rx
      mac80211: add suspend/resume callbacks
      ath5k: remove stop/start calls from within suspend/resume
      ath5k: remove unused led_off parameter
      ath5k: use short preamble when possible
      ath5k: honor the RTS/CTS bits
      mac80211: change workqueue back to non-freezeable
      mac80211: flush workqueue a second time in suspend()
      ath9k: remove write-only current_rd_inuse
      ath9k: save a few calls to ath9k_regd_get_eepromRD
      ath9k: convert isWwrSKU macro into C code
      ath9k: remove ath9k_regd_get_rd()
      ath9k: remove prototype for ath9k_regd_get_current_country
      ath9k: move common regulatory code out of if() branches
      ath5k: don't mask off interrupt bits
      ath5k: use spin_lock_irqsave for beacon lock
      ath5k: move beacon processing to a tasklet
      ath5k: compute rts/cts duration after computing full pktlen
      ath9k: fix 802.11g conformance test limit typo
      ath5k: extract LED code into a separate file
      ath5k: use a table for LED parameters
      ath5k: update LED table with reported devices
      ath5k: disable MIB interrupts
      ath5k: remove dummy PCI "retry timeout" fix
      ath5k: warn and correct rate for unknown hw rate indexes
      ath5k: properly drop packets from ops->tx