With the growing popularity of SoCs, external PHYs are making a bit of
a comeback.  In quite a few cases I'm seeing rgephy(4) show up twice,
once on address 0 and once on some other address.  But there is only
one PHY soldered onto the board.  This is a little bit annoying but
mostly harmless.  The mii(4) layer will use the first one that shows
up and everything works.  But now I'm seeing the same thing happening
with a Micrel PHY that shows up as ukphy(4).  And here it is causing
issues since the mii(4) attempts to "isolate" PHYs that it isn't using
and the Micrel PHY actually implements that functionality.

One way to solve the issue is to add the MIIF_NOISOLATE flag to the
mii_attach() call.  However that still means the PHY shows up twice in
dmesg.  So here is an alternative solution.  The mii_attach() function
has an offloc argument that kan be used to tell the mii(4) layer to
attach the first, second, third, etc. PHY it finds when scanning the
bus.  The diff below makes dwge(4) set offloc to 0 (to attach the
first PHY found) if phyloc is set to MII_PHY_ANY.  This means we
attach the PHY with address 0 instead of its real address, but that is
ok.

This code is a little bit ugly.  An alternative would be to modify
mii_attach(4) such that it no longer panics if phyloc != MII_PHY_ANY
and offloc != MII_OFFSET_ANY.  Then we could simply set offloc to 0 in
the mii_attach() call.

comments? ok?


Index: dev/ic/dwc_gmac.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/dwc_gmac.c,v
retrieving revision 1.8
diff -u -p -r1.8 dwc_gmac.c
--- dev/ic/dwc_gmac.c   29 Jun 2017 17:36:16 -0000      1.8
+++ dev/ic/dwc_gmac.c   4 Apr 2018 09:47:29 -0000
@@ -222,8 +222,8 @@ dwc_gmac_attach(struct dwc_gmac_softc *s
 
        ifmedia_init(&mii->mii_media, 0, dwc_gmac_ifmedia_upd,
            dwc_gmac_ifmedia_sts);
-       mii_attach((void *)sc, mii, 0xffffffff, phyloc, MII_OFFSET_ANY,
-           MIIF_DOPAUSE);
+       mii_attach((void *)sc, mii, 0xffffffff, phyloc,
+           (phyloc == MII_PHY_ANY) ? 0 : MII_OFFSET_ANY, MIIF_DOPAUSE);
 
        if (LIST_EMPTY(&mii->mii_phys)) {
                printf("%s: no PHY found!\n", sc->sc_dev.dv_xname);

Reply via email to