diff options
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/usb/ax88179_178a.c | 42 | ||||
-rw-r--r-- | drivers/net/usb/cdc_ether.c | 7 | ||||
-rw-r--r-- | drivers/net/usb/cdc_ncm.c | 48 | ||||
-rw-r--r-- | drivers/net/usb/r8152.c | 15 | ||||
-rw-r--r-- | drivers/net/usb/r815x.c | 248 | ||||
-rw-r--r-- | drivers/net/usb/usbnet.c | 33 |
7 files changed, 93 insertions, 302 deletions
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 433f0a00c683..e2797f1e1b31 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile | |||
@@ -11,7 +11,7 @@ obj-$(CONFIG_USB_HSO) += hso.o | |||
11 | obj-$(CONFIG_USB_NET_AX8817X) += asix.o | 11 | obj-$(CONFIG_USB_NET_AX8817X) += asix.o |
12 | asix-y := asix_devices.o asix_common.o ax88172a.o | 12 | asix-y := asix_devices.o asix_common.o ax88172a.o |
13 | obj-$(CONFIG_USB_NET_AX88179_178A) += ax88179_178a.o | 13 | obj-$(CONFIG_USB_NET_AX88179_178A) += ax88179_178a.o |
14 | obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r815x.o | 14 | obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.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 |
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 955df81a4358..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; |
@@ -1395,6 +1387,19 @@ static const struct driver_info ax88178a_info = { | |||
1395 | .tx_fixup = ax88179_tx_fixup, | 1387 | .tx_fixup = ax88179_tx_fixup, |
1396 | }; | 1388 | }; |
1397 | 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 | |||
1398 | static const struct driver_info sitecom_info = { | 1403 | static const struct driver_info sitecom_info = { |
1399 | .description = "Sitecom USB 3.0 to Gigabit Adapter", | 1404 | .description = "Sitecom USB 3.0 to Gigabit Adapter", |
1400 | .bind = ax88179_bind, | 1405 | .bind = ax88179_bind, |
@@ -1421,6 +1426,19 @@ static const struct driver_info samsung_info = { | |||
1421 | .tx_fixup = ax88179_tx_fixup, | 1426 | .tx_fixup = ax88179_tx_fixup, |
1422 | }; | 1427 | }; |
1423 | 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 | |||
1424 | static const struct usb_device_id products[] = { | 1442 | static const struct usb_device_id products[] = { |
1425 | { | 1443 | { |
1426 | /* ASIX AX88179 10/100/1000 */ | 1444 | /* ASIX AX88179 10/100/1000 */ |
@@ -1431,6 +1449,10 @@ static const struct usb_device_id products[] = { | |||
1431 | USB_DEVICE(0x0b95, 0x178a), | 1449 | USB_DEVICE(0x0b95, 0x178a), |
1432 | .driver_info = (unsigned long)&ax88178a_info, | 1450 | .driver_info = (unsigned long)&ax88178a_info, |
1433 | }, { | 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 | }, { | ||
1434 | /* Sitecom USB 3.0 to Gigabit Adapter */ | 1456 | /* Sitecom USB 3.0 to Gigabit Adapter */ |
1435 | USB_DEVICE(0x0df6, 0x0072), | 1457 | USB_DEVICE(0x0df6, 0x0072), |
1436 | .driver_info = (unsigned long)&sitecom_info, | 1458 | .driver_info = (unsigned long)&sitecom_info, |
@@ -1438,6 +1460,10 @@ static const struct usb_device_id products[] = { | |||
1438 | /* Samsung USB Ethernet Adapter */ | 1460 | /* Samsung USB Ethernet Adapter */ |
1439 | USB_DEVICE(0x04e8, 0xa100), | 1461 | USB_DEVICE(0x04e8, 0xa100), |
1440 | .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, | ||
1441 | }, | 1467 | }, |
1442 | { }, | 1468 | { }, |
1443 | }; | 1469 | }; |
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 42e176912c8e..bd363b27e854 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c | |||
@@ -652,6 +652,13 @@ static const struct usb_device_id products[] = { | |||
652 | .driver_info = 0, | 652 | .driver_info = 0, |
653 | }, | 653 | }, |
654 | 654 | ||
655 | /* Samsung USB Ethernet Adapters */ | ||
656 | { | ||
657 | USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, 0xa101, USB_CLASS_COMM, | ||
658 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | ||
659 | .driver_info = 0, | ||
660 | }, | ||
661 | |||
655 | /* WHITELIST!!! | 662 | /* WHITELIST!!! |
656 | * | 663 | * |
657 | * CDC Ether uses two interfaces, not necessarily consecutive. | 664 | * CDC Ether uses two interfaces, not necessarily consecutive. |
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index dbff290ed0e4..d350d2795e10 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
@@ -68,7 +68,6 @@ static struct usb_driver cdc_ncm_driver; | |||
68 | static int cdc_ncm_setup(struct usbnet *dev) | 68 | static int cdc_ncm_setup(struct usbnet *dev) |
69 | { | 69 | { |
70 | struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; | 70 | struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; |
71 | struct usb_cdc_ncm_ntb_parameters ncm_parm; | ||
72 | u32 val; | 71 | u32 val; |
73 | u8 flags; | 72 | u8 flags; |
74 | u8 iface_no; | 73 | u8 iface_no; |
@@ -82,22 +81,22 @@ static int cdc_ncm_setup(struct usbnet *dev) | |||
82 | err = usbnet_read_cmd(dev, USB_CDC_GET_NTB_PARAMETERS, | 81 | err = usbnet_read_cmd(dev, USB_CDC_GET_NTB_PARAMETERS, |
83 | USB_TYPE_CLASS | USB_DIR_IN | 82 | USB_TYPE_CLASS | USB_DIR_IN |
84 | |USB_RECIP_INTERFACE, | 83 | |USB_RECIP_INTERFACE, |
85 | 0, iface_no, &ncm_parm, | 84 | 0, iface_no, &ctx->ncm_parm, |
86 | sizeof(ncm_parm)); | 85 | sizeof(ctx->ncm_parm)); |
87 | if (err < 0) { | 86 | if (err < 0) { |
88 | dev_err(&dev->intf->dev, "failed GET_NTB_PARAMETERS\n"); | 87 | dev_err(&dev->intf->dev, "failed GET_NTB_PARAMETERS\n"); |
89 | return err; /* GET_NTB_PARAMETERS is required */ | 88 | return err; /* GET_NTB_PARAMETERS is required */ |
90 | } | 89 | } |
91 | 90 | ||
92 | /* read correct set of parameters according to device mode */ | 91 | /* read correct set of parameters according to device mode */ |
93 | ctx->rx_max = le32_to_cpu(ncm_parm.dwNtbInMaxSize); | 92 | ctx->rx_max = le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize); |
94 | ctx->tx_max = le32_to_cpu(ncm_parm.dwNtbOutMaxSize); | 93 | ctx->tx_max = le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize); |
95 | ctx->tx_remainder = le16_to_cpu(ncm_parm.wNdpOutPayloadRemainder); | 94 | ctx->tx_remainder = le16_to_cpu(ctx->ncm_parm.wNdpOutPayloadRemainder); |
96 | ctx->tx_modulus = le16_to_cpu(ncm_parm.wNdpOutDivisor); | 95 | ctx->tx_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutDivisor); |
97 | ctx->tx_ndp_modulus = le16_to_cpu(ncm_parm.wNdpOutAlignment); | 96 | ctx->tx_ndp_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutAlignment); |
98 | /* devices prior to NCM Errata shall set this field to zero */ | 97 | /* devices prior to NCM Errata shall set this field to zero */ |
99 | ctx->tx_max_datagrams = le16_to_cpu(ncm_parm.wNtbOutMaxDatagrams); | 98 | ctx->tx_max_datagrams = le16_to_cpu(ctx->ncm_parm.wNtbOutMaxDatagrams); |
100 | ntb_fmt_supported = le16_to_cpu(ncm_parm.bmNtbFormatsSupported); | 99 | ntb_fmt_supported = le16_to_cpu(ctx->ncm_parm.bmNtbFormatsSupported); |
101 | 100 | ||
102 | /* there are some minor differences in NCM and MBIM defaults */ | 101 | /* there are some minor differences in NCM and MBIM defaults */ |
103 | if (cdc_ncm_comm_intf_is_mbim(ctx->control->cur_altsetting)) { | 102 | if (cdc_ncm_comm_intf_is_mbim(ctx->control->cur_altsetting)) { |
@@ -146,7 +145,7 @@ static int cdc_ncm_setup(struct usbnet *dev) | |||
146 | } | 145 | } |
147 | 146 | ||
148 | /* inform device about NTB input size changes */ | 147 | /* inform device about NTB input size changes */ |
149 | if (ctx->rx_max != le32_to_cpu(ncm_parm.dwNtbInMaxSize)) { | 148 | if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) { |
150 | __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); | 149 | __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); |
151 | 150 | ||
152 | err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_INPUT_SIZE, | 151 | err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_INPUT_SIZE, |
@@ -162,14 +161,6 @@ static int cdc_ncm_setup(struct usbnet *dev) | |||
162 | dev_dbg(&dev->intf->dev, "Using default maximum transmit length=%d\n", | 161 | dev_dbg(&dev->intf->dev, "Using default maximum transmit length=%d\n", |
163 | CDC_NCM_NTB_MAX_SIZE_TX); | 162 | CDC_NCM_NTB_MAX_SIZE_TX); |
164 | ctx->tx_max = CDC_NCM_NTB_MAX_SIZE_TX; | 163 | ctx->tx_max = CDC_NCM_NTB_MAX_SIZE_TX; |
165 | |||
166 | /* Adding a pad byte here simplifies the handling in | ||
167 | * cdc_ncm_fill_tx_frame, by making tx_max always | ||
168 | * represent the real skb max size. | ||
169 | */ | ||
170 | if (ctx->tx_max % usb_maxpacket(dev->udev, dev->out, 1) == 0) | ||
171 | ctx->tx_max++; | ||
172 | |||
173 | } | 164 | } |
174 | 165 | ||
175 | /* | 166 | /* |
@@ -439,6 +430,10 @@ advance: | |||
439 | goto error2; | 430 | goto error2; |
440 | } | 431 | } |
441 | 432 | ||
433 | /* initialize data interface */ | ||
434 | if (cdc_ncm_setup(dev)) | ||
435 | goto error2; | ||
436 | |||
442 | /* configure data interface */ | 437 | /* configure data interface */ |
443 | temp = usb_set_interface(dev->udev, iface_no, data_altsetting); | 438 | temp = usb_set_interface(dev->udev, iface_no, data_altsetting); |
444 | if (temp) { | 439 | if (temp) { |
@@ -453,12 +448,6 @@ advance: | |||
453 | goto error2; | 448 | goto error2; |
454 | } | 449 | } |
455 | 450 | ||
456 | /* initialize data interface */ | ||
457 | if (cdc_ncm_setup(dev)) { | ||
458 | dev_dbg(&intf->dev, "cdc_ncm_setup() failed\n"); | ||
459 | goto error2; | ||
460 | } | ||
461 | |||
462 | usb_set_intfdata(ctx->data, dev); | 451 | usb_set_intfdata(ctx->data, dev); |
463 | usb_set_intfdata(ctx->control, dev); | 452 | usb_set_intfdata(ctx->control, dev); |
464 | 453 | ||
@@ -475,6 +464,15 @@ advance: | |||
475 | dev->hard_mtu = ctx->tx_max; | 464 | dev->hard_mtu = ctx->tx_max; |
476 | dev->rx_urb_size = ctx->rx_max; | 465 | dev->rx_urb_size = ctx->rx_max; |
477 | 466 | ||
467 | /* cdc_ncm_setup will override dwNtbOutMaxSize if it is | ||
468 | * outside the sane range. Adding a pad byte here if necessary | ||
469 | * simplifies the handling in cdc_ncm_fill_tx_frame, making | ||
470 | * tx_max always represent the real skb max size. | ||
471 | */ | ||
472 | if (ctx->tx_max != le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize) && | ||
473 | ctx->tx_max % usb_maxpacket(dev->udev, dev->out, 1) == 0) | ||
474 | ctx->tx_max++; | ||
475 | |||
478 | return 0; | 476 | return 0; |
479 | 477 | ||
480 | error2: | 478 | error2: |
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index d89dbe395ad2..adb12f349a61 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
@@ -449,9 +449,6 @@ enum rtl8152_flags { | |||
449 | #define MCU_TYPE_PLA 0x0100 | 449 | #define MCU_TYPE_PLA 0x0100 |
450 | #define MCU_TYPE_USB 0x0000 | 450 | #define MCU_TYPE_USB 0x0000 |
451 | 451 | ||
452 | #define REALTEK_USB_DEVICE(vend, prod) \ | ||
453 | USB_DEVICE_INTERFACE_CLASS(vend, prod, USB_CLASS_VENDOR_SPEC) | ||
454 | |||
455 | struct rx_desc { | 452 | struct rx_desc { |
456 | __le32 opts1; | 453 | __le32 opts1; |
457 | #define RX_LEN_MASK 0x7fff | 454 | #define RX_LEN_MASK 0x7fff |
@@ -2739,6 +2736,12 @@ static int rtl8152_probe(struct usb_interface *intf, | |||
2739 | struct net_device *netdev; | 2736 | struct net_device *netdev; |
2740 | int ret; | 2737 | int ret; |
2741 | 2738 | ||
2739 | if (udev->actconfig->desc.bConfigurationValue != 1) { | ||
2740 | usb_driver_set_configuration(udev, 1); | ||
2741 | return -ENODEV; | ||
2742 | } | ||
2743 | |||
2744 | usb_reset_device(udev); | ||
2742 | netdev = alloc_etherdev(sizeof(struct r8152)); | 2745 | netdev = alloc_etherdev(sizeof(struct r8152)); |
2743 | if (!netdev) { | 2746 | if (!netdev) { |
2744 | dev_err(&intf->dev, "Out of memory\n"); | 2747 | dev_err(&intf->dev, "Out of memory\n"); |
@@ -2819,9 +2822,9 @@ static void rtl8152_disconnect(struct usb_interface *intf) | |||
2819 | 2822 | ||
2820 | /* table of devices that work with this driver */ | 2823 | /* table of devices that work with this driver */ |
2821 | static struct usb_device_id rtl8152_table[] = { | 2824 | static struct usb_device_id rtl8152_table[] = { |
2822 | {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8152)}, | 2825 | {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8152)}, |
2823 | {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8153)}, | 2826 | {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8153)}, |
2824 | {REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG)}, | 2827 | {USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG)}, |
2825 | {} | 2828 | {} |
2826 | }; | 2829 | }; |
2827 | 2830 | ||
diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c deleted file mode 100644 index f0a8791b7636..000000000000 --- a/drivers/net/usb/r815x.c +++ /dev/null | |||
@@ -1,248 +0,0 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/netdevice.h> | ||
3 | #include <linux/mii.h> | ||
4 | #include <linux/usb.h> | ||
5 | #include <linux/usb/cdc.h> | ||
6 | #include <linux/usb/usbnet.h> | ||
7 | |||
8 | #define RTL815x_REQT_READ 0xc0 | ||
9 | #define RTL815x_REQT_WRITE 0x40 | ||
10 | #define RTL815x_REQ_GET_REGS 0x05 | ||
11 | #define RTL815x_REQ_SET_REGS 0x05 | ||
12 | |||
13 | #define MCU_TYPE_PLA 0x0100 | ||
14 | #define OCP_BASE 0xe86c | ||
15 | #define BASE_MII 0xa400 | ||
16 | |||
17 | #define BYTE_EN_DWORD 0xff | ||
18 | #define BYTE_EN_WORD 0x33 | ||
19 | #define BYTE_EN_BYTE 0x11 | ||
20 | |||
21 | #define R815x_PHY_ID 32 | ||
22 | #define REALTEK_VENDOR_ID 0x0bda | ||
23 | |||
24 | |||
25 | static int pla_read_word(struct usb_device *udev, u16 index) | ||
26 | { | ||
27 | int ret; | ||
28 | u8 shift = index & 2; | ||
29 | __le32 *tmp; | ||
30 | |||
31 | tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); | ||
32 | if (!tmp) | ||
33 | return -ENOMEM; | ||
34 | |||
35 | index &= ~3; | ||
36 | |||
37 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
38 | RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, | ||
39 | index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); | ||
40 | if (ret < 0) | ||
41 | goto out2; | ||
42 | |||
43 | ret = __le32_to_cpu(*tmp); | ||
44 | ret >>= (shift * 8); | ||
45 | ret &= 0xffff; | ||
46 | |||
47 | out2: | ||
48 | kfree(tmp); | ||
49 | return ret; | ||
50 | } | ||
51 | |||
52 | static int pla_write_word(struct usb_device *udev, u16 index, u32 data) | ||
53 | { | ||
54 | __le32 *tmp; | ||
55 | u32 mask = 0xffff; | ||
56 | u16 byen = BYTE_EN_WORD; | ||
57 | u8 shift = index & 2; | ||
58 | int ret; | ||
59 | |||
60 | tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); | ||
61 | if (!tmp) | ||
62 | return -ENOMEM; | ||
63 | |||
64 | data &= mask; | ||
65 | |||
66 | if (shift) { | ||
67 | byen <<= shift; | ||
68 | mask <<= (shift * 8); | ||
69 | data <<= (shift * 8); | ||
70 | index &= ~3; | ||
71 | } | ||
72 | |||
73 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
74 | RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, | ||
75 | index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); | ||
76 | if (ret < 0) | ||
77 | goto out3; | ||
78 | |||
79 | data |= __le32_to_cpu(*tmp) & ~mask; | ||
80 | *tmp = __cpu_to_le32(data); | ||
81 | |||
82 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
83 | RTL815x_REQ_SET_REGS, RTL815x_REQT_WRITE, | ||
84 | index, MCU_TYPE_PLA | byen, tmp, sizeof(*tmp), | ||
85 | 500); | ||
86 | |||
87 | out3: | ||
88 | kfree(tmp); | ||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | static int ocp_reg_read(struct usbnet *dev, u16 addr) | ||
93 | { | ||
94 | u16 ocp_base, ocp_index; | ||
95 | int ret; | ||
96 | |||
97 | ocp_base = addr & 0xf000; | ||
98 | ret = pla_write_word(dev->udev, OCP_BASE, ocp_base); | ||
99 | if (ret < 0) | ||
100 | goto out; | ||
101 | |||
102 | ocp_index = (addr & 0x0fff) | 0xb000; | ||
103 | ret = pla_read_word(dev->udev, ocp_index); | ||
104 | |||
105 | out: | ||
106 | return ret; | ||
107 | } | ||
108 | |||
109 | static int ocp_reg_write(struct usbnet *dev, u16 addr, u16 data) | ||
110 | { | ||
111 | u16 ocp_base, ocp_index; | ||
112 | int ret; | ||
113 | |||
114 | ocp_base = addr & 0xf000; | ||
115 | ret = pla_write_word(dev->udev, OCP_BASE, ocp_base); | ||
116 | if (ret < 0) | ||
117 | goto out1; | ||
118 | |||
119 | ocp_index = (addr & 0x0fff) | 0xb000; | ||
120 | ret = pla_write_word(dev->udev, ocp_index, data); | ||
121 | |||
122 | out1: | ||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | static int r815x_mdio_read(struct net_device *netdev, int phy_id, int reg) | ||
127 | { | ||
128 | struct usbnet *dev = netdev_priv(netdev); | ||
129 | int ret; | ||
130 | |||
131 | if (phy_id != R815x_PHY_ID) | ||
132 | return -EINVAL; | ||
133 | |||
134 | if (usb_autopm_get_interface(dev->intf) < 0) | ||
135 | return -ENODEV; | ||
136 | |||
137 | ret = ocp_reg_read(dev, BASE_MII + reg * 2); | ||
138 | |||
139 | usb_autopm_put_interface(dev->intf); | ||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | static | ||
144 | void r815x_mdio_write(struct net_device *netdev, int phy_id, int reg, int val) | ||
145 | { | ||
146 | struct usbnet *dev = netdev_priv(netdev); | ||
147 | |||
148 | if (phy_id != R815x_PHY_ID) | ||
149 | return; | ||
150 | |||
151 | if (usb_autopm_get_interface(dev->intf) < 0) | ||
152 | return; | ||
153 | |||
154 | ocp_reg_write(dev, BASE_MII + reg * 2, val); | ||
155 | |||
156 | usb_autopm_put_interface(dev->intf); | ||
157 | } | ||
158 | |||
159 | static int r8153_bind(struct usbnet *dev, struct usb_interface *intf) | ||
160 | { | ||
161 | int status; | ||
162 | |||
163 | status = usbnet_cdc_bind(dev, intf); | ||
164 | if (status < 0) | ||
165 | return status; | ||
166 | |||
167 | dev->mii.dev = dev->net; | ||
168 | dev->mii.mdio_read = r815x_mdio_read; | ||
169 | dev->mii.mdio_write = r815x_mdio_write; | ||
170 | dev->mii.phy_id_mask = 0x3f; | ||
171 | dev->mii.reg_num_mask = 0x1f; | ||
172 | dev->mii.phy_id = R815x_PHY_ID; | ||
173 | dev->mii.supports_gmii = 1; | ||
174 | |||
175 | return status; | ||
176 | } | ||
177 | |||
178 | static int r8152_bind(struct usbnet *dev, struct usb_interface *intf) | ||
179 | { | ||
180 | int status; | ||
181 | |||
182 | status = usbnet_cdc_bind(dev, intf); | ||
183 | if (status < 0) | ||
184 | return status; | ||
185 | |||
186 | dev->mii.dev = dev->net; | ||
187 | dev->mii.mdio_read = r815x_mdio_read; | ||
188 | dev->mii.mdio_write = r815x_mdio_write; | ||
189 | dev->mii.phy_id_mask = 0x3f; | ||
190 | dev->mii.reg_num_mask = 0x1f; | ||
191 | dev->mii.phy_id = R815x_PHY_ID; | ||
192 | dev->mii.supports_gmii = 0; | ||
193 | |||
194 | return status; | ||
195 | } | ||
196 | |||
197 | static const struct driver_info r8152_info = { | ||
198 | .description = "RTL8152 ECM Device", | ||
199 | .flags = FLAG_ETHER | FLAG_POINTTOPOINT, | ||
200 | .bind = r8152_bind, | ||
201 | .unbind = usbnet_cdc_unbind, | ||
202 | .status = usbnet_cdc_status, | ||
203 | .manage_power = usbnet_manage_power, | ||
204 | }; | ||
205 | |||
206 | static const struct driver_info r8153_info = { | ||
207 | .description = "RTL8153 ECM Device", | ||
208 | .flags = FLAG_ETHER | FLAG_POINTTOPOINT, | ||
209 | .bind = r8153_bind, | ||
210 | .unbind = usbnet_cdc_unbind, | ||
211 | .status = usbnet_cdc_status, | ||
212 | .manage_power = usbnet_manage_power, | ||
213 | }; | ||
214 | |||
215 | static const struct usb_device_id products[] = { | ||
216 | { | ||
217 | USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM, | ||
218 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | ||
219 | .driver_info = (unsigned long) &r8152_info, | ||
220 | }, | ||
221 | |||
222 | { | ||
223 | USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8153, USB_CLASS_COMM, | ||
224 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | ||
225 | .driver_info = (unsigned long) &r8153_info, | ||
226 | }, | ||
227 | |||
228 | { }, /* END */ | ||
229 | }; | ||
230 | MODULE_DEVICE_TABLE(usb, products); | ||
231 | |||
232 | static struct usb_driver r815x_driver = { | ||
233 | .name = "r815x", | ||
234 | .id_table = products, | ||
235 | .probe = usbnet_probe, | ||
236 | .disconnect = usbnet_disconnect, | ||
237 | .suspend = usbnet_suspend, | ||
238 | .resume = usbnet_resume, | ||
239 | .reset_resume = usbnet_resume, | ||
240 | .supports_autosuspend = 1, | ||
241 | .disable_hub_initiated_lpm = 1, | ||
242 | }; | ||
243 | |||
244 | module_usb_driver(r815x_driver); | ||
245 | |||
246 | MODULE_AUTHOR("Hayes Wang"); | ||
247 | MODULE_DESCRIPTION("Realtek USB ECM device"); | ||
248 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index dd10d5817d2a..f9e96c427558 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -752,14 +752,12 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs); | |||
752 | // precondition: never called in_interrupt | 752 | // precondition: never called in_interrupt |
753 | static void usbnet_terminate_urbs(struct usbnet *dev) | 753 | static void usbnet_terminate_urbs(struct usbnet *dev) |
754 | { | 754 | { |
755 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup); | ||
756 | DECLARE_WAITQUEUE(wait, current); | 755 | DECLARE_WAITQUEUE(wait, current); |
757 | int temp; | 756 | int temp; |
758 | 757 | ||
759 | /* ensure there are no more active urbs */ | 758 | /* ensure there are no more active urbs */ |
760 | add_wait_queue(&unlink_wakeup, &wait); | 759 | add_wait_queue(&dev->wait, &wait); |
761 | set_current_state(TASK_UNINTERRUPTIBLE); | 760 | set_current_state(TASK_UNINTERRUPTIBLE); |
762 | dev->wait = &unlink_wakeup; | ||
763 | temp = unlink_urbs(dev, &dev->txq) + | 761 | temp = unlink_urbs(dev, &dev->txq) + |
764 | unlink_urbs(dev, &dev->rxq); | 762 | unlink_urbs(dev, &dev->rxq); |
765 | 763 | ||
@@ -773,15 +771,14 @@ static void usbnet_terminate_urbs(struct usbnet *dev) | |||
773 | "waited for %d urb completions\n", temp); | 771 | "waited for %d urb completions\n", temp); |
774 | } | 772 | } |
775 | set_current_state(TASK_RUNNING); | 773 | set_current_state(TASK_RUNNING); |
776 | dev->wait = NULL; | 774 | remove_wait_queue(&dev->wait, &wait); |
777 | remove_wait_queue(&unlink_wakeup, &wait); | ||
778 | } | 775 | } |
779 | 776 | ||
780 | int usbnet_stop (struct net_device *net) | 777 | int usbnet_stop (struct net_device *net) |
781 | { | 778 | { |
782 | struct usbnet *dev = netdev_priv(net); | 779 | struct usbnet *dev = netdev_priv(net); |
783 | struct driver_info *info = dev->driver_info; | 780 | struct driver_info *info = dev->driver_info; |
784 | int retval; | 781 | int retval, pm; |
785 | 782 | ||
786 | clear_bit(EVENT_DEV_OPEN, &dev->flags); | 783 | clear_bit(EVENT_DEV_OPEN, &dev->flags); |
787 | netif_stop_queue (net); | 784 | netif_stop_queue (net); |
@@ -791,6 +788,8 @@ int usbnet_stop (struct net_device *net) | |||
791 | net->stats.rx_packets, net->stats.tx_packets, | 788 | net->stats.rx_packets, net->stats.tx_packets, |
792 | net->stats.rx_errors, net->stats.tx_errors); | 789 | net->stats.rx_errors, net->stats.tx_errors); |
793 | 790 | ||
791 | /* to not race resume */ | ||
792 | pm = usb_autopm_get_interface(dev->intf); | ||
794 | /* allow minidriver to stop correctly (wireless devices to turn off | 793 | /* allow minidriver to stop correctly (wireless devices to turn off |
795 | * radio etc) */ | 794 | * radio etc) */ |
796 | if (info->stop) { | 795 | if (info->stop) { |
@@ -817,6 +816,9 @@ int usbnet_stop (struct net_device *net) | |||
817 | dev->flags = 0; | 816 | dev->flags = 0; |
818 | del_timer_sync (&dev->delay); | 817 | del_timer_sync (&dev->delay); |
819 | tasklet_kill (&dev->bh); | 818 | tasklet_kill (&dev->bh); |
819 | if (!pm) | ||
820 | usb_autopm_put_interface(dev->intf); | ||
821 | |||
820 | if (info->manage_power && | 822 | if (info->manage_power && |
821 | !test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags)) | 823 | !test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags)) |
822 | info->manage_power(dev, 0); | 824 | info->manage_power(dev, 0); |
@@ -1437,11 +1439,12 @@ static void usbnet_bh (unsigned long param) | |||
1437 | /* restart RX again after disabling due to high error rate */ | 1439 | /* restart RX again after disabling due to high error rate */ |
1438 | clear_bit(EVENT_RX_KILL, &dev->flags); | 1440 | clear_bit(EVENT_RX_KILL, &dev->flags); |
1439 | 1441 | ||
1440 | // waiting for all pending urbs to complete? | 1442 | /* waiting for all pending urbs to complete? |
1441 | if (dev->wait) { | 1443 | * only then can we forgo submitting anew |
1442 | if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) { | 1444 | */ |
1443 | wake_up (dev->wait); | 1445 | if (waitqueue_active(&dev->wait)) { |
1444 | } | 1446 | if (dev->txq.qlen + dev->rxq.qlen + dev->done.qlen == 0) |
1447 | wake_up_all(&dev->wait); | ||
1445 | 1448 | ||
1446 | // or are we maybe short a few urbs? | 1449 | // or are we maybe short a few urbs? |
1447 | } else if (netif_running (dev->net) && | 1450 | } else if (netif_running (dev->net) && |
@@ -1580,6 +1583,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1580 | dev->driver_name = name; | 1583 | dev->driver_name = name; |
1581 | dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV | 1584 | dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV |
1582 | | NETIF_MSG_PROBE | NETIF_MSG_LINK); | 1585 | | NETIF_MSG_PROBE | NETIF_MSG_LINK); |
1586 | init_waitqueue_head(&dev->wait); | ||
1583 | skb_queue_head_init (&dev->rxq); | 1587 | skb_queue_head_init (&dev->rxq); |
1584 | skb_queue_head_init (&dev->txq); | 1588 | skb_queue_head_init (&dev->txq); |
1585 | skb_queue_head_init (&dev->done); | 1589 | skb_queue_head_init (&dev->done); |
@@ -1791,9 +1795,10 @@ int usbnet_resume (struct usb_interface *intf) | |||
1791 | spin_unlock_irq(&dev->txq.lock); | 1795 | spin_unlock_irq(&dev->txq.lock); |
1792 | 1796 | ||
1793 | if (test_bit(EVENT_DEV_OPEN, &dev->flags)) { | 1797 | if (test_bit(EVENT_DEV_OPEN, &dev->flags)) { |
1794 | /* handle remote wakeup ASAP */ | 1798 | /* handle remote wakeup ASAP |
1795 | if (!dev->wait && | 1799 | * we cannot race against stop |
1796 | netif_device_present(dev->net) && | 1800 | */ |
1801 | if (netif_device_present(dev->net) && | ||
1797 | !timer_pending(&dev->delay) && | 1802 | !timer_pending(&dev->delay) && |
1798 | !test_bit(EVENT_RX_HALT, &dev->flags)) | 1803 | !test_bit(EVENT_RX_HALT, &dev->flags)) |
1799 | rx_alloc_submit(dev, GFP_NOIO); | 1804 | rx_alloc_submit(dev, GFP_NOIO); |