(note: could have asked this on the net ML or device tree ML but the kn list has a lot of smart people so i'll throw it out here and hope for the best.) from poking around PHY drivers lately, i can see how a PHY driver can register to accept a wildcarded PHY ID pattern from a device tree source file. here's an example from asix.c: #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, } }; module_phy_driver(asix_driver); static struct mdio_device_id __maybe_unused asix_tbl[] = { { PHY_ID_ASIX_AX88796B, 0xfffffff0 }, { } }; so that represents a vendor (asix) whose precise PHY types are distinguished by the value in the last nybble. what this means (as i read it) is that, when creating a .dts file for a system, one would put *precisely* the PHY ID in the .dts file, and the wildcarding in the driver would be used to associate that entry with the appropriate driver so that, in the above, any PHY ID value of the form 0x003b184X (X being the low-order nybble) would map to this driver, correct? in addition, once the mdio_device_id array defines the PHY ID patterns compatible with this driver, the phy_driver array defines, based on the *actual* PHY ID, how to initialize for that specific PHY type, and that is based on the fact that the device tree source files provide the *exact* PHY type. does all this sound right so far? because here's the extra complication, so i've phrased it as a kind of puzzle. say i want to build an 8-port switch using PHYs from the acme corporation of coyote falls, arizona. acme has four different PHYs with different speeds, with the precise PHY IDs: 0x1234.5671 1G 0x1234.5672 2.5G 0x1234.5675 5G 0x1234.567A 10G but here's the problem. imagine i've been given a bucket of these PHYs and they are absolutely indistinguishable visually -- the only way to tell them apart is, when the system powers up, the driver can read a PHY's H/W register which contains the exact PHY ID of one of four possible values as above. other than that, i have this bucket of PHYs and i reach in, grab eight PHYs at random, and just bolt them into my switch. some will be 1G, some 2.5G, and so on -- any combination is possible -- so how do i handle this? first, it's obvious that i can't put precise PHY IDs in my device tree source file since i have no idea what type will be at each PHY address across different switches. the best i can do is just put in a matching wildcard pattern, so in the .dts file, all eight PHY definitions will have entries of the form: compatible = "ethernet-phy-id1234.5670" the above simply identifies that it's a PHY from acme, and it's only purpose is to get me to the appropriate driver. (as i see it, the last nybble could be any value from 0 to F since it's not relevant but let's leave it at 0 for now.) on the driver side, i would define a single mdio_device_id as above: #define PHY_ID_ACME 0x12345670 static struct mdio_device_id acme_tbl[] = { { PHY_ID_ACME, 0xfffffff0 }, { } } ; again, in the above, i can't possibly refine the wildcarding any further since the actual PHY ID value from the device tree does not distinguish between the four PHY types. once again, so far, so good? now here's where i'm unclear, as one would normally define an array of phy_drivers that match the possible wildcarding, as in for the asix example above: 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, } }; but as i understand it (and i might be completely wrong), these entries are based on matching that must be distinguishable from the precise PHY ID value in the .dts tree, is that right? what this means (and, again, i could be wrong) is that if i *had* a device tree that specified the precise acme PHYs at each address, i could define four exact matches, one for each PHY type: .phy_id = 0x1234.5671 .name = "Acme 1G PHY" .phy_id_mask = 0xffffffff .phy_id = 0x1234.5672 .name = "Acme 2.5G PHY" .phy_id_mask = 0xffffffff ... etc etc ... and the phy_driver matching would be done based on the exact PHY_ID for that PHY. but recall that my device tree source file does not have that info -- only the generic acme corp identifier 0x1234.5670. so, as i understand it, i can't define four different phy_driver entries, because that precise information is simply not available to me *at* *this* *time*. as i read it (and this is what i want to confirm), all of the wildcarding used in defining the phy_driver entries must be available from the PHY ID values in the device tree. and since i don't have that, i can really define only a single phy_driver entry that still encompasses all of the possible acme PHY types. is that correct? in the end, as i read it, given the scenario i've presented, it seems that i can define only one level of wildcarding, with one phy_driver entry that covers all that wildcarding, and all i can do is wait until i get into the driver init routines to finally read the PHY's H/W register to determine which of the four PHYs it is. i ask this as someone suggested that, no, even in this case, i can define four phy_driver entries, one to match each *exact* PHY ID, but i don't see how that's possible given that the exact PHY ID isn't available until i read the H/W register. so am i misunderstanding something here? anyway, didn't mean to go on this long but i wanted to make sure i explained this properly. thoughts, anyone? rday -- ======================================================================== Robert P. J. Day Ottawa, Ontario, CANADA http://crashcourse.ca/dokuwiki Twitter: http://twitter.com/rpjday LinkedIn: http://ca.linkedin.com/in/rpjday ======================================================================== _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies