January 18, 2026

Kyu - the U-boot MDIO command

I boot up my H5 system, type space to interrupt the boot. This give me the U-boot prompt.

My interest is to investigate the "mdio" and "mii" commands.
First I type these commands to investigate "mdio" --

mdio
mdio - MDIO utility commands

Usage:
mdio list			- List MDIO buses
mdio read  [.] - read PHY's register at .
mdio write  [.]  - write PHY's register at .
mdio rx  [.] - read PHY's extended register at .
mdio wx  [.]  - write PHY's extended register at .
 may be:
     
   
   
 , and  may be ranges, e.g. 1-5.4-0x1f.

=> mdio list
ethernet@1c30000:
1 - Generic PHY <--> ethernet@1c30000
Also (to my surprise) there is an "mii" command
=> mii
mii - MII utility commands

Usage:
mii device                            - list available devices
mii device                   - set current device
mii info                        - display MII PHY info
mii read                   - read  MII PHY  register 
mii write            - write MII PHY  register 
mii modify     - modify MII PHY  register 
                                        updating bits identified in 
mii dump                   - pretty-print   (0-5 only)
Addr and/or reg may be ranges, e.g. 2-7.
=> mii device
MII devices: 'ethernet@1c30000'
Current device: 'ethernet@1c30000'
=> mii info 1
PHY 0x01: OUI = 0x0732, Model = 0x11, Rev = 0x05,  10baseT, HDX
=> mii info 0
PHY 0x00: OUI = 0x0732, Model = 0x11, Rev = 0x05, 1000baseT, FDX
Of particular interest is getting two different speeds from Mii-1 and Mii-0. This will require investigation. I know my board is connected to my ethernet switch at 1000 Mbit. I go back and check, and the 10baseT status has vanished. => mii info 0 PHY 0x00: OUI = 0x0732, Model = 0x11, Rev = 0x05, 1000baseT, FDX => mii info 1 PHY 0x01: OUI = 0x0732, Model = 0x11, Rev = 0x05, 1000baseT, FDX

As we have learned already from the device tree, the Realtek RTL8211E PHY chip does not need a special driver, but is supported by the generic Phy code in drivers/net/phy/phy.c

The "mdio" command is implemented in the file cmd/mdio.c and the "mii" command in the file cmd/mii.c.

Why both mdio and mii?

We have the mii command (clause 22) and the mdio command (clause 45). Clause 45 is an extension which is not supported by old devices. The addressing method is different. It would be cumbersome to create a single command that handles both.

More from mii

The following post gives us some other ideas:
=> mii dump 1 0
0.     (1140)                 -- PHY control register --
  (8000:0000) 0.15    =     0	  reset
  (4000:0000) 0.14    =     0	  loopback
  (2040:0040) 0. 6,13 =   b10    speed selection = 1000 Mbps
  (1000:1000) 0.12    =     1	  A/N enable
  (0800:0000) 0.11    =     0	  power-down
  (0400:0000) 0.10    =     0	  isolate
  (0200:0000) 0. 9    =     0	  restart A/N
  (0100:0100) 0. 8    =     1	  duplex = full
  (0080:0000) 0. 7    =     0	  collision test enable
  (003f:0000) 0. 5- 0 =     0	  (reserved)

=> mii dump 1 1
1.     (796d)                 -- PHY status register --
  (8000:0000) 1.15    =     0	  100BASE-T4 able
  (4000:4000) 1.14    =     1	  100BASE-X  full duplex able
  (2000:2000) 1.13    =     1	  100BASE-X  half duplex able
  (1000:1000) 1.12    =     1	  10 Mbps    full duplex able
  (0800:0800) 1.11    =     1	  10 Mbps    half duplex able
  (0400:0000) 1.10    =     0	  100BASE-T2 full duplex able
  (0200:0000) 1. 9    =     0	  100BASE-T2 half duplex able
  (0100:0100) 1. 8    =     1	  extended status
  (0080:0000) 1. 7    =     0	  (reserved)
  (0040:0040) 1. 6    =     1	  MF preamble suppression
  (0020:0020) 1. 5    =     1	  A/N complete
  (0010:0000) 1. 4    =     0	  remote fault
  (0008:0008) 1. 3    =     1	  A/N able
  (0004:0004) 1. 2    =     1	  link status
  (0002:0000) 1. 1    =     0	  jabber detect
  (0001:0001) 1. 0    =     1	  extended capabilities

=> mii dump 1 2
2.     (001c)                 -- PHY ID 1 register --
  (ffff:001c) 2.15- 0 =    28	  OUI portion


=> mii dump 1 3
3.     (c915)                 -- PHY ID 2 register --
  (fc00:c800) 3.15-10 =    50	  OUI portion
  (03f0:0110) 3. 9- 4 =    17	  manufacturer part number
  (000f:0005) 3. 3- 0 =     5	  manufacturer rev. number

=> mii dump 1 4
4.     (01e1)                 -- Autonegotiation advertisement register --
  (8000:0000) 4.15    =     0	  next page able
  (4000:0000) 4.14    =     0	  (reserved)
  (2000:0000) 4.13    =     0	  remote fault
  (1000:0000) 4.12    =     0	  (reserved)
  (0800:0000) 4.11    =     0	  asymmetric pause
  (0400:0000) 4.10    =     0	  pause enable
  (0200:0000) 4. 9    =     0	  100BASE-T4 able
  (0100:0100) 4. 8    =     1	  100BASE-TX full duplex able
  (0080:0080) 4. 7    =     1	  100BASE-TX able
  (0040:0040) 4. 6    =     1	  10BASE-T   full duplex able
  (0020:0020) 4. 5    =     1	  10BASE-T   able
  (001f:0001) 4. 4- 0 =     1	  selector = IEEE 802.3 CSMA/CD

=> mdio read 0 0
0 is not a known ethernet
Reading from bus ethernet@1c30000
PHY at address 0:
0 - 0x1140

mdio read 0 1
0 is not a known ethernet
Reading from bus ethernet@1c30000
PHY at address 0:
1 - 0x796d
So clearly the "mdio read" command is reading the same registers as the "mii" command, but the mii command gives very nice displays of the registers.
cd cmd
wc mii.c mdio.c
  478  1875 13480 mii.c
  333  1001  7243 mdio.c

What about the RK3328 with two network interfaces

I thought this might be educational, because the board has two network interfaces. Maybe each will be set up as a separate MDIO bus. This is not the case.
I try it first without any network cables connected to the board. Here is what I get:
=> mdio list
mdio:
=> mii device
MII devices: 'mdio'
Current device: 'mdio'
=> mii info
PHY 0x00: OUI = 0x13D47A, Model = 0x11, Rev = 0x0B,  10baseT, HDX
PHY 0x01: OUI = 0x13D47A, Model = 0x11, Rev = 0x0B,  10baseT, HDX
Not at all what I expected. But I plug in a cable (into the interface away from the power connector). I reset the board, then I try a "ping 192.168.0.5" to trigger autonegotiation. Now I see:
=> ping 192.168.0.5
ethernet@ff540000 Waiting for PHY auto negotiation to complete...... done
Speed: 1000, full duplex

=> mdio list
mdio_register: non unique device name 'mdio'
mdio:
0 - YT8531 Gigabit Ethernet <--> ethernet@ff540000
=> mii device
MII devices: 'mdio'
Current device: 'mdio'
=> mii info
PHY 0x00: OUI = 0x13D47A, Model = 0x11, Rev = 0x0B, 1000baseT, FDX
PHY 0x01: OUI = 0x13D47A, Model = 0x11, Rev = 0x0B, 1000baseT, FDX
Plugging the cable into the other interface (next to the power jack) is useless. U-boot still tries to use the other connector and this fails with a timeout (since it is trying to autonegotiate without a cable and a peer at the other end).


Have any comments? Questions? Drop me a line!

Tom's electronics pages / tom@mmto.org