Adding new, undocumented features into a kernel driver
Sat, May 27, 2017Note: this is a recollection of my memory (and source files) from about 2 years ago

How would I go about changing the MAC address (permanently) on this AX88179 USB 3.0 device without breaking it open?
I found myself with an unusual challenge - the MAC address of many networking devices, if not already burnt into One-Time Programmable memory, could possibly be stored in an external (rewritable) EEPROM. Breaking open the device and directly accessing the EEPROM would be trivial, however I was unwilling to scuff the glossy plastic enclosure; I sought to do this without dismantling the device.
Understanding the target: ASIX AX88179

The first order of business is grabbing the datasheet to answer some preliminary questions:
- Does it use an EEPROM?
- How is the EEPROM memory laid out? Any checksums?
- Can the EEPROM be written in-system, without external aid?
- Do they already offer a tool to modify the hardware MAC?
After a loginwall, we have some preliminary answers:
- Yes, it has an EEPROM, along with an OTP EFuse. A valid EEPROM takes precedence during initialization.
- First 6 bytes store the MAC Address. There’s also a checksum
- Although not explicitly stated, EEPROM can be written to without aid (during manufacturing).
- They have a Windows tool to configure and test devices during manufacturing. However it is unavailable for mere mortals like me (“please email sales”)
The 41-page datasheet documents the AX88179 extremely well, however it was completely devoid of information pertaining to writing of the EEPROM. It seemed as though this was a sacred privilege reserved only for manufacturers : (
Can the drivers access the EEPROM?

ASIX kindly offers a “non-blobby” Linux driver sources on their portal which builds flawlessly out of the box. Muchas gracias!
When initializing the device, the drivers require access to information such as the MAC address, and it may be possible that the device offers some EEPROM access during this phase. While there’s a good chance that the manufacturer might have already implemented a specific command to simply return the 6 bytes, one can still hope for direct EEPROM access!

The ASIX driver interacts with the hardware mostly through passing commands to ax88179_read_cmd and ax88179_write_cmd, which are essentially read/write wrappers around usb_control_msg.
Within ax88179_178a.c lies a very interesting function access_eeprom_mac, which indeed directly accesses the EEPROM!
- When
wflagisfalse, it tries to read the MAC, one byte at a time from the EEPROM, and setsdev->net->dev_addrafterwards. - When
wflagistrue, it tries to write the MAC, one byte at a time to the EEPROM and waits for 15ms. It then reloads the new EEPROM data afterwards.
It seems that the key to writing the EEPROM is ax88179_write_cmd, with command AX_ACCESS_EEPROM with the desired data, followed by the AX_RELOAD_EEPROM_EFUSE command.
The curiously missing commands in the headers
Where did the commands 0x07 and 0x08 go?
The ax88179_178a.h header lists the constants associated with its respective commands. Oddly, before the undocumented EFuse Enable/Disable, there seemed to be 2 missing commands. Could they be for EEPROM Enable/Disable? The chip itself did not appear to have a EEPROM write-protect pin, but it could have an internal flag to prevent spurious writes.
For good measure, I added these to the header:
#define AX_WRITE_EEPROM_EN 0x07
#define AX_WRITE_EEPROM_DIS 0x08
Kludging it all together
It’s an one-time use driver - the code doesn’t look good
ax88179_178a.c
eepromBytesToWrite contains the value to write (CA FE) - note the endianness. eepromWriteAddress for the write address. Inserted above ax88179_get_mac
In ax88179_bind, inserted above /* Get the MAC address */
ax88179_178a.h
Inserted between AX_RELOAD_EEPROM_EFUSE and AX_WRITE_EFUSE_EN
Using it
makeshould happily emit aax88179_178a.ko.insmod ax88179_178a.koto load the driver, writing the EEPROMrmmod ax88179_178ato unload the driverdmesgto check if it worked! It should hopefully contain a “eeprom write completed”
That’s it! EEPROM writes for a mortal. Remember to unload or blacklist any existing ax88179 drivers first before trying the patched driver!.
Apart from the MAC, I intended to change the Device/Manufacturer name too. It is super exciting to plug the device onto a fresh Windows PC and have it recognize “my” hardware. Now I can pass off as a NIC vendor :^)