I need to add a couple of functions that were missing from the review, due to discovery of a SUSPEND/RESUME race during careful code review of my prototype... rather than run this as a separate self-review case, I think its easiest just to update the case here. If anyone would like more complete review let me know.
Essentially, I need to add three functions for mac drivers: /* * mii_reset * * Schedules a reset of the MII bus. Normally not needed, but * can be used to perform a full master reset, including * rescanning for PHYs. This function may be called in any * context except high level interrupt context, but must be * called without any locks held. The reset will probably not * be complete until sometime after the call returns. * * Note that if mii_start has not been called, then the reset * will not be performed until _after_ the MII is started. */ void mii_reset(mii_handle_t mii); /* * mii_suspend * * Suspends monitoring of the MII bus. Normally this is called * as a part of a driver's DDI_SUSPEND handling. On return, the * MII layer is guaranteed not to be executing any code in the * MII entry points. This function may be called in any context * except high level interrupt context, but must be called * without any locks held. */ void mii_suspend(mii_handle_t mii); /* * mii_resume * * Starts monitoring of the MII bus. Normally this is called as * a part of a driver's DDI_RESUME handling. This function may * be called in any context except high level interrupt context, * but must be called without any locks held. */ void mii_resume(mii_handle_t mii); The upshot of these functions is that the MII layer will only be monitoring the MII bus if *both* the MII has been started with mii_start() AND the MII has not been suspended with mii_suspend(). If anyone wants more explanation or details as to why this separation from mii_start() and mii_stop() are necessary, let me know and I'll be happy to provide more explanation. Thanks. - Garrett