On Mon, Apr 25, 2016 at 10:22:36PM +0000, woojung....@microchip.com wrote: > From: Woojung Huh <woojung....@microchip.com> > > 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.
Sorry to picking up this old patch. We're using a LAN7801T, with an external TI dp83tc811 PHY... > Signed-off-by: Woojung Huh <woojung....@microchip.com> > --- > drivers/net/usb/lan78xx.c | 29 ++++++++++++++++++++++++++++- > 1 file changed, 28 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c > index 0460b81..f64778a 100644 > --- a/drivers/net/usb/lan78xx.c > +++ b/drivers/net/usb/lan78xx.c > @@ -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); It seems here you are assuming a microchip PHY attached, where the INT_MASK register is at 0x19. In think 0x19 is a reserved register. You better not write to it. Are there some microchips components where the MAC and the PHY are in one chip? Is that combination identifiable by the USB-ID? > + 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); > + } > } regards, Marc -- Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung West/Dortmund | Phone: +49-231-2826-924 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
signature.asc
Description: PGP signature