lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Mon, 29 Aug 2016 09:32:23 -0400 From: robert.foss@...labora.com To: freddy@...x.com.tw, Dean_Jenkins@...tor.com, Mark_Craske@...tor.com, davem@...emloft.net, robert.foss@...labora.com, ivecera@...hat.com, john.stultz@...aro.org, vpalatin@...omium.org, stephen@...workplumber.org, grundler@...omium.org, changchias@...il.com, allan@...x.com.tw, andrew@...n.ch, tremyfr@...il.com, colin.king@...onical.com, linux-usb@...r.kernel.org, netdev@...r.kernel.org, linux-kernel@...r.kernel.org, vpalatin@...gle.com Subject: [PATCH v3 4/5] net: asix: see 802.3 spec for phy reset From: Grant Grundler <grundler@...omium.org> https://lkml.org/lkml/2014/11/11/947 Ben Hutchings is correct. IEEE 802.3 spec section "22.2.4.1.1 Reset" requires up to 500ms delay. Mitigate the "max" delay by polling the phy until BCM_RESET bit is clear. Signed-off-by: Grant Grundler <grundler@...omium.org> Signed-off-by: Robert Foss <robert.foss@...labora.com> Tested-by: Robert Foss <robert.foss@...labora.com> --- drivers/net/usb/asix_devices.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 083dc2e..dbcdda2 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c @@ -212,6 +212,28 @@ static const struct net_device_ops ax88172_netdev_ops = { .ndo_set_rx_mode = ax88172_set_multicast, }; +static void asix_phy_reset(struct usbnet *dev, unsigned int reset_bits) +{ + unsigned int timeout = 5000; + + asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, reset_bits); + + /* give phy_id a chance to process reset */ + udelay(500); + + /* See IEEE 802.3 "22.2.4.1.1 Reset": 500ms max */ + while (timeout--) { + if (asix_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR) + & BMCR_RESET) + udelay(100); + else + return; + } + + netdev_err(dev->net, "BMCR_RESET timeout on phy_id %d\n", + dev->mii.phy_id); +} + static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) { int ret = 0; @@ -258,7 +280,7 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->needed_headroom = 4; /* cf asix_tx_fixup() */ dev->net->needed_tailroom = 4; /* cf asix_tx_fixup() */ - asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); + asix_phy_reset(dev, BMCR_RESET); asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); mii_nway_restart(&dev->mii); @@ -900,8 +922,7 @@ static int ax88178_reset(struct usbnet *dev) } else if (data->phymode == PHY_MODE_RTL8211CL) rtl8211cl_phy_init(dev); - asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, - BMCR_RESET | BMCR_ANENABLE); + asix_phy_reset(dev, BMCR_RESET | BMCR_ANENABLE); asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); asix_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000, -- 2.7.4
Powered by blists - more mailing lists