03-30-2021 10:57 AM
I am patching the Xilinx MACB driver to retrieve the MAC address from NVRAM instead of generating a random one when it is initialized. This requires the MACB driver to use i2c on our custom board. However, in the kernel initialization stage, I can see that the i2c driver is not loaded until after the macb driver.
How can I set the macb driver to depend on the i2c driver, so that it is loaded after it? Preferably at build time.
This is on Petalinux 2019.1. Our embedded system is loosely based on the ZCU106 model.
03-30-2021 05:03 PM
You can modify the probe() method of the macb drive to return -EPROBE_DEFER when the I2C bus is not yet available. The kernel will then retry at a later time. More info at https://www.kernel.org/doc/html/latest/driver-api/driver-model/driver.html#callbacks
Alternatively, you could do this from userspace. The MAC address can be retrieved from I2C device (if it is an eeprom, you can access it via sysfs) and then use "ifconfig eth0 hwaddr 00:11:22:33:44:55" to set the MAC address before doing "ifconfig eth0 up". So basically you modify the init scripts that setup networking.
03-30-2021 05:05 PM
Already setting the proper MAC in user space, but the randomly generated MAC from the kernel initialization stage is causing issues, which is why I want to control it earlier.
Thanks for the DEFER tip, that might be what I am looking for.
04-06-2021 12:41 PM
Would you know how to go about the DEFER approach? I'm not sure how to check for the i2c driver from within the kernel module code. And could I even import the i2c files before making that check?
04-06-2021 05:54 PM
The NVRAM device on your I2C bus presumably has a driver with its own probe() routine. Once this probe() completes successfully, the NVRAM device is ready for use. So, this is the "trigger" that you want to know about.
As a crude hack, you could add a global variable, which defaults to 0. At the end of the NVRAM driver probe() routine, set the global to 1. Meanwhile in the macb driver probe() method, you can access the same global variable - just declare it as "extern". As long as the value is 0, return -EPROBE_DEFER. When the value is 1, then let the macb probe() continue as normal.
Of course this is not a recommend approach. There are better (more complicated) methods to signal between independent drivers. But really in this case I think the best solution is to avoid the problem: instead of trying to fix Linux, could you arrange for the bootloader (u-boot) to read the I2C device, and pass the proper MAC address via device tree to Linux?