Da der ursprüngliche Beitrag bereits geschlossen ist, sich aber gerade ältere Boxen hervorragend zum Experimentieren eignen, möchte ich an diesen Beitrag mit einer Lösung für die dort beschriebenen Netzwerkprobleme im Qemu-Gast anknüpfen.
Basierend auf der Version FRITZ.Box_Fon_WLAN_7170.29.04.88 lässt sich ein freetz image mit replace kernel für die 7170v1 so bauen, dass der avm_cpmac Treiber ein paar mehr Meldungen als üblich ausspuckt. Führt man nach dem Start auf der Konsole im Qemu-Gast
aus, erhält man Fehler der Art
wobei die 81 als Länge des jeweils verworfenen IP-Pakets variiert. Da an qemu keine -net Optionen an der Kommandozeile übergeben wurden, ist standardmäßig das SLiRP user network backend aktiv.
Die Fehlermeldung als Resultat auf die ping-Anfrage offenbart, dass der TCP/IP stack dieses user mode backends antwortet. Andernfalls würde cpmac_if_data_from_phy nicht aufgerufen werden. Aber der Aufruf scheitert, denn die Funktion verwirft das IP-Paket mit dem obskuren no 802.1 Fehler. Nachgeschlagen in cpmac_if.c finden sich die Fehlerbedingungen:
VLAN auf den cpmac Schnittstelle(n) wird von multid aktiviert und konfiguriert. Die Emulation des cpmac-Treibers in der auf 0.9.0 basierenden qemu-Variante von spblinux.de ist unvollständig, was sich u.a. dadurch bemerkbar macht, dass die bei der VLAN-Konfiguration beschriebenen (emulierten) Hardware-Register leer bleiben und nicht den Inhalt bewahren, den multid hineinschreibt. (Reale Hardware führt in Abhängigkeit der Registeränderungen Funktionen aus, weswegen es mit einfacher Speicherung des Werts für eine Emulation nicht getan ist.)
enable_vlan z.B. ist aber eine Option die im RAM der emulierten Maschine gesetzt wird und vom Funktionieren der (Switch-)Registeremulation unabhängig ist. D.h. während große Teile der Datenstrukturen des Treibers so verändert werden wie auf realer Hardware, erfolgen einige Änderungen aus Sicht des Qemu-Gasts nicht, die sonst durch IO-Schreibzugriffe auf Hardwarekomponenten korrekt erfolgen.
Eine schnelle Lösung für dieses Problem ist, ankommenden ungetaggten Paketen das passende VLAN-Tag zu verleihen, bevor sie weiterverarbeitet werden. Das bewerkstelligt der u.a. Patch.
Eine gute Lösung wäre, wesentlich aufwändiger, die fehlende Logik beim Beschreiben der Switch-Register der CPMAC-Emulation im qemu-ar7 port zu ergänzen.
Es gibt ein aktuelles Repo mit dem qemu ar7 code, das zwar kompilierbar ist, aber das hier erzeugte flashimage.bin nicht emulierte. Die Ursachensuche erfolgte da nur kurz, zugunsten der älteren qemu-Variante.
Hypothetisch: Ein weiterer Lösungsversuch ohne Kernelmodifikation (d.h. REPLACE_KERNEL) könnte evtl. mit cpmaccfg oder cpmacconfig bestehen, um die Schnittstellen alternativ zum multid ohne aktives VLAN hochzubringen.
EDIT: Offensichtlich funktioniert das nur, wenn der Switch-Treiber im read/write 32 bit mode arbeitet, der Patch wurde dazu ergänzt (wenn bootloader code einer Box mit einer anderen HWRevision verwendet wird, sollte die 94 entsprechend angepasst werden).
Auf allen 7170 Boxen mit einer punktseparierten HWRevision (94.x.x.x) läuft der Switch-Treiber sonst im 16 bit mode (betrifft Breite der Switchregister, die über den MDIO-Bus steuerbar sind). Diese Registerbreite wird laut Datenblatt z.B. für den ADM6996LC Switch-Chip in der 7170v1 per Hardware-Pin beim Chip-Reset festgelegt.
Basierend auf der Version FRITZ.Box_Fon_WLAN_7170.29.04.88 lässt sich ein freetz image mit replace kernel für die 7170v1 so bauen, dass der avm_cpmac Treiber ein paar mehr Meldungen als üblich ausspuckt. Führt man nach dem Start auf der Konsole im Qemu-Gast
Code:
ifconfig lan 10.0.2.15
ping 10.0.2.2
Code:
[cpmac] [cpmac_if_data_from_phy] no 802.1, 81
Die Fehlermeldung als Resultat auf die ping-Anfrage offenbart, dass der TCP/IP stack dieses user mode backends antwortet. Andernfalls würde cpmac_if_data_from_phy nicht aufgerufen werden. Aber der Aufruf scheitert, denn die Funktion verwirft das IP-Paket mit dem obskuren no 802.1 Fehler. Nachgeschlagen in cpmac_if.c finden sich die Fehlerbedingungen:
Wenn enable_vlan (Konfigurationsoption der cpmac0 Schnittstelle) aktiv ist und CPMAC_VLAN_IS_802_1Q_FRAME(x) (Testmakro, ob das Paket vlan-tagging besitzt) fehlschlägt.
(.. dann wird das Paket durch diese Funktion verworfen)
(.. dann wird das Paket durch diese Funktion verworfen)
VLAN auf den cpmac Schnittstelle(n) wird von multid aktiviert und konfiguriert. Die Emulation des cpmac-Treibers in der auf 0.9.0 basierenden qemu-Variante von spblinux.de ist unvollständig, was sich u.a. dadurch bemerkbar macht, dass die bei der VLAN-Konfiguration beschriebenen (emulierten) Hardware-Register leer bleiben und nicht den Inhalt bewahren, den multid hineinschreibt. (Reale Hardware führt in Abhängigkeit der Registeränderungen Funktionen aus, weswegen es mit einfacher Speicherung des Werts für eine Emulation nicht getan ist.)
enable_vlan z.B. ist aber eine Option die im RAM der emulierten Maschine gesetzt wird und vom Funktionieren der (Switch-)Registeremulation unabhängig ist. D.h. während große Teile der Datenstrukturen des Treibers so verändert werden wie auf realer Hardware, erfolgen einige Änderungen aus Sicht des Qemu-Gasts nicht, die sonst durch IO-Schreibzugriffe auf Hardwarekomponenten korrekt erfolgen.
Eine schnelle Lösung für dieses Problem ist, ankommenden ungetaggten Paketen das passende VLAN-Tag zu verleihen, bevor sie weiterverarbeitet werden. Das bewerkstelligt der u.a. Patch.
Eine gute Lösung wäre, wesentlich aufwändiger, die fehlende Logik beim Beschreiben der Switch-Register der CPMAC-Emulation im qemu-ar7 port zu ergänzen.
Es gibt ein aktuelles Repo mit dem qemu ar7 code, das zwar kompilierbar ist, aber das hier erzeugte flashimage.bin nicht emulierte. Die Ursachensuche erfolgte da nur kurz, zugunsten der älteren qemu-Variante.
Hypothetisch: Ein weiterer Lösungsversuch ohne Kernelmodifikation (d.h. REPLACE_KERNEL) könnte evtl. mit cpmaccfg oder cpmacconfig bestehen, um die Schnittstellen alternativ zum multid ohne aktives VLAN hochzubringen.
Code:
--- linux-2.6.13/drivers/net/avm_cpmac/cpmac_if.c
+++ linux-2.6.13/drivers/net/avm_cpmac/cpmac_if.c
@@ -133,6 +133,20 @@
/*--- DEB_TRC("[cpmac_if_data_from_phy] %u %:24B ... \n", skb->len, skb->data); ---*/
+# ifdef QEMU_AR7_CPMAC__ACCEPT_UNTAGGED
+ if(cpmac_priv->enable_vlan && !CPMAC_VLAN_IS_802_1Q_FRAME(skb->data)) {
+ struct avm_new_switch_struct *status = &(cpmac_priv->cppi->mdio->switch_status);
+ unsigned short vid = status->port[status->cpu_port].vid;
+ DEB_WARN("[%s] untagged data of length %u, tagging with VID %#x\n", __FUNCTION__, skb->len, vid);
+ skb = __vlan_put_tag(skb, vid);
+ if(!skb) {
+ DEB_WARN("[%s] dropped untagged data, because tagging failed\n", __FUNCTION__);
+ ((struct cpmac_devinfo *) (p_dev->priv))->stats.rx_dropped++;
+ return CPMAC_ERR_DROPPED;
+ }
+ }
+# endif
+
/* Discard big packets and packets with length 0 */
if( (length > 1522)
|| ( (length > 1518)
--- linux-2.6.13/drivers/net/avm_cpmac/cpphy_adm6996.c
+++ linux-2.6.13/drivers/net/avm_cpmac/cpphy_adm6996.c
@@ -1315,6 +1315,9 @@
if(hwrev && ( !(strncmp("79", hwrev, 2)) /* 3070 with ADM6996L */
|| !(strncmp("84", hwrev, 2)) /* 2070 with ADM6996L */
+# ifdef QEMU_AR7_CPMAC__ACCEPT_UNTAGGED
+ || !(strncmp("94", hwrev, 2)) /* 7170 with ADM6996L */
+# endif
)
) {
DEB_INFO("switch works in read/write 32 bit mode\n");
--- linux-2.6.13/drivers/net/avm_cpmac/Makefile.26
+++ linux-2.6.13/drivers/net/avm_cpmac/Makefile.26
@@ -6,6 +6,21 @@
EXTRA_CFLAGS := -DCPMAC_SIGNAL_CONGESTION -DCPPHY_USE_SWITCH -Wall -Wextra
+# tested to work with spblinux.de/fbox/tmp/x86/qemu-system-mipsel.new (0.9.0)
+# and mtd2 (bootloader) dump retrieved via ADAM2 FTP from 7170 v1 hardware
+#
+# fixes `ping 10.0.2.2` failure after `ifconfig lan 10.0.2.15` symptom
+#
+# fixes `[cpmac] [cpmac_if_data_from_phy] no 802.1, ..` messages
+# seen if FRITZ.Box_Fon_WLAN_7170.29.04.88.image is freetzed with
+# enabled DEB_* macros found in drivers/net/avm_cpmac/cpmac_debug.h
+# (requires REPLACE_KERNEL)
+#
+## intended for testing router firmware in qemu with e.g. user mode network
+## _not_ meant for production builds (DISABLE before flashing to real hw)
+#
+EXTRA_CFLAGS += -DQEMU_AR7_CPMAC__ACCEPT_UNTAGGED
+
# declare multi-module main driver.
obj-$(CONFIG_AVM_CPMAC) += avm_cpmac.o
EDIT: Offensichtlich funktioniert das nur, wenn der Switch-Treiber im read/write 32 bit mode arbeitet, der Patch wurde dazu ergänzt (wenn bootloader code einer Box mit einer anderen HWRevision verwendet wird, sollte die 94 entsprechend angepasst werden).
Auf allen 7170 Boxen mit einer punktseparierten HWRevision (94.x.x.x) läuft der Switch-Treiber sonst im 16 bit mode (betrifft Breite der Switchregister, die über den MDIO-Bus steuerbar sind). Diese Registerbreite wird laut Datenblatt z.B. für den ADM6996LC Switch-Chip in der 7170v1 per Hardware-Pin beim Chip-Reset festgelegt.
Zuletzt bearbeitet: