Any pointers for reading switch 32bit registers for qca8337?

I have a qca9558 SoC + qca8337 switch device, and want to read the switch registers to see how it is wired and configured from OEM firmware (have root shell). This is to compare the values to datasheets to work out how to configure the switch driver from OpenWRT.

This switch has 32bit registers for most data.

Does anyone know of a tool to read these qca 32bit registers over MDIO, or should I cobble something together?

Any advice would be great!


I did get phytool and mdio-tool cross compiled statically and running, but they only access the 16 bit registers.

Compiled with:

export PATH=/mnt/openwrt/openwrt/staging_dir/host/bin:$PATH
export PATH="/mnt/openwrt/openwrt/staging_dir/$toolchain/bin":$PATH
export STAGING_DIR="/mnt/openwrt/openwrt/staging_dir/$toolchain"

make CC=mips-openwrt-linux-musl-gcc CFLAGS="-static -static-libgcc" LDFLAGS="-static -static-libgcc"
ldd phytool

$STAGING_DIR/bin/mips-openwrt-linux-musl-gcc -static -static-libgcc mdio-tool.c -o mdio-tool
ldd mdio-tool


I seem to be able to use the math the drivers do, to read these 32bit registers using phytool.

From linux qca8k, with my notes…

	regaddr >>= 1;
	/* discard the last (2) bits, 1 here, 1 in zeroed r1) */

	r1 = regaddr & 0x1e;
	/* MDIOc22 REG address:
	 * last 6 bits of register address,
	 * with last discarded, and next zeroed (for low register access)
	 * +1 for register high bit access (bits with values 16-31 of register). */

	regaddr >>= 5;
	r2 = regaddr & 0x7;
	/* MDIOc22 PHY address:
	 * bits 7 through 9 of register address
	 * (always 0b10 in front of the 3 register address bits (phyaddr | 0x10)) */

	regaddr >>= 3;
	page = regaddr & 0x3ff;
	/* Write high addess: (MDIOc22 PHY address 0x18, REG address 0)
	 * write data of: bits 10 through 19 of register address */

I added a read32 function to phytool to do this, but it can be done manually:

#./phytool-mips $operation $device/$phyaddr/$regaddr $write_value
#example: (global) PORT0_PAD_CTRL 0x0004
./phytool-mips write eth0/0x18/0x0 0
./phytool-mips read eth0/0x10/0x2
./phytool-mips read eth0/0x10/0x3

/flash/rw/pckg # ./phytool-mips read32 eth0/0x0/0x4
#device: eth0 PHYaddr:0x18 REGaddr:0x0 write: 0x0
#device: eth0 PHYaddr:0x10 REGaddr:0x2 read: 0x0
#device: eth0 PHYaddr:0x10 REGaddr:0x3 read: 0x740

#high register examples:
/flash/rw/pckg # ./phytool-mips read32 eth0/0x0/0x420
#Creating socket
#device: eth0 PHYaddr:0x18 REGaddr:0x0 write: 0x2
#device: eth0 PHYaddr:0x10 REGaddr:0x10 read: 0x1
#device: eth0 PHYaddr:0x10 REGaddr:0x11 read: 0x1

/flash/rw/pckg # ./phytool-mips read32 eth0/0x0/0x800
#Creating socket
#device: eth0 PHYaddr:0x18 REGaddr:0x0 write: 0x4
#device: eth0 PHYaddr:0x10 REGaddr:0x0 read: 0x188
#device: eth0 PHYaddr:0x10 REGaddr:0x1 read: 0x120

Have been using busybox devmem to read the SoC registers:

# Ethernet configuration
/flash/rw/pckg/busybox-links # devmem 0x18070000

>>> bin(0x00148001)

1<<0	1 RGMII_EN
1<<15	10 15:14ETH_RXD_DELAY
1<<18	01 19:18ETH_TXD_DELAY
1<<20	01 21:20ETH_TXEN_DELAY

My little python function for printing bits:

def prettyprint_bin( number ):
  bit = 0
  while True:
    rem = number >> bit
    if rem <= 0:
    bitvalue = int(bin(rem)[-1])
    if (bitvalue > 0):
      print("{}<<{}".format(bitvalue, bit))
    bit = bit + 1

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.