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)
|
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)
|
static int lan78xx_phy_init(struct lan78xx_net *dev)
|
||||||
|
Loading…
Reference in New Issue
Block a user