diff options
Diffstat (limited to 'drivers/net/usb/asix_devices.c')
-rw-r--r-- | drivers/net/usb/asix_devices.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 083dc2ef10c8..dbcdda2ebb18 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 = { | |||
212 | .ndo_set_rx_mode = ax88172_set_multicast, | 212 | .ndo_set_rx_mode = ax88172_set_multicast, |
213 | }; | 213 | }; |
214 | 214 | ||
215 | static void asix_phy_reset(struct usbnet *dev, unsigned int reset_bits) | ||
216 | { | ||
217 | unsigned int timeout = 5000; | ||
218 | |||
219 | asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, reset_bits); | ||
220 | |||
221 | /* give phy_id a chance to process reset */ | ||
222 | udelay(500); | ||
223 | |||
224 | /* See IEEE 802.3 "22.2.4.1.1 Reset": 500ms max */ | ||
225 | while (timeout--) { | ||
226 | if (asix_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR) | ||
227 | & BMCR_RESET) | ||
228 | udelay(100); | ||
229 | else | ||
230 | return; | ||
231 | } | ||
232 | |||
233 | netdev_err(dev->net, "BMCR_RESET timeout on phy_id %d\n", | ||
234 | dev->mii.phy_id); | ||
235 | } | ||
236 | |||
215 | static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) | 237 | static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) |
216 | { | 238 | { |
217 | int ret = 0; | 239 | int ret = 0; |
@@ -258,7 +280,7 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) | |||
258 | dev->net->needed_headroom = 4; /* cf asix_tx_fixup() */ | 280 | dev->net->needed_headroom = 4; /* cf asix_tx_fixup() */ |
259 | dev->net->needed_tailroom = 4; /* cf asix_tx_fixup() */ | 281 | dev->net->needed_tailroom = 4; /* cf asix_tx_fixup() */ |
260 | 282 | ||
261 | asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); | 283 | asix_phy_reset(dev, BMCR_RESET); |
262 | asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, | 284 | asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, |
263 | ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); | 285 | ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); |
264 | mii_nway_restart(&dev->mii); | 286 | mii_nway_restart(&dev->mii); |
@@ -900,8 +922,7 @@ static int ax88178_reset(struct usbnet *dev) | |||
900 | } else if (data->phymode == PHY_MODE_RTL8211CL) | 922 | } else if (data->phymode == PHY_MODE_RTL8211CL) |
901 | rtl8211cl_phy_init(dev); | 923 | rtl8211cl_phy_init(dev); |
902 | 924 | ||
903 | asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, | 925 | asix_phy_reset(dev, BMCR_RESET | BMCR_ANENABLE); |
904 | BMCR_RESET | BMCR_ANENABLE); | ||
905 | asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, | 926 | asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, |
906 | ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); | 927 | ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); |
907 | asix_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000, | 928 | asix_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000, |