lan78xx: workaround of forced 100 Full/Half duplex mode error
At forced 100 Full & Half duplex mode, chip may fail to set mode correctly when cable is switched between long(~50+m) and short one. As workaround, set to 10 before setting to 100 at forced 100 F/H mode. Signed-off-by: Woojung Huh <woojung.huh@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
74d79a2e30
commit
14437e3fa2
|
@ -1804,7 +1804,34 @@ static void lan78xx_remove_mdio(struct lan78xx_net *dev)
|
|||
|
||||
static void lan78xx_link_status_change(struct net_device *net)
|
||||
{
|
||||
/* nothing to do */
|
||||
struct phy_device *phydev = net->phydev;
|
||||
int ret, temp;
|
||||
|
||||
/* At forced 100 F/H mode, chip may fail to set mode correctly
|
||||
* when cable is switched between long(~50+m) and short one.
|
||||
* As workaround, set to 10 before setting to 100
|
||||
* at forced 100 F/H mode.
|
||||
*/
|
||||
if (!phydev->autoneg && (phydev->speed == 100)) {
|
||||
/* disable phy interrupt */
|
||||
temp = phy_read(phydev, LAN88XX_INT_MASK);
|
||||
temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_;
|
||||
ret = phy_write(phydev, LAN88XX_INT_MASK, temp);
|
||||
|
||||
temp = phy_read(phydev, MII_BMCR);
|
||||
temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000);
|
||||
phy_write(phydev, MII_BMCR, temp); /* set to 10 first */
|
||||
temp |= BMCR_SPEED100;
|
||||
phy_write(phydev, MII_BMCR, temp); /* set to 100 later */
|
||||
|
||||
/* clear pending interrupt generated while workaround */
|
||||
temp = phy_read(phydev, LAN88XX_INT_STS);
|
||||
|
||||
/* enable phy interrupt back */
|
||||
temp = phy_read(phydev, LAN88XX_INT_MASK);
|
||||
temp |= LAN88XX_INT_MASK_MDINTPIN_EN_;
|
||||
ret = phy_write(phydev, LAN88XX_INT_MASK, temp);
|
||||
}
|
||||
}
|
||||
|
||||
static int lan78xx_phy_init(struct lan78xx_net *dev)
|
||||
|
|
Loading…
Reference in New Issue