Friday, August 21, 2009

Marvell Libertas CF8305 partly supported

So after my own private hackathon I held for last two weeks and where OpenBSD gained support for Palm hardware to some extent, I felt the urge to fix some hardware to work with Linux. And there was a perfect candidate for that, the WiFi card in Palm LifeDrive. That damn little piece of silicon bothered me for more than two years already, but just a few hours ago, I cracked the nut there at least.

The Marvell Libertas CF8305 is actually a very ancient piece of silicon and runs Marvell proprietary firmware version 3.0 . Being this old, the card has various issues which later models (like CF8381 and CF8385) do not have. The first difference from the later models is that this card runs only an one-stage firmware, but that's luckily loaded the same way as a helper firmware on the later models. The second-stage firmware isn't loaded at all on this card.

Next issue on the list happens when accessing registers of the card. It seems the card can not do an unaligned accesses to it's registers which means the driver has to access only odd addresses. Accesses to even addresses doesn't work - in case of reading the returned value is the one of the nearest lower odd address. But luckily, there is only one such unaligned access happening in the whole if_cs.c part of the driver and that is when reading the SCRATCH_PAD register which has address 0x3F . And this can be easily worked around by doing a 16bit read of address 0x3E and bit-shifting the result by 8 to the right.

This was the easy part, but the horrible bugs are still waiting. Apparently, with the first problem fixed, the firmware can be loaded and the card seem to respond to some commands, so far so good. What the card really does not like though is a command with code 0x0006 aka. CMD_802_11_SCAN. Once that command is sent to the card, the card plain hangs and all you can do is remove the driver, eject the card and reinsert it (there's no hardware eject so use 'pccardctl eject' and 'pccardctl insert'). The real problem here is, once the card is brought up (for instance by 'ifconfig eth0 up', the driver itself issues the SCAN command - or at least that's what it does when configured into Ad-Hoc mode. This can be worked around by editing 'drivers/net/wireless/libertas/scan.c' and commenting out 'ret = __lbs_cmd(priv, CMD_802_11_SCAN...);' at around line 333.

With the hack above, it's possible at least for the card to serve as a node in an Ad-Hoc network. But that's not the last limitation it has. It's impossible for now to reconfigure the card once brought up. Since in case you do that, the command 0x002b aka. CMD_802_11_AD_HOC_START will fail and again hanging the whole card.

Other than that, if the card is configured by 'iwconfig' and then brought up by 'ifconfig', it seems to be possible to establish at least the Ad-Hoc network. Well there are still some very hard limitations, but at least there are some signs of life from the card and it can't get any worse now.

Here's the patch for the if_cs.c file: LINK
And here's a picture of a working WiFi on Palm LifeDrive:

No comments: