diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-13 17:42:22 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-13 17:42:22 -0700 |
commit | be9c6d9169705504296bdb42ffec8f406691d99f (patch) | |
tree | 60e25d5f33f80a1c09476e770b89ca4661f2e944 /drivers/net/usb | |
parent | 03ce3ca4b02bfc1e6567a7851ae231ad3cc9418e (diff) | |
parent | 307f2fb95e9b96b3577916e73d92e104f8f26494 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller:
"Just a bunch of small fixes and tidy ups:
1) Finish the "busy_poll" renames, from Eliezer Tamir.
2) Fix RCU stalls in IFB driver, from Ding Tianhong.
3) Linearize buffers properly in tun/macvtap zerocopy code.
4) Don't crash on rmmod in vxlan, from Pravin B Shelar.
5) Spinlock used before init in alx driver, from Maarten Lankhorst.
6) A sparse warning fix in bnx2x broke TSO checksums, fix from Dmitry
Kravkov.
7) Dummy and ifb driver load failure paths can oops, fixes from Tan
Xiaojun and Ding Tianhong.
8) Correct MTU calculations in IP tunnels, from Alexander Duyck.
9) Account all TCP retransmits in SNMP stats properly, from Yuchung
Cheng.
10) atl1e and via-rhine do not handle DMA mapping failures properly,
from Neil Horman.
11) Various equal-cost multipath route fixes in ipv6 from Hannes
Frederic Sowa"
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (36 commits)
ipv6: only static routes qualify for equal cost multipathing
via-rhine: fix dma mapping errors
atl1e: fix dma mapping warnings
tcp: account all retransmit failures
usb/net/r815x: fix cast to restricted __le32
usb/net/r8152: fix integer overflow in expression
net: access page->private by using page_private
net: strict_strtoul is obsolete, use kstrtoul instead
drivers/net/ieee802154: don't use devm_pinctrl_get_select_default() in probe
drivers/net/ethernet/cadence: don't use devm_pinctrl_get_select_default() in probe
drivers/net/can/c_can: don't use devm_pinctrl_get_select_default() in probe
net/usb: add relative mii functions for r815x
net/tipc: use %*phC to dump small buffers in hex form
qlcnic: Adding Maintainers.
gre: Fix MTU sizing check for gretap tunnels
pkt_sched: sch_qfq: remove forward declaration of qfq_update_agg_ts
pkt_sched: sch_qfq: improve efficiency of make_eligible
gso: Update tunnel segmentation to support Tx checksum offload
inet: fix spacing in assignment
ifb: fix oops when loading the ifb failed
...
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/usb/cdc_ether.c | 9 | ||||
-rw-r--r-- | drivers/net/usb/r8152.c | 3 | ||||
-rw-r--r-- | drivers/net/usb/r815x.c | 234 |
4 files changed, 244 insertions, 4 deletions
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/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 4393f148312..03ad4dc293a 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -646,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/r8152.c b/drivers/net/usb/r8152.c index d02bac82fc5..ee13f9eb740 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -934,7 +934,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; diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c new file mode 100644 index 00000000000..85239226971 --- /dev/null +++ b/drivers/net/usb/r815x.c @@ -0,0 +1,234 @@ +#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 data, ret; + u8 shift = index & 2; + __le32 ocp_data; + + index &= ~3; + + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, + index, MCU_TYPE_PLA, &ocp_data, sizeof(ocp_data), + 500); + if (ret < 0) + return ret; + + data = __le32_to_cpu(ocp_data); + data >>= (shift * 8); + data &= 0xffff; + + return data; +} + +static int pla_write_word(struct usb_device *udev, u16 index, u32 data) +{ + __le32 ocp_data; + u32 mask = 0xffff; + u16 byen = BYTE_EN_WORD; + u8 shift = index & 2; + int ret; + + 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, &ocp_data, sizeof(ocp_data), + 500); + if (ret < 0) + return ret; + + data |= __le32_to_cpu(ocp_data) & ~mask; + ocp_data = __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, &ocp_data, + sizeof(ocp_data), 500); + + 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); + + if (phy_id != R815x_PHY_ID) + return -EINVAL; + + return ocp_reg_read(dev, BASE_MII + reg * 2); +} + +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; + + ocp_reg_write(dev, BASE_MII + reg * 2, val); +} + +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 0; +} + +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 0; +} + +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"); |