diff options
Diffstat (limited to 'drivers/net/usb/lan78xx.c')
-rw-r--r-- | drivers/net/usb/lan78xx.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 120e99914fd6..d6a71c051ec1 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c | |||
@@ -74,6 +74,8 @@ | |||
74 | #define LAN7801_USB_PRODUCT_ID (0x7801) | 74 | #define LAN7801_USB_PRODUCT_ID (0x7801) |
75 | #define LAN78XX_EEPROM_MAGIC (0x78A5) | 75 | #define LAN78XX_EEPROM_MAGIC (0x78A5) |
76 | #define LAN78XX_OTP_MAGIC (0x78F3) | 76 | #define LAN78XX_OTP_MAGIC (0x78F3) |
77 | #define AT29M2AF_USB_VENDOR_ID (0x07C9) | ||
78 | #define AT29M2AF_USB_PRODUCT_ID (0x0012) | ||
77 | 79 | ||
78 | #define MII_READ 1 | 80 | #define MII_READ 1 |
79 | #define MII_WRITE 0 | 81 | #define MII_WRITE 0 |
@@ -920,11 +922,9 @@ static int lan78xx_read_otp(struct lan78xx_net *dev, u32 offset, | |||
920 | ret = lan78xx_read_raw_otp(dev, 0, 1, &sig); | 922 | ret = lan78xx_read_raw_otp(dev, 0, 1, &sig); |
921 | 923 | ||
922 | if (ret == 0) { | 924 | if (ret == 0) { |
923 | if (sig == OTP_INDICATOR_1) | 925 | if (sig == OTP_INDICATOR_2) |
924 | offset = offset; | ||
925 | else if (sig == OTP_INDICATOR_2) | ||
926 | offset += 0x100; | 926 | offset += 0x100; |
927 | else | 927 | else if (sig != OTP_INDICATOR_1) |
928 | ret = -EINVAL; | 928 | ret = -EINVAL; |
929 | if (!ret) | 929 | if (!ret) |
930 | ret = lan78xx_read_raw_otp(dev, offset, length, data); | 930 | ret = lan78xx_read_raw_otp(dev, offset, length, data); |
@@ -1147,7 +1147,7 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) | |||
1147 | { | 1147 | { |
1148 | struct phy_device *phydev = dev->net->phydev; | 1148 | struct phy_device *phydev = dev->net->phydev; |
1149 | struct ethtool_link_ksettings ecmd; | 1149 | struct ethtool_link_ksettings ecmd; |
1150 | int ladv, radv, ret; | 1150 | int ladv, radv, ret, link; |
1151 | u32 buf; | 1151 | u32 buf; |
1152 | 1152 | ||
1153 | /* clear LAN78xx interrupt status */ | 1153 | /* clear LAN78xx interrupt status */ |
@@ -1155,9 +1155,12 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) | |||
1155 | if (unlikely(ret < 0)) | 1155 | if (unlikely(ret < 0)) |
1156 | return -EIO; | 1156 | return -EIO; |
1157 | 1157 | ||
1158 | mutex_lock(&phydev->lock); | ||
1158 | phy_read_status(phydev); | 1159 | phy_read_status(phydev); |
1160 | link = phydev->link; | ||
1161 | mutex_unlock(&phydev->lock); | ||
1159 | 1162 | ||
1160 | if (!phydev->link && dev->link_on) { | 1163 | if (!link && dev->link_on) { |
1161 | dev->link_on = false; | 1164 | dev->link_on = false; |
1162 | 1165 | ||
1163 | /* reset MAC */ | 1166 | /* reset MAC */ |
@@ -1170,7 +1173,7 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) | |||
1170 | return -EIO; | 1173 | return -EIO; |
1171 | 1174 | ||
1172 | del_timer(&dev->stat_monitor); | 1175 | del_timer(&dev->stat_monitor); |
1173 | } else if (phydev->link && !dev->link_on) { | 1176 | } else if (link && !dev->link_on) { |
1174 | dev->link_on = true; | 1177 | dev->link_on = true; |
1175 | 1178 | ||
1176 | phy_ethtool_ksettings_get(phydev, &ecmd); | 1179 | phy_ethtool_ksettings_get(phydev, &ecmd); |
@@ -1457,9 +1460,14 @@ static int lan78xx_set_eee(struct net_device *net, struct ethtool_eee *edata) | |||
1457 | 1460 | ||
1458 | static u32 lan78xx_get_link(struct net_device *net) | 1461 | static u32 lan78xx_get_link(struct net_device *net) |
1459 | { | 1462 | { |
1463 | u32 link; | ||
1464 | |||
1465 | mutex_lock(&net->phydev->lock); | ||
1460 | phy_read_status(net->phydev); | 1466 | phy_read_status(net->phydev); |
1467 | link = net->phydev->link; | ||
1468 | mutex_unlock(&net->phydev->lock); | ||
1461 | 1469 | ||
1462 | return net->phydev->link; | 1470 | return link; |
1463 | } | 1471 | } |
1464 | 1472 | ||
1465 | static void lan78xx_get_drvinfo(struct net_device *net, | 1473 | static void lan78xx_get_drvinfo(struct net_device *net, |
@@ -2044,7 +2052,7 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) | |||
2044 | if (dev->domain_data.phyirq > 0) | 2052 | if (dev->domain_data.phyirq > 0) |
2045 | phydev->irq = dev->domain_data.phyirq; | 2053 | phydev->irq = dev->domain_data.phyirq; |
2046 | else | 2054 | else |
2047 | phydev->irq = 0; | 2055 | phydev->irq = PHY_POLL; |
2048 | netdev_dbg(dev->net, "phydev->irq = %d\n", phydev->irq); | 2056 | netdev_dbg(dev->net, "phydev->irq = %d\n", phydev->irq); |
2049 | 2057 | ||
2050 | /* set to AUTOMDIX */ | 2058 | /* set to AUTOMDIX */ |
@@ -3607,6 +3615,12 @@ static int lan78xx_probe(struct usb_interface *intf, | |||
3607 | 3615 | ||
3608 | dev->maxpacket = usb_maxpacket(dev->udev, dev->pipe_out, 1); | 3616 | dev->maxpacket = usb_maxpacket(dev->udev, dev->pipe_out, 1); |
3609 | 3617 | ||
3618 | /* Reject broken descriptors. */ | ||
3619 | if (dev->maxpacket == 0) { | ||
3620 | ret = -ENODEV; | ||
3621 | goto out4; | ||
3622 | } | ||
3623 | |||
3610 | /* driver requires remote-wakeup capability during autosuspend. */ | 3624 | /* driver requires remote-wakeup capability during autosuspend. */ |
3611 | intf->needs_remote_wakeup = 1; | 3625 | intf->needs_remote_wakeup = 1; |
3612 | 3626 | ||
@@ -4001,6 +4015,10 @@ static const struct usb_device_id products[] = { | |||
4001 | /* LAN7801 USB Gigabit Ethernet Device */ | 4015 | /* LAN7801 USB Gigabit Ethernet Device */ |
4002 | USB_DEVICE(LAN78XX_USB_VENDOR_ID, LAN7801_USB_PRODUCT_ID), | 4016 | USB_DEVICE(LAN78XX_USB_VENDOR_ID, LAN7801_USB_PRODUCT_ID), |
4003 | }, | 4017 | }, |
4018 | { | ||
4019 | /* ATM2-AF USB Gigabit Ethernet Device */ | ||
4020 | USB_DEVICE(AT29M2AF_USB_VENDOR_ID, AT29M2AF_USB_PRODUCT_ID), | ||
4021 | }, | ||
4004 | {}, | 4022 | {}, |
4005 | }; | 4023 | }; |
4006 | MODULE_DEVICE_TABLE(usb, products); | 4024 | MODULE_DEVICE_TABLE(usb, products); |