static void brgphy_setmedia(struct mii_softc *sc, int media) { int bmcr = 0, gig; switch (IFM_SUBTYPE(media)) { case IFM_2500_SX: break; case IFM_1000_SX: case IFM_1000_T: bmcr = BRGPHY_S1000; break; case IFM_100_TX: bmcr = BRGPHY_S100; break; case IFM_10_T: default: bmcr = BRGPHY_S10; break; } if ((media & IFM_FDX) != 0) { bmcr |= BRGPHY_BMCR_FDX; gig = BRGPHY_1000CTL_AFD; } else { gig = BRGPHY_1000CTL_AHD; } /* Force loopback to disconnect PHY from Ethernet medium. */ brgphy_enable_loopback(sc); PHY_WRITE(sc, BRGPHY_MII_1000CTL, 0); PHY_WRITE(sc, BRGPHY_MII_ANAR, BRGPHY_SEL_TYPE); if (IFM_SUBTYPE(media) != IFM_1000_T && IFM_SUBTYPE(media) != IFM_1000_SX) { PHY_WRITE(sc, BRGPHY_MII_BMCR, bmcr); return; } if (IFM_SUBTYPE(media) == IFM_1000_T) { gig |= BRGPHY_1000CTL_MSE; if ((media & IFM_ETH_MASTER) != 0) gig |= BRGPHY_1000CTL_MSC; } PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig); PHY_WRITE(sc, BRGPHY_MII_BMCR, bmcr | BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG); }
static void brgphy_setmedia(struct mii_softc *sc, int media, int master) { struct brgphy_softc *bsc = (struct brgphy_softc *)sc; int bmcr = 0, gig; /* Calculate the value for the BMCR register. */ switch (IFM_SUBTYPE(media)) { case IFM_2500_SX: break; case IFM_1000_SX: case IFM_1000_T: bmcr = BRGPHY_S1000; break; case IFM_100_TX: bmcr = BRGPHY_S100; break; case IFM_10_T: default: bmcr = BRGPHY_S10; break; } /* Calculate duplex settings for 1000BasetT/1000BaseX. */ if ((media & IFM_GMASK) == IFM_FDX) { bmcr |= BRGPHY_BMCR_FDX; gig = BRGPHY_1000CTL_AFD; } else { gig = BRGPHY_1000CTL_AHD; } /* Force loopback to disconnect PHY for Ethernet medium. */ brgphy_enable_loopback(sc); /* Disable 1000BaseT advertisements. */ PHY_WRITE(sc, BRGPHY_MII_1000CTL, 0); /* Disable 10/100 advertisements. */ PHY_WRITE(sc, BRGPHY_MII_ANAR, BRGPHY_SEL_TYPE); /* Write forced link speed. */ PHY_WRITE(sc, BRGPHY_MII_BMCR, bmcr); /* If 10/100 only then configuration is complete. */ if ((IFM_SUBTYPE(media) != IFM_1000_T) && (IFM_SUBTYPE(media) != IFM_1000_SX)) goto brgphy_setmedia_exit; /* Set duplex speed advertisement for 1000BaseT/1000BaseX. */ PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig); /* Restart auto-negotiation for 1000BaseT/1000BaseX. */ PHY_WRITE(sc, BRGPHY_MII_BMCR, bmcr | BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG); /* If not 5701 PHY then configuration is complete. */ if (bsc->mii_model != MII_MODEL_xxBROADCOM_BCM5701) goto brgphy_setmedia_exit; /* * When setting the link manually, one side must be the master and * the other the slave. However ifmedia doesn't give us a good way * to specify this, so we fake it by using one of the LINK flags. * If LINK0 is set, we program the PHY to be a master, otherwise * it's a slave. */ if (master) { PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig | BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC); } else { PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig | BRGPHY_1000CTL_MSE); } brgphy_setmedia_exit: return; }