/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyreset */ static void bgmac_phy_reset(struct bgmac *bgmac) { if (bgmac->phyaddr == BGMAC_PHY_NOREGS) return; bgmac_phy_write(bgmac, bgmac->phyaddr, MII_BMCR, BMCR_RESET); udelay(100); if (bgmac_phy_read(bgmac, bgmac->phyaddr, MII_BMCR) & BMCR_RESET) bgmac_err(bgmac, "PHY reset failed\n"); bgmac_phy_init(bgmac); }
/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyadvertise */ static void bgmac_phy_advertise(struct bgmac *bgmac) { u16 adv; if (bgmac->phyaddr == BGMAC_PHY_NOREGS) return; if (!bgmac->autoneg) return; /* Adv selected 10/100 speeds */ adv = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV); adv &= ~(BGMAC_PHY_ADV_10HALF | BGMAC_PHY_ADV_10FULL | BGMAC_PHY_ADV_100HALF | BGMAC_PHY_ADV_100FULL); if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_10) adv |= BGMAC_PHY_ADV_10HALF; if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_100) adv |= BGMAC_PHY_ADV_100HALF; if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_10) adv |= BGMAC_PHY_ADV_10FULL; if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_100) adv |= BGMAC_PHY_ADV_100FULL; bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV, adv); /* Adv selected 1000 speeds */ adv = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV2); adv &= ~(BGMAC_PHY_ADV2_1000HALF | BGMAC_PHY_ADV2_1000FULL); if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_1000) adv |= BGMAC_PHY_ADV2_1000HALF; if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_1000) adv |= BGMAC_PHY_ADV2_1000FULL; bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV2, adv); /* Restart */ bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL, bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL) | BGMAC_PHY_CTL_RESTART); }
/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyforce */ static void bgmac_phy_force(struct bgmac *bgmac) { u16 ctl; u16 mask = ~(BGMAC_PHY_CTL_SPEED | BGMAC_PHY_CTL_SPEED_MSB | BGMAC_PHY_CTL_ANENAB | BGMAC_PHY_CTL_DUPLEX); if (bgmac->phyaddr == BGMAC_PHY_NOREGS) return; if (bgmac->autoneg) return; ctl = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL); ctl &= mask; if (bgmac->full_duplex) ctl |= BGMAC_PHY_CTL_DUPLEX; if (bgmac->speed == BGMAC_SPEED_100) ctl |= BGMAC_PHY_CTL_SPEED_100; else if (bgmac->speed == BGMAC_SPEED_1000) ctl |= BGMAC_PHY_CTL_SPEED_1000; bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL, ctl); }
static int bgmac_mii_read(struct mii_bus *bus, int mii_id, int regnum) { return bgmac_phy_read(bus->priv, mii_id, regnum); }