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.
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.
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.
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.
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
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)
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.
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:
A N D R O I D
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
# 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
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
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