forcedeth net driver: reverse mac address after pxe boot

Alex Owen
2006-10-04T16:19:22Z

I an issue with the forcedeth driver when used after the BIOS PXE routines.
When booting directly from disk the ethernet MAC address is normal.
eg: 00:16:17:xx:yy:zz
But is the BIOS PXE boot stack loads pxelinux which then boots the
local disk, or if pxelinux loads a kernel/initrd, then the MAC address
detected by the forcedeth linux driver is reversed.
eg zz:yy:xx:17:16:00

This is obviously causes me a problem with automated installs started
via PXE boot as the installed cannot DHCP as the MAC address is wrong.

I have read some of the bug reports and LKML threads on WOL and
forcedeth and I have looked at the code of the driver... most closely
forcedeth v57 as per comment #22 of
http://bugzilla.kernel.org/show_bug.cgi?id=6604

My understanding of the code is that the driver determines the cards
MAC address by reading from registers in the ethernet controller, but
that for reasons best known to nvidia this address backwards and so
the driver "fixes" this by itself reversing the read values and
writing them back to the controller.

This normally works ok and there has been some work to put the old
"wrong" MAC address back at close down to get WOL to work to.

Enter PXE... Booting from PXE (in BIOS) seems to "fixup" the "wrong"
MAC address so when the driver determines the cards MAC address by
reading from registers in the ethernet controller then MAC address
there is now CORRECT. The driver however assumes it is reversed and in
trying to "fix" the MAC address is infact writes back the
revesed/broken MAC back to the controller.

The obvious fix for this is to try and read the MAC address from the
canonical location... ie where is the source of the address writen
into the controlers registers at power on? But do we know where that
may be?

The other solution would be unconditionally reset the controler to
it's power on state then use the current logic? can we reset the
controller via software?
There does seem to be an nv_mac_reset function... and this does seem
to be called if the card has a capability DEV_HAS_POWER_CONTROL but it
is called in nv_open() while the MAC is read in nv_probe().

Perhaps we need to unconditionally run nv_mac_reset just before
reading the MAC in nv_probe() ?

Anyway I hope that someone who knows kernel internals and this driver
inparticular feels the urge to look at this!

Thanks for reading this far!
Alex Owen