Hi all. This post is to report status. At the moment I'm comparing GMACs registers between u-boot initialization booting vs. automatic booting. Definitively there is a difference - probably ag71xx OpenWRT's drive isn't doing all necessary register settings while on other devices a lot of init is done in bootloader.
Below little recipe to dump registers form the SoC (requires devmemenabled in OpenWRT build)
Registers dump how to
# change dir to /tmp while it allows files write
$ cd /tmp
# create list of registers you want to dump (space separated <reg_name> and <reg_address_in_hex>
$ cat <<eof > regs.txt
> RST_RESET 0x1806001C
> RST_REVISION_ID 0x18060090
> RST_BOOTSTRAP 0x180600B0
> ETH_CFG 0x18070000
> GMAC0_MAC_CFG1 0x19000000
> GMAC0_MAC_CFG2 0x19000004
> GMAC0_MAC_ADDR1 0x19000040
> GMAC0_MAC_ADDR2 0x19000044
> GMAC0_FIFO_CFG0 0x19000048
> GMAC1_MAC_CFG1 0x1A000000
> GMAC1_MAC_CFG2 0x1A000004
> GMAC1_MAC_ADDR1 0x1A000040
> GMAC1_MAC_ADDR2 0x1A000044
> GMAC1_FIFO_CFG0 0x1A000048
> eof
# dump registers to stdout by this little inline while loop
$ \
printf '\n' ;\
while read -r REG ADDR <&3; do \
printf '%s: ' "$ADDR"; devmem $ADDR | xargs printf '%s'; printf '\t// %s\n' $REG; \
done 3< regs.txt
I started going down that road, with a slightly different approach. I instrumented the ag71xx driver to log the values during probe. When I did that, I realised that in the interrupted boot case, the switch0 device appears before there is even any attempt to probe ag71xx, but in the auto-boot case, where is no switch0 device, so the problem, I think, goes beyond the ag71xx driver - something has to happen to initialise the switch (first).... unless that somehow magically happens when ag71xx does the right thing. I did try stuffing values into those registers during the probe, but it didn't seem to make any difference.
How did you "instrument" this driver? I was thinking about it while there are debug register dumps, but was unsure how to force it.
EDIT As per my observation the problem lies in fact that GEMACs are not released upon reset, therefore mdio probing (communication to/from phys fails in ag71xx_probe() function in ag71xx_main.c. I see that having switch on is side effect of u-boot inits while it initializes both phy4 and switch with phy0..3.
I was wondering that number of reset and initialization registers aren't at all setup in OpenWRT code (at least I couldn't find it).
Actually, after deeper code analysis I found out that peripheral reset is pretty well controlled by DTS and its reset bindings. Looking more precisely into RST_RESET register it looks that GE0_MAC_RESET and RESET_GE1_MDIO are de-asserted what is consistent with what we declared in DTS files.
EDIT
When you decipher RST_RESET content (no init) you will find out that some elements of ethernet subsystem are held in reset state - probably that could be reason while mdio init fails
RST_RESET = 0x2040B9F0
0: b23: RESET_GE1_MDIO
1: b22: RESET_GE0_MDIO
1: b13: GE1_MAC_RESET
1: b12: ETH_SWITCH_ARESET
0: b9: GE0_MAC_RESET
1: b8: ETH_SWITCH_RESET
ETH_CFG = 0x00002000
1: b13: SW_ACC_MSB_FIRST // this bit is clear for u-boot init
I just hacked at build_dir/target-mips_24kc_musl/linux-ath79_generic/linux-5.15.85/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c - changed some instances of DBG() to pr_err() (so it would be visible without turning on full debug (noisy!)), and added some more pr_err() calls with things I wanted to see, and recompiled. To attempt to set registers, I added calls like ag71xx_wr(ag, AG71XX_REG_MAC_IPG, 0x40605060); (with values observed from the case where everything works - not especially scientific!)
Hi there. Just to report (little) progress. I've made build6c with hot-fix for ETH_CFG register init (0x0000000), but it doesn't solve problem yet. I next steps will try to put quick and dirty fix for RST_RESET (clear ethernet switch reset bits) and GMAC0_MAC_CFG2 (set magic 0x01 on b9.8 as per documentation). If this won't fly we need to find a way to make ag71xx as loadable module to enable dynamic register changes and re-probing the module, while making separate builds for any register modification won't be convenient.
Q: How to make build where ag71xx driver is loadable module?
Hi, did you progress? Any findings? I didn't move much while had no time lastly. My next step will be to build with ag71xx as loadable module to ease pokiing withregisters - but don't know yet how to make such build
No progress here. I was waiting to see if you got anywhere with implementing the needed initialisation. My "plan B" is to use the u-boot binary copied from a CPE210v3 (already know that this works).
I did have a quick try at building ag71xx as a loadable module, but I ran into a symbol issue, and not quite sure how to get around it...
Hi @Dseven and others.
Just posting to acknowledge I still don't give up - just had no time lastly to move forward. At the moment trying to identify what is right init of QCA eth subsystem registers. Good news is I found u-boot sources in @pepe2ku-boot mod - a lot of code to analyze and reverse engineer to find out right registers initialization values.
OK. FWIW, my build in conjunction with the u-boot binary from the CPE210v3 has been working fine. I haven't actually put either of my EAP110's into service yet, but may be making the Outdoor one into a mesh node very soon.
I was going to follow this to provide some dumps of an eap 110-outdoor v1 to whoever would benefit. I have a problem that I don't have a writable directory. /bin/logdump doesn't exist on my system. Is there a known process to trigger it's creation?