if_ate handles the bytes of the MAC address in a "wrong" order

Björn König bkoenig at alpha-tierchen.de
Fri Jun 8 19:59:05 UTC 2007


M. Warner Losh wrote:

> We use the following code:
> 	low = RD4(sc, ETH_SA1L);
> 	high =  RD4(sc, ETH_SA1H);
> 	if ((low | (high & 0xffff)) == 0)
> 		return (ENXIO);
> 	eaddr[0] = (high >> 8) & 0xff;
> 	eaddr[1] = high & 0xff;
> 	eaddr[2] = (low >> 24) & 0xff;
> 	eaddr[3] = (low >> 16) & 0xff;
> 	eaddr[4] = (low >> 8) & 0xff;
> 	eaddr[5] = low & 0xff;
>
> which does look like it is wrong, based on what the text says.

These are the register contents during execution of U-Boot:

U-Boot> md fffbc098 8
fffbc098: 00000000 00000000 3ac25000 000051b4    .........P.:.Q..
fffbc0a8: 00000000 00000000 00000000 00000000    ................

ETH_SA2L = 3ac25000
ETH_SA2H = 000051b4

Our code makes the address 51:b4:3a:c2:50:00. The Linux code looks like this

     addr[0] = (lo & 0xff);
     addr[1] = (lo & 0xff00) >> 8;
     addr[2] = (lo & 0xff0000) >> 16;
     addr[3] = (lo & 0xff000000) >> 24;
     addr[4] = (hi & 0xff);
     addr[5] = (hi & 0xff00) >> 8;

and we would get the MAC address 00:50:c2:3a:b4:51. It may be important
that Linux makes a case differentiation because there is at least one boot
loader out there that stores the MAC address exactly the other way round:

     addr[0] = (hi & 0xff00) >> 8;
     addr[1] = (hi & 0xff);
     addr[2] = (lo & 0xff000000) >> 24;
     addr[3] = (lo & 0xff0000) >> 16;
     addr[4] = (lo & 0xff00) >> 8;
     addr[5] = (lo & 0xff);

with the comment "The CSB337 bootloader stores the MAC the wrong-way around."

The code is from linux-2.6.21/drivers/net/arm/at91_ether.c line 385ff.

Regards
nröjB




More information about the freebsd-arm mailing list