diff options
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/Kconfig | 15 | ||||
-rw-r--r-- | drivers/net/usb/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/usb/asix_devices.c | 3 | ||||
-rw-r--r-- | drivers/net/usb/ax88179_178a.c | 46 | ||||
-rw-r--r-- | drivers/net/usb/gl620a.c | 4 | ||||
-rw-r--r-- | drivers/net/usb/hso.c | 32 | ||||
-rw-r--r-- | drivers/net/usb/mcs7830.c | 5 | ||||
-rw-r--r-- | drivers/net/usb/net1080.c | 4 | ||||
-rw-r--r-- | drivers/net/usb/qmi_wwan.c | 11 | ||||
-rw-r--r-- | drivers/net/usb/r8152.c | 17 | ||||
-rw-r--r-- | drivers/net/usb/rndis_host.c | 4 | ||||
-rw-r--r-- | drivers/net/usb/smsc75xx.c | 4 | ||||
-rw-r--r-- | drivers/net/usb/smsc95xx.c | 4 | ||||
-rw-r--r-- | drivers/net/usb/sr9800.c | 874 | ||||
-rw-r--r-- | drivers/net/usb/sr9800.h | 202 | ||||
-rw-r--r-- | drivers/net/usb/usbnet.c | 25 |
16 files changed, 1191 insertions, 60 deletions
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 6b638a066c1d..7e7269fd3707 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
@@ -292,6 +292,21 @@ config USB_NET_SR9700 | |||
292 | This option adds support for CoreChip-sz SR9700 based USB 1.1 | 292 | This option adds support for CoreChip-sz SR9700 based USB 1.1 |
293 | 10/100 Ethernet adapters. | 293 | 10/100 Ethernet adapters. |
294 | 294 | ||
295 | config USB_NET_SR9800 | ||
296 | tristate "CoreChip-sz SR9800 based USB 2.0 10/100 ethernet devices" | ||
297 | depends on USB_USBNET | ||
298 | select CRC32 | ||
299 | ---help--- | ||
300 | Say Y if you want to use one of the following 100Mbps USB Ethernet | ||
301 | device based on the CoreChip-sz SR9800 chip. | ||
302 | |||
303 | This driver makes the adapter appear as a normal Ethernet interface, | ||
304 | typically on eth0, if it is the only ethernet device, or perhaps on | ||
305 | eth1, if you have a PCI or ISA ethernet card installed. | ||
306 | |||
307 | To compile this driver as a module, choose M here: the | ||
308 | module will be called sr9800. | ||
309 | |||
295 | config USB_NET_SMSC75XX | 310 | config USB_NET_SMSC75XX |
296 | tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" | 311 | tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" |
297 | depends on USB_USBNET | 312 | depends on USB_USBNET |
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index b17b5e88bbaf..433f0a00c683 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile | |||
@@ -15,6 +15,7 @@ obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r815x.o | |||
15 | obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o | 15 | obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o |
16 | obj-$(CONFIG_USB_NET_DM9601) += dm9601.o | 16 | obj-$(CONFIG_USB_NET_DM9601) += dm9601.o |
17 | obj-$(CONFIG_USB_NET_SR9700) += sr9700.o | 17 | obj-$(CONFIG_USB_NET_SR9700) += sr9700.o |
18 | obj-$(CONFIG_USB_NET_SR9800) += sr9800.o | ||
18 | obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o | 19 | obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o |
19 | obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o | 20 | obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o |
20 | obj-$(CONFIG_USB_NET_GL620A) += gl620a.o | 21 | obj-$(CONFIG_USB_NET_GL620A) += gl620a.o |
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 9765a7d4766d..5d194093f3e1 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c | |||
@@ -917,7 +917,8 @@ static const struct driver_info ax88178_info = { | |||
917 | .status = asix_status, | 917 | .status = asix_status, |
918 | .link_reset = ax88178_link_reset, | 918 | .link_reset = ax88178_link_reset, |
919 | .reset = ax88178_reset, | 919 | .reset = ax88178_reset, |
920 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR, | 920 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | |
921 | FLAG_MULTI_PACKET, | ||
921 | .rx_fixup = asix_rx_fixup_common, | 922 | .rx_fixup = asix_rx_fixup_common, |
922 | .tx_fixup = asix_tx_fixup, | 923 | .tx_fixup = asix_tx_fixup, |
923 | }; | 924 | }; |
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index d6f64dad05bc..054e59ca6946 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c | |||
@@ -1029,20 +1029,12 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) | |||
1029 | dev->mii.phy_id = 0x03; | 1029 | dev->mii.phy_id = 0x03; |
1030 | dev->mii.supports_gmii = 1; | 1030 | dev->mii.supports_gmii = 1; |
1031 | 1031 | ||
1032 | if (usb_device_no_sg_constraint(dev->udev)) | ||
1033 | dev->can_dma_sg = 1; | ||
1034 | |||
1035 | dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 1032 | dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
1036 | NETIF_F_RXCSUM; | 1033 | NETIF_F_RXCSUM; |
1037 | 1034 | ||
1038 | dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 1035 | dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
1039 | NETIF_F_RXCSUM; | 1036 | NETIF_F_RXCSUM; |
1040 | 1037 | ||
1041 | if (dev->can_dma_sg) { | ||
1042 | dev->net->features |= NETIF_F_SG | NETIF_F_TSO; | ||
1043 | dev->net->hw_features |= NETIF_F_SG | NETIF_F_TSO; | ||
1044 | } | ||
1045 | |||
1046 | /* Enable checksum offload */ | 1038 | /* Enable checksum offload */ |
1047 | *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | | 1039 | *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | |
1048 | AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; | 1040 | AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; |
@@ -1118,6 +1110,10 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
1118 | u16 hdr_off; | 1110 | u16 hdr_off; |
1119 | u32 *pkt_hdr; | 1111 | u32 *pkt_hdr; |
1120 | 1112 | ||
1113 | /* This check is no longer done by usbnet */ | ||
1114 | if (skb->len < dev->net->hard_header_len) | ||
1115 | return 0; | ||
1116 | |||
1121 | skb_trim(skb, skb->len - 4); | 1117 | skb_trim(skb, skb->len - 4); |
1122 | memcpy(&rx_hdr, skb_tail_pointer(skb), 4); | 1118 | memcpy(&rx_hdr, skb_tail_pointer(skb), 4); |
1123 | le32_to_cpus(&rx_hdr); | 1119 | le32_to_cpus(&rx_hdr); |
@@ -1391,6 +1387,19 @@ static const struct driver_info ax88178a_info = { | |||
1391 | .tx_fixup = ax88179_tx_fixup, | 1387 | .tx_fixup = ax88179_tx_fixup, |
1392 | }; | 1388 | }; |
1393 | 1389 | ||
1390 | static const struct driver_info dlink_dub1312_info = { | ||
1391 | .description = "D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter", | ||
1392 | .bind = ax88179_bind, | ||
1393 | .unbind = ax88179_unbind, | ||
1394 | .status = ax88179_status, | ||
1395 | .link_reset = ax88179_link_reset, | ||
1396 | .reset = ax88179_reset, | ||
1397 | .stop = ax88179_stop, | ||
1398 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | ||
1399 | .rx_fixup = ax88179_rx_fixup, | ||
1400 | .tx_fixup = ax88179_tx_fixup, | ||
1401 | }; | ||
1402 | |||
1394 | static const struct driver_info sitecom_info = { | 1403 | static const struct driver_info sitecom_info = { |
1395 | .description = "Sitecom USB 3.0 to Gigabit Adapter", | 1404 | .description = "Sitecom USB 3.0 to Gigabit Adapter", |
1396 | .bind = ax88179_bind, | 1405 | .bind = ax88179_bind, |
@@ -1417,6 +1426,19 @@ static const struct driver_info samsung_info = { | |||
1417 | .tx_fixup = ax88179_tx_fixup, | 1426 | .tx_fixup = ax88179_tx_fixup, |
1418 | }; | 1427 | }; |
1419 | 1428 | ||
1429 | static const struct driver_info lenovo_info = { | ||
1430 | .description = "Lenovo OneLinkDock Gigabit LAN", | ||
1431 | .bind = ax88179_bind, | ||
1432 | .unbind = ax88179_unbind, | ||
1433 | .status = ax88179_status, | ||
1434 | .link_reset = ax88179_link_reset, | ||
1435 | .reset = ax88179_reset, | ||
1436 | .stop = ax88179_stop, | ||
1437 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | ||
1438 | .rx_fixup = ax88179_rx_fixup, | ||
1439 | .tx_fixup = ax88179_tx_fixup, | ||
1440 | }; | ||
1441 | |||
1420 | static const struct usb_device_id products[] = { | 1442 | static const struct usb_device_id products[] = { |
1421 | { | 1443 | { |
1422 | /* ASIX AX88179 10/100/1000 */ | 1444 | /* ASIX AX88179 10/100/1000 */ |
@@ -1427,6 +1449,10 @@ static const struct usb_device_id products[] = { | |||
1427 | USB_DEVICE(0x0b95, 0x178a), | 1449 | USB_DEVICE(0x0b95, 0x178a), |
1428 | .driver_info = (unsigned long)&ax88178a_info, | 1450 | .driver_info = (unsigned long)&ax88178a_info, |
1429 | }, { | 1451 | }, { |
1452 | /* D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter */ | ||
1453 | USB_DEVICE(0x2001, 0x4a00), | ||
1454 | .driver_info = (unsigned long)&dlink_dub1312_info, | ||
1455 | }, { | ||
1430 | /* Sitecom USB 3.0 to Gigabit Adapter */ | 1456 | /* Sitecom USB 3.0 to Gigabit Adapter */ |
1431 | USB_DEVICE(0x0df6, 0x0072), | 1457 | USB_DEVICE(0x0df6, 0x0072), |
1432 | .driver_info = (unsigned long)&sitecom_info, | 1458 | .driver_info = (unsigned long)&sitecom_info, |
@@ -1434,6 +1460,10 @@ static const struct usb_device_id products[] = { | |||
1434 | /* Samsung USB Ethernet Adapter */ | 1460 | /* Samsung USB Ethernet Adapter */ |
1435 | USB_DEVICE(0x04e8, 0xa100), | 1461 | USB_DEVICE(0x04e8, 0xa100), |
1436 | .driver_info = (unsigned long)&samsung_info, | 1462 | .driver_info = (unsigned long)&samsung_info, |
1463 | }, { | ||
1464 | /* Lenovo OneLinkDock Gigabit LAN */ | ||
1465 | USB_DEVICE(0x17ef, 0x304b), | ||
1466 | .driver_info = (unsigned long)&lenovo_info, | ||
1437 | }, | 1467 | }, |
1438 | { }, | 1468 | { }, |
1439 | }; | 1469 | }; |
diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c index e4a8a93fbaf7..1cc24e6f23e2 100644 --- a/drivers/net/usb/gl620a.c +++ b/drivers/net/usb/gl620a.c | |||
@@ -84,6 +84,10 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
84 | u32 size; | 84 | u32 size; |
85 | u32 count; | 85 | u32 count; |
86 | 86 | ||
87 | /* This check is no longer done by usbnet */ | ||
88 | if (skb->len < dev->net->hard_header_len) | ||
89 | return 0; | ||
90 | |||
87 | header = (struct gl_header *) skb->data; | 91 | header = (struct gl_header *) skb->data; |
88 | 92 | ||
89 | // get the packet count of the received skb | 93 | // get the packet count of the received skb |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 1a482344b3f5..660bd5ea9fc0 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -1201,16 +1201,18 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
1201 | struct hso_serial *serial = urb->context; | 1201 | struct hso_serial *serial = urb->context; |
1202 | int status = urb->status; | 1202 | int status = urb->status; |
1203 | 1203 | ||
1204 | D4("\n--- Got serial_read_bulk callback %02x ---", status); | ||
1205 | |||
1204 | /* sanity check */ | 1206 | /* sanity check */ |
1205 | if (!serial) { | 1207 | if (!serial) { |
1206 | D1("serial == NULL"); | 1208 | D1("serial == NULL"); |
1207 | return; | 1209 | return; |
1208 | } else if (status) { | 1210 | } |
1211 | if (status) { | ||
1209 | handle_usb_error(status, __func__, serial->parent); | 1212 | handle_usb_error(status, __func__, serial->parent); |
1210 | return; | 1213 | return; |
1211 | } | 1214 | } |
1212 | 1215 | ||
1213 | D4("\n--- Got serial_read_bulk callback %02x ---", status); | ||
1214 | D1("Actual length = %d\n", urb->actual_length); | 1216 | D1("Actual length = %d\n", urb->actual_length); |
1215 | DUMP1(urb->transfer_buffer, urb->actual_length); | 1217 | DUMP1(urb->transfer_buffer, urb->actual_length); |
1216 | 1218 | ||
@@ -1218,25 +1220,13 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
1218 | if (serial->port.count == 0) | 1220 | if (serial->port.count == 0) |
1219 | return; | 1221 | return; |
1220 | 1222 | ||
1221 | if (status == 0) { | 1223 | if (serial->parent->port_spec & HSO_INFO_CRC_BUG) |
1222 | if (serial->parent->port_spec & HSO_INFO_CRC_BUG) | 1224 | fix_crc_bug(urb, serial->in_endp->wMaxPacketSize); |
1223 | fix_crc_bug(urb, serial->in_endp->wMaxPacketSize); | 1225 | /* Valid data, handle RX data */ |
1224 | /* Valid data, handle RX data */ | 1226 | spin_lock(&serial->serial_lock); |
1225 | spin_lock(&serial->serial_lock); | 1227 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1; |
1226 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1; | 1228 | put_rxbuf_data_and_resubmit_bulk_urb(serial); |
1227 | put_rxbuf_data_and_resubmit_bulk_urb(serial); | 1229 | spin_unlock(&serial->serial_lock); |
1228 | spin_unlock(&serial->serial_lock); | ||
1229 | } else if (status == -ENOENT || status == -ECONNRESET) { | ||
1230 | /* Unlinked - check for throttled port. */ | ||
1231 | D2("Port %d, successfully unlinked urb", serial->minor); | ||
1232 | spin_lock(&serial->serial_lock); | ||
1233 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; | ||
1234 | hso_resubmit_rx_bulk_urb(serial, urb); | ||
1235 | spin_unlock(&serial->serial_lock); | ||
1236 | } else { | ||
1237 | D2("Port %d, status = %d for read urb", serial->minor, status); | ||
1238 | return; | ||
1239 | } | ||
1240 | } | 1230 | } |
1241 | 1231 | ||
1242 | /* | 1232 | /* |
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index a305a7b2dae6..82d844a8ebd0 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c | |||
@@ -526,8 +526,9 @@ static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
526 | { | 526 | { |
527 | u8 status; | 527 | u8 status; |
528 | 528 | ||
529 | if (skb->len == 0) { | 529 | /* This check is no longer done by usbnet */ |
530 | dev_err(&dev->udev->dev, "unexpected empty rx frame\n"); | 530 | if (skb->len < dev->net->hard_header_len) { |
531 | dev_err(&dev->udev->dev, "unexpected tiny rx frame\n"); | ||
531 | return 0; | 532 | return 0; |
532 | } | 533 | } |
533 | 534 | ||
diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c index 0a85d9227775..4cbdb1307f3e 100644 --- a/drivers/net/usb/net1080.c +++ b/drivers/net/usb/net1080.c | |||
@@ -364,6 +364,10 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
364 | struct nc_trailer *trailer; | 364 | struct nc_trailer *trailer; |
365 | u16 hdr_len, packet_len; | 365 | u16 hdr_len, packet_len; |
366 | 366 | ||
367 | /* This check is no longer done by usbnet */ | ||
368 | if (skb->len < dev->net->hard_header_len) | ||
369 | return 0; | ||
370 | |||
367 | if (!(skb->len & 0x01)) { | 371 | if (!(skb->len & 0x01)) { |
368 | netdev_dbg(dev->net, "rx framesize %d range %d..%d mtu %d\n", | 372 | netdev_dbg(dev->net, "rx framesize %d range %d..%d mtu %d\n", |
369 | skb->len, dev->net->hard_header_len, dev->hard_mtu, | 373 | skb->len, dev->net->hard_header_len, dev->hard_mtu, |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 23bdd5b9274d..313cb6cd4848 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -80,10 +80,10 @@ static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
80 | { | 80 | { |
81 | __be16 proto; | 81 | __be16 proto; |
82 | 82 | ||
83 | /* usbnet rx_complete guarantees that skb->len is at least | 83 | /* This check is no longer done by usbnet */ |
84 | * hard_header_len, so we can inspect the dest address without | 84 | if (skb->len < dev->net->hard_header_len) |
85 | * checking skb->len | 85 | return 0; |
86 | */ | 86 | |
87 | switch (skb->data[0] & 0xf0) { | 87 | switch (skb->data[0] & 0xf0) { |
88 | case 0x40: | 88 | case 0x40: |
89 | proto = htons(ETH_P_IP); | 89 | proto = htons(ETH_P_IP); |
@@ -712,6 +712,7 @@ static const struct usb_device_id products[] = { | |||
712 | {QMI_FIXED_INTF(0x19d2, 0x1255, 3)}, | 712 | {QMI_FIXED_INTF(0x19d2, 0x1255, 3)}, |
713 | {QMI_FIXED_INTF(0x19d2, 0x1255, 4)}, | 713 | {QMI_FIXED_INTF(0x19d2, 0x1255, 4)}, |
714 | {QMI_FIXED_INTF(0x19d2, 0x1256, 4)}, | 714 | {QMI_FIXED_INTF(0x19d2, 0x1256, 4)}, |
715 | {QMI_FIXED_INTF(0x19d2, 0x1270, 5)}, /* ZTE MF667 */ | ||
715 | {QMI_FIXED_INTF(0x19d2, 0x1401, 2)}, | 716 | {QMI_FIXED_INTF(0x19d2, 0x1401, 2)}, |
716 | {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ | 717 | {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ |
717 | {QMI_FIXED_INTF(0x19d2, 0x1424, 2)}, | 718 | {QMI_FIXED_INTF(0x19d2, 0x1424, 2)}, |
@@ -723,6 +724,7 @@ static const struct usb_device_id products[] = { | |||
723 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ | 724 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ |
724 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ | 725 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ |
725 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ | 726 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ |
727 | {QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */ | ||
726 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ | 728 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
727 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ | 729 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
728 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ | 730 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ |
@@ -730,6 +732,7 @@ static const struct usb_device_id products[] = { | |||
730 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ | 732 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ |
731 | {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */ | 733 | {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */ |
732 | {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ | 734 | {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ |
735 | {QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */ | ||
733 | 736 | ||
734 | /* 4. Gobi 1000 devices */ | 737 | /* 4. Gobi 1000 devices */ |
735 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 738 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index e8fac732c6f1..d89dbe395ad2 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
@@ -2273,22 +2273,21 @@ static int rtl8152_open(struct net_device *netdev) | |||
2273 | struct r8152 *tp = netdev_priv(netdev); | 2273 | struct r8152 *tp = netdev_priv(netdev); |
2274 | int res = 0; | 2274 | int res = 0; |
2275 | 2275 | ||
2276 | rtl8152_set_speed(tp, AUTONEG_ENABLE, | ||
2277 | tp->mii.supports_gmii ? SPEED_1000 : SPEED_100, | ||
2278 | DUPLEX_FULL); | ||
2279 | tp->speed = 0; | ||
2280 | netif_carrier_off(netdev); | ||
2281 | netif_start_queue(netdev); | ||
2282 | set_bit(WORK_ENABLE, &tp->flags); | ||
2276 | res = usb_submit_urb(tp->intr_urb, GFP_KERNEL); | 2283 | res = usb_submit_urb(tp->intr_urb, GFP_KERNEL); |
2277 | if (res) { | 2284 | if (res) { |
2278 | if (res == -ENODEV) | 2285 | if (res == -ENODEV) |
2279 | netif_device_detach(tp->netdev); | 2286 | netif_device_detach(tp->netdev); |
2280 | netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n", | 2287 | netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n", |
2281 | res); | 2288 | res); |
2282 | return res; | ||
2283 | } | 2289 | } |
2284 | 2290 | ||
2285 | rtl8152_set_speed(tp, AUTONEG_ENABLE, | ||
2286 | tp->mii.supports_gmii ? SPEED_1000 : SPEED_100, | ||
2287 | DUPLEX_FULL); | ||
2288 | tp->speed = 0; | ||
2289 | netif_carrier_off(netdev); | ||
2290 | netif_start_queue(netdev); | ||
2291 | set_bit(WORK_ENABLE, &tp->flags); | ||
2292 | 2291 | ||
2293 | return res; | 2292 | return res; |
2294 | } | 2293 | } |
@@ -2298,8 +2297,8 @@ static int rtl8152_close(struct net_device *netdev) | |||
2298 | struct r8152 *tp = netdev_priv(netdev); | 2297 | struct r8152 *tp = netdev_priv(netdev); |
2299 | int res = 0; | 2298 | int res = 0; |
2300 | 2299 | ||
2301 | usb_kill_urb(tp->intr_urb); | ||
2302 | clear_bit(WORK_ENABLE, &tp->flags); | 2300 | clear_bit(WORK_ENABLE, &tp->flags); |
2301 | usb_kill_urb(tp->intr_urb); | ||
2303 | cancel_delayed_work_sync(&tp->schedule); | 2302 | cancel_delayed_work_sync(&tp->schedule); |
2304 | netif_stop_queue(netdev); | 2303 | netif_stop_queue(netdev); |
2305 | tasklet_disable(&tp->tl); | 2304 | tasklet_disable(&tp->tl); |
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index a48bc0f20c1a..524a47a28120 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c | |||
@@ -492,6 +492,10 @@ EXPORT_SYMBOL_GPL(rndis_unbind); | |||
492 | */ | 492 | */ |
493 | int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 493 | int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
494 | { | 494 | { |
495 | /* This check is no longer done by usbnet */ | ||
496 | if (skb->len < dev->net->hard_header_len) | ||
497 | return 0; | ||
498 | |||
495 | /* peripheral may have batched packets to us... */ | 499 | /* peripheral may have batched packets to us... */ |
496 | while (likely(skb->len)) { | 500 | while (likely(skb->len)) { |
497 | struct rndis_data_hdr *hdr = (void *)skb->data; | 501 | struct rndis_data_hdr *hdr = (void *)skb->data; |
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index f17b9e02dd34..d9e7892262fa 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c | |||
@@ -2106,6 +2106,10 @@ static void smsc75xx_rx_csum_offload(struct usbnet *dev, struct sk_buff *skb, | |||
2106 | 2106 | ||
2107 | static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 2107 | static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
2108 | { | 2108 | { |
2109 | /* This check is no longer done by usbnet */ | ||
2110 | if (skb->len < dev->net->hard_header_len) | ||
2111 | return 0; | ||
2112 | |||
2109 | while (skb->len > 0) { | 2113 | while (skb->len > 0) { |
2110 | u32 rx_cmd_a, rx_cmd_b, align_count, size; | 2114 | u32 rx_cmd_a, rx_cmd_b, align_count, size; |
2111 | struct sk_buff *ax_skb; | 2115 | struct sk_buff *ax_skb; |
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 8dd54a0f7b29..424db65e4396 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c | |||
@@ -1723,6 +1723,10 @@ static void smsc95xx_rx_csum_offload(struct sk_buff *skb) | |||
1723 | 1723 | ||
1724 | static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 1724 | static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
1725 | { | 1725 | { |
1726 | /* This check is no longer done by usbnet */ | ||
1727 | if (skb->len < dev->net->hard_header_len) | ||
1728 | return 0; | ||
1729 | |||
1726 | while (skb->len > 0) { | 1730 | while (skb->len > 0) { |
1727 | u32 header, align_count; | 1731 | u32 header, align_count; |
1728 | struct sk_buff *ax_skb; | 1732 | struct sk_buff *ax_skb; |
diff --git a/drivers/net/usb/sr9800.c b/drivers/net/usb/sr9800.c new file mode 100644 index 000000000000..b94a0fbb8b3b --- /dev/null +++ b/drivers/net/usb/sr9800.c | |||
@@ -0,0 +1,874 @@ | |||
1 | /* CoreChip-sz SR9800 one chip USB 2.0 Ethernet Devices | ||
2 | * | ||
3 | * Author : Liu Junliang <liujunliang_ljl@163.com> | ||
4 | * | ||
5 | * Based on asix_common.c, asix_devices.c | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public License | ||
8 | * version 2. This program is licensed "as is" without any warranty of any | ||
9 | * kind, whether express or implied.* | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/kmod.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/netdevice.h> | ||
16 | #include <linux/etherdevice.h> | ||
17 | #include <linux/ethtool.h> | ||
18 | #include <linux/workqueue.h> | ||
19 | #include <linux/mii.h> | ||
20 | #include <linux/usb.h> | ||
21 | #include <linux/crc32.h> | ||
22 | #include <linux/usb/usbnet.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/if_vlan.h> | ||
25 | |||
26 | #include "sr9800.h" | ||
27 | |||
28 | static int sr_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | ||
29 | u16 size, void *data) | ||
30 | { | ||
31 | int err; | ||
32 | |||
33 | err = usbnet_read_cmd(dev, cmd, SR_REQ_RD_REG, value, index, | ||
34 | data, size); | ||
35 | if ((err != size) && (err >= 0)) | ||
36 | err = -EINVAL; | ||
37 | |||
38 | return err; | ||
39 | } | ||
40 | |||
41 | static int sr_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | ||
42 | u16 size, void *data) | ||
43 | { | ||
44 | int err; | ||
45 | |||
46 | err = usbnet_write_cmd(dev, cmd, SR_REQ_WR_REG, value, index, | ||
47 | data, size); | ||
48 | if ((err != size) && (err >= 0)) | ||
49 | err = -EINVAL; | ||
50 | |||
51 | return err; | ||
52 | } | ||
53 | |||
54 | static void | ||
55 | sr_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, | ||
56 | u16 size, void *data) | ||
57 | { | ||
58 | usbnet_write_cmd_async(dev, cmd, SR_REQ_WR_REG, value, index, data, | ||
59 | size); | ||
60 | } | ||
61 | |||
62 | static int sr_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | ||
63 | { | ||
64 | int offset = 0; | ||
65 | |||
66 | /* This check is no longer done by usbnet */ | ||
67 | if (skb->len < dev->net->hard_header_len) | ||
68 | return 0; | ||
69 | |||
70 | while (offset + sizeof(u32) < skb->len) { | ||
71 | struct sk_buff *sr_skb; | ||
72 | u16 size; | ||
73 | u32 header = get_unaligned_le32(skb->data + offset); | ||
74 | |||
75 | offset += sizeof(u32); | ||
76 | /* get the packet length */ | ||
77 | size = (u16) (header & 0x7ff); | ||
78 | if (size != ((~header >> 16) & 0x07ff)) { | ||
79 | netdev_err(dev->net, "%s : Bad Header Length\n", | ||
80 | __func__); | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | if ((size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) || | ||
85 | (size + offset > skb->len)) { | ||
86 | netdev_err(dev->net, "%s : Bad RX Length %d\n", | ||
87 | __func__, size); | ||
88 | return 0; | ||
89 | } | ||
90 | sr_skb = netdev_alloc_skb_ip_align(dev->net, size); | ||
91 | if (!sr_skb) | ||
92 | return 0; | ||
93 | |||
94 | skb_put(sr_skb, size); | ||
95 | memcpy(sr_skb->data, skb->data + offset, size); | ||
96 | usbnet_skb_return(dev, sr_skb); | ||
97 | |||
98 | offset += (size + 1) & 0xfffe; | ||
99 | } | ||
100 | |||
101 | if (skb->len != offset) { | ||
102 | netdev_err(dev->net, "%s : Bad SKB Length %d\n", __func__, | ||
103 | skb->len); | ||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | return 1; | ||
108 | } | ||
109 | |||
110 | static struct sk_buff *sr_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | ||
111 | gfp_t flags) | ||
112 | { | ||
113 | int headroom = skb_headroom(skb); | ||
114 | int tailroom = skb_tailroom(skb); | ||
115 | u32 padbytes = 0xffff0000; | ||
116 | u32 packet_len; | ||
117 | int padlen; | ||
118 | |||
119 | padlen = ((skb->len + 4) % (dev->maxpacket - 1)) ? 0 : 4; | ||
120 | |||
121 | if ((!skb_cloned(skb)) && ((headroom + tailroom) >= (4 + padlen))) { | ||
122 | if ((headroom < 4) || (tailroom < padlen)) { | ||
123 | skb->data = memmove(skb->head + 4, skb->data, | ||
124 | skb->len); | ||
125 | skb_set_tail_pointer(skb, skb->len); | ||
126 | } | ||
127 | } else { | ||
128 | struct sk_buff *skb2; | ||
129 | skb2 = skb_copy_expand(skb, 4, padlen, flags); | ||
130 | dev_kfree_skb_any(skb); | ||
131 | skb = skb2; | ||
132 | if (!skb) | ||
133 | return NULL; | ||
134 | } | ||
135 | |||
136 | skb_push(skb, 4); | ||
137 | packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4); | ||
138 | cpu_to_le32s(&packet_len); | ||
139 | skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); | ||
140 | |||
141 | if (padlen) { | ||
142 | cpu_to_le32s(&padbytes); | ||
143 | memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes)); | ||
144 | skb_put(skb, sizeof(padbytes)); | ||
145 | } | ||
146 | |||
147 | return skb; | ||
148 | } | ||
149 | |||
150 | static void sr_status(struct usbnet *dev, struct urb *urb) | ||
151 | { | ||
152 | struct sr9800_int_data *event; | ||
153 | int link; | ||
154 | |||
155 | if (urb->actual_length < 8) | ||
156 | return; | ||
157 | |||
158 | event = urb->transfer_buffer; | ||
159 | link = event->link & 0x01; | ||
160 | if (netif_carrier_ok(dev->net) != link) { | ||
161 | usbnet_link_change(dev, link, 1); | ||
162 | netdev_dbg(dev->net, "Link Status is: %d\n", link); | ||
163 | } | ||
164 | |||
165 | return; | ||
166 | } | ||
167 | |||
168 | static inline int sr_set_sw_mii(struct usbnet *dev) | ||
169 | { | ||
170 | int ret; | ||
171 | |||
172 | ret = sr_write_cmd(dev, SR_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); | ||
173 | if (ret < 0) | ||
174 | netdev_err(dev->net, "Failed to enable software MII access\n"); | ||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | static inline int sr_set_hw_mii(struct usbnet *dev) | ||
179 | { | ||
180 | int ret; | ||
181 | |||
182 | ret = sr_write_cmd(dev, SR_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); | ||
183 | if (ret < 0) | ||
184 | netdev_err(dev->net, "Failed to enable hardware MII access\n"); | ||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | static inline int sr_get_phy_addr(struct usbnet *dev) | ||
189 | { | ||
190 | u8 buf[2]; | ||
191 | int ret; | ||
192 | |||
193 | ret = sr_read_cmd(dev, SR_CMD_READ_PHY_ID, 0, 0, 2, buf); | ||
194 | if (ret < 0) { | ||
195 | netdev_err(dev->net, "%s : Error reading PHYID register:%02x\n", | ||
196 | __func__, ret); | ||
197 | goto out; | ||
198 | } | ||
199 | netdev_dbg(dev->net, "%s : returning 0x%04x\n", __func__, | ||
200 | *((__le16 *)buf)); | ||
201 | |||
202 | ret = buf[1]; | ||
203 | |||
204 | out: | ||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | static int sr_sw_reset(struct usbnet *dev, u8 flags) | ||
209 | { | ||
210 | int ret; | ||
211 | |||
212 | ret = sr_write_cmd(dev, SR_CMD_SW_RESET, flags, 0, 0, NULL); | ||
213 | if (ret < 0) | ||
214 | netdev_err(dev->net, "Failed to send software reset:%02x\n", | ||
215 | ret); | ||
216 | |||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | static u16 sr_read_rx_ctl(struct usbnet *dev) | ||
221 | { | ||
222 | __le16 v; | ||
223 | int ret; | ||
224 | |||
225 | ret = sr_read_cmd(dev, SR_CMD_READ_RX_CTL, 0, 0, 2, &v); | ||
226 | if (ret < 0) { | ||
227 | netdev_err(dev->net, "Error reading RX_CTL register:%02x\n", | ||
228 | ret); | ||
229 | goto out; | ||
230 | } | ||
231 | |||
232 | ret = le16_to_cpu(v); | ||
233 | out: | ||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | static int sr_write_rx_ctl(struct usbnet *dev, u16 mode) | ||
238 | { | ||
239 | int ret; | ||
240 | |||
241 | netdev_dbg(dev->net, "%s : mode = 0x%04x\n", __func__, mode); | ||
242 | ret = sr_write_cmd(dev, SR_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); | ||
243 | if (ret < 0) | ||
244 | netdev_err(dev->net, | ||
245 | "Failed to write RX_CTL mode to 0x%04x:%02x\n", | ||
246 | mode, ret); | ||
247 | |||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | static u16 sr_read_medium_status(struct usbnet *dev) | ||
252 | { | ||
253 | __le16 v; | ||
254 | int ret; | ||
255 | |||
256 | ret = sr_read_cmd(dev, SR_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v); | ||
257 | if (ret < 0) { | ||
258 | netdev_err(dev->net, | ||
259 | "Error reading Medium Status register:%02x\n", ret); | ||
260 | return ret; /* TODO: callers not checking for error ret */ | ||
261 | } | ||
262 | |||
263 | return le16_to_cpu(v); | ||
264 | } | ||
265 | |||
266 | static int sr_write_medium_mode(struct usbnet *dev, u16 mode) | ||
267 | { | ||
268 | int ret; | ||
269 | |||
270 | netdev_dbg(dev->net, "%s : mode = 0x%04x\n", __func__, mode); | ||
271 | ret = sr_write_cmd(dev, SR_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); | ||
272 | if (ret < 0) | ||
273 | netdev_err(dev->net, | ||
274 | "Failed to write Medium Mode mode to 0x%04x:%02x\n", | ||
275 | mode, ret); | ||
276 | return ret; | ||
277 | } | ||
278 | |||
279 | static int sr_write_gpio(struct usbnet *dev, u16 value, int sleep) | ||
280 | { | ||
281 | int ret; | ||
282 | |||
283 | netdev_dbg(dev->net, "%s : value = 0x%04x\n", __func__, value); | ||
284 | ret = sr_write_cmd(dev, SR_CMD_WRITE_GPIOS, value, 0, 0, NULL); | ||
285 | if (ret < 0) | ||
286 | netdev_err(dev->net, "Failed to write GPIO value 0x%04x:%02x\n", | ||
287 | value, ret); | ||
288 | if (sleep) | ||
289 | msleep(sleep); | ||
290 | |||
291 | return ret; | ||
292 | } | ||
293 | |||
294 | /* SR9800 have a 16-bit RX_CTL value */ | ||
295 | static void sr_set_multicast(struct net_device *net) | ||
296 | { | ||
297 | struct usbnet *dev = netdev_priv(net); | ||
298 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
299 | u16 rx_ctl = SR_DEFAULT_RX_CTL; | ||
300 | |||
301 | if (net->flags & IFF_PROMISC) { | ||
302 | rx_ctl |= SR_RX_CTL_PRO; | ||
303 | } else if (net->flags & IFF_ALLMULTI || | ||
304 | netdev_mc_count(net) > SR_MAX_MCAST) { | ||
305 | rx_ctl |= SR_RX_CTL_AMALL; | ||
306 | } else if (netdev_mc_empty(net)) { | ||
307 | /* just broadcast and directed */ | ||
308 | } else { | ||
309 | /* We use the 20 byte dev->data | ||
310 | * for our 8 byte filter buffer | ||
311 | * to avoid allocating memory that | ||
312 | * is tricky to free later | ||
313 | */ | ||
314 | struct netdev_hw_addr *ha; | ||
315 | u32 crc_bits; | ||
316 | |||
317 | memset(data->multi_filter, 0, SR_MCAST_FILTER_SIZE); | ||
318 | |||
319 | /* Build the multicast hash filter. */ | ||
320 | netdev_for_each_mc_addr(ha, net) { | ||
321 | crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; | ||
322 | data->multi_filter[crc_bits >> 3] |= | ||
323 | 1 << (crc_bits & 7); | ||
324 | } | ||
325 | |||
326 | sr_write_cmd_async(dev, SR_CMD_WRITE_MULTI_FILTER, 0, 0, | ||
327 | SR_MCAST_FILTER_SIZE, data->multi_filter); | ||
328 | |||
329 | rx_ctl |= SR_RX_CTL_AM; | ||
330 | } | ||
331 | |||
332 | sr_write_cmd_async(dev, SR_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); | ||
333 | } | ||
334 | |||
335 | static int sr_mdio_read(struct net_device *net, int phy_id, int loc) | ||
336 | { | ||
337 | struct usbnet *dev = netdev_priv(net); | ||
338 | __le16 res; | ||
339 | |||
340 | mutex_lock(&dev->phy_mutex); | ||
341 | sr_set_sw_mii(dev); | ||
342 | sr_read_cmd(dev, SR_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, &res); | ||
343 | sr_set_hw_mii(dev); | ||
344 | mutex_unlock(&dev->phy_mutex); | ||
345 | |||
346 | netdev_dbg(dev->net, | ||
347 | "%s : phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", __func__, | ||
348 | phy_id, loc, le16_to_cpu(res)); | ||
349 | |||
350 | return le16_to_cpu(res); | ||
351 | } | ||
352 | |||
353 | static void | ||
354 | sr_mdio_write(struct net_device *net, int phy_id, int loc, int val) | ||
355 | { | ||
356 | struct usbnet *dev = netdev_priv(net); | ||
357 | __le16 res = cpu_to_le16(val); | ||
358 | |||
359 | netdev_dbg(dev->net, | ||
360 | "%s : phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", __func__, | ||
361 | phy_id, loc, val); | ||
362 | mutex_lock(&dev->phy_mutex); | ||
363 | sr_set_sw_mii(dev); | ||
364 | sr_write_cmd(dev, SR_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); | ||
365 | sr_set_hw_mii(dev); | ||
366 | mutex_unlock(&dev->phy_mutex); | ||
367 | } | ||
368 | |||
369 | /* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */ | ||
370 | static u32 sr_get_phyid(struct usbnet *dev) | ||
371 | { | ||
372 | int phy_reg; | ||
373 | u32 phy_id; | ||
374 | int i; | ||
375 | |||
376 | /* Poll for the rare case the FW or phy isn't ready yet. */ | ||
377 | for (i = 0; i < 100; i++) { | ||
378 | phy_reg = sr_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1); | ||
379 | if (phy_reg != 0 && phy_reg != 0xFFFF) | ||
380 | break; | ||
381 | mdelay(1); | ||
382 | } | ||
383 | |||
384 | if (phy_reg <= 0 || phy_reg == 0xFFFF) | ||
385 | return 0; | ||
386 | |||
387 | phy_id = (phy_reg & 0xffff) << 16; | ||
388 | |||
389 | phy_reg = sr_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID2); | ||
390 | if (phy_reg < 0) | ||
391 | return 0; | ||
392 | |||
393 | phy_id |= (phy_reg & 0xffff); | ||
394 | |||
395 | return phy_id; | ||
396 | } | ||
397 | |||
398 | static void | ||
399 | sr_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) | ||
400 | { | ||
401 | struct usbnet *dev = netdev_priv(net); | ||
402 | u8 opt; | ||
403 | |||
404 | if (sr_read_cmd(dev, SR_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { | ||
405 | wolinfo->supported = 0; | ||
406 | wolinfo->wolopts = 0; | ||
407 | return; | ||
408 | } | ||
409 | wolinfo->supported = WAKE_PHY | WAKE_MAGIC; | ||
410 | wolinfo->wolopts = 0; | ||
411 | if (opt & SR_MONITOR_LINK) | ||
412 | wolinfo->wolopts |= WAKE_PHY; | ||
413 | if (opt & SR_MONITOR_MAGIC) | ||
414 | wolinfo->wolopts |= WAKE_MAGIC; | ||
415 | } | ||
416 | |||
417 | static int | ||
418 | sr_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) | ||
419 | { | ||
420 | struct usbnet *dev = netdev_priv(net); | ||
421 | u8 opt = 0; | ||
422 | |||
423 | if (wolinfo->wolopts & WAKE_PHY) | ||
424 | opt |= SR_MONITOR_LINK; | ||
425 | if (wolinfo->wolopts & WAKE_MAGIC) | ||
426 | opt |= SR_MONITOR_MAGIC; | ||
427 | |||
428 | if (sr_write_cmd(dev, SR_CMD_WRITE_MONITOR_MODE, | ||
429 | opt, 0, 0, NULL) < 0) | ||
430 | return -EINVAL; | ||
431 | |||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | static int sr_get_eeprom_len(struct net_device *net) | ||
436 | { | ||
437 | struct usbnet *dev = netdev_priv(net); | ||
438 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
439 | |||
440 | return data->eeprom_len; | ||
441 | } | ||
442 | |||
443 | static int sr_get_eeprom(struct net_device *net, | ||
444 | struct ethtool_eeprom *eeprom, u8 *data) | ||
445 | { | ||
446 | struct usbnet *dev = netdev_priv(net); | ||
447 | __le16 *ebuf = (__le16 *)data; | ||
448 | int ret; | ||
449 | int i; | ||
450 | |||
451 | /* Crude hack to ensure that we don't overwrite memory | ||
452 | * if an odd length is supplied | ||
453 | */ | ||
454 | if (eeprom->len % 2) | ||
455 | return -EINVAL; | ||
456 | |||
457 | eeprom->magic = SR_EEPROM_MAGIC; | ||
458 | |||
459 | /* sr9800 returns 2 bytes from eeprom on read */ | ||
460 | for (i = 0; i < eeprom->len / 2; i++) { | ||
461 | ret = sr_read_cmd(dev, SR_CMD_READ_EEPROM, eeprom->offset + i, | ||
462 | 0, 2, &ebuf[i]); | ||
463 | if (ret < 0) | ||
464 | return -EINVAL; | ||
465 | } | ||
466 | return 0; | ||
467 | } | ||
468 | |||
469 | static void sr_get_drvinfo(struct net_device *net, | ||
470 | struct ethtool_drvinfo *info) | ||
471 | { | ||
472 | struct usbnet *dev = netdev_priv(net); | ||
473 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
474 | |||
475 | /* Inherit standard device info */ | ||
476 | usbnet_get_drvinfo(net, info); | ||
477 | strncpy(info->driver, DRIVER_NAME, sizeof(info->driver)); | ||
478 | strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); | ||
479 | info->eedump_len = data->eeprom_len; | ||
480 | } | ||
481 | |||
482 | static u32 sr_get_link(struct net_device *net) | ||
483 | { | ||
484 | struct usbnet *dev = netdev_priv(net); | ||
485 | |||
486 | return mii_link_ok(&dev->mii); | ||
487 | } | ||
488 | |||
489 | static int sr_ioctl(struct net_device *net, struct ifreq *rq, int cmd) | ||
490 | { | ||
491 | struct usbnet *dev = netdev_priv(net); | ||
492 | |||
493 | return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); | ||
494 | } | ||
495 | |||
496 | static int sr_set_mac_address(struct net_device *net, void *p) | ||
497 | { | ||
498 | struct usbnet *dev = netdev_priv(net); | ||
499 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
500 | struct sockaddr *addr = p; | ||
501 | |||
502 | if (netif_running(net)) | ||
503 | return -EBUSY; | ||
504 | if (!is_valid_ether_addr(addr->sa_data)) | ||
505 | return -EADDRNOTAVAIL; | ||
506 | |||
507 | memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); | ||
508 | |||
509 | /* We use the 20 byte dev->data | ||
510 | * for our 6 byte mac buffer | ||
511 | * to avoid allocating memory that | ||
512 | * is tricky to free later | ||
513 | */ | ||
514 | memcpy(data->mac_addr, addr->sa_data, ETH_ALEN); | ||
515 | sr_write_cmd_async(dev, SR_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, | ||
516 | data->mac_addr); | ||
517 | |||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | static const struct ethtool_ops sr9800_ethtool_ops = { | ||
522 | .get_drvinfo = sr_get_drvinfo, | ||
523 | .get_link = sr_get_link, | ||
524 | .get_msglevel = usbnet_get_msglevel, | ||
525 | .set_msglevel = usbnet_set_msglevel, | ||
526 | .get_wol = sr_get_wol, | ||
527 | .set_wol = sr_set_wol, | ||
528 | .get_eeprom_len = sr_get_eeprom_len, | ||
529 | .get_eeprom = sr_get_eeprom, | ||
530 | .get_settings = usbnet_get_settings, | ||
531 | .set_settings = usbnet_set_settings, | ||
532 | .nway_reset = usbnet_nway_reset, | ||
533 | }; | ||
534 | |||
535 | static int sr9800_link_reset(struct usbnet *dev) | ||
536 | { | ||
537 | struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; | ||
538 | u16 mode; | ||
539 | |||
540 | mii_check_media(&dev->mii, 1, 1); | ||
541 | mii_ethtool_gset(&dev->mii, &ecmd); | ||
542 | mode = SR9800_MEDIUM_DEFAULT; | ||
543 | |||
544 | if (ethtool_cmd_speed(&ecmd) != SPEED_100) | ||
545 | mode &= ~SR_MEDIUM_PS; | ||
546 | |||
547 | if (ecmd.duplex != DUPLEX_FULL) | ||
548 | mode &= ~SR_MEDIUM_FD; | ||
549 | |||
550 | netdev_dbg(dev->net, "%s : speed: %u duplex: %d mode: 0x%04x\n", | ||
551 | __func__, ethtool_cmd_speed(&ecmd), ecmd.duplex, mode); | ||
552 | |||
553 | sr_write_medium_mode(dev, mode); | ||
554 | |||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | |||
559 | static int sr9800_set_default_mode(struct usbnet *dev) | ||
560 | { | ||
561 | u16 rx_ctl; | ||
562 | int ret; | ||
563 | |||
564 | sr_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); | ||
565 | sr_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, | ||
566 | ADVERTISE_ALL | ADVERTISE_CSMA); | ||
567 | mii_nway_restart(&dev->mii); | ||
568 | |||
569 | ret = sr_write_medium_mode(dev, SR9800_MEDIUM_DEFAULT); | ||
570 | if (ret < 0) | ||
571 | goto out; | ||
572 | |||
573 | ret = sr_write_cmd(dev, SR_CMD_WRITE_IPG012, | ||
574 | SR9800_IPG0_DEFAULT | SR9800_IPG1_DEFAULT, | ||
575 | SR9800_IPG2_DEFAULT, 0, NULL); | ||
576 | if (ret < 0) { | ||
577 | netdev_dbg(dev->net, "Write IPG,IPG1,IPG2 failed: %d\n", ret); | ||
578 | goto out; | ||
579 | } | ||
580 | |||
581 | /* Set RX_CTL to default values with 2k buffer, and enable cactus */ | ||
582 | ret = sr_write_rx_ctl(dev, SR_DEFAULT_RX_CTL); | ||
583 | if (ret < 0) | ||
584 | goto out; | ||
585 | |||
586 | rx_ctl = sr_read_rx_ctl(dev); | ||
587 | netdev_dbg(dev->net, "RX_CTL is 0x%04x after all initializations\n", | ||
588 | rx_ctl); | ||
589 | |||
590 | rx_ctl = sr_read_medium_status(dev); | ||
591 | netdev_dbg(dev->net, "Medium Status:0x%04x after all initializations\n", | ||
592 | rx_ctl); | ||
593 | |||
594 | return 0; | ||
595 | out: | ||
596 | return ret; | ||
597 | } | ||
598 | |||
599 | static int sr9800_reset(struct usbnet *dev) | ||
600 | { | ||
601 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
602 | int ret, embd_phy; | ||
603 | u16 rx_ctl; | ||
604 | |||
605 | ret = sr_write_gpio(dev, | ||
606 | SR_GPIO_RSE | SR_GPIO_GPO_2 | SR_GPIO_GPO2EN, 5); | ||
607 | if (ret < 0) | ||
608 | goto out; | ||
609 | |||
610 | embd_phy = ((sr_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); | ||
611 | |||
612 | ret = sr_write_cmd(dev, SR_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); | ||
613 | if (ret < 0) { | ||
614 | netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); | ||
615 | goto out; | ||
616 | } | ||
617 | |||
618 | ret = sr_sw_reset(dev, SR_SWRESET_IPPD | SR_SWRESET_PRL); | ||
619 | if (ret < 0) | ||
620 | goto out; | ||
621 | |||
622 | msleep(150); | ||
623 | |||
624 | ret = sr_sw_reset(dev, SR_SWRESET_CLEAR); | ||
625 | if (ret < 0) | ||
626 | goto out; | ||
627 | |||
628 | msleep(150); | ||
629 | |||
630 | if (embd_phy) { | ||
631 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL); | ||
632 | if (ret < 0) | ||
633 | goto out; | ||
634 | } else { | ||
635 | ret = sr_sw_reset(dev, SR_SWRESET_PRTE); | ||
636 | if (ret < 0) | ||
637 | goto out; | ||
638 | } | ||
639 | |||
640 | msleep(150); | ||
641 | rx_ctl = sr_read_rx_ctl(dev); | ||
642 | netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); | ||
643 | ret = sr_write_rx_ctl(dev, 0x0000); | ||
644 | if (ret < 0) | ||
645 | goto out; | ||
646 | |||
647 | rx_ctl = sr_read_rx_ctl(dev); | ||
648 | netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); | ||
649 | |||
650 | ret = sr_sw_reset(dev, SR_SWRESET_PRL); | ||
651 | if (ret < 0) | ||
652 | goto out; | ||
653 | |||
654 | msleep(150); | ||
655 | |||
656 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL | SR_SWRESET_PRL); | ||
657 | if (ret < 0) | ||
658 | goto out; | ||
659 | |||
660 | msleep(150); | ||
661 | |||
662 | ret = sr9800_set_default_mode(dev); | ||
663 | if (ret < 0) | ||
664 | goto out; | ||
665 | |||
666 | /* Rewrite MAC address */ | ||
667 | memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); | ||
668 | ret = sr_write_cmd(dev, SR_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, | ||
669 | data->mac_addr); | ||
670 | if (ret < 0) | ||
671 | goto out; | ||
672 | |||
673 | return 0; | ||
674 | |||
675 | out: | ||
676 | return ret; | ||
677 | } | ||
678 | |||
679 | static const struct net_device_ops sr9800_netdev_ops = { | ||
680 | .ndo_open = usbnet_open, | ||
681 | .ndo_stop = usbnet_stop, | ||
682 | .ndo_start_xmit = usbnet_start_xmit, | ||
683 | .ndo_tx_timeout = usbnet_tx_timeout, | ||
684 | .ndo_change_mtu = usbnet_change_mtu, | ||
685 | .ndo_set_mac_address = sr_set_mac_address, | ||
686 | .ndo_validate_addr = eth_validate_addr, | ||
687 | .ndo_do_ioctl = sr_ioctl, | ||
688 | .ndo_set_rx_mode = sr_set_multicast, | ||
689 | }; | ||
690 | |||
691 | static int sr9800_phy_powerup(struct usbnet *dev) | ||
692 | { | ||
693 | int ret; | ||
694 | |||
695 | /* set the embedded Ethernet PHY in power-down state */ | ||
696 | ret = sr_sw_reset(dev, SR_SWRESET_IPPD | SR_SWRESET_IPRL); | ||
697 | if (ret < 0) { | ||
698 | netdev_err(dev->net, "Failed to power down PHY : %d\n", ret); | ||
699 | return ret; | ||
700 | } | ||
701 | msleep(20); | ||
702 | |||
703 | /* set the embedded Ethernet PHY in power-up state */ | ||
704 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL); | ||
705 | if (ret < 0) { | ||
706 | netdev_err(dev->net, "Failed to reset PHY: %d\n", ret); | ||
707 | return ret; | ||
708 | } | ||
709 | msleep(600); | ||
710 | |||
711 | /* set the embedded Ethernet PHY in reset state */ | ||
712 | ret = sr_sw_reset(dev, SR_SWRESET_CLEAR); | ||
713 | if (ret < 0) { | ||
714 | netdev_err(dev->net, "Failed to power up PHY: %d\n", ret); | ||
715 | return ret; | ||
716 | } | ||
717 | msleep(20); | ||
718 | |||
719 | /* set the embedded Ethernet PHY in power-up state */ | ||
720 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL); | ||
721 | if (ret < 0) { | ||
722 | netdev_err(dev->net, "Failed to reset PHY: %d\n", ret); | ||
723 | return ret; | ||
724 | } | ||
725 | |||
726 | return 0; | ||
727 | } | ||
728 | |||
729 | static int sr9800_bind(struct usbnet *dev, struct usb_interface *intf) | ||
730 | { | ||
731 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
732 | u16 led01_mux, led23_mux; | ||
733 | int ret, embd_phy; | ||
734 | u32 phyid; | ||
735 | u16 rx_ctl; | ||
736 | |||
737 | data->eeprom_len = SR9800_EEPROM_LEN; | ||
738 | |||
739 | usbnet_get_endpoints(dev, intf); | ||
740 | |||
741 | /* LED Setting Rule : | ||
742 | * AABB:CCDD | ||
743 | * AA : MFA0(LED0) | ||
744 | * BB : MFA1(LED1) | ||
745 | * CC : MFA2(LED2), Reserved for SR9800 | ||
746 | * DD : MFA3(LED3), Reserved for SR9800 | ||
747 | */ | ||
748 | led01_mux = (SR_LED_MUX_LINK_ACTIVE << 8) | SR_LED_MUX_LINK; | ||
749 | led23_mux = (SR_LED_MUX_LINK_ACTIVE << 8) | SR_LED_MUX_TX_ACTIVE; | ||
750 | ret = sr_write_cmd(dev, SR_CMD_LED_MUX, led01_mux, led23_mux, 0, NULL); | ||
751 | if (ret < 0) { | ||
752 | netdev_err(dev->net, "set LINK LED failed : %d\n", ret); | ||
753 | goto out; | ||
754 | } | ||
755 | |||
756 | /* Get the MAC address */ | ||
757 | ret = sr_read_cmd(dev, SR_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, | ||
758 | dev->net->dev_addr); | ||
759 | if (ret < 0) { | ||
760 | netdev_dbg(dev->net, "Failed to read MAC address: %d\n", ret); | ||
761 | return ret; | ||
762 | } | ||
763 | netdev_dbg(dev->net, "mac addr : %pM\n", dev->net->dev_addr); | ||
764 | |||
765 | /* Initialize MII structure */ | ||
766 | dev->mii.dev = dev->net; | ||
767 | dev->mii.mdio_read = sr_mdio_read; | ||
768 | dev->mii.mdio_write = sr_mdio_write; | ||
769 | dev->mii.phy_id_mask = 0x1f; | ||
770 | dev->mii.reg_num_mask = 0x1f; | ||
771 | dev->mii.phy_id = sr_get_phy_addr(dev); | ||
772 | |||
773 | dev->net->netdev_ops = &sr9800_netdev_ops; | ||
774 | dev->net->ethtool_ops = &sr9800_ethtool_ops; | ||
775 | |||
776 | embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0); | ||
777 | /* Reset the PHY to normal operation mode */ | ||
778 | ret = sr_write_cmd(dev, SR_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); | ||
779 | if (ret < 0) { | ||
780 | netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); | ||
781 | return ret; | ||
782 | } | ||
783 | |||
784 | /* Init PHY routine */ | ||
785 | ret = sr9800_phy_powerup(dev); | ||
786 | if (ret < 0) | ||
787 | goto out; | ||
788 | |||
789 | rx_ctl = sr_read_rx_ctl(dev); | ||
790 | netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); | ||
791 | ret = sr_write_rx_ctl(dev, 0x0000); | ||
792 | if (ret < 0) | ||
793 | goto out; | ||
794 | |||
795 | rx_ctl = sr_read_rx_ctl(dev); | ||
796 | netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); | ||
797 | |||
798 | /* Read PHYID register *AFTER* the PHY was reset properly */ | ||
799 | phyid = sr_get_phyid(dev); | ||
800 | netdev_dbg(dev->net, "PHYID=0x%08x\n", phyid); | ||
801 | |||
802 | /* medium mode setting */ | ||
803 | ret = sr9800_set_default_mode(dev); | ||
804 | if (ret < 0) | ||
805 | goto out; | ||
806 | |||
807 | if (dev->udev->speed == USB_SPEED_HIGH) { | ||
808 | ret = sr_write_cmd(dev, SR_CMD_BULKIN_SIZE, | ||
809 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].byte_cnt, | ||
810 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].threshold, | ||
811 | 0, NULL); | ||
812 | if (ret < 0) { | ||
813 | netdev_err(dev->net, "Reset RX_CTL failed: %d\n", ret); | ||
814 | goto out; | ||
815 | } | ||
816 | dev->rx_urb_size = | ||
817 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].size; | ||
818 | } else { | ||
819 | ret = sr_write_cmd(dev, SR_CMD_BULKIN_SIZE, | ||
820 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].byte_cnt, | ||
821 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].threshold, | ||
822 | 0, NULL); | ||
823 | if (ret < 0) { | ||
824 | netdev_err(dev->net, "Reset RX_CTL failed: %d\n", ret); | ||
825 | goto out; | ||
826 | } | ||
827 | dev->rx_urb_size = | ||
828 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].size; | ||
829 | } | ||
830 | netdev_dbg(dev->net, "%s : setting rx_urb_size with : %zu\n", __func__, | ||
831 | dev->rx_urb_size); | ||
832 | return 0; | ||
833 | |||
834 | out: | ||
835 | return ret; | ||
836 | } | ||
837 | |||
838 | static const struct driver_info sr9800_driver_info = { | ||
839 | .description = "CoreChip SR9800 USB 2.0 Ethernet", | ||
840 | .bind = sr9800_bind, | ||
841 | .status = sr_status, | ||
842 | .link_reset = sr9800_link_reset, | ||
843 | .reset = sr9800_reset, | ||
844 | .flags = DRIVER_FLAG, | ||
845 | .rx_fixup = sr_rx_fixup, | ||
846 | .tx_fixup = sr_tx_fixup, | ||
847 | }; | ||
848 | |||
849 | static const struct usb_device_id products[] = { | ||
850 | { | ||
851 | USB_DEVICE(0x0fe6, 0x9800), /* SR9800 Device */ | ||
852 | .driver_info = (unsigned long) &sr9800_driver_info, | ||
853 | }, | ||
854 | {}, /* END */ | ||
855 | }; | ||
856 | |||
857 | MODULE_DEVICE_TABLE(usb, products); | ||
858 | |||
859 | static struct usb_driver sr_driver = { | ||
860 | .name = DRIVER_NAME, | ||
861 | .id_table = products, | ||
862 | .probe = usbnet_probe, | ||
863 | .suspend = usbnet_suspend, | ||
864 | .resume = usbnet_resume, | ||
865 | .disconnect = usbnet_disconnect, | ||
866 | .supports_autosuspend = 1, | ||
867 | }; | ||
868 | |||
869 | module_usb_driver(sr_driver); | ||
870 | |||
871 | MODULE_AUTHOR("Liu Junliang <liujunliang_ljl@163.com"); | ||
872 | MODULE_VERSION(DRIVER_VERSION); | ||
873 | MODULE_DESCRIPTION("SR9800 USB 2.0 USB2NET Dev : http://www.corechip-sz.com"); | ||
874 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/usb/sr9800.h b/drivers/net/usb/sr9800.h new file mode 100644 index 000000000000..18f670251275 --- /dev/null +++ b/drivers/net/usb/sr9800.h | |||
@@ -0,0 +1,202 @@ | |||
1 | /* CoreChip-sz SR9800 one chip USB 2.0 Ethernet Devices | ||
2 | * | ||
3 | * Author : Liu Junliang <liujunliang_ljl@163.com> | ||
4 | * | ||
5 | * This file is licensed under the terms of the GNU General Public License | ||
6 | * version 2. This program is licensed "as is" without any warranty of any | ||
7 | * kind, whether express or implied. | ||
8 | */ | ||
9 | |||
10 | #ifndef _SR9800_H | ||
11 | #define _SR9800_H | ||
12 | |||
13 | /* SR9800 spec. command table on Linux Platform */ | ||
14 | |||
15 | /* command : Software Station Management Control Reg */ | ||
16 | #define SR_CMD_SET_SW_MII 0x06 | ||
17 | /* command : PHY Read Reg */ | ||
18 | #define SR_CMD_READ_MII_REG 0x07 | ||
19 | /* command : PHY Write Reg */ | ||
20 | #define SR_CMD_WRITE_MII_REG 0x08 | ||
21 | /* command : Hardware Station Management Control Reg */ | ||
22 | #define SR_CMD_SET_HW_MII 0x0a | ||
23 | /* command : SROM Read Reg */ | ||
24 | #define SR_CMD_READ_EEPROM 0x0b | ||
25 | /* command : SROM Write Reg */ | ||
26 | #define SR_CMD_WRITE_EEPROM 0x0c | ||
27 | /* command : SROM Write Enable Reg */ | ||
28 | #define SR_CMD_WRITE_ENABLE 0x0d | ||
29 | /* command : SROM Write Disable Reg */ | ||
30 | #define SR_CMD_WRITE_DISABLE 0x0e | ||
31 | /* command : RX Control Read Reg */ | ||
32 | #define SR_CMD_READ_RX_CTL 0x0f | ||
33 | #define SR_RX_CTL_PRO (1 << 0) | ||
34 | #define SR_RX_CTL_AMALL (1 << 1) | ||
35 | #define SR_RX_CTL_SEP (1 << 2) | ||
36 | #define SR_RX_CTL_AB (1 << 3) | ||
37 | #define SR_RX_CTL_AM (1 << 4) | ||
38 | #define SR_RX_CTL_AP (1 << 5) | ||
39 | #define SR_RX_CTL_ARP (1 << 6) | ||
40 | #define SR_RX_CTL_SO (1 << 7) | ||
41 | #define SR_RX_CTL_RH1M (1 << 8) | ||
42 | #define SR_RX_CTL_RH2M (1 << 9) | ||
43 | #define SR_RX_CTL_RH3M (1 << 10) | ||
44 | /* command : RX Control Write Reg */ | ||
45 | #define SR_CMD_WRITE_RX_CTL 0x10 | ||
46 | /* command : IPG0/IPG1/IPG2 Control Read Reg */ | ||
47 | #define SR_CMD_READ_IPG012 0x11 | ||
48 | /* command : IPG0/IPG1/IPG2 Control Write Reg */ | ||
49 | #define SR_CMD_WRITE_IPG012 0x12 | ||
50 | /* command : Node ID Read Reg */ | ||
51 | #define SR_CMD_READ_NODE_ID 0x13 | ||
52 | /* command : Node ID Write Reg */ | ||
53 | #define SR_CMD_WRITE_NODE_ID 0x14 | ||
54 | /* command : Multicast Filter Array Read Reg */ | ||
55 | #define SR_CMD_READ_MULTI_FILTER 0x15 | ||
56 | /* command : Multicast Filter Array Write Reg */ | ||
57 | #define SR_CMD_WRITE_MULTI_FILTER 0x16 | ||
58 | /* command : Eth/HomePNA PHY Address Reg */ | ||
59 | #define SR_CMD_READ_PHY_ID 0x19 | ||
60 | /* command : Medium Status Read Reg */ | ||
61 | #define SR_CMD_READ_MEDIUM_STATUS 0x1a | ||
62 | #define SR_MONITOR_LINK (1 << 1) | ||
63 | #define SR_MONITOR_MAGIC (1 << 2) | ||
64 | #define SR_MONITOR_HSFS (1 << 4) | ||
65 | /* command : Medium Status Write Reg */ | ||
66 | #define SR_CMD_WRITE_MEDIUM_MODE 0x1b | ||
67 | #define SR_MEDIUM_GM (1 << 0) | ||
68 | #define SR_MEDIUM_FD (1 << 1) | ||
69 | #define SR_MEDIUM_AC (1 << 2) | ||
70 | #define SR_MEDIUM_ENCK (1 << 3) | ||
71 | #define SR_MEDIUM_RFC (1 << 4) | ||
72 | #define SR_MEDIUM_TFC (1 << 5) | ||
73 | #define SR_MEDIUM_JFE (1 << 6) | ||
74 | #define SR_MEDIUM_PF (1 << 7) | ||
75 | #define SR_MEDIUM_RE (1 << 8) | ||
76 | #define SR_MEDIUM_PS (1 << 9) | ||
77 | #define SR_MEDIUM_RSV (1 << 10) | ||
78 | #define SR_MEDIUM_SBP (1 << 11) | ||
79 | #define SR_MEDIUM_SM (1 << 12) | ||
80 | /* command : Monitor Mode Status Read Reg */ | ||
81 | #define SR_CMD_READ_MONITOR_MODE 0x1c | ||
82 | /* command : Monitor Mode Status Write Reg */ | ||
83 | #define SR_CMD_WRITE_MONITOR_MODE 0x1d | ||
84 | /* command : GPIO Status Read Reg */ | ||
85 | #define SR_CMD_READ_GPIOS 0x1e | ||
86 | #define SR_GPIO_GPO0EN (1 << 0) /* GPIO0 Output enable */ | ||
87 | #define SR_GPIO_GPO_0 (1 << 1) /* GPIO0 Output value */ | ||
88 | #define SR_GPIO_GPO1EN (1 << 2) /* GPIO1 Output enable */ | ||
89 | #define SR_GPIO_GPO_1 (1 << 3) /* GPIO1 Output value */ | ||
90 | #define SR_GPIO_GPO2EN (1 << 4) /* GPIO2 Output enable */ | ||
91 | #define SR_GPIO_GPO_2 (1 << 5) /* GPIO2 Output value */ | ||
92 | #define SR_GPIO_RESERVED (1 << 6) /* Reserved */ | ||
93 | #define SR_GPIO_RSE (1 << 7) /* Reload serial EEPROM */ | ||
94 | /* command : GPIO Status Write Reg */ | ||
95 | #define SR_CMD_WRITE_GPIOS 0x1f | ||
96 | /* command : Eth PHY Power and Reset Control Reg */ | ||
97 | #define SR_CMD_SW_RESET 0x20 | ||
98 | #define SR_SWRESET_CLEAR 0x00 | ||
99 | #define SR_SWRESET_RR (1 << 0) | ||
100 | #define SR_SWRESET_RT (1 << 1) | ||
101 | #define SR_SWRESET_PRTE (1 << 2) | ||
102 | #define SR_SWRESET_PRL (1 << 3) | ||
103 | #define SR_SWRESET_BZ (1 << 4) | ||
104 | #define SR_SWRESET_IPRL (1 << 5) | ||
105 | #define SR_SWRESET_IPPD (1 << 6) | ||
106 | /* command : Software Interface Selection Status Read Reg */ | ||
107 | #define SR_CMD_SW_PHY_STATUS 0x21 | ||
108 | /* command : Software Interface Selection Status Write Reg */ | ||
109 | #define SR_CMD_SW_PHY_SELECT 0x22 | ||
110 | /* command : BULK in Buffer Size Reg */ | ||
111 | #define SR_CMD_BULKIN_SIZE 0x2A | ||
112 | /* command : LED_MUX Control Reg */ | ||
113 | #define SR_CMD_LED_MUX 0x70 | ||
114 | #define SR_LED_MUX_TX_ACTIVE (1 << 0) | ||
115 | #define SR_LED_MUX_RX_ACTIVE (1 << 1) | ||
116 | #define SR_LED_MUX_COLLISION (1 << 2) | ||
117 | #define SR_LED_MUX_DUP_COL (1 << 3) | ||
118 | #define SR_LED_MUX_DUP (1 << 4) | ||
119 | #define SR_LED_MUX_SPEED (1 << 5) | ||
120 | #define SR_LED_MUX_LINK_ACTIVE (1 << 6) | ||
121 | #define SR_LED_MUX_LINK (1 << 7) | ||
122 | |||
123 | /* Register Access Flags */ | ||
124 | #define SR_REQ_RD_REG (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE) | ||
125 | #define SR_REQ_WR_REG (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) | ||
126 | |||
127 | /* Multicast Filter Array size & Max Number */ | ||
128 | #define SR_MCAST_FILTER_SIZE 8 | ||
129 | #define SR_MAX_MCAST 64 | ||
130 | |||
131 | /* IPG0/1/2 Default Value */ | ||
132 | #define SR9800_IPG0_DEFAULT 0x15 | ||
133 | #define SR9800_IPG1_DEFAULT 0x0c | ||
134 | #define SR9800_IPG2_DEFAULT 0x12 | ||
135 | |||
136 | /* Medium Status Default Mode */ | ||
137 | #define SR9800_MEDIUM_DEFAULT \ | ||
138 | (SR_MEDIUM_FD | SR_MEDIUM_RFC | \ | ||
139 | SR_MEDIUM_TFC | SR_MEDIUM_PS | \ | ||
140 | SR_MEDIUM_AC | SR_MEDIUM_RE) | ||
141 | |||
142 | /* RX Control Default Setting */ | ||
143 | #define SR_DEFAULT_RX_CTL \ | ||
144 | (SR_RX_CTL_SO | SR_RX_CTL_AB | SR_RX_CTL_RH1M) | ||
145 | |||
146 | /* EEPROM Magic Number & EEPROM Size */ | ||
147 | #define SR_EEPROM_MAGIC 0xdeadbeef | ||
148 | #define SR9800_EEPROM_LEN 0xff | ||
149 | |||
150 | /* SR9800 Driver Version and Driver Name */ | ||
151 | #define DRIVER_VERSION "11-Nov-2013" | ||
152 | #define DRIVER_NAME "CoreChips" | ||
153 | #define DRIVER_FLAG \ | ||
154 | (FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET) | ||
155 | |||
156 | /* SR9800 BULKIN Buffer Size */ | ||
157 | #define SR9800_MAX_BULKIN_2K 0 | ||
158 | #define SR9800_MAX_BULKIN_4K 1 | ||
159 | #define SR9800_MAX_BULKIN_6K 2 | ||
160 | #define SR9800_MAX_BULKIN_8K 3 | ||
161 | #define SR9800_MAX_BULKIN_16K 4 | ||
162 | #define SR9800_MAX_BULKIN_20K 5 | ||
163 | #define SR9800_MAX_BULKIN_24K 6 | ||
164 | #define SR9800_MAX_BULKIN_32K 7 | ||
165 | |||
166 | struct {unsigned short size, byte_cnt, threshold; } SR9800_BULKIN_SIZE[] = { | ||
167 | /* 2k */ | ||
168 | {2048, 0x8000, 0x8001}, | ||
169 | /* 4k */ | ||
170 | {4096, 0x8100, 0x8147}, | ||
171 | /* 6k */ | ||
172 | {6144, 0x8200, 0x81EB}, | ||
173 | /* 8k */ | ||
174 | {8192, 0x8300, 0x83D7}, | ||
175 | /* 16 */ | ||
176 | {16384, 0x8400, 0x851E}, | ||
177 | /* 20k */ | ||
178 | {20480, 0x8500, 0x8666}, | ||
179 | /* 24k */ | ||
180 | {24576, 0x8600, 0x87AE}, | ||
181 | /* 32k */ | ||
182 | {32768, 0x8700, 0x8A3D}, | ||
183 | }; | ||
184 | |||
185 | /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ | ||
186 | struct sr_data { | ||
187 | u8 multi_filter[SR_MCAST_FILTER_SIZE]; | ||
188 | u8 mac_addr[ETH_ALEN]; | ||
189 | u8 phymode; | ||
190 | u8 ledmode; | ||
191 | u8 eeprom_len; | ||
192 | }; | ||
193 | |||
194 | struct sr9800_int_data { | ||
195 | __le16 res1; | ||
196 | u8 link; | ||
197 | __le16 res2; | ||
198 | u8 status; | ||
199 | __le16 res3; | ||
200 | } __packed; | ||
201 | |||
202 | #endif /* _SR9800_H */ | ||
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 4671da755e7b..dd10d5817d2a 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -542,17 +542,19 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) | |||
542 | } | 542 | } |
543 | // else network stack removes extra byte if we forced a short packet | 543 | // else network stack removes extra byte if we forced a short packet |
544 | 544 | ||
545 | if (skb->len) { | 545 | /* all data was already cloned from skb inside the driver */ |
546 | /* all data was already cloned from skb inside the driver */ | 546 | if (dev->driver_info->flags & FLAG_MULTI_PACKET) |
547 | if (dev->driver_info->flags & FLAG_MULTI_PACKET) | 547 | goto done; |
548 | dev_kfree_skb_any(skb); | 548 | |
549 | else | 549 | if (skb->len < ETH_HLEN) { |
550 | usbnet_skb_return(dev, skb); | 550 | dev->net->stats.rx_errors++; |
551 | dev->net->stats.rx_length_errors++; | ||
552 | netif_dbg(dev, rx_err, dev->net, "rx length %d\n", skb->len); | ||
553 | } else { | ||
554 | usbnet_skb_return(dev, skb); | ||
551 | return; | 555 | return; |
552 | } | 556 | } |
553 | 557 | ||
554 | netif_dbg(dev, rx_err, dev->net, "drop\n"); | ||
555 | dev->net->stats.rx_errors++; | ||
556 | done: | 558 | done: |
557 | skb_queue_tail(&dev->done, skb); | 559 | skb_queue_tail(&dev->done, skb); |
558 | } | 560 | } |
@@ -574,13 +576,6 @@ static void rx_complete (struct urb *urb) | |||
574 | switch (urb_status) { | 576 | switch (urb_status) { |
575 | /* success */ | 577 | /* success */ |
576 | case 0: | 578 | case 0: |
577 | if (skb->len < dev->net->hard_header_len) { | ||
578 | state = rx_cleanup; | ||
579 | dev->net->stats.rx_errors++; | ||
580 | dev->net->stats.rx_length_errors++; | ||
581 | netif_dbg(dev, rx_err, dev->net, | ||
582 | "rx length %d\n", skb->len); | ||
583 | } | ||
584 | break; | 579 | break; |
585 | 580 | ||
586 | /* stalls need manual reset. this is rare ... except that | 581 | /* stalls need manual reset. this is rare ... except that |