diff options
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/Kconfig | 4 | ||||
-rw-r--r-- | drivers/net/usb/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/usb/ax88179_178a.c | 14 | ||||
-rw-r--r-- | drivers/net/usb/cdc_ether.c | 31 | ||||
-rw-r--r-- | drivers/net/usb/ipheth.c | 5 | ||||
-rw-r--r-- | drivers/net/usb/kalmia.c | 45 | ||||
-rw-r--r-- | drivers/net/usb/qmi_wwan.c | 4 | ||||
-rw-r--r-- | drivers/net/usb/r8152.c | 143 | ||||
-rw-r--r-- | drivers/net/usb/r815x.c | 256 | ||||
-rw-r--r-- | drivers/net/usb/smsc75xx.c | 12 |
10 files changed, 375 insertions, 141 deletions
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 287cc624b90..d84bfd4109a 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -67,7 +67,6 @@ config USB_KAWETH config USB_PEGASUS tristate "USB Pegasus/Pegasus-II based ethernet device support" - select NET_CORE select MII ---help--- Say Y here if you know you have Pegasus or Pegasus-II based adapter. @@ -83,7 +82,6 @@ config USB_PEGASUS config USB_RTL8150 tristate "USB RTL8150 based ethernet device support" - select NET_CORE select MII help Say Y here if you have RTL8150 based usb-ethernet adapter. @@ -95,7 +93,6 @@ config USB_RTL8150 config USB_RTL8152 tristate "Realtek RTL8152 Based USB 2.0 Ethernet Adapters" - select NET_CORE select MII help This option adds support for Realtek RTL8152 based USB 2.0 @@ -106,7 +103,6 @@ config USB_RTL8152 config USB_USBNET tristate "Multi-purpose USB Networking Framework" - select NET_CORE select MII ---help--- This driver supports several kinds of network links over USB, diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 9ab5c9d4b45..e8171784529 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_USB_HSO) += hso.o obj-$(CONFIG_USB_NET_AX8817X) += asix.o asix-y := asix_devices.o asix_common.o ax88172a.o obj-$(CONFIG_USB_NET_AX88179_178A) += ax88179_178a.o -obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o +obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r815x.o obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o obj-$(CONFIG_USB_NET_DM9601) += dm9601.o obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index bd8758fa38c..2bc87e3a814 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -1029,10 +1029,10 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) dev->mii.supports_gmii = 1; dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO; + NETIF_F_RXCSUM; dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO; + NETIF_F_RXCSUM; /* Enable checksum offload */ *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | @@ -1173,7 +1173,6 @@ ax88179_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) if (((skb->len + 8) % frame_size) == 0) tx_hdr2 |= 0x80008000; /* Enable padding */ - skb_linearize(skb); headroom = skb_headroom(skb); tailroom = skb_tailroom(skb); @@ -1317,10 +1316,10 @@ static int ax88179_reset(struct usbnet *dev) 1, 1, tmp); dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO; + NETIF_F_RXCSUM; dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO; + NETIF_F_RXCSUM; /* Enable checksum offload */ *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | @@ -1371,7 +1370,7 @@ static int ax88179_stop(struct usbnet *dev) } static const struct driver_info ax88179_info = { - .description = "ASIX AX88179 USB 3.0 Gigibit Ethernet", + .description = "ASIX AX88179 USB 3.0 Gigabit Ethernet", .bind = ax88179_bind, .unbind = ax88179_unbind, .status = ax88179_status, @@ -1384,7 +1383,7 @@ static const struct driver_info ax88179_info = { }; static const struct driver_info ax88178a_info = { - .description = "ASIX AX88178A USB 2.0 Gigibit Ethernet", + .description = "ASIX AX88178A USB 2.0 Gigabit Ethernet", .bind = ax88179_bind, .unbind = ax88179_unbind, .status = ax88179_status, @@ -1433,6 +1432,7 @@ static struct usb_driver ax88179_178a_driver = { .probe = usbnet_probe, .suspend = ax88179_suspend, .resume = ax88179_resume, + .reset_resume = ax88179_resume, .disconnect = usbnet_disconnect, .supports_autosuspend = 1, .disable_hub_initiated_lpm = 1, diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 04ee044dde5..03ad4dc293a 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -215,6 +215,10 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) goto bad_desc; } + /* some devices merge these - skip class check */ + if (info->control == info->data) + goto next_desc; + /* a data interface altsetting does the real i/o */ d = &info->data->cur_altsetting->desc; if (d->bInterfaceClass != USB_CLASS_CDC_DATA) { @@ -304,19 +308,23 @@ next_desc: /* claim data interface and set it up ... with side effects. * network traffic can't flow until an altsetting is enabled. */ - status = usb_driver_claim_interface(driver, info->data, dev); - if (status < 0) - return status; + if (info->data != info->control) { + status = usb_driver_claim_interface(driver, info->data, dev); + if (status < 0) + return status; + } status = usbnet_get_endpoints(dev, info->data); if (status < 0) { /* ensure immediate exit from usbnet_disconnect */ usb_set_intfdata(info->data, NULL); - usb_driver_release_interface(driver, info->data); + if (info->data != info->control) + usb_driver_release_interface(driver, info->data); return status; } /* status endpoint: optional for CDC Ethernet, not RNDIS (or ACM) */ - dev->status = NULL; + if (info->data != info->control) + dev->status = NULL; if (info->control->cur_altsetting->desc.bNumEndpoints == 1) { struct usb_endpoint_descriptor *desc; @@ -349,6 +357,10 @@ void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf) struct cdc_state *info = (void *) &dev->data; struct usb_driver *driver = driver_of(intf); + /* combined interface - nothing to do */ + if (info->data == info->control) + return; + /* disconnect master --> disconnect slave */ if (intf == info->control && info->data) { /* ensure immediate exit from usbnet_disconnect */ @@ -634,13 +646,18 @@ static const struct usb_device_id products [] = { }, /* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */ -#if defined(CONFIG_USB_RTL8152) || defined(CONFIG_USB_RTL8152_MODULE) { USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), .driver_info = 0, }, -#endif + +/* Realtek RTL8153 Based USB 3.0 Ethernet Adapters */ +{ + USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8153, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, /* * WHITELIST!!! diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index 534d8becbbd..ff8594d8dd2 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -60,6 +60,7 @@ #define USB_PRODUCT_IPHONE_3GS 0x1294 #define USB_PRODUCT_IPHONE_4 0x1297 #define USB_PRODUCT_IPAD 0x129a +#define USB_PRODUCT_IPAD_MINI 0x12ab #define USB_PRODUCT_IPHONE_4_VZW 0x129c #define USB_PRODUCT_IPHONE_4S 0x12a0 #define USB_PRODUCT_IPHONE_5 0x12a8 @@ -107,6 +108,10 @@ static struct usb_device_id ipheth_table[] = { IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, IPHETH_USBINTF_PROTO) }, { USB_DEVICE_AND_INTERFACE_INFO( + USB_VENDOR_APPLE, USB_PRODUCT_IPAD_MINI, + IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, + IPHETH_USBINTF_PROTO) }, + { USB_DEVICE_AND_INTERFACE_INFO( USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4_VZW, IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, IPHETH_USBINTF_PROTO) }, diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c index 0192073e53a..6866eae3e38 100644 --- a/drivers/net/usb/kalmia.c +++ b/drivers/net/usb/kalmia.c @@ -221,12 +221,9 @@ done: memset(skb_put(skb, padlen), 0, padlen); } - netdev_dbg( - dev->net, - "Sending package with length %i and padding %i. Header: %02x:%02x:%02x:%02x:%02x:%02x.", - content_len, padlen, header_start[0], header_start[1], - header_start[2], header_start[3], header_start[4], - header_start[5]); + netdev_dbg(dev->net, + "Sending package with length %i and padding %i. Header: %6phC.", + content_len, padlen, header_start); return skb; } @@ -263,32 +260,23 @@ kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb) sizeof(EXPECTED_UNKNOWN_HEADER_1)) || !memcmp( header_start, EXPECTED_UNKNOWN_HEADER_2, sizeof(EXPECTED_UNKNOWN_HEADER_2))) { - netdev_dbg( - dev->net, - "Received expected unknown frame header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n", - header_start[0], header_start[1], - header_start[2], header_start[3], - header_start[4], header_start[5], + netdev_dbg(dev->net, + "Received expected unknown frame header: %6phC. Package length: %i\n", + header_start, skb->len - KALMIA_HEADER_LENGTH); } else { - netdev_err( - dev->net, - "Received unknown frame header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n", - header_start[0], header_start[1], - header_start[2], header_start[3], - header_start[4], header_start[5], + netdev_err(dev->net, + "Received unknown frame header: %6phC. Package length: %i\n", + header_start, skb->len - KALMIA_HEADER_LENGTH); return 0; } } else - netdev_dbg( - dev->net, - "Received header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n", - header_start[0], header_start[1], header_start[2], - header_start[3], header_start[4], header_start[5], - skb->len - KALMIA_HEADER_LENGTH); + netdev_dbg(dev->net, + "Received header: %6phC. Package length: %i\n", + header_start, skb->len - KALMIA_HEADER_LENGTH); /* subtract start header and end header */ usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH); @@ -310,12 +298,9 @@ kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb) sizeof(HEADER_END_OF_USB_PACKET)) == 0); if (!is_last) { header_start = skb->data + ether_packet_length; - netdev_dbg( - dev->net, - "End header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n", - header_start[0], header_start[1], - header_start[2], header_start[3], - header_start[4], header_start[5], + netdev_dbg(dev->net, + "End header: %6phC. Package length: %i\n", + header_start, skb->len - KALMIA_HEADER_LENGTH); } } diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 56459215a22..606eba2872b 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -523,6 +523,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x19d2, 0x0002, 1)}, {QMI_FIXED_INTF(0x19d2, 0x0012, 1)}, {QMI_FIXED_INTF(0x19d2, 0x0017, 3)}, + {QMI_FIXED_INTF(0x19d2, 0x0019, 3)}, /* ONDA MT689DC */ {QMI_FIXED_INTF(0x19d2, 0x0021, 4)}, {QMI_FIXED_INTF(0x19d2, 0x0025, 1)}, {QMI_FIXED_INTF(0x19d2, 0x0031, 4)}, @@ -582,6 +583,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ + {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ {QMI_FIXED_INTF(0x1e2d, 0x12d1, 4)}, /* Cinterion PLxx */ @@ -618,6 +620,7 @@ static const struct usb_device_id products[] = { {QMI_GOBI_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ {QMI_GOBI_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ {QMI_GOBI_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ + {QMI_GOBI_DEVICE(0x0af0, 0x8120)}, /* Option GTM681W */ {QMI_GOBI_DEVICE(0x1199, 0x68a5)}, /* Sierra Wireless Modem */ {QMI_GOBI_DEVICE(0x1199, 0x68a9)}, /* Sierra Wireless Modem */ {QMI_GOBI_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ @@ -631,7 +634,6 @@ static const struct usb_device_id products[] = { {QMI_GOBI_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ {QMI_GOBI_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ {QMI_GOBI_DEVICE(0x1199, 0x9011)}, /* Sierra Wireless Gobi 2000 Modem device (MC8305) */ - {QMI_FIXED_INTF(0x1199, 0x9011, 5)}, /* alternate interface number!? */ {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 14e51988863..11c51f27536 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -11,7 +11,6 @@ #include <linux/signal.h> #include <linux/slab.h> #include <linux/module.h> -#include <linux/version.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/mii.h> @@ -345,17 +344,41 @@ static const int multicast_filter_limit = 32; static int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) { - return usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), + int ret; + void *tmp; + + tmp = kmalloc(size, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, - value, index, data, size, 500); + value, index, tmp, size, 500); + + memcpy(data, tmp, size); + kfree(tmp); + + return ret; } static int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) { - return usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), + int ret; + void *tmp; + + tmp = kmalloc(size, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + memcpy(tmp, data, size); + + ret = usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, - value, index, data, size, 500); + value, index, tmp, size, 500); + + kfree(tmp); + return ret; } static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, @@ -491,37 +514,31 @@ int usb_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data) static u32 ocp_read_dword(struct r8152 *tp, u16 type, u16 index) { - u32 data; + __le32 data; - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(data), &data); - else - usb_ocp_read(tp, index, sizeof(data), &data); + generic_ocp_read(tp, index, sizeof(data), &data, type); return __le32_to_cpu(data); } static void ocp_write_dword(struct r8152 *tp, u16 type, u16 index, u32 data) { - if (type == MCU_TYPE_PLA) - pla_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(data), &data); - else - usb_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(data), &data); + __le32 tmp = __cpu_to_le32(data); + + generic_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(tmp), &tmp, type); } static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index) { u32 data; + __le32 tmp; u8 shift = index & 2; index &= ~3; - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(data), &data); - else - usb_ocp_read(tp, index, sizeof(data), &data); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - data = __le32_to_cpu(data); + data = __le32_to_cpu(tmp); data >>= (shift * 8); data &= 0xffff; @@ -530,7 +547,8 @@ static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index) static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) { - u32 tmp, mask = 0xffff; + u32 mask = 0xffff; + __le32 tmp; u16 byen = BYTE_EN_WORD; u8 shift = index & 2; @@ -543,34 +561,25 @@ static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) index &= ~3; } - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(tmp), &tmp); - else - usb_ocp_read(tp, index, sizeof(tmp), &tmp); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - tmp = __le32_to_cpu(tmp) & ~mask; - tmp |= data; - tmp = __cpu_to_le32(tmp); + data |= __le32_to_cpu(tmp) & ~mask; + tmp = __cpu_to_le32(data); - if (type == MCU_TYPE_PLA) - pla_ocp_write(tp, index, byen, sizeof(tmp), &tmp); - else - usb_ocp_write(tp, index, byen, sizeof(tmp), &tmp); + generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); } static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index) { u32 data; + __le32 tmp; u8 shift = index & 3; index &= ~3; - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(data), &data); - else - usb_ocp_read(tp, index, sizeof(data), &data); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - data = __le32_to_cpu(data); + data = __le32_to_cpu(tmp); data >>= (shift * 8); data &= 0xff; @@ -579,7 +588,8 @@ static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index) static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) { - u32 tmp, mask = 0xff; + u32 mask = 0xff; + __le32 tmp; u16 byen = BYTE_EN_BYTE; u8 shift = index & 3; @@ -592,19 +602,12 @@ static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) index &= ~3; } - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(tmp), &tmp); - else - usb_ocp_read(tp, index, sizeof(tmp), &tmp); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - tmp = __le32_to_cpu(tmp) & ~mask; - tmp |= data; - tmp = __cpu_to_le32(tmp); + data |= __le32_to_cpu(tmp) & ~mask; + tmp = __cpu_to_le32(data); - if (type == MCU_TYPE_PLA) - pla_ocp_write(tp, index, byen, sizeof(tmp), &tmp); - else - usb_ocp_write(tp, index, byen, sizeof(tmp), &tmp); + generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); } static void r8152_mdio_write(struct r8152 *tp, u32 reg_addr, u32 value) @@ -686,21 +689,14 @@ static void ocp_reg_write(struct r8152 *tp, u16 addr, u16 data) static inline void set_ethernet_addr(struct r8152 *tp) { struct net_device *dev = tp->netdev; - u8 *node_id; - - node_id = kmalloc(sizeof(u8) * 8, GFP_KERNEL); - if (!node_id) { - netif_err(tp, probe, dev, "out of memory"); - return; - } + u8 node_id[8] = {0}; - if (pla_ocp_read(tp, PLA_IDR, sizeof(u8) * 8, node_id) < 0) + if (pla_ocp_read(tp, PLA_IDR, sizeof(node_id), node_id) < 0) netif_notice(tp, probe, dev, "inet addr fail\n"); else { memcpy(dev->dev_addr, node_id, dev->addr_len); memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); } - kfree(node_id); } static int rtl8152_set_mac_address(struct net_device *netdev, void *p) @@ -883,15 +879,10 @@ static void rtl8152_set_rx_mode(struct net_device *netdev) static void _rtl8152_set_rx_mode(struct net_device *netdev) { struct r8152 *tp = netdev_priv(netdev); - u32 tmp, *mc_filter; /* Multicast hash filter */ + u32 mc_filter[2]; /* Multicast hash filter */ + __le32 tmp[2]; u32 ocp_data; - mc_filter = kmalloc(sizeof(u32) * 2, GFP_KERNEL); - if (!mc_filter) { - netif_err(tp, link, netdev, "out of memory"); - return; - } - clear_bit(RTL8152_SET_RX_MODE, &tp->flags); netif_stop_queue(netdev); ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); @@ -919,14 +910,12 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) } } - tmp = mc_filter[0]; - mc_filter[0] = __cpu_to_le32(swab32(mc_filter[1])); - mc_filter[1] = __cpu_to_le32(swab32(tmp)); + tmp[0] = __cpu_to_le32(swab32(mc_filter[1])); + tmp[1] = __cpu_to_le32(swab32(mc_filter[0])); - pla_ocp_write(tp, PLA_MAR, BYTE_EN_DWORD, sizeof(u32) * 2, mc_filter); + pla_ocp_write(tp, PLA_MAR, BYTE_EN_DWORD, sizeof(tmp), tmp); ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); netif_wake_queue(netdev); - kfree(mc_filter); } static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, @@ -935,7 +924,8 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, struct r8152 *tp = netdev_priv(netdev); struct net_device_stats *stats = rtl8152_get_stats(netdev); struct tx_desc *tx_desc; - int len, res; + unsigned int len; + int res; netif_stop_queue(netdev); len = skb->len; @@ -1749,18 +1739,7 @@ static struct usb_driver rtl8152_driver = { .resume = rtl8152_resume }; -static int __init usb_rtl8152_init(void) -{ - return usb_register(&rtl8152_driver); -} - -static void __exit usb_rtl8152_exit(void) -{ - usb_deregister(&rtl8152_driver); -} - -module_init(usb_rtl8152_init); -module_exit(usb_rtl8152_exit); +module_usb_driver(rtl8152_driver); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c new file mode 100644 index 00000000000..2df2f4fb42a --- /dev/null +++ b/drivers/net/usb/r815x.c @@ -0,0 +1,256 @@ +#include <linux/module.h> +#include <linux/netdevice.h> +#include <linux/mii.h> +#include <linux/usb.h> +#include <linux/usb/cdc.h> +#include <linux/usb/usbnet.h> + +#define RTL815x_REQT_READ 0xc0 +#define RTL815x_REQT_WRITE 0x40 +#define RTL815x_REQ_GET_REGS 0x05 +#define RTL815x_REQ_SET_REGS 0x05 + +#define MCU_TYPE_PLA 0x0100 +#define OCP_BASE 0xe86c +#define BASE_MII 0xa400 + +#define BYTE_EN_DWORD 0xff +#define BYTE_EN_WORD 0x33 +#define BYTE_EN_BYTE 0x11 + +#define R815x_PHY_ID 32 +#define REALTEK_VENDOR_ID 0x0bda + + +static int pla_read_word(struct usb_device *udev, u16 index) +{ + int ret; + u8 shift = index & 2; + __le32 *tmp; + + tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + index &= ~3; + + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, + index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); + if (ret < 0) + goto out2; + + ret = __le32_to_cpu(*tmp); + ret >>= (shift * 8); + ret &= 0xffff; + +out2: + kfree(tmp); + return ret; +} + +static int pla_write_word(struct usb_device *udev, u16 index, u32 data) +{ + __le32 *tmp; + u32 mask = 0xffff; + u16 byen = BYTE_EN_WORD; + u8 shift = index & 2; + int ret; + + tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + data &= mask; + + if (shift) { + byen <<= shift; + mask <<= (shift * 8); + data <<= (shift * 8); + index &= ~3; + } + + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, + index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); + if (ret < 0) + goto out3; + + data |= __le32_to_cpu(*tmp) & ~mask; + *tmp = __cpu_to_le32(data); + + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTL815x_REQ_SET_REGS, RTL815x_REQT_WRITE, + index, MCU_TYPE_PLA | byen, tmp, sizeof(*tmp), + 500); + +out3: + kfree(tmp); + return ret; +} + +static int ocp_reg_read(struct usbnet *dev, u16 addr) +{ + u16 ocp_base, ocp_index; + int ret; + + ocp_base = addr & 0xf000; + ret = pla_write_word(dev->udev, OCP_BASE, ocp_base); + if (ret < 0) + goto out; + + ocp_index = (addr & 0x0fff) | 0xb000; + ret = pla_read_word(dev->udev, ocp_index); + +out: + return ret; +} + +static int ocp_reg_write(struct usbnet *dev, u16 addr, u16 data) +{ + u16 ocp_base, ocp_index; + int ret; + + ocp_base = addr & 0xf000; + ret = pla_write_word(dev->udev, OCP_BASE, ocp_base); + if (ret < 0) + goto out1; + + ocp_index = (addr & 0x0fff) | 0xb000; + ret = pla_write_word(dev->udev, ocp_index, data); + +out1: + return ret; +} + +static int r815x_mdio_read(struct net_device *netdev, int phy_id, int reg) +{ + struct usbnet *dev = netdev_priv(netdev); + int ret; + + if (phy_id != R815x_PHY_ID) + return -EINVAL; + + if (usb_autopm_get_interface(dev->intf) < 0) + return -ENODEV; + + ret = ocp_reg_read(dev, BASE_MII + reg * 2); + + usb_autopm_put_interface(dev->intf); + return ret; +} + +static +void r815x_mdio_write(struct net_device *netdev, int phy_id, int reg, int val) +{ + struct usbnet *dev = netdev_priv(netdev); + + if (phy_id != R815x_PHY_ID) + return; + + if (usb_autopm_get_interface(dev->intf) < 0) + return; + + ocp_reg_write(dev, BASE_MII + reg * 2, val); + + usb_autopm_put_interface(dev->intf); +} + +static int r8153_bind(struct usbnet *dev, struct usb_interface *intf) +{ + int status; + + status = usbnet_cdc_bind(dev, intf); + if (status < 0) + return status; + + dev->mii.dev = dev->net; + dev->mii.mdio_read = r815x_mdio_read; + dev->mii.mdio_write = r815x_mdio_write; + dev->mii.phy_id_mask = 0x3f; + dev->mii.reg_num_mask = 0x1f; + dev->mii.phy_id = R815x_PHY_ID; + dev->mii.supports_gmii = 1; + + return status; +} + +static int r8152_bind(struct usbnet *dev, struct usb_interface *intf) +{ + int status; + + status = usbnet_cdc_bind(dev, intf); + if (status < 0) + return status; + + dev->mii.dev = dev->net; + dev->mii.mdio_read = r815x_mdio_read; + dev->mii.mdio_write = r815x_mdio_write; + dev->mii.phy_id_mask = 0x3f; + dev->mii.reg_num_mask = 0x1f; + dev->mii.phy_id = R815x_PHY_ID; + dev->mii.supports_gmii = 0; + + return status; +} + +static const struct driver_info r8152_info = { + .description = "RTL8152 ECM Device", + .flags = FLAG_ETHER | FLAG_POINTTOPOINT, + .bind = r8152_bind, + .unbind = usbnet_cdc_unbind, + .status = usbnet_cdc_status, + .manage_power = usbnet_manage_power, +}; + +static const struct driver_info r8153_info = { + .description = "RTL8153 ECM Device", + .flags = FLAG_ETHER | FLAG_POINTTOPOINT, + .bind = r8153_bind, + .unbind = usbnet_cdc_unbind, + .status = usbnet_cdc_status, + .manage_power = usbnet_manage_power, +}; + +static const struct usb_device_id products[] = { +{ + USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), +#if defined(CONFIG_USB_RTL8152) || defined(CONFIG_USB_RTL8152_MODULE) + .driver_info = 0, +#else + .driver_info = (unsigned long) &r8152_info, +#endif +}, + +{ + USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8153, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), +#if defined(CONFIG_USB_RTL8153) || defined(CONFIG_USB_RTL8153_MODULE) + .driver_info = 0, +#else + .driver_info = (unsigned long) &r8153_info, +#endif +}, + + { }, /* END */ +}; +MODULE_DEVICE_TABLE(usb, products); + +static struct usb_driver r815x_driver = { + .name = "r815x", + .id_table = products, + .probe = usbnet_probe, + .disconnect = usbnet_disconnect, + .suspend = usbnet_suspend, + .resume = usbnet_resume, + .reset_resume = usbnet_resume, + .supports_autosuspend = 1, + .disable_hub_initiated_lpm = 1, +}; + +module_usb_driver(r815x_driver); + +MODULE_AUTHOR("Hayes Wang"); +MODULE_DESCRIPTION("Realtek USB ECM device"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 75409748c77..66ebbacf066 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -45,7 +45,6 @@ #define EEPROM_MAC_OFFSET (0x01) #define DEFAULT_TX_CSUM_ENABLE (true) #define DEFAULT_RX_CSUM_ENABLE (true) -#define DEFAULT_TSO_ENABLE (true) #define SMSC75XX_INTERNAL_PHY_ID (1) #define SMSC75XX_TX_OVERHEAD (8) #define MAX_RX_FIFO_SIZE (20 * 1024) @@ -1410,17 +1409,14 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write); - if (DEFAULT_TX_CSUM_ENABLE) { + if (DEFAULT_TX_CSUM_ENABLE) dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - if (DEFAULT_TSO_ENABLE) - dev->net->features |= NETIF_F_SG | - NETIF_F_TSO | NETIF_F_TSO6; - } + if (DEFAULT_RX_CSUM_ENABLE) dev->net->features |= NETIF_F_RXCSUM; dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_RXCSUM; + NETIF_F_RXCSUM; ret = smsc75xx_wait_ready(dev, 0); if (ret < 0) { @@ -2200,8 +2196,6 @@ static struct sk_buff *smsc75xx_tx_fixup(struct usbnet *dev, { u32 tx_cmd_a, tx_cmd_b; - skb_linearize(skb); - if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) { struct sk_buff *skb2 = skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags); |