aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/smsc75xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/usb/smsc75xx.c')
-rw-r--r--drivers/net/usb/smsc75xx.c240
1 files changed, 237 insertions, 3 deletions
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 376143e8a1aa..b77ae76f4aa8 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -52,6 +52,7 @@
52#define USB_PRODUCT_ID_LAN7500 (0x7500) 52#define USB_PRODUCT_ID_LAN7500 (0x7500)
53#define USB_PRODUCT_ID_LAN7505 (0x7505) 53#define USB_PRODUCT_ID_LAN7505 (0x7505)
54#define RXW_PADDING 2 54#define RXW_PADDING 2
55#define SUPPORTED_WAKE (WAKE_MAGIC)
55 56
56#define check_warn(ret, fmt, args...) \ 57#define check_warn(ret, fmt, args...) \
57 ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); }) 58 ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
@@ -65,6 +66,7 @@
65struct smsc75xx_priv { 66struct smsc75xx_priv {
66 struct usbnet *dev; 67 struct usbnet *dev;
67 u32 rfe_ctl; 68 u32 rfe_ctl;
69 u32 wolopts;
68 u32 multicast_hash_table[DP_SEL_VHF_HASH_LEN]; 70 u32 multicast_hash_table[DP_SEL_VHF_HASH_LEN];
69 struct mutex dataport_mutex; 71 struct mutex dataport_mutex;
70 spinlock_t rfe_ctl_lock; 72 spinlock_t rfe_ctl_lock;
@@ -135,6 +137,30 @@ static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index,
135 return ret; 137 return ret;
136} 138}
137 139
140static int smsc75xx_set_feature(struct usbnet *dev, u32 feature)
141{
142 if (WARN_ON_ONCE(!dev))
143 return -EINVAL;
144
145 cpu_to_le32s(&feature);
146
147 return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
148 USB_REQ_SET_FEATURE, USB_RECIP_DEVICE, feature, 0, NULL, 0,
149 USB_CTRL_SET_TIMEOUT);
150}
151
152static int smsc75xx_clear_feature(struct usbnet *dev, u32 feature)
153{
154 if (WARN_ON_ONCE(!dev))
155 return -EINVAL;
156
157 cpu_to_le32s(&feature);
158
159 return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
160 USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, feature, 0, NULL, 0,
161 USB_CTRL_SET_TIMEOUT);
162}
163
138/* Loop until the read is completed with timeout 164/* Loop until the read is completed with timeout
139 * called with phy_mutex held */ 165 * called with phy_mutex held */
140static int smsc75xx_phy_wait_not_busy(struct usbnet *dev) 166static int smsc75xx_phy_wait_not_busy(struct usbnet *dev)
@@ -578,6 +604,26 @@ static int smsc75xx_ethtool_set_eeprom(struct net_device *netdev,
578 return smsc75xx_write_eeprom(dev, ee->offset, ee->len, data); 604 return smsc75xx_write_eeprom(dev, ee->offset, ee->len, data);
579} 605}
580 606
607static void smsc75xx_ethtool_get_wol(struct net_device *net,
608 struct ethtool_wolinfo *wolinfo)
609{
610 struct usbnet *dev = netdev_priv(net);
611 struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
612
613 wolinfo->supported = SUPPORTED_WAKE;
614 wolinfo->wolopts = pdata->wolopts;
615}
616
617static int smsc75xx_ethtool_set_wol(struct net_device *net,
618 struct ethtool_wolinfo *wolinfo)
619{
620 struct usbnet *dev = netdev_priv(net);
621 struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
622
623 pdata->wolopts = wolinfo->wolopts & SUPPORTED_WAKE;
624 return 0;
625}
626
581static const struct ethtool_ops smsc75xx_ethtool_ops = { 627static const struct ethtool_ops smsc75xx_ethtool_ops = {
582 .get_link = usbnet_get_link, 628 .get_link = usbnet_get_link,
583 .nway_reset = usbnet_nway_reset, 629 .nway_reset = usbnet_nway_reset,
@@ -589,6 +635,8 @@ static const struct ethtool_ops smsc75xx_ethtool_ops = {
589 .get_eeprom_len = smsc75xx_ethtool_get_eeprom_len, 635 .get_eeprom_len = smsc75xx_ethtool_get_eeprom_len,
590 .get_eeprom = smsc75xx_ethtool_get_eeprom, 636 .get_eeprom = smsc75xx_ethtool_get_eeprom,
591 .set_eeprom = smsc75xx_ethtool_set_eeprom, 637 .set_eeprom = smsc75xx_ethtool_set_eeprom,
638 .get_wol = smsc75xx_ethtool_get_wol,
639 .set_wol = smsc75xx_ethtool_set_wol,
592}; 640};
593 641
594static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) 642static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
@@ -756,6 +804,26 @@ static int smsc75xx_set_features(struct net_device *netdev,
756 return 0; 804 return 0;
757} 805}
758 806
807static int smsc75xx_wait_ready(struct usbnet *dev)
808{
809 int timeout = 0;
810
811 do {
812 u32 buf;
813 int ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
814 check_warn_return(ret, "Failed to read PMT_CTL: %d", ret);
815
816 if (buf & PMT_CTL_DEV_RDY)
817 return 0;
818
819 msleep(10);
820 timeout++;
821 } while (timeout < 100);
822
823 netdev_warn(dev->net, "timeout waiting for device ready");
824 return -EIO;
825}
826
759static int smsc75xx_reset(struct usbnet *dev) 827static int smsc75xx_reset(struct usbnet *dev)
760{ 828{
761 struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); 829 struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
@@ -764,6 +832,9 @@ static int smsc75xx_reset(struct usbnet *dev)
764 832
765 netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset"); 833 netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset");
766 834
835 ret = smsc75xx_wait_ready(dev);
836 check_warn_return(ret, "device not ready in smsc75xx_reset");
837
767 ret = smsc75xx_read_reg(dev, HW_CFG, &buf); 838 ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
768 check_warn_return(ret, "Failed to read HW_CFG: %d", ret); 839 check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
769 840
@@ -1083,6 +1154,169 @@ static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)
1083 } 1154 }
1084} 1155}
1085 1156
1157static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
1158{
1159 struct usbnet *dev = usb_get_intfdata(intf);
1160 struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
1161 int ret;
1162 u32 val;
1163
1164 ret = usbnet_suspend(intf, message);
1165 check_warn_return(ret, "usbnet_suspend error");
1166
1167 /* if no wol options set, enter lowest power SUSPEND2 mode */
1168 if (!(pdata->wolopts & SUPPORTED_WAKE)) {
1169 netdev_info(dev->net, "entering SUSPEND2 mode");
1170
1171 /* disable energy detect (link up) & wake up events */
1172 ret = smsc75xx_read_reg(dev, WUCSR, &val);
1173 check_warn_return(ret, "Error reading WUCSR");
1174
1175 val &= ~(WUCSR_MPEN | WUCSR_WUEN);
1176
1177 ret = smsc75xx_write_reg(dev, WUCSR, val);
1178 check_warn_return(ret, "Error writing WUCSR");
1179
1180 ret = smsc75xx_read_reg(dev, PMT_CTL, &val);
1181 check_warn_return(ret, "Error reading PMT_CTL");
1182
1183 val &= ~(PMT_CTL_ED_EN | PMT_CTL_WOL_EN);
1184
1185 ret = smsc75xx_write_reg(dev, PMT_CTL, val);
1186 check_warn_return(ret, "Error writing PMT_CTL");
1187
1188 /* enter suspend2 mode */
1189 ret = smsc75xx_read_reg(dev, PMT_CTL, &val);
1190 check_warn_return(ret, "Error reading PMT_CTL");
1191
1192 val &= ~(PMT_CTL_SUS_MODE | PMT_CTL_WUPS | PMT_CTL_PHY_RST);
1193 val |= PMT_CTL_SUS_MODE_2;
1194
1195 ret = smsc75xx_write_reg(dev, PMT_CTL, val);
1196 check_warn_return(ret, "Error writing PMT_CTL");
1197
1198 return 0;
1199 }
1200
1201 if (pdata->wolopts & WAKE_MAGIC) {
1202 /* clear any pending magic packet status */
1203 ret = smsc75xx_read_reg(dev, WUCSR, &val);
1204 check_warn_return(ret, "Error reading WUCSR");
1205
1206 val |= WUCSR_MPR;
1207
1208 ret = smsc75xx_write_reg(dev, WUCSR, val);
1209 check_warn_return(ret, "Error writing WUCSR");
1210 }
1211
1212 /* enable/disable magic packup wake */
1213 ret = smsc75xx_read_reg(dev, WUCSR, &val);
1214 check_warn_return(ret, "Error reading WUCSR");
1215
1216 if (pdata->wolopts & WAKE_MAGIC) {
1217 netdev_info(dev->net, "enabling magic packet wakeup");
1218 val |= WUCSR_MPEN;
1219 } else {
1220 netdev_info(dev->net, "disabling magic packet wakeup");
1221 val &= ~WUCSR_MPEN;
1222 }
1223
1224 ret = smsc75xx_write_reg(dev, WUCSR, val);
1225 check_warn_return(ret, "Error writing WUCSR");
1226
1227 /* enable wol wakeup source */
1228 ret = smsc75xx_read_reg(dev, PMT_CTL, &val);
1229 check_warn_return(ret, "Error reading PMT_CTL");
1230
1231 val |= PMT_CTL_WOL_EN;
1232
1233 ret = smsc75xx_write_reg(dev, PMT_CTL, val);
1234 check_warn_return(ret, "Error writing PMT_CTL");
1235
1236 /* enable receiver */
1237 ret = smsc75xx_read_reg(dev, MAC_RX, &val);
1238 check_warn_return(ret, "Failed to read MAC_RX: %d", ret);
1239
1240 val |= MAC_RX_RXEN;
1241
1242 ret = smsc75xx_write_reg(dev, MAC_RX, val);
1243 check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
1244
1245 /* some wol options are enabled, so enter SUSPEND0 */
1246 netdev_info(dev->net, "entering SUSPEND0 mode");
1247
1248 ret = smsc75xx_read_reg(dev, PMT_CTL, &val);
1249 check_warn_return(ret, "Error reading PMT_CTL");
1250
1251 val &= (~(PMT_CTL_SUS_MODE | PMT_CTL_WUPS | PMT_CTL_PHY_RST));
1252 val |= PMT_CTL_SUS_MODE_0;
1253
1254 ret = smsc75xx_write_reg(dev, PMT_CTL, val);
1255 check_warn_return(ret, "Error writing PMT_CTL");
1256
1257 /* clear wol status */
1258 val &= ~PMT_CTL_WUPS;
1259 val |= PMT_CTL_WUPS_WOL;
1260 ret = smsc75xx_write_reg(dev, PMT_CTL, val);
1261 check_warn_return(ret, "Error writing PMT_CTL");
1262
1263 /* read back PMT_CTL */
1264 ret = smsc75xx_read_reg(dev, PMT_CTL, &val);
1265 check_warn_return(ret, "Error reading PMT_CTL");
1266
1267 smsc75xx_set_feature(dev, USB_DEVICE_REMOTE_WAKEUP);
1268
1269 return 0;
1270}
1271
1272static int smsc75xx_resume(struct usb_interface *intf)
1273{
1274 struct usbnet *dev = usb_get_intfdata(intf);
1275 struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
1276 int ret;
1277 u32 val;
1278
1279 if (pdata->wolopts & WAKE_MAGIC) {
1280 netdev_info(dev->net, "resuming from SUSPEND0");
1281
1282 smsc75xx_clear_feature(dev, USB_DEVICE_REMOTE_WAKEUP);
1283
1284 /* Disable magic packup wake */
1285 ret = smsc75xx_read_reg(dev, WUCSR, &val);
1286 check_warn_return(ret, "Error reading WUCSR");
1287
1288 val &= ~WUCSR_MPEN;
1289
1290 ret = smsc75xx_write_reg(dev, WUCSR, val);
1291 check_warn_return(ret, "Error writing WUCSR");
1292
1293 /* clear wake-up status */
1294 ret = smsc75xx_read_reg(dev, PMT_CTL, &val);
1295 check_warn_return(ret, "Error reading PMT_CTL");
1296
1297 val &= ~PMT_CTL_WOL_EN;
1298 val |= PMT_CTL_WUPS;
1299
1300 ret = smsc75xx_write_reg(dev, PMT_CTL, val);
1301 check_warn_return(ret, "Error writing PMT_CTL");
1302 } else {
1303 netdev_info(dev->net, "resuming from SUSPEND2");
1304
1305 ret = smsc75xx_read_reg(dev, PMT_CTL, &val);
1306 check_warn_return(ret, "Error reading PMT_CTL");
1307
1308 val |= PMT_CTL_PHY_PWRUP;
1309
1310 ret = smsc75xx_write_reg(dev, PMT_CTL, val);
1311 check_warn_return(ret, "Error writing PMT_CTL");
1312 }
1313
1314 ret = smsc75xx_wait_ready(dev);
1315 check_warn_return(ret, "device not ready in smsc75xx_resume");
1316
1317 return usbnet_resume(intf);
1318}
1319
1086static void smsc75xx_rx_csum_offload(struct usbnet *dev, struct sk_buff *skb, 1320static void smsc75xx_rx_csum_offload(struct usbnet *dev, struct sk_buff *skb,
1087 u32 rx_cmd_a, u32 rx_cmd_b) 1321 u32 rx_cmd_a, u32 rx_cmd_b)
1088{ 1322{
@@ -1251,9 +1485,9 @@ static struct usb_driver smsc75xx_driver = {
1251 .name = SMSC_CHIPNAME, 1485 .name = SMSC_CHIPNAME,
1252 .id_table = products, 1486 .id_table = products,
1253 .probe = usbnet_probe, 1487 .probe = usbnet_probe,
1254 .suspend = usbnet_suspend, 1488 .suspend = smsc75xx_suspend,
1255 .resume = usbnet_resume, 1489 .resume = smsc75xx_resume,
1256 .reset_resume = usbnet_resume, 1490 .reset_resume = smsc75xx_resume,
1257 .disconnect = usbnet_disconnect, 1491 .disconnect = usbnet_disconnect,
1258 .disable_hub_initiated_lpm = 1, 1492 .disable_hub_initiated_lpm = 1,
1259}; 1493};