Zuwenig Sendeleistung mit TP-Link WLAN-Karte

Ich habe hier eine PCIe-WLAN-Karte vom Typ „TL-WDN4800“ mit Atheros-AR9380-Chip.

Laut iw list sendet die Karte im 5 GHz-Band nur mit 17 dBm statt der erlaubten 20 dBm:

[...]
 Frequencies:
 * 5180 MHz [36] (17.0 dBm)
 * 5200 MHz [40] (17.0 dBm)
 * 5220 MHz [44] (17.0 dBm)
[...]

Ursache ist ein auf der Karte verbautes EEPROM, in das von TP-Link die Einsatzregion (Regdomain) geschrieben wurde, laut dmesg „AU“, also Australien:

[Sun Oct 28 18:56:19 2018] ath: EEPROM regdomain: 0x21
[Sun Oct 28 18:56:19 2018] ath: EEPROM indicates we should expect a direct regpair map
[Sun Oct 28 18:56:19 2018] ath: Country alpha2 being used: AU
[Sun Oct 28 18:56:19 2018] ath: Regpair used: 0x21

Mit iw reg get kann man sich das auch noch mal hübsch anzeigen lassen:

global
country 98: DFS-ETSI
        (2402 - 2482 @ 40), (N/A, 20), (N/A)
        (5170 - 5250 @ 80), (N/A, 17), (N/A), NO-OUTDOOR, AUTO-BW
        (5250 - 5330 @ 80), (N/A, 20), (0 ms), NO-OUTDOOR, DFS, AUTO-BW
        (5490 - 5710 @ 160), (N/A, 24), (0 ms), DFS
        (5735 - 5835 @ 80), (N/A, 13), (N/A)

phy#0
country AU: DFS-ETSI
        (2402 - 2482 @ 40), (N/A, 20), (N/A)
        (5170 - 5250 @ 80), (N/A, 17), (N/A), AUTO-BW
        (5250 - 5330 @ 80), (N/A, 24), (0 ms), DFS, AUTO-BW
        (5490 - 5710 @ 160), (N/A, 24), (0 ms), DFS
        (5735 - 5835 @ 80), (N/A, 30), (N/A)

Die Karte darf damit maximal so senden, wie es in Australien erlaubt ist: Bei 5 GHz maximal 17 dBm. Und da ich in Deutschland bin, gilt die zusätzliche Einschränkung, die Deutschen Vorschriften nicht zu überschreiten. Die Karte wird also so senden, dass sie die Vorschriften beider Länder einhält. In der wireless-regdb kann man nachlesen, welche das genau sind.

Wie werde ich nun Australien mit all seinen Einschränkungen los?

Erster Fehlversuch: EEPROM ändern.

http://blog.asiantuntijakaveri.fi/2014/08/one-of-my-atheros-ar9280-minipcie-cards.html und da https://blog.aheymans.xyz/2018/01/02/ath9k_eeprom/ wird beschrieben, wie man das EEPROM ausliest, die Regdomain ändert und dann wieder auf die Karte schreibt. Im Github-Repository https://github.com/barkovv/AtherosROMKit.git gibt’s im Verzeichnis „MacNB_iwleeprom“ sogar ein gepatchtes iwleeprom-Programm, das das in einem Rutsch erledigen soll.

Nur funktioniert das leider mit Chips der AR9300-Reihe nicht, das EEPROM bleibt wie es ist.

Zweiter Fehlversuch: EEPROM ignorieren.

Oben in der dmesg-Ausgabe sieht man, dass das ath-Modul das EEPROM ausliest. Die Länder-zu-Frequenzen-und-Sendeleistungs-Zuordnung macht das Kernelmodul cfg80211.

Für ath9k gibt zwar einen EEPROM-Ignorieren-Patch, nur müsste ich dazu jedes Mal den hübschen Debian-Kernel neu kompilieren. Das ist mir für ein paar dBm mehr Sendeleistung zu aufwändig.

Ein OpenWRT-Entwickler hat ein Tool geschrieben, das die kompilierten(!) Kernelmodul patcht und die Vorgaben zumindest etwas aufweicht: https://github.com/drizzt/reghack.git:

Aus ath9k werden die Einschränkungen zu Radar entfernt, aus cfg80211 die gröbsten Beschränkungen der Länder bei Frequenzen und Sendeleistung.

Aber: Unter Debian kann das Tool nur ath9k patchen, cfg80211 bleibt so wie es ist. In Australien.

Dritter Fehlversuch: Australien ändern.

Welche Regeln in Australien gelten weiß der Linux-Kernel von crda („central regulatory domain agent“). Crda sieht wiederum in einer kleinen Datenbank, der wireless regulatory database, kurz wireless-regdb nach, in der sämtliche Länder mit deren Vorgaben gespeichert sind. Wenn ich hier die deutschen Vorgaben Australien unterschiebe, müsste es also passen. So der Plan.

Im Debian-Wiki ist die genaue Vorgehensweise beschrieben ist: https://wiki.debianforum.de/Ausländische_WLan-Karte_mit_deutschen_Kanälen_betreiben

Nur: Entweder hab ich was falsch gemacht oder der Wiki-Artikel aus dem Jahr 2012 spiegelt nicht mehr den aktuellen Stand wieder. Kurz: Funktioniert nicht.

Update 2020: Erfolg!

Vor geraumer Zeit hat mit ein Leser zu Fehlerversuch 1 „EEPROM öndern“ geschrieben:

Du kannst das EEPROM mit iwleeprom schreiben, wenn du vorher das Write-Protect-Pin (Pin 7) vom EEPROM ablötest und von der Platine abhebst, so dass es keinen Kontakt mehr hat.
Ein passendes Datenblatt vom 24c32f findest du hier: https://www.st.com/resource/en/datasheet/cd00001012.pdf

Das klappt tatsächlich:
Ich habe mit einer kleinen Zange Pin 7 des EEPROMs durchgezwickt und konnte danach das EPPROM mit iwleeprom beschreiben. Zumindest zwei bis drei mal. Danach gab’s Schreibfehler, das EEPROM schien kaputt zu sein. Meine WLAN-Karte stand dann auf Region auf 0x00 mit ungültiger Checksumme – Linux macht daraus USA.

Ein paar Monate später, an einem dunklen, kalten Winterabend samt Corona-Ausgangssperre hab ich dann das EEPROM einfach von der WLAN-Karte abgelötet und in meinem MiniPro-EEPROM-Programmer getestet. Schreiben, Lesen – alles funktioniert einwandfrei. Hurra! Keine Ahnung warum das EEPROM auf der WLAN-Karte nicht mehr beschrieben werden kann.

Ich habe dann noch ein bisschen mit iwleeprom aus https://github.com/barkovv/AtherosROMKit.git herumgespielt, mir die EEPROM-Dumps angesehen die ich damals erstellt hatte und dazu ein paar PDFs zu den Atheros-Chipsätzen überflogen, in denen das EEPROM erklärt wird.
Ziemlich schnell war’s dann klar: iwleeprom macht (fast) alles richtig, und die Anleitungen im Internet sind grob irreführend:
Die Positionen im EEPROM, an denen die Region und die Checksumme stehen, werden, wie in den Atheros-Datenblättern angegeben, von iwleeprom anhand der „short eeprom base“ berechnet. In den Anleitungen wird dagegen immer von fixen Positionen ausgegangen. Diese mögen für viele Karten passen, für meine jedoch nicht.

So ging’s dann – Pin 7 des EEPROMs ist bereits gekappt:

  1. iwleeprom runterladen und mit „make“ bauen
  2. Alle Kernelmodule deren Name mit „ath“ beginnt, mit „rmmod <Modulname>“ entladen
  3. PCI-Geräteadresse der WLAN-Karte mit lspci rausfinden. Bei mir: „02:00.0“
  4. WLAN-Karte mit Hilfe der PCI-Geräteadresse initialisieren: ./iwleeprom -d 0000:02:00.0 -I
  5. EEPROM auslesen und in Datei speichern: ./iwleeprom -d 0000:02:00.0 -o original.rom
  6. EEPROM analysieren:
    ./iwleeprom -n -F ath9300 -i original.rom -s

    Nach der Zeile „ath9300 short eeprom base“ suchen. Bei mit steht da: „ath9300 short eeprom base: 465 (0x01d1) size: 559“. Die „465“ merken, an diese Stelle kommt später die EEPROM-Checksumme.
    Nach der Zeile „Reg. domain“ suchen. Bei mir steht da: „Reg. domain : 0021 001f“. Die „21“ merken, das ist die aktuelle Regdomain die geändert werden soll.
  7. Reg. domain ändern:
    Mit einem Hex-Editor die Datei „original.rom“ öffnen und ganz nah am Ende der Datei nach „21“ (die „Reg. domain“ von oben) suchen. Bei mir stand sie an Position 1005 (dezimal) bei einer Dateilänge von „original.rom“ von 1024 – also wirklich fast am Ende.
    Die „21“ ändern zu „37“ und die Datei speichern als „modified.rom“. Die „37“ ist die Region „ETSI1_WORLD“ und sollte überall in Europa passen.
  8. Neue CRC herausfinden:
    Um sicherzustellen dass das EEPROM nicht beschädigt ist verwendet Atheros eine Prüfsumme. Da wir das EEPROM-Image eben geändert haben müssen wir die Prüfsumme ebenfalls anpassen.
    ./iwleeprom -n -F ath9300 -i modified.rom -s zeigt in der Zeile „CRC (stored)“ die Prüfsumme an,  die im EEPROM steht und in der Zeile „CRC (eval)“ die, die im EEPROM stehen müsste.
    Bei mir steht in „CRC (eval)“ „9f78“
  9. Neue CRC speichern:
    Die bei „CRC (eval)“ angezeigte Prüfsumme in „modified.rom“ eintragen. Entweder per Hex-Editor oder einfach mit echo -ne '\x9f\x78' | dd of=modified.rom bs=1 seek=465 count=2 conv=notruncrom
    ‚\x9f\x78‘ ist mein „CRC (eval)“ „9f78“
    Die Position (seek) ist die in Schritt 6 herausgefundenen „short eeprom base“, bei mir „465“
  10. EEPROM-Image prüfen mit ./iwleeprom -n -F ath9300 -i modified.rom -s
    Die „Reg. domain“ sollte auf „0037 001f“ stehen und „CRC (eval)“ den gleichen Wert wie „CRC (stored)“ haben.
  11. Flashen: ./iwleeprom -d 0000:02:00.0 -i modified.rom
    (Wie oben beschrieben ging das wegen meiner zahlreichen Fehlversuchen bei mir nicht mehr, ich musste ich das Flashen im EEPROM-Programmiergerät erledigen.)

Das ath9k-Kernelmodul verortet die WLAN-Karte ab jetzt korrekt in Europa, genauer in Albanien. Das ist jedoch egal, da dank EU bzw. ETSI in Albanien für WLAN die selben Regeln wie in Deutschland gelten. 5 GHz-WLAN geht jetzt mit 20 dBm.