(totally willing to embarrass myself further, this time with respect to inconsistency in basic terminology in the kernel files.)
from include/linux/mod_devicetable.h: /** * struct mdio_device_id - identifies PHY devices on an MDIO/MII bus * @phy_id: The result of * (mdio_read(&MII_PHYSID1) << 16 | mdio_read(&PHYSID2)) & @phy_id_mask * for this PHY type * @phy_id_mask: Defines the significant bits of @phy_id. A value of 0 * is used to terminate an array of struct mdio_device_id. */ struct mdio_device_id { __u32 phy_id; __u32 phy_id_mask; }; stop right there ... ignoring the obvious typo in "&PHYSID2" (should of course be "&MII_PHYSID2"), the definition of "phy_id" is puzzling, as it's defined as the full 32-bit value with the mask applied to it. is that right? is the technical definition of phy_id the value *after* the phy_id_mask is applied to the register contents? because that certainly seems inconsistent with most explanations i've seen. the definition of phy_id_mask compounds the confusion, as it's defined as "the significant bits of @phy_id". and the earlier definition defines phy_id as the masked value of "this PHY type". so now there is a PHY "type" in addition to a PHY "ID"? and the above doesn't even mesh with a random sample driver file i looked at -- asix.c -- which contains: #define PHY_ID_ASIX_AX88796B 0x003b1841 ... snip ... static struct phy_driver asix_driver[] = { { .phy_id = PHY_ID_ASIX_AX88796B, .name = "Asix Electronics AX88796B", .phy_id_mask = 0xfffffff0, .features = PHY_BASIC_FEATURES, .soft_reset = asix_soft_reset, } }; where the PHY ID being used is clearly the full 32-bit value *before* the mask is applied. linux networking experts might understand all this as second nature, but the inconsistency in terminology is definitely confusing for people trying to come to terms with this stuff. rday