RT2870 compile error under (K)Ubuntu Maverick (10.10)

Yesterday the next version of Ubuntu was released. It comes with kernel 2.6.35 which can make problems if you want to compile the RT2870 driver provided by Ralink. The reason for me to compile the driver rather than using the one shipped with the kernel is that the latter reduces my WLAN speed from 130 MBit/s to 54 MBit/s.

If you start compiling the Ralink driver you will soon get the following error message:

CC [M]  2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.o
2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.c: In function ‘RTMPAllocUsbBulkBufStruct’:
2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.c:52: error: implicit declaration of function ‘usb_buffer_alloc’
2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.c:52: warning: assignment makes pointer from integer without a cast
2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.c: In function ‘RTMPFreeUsbBulkBufStruct’:
2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.c:78: error: implicit declaration of function ‘usb_buffer_free’
2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.c: In function ‘RTMPFreeTxRxRingMemory’:
make[2]: *** [2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.o] Error 1
make[1]: *** [_module_2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-2.6.35-22-generic'
make: *** [LINUX] Error 2

The cause for these errors is that the driver makes use of the functions usb_buffer_alloc() and usb_buffer_free() which got renamed in kernel 2.6.35. This is stated in the Changelog:

    USB: rename usb_buffer_alloc() and usb_buffer_free() users

    For more clearance what the functions actually do,

      usb_buffer_alloc() is renamed to usb_alloc_coherent()
      usb_buffer_free()  is renamed to usb_free_coherent()

So to get rid of the error messages all you have to do is to rename the function in include/os/rt_linux.h. To make it easier you can download a patch here. Just run the following command in the driver directory:

patch -ul -p0 -i path/to/patch

Or use the one-liner:

wget -qO- http://www.linuxcrew.de/wp-content/uploads/2010/10/rt2870sta_usb_kernel2635.patch | patch -ul -p0

After patching you can compile the driver without errors again.

RT2870-Kompilierungsfehler unter (K)Ubuntu Maverick (10.10)

Gestern wurde die neue Version der beliebten Linux-Distribution veröffentlicht. Mit im Gepäck der Kernel 2.6.35. Wer wie ich im Besitz eines WLAN-Sticks mit dem RT2870-Chipsatz ist, stellt das erst mal vor Probleme. Ich nutze nicht den mitgelieferten Treiber rt2870sta, da dieser meine WLAN-Übertragung von 130 MBit/s auf 54 MBit/s drosselt.

Abhilfe schafft da den aktuellsten Ralink-Treiber zu kompilieren, was aber mit dem neuen Kernel 2.6.35 zu folgendem Fehler führt:

CC [M]  2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.o
2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.c: In function ‘RTMPAllocUsbBulkBufStruct’:
2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.c:52: error: implicit declaration of function ‘usb_buffer_alloc’
2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.c:52: warning: assignment makes pointer from integer without a cast
2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.c: In function ‘RTMPFreeUsbBulkBufStruct’:
2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.c:78: error: implicit declaration of function ‘usb_buffer_free’
2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.c: In function ‘RTMPFreeTxRxRingMemory’:
make[2]: *** [2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux/../../common/cmm_mac_usb.o] Fehler 1
make[1]: *** [_module_2010_0709_RT2870_Linux_STA_v2.4.0.1/os/linux] Fehler 2
make[1]: Verlasse Verzeichnis '/usr/src/linux-headers-2.6.35-22-generic'
make: *** [LINUX] Fehler 2

Schuld daran ist der Rückgriff auf die Funktionen usb_buffer_alloc() und usb_buffer_free(). Diese wurden umbenannt, was sich auch der Changelog des Kernels entnehmen lässt:

    USB: rename usb_buffer_alloc() and usb_buffer_free() users

    For more clearance what the functions actually do,

      usb_buffer_alloc() is renamed to usb_alloc_coherent()
      usb_buffer_free()  is renamed to usb_free_coherent()

Alles was man also tun muss ist die entsprechenden Funktionen in der include/os/rt_linux.h umzubenennen. Einen entsprechenden Patch könnt ihr hier runterladen. Einfach folgendes Kommando im Treiberverzeichnis ausführen:

patch -ul -p0 -i pfad/zur/patchdatei

Oder bequem per Einzeiler:

wget -qO- http://www.linuxcrew.de/wp-content/uploads/2010/10/rt2870sta_usb_kernel2635.patch | patch -ul -p0

Danach lässt sich der Treiber wieder problemlos kompilieren.

DD-WRT auf D-Link DIR-615 H/W Rev. D3 installieren

Mit der D-Link-Firmware auf dem DIR-615 zu arbeiten ist nicht gerade übersichtlich. Dies war einer der Gründe, warum ich mich entschied DD-WRT zu installieren. Der andere Grund — der gewichtigere von beiden — war die Firewall. Diese blockte von Zeit zu Zeit SSH-Verbindungen zwischen mir und den Root-Servern, mit denen ich verbunden war. Die lapidare Meldung im Log: "Xmas port scan attack from WAN". Da ich viel per SSH arbeite also ein unzumutbarer Zustand. DD-WRT unterstützt offiziell laut deren Router Database nicht die H/W Rev. D3, sondern nur D2. Mit der Webflash-Image für den D2 funktioniert der Umstieg trotzdem problemlos. Vorher sollte man allerdings die aktuelle Firmware 4.11 von D-Link aufspielen. Die kriegt man hier: D-Link Firmware 4.11 für DIR-615. Wichtig: Unbedingt die README-Datei lesen und befolgen. Nach dem Firmwareupdate auf 4.11 kann man dann das Webflash-Image für die H/W Rev. D2 aufspielen. In der Router-Database wird es unter dem Namen "D-Link DIR-615 rev D2 Firmware: Special image for initial flashing" geführt. Build 14896 hat bei mir problemlos funktioniert. Für den Fall, dass es nicht funktioniert oder beim Flashen etwas schief geht, gibt es beim D-Link einen "Emergency Room", über den das Image eingespielt werden kann. Wie man den aktiviert wird im OpenWRT-Forum beschrieben.

Eine gute Vorbereitung erspart Kummer

Generell sollte man sich vor dem Flashen erst mal etwas in die Thematik einlesen. Daher lege ich jedem folgende Dokumentationen ans Herz: Infos zur Installation von DD-WRT – Grundlegende Informationen. Darin wird auch auf den Peacock Thread verwiesen, der weitere Informationen enthält. Darin wird auch die 30-30-30-Reset-Methode angesprochen. Diese ist meines Wissens nach nicht nötig beim DIR-615. Hält man nämlich Reset gedrückt und schält den Router an, landet man im oben erwähnten "Emergency Room". Hardware-spezifische Infos – Sind nur für die H/W Rev. CX verfügbar. Die Passage über’s Editieren der Firmware entfällt beim D3!