wl12xx on the Google Android Dev Phone 1

Introduction

The Android kernel uses a TI-provided 802.11 driver. This driver
is GPLed, however it does not use the standard Linux wireless stack.
Kalle Valo of Nokia has written a mac80211-based driver, wl12xx,
which was mainlined in 2.6.31, and I have written the SDIO interface
logic, likely to go in for 2.6.32.

Most people should just stick with the driver that comes with the
ADP1, as it’s rather painful to switch drivers and there are few
benefits to using wl12xx at this time. However, in the interest of
having a mainlined wifi driver on the device, here are a few notes
on how to install and use wl12xx.

There is a lot of room for streamlining the process here, but this
is more or less what I’ve arrived at. Please let me know if there are
any errors.

I assume you already have ADP v1.5 installed since the kernel needs a
recent userspace. I also have busybox installed in my path, but I’ve
left out any manual path setup for brevity’s sake.

Patches

Android wireless setup

Android uses a wpa_supplicant build with a custom driver for the
TI vendor driver. The UI communicates with this lower level via
the Java class android.net.wifi.WifiNative, which is implemented in
android_net_wifi_Wifi.cpp. This, in turn, uses functions in
libhardware_legacy/wifi/wifi.c to interact with the wpa_supplicant
control socket located on the device in /dev/socket/wpa_tiwlan0.
Android handles some additional commands not included in the stock
wpa_supplicant, defined in external/wpa_supplicant/ctrl_iface.c.

Note, the default wpa_supplicant drivers (e.g. -Dwext), will not do
anything useful for the custom Android commands, so the UI will not
work properly at this time. My patch for wpa_supplicant adds a few
stubs to the nl80211 driver, but it is incomplete.

Base Environment

The Android code drop described
here includes
a kernel tree as well as a cross-compiler toolchain and userland. You
will need to build this first to create all the libraries for building
userspace utilities.

Building the MSM kernel

I prefer to clone my kernel directly rather than using the repo tool,
Also I use the 2.6.29 version because it is compatible with
compat-wireless, and the precompiled tiwlan driver won’t load so it
doesn’t get in the way.

Apply this patch
to create a new module called msm_wifi. This
module sets GPIOs appropriately to power up the wifi module and
implement virtual card-select; it needs to be loaded for wl1251_sdio
to successfully probe the device.

You should configure the kernel with at least SDIO and MAC80211 support
(my .config).
Put the arm toolchain in your path and do:

% make ARCH=arm CROSS_COMPILE=arm-none-eabi-

Building compat-wireless

Current compat-wireless contains everything you need to build wl1251_sdio.
Download it here.

Getting firmware files

wl12xx needs two firmware files. One includes the standard firmware which
is the same for all devices, and another that includes calibration data
that is specific to each individual device. To get them in the right place,
boot the normal kernel. Turn on the wifi to load the TI driver, then do:

Booting the device

In my opinion, the easiest way to load a custom kernel is to unpack the
ramdisk image from the 1.5 firmare package, then boot with the self-compiled
zImage. To get the ramdisk, I use the
unpack-bootimg.pl
script on the boot.img from the Android 1.5 system image zip archive:

To boot the kernel, put the phone in fastboot mode. Plug the phone into
USB, then hold down the back-arrow while turning the phone on. This should
bring up the boot loader (robots on skateboards) with the string "FASTBOOT"
in the center. Now run the fastboot tool:

You won’t see anything for a minute or so, then the phone will reboot.
If you have all the proper tools installed (see below) and a
wpa_supplicant.conf, you can then try loading the modules and
associating:

If all goes well, wlan0 will have associated with your AP and you’re
up and running.

Userland tools

wpa_supplicant - WEXT

You can rebuild the wpa_supplicant that comes with the Android build
environment to also support wl1251 (and any other mac80211 driver)
by including the wireless extensions driver. To do so, from the
toplevel Android directory, edit external/wpa_supplicant/Makefile
and add the following lines to the mkconfig target:

However, WEXT is old and busted and NL80211 is the new hotness, so
read on to build one that supports nl80211.

wpa_supplicant - nl80211

Here’s how to build a recent, dynamically-linked wpa_supplicant from git.
Note it does not include support for the tiwlan0 driver that works with
the vendor driver. The SHA-1s noted below are known to work but newer ones
might also suffice.

Then apply this patch.
Again, edit wpa_supplicant/config_android to configure the ANDROID and
LIBNL paths appropriately.

% cd wpa_supplicant
% cp config_android .config
% make

You now have a wpa_supplicant binary dynamically linked against bionic libc
and libnl.so. Unlike the android fork, it does not include the custom TI
supplicant driver, so it can only be used with wl12xx or other native
Linux drivers.

Either version of wpa_supplicant needs a config file like the following
to connect to your AP: