OpenWrt support for TP Link EAP115

Those are host keys - they are used to authenticate the host (server) to clients.

If you want to break into the TP-Link firmware, I'd suggest unpacking the squashfs file-system and placing a public key (for which you have the corresponding private key) in root's authorized_hosts, then building a new squashfs ... and hope it boots (with signature checking disabled, I suppose).

Edit: not sure what sort of overlaying they might be using, so this may or may not work, but it's an avenue to explore...

Sounds like a yet another separate "big" project...

As per QCA953x documentation the ethernet is constructed with two GMACs, ethernet switch and five phys. We "just" need to figure out how our devices tight thees puzzles together :slight_smile:
So far we know that Phy4 is linked to external LAN jack. Question is whether it is linked to the system as stand alone port via GMAC0 or is it part of the switch linked via GMAC1.

What is host and client in this setup. Having this pair (private on EAP and public on my client) can it open connection from my PC to EAP?

I'm certainly no expert on this, but the way I see it (at a high level) is that code would have to be written to do the GMAC setup (that code is apparently present in the TP-Link kernel for these devices, and u-boot for other devices). If you're proposing to write this code, you could write it to setup the GMACs either way, and then lay out your Device Tree to align with your choice.

I still believe the issue is sitting in DTS. I've just found ethernet problem description for CPE510 device. I need to understand it better and compare to our case.

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 devmem enabled 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
Registers dump form manual u-boot booting
[    0.000000] CPU0 revision is: 00019374 (MIPS 24Kc)
[    0.000000] MIPS: machine is TP-Link EAP115 v4
[    0.000000] SoC: Qualcomm Atheros QCA9533 ver 2 rev 0

        --- after u-boot init (manual boot) ---
[    0.893597] switch0: Atheros AR8229 rev. 1 switch registered on mdio.0
[    1.291450] ag71xx 19000000.eth: connected to PHY at mdio.0:1f:04 [uid=004dd042, driver=Generic PHY]
[    1.301725] eth0: Atheros AG71xx at 0xb9000000, irq 4, mode: mii

--- registers dump ---
0x1806001C: 0x200088F0  // RST_RESET
0x18060090: 0x00000160  // RST_REVISION_ID
0x180600B0: 0x00000400  // RST_BOOTSTRAP
0x18070000: 0x00000000  // ETH_CFG
0x19000000: 0x0000000F  // GMAC0_MAC_CFG1
0x19000004: 0x00007114  // GMAC0_MAC_CFG2
0x19000008: 0x40605060  // GMAC0_MAC_IPG
0x1900000c: 0x00A1F037  // GMAC0_MAC_HDX
0x19000010: 0x000005F4  // GMAC0_MAC_MFL
0x19000020: 0x00000002  // GMAC0_MII_CFG
0x19000024: 0x00000000  // GMAC0_MII_CMD
0x19000028: 0x00000000  // GMAC0_MII_ADDR
0x1900002c: 0x00000000  // GMAC0_MII_CTRL
0x19000030: 0x00000000  // GMAC0_MII_STATUS
0x19000034: 0x00000000  // GMAC0_MII_IND
0x19000038: 0x00000000  // GMAC0_MAC_IFCTL
0x19000040: 0x6FA2F9C6  // GMAC0_MAC_ADDR1
0x19000044: 0x84AC0000  // GMAC0_MAC_ADDR2
0x19000048: 0x001D1F00  // GMAC0_FIFO_CFG0
0x1A000000: 0x800C0000  // GMAC1_MAC_CFG1
0x1A000004: 0x00007214  // GMAC1_MAC_CFG2
0x1A000008: 0x40605060  // GMAC1_MAC_IPG
0x1A00000c: 0x00A1F037  // GMAC1_MAC_HDX
0x1A000010: 0x00000600  // GMAC1_MAC_MFL
0x1A000020: 0x00000002  // GMAC1_MII_CFG
0x1A000024: 0x00000000  // GMAC1_MII_CMD
0x1A000028: 0x0000120D  // GMAC1_MII_ADDR
0x1A00002c: 0x00000102  // GMAC1_MII_CTRL
0x1A000030: 0x00000000  // GMAC1_MII_STATUS
0x1A000034: 0x00000000  // GMAC1_MII_IND
0x1A000038: 0x00000000  // GMAC1_MAC_IFCTL
0x1A000040: 0x00000BAD  // GMAC1_MAC_ADDR1
0x1A000044: 0x00030000  // GMAC1_MAC_ADDR2
0x1A000048: 0x001D1F00  // GMAC1_FIFO_CFG0
Automatic boot (no GMAC init in u-boot)
[    0.000000] CPU0 revision is: 00019374 (MIPS 24Kc)
[    0.000000] MIPS: machine is TP-Link EAP115 v4
[    0.000000] SoC: Qualcomm Atheros QCA9533 ver 2 rev 0

[    1.220371] ag71xx 19000000.eth: Could not connect to PHY device. Deferring probe.

--- registers dump ---
0x1806001C: 0x2040B9F0  // RST_RESET
0x18060090: 0x00000160  // RST_REVISION_ID
0x180600B0: 0x00000400  // RST_BOOTSTRAP
0x18070000: 0x00002000  // ETH_CFG
0x19000000: 0x00000005  // GMAC0_MAC_CFG1
0x19000004: 0x00007014  // GMAC0_MAC_CFG2
0x19000008: 0x40605060  // GMAC0_MAC_IPG
0x1900000c: 0x00A1F037  // GMAC0_MAC_HDX
0x19000010: 0x00000000  // GMAC0_MAC_MFL
0x19000020: 0x00000000  // GMAC0_MII_CFG
0x19000024: 0x00000000  // GMAC0_MII_CMD
0x19000028: 0x00000000  // GMAC0_MII_ADDR
0x1900002c: 0x00000000  // GMAC0_MII_CTRL
0x19000030: 0x00000000  // GMAC0_MII_STATUS
0x19000034: 0x00000000  // GMAC0_MII_IND
0x19000038: 0x00000000  // GMAC0_MAC_IFCTL
0x19000040: 0x00000000  // GMAC0_MAC_ADDR1
0x19000044: 0x00000000  // GMAC0_MAC_ADDR2
0x19000048: 0x00141F00  // GMAC0_FIFO_CFG0
0x1A000000: 0x80000000  // GMAC1_MAC_CFG1
0x1A000004: 0x00007000  // GMAC1_MAC_CFG2
0x1A000008: 0x40605060  // GMAC1_MAC_IPG
0x1A00000c: 0x00A1F037  // GMAC1_MAC_HDX
0x1A000010: 0x00000600  // GMAC1_MAC_MFL
0x1A000020: 0x00000002  // GMAC1_MII_CFG
0x1A000024: 0x00000000  // GMAC1_MII_CMD
0x1A000028: 0x00001001  // GMAC1_MII_ADDR
0x1A00002c: 0x00000000  // GMAC1_MII_CTRL
0x1A000030: 0x0000FFFF  // GMAC1_MII_STATUS
0x1A000034: 0x00000000  // GMAC1_MII_IND
0x1A000038: 0x00000000  // GMAC1_MAC_IFCTL
0x1A000040: 0x00000000  // GMAC1_MAC_ADDR1
0x1A000044: 0x00000000  // GMAC1_MAC_ADDR2
0x1A000048: 0x0000001F  // GMAC1_FIFO_CFG0

Obviously there are differences in registers setting which need to be analyzed. At first glance will focus on:

RST_RESET
ETH_CFG
GMACx_MAC_CFG1
GMACx_MAC_CFG2

I need to look how the OpenWRT driver ar71xx copes with these registers and where to put a temporary patch.

Any advice, hints, past experience more than welcome...

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.

--- manual boot  (u-boot init) ---
0x1806001C: 0x200088F0  // RST_RESET
0x18070000: 0x00000000  // ETH_CFG
0x19000004: 0x00007114  // GMAC0_MAC_CFG2
0x1A000004: 0x00007214  // GMAC1_MAC_CFG2

--- auto boot (no init) ---
0x1806001C: 0x2040B9F0  // RST_RESET
0x18070000: 0x00002000  // ETH_CFG
0x19000004: 0x00007014  // GMAC0_MAC_CFG2
0x1A000004: 0x00007000  // GMAC1_MAC_CFG2

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!)

Thank you for hint. I've just found out there is ethtool which reads driver info and also can modify debug level. I'll add it into next build...

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?

1 Like

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 :frowning:

1 Like

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...

ERROR: modpost: "ath79_pll_base" [drivers/net/ethernet/atheros/ag71xx/ag71xx.ko] undefined!

1 Like

I've just unsuccessful built with same compile error :frowning:

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 @pepe2k u-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?

Did you mean /tmp/logdump ? Not sure if /bin/logdump a typo in your post or if that's the actual directory you were looking for...