April 9, 2026

Allwinner H5 network driver -- Unify h5 and h3 source for Kyu

I left this in somewhat of a mess. I copied the files from the h3 directory to the h5 directory, then began editing with wild abandon. Now I would like to reconcile the two versions and have one driver source.

The "h3" directory has these 3 files:

wc emac*
 1547  6546 41403 emac.c
  809  3788 22507 emac_phy.c
  127   578  3847 emac_regs.h

The "h5" directory has these 4 files:

wc *emac*
 1389  5919 37714 emac.c
  444  1984 12058 emac_phy.c
  127   534  3474 emac_regs.h
   42   229  1457 emac_syscon.c
I want to move a set of files into the "allwinner" directory that can be shared for both chips, and then make symlinks from each chip directory as I have done for other h3/h5 peripherals.

emac_regs.h

Sharing emac_regs.h should be a simple starting point. I can introduce my "vu32" typedef for "volatile unsigned int" and go from there.
One thing pops up and that is this:

// volatile void * tx_desc;
    vu32 tx_desc;       /* 20 */
Using a "void *" was fine for the 32 bit ARM in the h3, but on the 64 bit ARM in the h5 this becomes a 64 bit object and throws all subsequent structure offsets out of whack. To share this header file with the current h3 driver will require some code changes in the file emac.c

The compiler whines and gives warnings. On these systems addresses are in fact always 32 bits in size -- but pointers on arm64 are held in 64 bit objects. So the upper 32 bits are always zeros, but the compiler doesn't know, hence the warnings.

emac_syscon.c

When working with the h5, I split out the syscon register access into a separate file. I will either have to do the same split for h3 or put it back into the file emac.c for both. I am undecided right now, but am inclined to view any changes in the h5 directory as "the most up-to-date" and the guiding light for what I want to do.

I decide that I will indeed place this into its own file and share it. The value placed into this register must be different for the h5 and this is crucial. The h5 uses and external PHY (the Realtek 8211), while the h3 used an internal PHY. The bit to determine which one is used is in this syscon register.

This business of a single register outside of the normal emac registers has the smell of a last minute addition. My guess is that Allwinner decided at some point to include the internal PHY as a cost saving measure for some clients, and this required the control provided by the syscon register.

emac_phy.c

Here there is a significant amount of code that I need to merge and clean up. Two routines (read and write) provide MDIO access via emac registers. The rest of the code in this file is not emac specific, and could be reused for other hardware give MDIO read/write routines for that hardware.

A bit of code cleanup and proper setup of the syscon register lets me access the 8211, which I verify by reading the pair of chip ID bytes. I will need to write new code to support gigabit operation. The internal PHY is only 10/100 capable.


Have any comments? Questions? Drop me a line!

Tom's electronics pages / tom@mmto.org