summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/drivers/net/usb
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/drivers/net/usb')
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/Kconfig487
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/Makefile36
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/asix.c1665
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/catc.c952
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/cdc-phonet.c466
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/cdc_eem.c377
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/cdc_ether.c660
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/cdc_ncm.c1231
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/cdc_subset.c345
-rwxr-xr-xANDROID_3.4.5/drivers/net/usb/ch9x00.c852
-rwxr-xr-xANDROID_3.4.5/drivers/net/usb/compatibility.h387
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/cx82310_eth.c336
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/dm9601.c679
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/gl620a.c235
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/hso.c3380
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/int51x1.c245
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/ipheth.c560
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/kalmia.c382
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/kaweth.c1321
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/lg-vl600.c353
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/mcs7830.c698
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/net1080.c596
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/pegasus.c1539
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/pegasus.h315
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/plusb.c161
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/qmi_wwan.c563
-rwxr-xr-xANDROID_3.4.5/drivers/net/usb/r8152.c5481
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/rndis_host.c642
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/rtl8150.c957
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/sierra_net.c998
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/smsc75xx.c1260
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/smsc75xx.h421
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/smsc95xx.c1307
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/smsc95xx.h256
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/usbnet.c1668
-rw-r--r--ANDROID_3.4.5/drivers/net/usb/zaurus.c386
36 files changed, 0 insertions, 32197 deletions
diff --git a/ANDROID_3.4.5/drivers/net/usb/Kconfig b/ANDROID_3.4.5/drivers/net/usb/Kconfig
deleted file mode 100644
index 833e32f8..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/Kconfig
+++ /dev/null
@@ -1,487 +0,0 @@
-#
-# USB Network devices configuration
-#
-comment "Networking support is needed for USB Network Adapter support"
- depends on USB && !NET
-
-menu "USB Network Adapters"
- depends on USB && NET
-
-config USB_CATC
- tristate "USB CATC NetMate-based Ethernet device support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
- select CRC32
- ---help---
- Say Y if you want to use one of the following 10Mbps USB Ethernet
- device based on the EL1210A chip. Supported devices are:
- Belkin F5U011
- Belkin F5U111
- CATC NetMate
- CATC NetMate II
- smartBridges smartNIC
-
- This driver makes the adapter appear as a normal Ethernet interface,
- typically on eth0, if it is the only ethernet device, or perhaps on
- eth1, if you have a PCI or ISA ethernet card installed.
-
- To compile this driver as a module, choose M here: the
- module will be called catc.
-
-config USB_KAWETH
- tristate "USB KLSI KL5USB101-based ethernet device support"
- ---help---
- Say Y here if you want to use one of the following 10Mbps only
- USB Ethernet adapters based on the KLSI KL5KUSB101B chipset:
- 3Com 3C19250
- ADS USB-10BT
- ATEN USB Ethernet
- ASANTE USB To Ethernet Adapter
- AOX Endpoints USB Ethernet
- Correga K.K.
- D-Link DSB-650C and DU-E10
- Entrega / Portgear E45
- I-O DATA USB-ET/T
- Jaton USB Ethernet Device Adapter
- Kingston Technology USB Ethernet Adapter
- Linksys USB10T
- Mobility USB-Ethernet Adapter
- NetGear EA-101
- Peracom Enet and Enet2
- Portsmith Express Ethernet Adapter
- Shark Pocket Adapter
- SMC 2202USB
- Sony Vaio port extender
-
- This driver is likely to work with most 10Mbps only USB Ethernet
- adapters, including some "no brand" devices. It does NOT work on
- SmartBridges smartNIC or on Belkin F5U111 devices - you should use
- the CATC NetMate driver for those. If you are not sure which one
- you need, select both, and the correct one should be selected for
- you.
-
- This driver makes the adapter appear as a normal Ethernet interface,
- typically on eth0, if it is the only ethernet device, or perhaps on
- eth1, if you have a PCI or ISA ethernet card installed.
-
- To compile this driver as a module, choose M here: the
- module will be called 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.
- If in doubt then look at <file:drivers/net/usb/pegasus.h> for the
- complete list of supported devices.
-
- If your particular adapter is not in the list and you are _sure_ it
- is Pegasus or Pegasus II based then send me
- <petkan@users.sourceforge.net> vendor and device IDs.
-
- To compile this driver as a module, choose M here: the
- module will be called pegasus.
-
-config USB_RTL8150
- tristate "USB RTL8150 based ethernet device support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
- select NET_CORE
- select MII
- help
- Say Y here if you have RTL8150 based usb-ethernet adapter.
- Send me <petkan@users.sourceforge.net> any comments you may have.
- You can also check for updates at <http://pegasus2.sourceforge.net/>.
-
- To compile this driver as a module, choose M here: the
- module will be called rtl8150.
-
-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,
- with "minidrivers" built around a common network driver core
- that supports deep queues for efficient transfers. (This gives
- better performance with small packets and at high speeds).
-
- The USB host runs "usbnet", and the other end of the link might be:
-
- - Another USB host, when using USB "network" or "data transfer"
- cables. These are often used to network laptops to PCs, like
- "Laplink" parallel cables or some motherboards. These rely
- on specialized chips from many suppliers.
-
- - An intelligent USB gadget, perhaps embedding a Linux system.
- These include PDAs running Linux (iPaq, Yopy, Zaurus, and
- others), and devices that interoperate using the standard
- CDC-Ethernet specification (including many cable modems).
-
- - Network adapter hardware (like those for 10/100 Ethernet) which
- uses this driver framework.
-
- The link will appear with a name like "usb0", when the link is
- a two-node link, or "eth0" for most CDC-Ethernet devices. Those
- two-node links are most easily managed with Ethernet Bridging
- (CONFIG_BRIDGE) instead of routing.
-
- For more information see <http://www.linux-usb.org/usbnet/>.
-
- To compile this driver as a module, choose M here: the
- module will be called usbnet.
-
-config USB_NET_AX8817X
- tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters"
- depends on USB_USBNET
- select CRC32
- default y
- help
- This option adds support for ASIX AX88xxx based USB 2.0
- 10/100 Ethernet adapters.
-
- This driver should work with at least the following devices:
- * Aten UC210T
- * ASIX AX88172
- * Billionton Systems, USB2AR
- * Buffalo LUA-U2-KTX
- * Corega FEther USB2-TX
- * D-Link DUB-E100
- * Hawking UF200
- * Linksys USB200M
- * Netgear FA120
- * Sitecom LN-029
- * Intellinet USB 2.0 Ethernet
- * ST Lab USB 2.0 Ethernet
- * TrendNet TU2-ET100
-
- This driver creates an interface named "ethX", where X depends on
- what other networking devices you have in use.
-
-config USB_NET_CDCETHER
- tristate "CDC Ethernet support (smart devices such as cable modems)"
- depends on USB_USBNET
- default y
- help
- This option supports devices conforming to the Communication Device
- Class (CDC) Ethernet Control Model, a specification that's easy to
- implement in device firmware. The CDC specifications are available
- from <http://www.usb.org/>.
-
- CDC Ethernet is an implementation option for DOCSIS cable modems
- that support USB connectivity, used for non-Microsoft USB hosts.
- The Linux-USB CDC Ethernet Gadget driver is an open implementation.
- This driver should work with at least the following devices:
-
- * Dell Wireless 5530 HSPA
- * Ericsson PipeRider (all variants)
- * Ericsson Mobile Broadband Module (all variants)
- * Motorola (DM100 and SB4100)
- * Broadcom Cable Modem (reference design)
- * Toshiba (PCX1100U and F3507g/F3607gw)
- * ...
-
- This driver creates an interface named "ethX", where X depends on
- what other networking devices you have in use. However, if the
- IEEE 802 "local assignment" bit is set in the address, a "usbX"
- name is used instead.
-
-config USB_NET_CDC_EEM
- tristate "CDC EEM support"
- depends on USB_USBNET && EXPERIMENTAL
- help
- This option supports devices conforming to the Communication Device
- Class (CDC) Ethernet Emulation Model, a specification that's easy to
- implement in device firmware. The CDC EEM specifications are available
- from <http://www.usb.org/>.
-
- This driver creates an interface named "ethX", where X depends on
- what other networking devices you have in use. However, if the
- IEEE 802 "local assignment" bit is set in the address, a "usbX"
- name is used instead.
-
-config USB_NET_CDC_NCM
- tristate "CDC NCM support"
- depends on USB_USBNET
- default y
- help
- This driver provides support for CDC NCM (Network Control Model
- Device USB Class Specification). The CDC NCM specification is
- available from <http://www.usb.org/>.
-
- Say "y" to link the driver statically, or "m" to build a
- dynamically linked module.
-
- This driver should work with at least the following devices:
- * ST-Ericsson M700 LTE FDD/TDD Mobile Broadband Modem (ref. design)
- * ST-Ericsson M5730 HSPA+ Mobile Broadband Modem (reference design)
- * ST-Ericsson M570 HSPA+ Mobile Broadband Modem (reference design)
- * ST-Ericsson M343 HSPA Mobile Broadband Modem (reference design)
- * Ericsson F5521gw Mobile Broadband Module
-
-config USB_NET_DM9601
- tristate "Davicom DM9601 based USB 1.1 10/100 ethernet devices"
- depends on USB_USBNET
- select CRC32
- help
- This option adds support for Davicom DM9601 based USB 1.1
- 10/100 Ethernet adapters.
-
-config USB_NET_SMSC75XX
- tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices"
- depends on USB_USBNET
- select CRC32
- help
- This option adds support for SMSC LAN95XX based USB 2.0
- Gigabit Ethernet adapters.
-
-config USB_NET_SMSC95XX
- tristate "SMSC LAN95XX based USB 2.0 10/100 ethernet devices"
- depends on USB_USBNET
- select CRC32
- help
- This option adds support for SMSC LAN95XX based USB 2.0
- 10/100 Ethernet adapters.
-
-config USB_NET_GL620A
- tristate "GeneSys GL620USB-A based cables"
- depends on USB_USBNET
- help
- Choose this option if you're using a host-to-host cable,
- or PC2PC motherboard, with this chip.
-
- Note that the half-duplex "GL620USB" is not supported.
-
-config USB_NET_NET1080
- tristate "NetChip 1080 based cables (Laplink, ...)"
- default y
- depends on USB_USBNET
- help
- Choose this option if you're using a host-to-host cable based
- on this design: one NetChip 1080 chip and supporting logic,
- optionally with LEDs that indicate traffic
-
-config USB_NET_PLUSB
- tristate "Prolific PL-2301/2302/25A1 based cables"
- # if the handshake/init/reset problems, from original 'plusb',
- # are ever resolved ... then remove "experimental"
- depends on USB_USBNET && EXPERIMENTAL
- help
- Choose this option if you're using a host-to-host cable
- with one of these chips.
-
-config USB_NET_MCS7830
- tristate "MosChip MCS7830 based Ethernet adapters"
- depends on USB_USBNET
- help
- Choose this option if you're using a 10/100 Ethernet USB2
- adapter based on the MosChip 7830 controller. This includes
- adapters marketed under the DeLOCK brand.
-
-config USB_NET_RNDIS_HOST
- tristate "Host for RNDIS and ActiveSync devices (EXPERIMENTAL)"
- depends on USB_USBNET && EXPERIMENTAL
- select USB_NET_CDCETHER
- help
- This option enables hosting "Remote NDIS" USB networking links,
- as encouraged by Microsoft (instead of CDC Ethernet!) for use in
- various devices that may only support this protocol. A variant
- of this protocol (with even less public documentation) seems to
- be at the root of Microsoft's "ActiveSync" too.
-
- Avoid using this protocol unless you have no better options.
- The protocol specification is incomplete, and is controlled by
- (and for) Microsoft; it isn't an "Open" ecosystem or market.
-
-config USB_NET_CDC_SUBSET
- tristate "Simple USB Network Links (CDC Ethernet subset)"
- depends on USB_USBNET
- default y
- help
- This driver module supports USB network devices that can work
- without any device-specific information. Select it if you have
- one of these drivers.
-
- Note that while many USB host-to-host cables can work in this mode,
- that may mean not being able to talk to Win32 systems or more
- commonly not being able to handle certain events (like replugging
- the host on the other end) very well. Also, these devices will
- not generally have permanently assigned Ethernet addresses.
-
-config USB_ALI_M5632
- boolean "ALi M5632 based 'USB 2.0 Data Link' cables"
- depends on USB_NET_CDC_SUBSET
- help
- Choose this option if you're using a host-to-host cable
- based on this design, which supports USB 2.0 high speed.
-
-config USB_AN2720
- boolean "AnchorChips 2720 based cables (Xircom PGUNET, ...)"
- depends on USB_NET_CDC_SUBSET
- help
- Choose this option if you're using a host-to-host cable
- based on this design. Note that AnchorChips is now a
- Cypress brand.
-
-config USB_BELKIN
- boolean "eTEK based host-to-host cables (Advance, Belkin, ...)"
- depends on USB_NET_CDC_SUBSET
- default y
- help
- Choose this option if you're using a host-to-host cable
- based on this design: two NetChip 2890 chips and an Atmel
- microcontroller, with LEDs that indicate traffic.
-
-config USB_ARMLINUX
- boolean "Embedded ARM Linux links (iPaq, ...)"
- depends on USB_NET_CDC_SUBSET
- default y
- help
- Choose this option to support the "usb-eth" networking driver
- used by most of the ARM Linux community with device controllers
- such as the SA-11x0 and PXA-25x UDCs, or the tftp capabilities
- in some PXA versions of the "blob" boot loader.
-
- Linux-based "Gumstix" PXA-25x based systems use this protocol
- to talk with other Linux systems.
-
- Although the ROMs shipped with Sharp Zaurus products use a
- different link level framing protocol, you can have them use
- this simpler protocol by installing a different kernel.
-
-config USB_EPSON2888
- boolean "Epson 2888 based firmware (DEVELOPMENT)"
- depends on USB_NET_CDC_SUBSET
- help
- Choose this option to support the usb networking links used
- by some sample firmware from Epson.
-
-config USB_KC2190
- boolean "KT Technology KC2190 based cables (InstaNet)"
- depends on USB_NET_CDC_SUBSET && EXPERIMENTAL
- help
- Choose this option if you're using a host-to-host cable
- with one of these chips.
-
-config USB_NET_ZAURUS
- tristate "Sharp Zaurus (stock ROMs) and compatible"
- depends on USB_USBNET
- select USB_NET_CDCETHER
- select CRC32
- default y
- help
- Choose this option to support the usb networking links used by
- Zaurus models like the SL-5000D, SL-5500, SL-5600, A-300, B-500.
- This also supports some related device firmware, as used in some
- PDAs from Olympus and some cell phones from Motorola.
-
- If you install an alternate image, such as the Linux 2.6 based
- versions of OpenZaurus, you should no longer need to support this
- protocol. Only the "eth-fd" or "net_fd" drivers in these devices
- really need this non-conformant variant of CDC Ethernet (or in
- some cases CDC MDLM) protocol, not "g_ether".
-
-config USB_NET_CX82310_ETH
- tristate "Conexant CX82310 USB ethernet port"
- depends on USB_USBNET
- help
- Choose this option if you're using a Conexant CX82310-based ADSL
- router with USB ethernet port. This driver is for routers only,
- it will not work with ADSL modems (use cxacru driver instead).
-
-config USB_NET_KALMIA
- tristate "Samsung Kalmia based LTE USB modem"
- depends on USB_USBNET
- help
- Choose this option if you have a Samsung Kalmia based USB modem
- as Samsung GT-B3730.
-
- To compile this driver as a module, choose M here: the
- module will be called kalmia.
-
-config USB_NET_QMI_WWAN
- tristate "QMI WWAN driver for Qualcomm MSM based 3G and LTE modems"
- depends on USB_USBNET
- select USB_WDM
- help
- Support WWAN LTE/3G devices based on Qualcomm Mobile Data Modem
- (MDM) chipsets. Examples of such devices are
- * Huawei E392/E398
-
- This driver will only drive the ethernet part of the chips.
- The devices require additional configuration to be usable.
- Multiple management interfaces with linux drivers are
- available:
-
- * option: AT commands on /dev/ttyUSBx
- * cdc-wdm: Qualcomm MSM Interface (QMI) protocol on /dev/cdc-wdmx
-
- A modem manager with support for QMI is recommended.
-
- To compile this driver as a module, choose M here: the
- module will be called qmi_wwan.
-
-config USB_HSO
- tristate "Option USB High Speed Mobile Devices"
- depends on USB && RFKILL
- default n
- help
- Choose this option if you have an Option HSDPA/HSUPA card.
- These cards support downlink speeds of 7.2Mbps or greater.
-
- To compile this driver as a module, choose M here: the
- module will be called hso.
-
-config USB_NET_INT51X1
- tristate "Intellon PLC based usb adapter"
- depends on USB_USBNET
- help
- Choose this option if you're using a 14Mb USB-based PLC
- (Powerline Communications) solution with an Intellon
- INT51x1/INT5200 chip, like the "devolo dLan duo".
-
-config USB_CDC_PHONET
- tristate "CDC Phonet support"
- depends on PHONET
- help
- Choose this option to support the Phonet interface to a Nokia
- cellular modem, as found on most Nokia handsets with the
- "PC suite" USB profile.
-
-config USB_IPHETH
- tristate "Apple iPhone USB Ethernet driver"
- default n
- ---help---
- Module used to share Internet connection (tethering) from your
- iPhone (Original, 3G and 3GS) to your system.
- Note that you need userspace libraries and programs that are needed
- to pair your device with your system and that understand the iPhone
- protocol.
-
- For more information: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver
-
-config USB_SIERRA_NET
- tristate "USB-to-WWAN Driver for Sierra Wireless modems"
- depends on USB_USBNET
- help
- Choose this option if you have a Sierra Wireless USB-to-WWAN device.
-
- To compile this driver as a module, choose M here: the
- module will be called sierra_net.
-
-config USB_VL600
- tristate "LG VL600 modem dongle"
- depends on USB_NET_CDCETHER
- select USB_ACM
- help
- Select this if you want to use an LG Electronics 4G/LTE usb modem
- called VL600. This driver only handles the ethernet
- interface exposed by the modem firmware. To establish a connection
- you will first need a userspace program that sends the right
- command to the modem through its CDC ACM port, and most
- likely also a DHCP client. See this thread about using the
- 4G modem from Verizon:
-
- http://ubuntuforums.org/showpost.php?p=10589647&postcount=17
-
-
-endmenu
diff --git a/ANDROID_3.4.5/drivers/net/usb/Makefile b/ANDROID_3.4.5/drivers/net/usb/Makefile
deleted file mode 100644
index 60eb76c4..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/Makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Makefile for USB Network drivers
-#
-
-obj-$(CONFIG_USB_CATC) += catc.o
-obj-$(CONFIG_USB_KAWETH) += kaweth.o
-obj-$(CONFIG_USB_PEGASUS) += pegasus.o
-obj-$(CONFIG_USB_RTL8150) += rtl8150.o
-obj-$(CONFIG_USB_HSO) += hso.o
-obj-$(CONFIG_USB_NET_AX8817X) += asix.o
-obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
-obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o
-obj-$(CONFIG_USB_NET_DM9601) += dm9601.o
-obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o
-obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o
-obj-$(CONFIG_USB_NET_GL620A) += gl620a.o
-obj-$(CONFIG_USB_NET_NET1080) += net1080.o
-obj-$(CONFIG_USB_NET_PLUSB) += plusb.o
-obj-$(CONFIG_USB_NET_RNDIS_HOST) += rndis_host.o
-obj-$(CONFIG_USB_NET_CDC_SUBSET) += cdc_subset.o
-obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o
-obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o
-obj-$(CONFIG_USB_USBNET) += usbnet.o
-obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o
-obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o
-obj-$(CONFIG_USB_NET_KALMIA) += kalmia.o
-obj-$(CONFIG_USB_IPHETH) += ipheth.o
-obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o
-obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o
-obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o
-obj-$(CONFIG_USB_VL600) += lg-vl600.o
-obj-$(CONFIG_USB_NET_QMI_WWAN) += qmi_wwan.o
-obj-m += r8152.o
-obj-y+=ch9x00.o
-
-
diff --git a/ANDROID_3.4.5/drivers/net/usb/asix.c b/ANDROID_3.4.5/drivers/net/usb/asix.c
deleted file mode 100644
index 0dd2aa84..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/asix.c
+++ /dev/null
@@ -1,1665 +0,0 @@
-/*
- * ASIX AX8817X based USB 2.0 Ethernet Devices
- * Copyright (C) 2003-2006 David Hollis <dhollis@davehollis.com>
- * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
- * Copyright (C) 2006 James Painter <jamie.painter@iname.com>
- * Copyright (c) 2002-2003 TiVo Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-// #define DEBUG // error path messages, extra info
-// #define VERBOSE // more; success messages
-
-#include <linux/module.h>
-#include <linux/kmod.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/workqueue.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/crc32.h>
-#include <linux/usb/usbnet.h>
-#include <linux/slab.h>
-#include <linux/if_vlan.h>
-
-#define DRIVER_VERSION "22-Dec-2011"
-#define DRIVER_NAME "asix"
-
-/* ASIX AX8817X based USB 2.0 Ethernet Devices */
-
-#define AX_CMD_SET_SW_MII 0x06
-#define AX_CMD_READ_MII_REG 0x07
-#define AX_CMD_WRITE_MII_REG 0x08
-#define AX_CMD_SET_HW_MII 0x0a
-#define AX_CMD_READ_EEPROM 0x0b
-#define AX_CMD_WRITE_EEPROM 0x0c
-#define AX_CMD_WRITE_ENABLE 0x0d
-#define AX_CMD_WRITE_DISABLE 0x0e
-#define AX_CMD_READ_RX_CTL 0x0f
-#define AX_CMD_WRITE_RX_CTL 0x10
-#define AX_CMD_READ_IPG012 0x11
-#define AX_CMD_WRITE_IPG0 0x12
-#define AX_CMD_WRITE_IPG1 0x13
-#define AX_CMD_READ_NODE_ID 0x13
-#define AX_CMD_WRITE_NODE_ID 0x14
-#define AX_CMD_WRITE_IPG2 0x14
-#define AX_CMD_WRITE_MULTI_FILTER 0x16
-#define AX88172_CMD_READ_NODE_ID 0x17
-#define AX_CMD_READ_PHY_ID 0x19
-#define AX_CMD_READ_MEDIUM_STATUS 0x1a
-#define AX_CMD_WRITE_MEDIUM_MODE 0x1b
-#define AX_CMD_READ_MONITOR_MODE 0x1c
-#define AX_CMD_WRITE_MONITOR_MODE 0x1d
-#define AX_CMD_READ_GPIOS 0x1e
-#define AX_CMD_WRITE_GPIOS 0x1f
-#define AX_CMD_SW_RESET 0x20
-#define AX_CMD_SW_PHY_STATUS 0x21
-#define AX_CMD_SW_PHY_SELECT 0x22
-
-#define AX_MONITOR_MODE 0x01
-#define AX_MONITOR_LINK 0x02
-#define AX_MONITOR_MAGIC 0x04
-#define AX_MONITOR_HSFS 0x10
-
-/* AX88172 Medium Status Register values */
-#define AX88172_MEDIUM_FD 0x02
-#define AX88172_MEDIUM_TX 0x04
-#define AX88172_MEDIUM_FC 0x10
-#define AX88172_MEDIUM_DEFAULT \
- ( AX88172_MEDIUM_FD | AX88172_MEDIUM_TX | AX88172_MEDIUM_FC )
-
-#define AX_MCAST_FILTER_SIZE 8
-#define AX_MAX_MCAST 64
-
-#define AX_SWRESET_CLEAR 0x00
-#define AX_SWRESET_RR 0x01
-#define AX_SWRESET_RT 0x02
-#define AX_SWRESET_PRTE 0x04
-#define AX_SWRESET_PRL 0x08
-#define AX_SWRESET_BZ 0x10
-#define AX_SWRESET_IPRL 0x20
-#define AX_SWRESET_IPPD 0x40
-
-#define AX88772_IPG0_DEFAULT 0x15
-#define AX88772_IPG1_DEFAULT 0x0c
-#define AX88772_IPG2_DEFAULT 0x12
-
-/* AX88772 & AX88178 Medium Mode Register */
-#define AX_MEDIUM_PF 0x0080
-#define AX_MEDIUM_JFE 0x0040
-#define AX_MEDIUM_TFC 0x0020
-#define AX_MEDIUM_RFC 0x0010
-#define AX_MEDIUM_ENCK 0x0008
-#define AX_MEDIUM_AC 0x0004
-#define AX_MEDIUM_FD 0x0002
-#define AX_MEDIUM_GM 0x0001
-#define AX_MEDIUM_SM 0x1000
-#define AX_MEDIUM_SBP 0x0800
-#define AX_MEDIUM_PS 0x0200
-#define AX_MEDIUM_RE 0x0100
-
-#define AX88178_MEDIUM_DEFAULT \
- (AX_MEDIUM_PS | AX_MEDIUM_FD | AX_MEDIUM_AC | \
- AX_MEDIUM_RFC | AX_MEDIUM_TFC | AX_MEDIUM_JFE | \
- AX_MEDIUM_RE)
-
-#define AX88772_MEDIUM_DEFAULT \
- (AX_MEDIUM_FD | AX_MEDIUM_RFC | \
- AX_MEDIUM_TFC | AX_MEDIUM_PS | \
- AX_MEDIUM_AC | AX_MEDIUM_RE)
-
-/* AX88772 & AX88178 RX_CTL values */
-#define AX_RX_CTL_SO 0x0080
-#define AX_RX_CTL_AP 0x0020
-#define AX_RX_CTL_AM 0x0010
-#define AX_RX_CTL_AB 0x0008
-#define AX_RX_CTL_SEP 0x0004
-#define AX_RX_CTL_AMALL 0x0002
-#define AX_RX_CTL_PRO 0x0001
-#define AX_RX_CTL_MFB_2048 0x0000
-#define AX_RX_CTL_MFB_4096 0x0100
-#define AX_RX_CTL_MFB_8192 0x0200
-#define AX_RX_CTL_MFB_16384 0x0300
-
-#define AX_DEFAULT_RX_CTL (AX_RX_CTL_SO | AX_RX_CTL_AB)
-
-/* GPIO 0 .. 2 toggles */
-#define AX_GPIO_GPO0EN 0x01 /* GPIO0 Output enable */
-#define AX_GPIO_GPO_0 0x02 /* GPIO0 Output value */
-#define AX_GPIO_GPO1EN 0x04 /* GPIO1 Output enable */
-#define AX_GPIO_GPO_1 0x08 /* GPIO1 Output value */
-#define AX_GPIO_GPO2EN 0x10 /* GPIO2 Output enable */
-#define AX_GPIO_GPO_2 0x20 /* GPIO2 Output value */
-#define AX_GPIO_RESERVED 0x40 /* Reserved */
-#define AX_GPIO_RSE 0x80 /* Reload serial EEPROM */
-
-#define AX_EEPROM_MAGIC 0xdeadbeef
-#define AX88172_EEPROM_LEN 0x40
-#define AX88772_EEPROM_LEN 0xff
-
-#define PHY_MODE_MARVELL 0x0000
-#define MII_MARVELL_LED_CTRL 0x0018
-#define MII_MARVELL_STATUS 0x001b
-#define MII_MARVELL_CTRL 0x0014
-
-#define MARVELL_LED_MANUAL 0x0019
-
-#define MARVELL_STATUS_HWCFG 0x0004
-
-#define MARVELL_CTRL_TXDELAY 0x0002
-#define MARVELL_CTRL_RXDELAY 0x0080
-
-#define PHY_MODE_RTL8211CL 0x000C
-
-/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
-struct asix_data {
- u8 multi_filter[AX_MCAST_FILTER_SIZE];
- u8 mac_addr[ETH_ALEN];
- u8 phymode;
- u8 ledmode;
- u8 eeprom_len;
-};
-
-struct ax88172_int_data {
- __le16 res1;
- u8 link;
- __le16 res2;
- u8 status;
- __le16 res3;
-} __packed;
-
-static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
- u16 size, void *data)
-{
- void *buf;
- int err = -ENOMEM;
-
- netdev_dbg(dev->net, "asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
- cmd, value, index, size);
-
- buf = kmalloc(size, GFP_KERNEL);
- if (!buf)
- goto out;
-
- err = usb_control_msg(
- dev->udev,
- usb_rcvctrlpipe(dev->udev, 0),
- cmd,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value,
- index,
- buf,
- size,
- USB_CTRL_GET_TIMEOUT);
- if (err == size)
- memcpy(data, buf, size);
- else if (err >= 0)
- err = -EINVAL;
- kfree(buf);
-
-out:
- return err;
-}
-
-static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
- u16 size, void *data)
-{
- void *buf = NULL;
- int err = -ENOMEM;
-
- netdev_dbg(dev->net, "asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
- cmd, value, index, size);
-
- if (data) {
- buf = kmemdup(data, size, GFP_KERNEL);
- if (!buf)
- goto out;
- }
-
- err = usb_control_msg(
- dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- cmd,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value,
- index,
- buf,
- size,
- USB_CTRL_SET_TIMEOUT);
- kfree(buf);
-
-out:
- return err;
-}
-
-static void asix_async_cmd_callback(struct urb *urb)
-{
- struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
- int status = urb->status;
-
- if (status < 0)
- printk(KERN_DEBUG "asix_async_cmd_callback() failed with %d",
- status);
-
- kfree(req);
- usb_free_urb(urb);
-}
-
-static void
-asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
- u16 size, void *data)
-{
- struct usb_ctrlrequest *req;
- int status;
- struct urb *urb;
-
- netdev_dbg(dev->net, "asix_write_cmd_async() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
- cmd, value, index, size);
-
- urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!urb) {
- netdev_err(dev->net, "Error allocating URB in write_cmd_async!\n");
- return;
- }
-
- req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
- if (!req) {
- netdev_err(dev->net, "Failed to allocate memory for control request\n");
- usb_free_urb(urb);
- return;
- }
-
- req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
- req->bRequest = cmd;
- req->wValue = cpu_to_le16(value);
- req->wIndex = cpu_to_le16(index);
- req->wLength = cpu_to_le16(size);
-
- usb_fill_control_urb(urb, dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- (void *)req, data, size,
- asix_async_cmd_callback, req);
-
- status = usb_submit_urb(urb, GFP_ATOMIC);
- if (status < 0) {
- netdev_err(dev->net, "Error submitting the control message: status=%d\n",
- status);
- kfree(req);
- usb_free_urb(urb);
- }
-}
-
-static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- int offset = 0;
-
- while (offset + sizeof(u32) < skb->len) {
- struct sk_buff *ax_skb;
- u16 size;
- u32 header = get_unaligned_le32(skb->data + offset);
-
- offset += sizeof(u32);
-
- /* get the packet length */
- size = (u16) (header & 0x7ff);
- if (size != ((~header >> 16) & 0x07ff)) {
- netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n");
- return 0;
- }
-
- if ((size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) ||
- (size + offset > skb->len)) {
- netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n",
- size);
- return 0;
- }
- ax_skb = netdev_alloc_skb_ip_align(dev->net, size);
- if (!ax_skb)
- return 0;
-
- skb_put(ax_skb, size);
- memcpy(ax_skb->data, skb->data + offset, size);
- usbnet_skb_return(dev, ax_skb);
-
- offset += (size + 1) & 0xfffe;
- }
-
- if (skb->len != offset) {
- netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d\n",
- skb->len);
- return 0;
- }
- return 1;
-}
-
-static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
- gfp_t flags)
-{
- int padlen;
- int headroom = skb_headroom(skb);
- int tailroom = skb_tailroom(skb);
- u32 packet_len;
- u32 padbytes = 0xffff0000;
-
- padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4;
-
- if ((!skb_cloned(skb)) &&
- ((headroom + tailroom) >= (4 + padlen))) {
- if ((headroom < 4) || (tailroom < padlen)) {
- skb->data = memmove(skb->head + 4, skb->data, skb->len);
- skb_set_tail_pointer(skb, skb->len);
- }
- } else {
- struct sk_buff *skb2;
- skb2 = skb_copy_expand(skb, 4, padlen, flags);
- dev_kfree_skb_any(skb);
- skb = skb2;
- if (!skb)
- return NULL;
- }
-
- skb_push(skb, 4);
- packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4);
- cpu_to_le32s(&packet_len);
- skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len));
-
- if (padlen) {
- cpu_to_le32s(&padbytes);
- memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes));
- skb_put(skb, sizeof(padbytes));
- }
- return skb;
-}
-
-static void asix_status(struct usbnet *dev, struct urb *urb)
-{
- struct ax88172_int_data *event;
- int link;
-
- if (urb->actual_length < 8)
- return;
-
- event = urb->transfer_buffer;
- link = event->link & 0x01;
- if (netif_carrier_ok(dev->net) != link) {
- if (link) {
- netif_carrier_on(dev->net);
- usbnet_defer_kevent (dev, EVENT_LINK_RESET );
- } else
- netif_carrier_off(dev->net);
- netdev_dbg(dev->net, "Link Status is: %d\n", link);
- }
-}
-
-static inline int asix_set_sw_mii(struct usbnet *dev)
-{
- int ret;
- ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL);
- if (ret < 0)
- netdev_err(dev->net, "Failed to enable software MII access\n");
- return ret;
-}
-
-static inline int asix_set_hw_mii(struct usbnet *dev)
-{
- int ret;
- ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL);
- if (ret < 0)
- netdev_err(dev->net, "Failed to enable hardware MII access\n");
- return ret;
-}
-
-static inline int asix_get_phy_addr(struct usbnet *dev)
-{
- u8 buf[2];
- int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf);
-
- netdev_dbg(dev->net, "asix_get_phy_addr()\n");
-
- if (ret < 0) {
- netdev_err(dev->net, "Error reading PHYID register: %02x\n", ret);
- goto out;
- }
- netdev_dbg(dev->net, "asix_get_phy_addr() returning 0x%04x\n",
- *((__le16 *)buf));
- ret = buf[1];
-
-out:
- return ret;
-}
-
-static int asix_sw_reset(struct usbnet *dev, u8 flags)
-{
- int ret;
-
- ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL);
- if (ret < 0)
- netdev_err(dev->net, "Failed to send software reset: %02x\n", ret);
-
- return ret;
-}
-
-static u16 asix_read_rx_ctl(struct usbnet *dev)
-{
- __le16 v;
- int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v);
-
- if (ret < 0) {
- netdev_err(dev->net, "Error reading RX_CTL register: %02x\n", ret);
- goto out;
- }
- ret = le16_to_cpu(v);
-out:
- return ret;
-}
-
-static int asix_write_rx_ctl(struct usbnet *dev, u16 mode)
-{
- int ret;
-
- netdev_dbg(dev->net, "asix_write_rx_ctl() - mode = 0x%04x\n", mode);
- ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL);
- if (ret < 0)
- netdev_err(dev->net, "Failed to write RX_CTL mode to 0x%04x: %02x\n",
- mode, ret);
-
- return ret;
-}
-
-static u16 asix_read_medium_status(struct usbnet *dev)
-{
- __le16 v;
- int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v);
-
- if (ret < 0) {
- netdev_err(dev->net, "Error reading Medium Status register: %02x\n",
- ret);
- return ret; /* TODO: callers not checking for error ret */
- }
-
- return le16_to_cpu(v);
-
-}
-
-static int asix_write_medium_mode(struct usbnet *dev, u16 mode)
-{
- int ret;
-
- netdev_dbg(dev->net, "asix_write_medium_mode() - mode = 0x%04x\n", mode);
- ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
- if (ret < 0)
- netdev_err(dev->net, "Failed to write Medium Mode mode to 0x%04x: %02x\n",
- mode, ret);
-
- return ret;
-}
-
-static int asix_write_gpio(struct usbnet *dev, u16 value, int sleep)
-{
- int ret;
-
- netdev_dbg(dev->net, "asix_write_gpio() - value = 0x%04x\n", value);
- ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL);
- if (ret < 0)
- netdev_err(dev->net, "Failed to write GPIO value 0x%04x: %02x\n",
- value, ret);
-
- if (sleep)
- msleep(sleep);
-
- return ret;
-}
-
-/*
- * AX88772 & AX88178 have a 16-bit RX_CTL value
- */
-static void asix_set_multicast(struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
- struct asix_data *data = (struct asix_data *)&dev->data;
- u16 rx_ctl = AX_DEFAULT_RX_CTL;
-
- if (net->flags & IFF_PROMISC) {
- rx_ctl |= AX_RX_CTL_PRO;
- } else if (net->flags & IFF_ALLMULTI ||
- netdev_mc_count(net) > AX_MAX_MCAST) {
- rx_ctl |= AX_RX_CTL_AMALL;
- } else if (netdev_mc_empty(net)) {
- /* just broadcast and directed */
- } else {
- /* We use the 20 byte dev->data
- * for our 8 byte filter buffer
- * to avoid allocating memory that
- * is tricky to free later */
- struct netdev_hw_addr *ha;
- u32 crc_bits;
-
- memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);
-
- /* Build the multicast hash filter. */
- netdev_for_each_mc_addr(ha, net) {
- crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26;
- data->multi_filter[crc_bits >> 3] |=
- 1 << (crc_bits & 7);
- }
-
- asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
- AX_MCAST_FILTER_SIZE, data->multi_filter);
-
- rx_ctl |= AX_RX_CTL_AM;
- }
-
- asix_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
-}
-
-static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc)
-{
- struct usbnet *dev = netdev_priv(netdev);
- __le16 res;
-
- mutex_lock(&dev->phy_mutex);
- asix_set_sw_mii(dev);
- asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id,
- (__u16)loc, 2, &res);
- asix_set_hw_mii(dev);
- mutex_unlock(&dev->phy_mutex);
-
- netdev_dbg(dev->net, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
- phy_id, loc, le16_to_cpu(res));
-
- return le16_to_cpu(res);
-}
-
-static void
-asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
-{
- struct usbnet *dev = netdev_priv(netdev);
- __le16 res = cpu_to_le16(val);
-
- netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
- phy_id, loc, val);
- mutex_lock(&dev->phy_mutex);
- asix_set_sw_mii(dev);
- asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res);
- asix_set_hw_mii(dev);
- mutex_unlock(&dev->phy_mutex);
-}
-
-/* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */
-static u32 asix_get_phyid(struct usbnet *dev)
-{
- int phy_reg;
- u32 phy_id;
- int i;
-
- /* Poll for the rare case the FW or phy isn't ready yet. */
- for (i = 0; i < 100; i++) {
- phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1);
- if (phy_reg != 0 && phy_reg != 0xFFFF)
- break;
- mdelay(1);
- }
-
- if (phy_reg <= 0 || phy_reg == 0xFFFF)
- return 0;
-
- phy_id = (phy_reg & 0xffff) << 16;
-
- phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID2);
- if (phy_reg < 0)
- return 0;
-
- phy_id |= (phy_reg & 0xffff);
-
- return phy_id;
-}
-
-static void
-asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
-{
- struct usbnet *dev = netdev_priv(net);
- u8 opt;
-
- if (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) {
- wolinfo->supported = 0;
- wolinfo->wolopts = 0;
- return;
- }
- wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
- wolinfo->wolopts = 0;
- if (opt & AX_MONITOR_LINK)
- wolinfo->wolopts |= WAKE_PHY;
- if (opt & AX_MONITOR_MAGIC)
- wolinfo->wolopts |= WAKE_MAGIC;
-}
-
-static int
-asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
-{
- struct usbnet *dev = netdev_priv(net);
- u8 opt = 0;
-
- if (wolinfo->wolopts & WAKE_PHY)
- opt |= AX_MONITOR_LINK;
- if (wolinfo->wolopts & WAKE_MAGIC)
- opt |= AX_MONITOR_MAGIC;
-
- if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
- opt, 0, 0, NULL) < 0)
- return -EINVAL;
-
- return 0;
-}
-
-static int asix_get_eeprom_len(struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
- struct asix_data *data = (struct asix_data *)&dev->data;
-
- return data->eeprom_len;
-}
-
-static int asix_get_eeprom(struct net_device *net,
- struct ethtool_eeprom *eeprom, u8 *data)
-{
- struct usbnet *dev = netdev_priv(net);
- __le16 *ebuf = (__le16 *)data;
- int i;
-
- /* Crude hack to ensure that we don't overwrite memory
- * if an odd length is supplied
- */
- if (eeprom->len % 2)
- return -EINVAL;
-
- eeprom->magic = AX_EEPROM_MAGIC;
-
- /* ax8817x returns 2 bytes from eeprom on read */
- for (i=0; i < eeprom->len / 2; i++) {
- if (asix_read_cmd(dev, AX_CMD_READ_EEPROM,
- eeprom->offset + i, 0, 2, &ebuf[i]) < 0)
- return -EINVAL;
- }
- return 0;
-}
-
-static void asix_get_drvinfo (struct net_device *net,
- struct ethtool_drvinfo *info)
-{
- struct usbnet *dev = netdev_priv(net);
- struct asix_data *data = (struct asix_data *)&dev->data;
-
- /* Inherit standard device info */
- usbnet_get_drvinfo(net, info);
- strncpy (info->driver, DRIVER_NAME, sizeof info->driver);
- strncpy (info->version, DRIVER_VERSION, sizeof info->version);
- info->eedump_len = data->eeprom_len;
-}
-
-static u32 asix_get_link(struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
-
- return mii_link_ok(&dev->mii);
-}
-
-static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
-{
- struct usbnet *dev = netdev_priv(net);
-
- return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
-}
-
-static int asix_set_mac_address(struct net_device *net, void *p)
-{
- struct usbnet *dev = netdev_priv(net);
- struct asix_data *data = (struct asix_data *)&dev->data;
- struct sockaddr *addr = p;
-
- if (netif_running(net))
- return -EBUSY;
- if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
-
- memcpy(net->dev_addr, addr->sa_data, ETH_ALEN);
-
- /* We use the 20 byte dev->data
- * for our 6 byte mac buffer
- * to avoid allocating memory that
- * is tricky to free later */
- memcpy(data->mac_addr, addr->sa_data, ETH_ALEN);
- asix_write_cmd_async(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
- data->mac_addr);
-
- return 0;
-}
-
-/* We need to override some ethtool_ops so we require our
- own structure so we don't interfere with other usbnet
- devices that may be connected at the same time. */
-static const struct ethtool_ops ax88172_ethtool_ops = {
- .get_drvinfo = asix_get_drvinfo,
- .get_link = asix_get_link,
- .get_msglevel = usbnet_get_msglevel,
- .set_msglevel = usbnet_set_msglevel,
- .get_wol = asix_get_wol,
- .set_wol = asix_set_wol,
- .get_eeprom_len = asix_get_eeprom_len,
- .get_eeprom = asix_get_eeprom,
- .get_settings = usbnet_get_settings,
- .set_settings = usbnet_set_settings,
- .nway_reset = usbnet_nway_reset,
-};
-
-static void ax88172_set_multicast(struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
- struct asix_data *data = (struct asix_data *)&dev->data;
- u8 rx_ctl = 0x8c;
-
- if (net->flags & IFF_PROMISC) {
- rx_ctl |= 0x01;
- } else if (net->flags & IFF_ALLMULTI ||
- netdev_mc_count(net) > AX_MAX_MCAST) {
- rx_ctl |= 0x02;
- } else if (netdev_mc_empty(net)) {
- /* just broadcast and directed */
- } else {
- /* We use the 20 byte dev->data
- * for our 8 byte filter buffer
- * to avoid allocating memory that
- * is tricky to free later */
- struct netdev_hw_addr *ha;
- u32 crc_bits;
-
- memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);
-
- /* Build the multicast hash filter. */
- netdev_for_each_mc_addr(ha, net) {
- crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26;
- data->multi_filter[crc_bits >> 3] |=
- 1 << (crc_bits & 7);
- }
-
- asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
- AX_MCAST_FILTER_SIZE, data->multi_filter);
-
- rx_ctl |= 0x10;
- }
-
- asix_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
-}
-
-static int ax88172_link_reset(struct usbnet *dev)
-{
- u8 mode;
- struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
-
- mii_check_media(&dev->mii, 1, 1);
- mii_ethtool_gset(&dev->mii, &ecmd);
- mode = AX88172_MEDIUM_DEFAULT;
-
- if (ecmd.duplex != DUPLEX_FULL)
- mode |= ~AX88172_MEDIUM_FD;
-
- netdev_dbg(dev->net, "ax88172_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
- ethtool_cmd_speed(&ecmd), ecmd.duplex, mode);
-
- asix_write_medium_mode(dev, mode);
-
- return 0;
-}
-
-static const struct net_device_ops ax88172_netdev_ops = {
- .ndo_open = usbnet_open,
- .ndo_stop = usbnet_stop,
- .ndo_start_xmit = usbnet_start_xmit,
- .ndo_tx_timeout = usbnet_tx_timeout,
- .ndo_change_mtu = usbnet_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_do_ioctl = asix_ioctl,
- .ndo_set_rx_mode = ax88172_set_multicast,
-};
-
-static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- int ret = 0;
- u8 buf[ETH_ALEN];
- int i;
- unsigned long gpio_bits = dev->driver_info->data;
- struct asix_data *data = (struct asix_data *)&dev->data;
-
- data->eeprom_len = AX88172_EEPROM_LEN;
-
- usbnet_get_endpoints(dev,intf);
-
- /* Toggle the GPIOs in a manufacturer/model specific way */
- for (i = 2; i >= 0; i--) {
- ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS,
- (gpio_bits >> (i * 8)) & 0xff, 0, 0, NULL);
- if (ret < 0)
- goto out;
- msleep(5);
- }
-
- ret = asix_write_rx_ctl(dev, 0x80);
- if (ret < 0)
- goto out;
-
- /* Get the MAC address */
- ret = asix_read_cmd(dev, AX88172_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf);
- if (ret < 0) {
- dbg("read AX_CMD_READ_NODE_ID failed: %d", ret);
- goto out;
- }
- memcpy(dev->net->dev_addr, buf, ETH_ALEN);
-
- /* Initialize MII structure */
- dev->mii.dev = dev->net;
- dev->mii.mdio_read = asix_mdio_read;
- dev->mii.mdio_write = asix_mdio_write;
- dev->mii.phy_id_mask = 0x3f;
- dev->mii.reg_num_mask = 0x1f;
- dev->mii.phy_id = asix_get_phy_addr(dev);
-
- dev->net->netdev_ops = &ax88172_netdev_ops;
- dev->net->ethtool_ops = &ax88172_ethtool_ops;
-
- asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
- asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
- ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
- mii_nway_restart(&dev->mii);
-
- return 0;
-
-out:
- return ret;
-}
-
-static const struct ethtool_ops ax88772_ethtool_ops = {
- .get_drvinfo = asix_get_drvinfo,
- .get_link = asix_get_link,
- .get_msglevel = usbnet_get_msglevel,
- .set_msglevel = usbnet_set_msglevel,
- .get_wol = asix_get_wol,
- .set_wol = asix_set_wol,
- .get_eeprom_len = asix_get_eeprom_len,
- .get_eeprom = asix_get_eeprom,
- .get_settings = usbnet_get_settings,
- .set_settings = usbnet_set_settings,
- .nway_reset = usbnet_nway_reset,
-};
-
-static int ax88772_link_reset(struct usbnet *dev)
-{
- u16 mode;
- struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
-
- mii_check_media(&dev->mii, 1, 1);
- mii_ethtool_gset(&dev->mii, &ecmd);
- mode = AX88772_MEDIUM_DEFAULT;
-
- if (ethtool_cmd_speed(&ecmd) != SPEED_100)
- mode &= ~AX_MEDIUM_PS;
-
- if (ecmd.duplex != DUPLEX_FULL)
- mode &= ~AX_MEDIUM_FD;
-
- netdev_dbg(dev->net, "ax88772_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
- ethtool_cmd_speed(&ecmd), ecmd.duplex, mode);
-
- asix_write_medium_mode(dev, mode);
-
- return 0;
-}
-
-static int ax88772_reset(struct usbnet *dev)
-{
- struct asix_data *data = (struct asix_data *)&dev->data;
- int ret, embd_phy;
- u16 rx_ctl;
-
- ret = asix_write_gpio(dev,
- AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5);
- if (ret < 0)
- goto out;
-
- embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0);
-
- ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL);
- if (ret < 0) {
- dbg("Select PHY #1 failed: %d", ret);
- goto out;
- }
-
- ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL);
- if (ret < 0)
- goto out;
-
- msleep(150);
-
- ret = asix_sw_reset(dev, AX_SWRESET_CLEAR);
- if (ret < 0)
- goto out;
-
- msleep(150);
-
- if (embd_phy) {
- ret = asix_sw_reset(dev, AX_SWRESET_IPRL);
- if (ret < 0)
- goto out;
- } else {
- ret = asix_sw_reset(dev, AX_SWRESET_PRTE);
- if (ret < 0)
- goto out;
- }
-
- msleep(150);
- rx_ctl = asix_read_rx_ctl(dev);
- dbg("RX_CTL is 0x%04x after software reset", rx_ctl);
- ret = asix_write_rx_ctl(dev, 0x0000);
- if (ret < 0)
- goto out;
-
- rx_ctl = asix_read_rx_ctl(dev);
- dbg("RX_CTL is 0x%04x setting to 0x0000", rx_ctl);
-
- ret = asix_sw_reset(dev, AX_SWRESET_PRL);
- if (ret < 0)
- goto out;
-
- msleep(150);
-
- ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL);
- if (ret < 0)
- goto out;
-
- msleep(150);
-
- asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
- asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
- ADVERTISE_ALL | ADVERTISE_CSMA);
- mii_nway_restart(&dev->mii);
-
- ret = asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT);
- if (ret < 0)
- goto out;
-
- ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0,
- AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
- AX88772_IPG2_DEFAULT, 0, NULL);
- if (ret < 0) {
- dbg("Write IPG,IPG1,IPG2 failed: %d", ret);
- goto out;
- }
-
- /* Rewrite MAC address */
- memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN);
- ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
- data->mac_addr);
- if (ret < 0)
- goto out;
-
- /* Set RX_CTL to default values with 2k buffer, and enable cactus */
- ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL);
- if (ret < 0)
- goto out;
-
- rx_ctl = asix_read_rx_ctl(dev);
- dbg("RX_CTL is 0x%04x after all initializations", rx_ctl);
-
- rx_ctl = asix_read_medium_status(dev);
- dbg("Medium Status is 0x%04x after all initializations", rx_ctl);
-
- return 0;
-
-out:
- return ret;
-
-}
-
-static const struct net_device_ops ax88772_netdev_ops = {
- .ndo_open = usbnet_open,
- .ndo_stop = usbnet_stop,
- .ndo_start_xmit = usbnet_start_xmit,
- .ndo_tx_timeout = usbnet_tx_timeout,
- .ndo_change_mtu = usbnet_change_mtu,
- .ndo_set_mac_address = asix_set_mac_address,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_do_ioctl = asix_ioctl,
- .ndo_set_rx_mode = asix_set_multicast,
-};
-
-
-void check_set_mac(unsigned char *buf);
-static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- int ret, embd_phy;
- struct asix_data *data = (struct asix_data *)&dev->data;
- u8 buf[ETH_ALEN];
- u32 phyid;
-
- data->eeprom_len = AX88772_EEPROM_LEN;
-
- usbnet_get_endpoints(dev,intf);
-
- /* Get the MAC address */
- ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf);
- if (ret < 0) {
- dbg("Failed to read MAC address: %d", ret);
- return ret;
- }
-
- check_set_mac(buf);
-
-
- memcpy(dev->net->dev_addr, buf, ETH_ALEN);
-
- /* Initialize MII structure */
- dev->mii.dev = dev->net;
- dev->mii.mdio_read = asix_mdio_read;
- dev->mii.mdio_write = asix_mdio_write;
- dev->mii.phy_id_mask = 0x1f;
- dev->mii.reg_num_mask = 0x1f;
- dev->mii.phy_id = asix_get_phy_addr(dev);
-
- dev->net->netdev_ops = &ax88772_netdev_ops;
- dev->net->ethtool_ops = &ax88772_ethtool_ops;
-
- embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0);
-
- /* Reset the PHY to normal operation mode */
- ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL);
- if (ret < 0) {
- dbg("Select PHY #1 failed: %d", ret);
- return ret;
- }
-
- ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL);
- if (ret < 0)
- return ret;
-
- msleep(150);
-
- ret = asix_sw_reset(dev, AX_SWRESET_CLEAR);
- if (ret < 0)
- return ret;
-
- msleep(150);
-
- ret = asix_sw_reset(dev, embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_PRTE);
-
- /* Read PHYID register *AFTER* the PHY was reset properly */
- phyid = asix_get_phyid(dev);
- dbg("PHYID=0x%08x", phyid);
-
- /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
- if (dev->driver_info->flags & FLAG_FRAMING_AX) {
- /* hard_mtu is still the default - the device does not support
- jumbo eth frames */
- dev->rx_urb_size = 2048;
- }
-
- return 0;
-}
-
-static const struct ethtool_ops ax88178_ethtool_ops = {
- .get_drvinfo = asix_get_drvinfo,
- .get_link = asix_get_link,
- .get_msglevel = usbnet_get_msglevel,
- .set_msglevel = usbnet_set_msglevel,
- .get_wol = asix_get_wol,
- .set_wol = asix_set_wol,
- .get_eeprom_len = asix_get_eeprom_len,
- .get_eeprom = asix_get_eeprom,
- .get_settings = usbnet_get_settings,
- .set_settings = usbnet_set_settings,
- .nway_reset = usbnet_nway_reset,
-};
-
-static int marvell_phy_init(struct usbnet *dev)
-{
- struct asix_data *data = (struct asix_data *)&dev->data;
- u16 reg;
-
- netdev_dbg(dev->net, "marvell_phy_init()\n");
-
- reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_MARVELL_STATUS);
- netdev_dbg(dev->net, "MII_MARVELL_STATUS = 0x%04x\n", reg);
-
- asix_mdio_write(dev->net, dev->mii.phy_id, MII_MARVELL_CTRL,
- MARVELL_CTRL_RXDELAY | MARVELL_CTRL_TXDELAY);
-
- if (data->ledmode) {
- reg = asix_mdio_read(dev->net, dev->mii.phy_id,
- MII_MARVELL_LED_CTRL);
- netdev_dbg(dev->net, "MII_MARVELL_LED_CTRL (1) = 0x%04x\n", reg);
-
- reg &= 0xf8ff;
- reg |= (1 + 0x0100);
- asix_mdio_write(dev->net, dev->mii.phy_id,
- MII_MARVELL_LED_CTRL, reg);
-
- reg = asix_mdio_read(dev->net, dev->mii.phy_id,
- MII_MARVELL_LED_CTRL);
- netdev_dbg(dev->net, "MII_MARVELL_LED_CTRL (2) = 0x%04x\n", reg);
- reg &= 0xfc0f;
- }
-
- return 0;
-}
-
-static int rtl8211cl_phy_init(struct usbnet *dev)
-{
- struct asix_data *data = (struct asix_data *)&dev->data;
-
- netdev_dbg(dev->net, "rtl8211cl_phy_init()\n");
-
- asix_mdio_write (dev->net, dev->mii.phy_id, 0x1f, 0x0005);
- asix_mdio_write (dev->net, dev->mii.phy_id, 0x0c, 0);
- asix_mdio_write (dev->net, dev->mii.phy_id, 0x01,
- asix_mdio_read (dev->net, dev->mii.phy_id, 0x01) | 0x0080);
- asix_mdio_write (dev->net, dev->mii.phy_id, 0x1f, 0);
-
- if (data->ledmode == 12) {
- asix_mdio_write (dev->net, dev->mii.phy_id, 0x1f, 0x0002);
- asix_mdio_write (dev->net, dev->mii.phy_id, 0x1a, 0x00cb);
- asix_mdio_write (dev->net, dev->mii.phy_id, 0x1f, 0);
- }
-
- return 0;
-}
-
-static int marvell_led_status(struct usbnet *dev, u16 speed)
-{
- u16 reg = asix_mdio_read(dev->net, dev->mii.phy_id, MARVELL_LED_MANUAL);
-
- netdev_dbg(dev->net, "marvell_led_status() read 0x%04x\n", reg);
-
- /* Clear out the center LED bits - 0x03F0 */
- reg &= 0xfc0f;
-
- switch (speed) {
- case SPEED_1000:
- reg |= 0x03e0;
- break;
- case SPEED_100:
- reg |= 0x03b0;
- break;
- default:
- reg |= 0x02f0;
- }
-
- netdev_dbg(dev->net, "marvell_led_status() writing 0x%04x\n", reg);
- asix_mdio_write(dev->net, dev->mii.phy_id, MARVELL_LED_MANUAL, reg);
-
- return 0;
-}
-
-static int ax88178_reset(struct usbnet *dev)
-{
- struct asix_data *data = (struct asix_data *)&dev->data;
- int ret;
- __le16 eeprom;
- u8 status;
- int gpio0 = 0;
- u32 phyid;
-
- asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status);
- dbg("GPIO Status: 0x%04x", status);
-
- asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL);
- asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom);
- asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0, 0, 0, NULL);
-
- dbg("EEPROM index 0x17 is 0x%04x", eeprom);
-
- if (eeprom == cpu_to_le16(0xffff)) {
- data->phymode = PHY_MODE_MARVELL;
- data->ledmode = 0;
- gpio0 = 1;
- } else {
- data->phymode = le16_to_cpu(eeprom) & 0x7F;
- data->ledmode = le16_to_cpu(eeprom) >> 8;
- gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1;
- }
- dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode);
-
- /* Power up external GigaPHY through AX88178 GPIO pin */
- asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40);
- if ((le16_to_cpu(eeprom) >> 8) != 1) {
- asix_write_gpio(dev, 0x003c, 30);
- asix_write_gpio(dev, 0x001c, 300);
- asix_write_gpio(dev, 0x003c, 30);
- } else {
- dbg("gpio phymode == 1 path");
- asix_write_gpio(dev, AX_GPIO_GPO1EN, 30);
- asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30);
- }
-
- /* Read PHYID register *AFTER* powering up PHY */
- phyid = asix_get_phyid(dev);
- dbg("PHYID=0x%08x", phyid);
-
- /* Set AX88178 to enable MII/GMII/RGMII interface for external PHY */
- asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0, 0, 0, NULL);
-
- asix_sw_reset(dev, 0);
- msleep(150);
-
- asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD);
- msleep(150);
-
- asix_write_rx_ctl(dev, 0);
-
- if (data->phymode == PHY_MODE_MARVELL) {
- marvell_phy_init(dev);
- msleep(60);
- } else if (data->phymode == PHY_MODE_RTL8211CL)
- rtl8211cl_phy_init(dev);
-
- asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR,
- BMCR_RESET | BMCR_ANENABLE);
- asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
- ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
- asix_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000,
- ADVERTISE_1000FULL);
-
- mii_nway_restart(&dev->mii);
-
- ret = asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT);
- if (ret < 0)
- return ret;
-
- /* Rewrite MAC address */
- memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN);
- ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
- data->mac_addr);
- if (ret < 0)
- return ret;
-
- ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int ax88178_link_reset(struct usbnet *dev)
-{
- u16 mode;
- struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
- struct asix_data *data = (struct asix_data *)&dev->data;
- u32 speed;
-
- netdev_dbg(dev->net, "ax88178_link_reset()\n");
-
- mii_check_media(&dev->mii, 1, 1);
- mii_ethtool_gset(&dev->mii, &ecmd);
- mode = AX88178_MEDIUM_DEFAULT;
- speed = ethtool_cmd_speed(&ecmd);
-
- if (speed == SPEED_1000)
- mode |= AX_MEDIUM_GM;
- else if (speed == SPEED_100)
- mode |= AX_MEDIUM_PS;
- else
- mode &= ~(AX_MEDIUM_PS | AX_MEDIUM_GM);
-
- mode |= AX_MEDIUM_ENCK;
-
- if (ecmd.duplex == DUPLEX_FULL)
- mode |= AX_MEDIUM_FD;
- else
- mode &= ~AX_MEDIUM_FD;
-
- netdev_dbg(dev->net, "ax88178_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
- speed, ecmd.duplex, mode);
-
- asix_write_medium_mode(dev, mode);
-
- if (data->phymode == PHY_MODE_MARVELL && data->ledmode)
- marvell_led_status(dev, speed);
-
- return 0;
-}
-
-static void ax88178_set_mfb(struct usbnet *dev)
-{
- u16 mfb = AX_RX_CTL_MFB_16384;
- u16 rxctl;
- u16 medium;
- int old_rx_urb_size = dev->rx_urb_size;
-
- if (dev->hard_mtu < 2048) {
- dev->rx_urb_size = 2048;
- mfb = AX_RX_CTL_MFB_2048;
- } else if (dev->hard_mtu < 4096) {
- dev->rx_urb_size = 4096;
- mfb = AX_RX_CTL_MFB_4096;
- } else if (dev->hard_mtu < 8192) {
- dev->rx_urb_size = 8192;
- mfb = AX_RX_CTL_MFB_8192;
- } else if (dev->hard_mtu < 16384) {
- dev->rx_urb_size = 16384;
- mfb = AX_RX_CTL_MFB_16384;
- }
-
- rxctl = asix_read_rx_ctl(dev);
- asix_write_rx_ctl(dev, (rxctl & ~AX_RX_CTL_MFB_16384) | mfb);
-
- medium = asix_read_medium_status(dev);
- if (dev->net->mtu > 1500)
- medium |= AX_MEDIUM_JFE;
- else
- medium &= ~AX_MEDIUM_JFE;
- asix_write_medium_mode(dev, medium);
-
- if (dev->rx_urb_size > old_rx_urb_size)
- usbnet_unlink_rx_urbs(dev);
-}
-
-static int ax88178_change_mtu(struct net_device *net, int new_mtu)
-{
- struct usbnet *dev = netdev_priv(net);
- int ll_mtu = new_mtu + net->hard_header_len + 4;
-
- netdev_dbg(dev->net, "ax88178_change_mtu() new_mtu=%d\n", new_mtu);
-
- if (new_mtu <= 0 || ll_mtu > 16384)
- return -EINVAL;
-
- if ((ll_mtu % dev->maxpacket) == 0)
- return -EDOM;
-
- net->mtu = new_mtu;
- dev->hard_mtu = net->mtu + net->hard_header_len;
- ax88178_set_mfb(dev);
-
- return 0;
-}
-
-static const struct net_device_ops ax88178_netdev_ops = {
- .ndo_open = usbnet_open,
- .ndo_stop = usbnet_stop,
- .ndo_start_xmit = usbnet_start_xmit,
- .ndo_tx_timeout = usbnet_tx_timeout,
- .ndo_set_mac_address = asix_set_mac_address,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_rx_mode = asix_set_multicast,
- .ndo_do_ioctl = asix_ioctl,
- .ndo_change_mtu = ax88178_change_mtu,
-};
-
-static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- int ret;
- u8 buf[ETH_ALEN];
- struct asix_data *data = (struct asix_data *)&dev->data;
-
- data->eeprom_len = AX88772_EEPROM_LEN;
-
- usbnet_get_endpoints(dev,intf);
-
- /* Get the MAC address */
- ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf);
- if (ret < 0) {
- dbg("Failed to read MAC address: %d", ret);
- return ret;
- }
- memcpy(dev->net->dev_addr, buf, ETH_ALEN);
-
- /* Initialize MII structure */
- dev->mii.dev = dev->net;
- dev->mii.mdio_read = asix_mdio_read;
- dev->mii.mdio_write = asix_mdio_write;
- dev->mii.phy_id_mask = 0x1f;
- dev->mii.reg_num_mask = 0xff;
- dev->mii.supports_gmii = 1;
- dev->mii.phy_id = asix_get_phy_addr(dev);
-
- dev->net->netdev_ops = &ax88178_netdev_ops;
- dev->net->ethtool_ops = &ax88178_ethtool_ops;
-
- /* Blink LEDS so users know driver saw dongle */
- asix_sw_reset(dev, 0);
- msleep(150);
-
- asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD);
- msleep(150);
-
- /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
- if (dev->driver_info->flags & FLAG_FRAMING_AX) {
- /* hard_mtu is still the default - the device does not support
- jumbo eth frames */
- dev->rx_urb_size = 2048;
- }
-
- return 0;
-}
-
-static const struct driver_info ax8817x_info = {
- .description = "ASIX AX8817x USB 2.0 Ethernet",
- .bind = ax88172_bind,
- .status = asix_status,
- .link_reset = ax88172_link_reset,
- .reset = ax88172_link_reset,
- .flags = FLAG_ETHER | FLAG_LINK_INTR,
- .data = 0x00130103,
-};
-
-static const struct driver_info dlink_dub_e100_info = {
- .description = "DLink DUB-E100 USB Ethernet",
- .bind = ax88172_bind,
- .status = asix_status,
- .link_reset = ax88172_link_reset,
- .reset = ax88172_link_reset,
- .flags = FLAG_ETHER | FLAG_LINK_INTR,
- .data = 0x009f9d9f,
-};
-
-static const struct driver_info netgear_fa120_info = {
- .description = "Netgear FA-120 USB Ethernet",
- .bind = ax88172_bind,
- .status = asix_status,
- .link_reset = ax88172_link_reset,
- .reset = ax88172_link_reset,
- .flags = FLAG_ETHER | FLAG_LINK_INTR,
- .data = 0x00130103,
-};
-
-static const struct driver_info hawking_uf200_info = {
- .description = "Hawking UF200 USB Ethernet",
- .bind = ax88172_bind,
- .status = asix_status,
- .link_reset = ax88172_link_reset,
- .reset = ax88172_link_reset,
- .flags = FLAG_ETHER | FLAG_LINK_INTR,
- .data = 0x001f1d1f,
-};
-
-static const struct driver_info ax88772_info = {
- .description = "ASIX AX88772 USB 2.0 Ethernet",
- .bind = ax88772_bind,
- .status = asix_status,
- .link_reset = ax88772_link_reset,
- .reset = ax88772_reset,
- .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET,
- .rx_fixup = asix_rx_fixup,
- .tx_fixup = asix_tx_fixup,
-};
-
-static const struct driver_info ax88178_info = {
- .description = "ASIX AX88178 USB 2.0 Ethernet",
- .bind = ax88178_bind,
- .status = asix_status,
- .link_reset = ax88178_link_reset,
- .reset = ax88178_reset,
- .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR,
- .rx_fixup = asix_rx_fixup,
- .tx_fixup = asix_tx_fixup,
-};
-
-static const struct usb_device_id products [] = {
-{
- // Linksys USB200M
- USB_DEVICE (0x077b, 0x2226),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // Netgear FA120
- USB_DEVICE (0x0846, 0x1040),
- .driver_info = (unsigned long) &netgear_fa120_info,
-}, {
- // DLink DUB-E100
- USB_DEVICE (0x2001, 0x1a00),
- .driver_info = (unsigned long) &dlink_dub_e100_info,
-}, {
- // Intellinet, ST Lab USB Ethernet
- USB_DEVICE (0x0b95, 0x1720),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // Hawking UF200, TrendNet TU2-ET100
- USB_DEVICE (0x07b8, 0x420a),
- .driver_info = (unsigned long) &hawking_uf200_info,
-}, {
- // Billionton Systems, USB2AR
- USB_DEVICE (0x08dd, 0x90ff),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // ATEN UC210T
- USB_DEVICE (0x0557, 0x2009),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // Buffalo LUA-U2-KTX
- USB_DEVICE (0x0411, 0x003d),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // Buffalo LUA-U2-GT 10/100/1000
- USB_DEVICE (0x0411, 0x006e),
- .driver_info = (unsigned long) &ax88178_info,
-}, {
- // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
- USB_DEVICE (0x6189, 0x182d),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // Sitecom LN-031 "USB 2.0 10/100/1000 Ethernet adapter"
- USB_DEVICE (0x0df6, 0x0056),
- .driver_info = (unsigned long) &ax88178_info,
-}, {
- // corega FEther USB2-TX
- USB_DEVICE (0x07aa, 0x0017),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // Surecom EP-1427X-2
- USB_DEVICE (0x1189, 0x0893),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // goodway corp usb gwusb2e
- USB_DEVICE (0x1631, 0x6200),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // JVC MP-PRX1 Port Replicator
- USB_DEVICE (0x04f1, 0x3008),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // ASIX AX88772B 10/100
- USB_DEVICE (0x0b95, 0x772b),
- .driver_info = (unsigned long) &ax88772_info,
-}, {
- // ASIX AX88772 10/100
- USB_DEVICE (0x0b95, 0x7720),
- .driver_info = (unsigned long) &ax88772_info,
-}, {
- // ASIX AX88178 10/100/1000
- USB_DEVICE (0x0b95, 0x1780),
- .driver_info = (unsigned long) &ax88178_info,
-}, {
- // Logitec LAN-GTJ/U2A
- USB_DEVICE (0x0789, 0x0160),
- .driver_info = (unsigned long) &ax88178_info,
-}, {
- // Linksys USB200M Rev 2
- USB_DEVICE (0x13b1, 0x0018),
- .driver_info = (unsigned long) &ax88772_info,
-}, {
- // 0Q0 cable ethernet
- USB_DEVICE (0x1557, 0x7720),
- .driver_info = (unsigned long) &ax88772_info,
-}, {
- // DLink DUB-E100 H/W Ver B1
- USB_DEVICE (0x07d1, 0x3c05),
- .driver_info = (unsigned long) &ax88772_info,
-}, {
- // DLink DUB-E100 H/W Ver B1 Alternate
- USB_DEVICE (0x2001, 0x3c05),
- .driver_info = (unsigned long) &ax88772_info,
-}, {
- // Linksys USB1000
- USB_DEVICE (0x1737, 0x0039),
- .driver_info = (unsigned long) &ax88178_info,
-}, {
- // IO-DATA ETG-US2
- USB_DEVICE (0x04bb, 0x0930),
- .driver_info = (unsigned long) &ax88178_info,
-}, {
- // Belkin F5D5055
- USB_DEVICE(0x050d, 0x5055),
- .driver_info = (unsigned long) &ax88178_info,
-}, {
- // Apple USB Ethernet Adapter
- USB_DEVICE(0x05ac, 0x1402),
- .driver_info = (unsigned long) &ax88772_info,
-}, {
- // Cables-to-Go USB Ethernet Adapter
- USB_DEVICE(0x0b95, 0x772a),
- .driver_info = (unsigned long) &ax88772_info,
-}, {
- // ABOCOM for pci
- USB_DEVICE(0x14ea, 0xab11),
- .driver_info = (unsigned long) &ax88178_info,
-}, {
- // ASIX 88772a
- USB_DEVICE(0x0db0, 0xa877),
- .driver_info = (unsigned long) &ax88772_info,
-}, {
- // Asus USB Ethernet Adapter
- USB_DEVICE (0x0b95, 0x7e2b),
- .driver_info = (unsigned long) &ax88772_info,
-},
- { }, // END
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver asix_driver = {
- .name = DRIVER_NAME,
- .id_table = products,
- .probe = usbnet_probe,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
- .disconnect = usbnet_disconnect,
- .supports_autosuspend = 1,
-};
-
-module_usb_driver(asix_driver);
-
-MODULE_AUTHOR("David Hollis");
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_DESCRIPTION("ASIX AX8817X based USB 2.0 Ethernet Devices");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/drivers/net/usb/catc.c b/ANDROID_3.4.5/drivers/net/usb/catc.c
deleted file mode 100644
index 182cfb4a..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/catc.c
+++ /dev/null
@@ -1,952 +0,0 @@
-/*
- * Copyright (c) 2001 Vojtech Pavlik
- *
- * CATC EL1210A NetMate USB Ethernet driver
- *
- * Sponsored by SuSE
- *
- * Based on the work of
- * Donald Becker
- *
- * Old chipset support added by Simon Evans <spse@secret.org.uk> 2002
- * - adds support for Belkin F5U011
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <linux/ethtool.h>
-#include <linux/crc32.h>
-#include <linux/bitops.h>
-#include <linux/gfp.h>
-#include <asm/uaccess.h>
-
-#undef DEBUG
-
-#include <linux/usb.h>
-
-/*
- * Version information.
- */
-
-#define DRIVER_VERSION "v2.8"
-#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@suse.cz>"
-#define DRIVER_DESC "CATC EL1210A NetMate USB Ethernet driver"
-#define SHORT_DRIVER_DESC "EL1210A NetMate USB Ethernet"
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-
-static const char driver_name[] = "catc";
-
-/*
- * Some defines.
- */
-
-#define STATS_UPDATE (HZ) /* Time between stats updates */
-#define TX_TIMEOUT (5*HZ) /* Max time the queue can be stopped */
-#define PKT_SZ 1536 /* Max Ethernet packet size */
-#define RX_MAX_BURST 15 /* Max packets per rx buffer (> 0, < 16) */
-#define TX_MAX_BURST 15 /* Max full sized packets per tx buffer (> 0) */
-#define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */
-#define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */
-
-/*
- * Control requests.
- */
-
-enum control_requests {
- ReadMem = 0xf1,
- GetMac = 0xf2,
- Reset = 0xf4,
- SetMac = 0xf5,
- SetRxMode = 0xf5, /* F5U011 only */
- WriteROM = 0xf8,
- SetReg = 0xfa,
- GetReg = 0xfb,
- WriteMem = 0xfc,
- ReadROM = 0xfd,
-};
-
-/*
- * Registers.
- */
-
-enum register_offsets {
- TxBufCount = 0x20,
- RxBufCount = 0x21,
- OpModes = 0x22,
- TxQed = 0x23,
- RxQed = 0x24,
- MaxBurst = 0x25,
- RxUnit = 0x60,
- EthStatus = 0x61,
- StationAddr0 = 0x67,
- EthStats = 0x69,
- LEDCtrl = 0x81,
-};
-
-enum eth_stats {
- TxSingleColl = 0x00,
- TxMultiColl = 0x02,
- TxExcessColl = 0x04,
- RxFramErr = 0x06,
-};
-
-enum op_mode_bits {
- Op3MemWaits = 0x03,
- OpLenInclude = 0x08,
- OpRxMerge = 0x10,
- OpTxMerge = 0x20,
- OpWin95bugfix = 0x40,
- OpLoopback = 0x80,
-};
-
-enum rx_filter_bits {
- RxEnable = 0x01,
- RxPolarity = 0x02,
- RxForceOK = 0x04,
- RxMultiCast = 0x08,
- RxPromisc = 0x10,
- AltRxPromisc = 0x20, /* F5U011 uses different bit */
-};
-
-enum led_values {
- LEDFast = 0x01,
- LEDSlow = 0x02,
- LEDFlash = 0x03,
- LEDPulse = 0x04,
- LEDLink = 0x08,
-};
-
-enum link_status {
- LinkNoChange = 0,
- LinkGood = 1,
- LinkBad = 2
-};
-
-/*
- * The catc struct.
- */
-
-#define CTRL_RUNNING 0
-#define RX_RUNNING 1
-#define TX_RUNNING 2
-
-struct catc {
- struct net_device *netdev;
- struct usb_device *usbdev;
-
- unsigned long flags;
-
- unsigned int tx_ptr, tx_idx;
- unsigned int ctrl_head, ctrl_tail;
- spinlock_t tx_lock, ctrl_lock;
-
- u8 tx_buf[2][TX_MAX_BURST * (PKT_SZ + 2)];
- u8 rx_buf[RX_MAX_BURST * (PKT_SZ + 2)];
- u8 irq_buf[2];
- u8 ctrl_buf[64];
- struct usb_ctrlrequest ctrl_dr;
-
- struct timer_list timer;
- u8 stats_buf[8];
- u16 stats_vals[4];
- unsigned long last_stats;
-
- u8 multicast[64];
-
- struct ctrl_queue {
- u8 dir;
- u8 request;
- u16 value;
- u16 index;
- void *buf;
- int len;
- void (*callback)(struct catc *catc, struct ctrl_queue *q);
- } ctrl_queue[CTRL_QUEUE];
-
- struct urb *tx_urb, *rx_urb, *irq_urb, *ctrl_urb;
-
- u8 is_f5u011; /* Set if device is an F5U011 */
- u8 rxmode[2]; /* Used for F5U011 */
- atomic_t recq_sz; /* Used for F5U011 - counter of waiting rx packets */
-};
-
-/*
- * Useful macros.
- */
-
-#define catc_get_mac(catc, mac) catc_ctrl_msg(catc, USB_DIR_IN, GetMac, 0, 0, mac, 6)
-#define catc_reset(catc) catc_ctrl_msg(catc, USB_DIR_OUT, Reset, 0, 0, NULL, 0)
-#define catc_set_reg(catc, reg, val) catc_ctrl_msg(catc, USB_DIR_OUT, SetReg, val, reg, NULL, 0)
-#define catc_get_reg(catc, reg, buf) catc_ctrl_msg(catc, USB_DIR_IN, GetReg, 0, reg, buf, 1)
-#define catc_write_mem(catc, addr, buf, size) catc_ctrl_msg(catc, USB_DIR_OUT, WriteMem, 0, addr, buf, size)
-#define catc_read_mem(catc, addr, buf, size) catc_ctrl_msg(catc, USB_DIR_IN, ReadMem, 0, addr, buf, size)
-
-#define f5u011_rxmode(catc, rxmode) catc_ctrl_msg(catc, USB_DIR_OUT, SetRxMode, 0, 1, rxmode, 2)
-#define f5u011_rxmode_async(catc, rxmode) catc_ctrl_async(catc, USB_DIR_OUT, SetRxMode, 0, 1, &rxmode, 2, NULL)
-#define f5u011_mchash_async(catc, hash) catc_ctrl_async(catc, USB_DIR_OUT, SetRxMode, 0, 2, &hash, 8, NULL)
-
-#define catc_set_reg_async(catc, reg, val) catc_ctrl_async(catc, USB_DIR_OUT, SetReg, val, reg, NULL, 0, NULL)
-#define catc_get_reg_async(catc, reg, cb) catc_ctrl_async(catc, USB_DIR_IN, GetReg, 0, reg, NULL, 1, cb)
-#define catc_write_mem_async(catc, addr, buf, size) catc_ctrl_async(catc, USB_DIR_OUT, WriteMem, 0, addr, buf, size, NULL)
-
-/*
- * Receive routines.
- */
-
-static void catc_rx_done(struct urb *urb)
-{
- struct catc *catc = urb->context;
- u8 *pkt_start = urb->transfer_buffer;
- struct sk_buff *skb;
- int pkt_len, pkt_offset = 0;
- int status = urb->status;
-
- if (!catc->is_f5u011) {
- clear_bit(RX_RUNNING, &catc->flags);
- pkt_offset = 2;
- }
-
- if (status) {
- dbg("rx_done, status %d, length %d", status, urb->actual_length);
- return;
- }
-
- do {
- if(!catc->is_f5u011) {
- pkt_len = le16_to_cpup((__le16*)pkt_start);
- if (pkt_len > urb->actual_length) {
- catc->netdev->stats.rx_length_errors++;
- catc->netdev->stats.rx_errors++;
- break;
- }
- } else {
- pkt_len = urb->actual_length;
- }
-
- if (!(skb = dev_alloc_skb(pkt_len)))
- return;
-
- skb_copy_to_linear_data(skb, pkt_start + pkt_offset, pkt_len);
- skb_put(skb, pkt_len);
-
- skb->protocol = eth_type_trans(skb, catc->netdev);
- netif_rx(skb);
-
- catc->netdev->stats.rx_packets++;
- catc->netdev->stats.rx_bytes += pkt_len;
-
- /* F5U011 only does one packet per RX */
- if (catc->is_f5u011)
- break;
- pkt_start += (((pkt_len + 1) >> 6) + 1) << 6;
-
- } while (pkt_start - (u8 *) urb->transfer_buffer < urb->actual_length);
-
- if (catc->is_f5u011) {
- if (atomic_read(&catc->recq_sz)) {
- int state;
- atomic_dec(&catc->recq_sz);
- dbg("getting extra packet");
- urb->dev = catc->usbdev;
- if ((state = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- dbg("submit(rx_urb) status %d", state);
- }
- } else {
- clear_bit(RX_RUNNING, &catc->flags);
- }
- }
-}
-
-static void catc_irq_done(struct urb *urb)
-{
- struct catc *catc = urb->context;
- u8 *data = urb->transfer_buffer;
- int status = urb->status;
- unsigned int hasdata = 0, linksts = LinkNoChange;
- int res;
-
- if (!catc->is_f5u011) {
- hasdata = data[1] & 0x80;
- if (data[1] & 0x40)
- linksts = LinkGood;
- else if (data[1] & 0x20)
- linksts = LinkBad;
- } else {
- hasdata = (unsigned int)(be16_to_cpup((__be16*)data) & 0x0fff);
- if (data[0] == 0x90)
- linksts = LinkGood;
- else if (data[0] == 0xA0)
- linksts = LinkBad;
- }
-
- switch (status) {
- case 0: /* success */
- break;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- /* -EPIPE: should clear the halt */
- default: /* error */
- dbg("irq_done, status %d, data %02x %02x.", status, data[0], data[1]);
- goto resubmit;
- }
-
- if (linksts == LinkGood) {
- netif_carrier_on(catc->netdev);
- dbg("link ok");
- }
-
- if (linksts == LinkBad) {
- netif_carrier_off(catc->netdev);
- dbg("link bad");
- }
-
- if (hasdata) {
- if (test_and_set_bit(RX_RUNNING, &catc->flags)) {
- if (catc->is_f5u011)
- atomic_inc(&catc->recq_sz);
- } else {
- catc->rx_urb->dev = catc->usbdev;
- if ((res = usb_submit_urb(catc->rx_urb, GFP_ATOMIC)) < 0) {
- err("submit(rx_urb) status %d", res);
- }
- }
- }
-resubmit:
- res = usb_submit_urb (urb, GFP_ATOMIC);
- if (res)
- err ("can't resubmit intr, %s-%s, status %d",
- catc->usbdev->bus->bus_name,
- catc->usbdev->devpath, res);
-}
-
-/*
- * Transmit routines.
- */
-
-static int catc_tx_run(struct catc *catc)
-{
- int status;
-
- if (catc->is_f5u011)
- catc->tx_ptr = (catc->tx_ptr + 63) & ~63;
-
- catc->tx_urb->transfer_buffer_length = catc->tx_ptr;
- catc->tx_urb->transfer_buffer = catc->tx_buf[catc->tx_idx];
- catc->tx_urb->dev = catc->usbdev;
-
- if ((status = usb_submit_urb(catc->tx_urb, GFP_ATOMIC)) < 0)
- err("submit(tx_urb), status %d", status);
-
- catc->tx_idx = !catc->tx_idx;
- catc->tx_ptr = 0;
-
- catc->netdev->trans_start = jiffies;
- return status;
-}
-
-static void catc_tx_done(struct urb *urb)
-{
- struct catc *catc = urb->context;
- unsigned long flags;
- int r, status = urb->status;
-
- if (status == -ECONNRESET) {
- dbg("Tx Reset.");
- urb->status = 0;
- catc->netdev->trans_start = jiffies;
- catc->netdev->stats.tx_errors++;
- clear_bit(TX_RUNNING, &catc->flags);
- netif_wake_queue(catc->netdev);
- return;
- }
-
- if (status) {
- dbg("tx_done, status %d, length %d", status, urb->actual_length);
- return;
- }
-
- spin_lock_irqsave(&catc->tx_lock, flags);
-
- if (catc->tx_ptr) {
- r = catc_tx_run(catc);
- if (unlikely(r < 0))
- clear_bit(TX_RUNNING, &catc->flags);
- } else {
- clear_bit(TX_RUNNING, &catc->flags);
- }
-
- netif_wake_queue(catc->netdev);
-
- spin_unlock_irqrestore(&catc->tx_lock, flags);
-}
-
-static netdev_tx_t catc_start_xmit(struct sk_buff *skb,
- struct net_device *netdev)
-{
- struct catc *catc = netdev_priv(netdev);
- unsigned long flags;
- int r = 0;
- char *tx_buf;
-
- spin_lock_irqsave(&catc->tx_lock, flags);
-
- catc->tx_ptr = (((catc->tx_ptr - 1) >> 6) + 1) << 6;
- tx_buf = catc->tx_buf[catc->tx_idx] + catc->tx_ptr;
- if (catc->is_f5u011)
- *(__be16 *)tx_buf = cpu_to_be16(skb->len);
- else
- *(__le16 *)tx_buf = cpu_to_le16(skb->len);
- skb_copy_from_linear_data(skb, tx_buf + 2, skb->len);
- catc->tx_ptr += skb->len + 2;
-
- if (!test_and_set_bit(TX_RUNNING, &catc->flags)) {
- r = catc_tx_run(catc);
- if (r < 0)
- clear_bit(TX_RUNNING, &catc->flags);
- }
-
- if ((catc->is_f5u011 && catc->tx_ptr) ||
- (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2))))
- netif_stop_queue(netdev);
-
- spin_unlock_irqrestore(&catc->tx_lock, flags);
-
- if (r >= 0) {
- catc->netdev->stats.tx_bytes += skb->len;
- catc->netdev->stats.tx_packets++;
- }
-
- dev_kfree_skb(skb);
-
- return NETDEV_TX_OK;
-}
-
-static void catc_tx_timeout(struct net_device *netdev)
-{
- struct catc *catc = netdev_priv(netdev);
-
- dev_warn(&netdev->dev, "Transmit timed out.\n");
- usb_unlink_urb(catc->tx_urb);
-}
-
-/*
- * Control messages.
- */
-
-static int catc_ctrl_msg(struct catc *catc, u8 dir, u8 request, u16 value, u16 index, void *buf, int len)
-{
- int retval = usb_control_msg(catc->usbdev,
- dir ? usb_rcvctrlpipe(catc->usbdev, 0) : usb_sndctrlpipe(catc->usbdev, 0),
- request, 0x40 | dir, value, index, buf, len, 1000);
- return retval < 0 ? retval : 0;
-}
-
-static void catc_ctrl_run(struct catc *catc)
-{
- struct ctrl_queue *q = catc->ctrl_queue + catc->ctrl_tail;
- struct usb_device *usbdev = catc->usbdev;
- struct urb *urb = catc->ctrl_urb;
- struct usb_ctrlrequest *dr = &catc->ctrl_dr;
- int status;
-
- dr->bRequest = q->request;
- dr->bRequestType = 0x40 | q->dir;
- dr->wValue = cpu_to_le16(q->value);
- dr->wIndex = cpu_to_le16(q->index);
- dr->wLength = cpu_to_le16(q->len);
-
- urb->pipe = q->dir ? usb_rcvctrlpipe(usbdev, 0) : usb_sndctrlpipe(usbdev, 0);
- urb->transfer_buffer_length = q->len;
- urb->transfer_buffer = catc->ctrl_buf;
- urb->setup_packet = (void *) dr;
- urb->dev = usbdev;
-
- if (!q->dir && q->buf && q->len)
- memcpy(catc->ctrl_buf, q->buf, q->len);
-
- if ((status = usb_submit_urb(catc->ctrl_urb, GFP_ATOMIC)))
- err("submit(ctrl_urb) status %d", status);
-}
-
-static void catc_ctrl_done(struct urb *urb)
-{
- struct catc *catc = urb->context;
- struct ctrl_queue *q;
- unsigned long flags;
- int status = urb->status;
-
- if (status)
- dbg("ctrl_done, status %d, len %d.", status, urb->actual_length);
-
- spin_lock_irqsave(&catc->ctrl_lock, flags);
-
- q = catc->ctrl_queue + catc->ctrl_tail;
-
- if (q->dir) {
- if (q->buf && q->len)
- memcpy(q->buf, catc->ctrl_buf, q->len);
- else
- q->buf = catc->ctrl_buf;
- }
-
- if (q->callback)
- q->callback(catc, q);
-
- catc->ctrl_tail = (catc->ctrl_tail + 1) & (CTRL_QUEUE - 1);
-
- if (catc->ctrl_head != catc->ctrl_tail)
- catc_ctrl_run(catc);
- else
- clear_bit(CTRL_RUNNING, &catc->flags);
-
- spin_unlock_irqrestore(&catc->ctrl_lock, flags);
-}
-
-static int catc_ctrl_async(struct catc *catc, u8 dir, u8 request, u16 value,
- u16 index, void *buf, int len, void (*callback)(struct catc *catc, struct ctrl_queue *q))
-{
- struct ctrl_queue *q;
- int retval = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&catc->ctrl_lock, flags);
-
- q = catc->ctrl_queue + catc->ctrl_head;
-
- q->dir = dir;
- q->request = request;
- q->value = value;
- q->index = index;
- q->buf = buf;
- q->len = len;
- q->callback = callback;
-
- catc->ctrl_head = (catc->ctrl_head + 1) & (CTRL_QUEUE - 1);
-
- if (catc->ctrl_head == catc->ctrl_tail) {
- err("ctrl queue full");
- catc->ctrl_tail = (catc->ctrl_tail + 1) & (CTRL_QUEUE - 1);
- retval = -1;
- }
-
- if (!test_and_set_bit(CTRL_RUNNING, &catc->flags))
- catc_ctrl_run(catc);
-
- spin_unlock_irqrestore(&catc->ctrl_lock, flags);
-
- return retval;
-}
-
-/*
- * Statistics.
- */
-
-static void catc_stats_done(struct catc *catc, struct ctrl_queue *q)
-{
- int index = q->index - EthStats;
- u16 data, last;
-
- catc->stats_buf[index] = *((char *)q->buf);
-
- if (index & 1)
- return;
-
- data = ((u16)catc->stats_buf[index] << 8) | catc->stats_buf[index + 1];
- last = catc->stats_vals[index >> 1];
-
- switch (index) {
- case TxSingleColl:
- case TxMultiColl:
- catc->netdev->stats.collisions += data - last;
- break;
- case TxExcessColl:
- catc->netdev->stats.tx_aborted_errors += data - last;
- catc->netdev->stats.tx_errors += data - last;
- break;
- case RxFramErr:
- catc->netdev->stats.rx_frame_errors += data - last;
- catc->netdev->stats.rx_errors += data - last;
- break;
- }
-
- catc->stats_vals[index >> 1] = data;
-}
-
-static void catc_stats_timer(unsigned long data)
-{
- struct catc *catc = (void *) data;
- int i;
-
- for (i = 0; i < 8; i++)
- catc_get_reg_async(catc, EthStats + 7 - i, catc_stats_done);
-
- mod_timer(&catc->timer, jiffies + STATS_UPDATE);
-}
-
-/*
- * Receive modes. Broadcast, Multicast, Promisc.
- */
-
-static void catc_multicast(unsigned char *addr, u8 *multicast)
-{
- u32 crc;
-
- crc = ether_crc_le(6, addr);
- multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7);
-}
-
-static void catc_set_multicast_list(struct net_device *netdev)
-{
- struct catc *catc = netdev_priv(netdev);
- struct netdev_hw_addr *ha;
- u8 broadcast[6];
- u8 rx = RxEnable | RxPolarity | RxMultiCast;
-
- memset(broadcast, 0xff, 6);
- memset(catc->multicast, 0, 64);
-
- catc_multicast(broadcast, catc->multicast);
- catc_multicast(netdev->dev_addr, catc->multicast);
-
- if (netdev->flags & IFF_PROMISC) {
- memset(catc->multicast, 0xff, 64);
- rx |= (!catc->is_f5u011) ? RxPromisc : AltRxPromisc;
- }
-
- if (netdev->flags & IFF_ALLMULTI) {
- memset(catc->multicast, 0xff, 64);
- } else {
- netdev_for_each_mc_addr(ha, netdev) {
- u32 crc = ether_crc_le(6, ha->addr);
- if (!catc->is_f5u011) {
- catc->multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7);
- } else {
- catc->multicast[7-(crc >> 29)] |= 1 << ((crc >> 26) & 7);
- }
- }
- }
- if (!catc->is_f5u011) {
- catc_set_reg_async(catc, RxUnit, rx);
- catc_write_mem_async(catc, 0xfa80, catc->multicast, 64);
- } else {
- f5u011_mchash_async(catc, catc->multicast);
- if (catc->rxmode[0] != rx) {
- catc->rxmode[0] = rx;
- dbg("Setting RX mode to %2.2X %2.2X", catc->rxmode[0], catc->rxmode[1]);
- f5u011_rxmode_async(catc, catc->rxmode);
- }
- }
-}
-
-static void catc_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- struct catc *catc = netdev_priv(dev);
- strncpy(info->driver, driver_name, ETHTOOL_BUSINFO_LEN);
- strncpy(info->version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
- usb_make_path (catc->usbdev, info->bus_info, sizeof info->bus_info);
-}
-
-static int catc_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct catc *catc = netdev_priv(dev);
- if (!catc->is_f5u011)
- return -EOPNOTSUPP;
-
- cmd->supported = SUPPORTED_10baseT_Half | SUPPORTED_TP;
- cmd->advertising = ADVERTISED_10baseT_Half | ADVERTISED_TP;
- ethtool_cmd_speed_set(cmd, SPEED_10);
- cmd->duplex = DUPLEX_HALF;
- cmd->port = PORT_TP;
- cmd->phy_address = 0;
- cmd->transceiver = XCVR_INTERNAL;
- cmd->autoneg = AUTONEG_DISABLE;
- cmd->maxtxpkt = 1;
- cmd->maxrxpkt = 1;
- return 0;
-}
-
-static const struct ethtool_ops ops = {
- .get_drvinfo = catc_get_drvinfo,
- .get_settings = catc_get_settings,
- .get_link = ethtool_op_get_link
-};
-
-/*
- * Open, close.
- */
-
-static int catc_open(struct net_device *netdev)
-{
- struct catc *catc = netdev_priv(netdev);
- int status;
-
- catc->irq_urb->dev = catc->usbdev;
- if ((status = usb_submit_urb(catc->irq_urb, GFP_KERNEL)) < 0) {
- err("submit(irq_urb) status %d", status);
- return -1;
- }
-
- netif_start_queue(netdev);
-
- if (!catc->is_f5u011)
- mod_timer(&catc->timer, jiffies + STATS_UPDATE);
-
- return 0;
-}
-
-static int catc_stop(struct net_device *netdev)
-{
- struct catc *catc = netdev_priv(netdev);
-
- netif_stop_queue(netdev);
-
- if (!catc->is_f5u011)
- del_timer_sync(&catc->timer);
-
- usb_kill_urb(catc->rx_urb);
- usb_kill_urb(catc->tx_urb);
- usb_kill_urb(catc->irq_urb);
- usb_kill_urb(catc->ctrl_urb);
-
- return 0;
-}
-
-static const struct net_device_ops catc_netdev_ops = {
- .ndo_open = catc_open,
- .ndo_stop = catc_stop,
- .ndo_start_xmit = catc_start_xmit,
-
- .ndo_tx_timeout = catc_tx_timeout,
- .ndo_set_rx_mode = catc_set_multicast_list,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/*
- * USB probe, disconnect.
- */
-
-static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *usbdev = interface_to_usbdev(intf);
- struct net_device *netdev;
- struct catc *catc;
- u8 broadcast[6];
- int i, pktsz;
-
- if (usb_set_interface(usbdev,
- intf->altsetting->desc.bInterfaceNumber, 1)) {
- err("Can't set altsetting 1.");
- return -EIO;
- }
-
- netdev = alloc_etherdev(sizeof(struct catc));
- if (!netdev)
- return -ENOMEM;
-
- catc = netdev_priv(netdev);
-
- netdev->netdev_ops = &catc_netdev_ops;
- netdev->watchdog_timeo = TX_TIMEOUT;
- SET_ETHTOOL_OPS(netdev, &ops);
-
- catc->usbdev = usbdev;
- catc->netdev = netdev;
-
- spin_lock_init(&catc->tx_lock);
- spin_lock_init(&catc->ctrl_lock);
-
- init_timer(&catc->timer);
- catc->timer.data = (long) catc;
- catc->timer.function = catc_stats_timer;
-
- catc->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
- catc->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
- catc->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
- catc->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
- if ((!catc->ctrl_urb) || (!catc->tx_urb) ||
- (!catc->rx_urb) || (!catc->irq_urb)) {
- err("No free urbs available.");
- usb_free_urb(catc->ctrl_urb);
- usb_free_urb(catc->tx_urb);
- usb_free_urb(catc->rx_urb);
- usb_free_urb(catc->irq_urb);
- free_netdev(netdev);
- return -ENOMEM;
- }
-
- /* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */
- if (le16_to_cpu(usbdev->descriptor.idVendor) == 0x0423 &&
- le16_to_cpu(usbdev->descriptor.idProduct) == 0xa &&
- le16_to_cpu(catc->usbdev->descriptor.bcdDevice) == 0x0130) {
- dbg("Testing for f5u011");
- catc->is_f5u011 = 1;
- atomic_set(&catc->recq_sz, 0);
- pktsz = RX_PKT_SZ;
- } else {
- pktsz = RX_MAX_BURST * (PKT_SZ + 2);
- }
-
- usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0),
- NULL, NULL, 0, catc_ctrl_done, catc);
-
- usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1),
- NULL, 0, catc_tx_done, catc);
-
- usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1),
- catc->rx_buf, pktsz, catc_rx_done, catc);
-
- usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2),
- catc->irq_buf, 2, catc_irq_done, catc, 1);
-
- if (!catc->is_f5u011) {
- dbg("Checking memory size\n");
-
- i = 0x12345678;
- catc_write_mem(catc, 0x7a80, &i, 4);
- i = 0x87654321;
- catc_write_mem(catc, 0xfa80, &i, 4);
- catc_read_mem(catc, 0x7a80, &i, 4);
-
- switch (i) {
- case 0x12345678:
- catc_set_reg(catc, TxBufCount, 8);
- catc_set_reg(catc, RxBufCount, 32);
- dbg("64k Memory\n");
- break;
- default:
- dev_warn(&intf->dev,
- "Couldn't detect memory size, assuming 32k\n");
- case 0x87654321:
- catc_set_reg(catc, TxBufCount, 4);
- catc_set_reg(catc, RxBufCount, 16);
- dbg("32k Memory\n");
- break;
- }
-
- dbg("Getting MAC from SEEROM.");
-
- catc_get_mac(catc, netdev->dev_addr);
-
- dbg("Setting MAC into registers.");
-
- for (i = 0; i < 6; i++)
- catc_set_reg(catc, StationAddr0 - i, netdev->dev_addr[i]);
-
- dbg("Filling the multicast list.");
-
- memset(broadcast, 0xff, 6);
- catc_multicast(broadcast, catc->multicast);
- catc_multicast(netdev->dev_addr, catc->multicast);
- catc_write_mem(catc, 0xfa80, catc->multicast, 64);
-
- dbg("Clearing error counters.");
-
- for (i = 0; i < 8; i++)
- catc_set_reg(catc, EthStats + i, 0);
- catc->last_stats = jiffies;
-
- dbg("Enabling.");
-
- catc_set_reg(catc, MaxBurst, RX_MAX_BURST);
- catc_set_reg(catc, OpModes, OpTxMerge | OpRxMerge | OpLenInclude | Op3MemWaits);
- catc_set_reg(catc, LEDCtrl, LEDLink);
- catc_set_reg(catc, RxUnit, RxEnable | RxPolarity | RxMultiCast);
- } else {
- dbg("Performing reset\n");
- catc_reset(catc);
- catc_get_mac(catc, netdev->dev_addr);
-
- dbg("Setting RX Mode");
- catc->rxmode[0] = RxEnable | RxPolarity | RxMultiCast;
- catc->rxmode[1] = 0;
- f5u011_rxmode(catc, catc->rxmode);
- }
- dbg("Init done.");
- printk(KERN_INFO "%s: %s USB Ethernet at usb-%s-%s, %pM.\n",
- netdev->name, (catc->is_f5u011) ? "Belkin F5U011" : "CATC EL1210A NetMate",
- usbdev->bus->bus_name, usbdev->devpath, netdev->dev_addr);
- usb_set_intfdata(intf, catc);
-
- SET_NETDEV_DEV(netdev, &intf->dev);
- if (register_netdev(netdev) != 0) {
- usb_set_intfdata(intf, NULL);
- usb_free_urb(catc->ctrl_urb);
- usb_free_urb(catc->tx_urb);
- usb_free_urb(catc->rx_urb);
- usb_free_urb(catc->irq_urb);
- free_netdev(netdev);
- return -EIO;
- }
- return 0;
-}
-
-static void catc_disconnect(struct usb_interface *intf)
-{
- struct catc *catc = usb_get_intfdata(intf);
-
- usb_set_intfdata(intf, NULL);
- if (catc) {
- unregister_netdev(catc->netdev);
- usb_free_urb(catc->ctrl_urb);
- usb_free_urb(catc->tx_urb);
- usb_free_urb(catc->rx_urb);
- usb_free_urb(catc->irq_urb);
- free_netdev(catc->netdev);
- }
-}
-
-/*
- * Module functions and tables.
- */
-
-static struct usb_device_id catc_id_table [] = {
- { USB_DEVICE(0x0423, 0xa) }, /* CATC Netmate, Belkin F5U011 */
- { USB_DEVICE(0x0423, 0xc) }, /* CATC Netmate II, Belkin F5U111 */
- { USB_DEVICE(0x08d1, 0x1) }, /* smartBridges smartNIC */
- { }
-};
-
-MODULE_DEVICE_TABLE(usb, catc_id_table);
-
-static struct usb_driver catc_driver = {
- .name = driver_name,
- .probe = catc_probe,
- .disconnect = catc_disconnect,
- .id_table = catc_id_table,
-};
-
-module_usb_driver(catc_driver);
diff --git a/ANDROID_3.4.5/drivers/net/usb/cdc-phonet.c b/ANDROID_3.4.5/drivers/net/usb/cdc-phonet.c
deleted file mode 100644
index 3e41b00c..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/cdc-phonet.c
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * phonet.c -- USB CDC Phonet host driver
- *
- * Copyright (C) 2008-2009 Nokia Corporation. All rights reserved.
- *
- * Author: Rémi Denis-Courmont
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/gfp.h>
-#include <linux/usb.h>
-#include <linux/usb/cdc.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/if_phonet.h>
-#include <linux/phonet.h>
-
-#define PN_MEDIA_USB 0x1B
-
-static const unsigned rxq_size = 17;
-
-struct usbpn_dev {
- struct net_device *dev;
-
- struct usb_interface *intf, *data_intf;
- struct usb_device *usb;
- unsigned int tx_pipe, rx_pipe;
- u8 active_setting;
- u8 disconnected;
-
- unsigned tx_queue;
- spinlock_t tx_lock;
-
- spinlock_t rx_lock;
- struct sk_buff *rx_skb;
- struct urb *urbs[0];
-};
-
-static void tx_complete(struct urb *req);
-static void rx_complete(struct urb *req);
-
-/*
- * Network device callbacks
- */
-static netdev_tx_t usbpn_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct usbpn_dev *pnd = netdev_priv(dev);
- struct urb *req = NULL;
- unsigned long flags;
- int err;
-
- if (skb->protocol != htons(ETH_P_PHONET))
- goto drop;
-
- req = usb_alloc_urb(0, GFP_ATOMIC);
- if (!req)
- goto drop;
- usb_fill_bulk_urb(req, pnd->usb, pnd->tx_pipe, skb->data, skb->len,
- tx_complete, skb);
- req->transfer_flags = URB_ZERO_PACKET;
- err = usb_submit_urb(req, GFP_ATOMIC);
- if (err) {
- usb_free_urb(req);
- goto drop;
- }
-
- spin_lock_irqsave(&pnd->tx_lock, flags);
- pnd->tx_queue++;
- if (pnd->tx_queue >= dev->tx_queue_len)
- netif_stop_queue(dev);
- spin_unlock_irqrestore(&pnd->tx_lock, flags);
- return NETDEV_TX_OK;
-
-drop:
- dev_kfree_skb(skb);
- dev->stats.tx_dropped++;
- return NETDEV_TX_OK;
-}
-
-static void tx_complete(struct urb *req)
-{
- struct sk_buff *skb = req->context;
- struct net_device *dev = skb->dev;
- struct usbpn_dev *pnd = netdev_priv(dev);
- int status = req->status;
-
- switch (status) {
- case 0:
- dev->stats.tx_bytes += skb->len;
- break;
-
- case -ENOENT:
- case -ECONNRESET:
- case -ESHUTDOWN:
- dev->stats.tx_aborted_errors++;
- default:
- dev->stats.tx_errors++;
- dev_dbg(&dev->dev, "TX error (%d)\n", status);
- }
- dev->stats.tx_packets++;
-
- spin_lock(&pnd->tx_lock);
- pnd->tx_queue--;
- netif_wake_queue(dev);
- spin_unlock(&pnd->tx_lock);
-
- dev_kfree_skb_any(skb);
- usb_free_urb(req);
-}
-
-static int rx_submit(struct usbpn_dev *pnd, struct urb *req, gfp_t gfp_flags)
-{
- struct net_device *dev = pnd->dev;
- struct page *page;
- int err;
-
- page = alloc_page(gfp_flags);
- if (!page)
- return -ENOMEM;
-
- usb_fill_bulk_urb(req, pnd->usb, pnd->rx_pipe, page_address(page),
- PAGE_SIZE, rx_complete, dev);
- req->transfer_flags = 0;
- err = usb_submit_urb(req, gfp_flags);
- if (unlikely(err)) {
- dev_dbg(&dev->dev, "RX submit error (%d)\n", err);
- put_page(page);
- }
- return err;
-}
-
-static void rx_complete(struct urb *req)
-{
- struct net_device *dev = req->context;
- struct usbpn_dev *pnd = netdev_priv(dev);
- struct page *page = virt_to_page(req->transfer_buffer);
- struct sk_buff *skb;
- unsigned long flags;
- int status = req->status;
-
- switch (status) {
- case 0:
- spin_lock_irqsave(&pnd->rx_lock, flags);
- skb = pnd->rx_skb;
- if (!skb) {
- skb = pnd->rx_skb = netdev_alloc_skb(dev, 12);
- if (likely(skb)) {
- /* Can't use pskb_pull() on page in IRQ */
- memcpy(skb_put(skb, 1), page_address(page), 1);
- skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
- page, 1, req->actual_length,
- PAGE_SIZE);
- page = NULL;
- }
- } else {
- skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
- page, 0, req->actual_length,
- PAGE_SIZE);
- page = NULL;
- }
- if (req->actual_length < PAGE_SIZE)
- pnd->rx_skb = NULL; /* Last fragment */
- else
- skb = NULL;
- spin_unlock_irqrestore(&pnd->rx_lock, flags);
- if (skb) {
- skb->protocol = htons(ETH_P_PHONET);
- skb_reset_mac_header(skb);
- __skb_pull(skb, 1);
- skb->dev = dev;
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += skb->len;
-
- netif_rx(skb);
- }
- goto resubmit;
-
- case -ENOENT:
- case -ECONNRESET:
- case -ESHUTDOWN:
- req = NULL;
- break;
-
- case -EOVERFLOW:
- dev->stats.rx_over_errors++;
- dev_dbg(&dev->dev, "RX overflow\n");
- break;
-
- case -EILSEQ:
- dev->stats.rx_crc_errors++;
- break;
- }
-
- dev->stats.rx_errors++;
-resubmit:
- if (page)
- put_page(page);
- if (req)
- rx_submit(pnd, req, GFP_ATOMIC | __GFP_COLD);
-}
-
-static int usbpn_close(struct net_device *dev);
-
-static int usbpn_open(struct net_device *dev)
-{
- struct usbpn_dev *pnd = netdev_priv(dev);
- int err;
- unsigned i;
- unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber;
-
- err = usb_set_interface(pnd->usb, num, pnd->active_setting);
- if (err)
- return err;
-
- for (i = 0; i < rxq_size; i++) {
- struct urb *req = usb_alloc_urb(0, GFP_KERNEL);
-
- if (!req || rx_submit(pnd, req, GFP_KERNEL | __GFP_COLD)) {
- usbpn_close(dev);
- return -ENOMEM;
- }
- pnd->urbs[i] = req;
- }
-
- netif_wake_queue(dev);
- return 0;
-}
-
-static int usbpn_close(struct net_device *dev)
-{
- struct usbpn_dev *pnd = netdev_priv(dev);
- unsigned i;
- unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber;
-
- netif_stop_queue(dev);
-
- for (i = 0; i < rxq_size; i++) {
- struct urb *req = pnd->urbs[i];
-
- if (!req)
- continue;
- usb_kill_urb(req);
- usb_free_urb(req);
- pnd->urbs[i] = NULL;
- }
-
- return usb_set_interface(pnd->usb, num, !pnd->active_setting);
-}
-
-static int usbpn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-{
- struct if_phonet_req *req = (struct if_phonet_req *)ifr;
-
- switch (cmd) {
- case SIOCPNGAUTOCONF:
- req->ifr_phonet_autoconf.device = PN_DEV_PC;
- return 0;
- }
- return -ENOIOCTLCMD;
-}
-
-static int usbpn_set_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < PHONET_MIN_MTU) || (new_mtu > PHONET_MAX_MTU))
- return -EINVAL;
-
- dev->mtu = new_mtu;
- return 0;
-}
-
-static const struct net_device_ops usbpn_ops = {
- .ndo_open = usbpn_open,
- .ndo_stop = usbpn_close,
- .ndo_start_xmit = usbpn_xmit,
- .ndo_do_ioctl = usbpn_ioctl,
- .ndo_change_mtu = usbpn_set_mtu,
-};
-
-static void usbpn_setup(struct net_device *dev)
-{
- dev->features = 0;
- dev->netdev_ops = &usbpn_ops,
- dev->header_ops = &phonet_header_ops;
- dev->type = ARPHRD_PHONET;
- dev->flags = IFF_POINTOPOINT | IFF_NOARP;
- dev->mtu = PHONET_MAX_MTU;
- dev->hard_header_len = 1;
- dev->dev_addr[0] = PN_MEDIA_USB;
- dev->addr_len = 1;
- dev->tx_queue_len = 3;
-
- dev->destructor = free_netdev;
-}
-
-/*
- * USB driver callbacks
- */
-static struct usb_device_id usbpn_ids[] = {
- {
- .match_flags = USB_DEVICE_ID_MATCH_VENDOR
- | USB_DEVICE_ID_MATCH_INT_CLASS
- | USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .idVendor = 0x0421, /* Nokia */
- .bInterfaceClass = USB_CLASS_COMM,
- .bInterfaceSubClass = 0xFE,
- },
- { },
-};
-
-MODULE_DEVICE_TABLE(usb, usbpn_ids);
-
-static struct usb_driver usbpn_driver;
-
-int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- static const char ifname[] = "usbpn%d";
- const struct usb_cdc_union_desc *union_header = NULL;
- const struct usb_host_interface *data_desc;
- struct usb_interface *data_intf;
- struct usb_device *usbdev = interface_to_usbdev(intf);
- struct net_device *dev;
- struct usbpn_dev *pnd;
- u8 *data;
- int phonet = 0;
- int len, err;
-
- data = intf->altsetting->extra;
- len = intf->altsetting->extralen;
- while (len >= 3) {
- u8 dlen = data[0];
- if (dlen < 3)
- return -EINVAL;
-
- /* bDescriptorType */
- if (data[1] == USB_DT_CS_INTERFACE) {
- /* bDescriptorSubType */
- switch (data[2]) {
- case USB_CDC_UNION_TYPE:
- if (union_header || dlen < 5)
- break;
- union_header =
- (struct usb_cdc_union_desc *)data;
- break;
- case 0xAB:
- phonet = 1;
- break;
- }
- }
- data += dlen;
- len -= dlen;
- }
-
- if (!union_header || !phonet)
- return -EINVAL;
-
- data_intf = usb_ifnum_to_if(usbdev, union_header->bSlaveInterface0);
- if (data_intf == NULL)
- return -ENODEV;
- /* Data interface has one inactive and one active setting */
- if (data_intf->num_altsetting != 2)
- return -EINVAL;
- if (data_intf->altsetting[0].desc.bNumEndpoints == 0 &&
- data_intf->altsetting[1].desc.bNumEndpoints == 2)
- data_desc = data_intf->altsetting + 1;
- else
- if (data_intf->altsetting[0].desc.bNumEndpoints == 2 &&
- data_intf->altsetting[1].desc.bNumEndpoints == 0)
- data_desc = data_intf->altsetting;
- else
- return -EINVAL;
-
- dev = alloc_netdev(sizeof(*pnd) + sizeof(pnd->urbs[0]) * rxq_size,
- ifname, usbpn_setup);
- if (!dev)
- return -ENOMEM;
-
- pnd = netdev_priv(dev);
- SET_NETDEV_DEV(dev, &intf->dev);
-
- pnd->dev = dev;
- pnd->usb = usb_get_dev(usbdev);
- pnd->intf = intf;
- pnd->data_intf = data_intf;
- spin_lock_init(&pnd->tx_lock);
- spin_lock_init(&pnd->rx_lock);
- /* Endpoints */
- if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) {
- pnd->rx_pipe = usb_rcvbulkpipe(usbdev,
- data_desc->endpoint[0].desc.bEndpointAddress);
- pnd->tx_pipe = usb_sndbulkpipe(usbdev,
- data_desc->endpoint[1].desc.bEndpointAddress);
- } else {
- pnd->rx_pipe = usb_rcvbulkpipe(usbdev,
- data_desc->endpoint[1].desc.bEndpointAddress);
- pnd->tx_pipe = usb_sndbulkpipe(usbdev,
- data_desc->endpoint[0].desc.bEndpointAddress);
- }
- pnd->active_setting = data_desc - data_intf->altsetting;
-
- err = usb_driver_claim_interface(&usbpn_driver, data_intf, pnd);
- if (err)
- goto out;
-
- /* Force inactive mode until the network device is brought UP */
- usb_set_interface(usbdev, union_header->bSlaveInterface0,
- !pnd->active_setting);
- usb_set_intfdata(intf, pnd);
-
- err = register_netdev(dev);
- if (err) {
- usb_driver_release_interface(&usbpn_driver, data_intf);
- goto out;
- }
-
- dev_dbg(&dev->dev, "USB CDC Phonet device found\n");
- return 0;
-
-out:
- usb_set_intfdata(intf, NULL);
- free_netdev(dev);
- return err;
-}
-
-static void usbpn_disconnect(struct usb_interface *intf)
-{
- struct usbpn_dev *pnd = usb_get_intfdata(intf);
- struct usb_device *usb = pnd->usb;
-
- if (pnd->disconnected)
- return;
-
- pnd->disconnected = 1;
- usb_driver_release_interface(&usbpn_driver,
- (pnd->intf == intf) ? pnd->data_intf : pnd->intf);
- unregister_netdev(pnd->dev);
- usb_put_dev(usb);
-}
-
-static struct usb_driver usbpn_driver = {
- .name = "cdc_phonet",
- .probe = usbpn_probe,
- .disconnect = usbpn_disconnect,
- .id_table = usbpn_ids,
-};
-
-module_usb_driver(usbpn_driver);
-
-MODULE_AUTHOR("Remi Denis-Courmont");
-MODULE_DESCRIPTION("USB CDC Phonet host interface");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/cdc_eem.c b/ANDROID_3.4.5/drivers/net/usb/cdc_eem.c
deleted file mode 100644
index 685a4e22..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/cdc_eem.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * USB CDC EEM network interface driver
- * Copyright (C) 2009 Oberthur Technologies
- * by Omar Laazimani, Olivier Condemine
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ctype.h>
-#include <linux/ethtool.h>
-#include <linux/workqueue.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/crc32.h>
-#include <linux/usb/cdc.h>
-#include <linux/usb/usbnet.h>
-#include <linux/gfp.h>
-
-
-/*
- * This driver is an implementation of the CDC "Ethernet Emulation
- * Model" (EEM) specification, which encapsulates Ethernet frames
- * for transport over USB using a simpler USB device model than the
- * previous CDC "Ethernet Control Model" (ECM, or "CDC Ethernet").
- *
- * For details, see www.usb.org/developers/devclass_docs/CDC_EEM10.pdf
- *
- * This version has been tested with GIGAntIC WuaoW SIM Smart Card on 2.6.24,
- * 2.6.27 and 2.6.30rc2 kernel.
- * It has also been validated on Openmoko Om 2008.12 (based on 2.6.24 kernel).
- * build on 23-April-2009
- */
-
-#define EEM_HEAD 2 /* 2 byte header */
-
-/*-------------------------------------------------------------------------*/
-
-static void eem_linkcmd_complete(struct urb *urb)
-{
- dev_kfree_skb(urb->context);
- usb_free_urb(urb);
-}
-
-static void eem_linkcmd(struct usbnet *dev, struct sk_buff *skb)
-{
- struct urb *urb;
- int status;
-
- urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!urb)
- goto fail;
-
- usb_fill_bulk_urb(urb, dev->udev, dev->out,
- skb->data, skb->len, eem_linkcmd_complete, skb);
-
- status = usb_submit_urb(urb, GFP_ATOMIC);
- if (status) {
- usb_free_urb(urb);
-fail:
- dev_kfree_skb(skb);
- netdev_warn(dev->net, "link cmd failure\n");
- return;
- }
-}
-
-static int eem_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- int status = 0;
-
- status = usbnet_get_endpoints(dev, intf);
- if (status < 0) {
- usb_set_intfdata(intf, NULL);
- usb_driver_release_interface(driver_of(intf), intf);
- return status;
- }
-
- /* no jumbogram (16K) support for now */
-
- dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN;
- dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
-
- return 0;
-}
-
-/*
- * EEM permits packing multiple Ethernet frames into USB transfers
- * (a "bundle"), but for TX we don't try to do that.
- */
-static struct sk_buff *eem_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
- gfp_t flags)
-{
- struct sk_buff *skb2 = NULL;
- u16 len = skb->len;
- u32 crc = 0;
- int padlen = 0;
-
- /* When ((len + EEM_HEAD + ETH_FCS_LEN) % dev->maxpacket) is
- * zero, stick two bytes of zero length EEM packet on the end.
- * Else the framework would add invalid single byte padding,
- * since it can't know whether ZLPs will be handled right by
- * all the relevant hardware and software.
- */
- if (!((len + EEM_HEAD + ETH_FCS_LEN) % dev->maxpacket))
- padlen += 2;
-
- if (!skb_cloned(skb)) {
- int headroom = skb_headroom(skb);
- int tailroom = skb_tailroom(skb);
-
- if ((tailroom >= ETH_FCS_LEN + padlen) &&
- (headroom >= EEM_HEAD))
- goto done;
-
- if ((headroom + tailroom)
- > (EEM_HEAD + ETH_FCS_LEN + padlen)) {
- skb->data = memmove(skb->head +
- EEM_HEAD,
- skb->data,
- skb->len);
- skb_set_tail_pointer(skb, len);
- goto done;
- }
- }
-
- skb2 = skb_copy_expand(skb, EEM_HEAD, ETH_FCS_LEN + padlen, flags);
- if (!skb2)
- return NULL;
-
- dev_kfree_skb_any(skb);
- skb = skb2;
-
-done:
- /* we don't use the "no Ethernet CRC" option */
- crc = crc32_le(~0, skb->data, skb->len);
- crc = ~crc;
-
- put_unaligned_le32(crc, skb_put(skb, 4));
-
- /* EEM packet header format:
- * b0..13: length of ethernet frame
- * b14: bmCRC (1 == valid Ethernet CRC)
- * b15: bmType (0 == data)
- */
- len = skb->len;
- put_unaligned_le16(BIT(14) | len, skb_push(skb, 2));
-
- /* Bundle a zero length EEM packet if needed */
- if (padlen)
- put_unaligned_le16(0, skb_put(skb, 2));
-
- return skb;
-}
-
-static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- /*
- * Our task here is to strip off framing, leaving skb with one
- * data frame for the usbnet framework code to process. But we
- * may have received multiple EEM payloads, or command payloads.
- * So we must process _everything_ as if it's a header, except
- * maybe the last data payload
- *
- * REVISIT the framework needs updating so that when we consume
- * all payloads (the last or only message was a command, or a
- * zero length EEM packet) that is not accounted as an rx_error.
- */
- do {
- struct sk_buff *skb2 = NULL;
- u16 header;
- u16 len = 0;
-
- /* incomplete EEM header? */
- if (skb->len < EEM_HEAD)
- return 0;
-
- /*
- * EEM packet header format:
- * b0..14: EEM type dependent (Data or Command)
- * b15: bmType
- */
- header = get_unaligned_le16(skb->data);
- skb_pull(skb, EEM_HEAD);
-
- /*
- * The bmType bit helps to denote when EEM
- * packet is data or command :
- * bmType = 0 : EEM data payload
- * bmType = 1 : EEM (link) command
- */
- if (header & BIT(15)) {
- u16 bmEEMCmd;
-
- /*
- * EEM (link) command packet:
- * b0..10: bmEEMCmdParam
- * b11..13: bmEEMCmd
- * b14: bmReserved (must be 0)
- * b15: 1 (EEM command)
- */
- if (header & BIT(14)) {
- netdev_dbg(dev->net, "reserved command %04x\n",
- header);
- continue;
- }
-
- bmEEMCmd = (header >> 11) & 0x7;
- switch (bmEEMCmd) {
-
- /* Responding to echo requests is mandatory. */
- case 0: /* Echo command */
- len = header & 0x7FF;
-
- /* bogus command? */
- if (skb->len < len)
- return 0;
-
- skb2 = skb_clone(skb, GFP_ATOMIC);
- if (unlikely(!skb2))
- goto next;
- skb_trim(skb2, len);
- put_unaligned_le16(BIT(15) | (1 << 11) | len,
- skb_push(skb2, 2));
- eem_linkcmd(dev, skb2);
- break;
-
- /*
- * Host may choose to ignore hints.
- * - suspend: peripheral ready to suspend
- * - response: suggest N millisec polling
- * - response complete: suggest N sec polling
- */
- case 2: /* Suspend hint */
- case 3: /* Response hint */
- case 4: /* Response complete hint */
- continue;
-
- /*
- * Hosts should never receive host-to-peripheral
- * or reserved command codes; or responses to an
- * echo command we didn't send.
- */
- case 1: /* Echo response */
- case 5: /* Tickle */
- default: /* reserved */
- netdev_warn(dev->net,
- "unexpected link command %d\n",
- bmEEMCmd);
- continue;
- }
-
- } else {
- u32 crc, crc2;
- int is_last;
-
- /* zero length EEM packet? */
- if (header == 0)
- continue;
-
- /*
- * EEM data packet header :
- * b0..13: length of ethernet frame
- * b14: bmCRC
- * b15: 0 (EEM data)
- */
- len = header & 0x3FFF;
-
- /* bogus EEM payload? */
- if (skb->len < len)
- return 0;
-
- /* bogus ethernet frame? */
- if (len < (ETH_HLEN + ETH_FCS_LEN))
- goto next;
-
- /*
- * Treat the last payload differently: framework
- * code expects our "fixup" to have stripped off
- * headers, so "skb" is a data packet (or error).
- * Else if it's not the last payload, keep "skb"
- * for further processing.
- */
- is_last = (len == skb->len);
- if (is_last)
- skb2 = skb;
- else {
- skb2 = skb_clone(skb, GFP_ATOMIC);
- if (unlikely(!skb2))
- return 0;
- }
-
- /*
- * The bmCRC helps to denote when the CRC field in
- * the Ethernet frame contains a calculated CRC:
- * bmCRC = 1 : CRC is calculated
- * bmCRC = 0 : CRC = 0xDEADBEEF
- */
- if (header & BIT(14)) {
- crc = get_unaligned_le32(skb2->data
- + len - ETH_FCS_LEN);
- crc2 = ~crc32_le(~0, skb2->data, skb2->len
- - ETH_FCS_LEN);
- } else {
- crc = get_unaligned_be32(skb2->data
- + len - ETH_FCS_LEN);
- crc2 = 0xdeadbeef;
- }
- skb_trim(skb2, len - ETH_FCS_LEN);
-
- if (is_last)
- return crc == crc2;
-
- if (unlikely(crc != crc2)) {
- dev->net->stats.rx_errors++;
- dev_kfree_skb_any(skb2);
- } else
- usbnet_skb_return(dev, skb2);
- }
-
-next:
- skb_pull(skb, len);
- } while (skb->len);
-
- return 1;
-}
-
-static const struct driver_info eem_info = {
- .description = "CDC EEM Device",
- .flags = FLAG_ETHER | FLAG_POINTTOPOINT,
- .bind = eem_bind,
- .rx_fixup = eem_rx_fixup,
- .tx_fixup = eem_tx_fixup,
-};
-
-/*-------------------------------------------------------------------------*/
-
-static const struct usb_device_id products[] = {
-{
- USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_EEM,
- USB_CDC_PROTO_EEM),
- .driver_info = (unsigned long) &eem_info,
-},
-{
- /* EMPTY == end of list */
-},
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver eem_driver = {
- .name = "cdc_eem",
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
-};
-
-module_usb_driver(eem_driver);
-
-MODULE_AUTHOR("Omar Laazimani <omar.oberthur@gmail.com>");
-MODULE_DESCRIPTION("USB CDC EEM");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/cdc_ether.c b/ANDROID_3.4.5/drivers/net/usb/cdc_ether.c
deleted file mode 100644
index 202af629..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/cdc_ether.c
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * CDC Ethernet based networking peripherals
- * Copyright (C) 2003-2005 by David Brownell
- * Copyright (C) 2006 by Ole Andre Vadla Ravnas (ActiveSync)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-// #define DEBUG // error path messages, extra info
-// #define VERBOSE // more; success messages
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/workqueue.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/usb/cdc.h>
-#include <linux/usb/usbnet.h>
-
-
-#if defined(CONFIG_USB_NET_RNDIS_HOST) || defined(CONFIG_USB_NET_RNDIS_HOST_MODULE)
-
-static int is_rndis(struct usb_interface_descriptor *desc)
-{
- return (desc->bInterfaceClass == USB_CLASS_COMM &&
- desc->bInterfaceSubClass == 2 &&
- desc->bInterfaceProtocol == 0xff);
-}
-
-static int is_activesync(struct usb_interface_descriptor *desc)
-{
- return (desc->bInterfaceClass == USB_CLASS_MISC &&
- desc->bInterfaceSubClass == 1 &&
- desc->bInterfaceProtocol == 1);
-}
-
-static int is_wireless_rndis(struct usb_interface_descriptor *desc)
-{
- return (desc->bInterfaceClass == USB_CLASS_WIRELESS_CONTROLLER &&
- desc->bInterfaceSubClass == 1 &&
- desc->bInterfaceProtocol == 3);
-}
-
-#else
-
-#define is_rndis(desc) 0
-#define is_activesync(desc) 0
-#define is_wireless_rndis(desc) 0
-
-#endif
-
-static const u8 mbm_guid[16] = {
- 0xa3, 0x17, 0xa8, 0x8b, 0x04, 0x5e, 0x4f, 0x01,
- 0xa6, 0x07, 0xc0, 0xff, 0xcb, 0x7e, 0x39, 0x2a,
-};
-
-/*
- * probes control interface, claims data interface, collects the bulk
- * endpoints, activates data interface (if needed), maybe sets MTU.
- * all pure cdc, except for certain firmware workarounds, and knowing
- * that rndis uses one different rule.
- */
-int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- u8 *buf = intf->cur_altsetting->extra;
- int len = intf->cur_altsetting->extralen;
- struct usb_interface_descriptor *d;
- struct cdc_state *info = (void *) &dev->data;
- int status;
- int rndis;
- bool android_rndis_quirk = false;
- struct usb_driver *driver = driver_of(intf);
- struct usb_cdc_mdlm_desc *desc = NULL;
- struct usb_cdc_mdlm_detail_desc *detail = NULL;
-
- if (sizeof dev->data < sizeof *info)
- return -EDOM;
-
- /* expect strict spec conformance for the descriptors, but
- * cope with firmware which stores them in the wrong place
- */
- if (len == 0 && dev->udev->actconfig->extralen) {
- /* Motorola SB4100 (and others: Brad Hards says it's
- * from a Broadcom design) put CDC descriptors here
- */
- buf = dev->udev->actconfig->extra;
- len = dev->udev->actconfig->extralen;
- dev_dbg(&intf->dev, "CDC descriptors on config\n");
- }
-
- /* Maybe CDC descriptors are after the endpoint? This bug has
- * been seen on some 2Wire Inc RNDIS-ish products.
- */
- if (len == 0) {
- struct usb_host_endpoint *hep;
-
- hep = intf->cur_altsetting->endpoint;
- if (hep) {
- buf = hep->extra;
- len = hep->extralen;
- }
- if (len)
- dev_dbg(&intf->dev,
- "CDC descriptors on endpoint\n");
- }
-
- /* this assumes that if there's a non-RNDIS vendor variant
- * of cdc-acm, it'll fail RNDIS requests cleanly.
- */
- rndis = (is_rndis(&intf->cur_altsetting->desc) ||
- is_activesync(&intf->cur_altsetting->desc) ||
- is_wireless_rndis(&intf->cur_altsetting->desc));
-
- memset(info, 0, sizeof *info);
- info->control = intf;
- while (len > 3) {
- if (buf [1] != USB_DT_CS_INTERFACE)
- goto next_desc;
-
- /* use bDescriptorSubType to identify the CDC descriptors.
- * We expect devices with CDC header and union descriptors.
- * For CDC Ethernet we need the ethernet descriptor.
- * For RNDIS, ignore two (pointless) CDC modem descriptors
- * in favor of a complicated OID-based RPC scheme doing what
- * CDC Ethernet achieves with a simple descriptor.
- */
- switch (buf [2]) {
- case USB_CDC_HEADER_TYPE:
- if (info->header) {
- dev_dbg(&intf->dev, "extra CDC header\n");
- goto bad_desc;
- }
- info->header = (void *) buf;
- if (info->header->bLength != sizeof *info->header) {
- dev_dbg(&intf->dev, "CDC header len %u\n",
- info->header->bLength);
- goto bad_desc;
- }
- break;
- case USB_CDC_ACM_TYPE:
- /* paranoia: disambiguate a "real" vendor-specific
- * modem interface from an RNDIS non-modem.
- */
- if (rndis) {
- struct usb_cdc_acm_descriptor *acm;
-
- acm = (void *) buf;
- if (acm->bmCapabilities) {
- dev_dbg(&intf->dev,
- "ACM capabilities %02x, "
- "not really RNDIS?\n",
- acm->bmCapabilities);
- goto bad_desc;
- }
- }
- break;
- case USB_CDC_UNION_TYPE:
- if (info->u) {
- dev_dbg(&intf->dev, "extra CDC union\n");
- goto bad_desc;
- }
- info->u = (void *) buf;
- if (info->u->bLength != sizeof *info->u) {
- dev_dbg(&intf->dev, "CDC union len %u\n",
- info->u->bLength);
- goto bad_desc;
- }
-
- /* we need a master/control interface (what we're
- * probed with) and a slave/data interface; union
- * descriptors sort this all out.
- */
- info->control = usb_ifnum_to_if(dev->udev,
- info->u->bMasterInterface0);
- info->data = usb_ifnum_to_if(dev->udev,
- info->u->bSlaveInterface0);
- if (!info->control || !info->data) {
- dev_dbg(&intf->dev,
- "master #%u/%p slave #%u/%p\n",
- info->u->bMasterInterface0,
- info->control,
- info->u->bSlaveInterface0,
- info->data);
- /* fall back to hard-wiring for RNDIS */
- if (rndis) {
- android_rndis_quirk = true;
- goto next_desc;
- }
- goto bad_desc;
- }
- if (info->control != intf) {
- dev_dbg(&intf->dev, "bogus CDC Union\n");
- /* Ambit USB Cable Modem (and maybe others)
- * interchanges master and slave interface.
- */
- if (info->data == intf) {
- info->data = info->control;
- info->control = intf;
- } else
- goto bad_desc;
- }
-
- /* a data interface altsetting does the real i/o */
- d = &info->data->cur_altsetting->desc;
- if (d->bInterfaceClass != USB_CLASS_CDC_DATA) {
- dev_dbg(&intf->dev, "slave class %u\n",
- d->bInterfaceClass);
- goto bad_desc;
- }
- break;
- case USB_CDC_ETHERNET_TYPE:
- if (info->ether) {
- dev_dbg(&intf->dev, "extra CDC ether\n");
- goto bad_desc;
- }
- info->ether = (void *) buf;
- if (info->ether->bLength != sizeof *info->ether) {
- dev_dbg(&intf->dev, "CDC ether len %u\n",
- info->ether->bLength);
- goto bad_desc;
- }
- dev->hard_mtu = le16_to_cpu(
- info->ether->wMaxSegmentSize);
- /* because of Zaurus, we may be ignoring the host
- * side link address we were given.
- */
- break;
- case USB_CDC_MDLM_TYPE:
- if (desc) {
- dev_dbg(&intf->dev, "extra MDLM descriptor\n");
- goto bad_desc;
- }
-
- desc = (void *)buf;
-
- if (desc->bLength != sizeof(*desc))
- goto bad_desc;
-
- if (memcmp(&desc->bGUID, mbm_guid, 16))
- goto bad_desc;
- break;
- case USB_CDC_MDLM_DETAIL_TYPE:
- if (detail) {
- dev_dbg(&intf->dev, "extra MDLM detail descriptor\n");
- goto bad_desc;
- }
-
- detail = (void *)buf;
-
- if (detail->bGuidDescriptorType == 0) {
- if (detail->bLength < (sizeof(*detail) + 1))
- goto bad_desc;
- } else
- goto bad_desc;
- break;
- }
-next_desc:
- len -= buf [0]; /* bLength */
- buf += buf [0];
- }
-
- /* Microsoft ActiveSync based and some regular RNDIS devices lack the
- * CDC descriptors, so we'll hard-wire the interfaces and not check
- * for descriptors.
- *
- * Some Android RNDIS devices have a CDC Union descriptor pointing
- * to non-existing interfaces. Ignore that and attempt the same
- * hard-wired 0 and 1 interfaces.
- */
- if (rndis && (!info->u || android_rndis_quirk)) {
- info->control = usb_ifnum_to_if(dev->udev, 0);
- info->data = usb_ifnum_to_if(dev->udev, 1);
- if (!info->control || !info->data || info->control != intf) {
- dev_dbg(&intf->dev,
- "rndis: master #0/%p slave #1/%p\n",
- info->control,
- info->data);
- goto bad_desc;
- }
-
- } else if (!info->header || !info->u || (!rndis && !info->ether)) {
- dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n",
- info->header ? "" : "header ",
- info->u ? "" : "union ",
- info->ether ? "" : "ether ");
- goto bad_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;
- 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);
- return status;
- }
-
- /* status endpoint: optional for CDC Ethernet, not RNDIS (or ACM) */
- dev->status = NULL;
- if (info->control->cur_altsetting->desc.bNumEndpoints == 1) {
- struct usb_endpoint_descriptor *desc;
-
- dev->status = &info->control->cur_altsetting->endpoint [0];
- desc = &dev->status->desc;
- if (!usb_endpoint_is_int_in(desc) ||
- (le16_to_cpu(desc->wMaxPacketSize)
- < sizeof(struct usb_cdc_notification)) ||
- !desc->bInterval) {
- dev_dbg(&intf->dev, "bad notification endpoint\n");
- dev->status = NULL;
- }
- }
- if (rndis && !dev->status) {
- dev_dbg(&intf->dev, "missing RNDIS status endpoint\n");
- usb_set_intfdata(info->data, NULL);
- usb_driver_release_interface(driver, info->data);
- return -ENODEV;
- }
- return 0;
-
-bad_desc:
- dev_info(&dev->udev->dev, "bad CDC descriptors\n");
- return -ENODEV;
-}
-EXPORT_SYMBOL_GPL(usbnet_generic_cdc_bind);
-
-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);
-
- /* disconnect master --> disconnect slave */
- if (intf == info->control && info->data) {
- /* ensure immediate exit from usbnet_disconnect */
- usb_set_intfdata(info->data, NULL);
- usb_driver_release_interface(driver, info->data);
- info->data = NULL;
- }
-
- /* and vice versa (just in case) */
- else if (intf == info->data && info->control) {
- /* ensure immediate exit from usbnet_disconnect */
- usb_set_intfdata(info->control, NULL);
- usb_driver_release_interface(driver, info->control);
- info->control = NULL;
- }
-}
-EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
-
-/*-------------------------------------------------------------------------
- *
- * Communications Device Class, Ethernet Control model
- *
- * Takes two interfaces. The DATA interface is inactive till an altsetting
- * is selected. Configuration data includes class descriptors. There's
- * an optional status endpoint on the control interface.
- *
- * This should interop with whatever the 2.4 "CDCEther.c" driver
- * (by Brad Hards) talked with, with more functionality.
- *
- *-------------------------------------------------------------------------*/
-
-static void dumpspeed(struct usbnet *dev, __le32 *speeds)
-{
- netif_info(dev, timer, dev->net,
- "link speeds: %u kbps up, %u kbps down\n",
- __le32_to_cpu(speeds[0]) / 1000,
- __le32_to_cpu(speeds[1]) / 1000);
-}
-
-void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)
-{
- struct usb_cdc_notification *event;
-
- if (urb->actual_length < sizeof *event)
- return;
-
- /* SPEED_CHANGE can get split into two 8-byte packets */
- if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) {
- dumpspeed(dev, (__le32 *) urb->transfer_buffer);
- return;
- }
-
- event = urb->transfer_buffer;
- switch (event->bNotificationType) {
- case USB_CDC_NOTIFY_NETWORK_CONNECTION:
- netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
- event->wValue ? "on" : "off");
- if (event->wValue)
- netif_carrier_on(dev->net);
- else
- netif_carrier_off(dev->net);
- break;
- case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */
- netif_dbg(dev, timer, dev->net, "CDC: speed change (len %d)\n",
- urb->actual_length);
- if (urb->actual_length != (sizeof *event + 8))
- set_bit(EVENT_STS_SPLIT, &dev->flags);
- else
- dumpspeed(dev, (__le32 *) &event[1]);
- break;
- /* USB_CDC_NOTIFY_RESPONSE_AVAILABLE can happen too (e.g. RNDIS),
- * but there are no standard formats for the response data.
- */
- default:
- netdev_err(dev->net, "CDC: unexpected notification %02x!\n",
- event->bNotificationType);
- break;
- }
-}
-EXPORT_SYMBOL_GPL(usbnet_cdc_status);
-void check_set_mac(unsigned char *buf);
-int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- int status;
- struct cdc_state *info = (void *) &dev->data;
-
- BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data)
- < sizeof(struct cdc_state)));
-
- status = usbnet_generic_cdc_bind(dev, intf);
- if (status < 0)
- return status;
-
- status = usbnet_get_ethernet_addr(dev, info->ether->iMACAddress);
- check_set_mac(dev->net->dev_addr);
- if (status < 0) {
- usb_set_intfdata(info->data, NULL);
- usb_driver_release_interface(driver_of(intf), info->data);
- return status;
- }
-
- /* FIXME cdc-ether has some multicast code too, though it complains
- * in routine cases. info->ether describes the multicast support.
- * Implement that here, manipulating the cdc filter as needed.
- */
- return 0;
-}
-EXPORT_SYMBOL_GPL(usbnet_cdc_bind);
-
-static int cdc_manage_power(struct usbnet *dev, int on)
-{
- dev->intf->needs_remote_wakeup = on;
- return 0;
-}
-
-static const struct driver_info cdc_info = {
- .description = "CDC Ethernet Device",
- .flags = FLAG_ETHER | FLAG_POINTTOPOINT,
- // .check_connect = cdc_check_connect,
- .bind = usbnet_cdc_bind,
- .unbind = usbnet_cdc_unbind,
- .status = usbnet_cdc_status,
- .manage_power = cdc_manage_power,
-};
-
-static const struct driver_info wwan_info = {
- .description = "Mobile Broadband Network Device",
- .flags = FLAG_WWAN,
- .bind = usbnet_cdc_bind,
- .unbind = usbnet_cdc_unbind,
- .status = usbnet_cdc_status,
- .manage_power = cdc_manage_power,
-};
-
-/*-------------------------------------------------------------------------*/
-
-#define HUAWEI_VENDOR_ID 0x12D1
-#define NOVATEL_VENDOR_ID 0x1410
-
-static const struct usb_device_id products [] = {
-/*
- * BLACKLIST !!
- *
- * First blacklist any products that are egregiously nonconformant
- * with the CDC Ethernet specs. Minor braindamage we cope with; when
- * they're not even trying, needing a separate driver is only the first
- * of the differences to show up.
- */
-
-#define ZAURUS_MASTER_INTERFACE \
- .bInterfaceClass = USB_CLASS_COMM, \
- .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \
- .bInterfaceProtocol = USB_CDC_PROTO_NONE
-
-/* SA-1100 based Sharp Zaurus ("collie"), or compatible;
- * wire-incompatible with true CDC Ethernet implementations.
- * (And, it seems, needlessly so...)
- */
-{
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x8004,
- ZAURUS_MASTER_INTERFACE,
- .driver_info = 0,
-},
-
-/* PXA-25x based Sharp Zaurii. Note that it seems some of these
- * (later models especially) may have shipped only with firmware
- * advertising false "CDC MDLM" compatibility ... but we're not
- * clear which models did that, so for now let's assume the worst.
- */
-{
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x8005, /* A-300 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = 0,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x8006, /* B-500/SL-5600 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = 0,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x8007, /* C-700 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = 0,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x9031, /* C-750 C-760 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = 0,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x9032, /* SL-6000 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = 0,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- /* reported with some C860 units */
- .idProduct = 0x9050, /* C-860 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = 0,
-},
-
-/* Olympus has some models with a Zaurus-compatible option.
- * R-1000 uses a FreeScale i.MXL cpu (ARMv4T)
- */
-{
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x07B4,
- .idProduct = 0x0F02, /* R-1000 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = 0,
-},
-
-/* LG Electronics VL600 wants additional headers on every frame */
-{
- USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
- .driver_info = 0,
-},
-
-/* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */
-{
- USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = 0,
-},
-
-/*
- * WHITELIST!!!
- *
- * CDC Ether uses two interfaces, not necessarily consecutive.
- * We match the main interface, ignoring the optional device
- * class so we could handle devices that aren't exclusively
- * CDC ether.
- *
- * NOTE: this match must come AFTER entries blacklisting devices
- * because of bugs/quirks in a given product (like Zaurus, above).
- */
-{
- /* Novatel USB551L */
- /* This match must come *before* the generic CDC-ETHER match so that
- * we get FLAG_WWAN set on the device, since it's descriptors are
- * generic CDC-ETHER.
- */
- .match_flags = USB_DEVICE_ID_MATCH_VENDOR
- | USB_DEVICE_ID_MATCH_PRODUCT
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = NOVATEL_VENDOR_ID,
- .idProduct = 0xB001,
- .bInterfaceClass = USB_CLASS_COMM,
- .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
- .bInterfaceProtocol = USB_CDC_PROTO_NONE,
- .driver_info = (unsigned long)&wwan_info,
-}, {
- USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
- USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &cdc_info,
-}, {
- USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
- USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long)&wwan_info,
-
-}, {
- /* Various Huawei modems with a network port like the UMG1831 */
- .match_flags = USB_DEVICE_ID_MATCH_VENDOR
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = HUAWEI_VENDOR_ID,
- .bInterfaceClass = USB_CLASS_COMM,
- .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
- .bInterfaceProtocol = 255,
- .driver_info = (unsigned long)&wwan_info,
-},
- { }, // END
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-struct usb_driver cdc_driver = {
- .name = "cdc_ether",
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
- .reset_resume = usbnet_resume,
- .supports_autosuspend = 1,
-};
-EXPORT_SYMBOL_GPL(cdc_driver);
-
-module_usb_driver(cdc_driver);
-
-MODULE_AUTHOR("David Brownell");
-MODULE_DESCRIPTION("USB CDC Ethernet devices");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/cdc_ncm.c b/ANDROID_3.4.5/drivers/net/usb/cdc_ncm.c
deleted file mode 100644
index 7adc9f6b..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/cdc_ncm.c
+++ /dev/null
@@ -1,1231 +0,0 @@
-/*
- * cdc_ncm.c
- *
- * Copyright (C) ST-Ericsson 2010-2012
- * Contact: Alexey Orishko <alexey.orishko@stericsson.com>
- * Original author: Hans Petter Selasky <hans.petter.selasky@stericsson.com>
- *
- * USB Host Driver for Network Control Model (NCM)
- * http://www.usb.org/developers/devclass_docs/NCM10.zip
- *
- * The NCM encoding, decoding and initialization logic
- * derives from FreeBSD 8.x. if_cdce.c and if_cdcereg.h
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose this file to be licensed under the terms
- * of the GNU General Public License (GPL) Version 2 or the 2-clause
- * BSD license listed below:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/ctype.h>
-#include <linux/ethtool.h>
-#include <linux/workqueue.h>
-#include <linux/mii.h>
-#include <linux/crc32.h>
-#include <linux/usb.h>
-#include <linux/hrtimer.h>
-#include <linux/atomic.h>
-#include <linux/usb/usbnet.h>
-#include <linux/usb/cdc.h>
-
-#define DRIVER_VERSION "14-Mar-2012"
-
-/* CDC NCM subclass 3.2.1 */
-#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10
-
-/* Maximum NTB length */
-#define CDC_NCM_NTB_MAX_SIZE_TX 32768 /* bytes */
-#define CDC_NCM_NTB_MAX_SIZE_RX 32768 /* bytes */
-
-/* Minimum value for MaxDatagramSize, ch. 6.2.9 */
-#define CDC_NCM_MIN_DATAGRAM_SIZE 1514 /* bytes */
-
-#define CDC_NCM_MIN_TX_PKT 512 /* bytes */
-
-/* Default value for MaxDatagramSize */
-#define CDC_NCM_MAX_DATAGRAM_SIZE 8192 /* bytes */
-
-/*
- * Maximum amount of datagrams in NCM Datagram Pointer Table, not counting
- * the last NULL entry.
- */
-#define CDC_NCM_DPT_DATAGRAMS_MAX 40
-
-/* Restart the timer, if amount of datagrams is less than given value */
-#define CDC_NCM_RESTART_TIMER_DATAGRAM_CNT 3
-#define CDC_NCM_TIMER_PENDING_CNT 2
-#define CDC_NCM_TIMER_INTERVAL (400UL * NSEC_PER_USEC)
-
-/* The following macro defines the minimum header space */
-#define CDC_NCM_MIN_HDR_SIZE \
- (sizeof(struct usb_cdc_ncm_nth16) + sizeof(struct usb_cdc_ncm_ndp16) + \
- (CDC_NCM_DPT_DATAGRAMS_MAX + 1) * sizeof(struct usb_cdc_ncm_dpe16))
-
-struct cdc_ncm_data {
- struct usb_cdc_ncm_nth16 nth16;
- struct usb_cdc_ncm_ndp16 ndp16;
- struct usb_cdc_ncm_dpe16 dpe16[CDC_NCM_DPT_DATAGRAMS_MAX + 1];
-};
-
-struct cdc_ncm_ctx {
- struct cdc_ncm_data tx_ncm;
- struct usb_cdc_ncm_ntb_parameters ncm_parm;
- struct hrtimer tx_timer;
- struct tasklet_struct bh;
-
- const struct usb_cdc_ncm_desc *func_desc;
- const struct usb_cdc_header_desc *header_desc;
- const struct usb_cdc_union_desc *union_desc;
- const struct usb_cdc_ether_desc *ether_desc;
-
- struct net_device *netdev;
- struct usb_device *udev;
- struct usb_host_endpoint *in_ep;
- struct usb_host_endpoint *out_ep;
- struct usb_host_endpoint *status_ep;
- struct usb_interface *intf;
- struct usb_interface *control;
- struct usb_interface *data;
-
- struct sk_buff *tx_curr_skb;
- struct sk_buff *tx_rem_skb;
-
- spinlock_t mtx;
- atomic_t stop;
-
- u32 tx_timer_pending;
- u32 tx_curr_offset;
- u32 tx_curr_last_offset;
- u32 tx_curr_frame_num;
- u32 rx_speed;
- u32 tx_speed;
- u32 rx_max;
- u32 tx_max;
- u32 max_datagram_size;
- u16 tx_max_datagrams;
- u16 tx_remainder;
- u16 tx_modulus;
- u16 tx_ndp_modulus;
- u16 tx_seq;
- u16 rx_seq;
- u16 connected;
-};
-
-static void cdc_ncm_txpath_bh(unsigned long param);
-static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx);
-static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer);
-static const struct driver_info cdc_ncm_info;
-static struct usb_driver cdc_ncm_driver;
-static const struct ethtool_ops cdc_ncm_ethtool_ops;
-
-static const struct usb_device_id cdc_devs[] = {
- { USB_INTERFACE_INFO(USB_CLASS_COMM,
- USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long)&cdc_ncm_info,
- },
- {
- },
-};
-
-MODULE_DEVICE_TABLE(usb, cdc_devs);
-
-static void
-cdc_ncm_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
-{
- struct usbnet *dev = netdev_priv(net);
-
- strncpy(info->driver, dev->driver_name, sizeof(info->driver));
- strncpy(info->version, DRIVER_VERSION, sizeof(info->version));
- strncpy(info->fw_version, dev->driver_info->description,
- sizeof(info->fw_version));
- usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info));
-}
-
-static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
-{
- u32 val;
- u8 flags;
- u8 iface_no;
- int err;
- u16 ntb_fmt_supported;
-
- iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
-
- err = usb_control_msg(ctx->udev,
- usb_rcvctrlpipe(ctx->udev, 0),
- USB_CDC_GET_NTB_PARAMETERS,
- USB_TYPE_CLASS | USB_DIR_IN
- | USB_RECIP_INTERFACE,
- 0, iface_no, &ctx->ncm_parm,
- sizeof(ctx->ncm_parm), 10000);
- if (err < 0) {
- pr_debug("failed GET_NTB_PARAMETERS\n");
- return 1;
- }
-
- /* read correct set of parameters according to device mode */
- ctx->rx_max = le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize);
- ctx->tx_max = le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize);
- ctx->tx_remainder = le16_to_cpu(ctx->ncm_parm.wNdpOutPayloadRemainder);
- ctx->tx_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutDivisor);
- ctx->tx_ndp_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutAlignment);
- /* devices prior to NCM Errata shall set this field to zero */
- ctx->tx_max_datagrams = le16_to_cpu(ctx->ncm_parm.wNtbOutMaxDatagrams);
- ntb_fmt_supported = le16_to_cpu(ctx->ncm_parm.bmNtbFormatsSupported);
-
- if (ctx->func_desc != NULL)
- flags = ctx->func_desc->bmNetworkCapabilities;
- else
- flags = 0;
-
- pr_debug("dwNtbInMaxSize=%u dwNtbOutMaxSize=%u "
- "wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u "
- "wNdpOutAlignment=%u wNtbOutMaxDatagrams=%u flags=0x%x\n",
- ctx->rx_max, ctx->tx_max, ctx->tx_remainder, ctx->tx_modulus,
- ctx->tx_ndp_modulus, ctx->tx_max_datagrams, flags);
-
- /* max count of tx datagrams */
- if ((ctx->tx_max_datagrams == 0) ||
- (ctx->tx_max_datagrams > CDC_NCM_DPT_DATAGRAMS_MAX))
- ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX;
-
- /* verify maximum size of received NTB in bytes */
- if (ctx->rx_max < USB_CDC_NCM_NTB_MIN_IN_SIZE) {
- pr_debug("Using min receive length=%d\n",
- USB_CDC_NCM_NTB_MIN_IN_SIZE);
- ctx->rx_max = USB_CDC_NCM_NTB_MIN_IN_SIZE;
- }
-
- if (ctx->rx_max > CDC_NCM_NTB_MAX_SIZE_RX) {
- pr_debug("Using default maximum receive length=%d\n",
- CDC_NCM_NTB_MAX_SIZE_RX);
- ctx->rx_max = CDC_NCM_NTB_MAX_SIZE_RX;
- }
-
- /* inform device about NTB input size changes */
- if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) {
-
- if (flags & USB_CDC_NCM_NCAP_NTB_INPUT_SIZE) {
- struct usb_cdc_ncm_ndp_input_size *ndp_in_sz;
-
- ndp_in_sz = kzalloc(sizeof(*ndp_in_sz), GFP_KERNEL);
- if (!ndp_in_sz) {
- err = -ENOMEM;
- goto size_err;
- }
-
- err = usb_control_msg(ctx->udev,
- usb_sndctrlpipe(ctx->udev, 0),
- USB_CDC_SET_NTB_INPUT_SIZE,
- USB_TYPE_CLASS | USB_DIR_OUT
- | USB_RECIP_INTERFACE,
- 0, iface_no, ndp_in_sz, 8, 1000);
- kfree(ndp_in_sz);
- } else {
- __le32 *dwNtbInMaxSize;
- dwNtbInMaxSize = kzalloc(sizeof(*dwNtbInMaxSize),
- GFP_KERNEL);
- if (!dwNtbInMaxSize) {
- err = -ENOMEM;
- goto size_err;
- }
- *dwNtbInMaxSize = cpu_to_le32(ctx->rx_max);
-
- err = usb_control_msg(ctx->udev,
- usb_sndctrlpipe(ctx->udev, 0),
- USB_CDC_SET_NTB_INPUT_SIZE,
- USB_TYPE_CLASS | USB_DIR_OUT
- | USB_RECIP_INTERFACE,
- 0, iface_no, dwNtbInMaxSize, 4, 1000);
- kfree(dwNtbInMaxSize);
- }
-size_err:
- if (err < 0)
- pr_debug("Setting NTB Input Size failed\n");
- }
-
- /* verify maximum size of transmitted NTB in bytes */
- if ((ctx->tx_max <
- (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) ||
- (ctx->tx_max > CDC_NCM_NTB_MAX_SIZE_TX)) {
- pr_debug("Using default maximum transmit length=%d\n",
- CDC_NCM_NTB_MAX_SIZE_TX);
- ctx->tx_max = CDC_NCM_NTB_MAX_SIZE_TX;
- }
-
- /*
- * verify that the structure alignment is:
- * - power of two
- * - not greater than the maximum transmit length
- * - not less than four bytes
- */
- val = ctx->tx_ndp_modulus;
-
- if ((val < USB_CDC_NCM_NDP_ALIGN_MIN_SIZE) ||
- (val != ((-val) & val)) || (val >= ctx->tx_max)) {
- pr_debug("Using default alignment: 4 bytes\n");
- ctx->tx_ndp_modulus = USB_CDC_NCM_NDP_ALIGN_MIN_SIZE;
- }
-
- /*
- * verify that the payload alignment is:
- * - power of two
- * - not greater than the maximum transmit length
- * - not less than four bytes
- */
- val = ctx->tx_modulus;
-
- if ((val < USB_CDC_NCM_NDP_ALIGN_MIN_SIZE) ||
- (val != ((-val) & val)) || (val >= ctx->tx_max)) {
- pr_debug("Using default transmit modulus: 4 bytes\n");
- ctx->tx_modulus = USB_CDC_NCM_NDP_ALIGN_MIN_SIZE;
- }
-
- /* verify the payload remainder */
- if (ctx->tx_remainder >= ctx->tx_modulus) {
- pr_debug("Using default transmit remainder: 0 bytes\n");
- ctx->tx_remainder = 0;
- }
-
- /* adjust TX-remainder according to NCM specification. */
- ctx->tx_remainder = ((ctx->tx_remainder - ETH_HLEN) &
- (ctx->tx_modulus - 1));
-
- /* additional configuration */
-
- /* set CRC Mode */
- if (flags & USB_CDC_NCM_NCAP_CRC_MODE) {
- err = usb_control_msg(ctx->udev, usb_sndctrlpipe(ctx->udev, 0),
- USB_CDC_SET_CRC_MODE,
- USB_TYPE_CLASS | USB_DIR_OUT
- | USB_RECIP_INTERFACE,
- USB_CDC_NCM_CRC_NOT_APPENDED,
- iface_no, NULL, 0, 1000);
- if (err < 0)
- pr_debug("Setting CRC mode off failed\n");
- }
-
- /* set NTB format, if both formats are supported */
- if (ntb_fmt_supported & USB_CDC_NCM_NTH32_SIGN) {
- err = usb_control_msg(ctx->udev, usb_sndctrlpipe(ctx->udev, 0),
- USB_CDC_SET_NTB_FORMAT, USB_TYPE_CLASS
- | USB_DIR_OUT | USB_RECIP_INTERFACE,
- USB_CDC_NCM_NTB16_FORMAT,
- iface_no, NULL, 0, 1000);
- if (err < 0)
- pr_debug("Setting NTB format to 16-bit failed\n");
- }
-
- ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE;
-
- /* set Max Datagram Size (MTU) */
- if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) {
- __le16 *max_datagram_size;
- u16 eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
-
- max_datagram_size = kzalloc(sizeof(*max_datagram_size),
- GFP_KERNEL);
- if (!max_datagram_size) {
- err = -ENOMEM;
- goto max_dgram_err;
- }
-
- err = usb_control_msg(ctx->udev, usb_rcvctrlpipe(ctx->udev, 0),
- USB_CDC_GET_MAX_DATAGRAM_SIZE,
- USB_TYPE_CLASS | USB_DIR_IN
- | USB_RECIP_INTERFACE,
- 0, iface_no, max_datagram_size,
- 2, 1000);
- if (err < 0) {
- pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n",
- CDC_NCM_MIN_DATAGRAM_SIZE);
- } else {
- ctx->max_datagram_size =
- le16_to_cpu(*max_datagram_size);
- /* Check Eth descriptor value */
- if (ctx->max_datagram_size > eth_max_sz)
- ctx->max_datagram_size = eth_max_sz;
-
- if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE)
- ctx->max_datagram_size =
- CDC_NCM_MAX_DATAGRAM_SIZE;
-
- if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE)
- ctx->max_datagram_size =
- CDC_NCM_MIN_DATAGRAM_SIZE;
-
- /* if value changed, update device */
- if (ctx->max_datagram_size !=
- le16_to_cpu(*max_datagram_size)) {
- err = usb_control_msg(ctx->udev,
- usb_sndctrlpipe(ctx->udev, 0),
- USB_CDC_SET_MAX_DATAGRAM_SIZE,
- USB_TYPE_CLASS | USB_DIR_OUT
- | USB_RECIP_INTERFACE,
- 0,
- iface_no, max_datagram_size,
- 2, 1000);
- if (err < 0)
- pr_debug("SET_MAX_DGRAM_SIZE failed\n");
- }
- }
- kfree(max_datagram_size);
- }
-
-max_dgram_err:
- if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN))
- ctx->netdev->mtu = ctx->max_datagram_size - ETH_HLEN;
-
- return 0;
-}
-
-static void
-cdc_ncm_find_endpoints(struct cdc_ncm_ctx *ctx, struct usb_interface *intf)
-{
- struct usb_host_endpoint *e;
- u8 ep;
-
- for (ep = 0; ep < intf->cur_altsetting->desc.bNumEndpoints; ep++) {
-
- e = intf->cur_altsetting->endpoint + ep;
- switch (e->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
- case USB_ENDPOINT_XFER_INT:
- if (usb_endpoint_dir_in(&e->desc)) {
- if (ctx->status_ep == NULL)
- ctx->status_ep = e;
- }
- break;
-
- case USB_ENDPOINT_XFER_BULK:
- if (usb_endpoint_dir_in(&e->desc)) {
- if (ctx->in_ep == NULL)
- ctx->in_ep = e;
- } else {
- if (ctx->out_ep == NULL)
- ctx->out_ep = e;
- }
- break;
-
- default:
- break;
- }
- }
-}
-
-static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
-{
- if (ctx == NULL)
- return;
-
- if (ctx->tx_rem_skb != NULL) {
- dev_kfree_skb_any(ctx->tx_rem_skb);
- ctx->tx_rem_skb = NULL;
- }
-
- if (ctx->tx_curr_skb != NULL) {
- dev_kfree_skb_any(ctx->tx_curr_skb);
- ctx->tx_curr_skb = NULL;
- }
-
- kfree(ctx);
-}
-
-static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- struct cdc_ncm_ctx *ctx;
- struct usb_driver *driver;
- u8 *buf;
- int len;
- int temp;
- u8 iface_no;
-
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (ctx == NULL)
- return -ENODEV;
-
- hrtimer_init(&ctx->tx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- ctx->tx_timer.function = &cdc_ncm_tx_timer_cb;
- ctx->bh.data = (unsigned long)ctx;
- ctx->bh.func = cdc_ncm_txpath_bh;
- atomic_set(&ctx->stop, 0);
- spin_lock_init(&ctx->mtx);
- ctx->netdev = dev->net;
-
- /* store ctx pointer in device data field */
- dev->data[0] = (unsigned long)ctx;
-
- /* get some pointers */
- driver = driver_of(intf);
- buf = intf->cur_altsetting->extra;
- len = intf->cur_altsetting->extralen;
-
- ctx->udev = dev->udev;
- ctx->intf = intf;
-
- /* parse through descriptors associated with control interface */
- while ((len > 0) && (buf[0] > 2) && (buf[0] <= len)) {
-
- if (buf[1] != USB_DT_CS_INTERFACE)
- goto advance;
-
- switch (buf[2]) {
- case USB_CDC_UNION_TYPE:
- if (buf[0] < sizeof(*(ctx->union_desc)))
- break;
-
- ctx->union_desc =
- (const struct usb_cdc_union_desc *)buf;
-
- ctx->control = usb_ifnum_to_if(dev->udev,
- ctx->union_desc->bMasterInterface0);
- ctx->data = usb_ifnum_to_if(dev->udev,
- ctx->union_desc->bSlaveInterface0);
- break;
-
- case USB_CDC_ETHERNET_TYPE:
- if (buf[0] < sizeof(*(ctx->ether_desc)))
- break;
-
- ctx->ether_desc =
- (const struct usb_cdc_ether_desc *)buf;
- dev->hard_mtu =
- le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
-
- if (dev->hard_mtu < CDC_NCM_MIN_DATAGRAM_SIZE)
- dev->hard_mtu = CDC_NCM_MIN_DATAGRAM_SIZE;
- else if (dev->hard_mtu > CDC_NCM_MAX_DATAGRAM_SIZE)
- dev->hard_mtu = CDC_NCM_MAX_DATAGRAM_SIZE;
- break;
-
- case USB_CDC_NCM_TYPE:
- if (buf[0] < sizeof(*(ctx->func_desc)))
- break;
-
- ctx->func_desc = (const struct usb_cdc_ncm_desc *)buf;
- break;
-
- default:
- break;
- }
-advance:
- /* advance to next descriptor */
- temp = buf[0];
- buf += temp;
- len -= temp;
- }
-
- /* check if we got everything */
- if ((ctx->control == NULL) || (ctx->data == NULL) ||
- (ctx->ether_desc == NULL) || (ctx->control != intf))
- goto error;
-
- /* claim interfaces, if any */
- temp = usb_driver_claim_interface(driver, ctx->data, dev);
- if (temp)
- goto error;
-
- iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;
-
- /* reset data interface */
- temp = usb_set_interface(dev->udev, iface_no, 0);
- if (temp)
- goto error2;
-
- /* initialize data interface */
- if (cdc_ncm_setup(ctx))
- goto error2;
-
- /* configure data interface */
- temp = usb_set_interface(dev->udev, iface_no, 1);
- if (temp)
- goto error2;
-
- cdc_ncm_find_endpoints(ctx, ctx->data);
- cdc_ncm_find_endpoints(ctx, ctx->control);
-
- if ((ctx->in_ep == NULL) || (ctx->out_ep == NULL) ||
- (ctx->status_ep == NULL))
- goto error2;
-
- dev->net->ethtool_ops = &cdc_ncm_ethtool_ops;
-
- usb_set_intfdata(ctx->data, dev);
- usb_set_intfdata(ctx->control, dev);
- usb_set_intfdata(ctx->intf, dev);
-
- temp = usbnet_get_ethernet_addr(dev, ctx->ether_desc->iMACAddress);
- if (temp)
- goto error2;
-
- dev_info(&dev->udev->dev, "MAC-Address: %pM\n", dev->net->dev_addr);
-
- dev->in = usb_rcvbulkpipe(dev->udev,
- ctx->in_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
- dev->out = usb_sndbulkpipe(dev->udev,
- ctx->out_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
- dev->status = ctx->status_ep;
- dev->rx_urb_size = ctx->rx_max;
-
- /*
- * We should get an event when network connection is "connected" or
- * "disconnected". Set network connection in "disconnected" state
- * (carrier is OFF) during attach, so the IP network stack does not
- * start IPv6 negotiation and more.
- */
- netif_carrier_off(dev->net);
- ctx->tx_speed = ctx->rx_speed = 0;
- return 0;
-
-error2:
- usb_set_intfdata(ctx->control, NULL);
- usb_set_intfdata(ctx->data, NULL);
- usb_driver_release_interface(driver, ctx->data);
-error:
- cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]);
- dev->data[0] = 0;
- dev_info(&dev->udev->dev, "bind() failure\n");
- return -ENODEV;
-}
-
-static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
-{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
- struct usb_driver *driver = driver_of(intf);
-
- if (ctx == NULL)
- return; /* no setup */
-
- atomic_set(&ctx->stop, 1);
-
- if (hrtimer_active(&ctx->tx_timer))
- hrtimer_cancel(&ctx->tx_timer);
-
- tasklet_kill(&ctx->bh);
-
- /* disconnect master --> disconnect slave */
- if (intf == ctx->control && ctx->data) {
- usb_set_intfdata(ctx->data, NULL);
- usb_driver_release_interface(driver, ctx->data);
- ctx->data = NULL;
-
- } else if (intf == ctx->data && ctx->control) {
- usb_set_intfdata(ctx->control, NULL);
- usb_driver_release_interface(driver, ctx->control);
- ctx->control = NULL;
- }
-
- usb_set_intfdata(ctx->intf, NULL);
- cdc_ncm_free(ctx);
-}
-
-static void cdc_ncm_zero_fill(u8 *ptr, u32 first, u32 end, u32 max)
-{
- if (first >= max)
- return;
- if (first >= end)
- return;
- if (end > max)
- end = max;
- memset(ptr + first, 0, end - first);
-}
-
-static struct sk_buff *
-cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
-{
- struct sk_buff *skb_out;
- u32 rem;
- u32 offset;
- u32 last_offset;
- u16 n = 0, index;
- u8 ready2send = 0;
-
- /* if there is a remaining skb, it gets priority */
- if (skb != NULL)
- swap(skb, ctx->tx_rem_skb);
- else
- ready2send = 1;
-
- /*
- * +----------------+
- * | skb_out |
- * +----------------+
- * ^ offset
- * ^ last_offset
- */
-
- /* check if we are resuming an OUT skb */
- if (ctx->tx_curr_skb != NULL) {
- /* pop variables */
- skb_out = ctx->tx_curr_skb;
- offset = ctx->tx_curr_offset;
- last_offset = ctx->tx_curr_last_offset;
- n = ctx->tx_curr_frame_num;
-
- } else {
- /* reset variables */
- skb_out = alloc_skb((ctx->tx_max + 1), GFP_ATOMIC);
- if (skb_out == NULL) {
- if (skb != NULL) {
- dev_kfree_skb_any(skb);
- ctx->netdev->stats.tx_dropped++;
- }
- goto exit_no_skb;
- }
-
- /* make room for NTH and NDP */
- offset = ALIGN(sizeof(struct usb_cdc_ncm_nth16),
- ctx->tx_ndp_modulus) +
- sizeof(struct usb_cdc_ncm_ndp16) +
- (ctx->tx_max_datagrams + 1) *
- sizeof(struct usb_cdc_ncm_dpe16);
-
- /* store last valid offset before alignment */
- last_offset = offset;
- /* align first Datagram offset correctly */
- offset = ALIGN(offset, ctx->tx_modulus) + ctx->tx_remainder;
- /* zero buffer till the first IP datagram */
- cdc_ncm_zero_fill(skb_out->data, 0, offset, offset);
- n = 0;
- ctx->tx_curr_frame_num = 0;
- }
-
- for (; n < ctx->tx_max_datagrams; n++) {
- /* check if end of transmit buffer is reached */
- if (offset >= ctx->tx_max) {
- ready2send = 1;
- break;
- }
- /* compute maximum buffer size */
- rem = ctx->tx_max - offset;
-
- if (skb == NULL) {
- skb = ctx->tx_rem_skb;
- ctx->tx_rem_skb = NULL;
-
- /* check for end of skb */
- if (skb == NULL)
- break;
- }
-
- if (skb->len > rem) {
- if (n == 0) {
- /* won't fit, MTU problem? */
- dev_kfree_skb_any(skb);
- skb = NULL;
- ctx->netdev->stats.tx_dropped++;
- } else {
- /* no room for skb - store for later */
- if (ctx->tx_rem_skb != NULL) {
- dev_kfree_skb_any(ctx->tx_rem_skb);
- ctx->netdev->stats.tx_dropped++;
- }
- ctx->tx_rem_skb = skb;
- skb = NULL;
- ready2send = 1;
- }
- break;
- }
-
- memcpy(((u8 *)skb_out->data) + offset, skb->data, skb->len);
-
- ctx->tx_ncm.dpe16[n].wDatagramLength = cpu_to_le16(skb->len);
- ctx->tx_ncm.dpe16[n].wDatagramIndex = cpu_to_le16(offset);
-
- /* update offset */
- offset += skb->len;
-
- /* store last valid offset before alignment */
- last_offset = offset;
-
- /* align offset correctly */
- offset = ALIGN(offset, ctx->tx_modulus) + ctx->tx_remainder;
-
- /* zero padding */
- cdc_ncm_zero_fill(skb_out->data, last_offset, offset,
- ctx->tx_max);
- dev_kfree_skb_any(skb);
- skb = NULL;
- }
-
- /* free up any dangling skb */
- if (skb != NULL) {
- dev_kfree_skb_any(skb);
- skb = NULL;
- ctx->netdev->stats.tx_dropped++;
- }
-
- ctx->tx_curr_frame_num = n;
-
- if (n == 0) {
- /* wait for more frames */
- /* push variables */
- ctx->tx_curr_skb = skb_out;
- ctx->tx_curr_offset = offset;
- ctx->tx_curr_last_offset = last_offset;
- goto exit_no_skb;
-
- } else if ((n < ctx->tx_max_datagrams) && (ready2send == 0)) {
- /* wait for more frames */
- /* push variables */
- ctx->tx_curr_skb = skb_out;
- ctx->tx_curr_offset = offset;
- ctx->tx_curr_last_offset = last_offset;
- /* set the pending count */
- if (n < CDC_NCM_RESTART_TIMER_DATAGRAM_CNT)
- ctx->tx_timer_pending = CDC_NCM_TIMER_PENDING_CNT;
- goto exit_no_skb;
-
- } else {
- /* frame goes out */
- /* variables will be reset at next call */
- }
-
- /* check for overflow */
- if (last_offset > ctx->tx_max)
- last_offset = ctx->tx_max;
-
- /* revert offset */
- offset = last_offset;
-
- /*
- * If collected data size is less or equal CDC_NCM_MIN_TX_PKT bytes,
- * we send buffers as it is. If we get more data, it would be more
- * efficient for USB HS mobile device with DMA engine to receive a full
- * size NTB, than canceling DMA transfer and receiving a short packet.
- */
- if (offset > CDC_NCM_MIN_TX_PKT)
- offset = ctx->tx_max;
-
- /* final zero padding */
- cdc_ncm_zero_fill(skb_out->data, last_offset, offset, ctx->tx_max);
-
- /* store last offset */
- last_offset = offset;
-
- if (((last_offset < ctx->tx_max) && ((last_offset %
- le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) ||
- (((last_offset == ctx->tx_max) && ((ctx->tx_max %
- le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) &&
- (ctx->tx_max < le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize)))) {
- /* force short packet */
- *(((u8 *)skb_out->data) + last_offset) = 0;
- last_offset++;
- }
-
- /* zero the rest of the DPEs plus the last NULL entry */
- for (; n <= CDC_NCM_DPT_DATAGRAMS_MAX; n++) {
- ctx->tx_ncm.dpe16[n].wDatagramLength = 0;
- ctx->tx_ncm.dpe16[n].wDatagramIndex = 0;
- }
-
- /* fill out 16-bit NTB header */
- ctx->tx_ncm.nth16.dwSignature = cpu_to_le32(USB_CDC_NCM_NTH16_SIGN);
- ctx->tx_ncm.nth16.wHeaderLength =
- cpu_to_le16(sizeof(ctx->tx_ncm.nth16));
- ctx->tx_ncm.nth16.wSequence = cpu_to_le16(ctx->tx_seq);
- ctx->tx_ncm.nth16.wBlockLength = cpu_to_le16(last_offset);
- index = ALIGN(sizeof(struct usb_cdc_ncm_nth16), ctx->tx_ndp_modulus);
- ctx->tx_ncm.nth16.wNdpIndex = cpu_to_le16(index);
-
- memcpy(skb_out->data, &(ctx->tx_ncm.nth16), sizeof(ctx->tx_ncm.nth16));
- ctx->tx_seq++;
-
- /* fill out 16-bit NDP table */
- ctx->tx_ncm.ndp16.dwSignature =
- cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN);
- rem = sizeof(ctx->tx_ncm.ndp16) + ((ctx->tx_curr_frame_num + 1) *
- sizeof(struct usb_cdc_ncm_dpe16));
- ctx->tx_ncm.ndp16.wLength = cpu_to_le16(rem);
- ctx->tx_ncm.ndp16.wNextNdpIndex = 0; /* reserved */
-
- memcpy(((u8 *)skb_out->data) + index,
- &(ctx->tx_ncm.ndp16),
- sizeof(ctx->tx_ncm.ndp16));
-
- memcpy(((u8 *)skb_out->data) + index + sizeof(ctx->tx_ncm.ndp16),
- &(ctx->tx_ncm.dpe16),
- (ctx->tx_curr_frame_num + 1) *
- sizeof(struct usb_cdc_ncm_dpe16));
-
- /* set frame length */
- skb_put(skb_out, last_offset);
-
- /* return skb */
- ctx->tx_curr_skb = NULL;
- ctx->netdev->stats.tx_packets += ctx->tx_curr_frame_num;
- return skb_out;
-
-exit_no_skb:
- /* Start timer, if there is a remaining skb */
- if (ctx->tx_curr_skb != NULL)
- cdc_ncm_tx_timeout_start(ctx);
- return NULL;
-}
-
-static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx)
-{
- /* start timer, if not already started */
- if (!(hrtimer_active(&ctx->tx_timer) || atomic_read(&ctx->stop)))
- hrtimer_start(&ctx->tx_timer,
- ktime_set(0, CDC_NCM_TIMER_INTERVAL),
- HRTIMER_MODE_REL);
-}
-
-static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *timer)
-{
- struct cdc_ncm_ctx *ctx =
- container_of(timer, struct cdc_ncm_ctx, tx_timer);
-
- if (!atomic_read(&ctx->stop))
- tasklet_schedule(&ctx->bh);
- return HRTIMER_NORESTART;
-}
-
-static void cdc_ncm_txpath_bh(unsigned long param)
-{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)param;
-
- spin_lock_bh(&ctx->mtx);
- if (ctx->tx_timer_pending != 0) {
- ctx->tx_timer_pending--;
- cdc_ncm_tx_timeout_start(ctx);
- spin_unlock_bh(&ctx->mtx);
- } else if (ctx->netdev != NULL) {
- spin_unlock_bh(&ctx->mtx);
- netif_tx_lock_bh(ctx->netdev);
- usbnet_start_xmit(NULL, ctx->netdev);
- netif_tx_unlock_bh(ctx->netdev);
- }
-}
-
-static struct sk_buff *
-cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
-{
- struct sk_buff *skb_out;
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
-
- /*
- * The Ethernet API we are using does not support transmitting
- * multiple Ethernet frames in a single call. This driver will
- * accumulate multiple Ethernet frames and send out a larger
- * USB frame when the USB buffer is full or when a single jiffies
- * timeout happens.
- */
- if (ctx == NULL)
- goto error;
-
- spin_lock_bh(&ctx->mtx);
- skb_out = cdc_ncm_fill_tx_frame(ctx, skb);
- spin_unlock_bh(&ctx->mtx);
- return skb_out;
-
-error:
- if (skb != NULL)
- dev_kfree_skb_any(skb);
-
- return NULL;
-}
-
-static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
-{
- struct sk_buff *skb;
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
- int len;
- int nframes;
- int x;
- int offset;
- struct usb_cdc_ncm_nth16 *nth16;
- struct usb_cdc_ncm_ndp16 *ndp16;
- struct usb_cdc_ncm_dpe16 *dpe16;
-
- if (ctx == NULL)
- goto error;
-
- if (skb_in->len < (sizeof(struct usb_cdc_ncm_nth16) +
- sizeof(struct usb_cdc_ncm_ndp16))) {
- pr_debug("frame too short\n");
- goto error;
- }
-
- nth16 = (struct usb_cdc_ncm_nth16 *)skb_in->data;
-
- if (le32_to_cpu(nth16->dwSignature) != USB_CDC_NCM_NTH16_SIGN) {
- pr_debug("invalid NTH16 signature <%u>\n",
- le32_to_cpu(nth16->dwSignature));
- goto error;
- }
-
- len = le16_to_cpu(nth16->wBlockLength);
- if (len > ctx->rx_max) {
- pr_debug("unsupported NTB block length %u/%u\n", len,
- ctx->rx_max);
- goto error;
- }
-
- if ((ctx->rx_seq + 1) != le16_to_cpu(nth16->wSequence) &&
- (ctx->rx_seq || le16_to_cpu(nth16->wSequence)) &&
- !((ctx->rx_seq == 0xffff) && !le16_to_cpu(nth16->wSequence))) {
- pr_debug("sequence number glitch prev=%d curr=%d\n",
- ctx->rx_seq, le16_to_cpu(nth16->wSequence));
- }
- ctx->rx_seq = le16_to_cpu(nth16->wSequence);
-
- len = le16_to_cpu(nth16->wNdpIndex);
- if ((len + sizeof(struct usb_cdc_ncm_ndp16)) > skb_in->len) {
- pr_debug("invalid DPT16 index <%u>\n",
- le16_to_cpu(nth16->wNdpIndex));
- goto error;
- }
-
- ndp16 = (struct usb_cdc_ncm_ndp16 *)(((u8 *)skb_in->data) + len);
-
- if (le32_to_cpu(ndp16->dwSignature) != USB_CDC_NCM_NDP16_NOCRC_SIGN) {
- pr_debug("invalid DPT16 signature <%u>\n",
- le32_to_cpu(ndp16->dwSignature));
- goto error;
- }
-
- if (le16_to_cpu(ndp16->wLength) < USB_CDC_NCM_NDP16_LENGTH_MIN) {
- pr_debug("invalid DPT16 length <%u>\n",
- le32_to_cpu(ndp16->dwSignature));
- goto error;
- }
-
- nframes = ((le16_to_cpu(ndp16->wLength) -
- sizeof(struct usb_cdc_ncm_ndp16)) /
- sizeof(struct usb_cdc_ncm_dpe16));
- nframes--; /* we process NDP entries except for the last one */
-
- len += sizeof(struct usb_cdc_ncm_ndp16);
-
- if ((len + nframes * (sizeof(struct usb_cdc_ncm_dpe16))) >
- skb_in->len) {
- pr_debug("Invalid nframes = %d\n", nframes);
- goto error;
- }
-
- dpe16 = (struct usb_cdc_ncm_dpe16 *)(((u8 *)skb_in->data) + len);
-
- for (x = 0; x < nframes; x++, dpe16++) {
- offset = le16_to_cpu(dpe16->wDatagramIndex);
- len = le16_to_cpu(dpe16->wDatagramLength);
-
- /*
- * CDC NCM ch. 3.7
- * All entries after first NULL entry are to be ignored
- */
- if ((offset == 0) || (len == 0)) {
- if (!x)
- goto error; /* empty NTB */
- break;
- }
-
- /* sanity checking */
- if (((offset + len) > skb_in->len) ||
- (len > ctx->rx_max) || (len < ETH_HLEN)) {
- pr_debug("invalid frame detected (ignored)"
- "offset[%u]=%u, length=%u, skb=%p\n",
- x, offset, len, skb_in);
- if (!x)
- goto error;
- break;
-
- } else {
- skb = skb_clone(skb_in, GFP_ATOMIC);
- if (!skb)
- goto error;
- skb->len = len;
- skb->data = ((u8 *)skb_in->data) + offset;
- skb_set_tail_pointer(skb, len);
- usbnet_skb_return(dev, skb);
- }
- }
- return 1;
-error:
- return 0;
-}
-
-static void
-cdc_ncm_speed_change(struct cdc_ncm_ctx *ctx,
- struct usb_cdc_speed_change *data)
-{
- uint32_t rx_speed = le32_to_cpu(data->DLBitRRate);
- uint32_t tx_speed = le32_to_cpu(data->ULBitRate);
-
- /*
- * Currently the USB-NET API does not support reporting the actual
- * device speed. Do print it instead.
- */
- if ((tx_speed != ctx->tx_speed) || (rx_speed != ctx->rx_speed)) {
- ctx->tx_speed = tx_speed;
- ctx->rx_speed = rx_speed;
-
- if ((tx_speed > 1000000) && (rx_speed > 1000000)) {
- printk(KERN_INFO KBUILD_MODNAME
- ": %s: %u mbit/s downlink "
- "%u mbit/s uplink\n",
- ctx->netdev->name,
- (unsigned int)(rx_speed / 1000000U),
- (unsigned int)(tx_speed / 1000000U));
- } else {
- printk(KERN_INFO KBUILD_MODNAME
- ": %s: %u kbit/s downlink "
- "%u kbit/s uplink\n",
- ctx->netdev->name,
- (unsigned int)(rx_speed / 1000U),
- (unsigned int)(tx_speed / 1000U));
- }
- }
-}
-
-static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
-{
- struct cdc_ncm_ctx *ctx;
- struct usb_cdc_notification *event;
-
- ctx = (struct cdc_ncm_ctx *)dev->data[0];
-
- if (urb->actual_length < sizeof(*event))
- return;
-
- /* test for split data in 8-byte chunks */
- if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) {
- cdc_ncm_speed_change(ctx,
- (struct usb_cdc_speed_change *)urb->transfer_buffer);
- return;
- }
-
- event = urb->transfer_buffer;
-
- switch (event->bNotificationType) {
- case USB_CDC_NOTIFY_NETWORK_CONNECTION:
- /*
- * According to the CDC NCM specification ch.7.1
- * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be
- * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE.
- */
- ctx->connected = event->wValue;
-
- printk(KERN_INFO KBUILD_MODNAME ": %s: network connection:"
- " %sconnected\n",
- ctx->netdev->name, ctx->connected ? "" : "dis");
-
- if (ctx->connected)
- netif_carrier_on(dev->net);
- else {
- netif_carrier_off(dev->net);
- ctx->tx_speed = ctx->rx_speed = 0;
- }
- break;
-
- case USB_CDC_NOTIFY_SPEED_CHANGE:
- if (urb->actual_length < (sizeof(*event) +
- sizeof(struct usb_cdc_speed_change)))
- set_bit(EVENT_STS_SPLIT, &dev->flags);
- else
- cdc_ncm_speed_change(ctx,
- (struct usb_cdc_speed_change *) &event[1]);
- break;
-
- default:
- dev_err(&dev->udev->dev, "NCM: unexpected "
- "notification 0x%02x!\n", event->bNotificationType);
- break;
- }
-}
-
-static int cdc_ncm_check_connect(struct usbnet *dev)
-{
- struct cdc_ncm_ctx *ctx;
-
- ctx = (struct cdc_ncm_ctx *)dev->data[0];
- if (ctx == NULL)
- return 1; /* disconnected */
-
- return !ctx->connected;
-}
-
-static int
-cdc_ncm_probe(struct usb_interface *udev, const struct usb_device_id *prod)
-{
- return usbnet_probe(udev, prod);
-}
-
-static void cdc_ncm_disconnect(struct usb_interface *intf)
-{
- struct usbnet *dev = usb_get_intfdata(intf);
-
- if (dev == NULL)
- return; /* already disconnected */
-
- usbnet_disconnect(intf);
-}
-
-static int cdc_ncm_manage_power(struct usbnet *dev, int status)
-{
- dev->intf->needs_remote_wakeup = status;
- return 0;
-}
-
-static const struct driver_info cdc_ncm_info = {
- .description = "CDC NCM",
- .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET,
- .bind = cdc_ncm_bind,
- .unbind = cdc_ncm_unbind,
- .check_connect = cdc_ncm_check_connect,
- .manage_power = cdc_ncm_manage_power,
- .status = cdc_ncm_status,
- .rx_fixup = cdc_ncm_rx_fixup,
- .tx_fixup = cdc_ncm_tx_fixup,
-};
-
-static struct usb_driver cdc_ncm_driver = {
- .name = "cdc_ncm",
- .id_table = cdc_devs,
- .probe = cdc_ncm_probe,
- .disconnect = cdc_ncm_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
- .reset_resume = usbnet_resume,
- .supports_autosuspend = 1,
-};
-
-static const struct ethtool_ops cdc_ncm_ethtool_ops = {
- .get_drvinfo = cdc_ncm_get_drvinfo,
- .get_link = usbnet_get_link,
- .get_msglevel = usbnet_get_msglevel,
- .set_msglevel = usbnet_set_msglevel,
- .get_settings = usbnet_get_settings,
- .set_settings = usbnet_set_settings,
- .nway_reset = usbnet_nway_reset,
-};
-
-module_usb_driver(cdc_ncm_driver);
-
-MODULE_AUTHOR("Hans Petter Selasky");
-MODULE_DESCRIPTION("USB CDC NCM host driver");
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/cdc_subset.c b/ANDROID_3.4.5/drivers/net/usb/cdc_subset.c
deleted file mode 100644
index b403d934..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/cdc_subset.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Simple "CDC Subset" USB Networking Links
- * Copyright (C) 2000-2005 by David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/kmod.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/workqueue.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/usb/usbnet.h>
-
-
-/*
- * This supports simple USB network links that don't require any special
- * framing or hardware control operations. The protocol used here is a
- * strict subset of CDC Ethernet, with three basic differences reflecting
- * the goal that almost any hardware should run it:
- *
- * - Minimal runtime control: one interface, no altsettings, and
- * no vendor or class specific control requests. If a device is
- * configured, it is allowed to exchange packets with the host.
- * Fancier models would mean not working on some hardware.
- *
- * - Minimal manufacturing control: no IEEE "Organizationally
- * Unique ID" required, or an EEPROMs to store one. Each host uses
- * one random "locally assigned" Ethernet address instead, which can
- * of course be overridden using standard tools like "ifconfig".
- * (With 2^46 such addresses, same-net collisions are quite rare.)
- *
- * - There is no additional framing data for USB. Packets are written
- * exactly as in CDC Ethernet, starting with an Ethernet header and
- * terminated by a short packet. However, the host will never send a
- * zero length packet; some systems can't handle those robustly.
- *
- * Anything that can transmit and receive USB bulk packets can implement
- * this protocol. That includes both smart peripherals and quite a lot
- * of "host-to-host" USB cables (which embed two devices back-to-back).
- *
- * Note that although Linux may use many of those host-to-host links
- * with this "cdc_subset" framing, that doesn't mean there may not be a
- * better approach. Handling the "other end unplugs/replugs" scenario
- * well tends to require chip-specific vendor requests. Also, Windows
- * peers at the other end of host-to-host cables may expect their own
- * framing to be used rather than this "cdc_subset" model.
- */
-
-#if defined(CONFIG_USB_EPSON2888) || defined(CONFIG_USB_ARMLINUX)
-/* PDA style devices are always connected if present */
-static int always_connected (struct usbnet *dev)
-{
- return 0;
-}
-#endif
-
-#ifdef CONFIG_USB_ALI_M5632
-#define HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * ALi M5632 driver ... does high speed
- *
- * NOTE that the MS-Windows drivers for this chip use some funky and
- * (naturally) undocumented 7-byte prefix to each packet, so this is a
- * case where we don't currently interoperate. Also, once you unplug
- * one end of the cable, you need to replug the other end too ... since
- * chip docs are unavailable, there's no way to reset the relevant state
- * short of a power cycle.
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info ali_m5632_info = {
- .description = "ALi M5632",
- .flags = FLAG_POINTTOPOINT,
-};
-
-#endif
-
-
-#ifdef CONFIG_USB_AN2720
-#define HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * AnchorChips 2720 driver ... http://www.cypress.com
- *
- * This doesn't seem to have a way to detect whether the peer is
- * connected, or need any reset handshaking. It's got pretty big
- * internal buffers (handles most of a frame's worth of data).
- * Chip data sheets don't describe any vendor control messages.
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info an2720_info = {
- .description = "AnchorChips/Cypress 2720",
- .flags = FLAG_POINTTOPOINT,
- // no reset available!
- // no check_connect available!
-
- .in = 2, .out = 2, // direction distinguishes these
-};
-
-#endif /* CONFIG_USB_AN2720 */
-
-
-#ifdef CONFIG_USB_BELKIN
-#define HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * Belkin F5U104 ... two NetChip 2280 devices + Atmel AVR microcontroller
- *
- * ... also two eTEK designs, including one sold as "Advance USBNET"
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info belkin_info = {
- .description = "Belkin, eTEK, or compatible",
- .flags = FLAG_POINTTOPOINT,
-};
-
-#endif /* CONFIG_USB_BELKIN */
-
-
-
-#ifdef CONFIG_USB_EPSON2888
-#define HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * EPSON USB clients
- *
- * This is the same idea as Linux PDAs (below) except the firmware in the
- * device might not be Tux-powered. Epson provides reference firmware that
- * implements this interface. Product developers can reuse or modify that
- * code, such as by using their own product and vendor codes.
- *
- * Support was from Juro Bystricky <bystricky.juro@erd.epson.com>
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info epson2888_info = {
- .description = "Epson USB Device",
- .check_connect = always_connected,
- .flags = FLAG_POINTTOPOINT,
-
- .in = 4, .out = 3,
-};
-
-#endif /* CONFIG_USB_EPSON2888 */
-
-
-/*-------------------------------------------------------------------------
- *
- * info from Jonathan McDowell <noodles@earth.li>
- *
- *-------------------------------------------------------------------------*/
-#ifdef CONFIG_USB_KC2190
-#define HAVE_HARDWARE
-static const struct driver_info kc2190_info = {
- .description = "KC Technology KC-190",
- .flags = FLAG_POINTTOPOINT,
-};
-#endif /* CONFIG_USB_KC2190 */
-
-
-#ifdef CONFIG_USB_ARMLINUX
-#define HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * Intel's SA-1100 chip integrates basic USB support, and is used
- * in PDAs like some iPaqs, the Yopy, some Zaurus models, and more.
- * When they run Linux, arch/arm/mach-sa1100/usb-eth.c may be used to
- * network using minimal USB framing data.
- *
- * This describes the driver currently in standard ARM Linux kernels.
- * The Zaurus uses a different driver (see later).
- *
- * PXA25x and PXA210 use XScale cores (ARM v5TE) with better USB support
- * and different USB endpoint numbering than the SA1100 devices. The
- * mach-pxa/usb-eth.c driver re-uses the device ids from mach-sa1100
- * so we rely on the endpoint descriptors.
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info linuxdev_info = {
- .description = "Linux Device",
- .check_connect = always_connected,
- .flags = FLAG_POINTTOPOINT,
-};
-
-static const struct driver_info yopy_info = {
- .description = "Yopy",
- .check_connect = always_connected,
- .flags = FLAG_POINTTOPOINT,
-};
-
-static const struct driver_info blob_info = {
- .description = "Boot Loader OBject",
- .check_connect = always_connected,
- .flags = FLAG_POINTTOPOINT,
-};
-
-#endif /* CONFIG_USB_ARMLINUX */
-
-
-/*-------------------------------------------------------------------------*/
-
-#ifndef HAVE_HARDWARE
-#warning You need to configure some hardware for this driver
-#endif
-
-/*
- * chip vendor names won't normally be on the cables, and
- * may not be on the device.
- */
-
-static const struct usb_device_id products [] = {
-
-#ifdef CONFIG_USB_ALI_M5632
-{
- USB_DEVICE (0x0402, 0x5632), // ALi defaults
- .driver_info = (unsigned long) &ali_m5632_info,
-},
-{
- USB_DEVICE (0x182d,0x207c), // SiteCom CN-124
- .driver_info = (unsigned long) &ali_m5632_info,
-},
-#endif
-
-#ifdef CONFIG_USB_AN2720
-{
- USB_DEVICE (0x0547, 0x2720), // AnchorChips defaults
- .driver_info = (unsigned long) &an2720_info,
-}, {
- USB_DEVICE (0x0547, 0x2727), // Xircom PGUNET
- .driver_info = (unsigned long) &an2720_info,
-},
-#endif
-
-#ifdef CONFIG_USB_BELKIN
-{
- USB_DEVICE (0x050d, 0x0004), // Belkin
- .driver_info = (unsigned long) &belkin_info,
-}, {
- USB_DEVICE (0x056c, 0x8100), // eTEK
- .driver_info = (unsigned long) &belkin_info,
-}, {
- USB_DEVICE (0x0525, 0x9901), // Advance USBNET (eTEK)
- .driver_info = (unsigned long) &belkin_info,
-},
-#endif
-
-#ifdef CONFIG_USB_EPSON2888
-{
- USB_DEVICE (0x0525, 0x2888), // EPSON USB client
- .driver_info = (unsigned long) &epson2888_info,
-},
-#endif
-
-#ifdef CONFIG_USB_KC2190
-{
- USB_DEVICE (0x050f, 0x0190), // KC-190
- .driver_info = (unsigned long) &kc2190_info,
-},
-#endif
-
-#ifdef CONFIG_USB_ARMLINUX
-/*
- * SA-1100 using standard ARM Linux kernels, or compatible.
- * Often used when talking to Linux PDAs (iPaq, Yopy, etc).
- * The sa-1100 "usb-eth" driver handles the basic framing.
- *
- * PXA25x or PXA210 ... these use a "usb-eth" driver much like
- * the sa1100 one, but hardware uses different endpoint numbers.
- *
- * Or the Linux "Ethernet" gadget on hardware that can't talk
- * CDC Ethernet (e.g., no altsettings), in either of two modes:
- * - acting just like the old "usb-eth" firmware, though
- * the implementation is different
- * - supporting RNDIS as the first/default configuration for
- * MS-Windows interop; Linux needs to use the other config
- */
-{
- // 1183 = 0x049F, both used as hex values?
- // Compaq "Itsy" vendor/product id
- USB_DEVICE (0x049F, 0x505A), // usb-eth, or compatible
- .driver_info = (unsigned long) &linuxdev_info,
-}, {
- USB_DEVICE (0x0E7E, 0x1001), // G.Mate "Yopy"
- .driver_info = (unsigned long) &yopy_info,
-}, {
- USB_DEVICE (0x8086, 0x07d3), // "blob" bootloader
- .driver_info = (unsigned long) &blob_info,
-}, {
- USB_DEVICE (0x1286, 0x8001), // "blob" bootloader
- .driver_info = (unsigned long) &blob_info,
-}, {
- // Linux Ethernet/RNDIS gadget, mostly on PXA, second config
- // e.g. Gumstix, current OpenZaurus, ... or anything else
- // that just enables this gadget option.
- USB_DEVICE (0x0525, 0xa4a2),
- .driver_info = (unsigned long) &linuxdev_info,
-},
-#endif
-
- { }, // END
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-/*-------------------------------------------------------------------------*/
-
-static struct usb_driver cdc_subset_driver = {
- .name = "cdc_subset",
- .probe = usbnet_probe,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
- .disconnect = usbnet_disconnect,
- .id_table = products,
-};
-
-module_usb_driver(cdc_subset_driver);
-
-MODULE_AUTHOR("David Brownell");
-MODULE_DESCRIPTION("Simple 'CDC Subset' USB networking links");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/ch9x00.c b/ANDROID_3.4.5/drivers/net/usb/ch9x00.c
deleted file mode 100755
index 11ac3d50..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/ch9x00.c
+++ /dev/null
@@ -1,852 +0,0 @@
-/*
- * USB 10M/100M ethernet adapter
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whther express or implied
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/stddef.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/crc32.h>
-#include <linux/usb/usbnet.h>
-#include <linux/slab.h>
-
-
-#define CH9x00_VID 0x1A86
-#define CH9x00_PID_8339 0x8339
-#define CH9x00_PID_E091 0xE091
-#define CH9x00_PID_E092 0xE092
-
-#define DRIVER_VERSION "29-May-2013"
-
-#define DEBUG_PRT //for debug
-#undef DEBUG_PRT
-
-#ifdef DEBUG_PRT
-#define dbg_prt(format, arg...) printk(KERN_DEBUG format "\n", ## arg)
-#else
-#define dbg_prt(format, arg...) do {} while (0)
-#endif
-
-/**** Reg and CMD definition for CH9x00_PID_E091 and CH9x00_PID_8339****/
-#define DEVICE_SPEED_10M 0x80
-#define DEVICE_MEDIA_CONNECTED 0x40
-#define DEVICE_DUPLEX_FULL 0x20
-#define DEVICE_PHY 0x10
-
-#define REQ_RD_REG (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE)
-#define REQ_WR_REG (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE)
-#define CTRL_TIMEOUT_MS 1000
-
-#define MCAST_MAX 0x40
-#define TX_OVERHEAD 0x04
-#define RX_OVERHEAD 0x04
-
-#define GET_MAC_ADDRESS 0x00
-#define SET_HASH_TABLE 0x04
-#define SET_PACKAGE_FILTER 0x05
- #define RECEIVE_ALL 0x08
- #define MULTIPKT_EN 0x04
- #define BROADPKT_EN 0x02
- #define HASH_MULTI_EN 0x01
- #define CTRL_CLOSE 0x00
- #define CTRL_OPEN 0x01
-#define SET_SPEED_DUPLEX 0x06
- #define HALF_DUPLEX 0x00
- #define FULL_DUPLEX 0x01
- #define SPEED_10M 0x00
- #define SPEED_100M 0x02
- #define MT 0x00
- #define AT 0x04
-#define SET_MAC_ADDRESS 0x07
-#define SET_MAC_WAKEUP_FRAME 0x08
-#define SET_WAKEUP_ENABLE 0x09
- #define LINKCHG0_EN 0x01
- #define LINKCHG1_EN 0x02
- #define MAGICPKT_EN 0x04
- #define WAKEUP1_EN 0x08
- #define WAKEUP2_EN 0x10
- #define WAKEUP3_EN 0x20
- #define WAKEUP4_EN 0x40
-#define SET_FULL_DUPLEX_FLOW_CONTROL 0x0A
-#define SET_HALF_DUPLEX_FLOW_CONTROL 0x0B
-
-#define TEST_GET_MAC_ADDRESS
-#define TEST_SET_MAC_ADDRESS
-//#define TEST_SET_HASH
-//#define TEST_SET_PACKAGE_FILTER
-#define TEST_SET_SPEED_DUPLEX
-//#define TEST_SET_WAKEUP_ENABLE
- #if defined(TEST_SET_WAKEUP_ENABLE)
- #define WKE1_EN
- #define WKE2_EN
- #define WKE3_EN
- #define WKE4_EN
- #define MAGIC_EN
- #define LIKCHG1_EN
- #define LIKCHG0_EN
- #endif
-
-
-/**** Reg and CMD definition for CH9x00_PID_E092 ****/
-// === constant define
-#define RX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4)
-#define TX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4)
-
-#define MIN_PACKET sizeof(struct ethhdr)
-#define MAX_PACKET 32768
-
-#define TX_TIMEOUT_JIFFIES (5 * HZ)
-#define THROTTLE_JIFFIES (HZ / 8)
-#define UNLINK_TIMEOUT_MS 3
-
-// for vendor-specific control operations
-#define CONTROL_TIMEOUT_MS 1000
-
-// request
-#define REQUEST_READ 0x0E
-#define REQUEST_WRITE 0x0F
-
-#define REQUEST_TYPE_READ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER)
-#define REQUEST_TYPE_WRITE (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER)
-
-// address space
-// addr 00---63 : mii addr
-// addr 64---128 : mac addr
-// note : read/write must be in word (16 bit)
-
-#define MAC_REG_CTRL 64
-#define MAC_REG_STATUS 66
-#define MAC_REG_INTERRUPT_MASK 68
-#define MAC_REG_PHY_COMMAND 70
-#define MAC_REG_PHY_DATA 72
-#define MAC_REG_STATION_L 74
-#define MAC_REG_STATION_M 76
-#define MAC_REG_STATION_H 78
-#define MAC_REG_HASH_L 80
-#define MAC_REG_HASH_M1 82
-#define MAC_REG_HASH_M2 84
-#define MAC_REG_HASH_H 86
-#define MAC_REG_THRESHOLD 88
-#define MAC_REG_FIFO_DEPTH 90
-#define MAC_REG_PAUSE 92
-#define MAC_REG_FLOW_CONTROL 94
-
-// BIT
-// control register bit15 and bit13 reserve
-#define LOOPBACK (0x01 << 14)
-#define BASE100X (0x01 << 12)
-#define MBPS_10 (0x01 << 11)
-#define DUPLEX_MODE (0x01 << 10)
-#define PAUSE_FRAME (0x01 << 9)
-#define PROMISCUOUS (0x01 << 8)
-#define MULTICAST (0x01 << 7)
-#define BROADCAST (0x01 << 6)
-#define HASH (0x01 << 5)
-#define APPEND_PAD (0x01 << 4)
-#define APPEND_CRC (0x01 << 3)
-#define TRANSMITTER_ACTION (0x01 << 2)
-#define RECEIVER_ACTION (0x01 << 1)
-#define DMA_ACTION (0x01 << 0)
-
-// status register bit15-bit7 reserve
-#define ALIGNMENT (0x01 << 6)
-#define FIFO_OVER_RUN (0x01 << 5)
-#define FIFO_UNDER_RUN (0x01 << 4)
-#define RX_ERROR (0x01 << 3)
-#define RX_COMPLETE (0x01 << 2)
-#define TX_ERROR (0x01 << 1)
-#define TX_COMPLETE (0x01 << 0)
-
-// fifo depth register bit14 and bit6 reserve
-#define ETH_TXBD (0x01 << 15)
-#define ETN_TX_FIFO_DEPTH // bit13:8
-#define ETH_RXBD (0x01 << 7)// bit
-#define ETH_RX_FIFO_DEPTH // bit5:0
-
-
-// **************************************************
-int speed_status;
-int link_status;
-int duplex_status;
-int phy_status;
-
-
-static void ch9x00_async_cmd_callback( struct urb *urb )
-{
- struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
-
- if( urb->status < 0 )
- printk( KERN_DEBUG "%s() failed with %d\n", __FUNCTION__, urb->status);
-
- kfree(req);
- usb_free_urb(urb);
-}
-
-
-static void ch9x00_set_reg_async(
- struct usbnet *dev,
- unsigned char request,
- unsigned char requesttype,
- unsigned short value,
- unsigned short index,
- unsigned short size,
- void *data )
-{
- struct usb_ctrlrequest *req;
- int ret;
- struct urb *urb;
-
- urb = usb_alloc_urb( 0, GFP_ATOMIC);
- if(!urb) {
- dev_dbg( &dev->udev->dev,
- "Error allocation URB in write_cmd_async!\n");
- return;
- }
-
- req = kmalloc( sizeof *req, GFP_ATOMIC);
- if(!req) {
- dev_err( &dev->udev->dev,
- "Failed to allocate memory for control request\n");
- goto out;
- }
-
- req->bRequestType = requesttype;
- req->bRequest = request;
- req->wValue = cpu_to_le16(value);
- req->wIndex = cpu_to_le16(index);
- req->wLength = cpu_to_le16(size);
-
- usb_fill_control_urb( urb, dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- (void *)req, data, size, ch9x00_async_cmd_callback,req);
-
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if( ret < 0 ) {
- dev_err( &dev->udev->dev,
- "Error submitting the control message, ret:%d\n", ret );
- goto out;
- }
- return;
-
-out:
- kfree(req);
- usb_free_urb(urb);
-}
-
-
-static void set_speed_duplex( struct usbnet *dev, unsigned char value_l )
-{
- unsigned short value;
- unsigned char value_low = 0x00;
- unsigned char value_high = 0x00;
-
- value_low = value_l;
- value = value_low | (value_high << 8 );
- ch9x00_set_reg_async( dev, SET_SPEED_DUPLEX, REQ_WR_REG, value, 0, 0, NULL);
-
- return;
-}
-
-
-static int control_read( struct usbnet *dev,
- unsigned char request, unsigned char requesttype,
- unsigned short value, unsigned short index,
- void *data, unsigned short size, int timeout )
-{
- unsigned char *buf = NULL;
- int err = 0;
-
- dbg_prt("\n--> Control_read() index=0x%02x size=%d\n", index, size );
-
- buf = kmalloc( size, GFP_KERNEL );
- if( !buf ) {
- err = -ENOMEM;
- goto err_out;
- }
-
- err = usb_control_msg( dev->udev,
- usb_rcvctrlpipe(dev->udev, 0),
- request, requesttype,
- value, index,
- buf, size, timeout);
- if( err == size )
- memcpy( data, buf, size );
- else if( err >= 0 )
- err = -EINVAL;
- kfree(buf);
-
- return err;
-
-err_out:
- return err;
-}
-
-
-static int control_write( struct usbnet *dev,
- unsigned char request, unsigned char requesttype,
- unsigned short value, unsigned short index,
- void *data, unsigned short size, int timeout )
-{
- unsigned char *buf = NULL;
- int err = 0;
-
- dbg_prt("\n--> Control_write() index=0x%02x size=%d\n", index, size );
-
- if( data ) {
- buf = kmalloc( size, GFP_KERNEL );
- if( !buf ) {
- err = -ENOMEM;
- goto err_out;
- }
- memcpy( buf, data, size );
- }
-
- err = usb_control_msg( dev->udev,
- usb_sndctrlpipe( dev->udev, 0 ),
- request, requesttype,
- value, index,
- buf, size, timeout );
- if( err >= 0 && err < size )
- err = -EINVAL;
- kfree( buf );
-
- return 0;
-
-err_out:
- return err;
-}
-
-static int ch9x00_mdio_read( struct net_device *netdev,
- int phy_id, int loc )
-{
- struct usbnet *dev = netdev_priv(netdev);
- int product_id = dev->udev->descriptor.idProduct;
- __le16 res = 0x00; //for E091
- unsigned char buff[2]; //for E092
-
- dbg_prt("ch9x00_mdio_read phy_id:%02x loc:%02x\n", phy_id, loc);
-
- if( product_id == CH9x00_PID_E091 ||
- product_id == CH9x00_PID_8339 ) {
- mutex_lock( &dev->phy_mutex );
- if( phy_id == 0x00 ) {
- switch(loc) {
- case MII_BMCR: //Basic mode control register
- {
- if(speed_status == DEVICE_SPEED_10M){
- //Do nothing here
- }
- else
- res |= BMCR_SPEED100;
-
- if(duplex_status == DEVICE_DUPLEX_FULL)
- res |= BMCR_FULLDPLX;
- else {
- //Do nothing here
- }
-
- res |= BMCR_ANENABLE;
- break;
- }
- case MII_BMSR: //Basic mode status register
- {
- if(link_status == DEVICE_MEDIA_CONNECTED) //up
- res |= BMSR_LSTATUS;
- else { //down
- //Do nothing
- }
-
- if(speed_status == DEVICE_SPEED_10M) {
- if(duplex_status == DEVICE_DUPLEX_FULL)
- res |= BMSR_10FULL;
- else
- res |= BMSR_10HALF;
- }
- else {
- if(duplex_status == DEVICE_DUPLEX_FULL)
- res |= BMSR_100FULL;
- else
- res |= BMSR_100HALF;
- }
-
- break;
- }
- case MII_ADVERTISE: //Advertisement control reg
- {
- if(speed_status == DEVICE_SPEED_10M)
- res |= ADVERTISE_10FULL;
- else
- res |= ADVERTISE_10HALF;
-
- res |= 0x01; //IEEE 802.3
- }
- case MII_LPA: //Link partner ability reg
- {
- if(speed_status == DEVICE_SPEED_10M) {
- if(duplex_status == DEVICE_DUPLEX_FULL)
- res |= LPA_10FULL;
- else
- res |= LPA_10HALF;
- }
- else {
- if(duplex_status == DEVICE_DUPLEX_FULL)
- res |= LPA_100FULL;
- else
- res |= LPA_100HALF;
- }
-
- res |= 0x01; //IEEE 802.3
- break;
- }
- case MII_EXPANSION: //Expansion register
- break;
- default:
- break;
- }
- }
- mutex_unlock( &dev->phy_mutex);
- return le16_to_cpu(res);
- }
- else if( product_id == CH9x00_PID_E092 ) {
- if( phy_id )
- return 0;
-
- control_read( dev, REQUEST_READ, REQUEST_TYPE_READ,
- 0, loc*2, buff, 0x02, CONTROL_TIMEOUT_MS );
-
- return ( buff[0] | buff[1] << 8 );
- }
-
- return 0;
-}
-
-
-static void ch9x00_mdio_write( struct net_device *netdev,
- int phy_id, int loc, int val )
-{
- struct usbnet *dev = netdev_priv(netdev);
- int product_id = dev->udev->descriptor.idProduct;
- unsigned char value_l = 0; //for E091
- unsigned char buff[2]; //for E092
-
- dbg_prt("ch9x00_mdio_write() phy_id=%02x loc:%02x\n", phy_id, loc);
-
- if( product_id == CH9x00_PID_E091 ||
- product_id == CH9x00_PID_8339 ) {
- mutex_lock( &dev->phy_mutex );
- if(phy_id == 0x00) {
- switch(loc) {
- case MII_BMCR: //Base mode control register
- {
- if( val & BMCR_ANRESTART ) {
- //Do nothing
- }
-
- if( val & BMCR_ANENABLE ) {
- value_l |= AT;
- goto set;
- }
-
- if( val & BMCR_SPEED100 ) {
- value_l |= SPEED_100M;
- }
-
- // bit 8 duplex mode 1 = full-duplex
- if( val & BMCR_FULLDPLX ) {
- value_l |= FULL_DUPLEX;
- }
-set:
- set_speed_duplex(dev, value_l);
- break;
- }
- case MII_BMSR: //Basic mode status register
- break;
- case MII_ADVERTISE: //Advertisement control reg
- break;
- case MII_LPA: //Link partner ability reg
- break;
- case MII_EXPANSION: //Expansion register
- break;
- default:
- break;
- }
- }
- mutex_unlock( &dev->phy_mutex );
- return;
- }
- else if( product_id == CH9x00_PID_E092 ) {
- buff[0] = (unsigned char)val;
- buff[1] = (unsigned char)(val >> 8);
-
- if(phy_id)
- return;
-
- control_write( dev, REQUEST_WRITE, REQUEST_TYPE_WRITE,
- 0, loc*2, buff, 0x02, CONTROL_TIMEOUT_MS );
-
- }
-
-}
-
-
-static int ch9x00_link_reset( struct usbnet *dev )
-{
- struct ethtool_cmd ecmd;
-
- mii_check_media( &dev->mii, 1, 1 );
- mii_ethtool_gset( &dev->mii, &ecmd );
-
- dbg_prt("\nlink_reset() speed:%d duplex:%d \n", ecmd.speed, ecmd.duplex );
-
- return 0;
-}
-
-
-static void ch9x00_status( struct usbnet *dev, struct urb *urb )
-{
- int link;
- unsigned char *buf;
- int product_id = dev->udev->descriptor.idProduct;
-
- if( product_id == CH9x00_PID_E091 ||
- product_id == CH9x00_PID_8339 ) {
- if( urb->actual_length < 8 )
- return;
-
- buf = urb->transfer_buffer;
- link = !!(buf[0] & DEVICE_MEDIA_CONNECTED );
- link_status = buf[0] & DEVICE_MEDIA_CONNECTED;
- speed_status = buf[0] & DEVICE_SPEED_10M;
- duplex_status = buf[0] & DEVICE_DUPLEX_FULL;
- phy_status = buf[0] & DEVICE_PHY;
-
- if( netif_carrier_ok(dev->net) != link ) {
- if(link) {
- netif_carrier_on(dev->net);
- usbnet_defer_kevent(dev, EVENT_LINK_RESET);
- }
- else {
- netif_carrier_off(dev->net);
- }
- }
- }
- else if( product_id == CH9x00_PID_E092 ) {
- if( urb->actual_length < 16 )
- return;
-
- buf = urb->transfer_buffer;
- link = !!(buf[0] & 0x01);
-
- if( link ) {
- netif_carrier_on(dev->net);
- usbnet_defer_kevent(dev, EVENT_LINK_RESET);
- }
- else {
- netif_carrier_off(dev->net);
- }
- }
-
-
- return;
-}
-
-
-static struct sk_buff *ch9x00_tx_fixup(
- struct usbnet *dev, struct sk_buff *skb, gfp_t flags )
-{
- int i = 0;
- int len = 0;
- int tx_overhead = 0;
- int product_id = dev->udev->descriptor.idProduct;
-
- if( product_id == CH9x00_PID_E091 ||
- product_id == CH9x00_PID_8339 )
- tx_overhead = TX_OVERHEAD; //TX_OVERHEAD: 0x04
- else if( product_id == CH9x00_PID_E092 )
- tx_overhead = 0x40; //64
-
- len = skb->len;
- if( skb_headroom(skb) < tx_overhead ) {
- struct sk_buff *skb2;
-
- skb2 = skb_copy_expand(skb, tx_overhead, 0, flags);
- dev_kfree_skb_any(skb);
- skb = skb2;
- if( !skb )
- return NULL;
- }
-
- __skb_push(skb, tx_overhead);
- /* usbnet adds padding if length is a multiple of packet size
- if so, adjust length value in header */
- if( (skb->len % dev->maxpacket) == 0 ) {
- len++;
- }
-
- if( product_id == CH9x00_PID_E091 ||
- product_id == CH9x00_PID_8339 ) {
- skb->data[0] = len;
- skb->data[1] = len >> 8;
- skb->data[2] = 0x00;
- skb->data[3] = 0x00;
- }
- else if( product_id == CH9x00_PID_E092 ) {
- skb->data[0] = len;
- skb->data[1] = len >> 8;
- skb->data[2] = 0x00;
- skb->data[3] = 0x80;
-
- for( i = 4; i < 48; i++ )
- skb->data[i] = 0x00;
-
- skb->data[48] = len;
- skb->data[49] = len >> 8;
- skb->data[50] = 0x00;
- skb->data[51] = 0x80;
-
- for( i = 52; i < 64; i++ )
- skb->data[i] = 0x00;
- }
-
- return skb;
-}
-
-
-static int ch9x00_rx_fixup( struct usbnet *dev, struct sk_buff *skb )
-{
- int len = 0;
- int rx_overhead = 0;
- int product_id = dev->udev->descriptor.idProduct;
-
- if( product_id == CH9x00_PID_E091 ||
- product_id == CH9x00_PID_8339 ) {
- rx_overhead = RX_OVERHEAD;
-
- if( unlikely(skb->len < rx_overhead) ) {
- dev_err( &dev->udev->dev, "unexpected tiny rx frame\n");
- return 0;
- }
-
- len = (skb->data[0] | skb->data[1] << 8 );
-
- skb_pull(skb, rx_overhead);
- skb_trim(skb, len);
- }
- else if( product_id == CH9x00_PID_E092 ) {
- // Do nothing here
- rx_overhead = 64;
-
- if( unlikely(skb->len < rx_overhead) ) {
- dev_err( &dev->udev->dev, "unexpected tiny rx frame\n");
- return 0;
- }
-
- len = (skb->data[skb->len - 16] | skb->data[skb->len - 15] << 8 );
- /*printk("rx_fixup skb->len=%d, len=%d\n", skb->len, len );*/
-
- /*skb_pull(skb, rx_overhead);*/
- skb_trim(skb, len);
- }
-
- return 1;
-}
-
-
-static int get_mac_address( struct usbnet *dev, unsigned char *data )
-{
- int err = 0;
- //for E092
- unsigned char mac_addr[0x06];
- int rd_mac_len = 0;
-
- dbg_prt("\n--> get_mac_address:\n\tusbnet VID:%0x PID:%0x\n",
- dev->udev->descriptor.idVendor,
- dev->udev->descriptor.idProduct);
-
- if( dev->udev->descriptor.idProduct == CH9x00_PID_E091 ||
- dev->udev->descriptor.idProduct == CH9x00_PID_8339 )
- err = control_read( dev, GET_MAC_ADDRESS, REQ_RD_REG,
- 0, 0, data, 0x06, CTRL_TIMEOUT_MS );
- else if( dev->udev->descriptor.idProduct == CH9x00_PID_E092 ) {
- memset( mac_addr, 0, sizeof(mac_addr) );
- rd_mac_len = control_read( dev, REQUEST_READ, REQUEST_TYPE_READ,
- 0, MAC_REG_STATION_L, mac_addr, 0x02, CONTROL_TIMEOUT_MS );
- rd_mac_len += control_read( dev, REQUEST_READ, REQUEST_TYPE_READ,
- 0, MAC_REG_STATION_M, mac_addr+2, 0x02, CONTROL_TIMEOUT_MS );
- rd_mac_len += control_read( dev, REQUEST_READ, REQUEST_TYPE_READ,
- 0, MAC_REG_STATION_H, mac_addr+4, 0x02, CONTROL_TIMEOUT_MS );
- if( rd_mac_len != ETH_ALEN )
- err = -EINVAL;
- //Set MAC
- data[0] = mac_addr[5];
- data[1] = mac_addr[4];
- data[2] = mac_addr[3];
- data[3] = mac_addr[2];
- data[4] = mac_addr[1];
- data[5] = mac_addr[0];
- }
-
- if( err < 0 )
- goto err_out;
-
- return 0;
-
-err_out:
- return err;
-}
-
-
-static int ch9x00_bind( struct usbnet *dev, struct usb_interface *intf )
-{
- int retval = 0;
- unsigned char data[2];
-
- //int vendor_id = dev->udev->descriptor.idVendor;
- int product_id = dev->udev->descriptor.idProduct;
-
- retval = usbnet_get_endpoints(dev, intf);
- if(retval)
- goto err_out;
-
- // compatibility of E091 and E092
- if( product_id == CH9x00_PID_E091 ||
- product_id == CH9x00_PID_8339 ) {
- if( (retval = get_mac_address(dev, dev->net->dev_addr)) < 0 ) {
- return retval;
- goto err_out;
- }
- }
-
- // Initialize MII structure for Setting Speed Duplex
- dev->mii.dev = dev->net;
- dev->mii.mdio_read = ch9x00_mdio_read;
- dev->mii.mdio_write = ch9x00_mdio_write;
- dev->mii.reg_num_mask = 0x1f;
-
- if( product_id == CH9x00_PID_E091 ||
- product_id == CH9x00_PID_8339 ) {
- dev->mii.phy_id_mask = 0x3f;
- /*dev->rx_urb_size = dev->net->mtu + 14 + RX_OVERHEAD;*/
- // Note: Max package length=1518 (MTU + ETH_HELN + RX_OVERHEAD)
- dev->rx_urb_size = dev->net->mtu + ETH_HLEN + RX_OVERHEAD;
- // Adaptor can restart, when driver rmmoded or insmoded
- mii_nway_restart( &dev->mii );
- }
- else if( product_id == CH9x00_PID_E092 ) {
- dev->mii.phy_id_mask = 0x1f;
-
- dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
- // Note: Max package legth= 24*64 + 16
- dev->rx_urb_size = 24*64 + 16;
- // Adaptor can restart, when driver rmmoded or insmoded
- mii_nway_restart( &dev->mii );
-
- // Initilization hardware
- data[0] = 0x01;
- data[1] = 0x0F;
- retval = control_write( dev, REQUEST_WRITE, REQUEST_TYPE_WRITE,
- 0, 88, data, 0x02, CONTROL_TIMEOUT_MS );
-
- data[0] = 0xA0;
- data[1] = 0x90;
- retval = control_write( dev, REQUEST_WRITE, REQUEST_TYPE_WRITE,
- 0, 90, data, 0x02, CONTROL_TIMEOUT_MS );
-
- data[0] = 0x30;
- data[1] = 0x00;
- retval = control_write( dev, REQUEST_WRITE, REQUEST_TYPE_WRITE,
- 0, 92, data, 0x02, CONTROL_TIMEOUT_MS );
-
- data[0] = 0x17;
- data[1] = 0xD8;
- retval = control_write( dev, REQUEST_WRITE, REQUEST_TYPE_WRITE,
- 0, 94, data, 0x02, CONTROL_TIMEOUT_MS );
-
- data[0] = 0x01;
- data[1] = 0x00;
- retval = control_write( dev, REQUEST_WRITE, REQUEST_TYPE_WRITE,
- 0, 254, data, 0x02, CONTROL_TIMEOUT_MS );
-
- data[0] = 0x5F; // 0x0101 1111
- data[1] = 0x0D; // 0x0000 1101
- // Control Register Setting
- retval = control_write( dev, REQUEST_WRITE, REQUEST_TYPE_WRITE,
- 0, 64, data, 0x02, CONTROL_TIMEOUT_MS );
-
- if( (retval = get_mac_address(dev, dev->net->dev_addr)) < 0 ) {
- return retval;
- goto err_out;
- }
- }
- if( retval < 0 )
- goto err_out;
-
- return 0;
-
-err_out:
- return retval;
-}
-
-
-static const struct driver_info ch9x00_info = {
- .description = "CH9x00 USB to Network Adaptor",
- .flags = FLAG_ETHER,
- .bind = ch9x00_bind,
- .rx_fixup = ch9x00_rx_fixup,
- .tx_fixup = ch9x00_tx_fixup,
- .status = ch9x00_status,
- .link_reset = ch9x00_link_reset,
- .reset = ch9x00_link_reset,
-};
-
-static const struct usb_device_id ch9x00_products[] = {
- {
- USB_DEVICE( 0x1A86, 0xE091 ),
- .driver_info = (unsigned long)&ch9x00_info,
- },
- {
- USB_DEVICE( 0x1A86, 0xE092 ),
- .driver_info = (unsigned long)&ch9x00_info,
- },
- { USB_DEVICE( 0x1A86, 0x8339 ),
- .driver_info = (unsigned long)&ch9x00_info,
- },
- {},
-};
-MODULE_DEVICE_TABLE( usb, ch9x00_products );
-
-static struct usb_driver ch9x00_driver = {
- .name = "ch9x00",
- .id_table = ch9x00_products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
-};
-
-static int __init ch9x00_init( void )
-{
- printk( KERN_INFO "\tCH9x00 Driver Version:%s\n", DRIVER_VERSION);
- return usb_register( &ch9x00_driver );
-}
-
-static void __exit ch9x00_exit( void )
-{
- usb_deregister( &ch9x00_driver );
-}
-
-module_init( ch9x00_init );
-module_exit( ch9x00_exit );
-
-MODULE_DESCRIPTION( "USB to Network adapter CH9x00" );
-MODULE_LICENSE( "GPL" );
diff --git a/ANDROID_3.4.5/drivers/net/usb/compatibility.h b/ANDROID_3.4.5/drivers/net/usb/compatibility.h
deleted file mode 100755
index cb2ed9ae..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/compatibility.h
+++ /dev/null
@@ -1,387 +0,0 @@
-#ifndef LINUX_COMPATIBILITY_H
-#define LINUX_COMPATIBILITY_H
-
-/*
- * Definition and macro
- */
-
-#include <linux/init.h>
-#include <linux/version.h>
-#include <linux/in.h>
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
-#include <linux/mdio.h>
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
- #define NETIF_F_HW_VLAN_CTAG_RX NETIF_F_HW_VLAN_RX
- #define NETIF_F_HW_VLAN_CTAG_TX NETIF_F_HW_VLAN_TX
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
-/*
- static inline __sum16 tcp_v6_check(int len,
- const struct in6_addr *saddr,
- const struct in6_addr *daddr,
- wsum base)
- {
- return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base);
- }*/
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
- #define eth_random_addr(addr) random_ether_addr(addr)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
- #define ETH_MDIO_SUPPORTS_C22 MDIO_SUPPORTS_C22
-
- static inline void eth_hw_addr_random(struct net_device *dev)
- {
- random_ether_addr(dev->dev_addr);
- }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)
- #define module_usb_driver(__driver) \
- static int __init __driver##_init(void) \
- { \
- return usb_register(&(__driver)); \
- } \
- module_init(__driver##_init); \
- static void __exit __driver##_exit(void) \
- { \
- usb_deregister(&(__driver)); \
- } \
- module_exit(__driver##_exit);
-
- #define netdev_features_t u32
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)
- #define PMSG_IS_AUTO(msg) (((msg).event & PM_EVENT_AUTO) != 0)
-
- static inline struct page *skb_frag_page(const skb_frag_t *frag)
- {
- return frag->page;
- }
-
- static inline void *skb_frag_address(const skb_frag_t *frag)
- {
- return page_address(skb_frag_page(frag)) + frag->page_offset;
- }
-
- static inline unsigned int skb_frag_size(const skb_frag_t *frag)
- {
- return frag->size;
- }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)
- #define ndo_set_rx_mode ndo_set_multicast_list
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)
- #define NETIF_F_RXCSUM (1 << 29) /* Receive checksumming offload */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
- #define skb_checksum_none_assert(skb_ptr) (skb_ptr)->ip_summed = CHECKSUM_NONE
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
- static inline void usleep_range(unsigned long min, unsigned long max)
- {
- unsigned long ms = min / 1000;
-
- if (ms)
- mdelay(ms);
-
- udelay(min % 1000);
- }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
- static inline bool pci_dev_run_wake(struct pci_dev *dev)
- {
- return 1;
- }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)
- #define netdev_mc_count(netdev) ((netdev)->mc_count)
- #define netdev_mc_empty(netdev) (netdev_mc_count(netdev) == 0)
-
- #define netif_printk(priv, type, level, netdev, fmt, args...) \
- do { \
- if (netif_msg_##type(priv)) \
- printk(level "%s: " fmt,(netdev)->name , ##args); \
- } while (0)
-
- #define netif_emerg(priv, type, netdev, fmt, args...) \
- netif_printk(priv, type, KERN_EMERG, netdev, fmt, ##args)
- #define netif_alert(priv, type, netdev, fmt, args...) \
- netif_printk(priv, type, KERN_ALERT, netdev, fmt, ##args)
- #define netif_crit(priv, type, netdev, fmt, args...) \
- netif_printk(priv, type, KERN_CRIT, netdev, fmt, ##args)
- #define netif_err(priv, type, netdev, fmt, args...) \
- netif_printk(priv, type, KERN_ERR, netdev, fmt, ##args)
- #define netif_warn(priv, type, netdev, fmt, args...) \
- netif_printk(priv, type, KERN_WARNING, netdev, fmt, ##args)
- #define netif_notice(priv, type, netdev, fmt, args...) \
- netif_printk(priv, type, KERN_NOTICE, netdev, fmt, ##args)
- #define netif_info(priv, type, netdev, fmt, args...) \
- netif_printk(priv, type, KERN_INFO, (netdev), fmt, ##args)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
- #define get_sset_count get_stats_count
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
- #define pm_request_resume(para)
- #define pm_runtime_set_suspended(para)
- #define pm_schedule_suspend(para1, para2)
- #define pm_runtime_get_sync(para)
- #define pm_runtime_put_sync(para)
- #define pm_runtime_put_noidle(para)
- #define pm_runtime_idle(para)
- #define pm_runtime_set_active(para)
- #define pm_runtime_enable(para)
- #define pm_runtime_disable(para)
- typedef int netdev_tx_t;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
- #define USB_SPEED_SUPER (USB_SPEED_VARIABLE + 1)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
- static inline void usb_autopm_put_interface_async(struct usb_interface *intf)
- {
- struct usb_device *udev = interface_to_usbdev(intf);
- int status = 0;
-
- if (intf->condition == USB_INTERFACE_UNBOUND) {
- status = -ENODEV;
- } else {
- udev->last_busy = jiffies;
- --intf->pm_usage_cnt;
- if (udev->autosuspend_disabled || udev->autosuspend_delay < 0)
- status = -EPERM;
- }
- }
-
- static inline int usb_autopm_get_interface_async(struct usb_interface *intf)
- {
- struct usb_device *udev = interface_to_usbdev(intf);
- int status = 0;
-
- if (intf->condition == USB_INTERFACE_UNBOUND)
- status = -ENODEV;
- else if (udev->autoresume_disabled)
- status = -EPERM;
- else
- ++intf->pm_usage_cnt;
- return status;
- }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
- static inline void __skb_queue_splice(const struct sk_buff_head *list,
- struct sk_buff *prev,
- struct sk_buff *next)
- {
- struct sk_buff *first = list->next;
- struct sk_buff *last = list->prev;
-
- first->prev = prev;
- prev->next = first;
-
- last->next = next;
- next->prev = last;
- }
-
- static inline void skb_queue_splice(const struct sk_buff_head *list,
- struct sk_buff_head *head)
- {
- if (!skb_queue_empty(list)) {
- __skb_queue_splice(list, (struct sk_buff *) head, head->next);
- head->qlen += list->qlen;
- }
- }
-
- static inline void __skb_queue_head_init(struct sk_buff_head *list)
- {
- list->prev = list->next = (struct sk_buff *)list;
- list->qlen = 0;
- }
-
- static inline void skb_queue_splice_init(struct sk_buff_head *list,
- struct sk_buff_head *head)
- {
- if (!skb_queue_empty(list)) {
- __skb_queue_splice(list, (struct sk_buff *) head, head->next);
- head->qlen += list->qlen;
- __skb_queue_head_init(list);
- }
- }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
- #define PM_EVENT_AUTO 0x0400
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
- #define napi_enable(napi_ptr) netif_poll_enable(tp->dev)
- #define napi_disable(napi_ptr) netif_poll_disable(tp->dev)
- #define napi_schedule(napi_ptr) netif_rx_schedule(tp->dev)
- #define napi_complete(napi_ptr) netif_rx_complete(tp->dev)
- #define netif_napi_del(napi_ptr)
- #define netif_napi_add(ndev, napi_ptr, function, weight_t) \
- ndev->poll = function; \
- ndev->weight = weight_t;
- typedef unsigned long uintptr_t;
- #define DMA_BIT_MASK(value) \
- (value < 64 ? ((1ULL << value) - 1) : 0xFFFFFFFFFFFFFFFFULL)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
- #define NETIF_F_IPV6_CSUM 16
- #define cancel_delayed_work_sync cancel_delayed_work
-
- static inline int skb_cow_head(struct sk_buff *skb, unsigned int headroom)
- {
- int delta = 0;
-
- if (headroom > skb_headroom(skb))
- delta = headroom - skb_headroom(skb);
-
- if (delta || skb_header_cloned(skb))
- return pskb_expand_head(skb, ALIGN(delta, NET_SKB_PAD), 0,
- GFP_ATOMIC);
- return 0;
- }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
- #define ip_hdr(skb_ptr) (skb_ptr)->nh.iph
- #define ipv6hdr(skb_ptr) (skb_ptr)->nh.ipv6h
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
- #define vlan_group_set_device(vlgrp, vid, value) \
- if (vlgrp) \
- vlgrp->vlan_devices[vid] = value;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- #define delayed_work work_struct
- #define INIT_DELAYED_WORK(a,b) INIT_WORK(a,b,tp)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
- #define CHECKSUM_PARTIAL CHECKSUM_HW
-
- static inline void *kmemdup(const void *src, size_t len, gfp_t gfp)
- {
- void *p;
-
- p = kmalloc_track_caller(len, gfp);
- if (p)
- memcpy(p, src, len);
- return p;
- }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
- #define skb_is_gso(skb_ptr) skb_shinfo(skb_ptr)->tso_size
- #define netdev_alloc_skb(dev, len) dev_alloc_skb(len)
- #define IRQF_SHARED SA_SHIRQ
-
- static inline struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
- {
- return NULL;
- }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
-#ifndef __LINUX_MUTEX_H
- #define mutex semaphore
- #define mutex_lock down
- #define mutex_unlock up
- #define mutex_lock_interruptible down_interruptible
- #define mutex_init init_MUTEX
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
- #define ADVERTISED_Pause (1 << 13)
- #define ADVERTISED_Asym_Pause (1 << 14)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)
- #define skb_header_cloned(skb) skb_cloned(skb)
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) */
-
-#ifndef FALSE
- #define TRUE 1
- #define FALSE 0
-#endif
-
-/*
- * inline function
- */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
-static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
- unsigned int length)
-{
- struct sk_buff *skb = netdev_alloc_skb(dev, length + NET_IP_ALIGN);
-
- if (NET_IP_ALIGN && skb)
- skb_reserve(skb, NET_IP_ALIGN);
- return skb;
-}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
-static inline void skb_copy_from_linear_data(const struct sk_buff *skb,
- void *to,
- const unsigned int len)
-{
- memcpy(to, skb->data, len);
-}
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) */
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
-/**
- * netif_napi_del - remove a napi context
- * @napi: napi context
- *
- * netif_napi_del() removes a napi context from the network device napi list
- */
-static inline void netif_napi_del(struct napi_struct *napi)
-{
-#ifdef CONFIG_NETPOLL
- list_del(&napi->dev_list);
-#endif
-}
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
- #define skb_tx_timestamp(skb) (tp->netdev->trans_start = jiffies)
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
- #define skb_tx_timestamp(skb)
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) */
-
-enum rtl_cmd {
- RTLTOOL_PLA_OCP_READ_DWORD = 0,
- RTLTOOL_PLA_OCP_WRITE_DWORD,
- RTLTOOL_USB_OCP_READ_DWORD,
- RTLTOOL_USB_OCP_WRITE_DWORD,
- RTLTOOL_PLA_OCP_READ,
- RTLTOOL_PLA_OCP_WRITE,
- RTLTOOL_USB_OCP_READ,
- RTLTOOL_USB_OCP_WRITE,
- RTLTOOL_USB_INFO,
- RTL_ENABLE_USB_DIAG,
- RTL_DISABLE_USB_DIAG,
-
- RTLTOOL_INVALID
-};
-
-struct usb_device_info {
- __u16 idVendor;
- __u16 idProduct;
- __u16 bcdDevice;
- __u8 dev_addr[8];
- char devpath[16];
-};
-
-struct rtltool_cmd {
- __u32 cmd;
- __u32 offset;
- __u32 byteen;
- __u32 data;
- void *buf;
- struct usb_device_info nic_info;
- struct sockaddr ifru_addr;
- struct sockaddr ifru_netmask;
- struct sockaddr ifru_hwaddr;
-};
-
-#endif /* LINUX_COMPATIBILITY_H */
diff --git a/ANDROID_3.4.5/drivers/net/usb/cx82310_eth.c b/ANDROID_3.4.5/drivers/net/usb/cx82310_eth.c
deleted file mode 100644
index 0e053135..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/cx82310_eth.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Driver for USB ethernet port of Conexant CX82310-based ADSL routers
- * Copyright (C) 2010 by Ondrej Zary
- * some parts inspired by the cxacru driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/workqueue.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/usb/usbnet.h>
-
-enum cx82310_cmd {
- CMD_START = 0x84, /* no effect? */
- CMD_STOP = 0x85, /* no effect? */
- CMD_GET_STATUS = 0x90, /* returns nothing? */
- CMD_GET_MAC_ADDR = 0x91, /* read MAC address */
- CMD_GET_LINK_STATUS = 0x92, /* not useful, link is always up */
- CMD_ETHERNET_MODE = 0x99, /* unknown, needed during init */
-};
-
-enum cx82310_status {
- STATUS_UNDEFINED,
- STATUS_SUCCESS,
- STATUS_ERROR,
- STATUS_UNSUPPORTED,
- STATUS_UNIMPLEMENTED,
- STATUS_PARAMETER_ERROR,
- STATUS_DBG_LOOPBACK,
-};
-
-#define CMD_PACKET_SIZE 64
-/* first command after power on can take around 8 seconds */
-#define CMD_TIMEOUT 15000
-#define CMD_REPLY_RETRY 5
-
-#define CX82310_MTU 1514
-#define CMD_EP 0x01
-
-/*
- * execute control command
- * - optionally send some data (command parameters)
- * - optionally wait for the reply
- * - optionally read some data from the reply
- */
-static int cx82310_cmd(struct usbnet *dev, enum cx82310_cmd cmd, bool reply,
- u8 *wdata, int wlen, u8 *rdata, int rlen)
-{
- int actual_len, retries, ret;
- struct usb_device *udev = dev->udev;
- u8 *buf = kzalloc(CMD_PACKET_SIZE, GFP_KERNEL);
-
- if (!buf)
- return -ENOMEM;
-
- /* create command packet */
- buf[0] = cmd;
- if (wdata)
- memcpy(buf + 4, wdata, min_t(int, wlen, CMD_PACKET_SIZE - 4));
-
- /* send command packet */
- ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, CMD_EP), buf,
- CMD_PACKET_SIZE, &actual_len, CMD_TIMEOUT);
- if (ret < 0) {
- dev_err(&dev->udev->dev, "send command %#x: error %d\n",
- cmd, ret);
- goto end;
- }
-
- if (reply) {
- /* wait for reply, retry if it's empty */
- for (retries = 0; retries < CMD_REPLY_RETRY; retries++) {
- ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, CMD_EP),
- buf, CMD_PACKET_SIZE, &actual_len,
- CMD_TIMEOUT);
- if (ret < 0) {
- dev_err(&dev->udev->dev,
- "reply receive error %d\n", ret);
- goto end;
- }
- if (actual_len > 0)
- break;
- }
- if (actual_len == 0) {
- dev_err(&dev->udev->dev, "no reply to command %#x\n",
- cmd);
- ret = -EIO;
- goto end;
- }
- if (buf[0] != cmd) {
- dev_err(&dev->udev->dev,
- "got reply to command %#x, expected: %#x\n",
- buf[0], cmd);
- ret = -EIO;
- goto end;
- }
- if (buf[1] != STATUS_SUCCESS) {
- dev_err(&dev->udev->dev, "command %#x failed: %#x\n",
- cmd, buf[1]);
- ret = -EIO;
- goto end;
- }
- if (rdata)
- memcpy(rdata, buf + 4,
- min_t(int, rlen, CMD_PACKET_SIZE - 4));
- }
-end:
- kfree(buf);
- return ret;
-}
-
-#define partial_len data[0] /* length of partial packet data */
-#define partial_rem data[1] /* remaining (missing) data length */
-#define partial_data data[2] /* partial packet data */
-
-static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- int ret;
- char buf[15];
- struct usb_device *udev = dev->udev;
-
- /* avoid ADSL modems - continue only if iProduct is "USB NET CARD" */
- if (usb_string(udev, udev->descriptor.iProduct, buf, sizeof(buf)) > 0
- && strcmp(buf, "USB NET CARD")) {
- dev_info(&udev->dev, "ignoring: probably an ADSL modem\n");
- return -ENODEV;
- }
-
- ret = usbnet_get_endpoints(dev, intf);
- if (ret)
- return ret;
-
- /*
- * this must not include ethernet header as the device can send partial
- * packets with no header (and sometimes even empty URBs)
- */
- dev->net->hard_header_len = 0;
- /* we can send at most 1514 bytes of data (+ 2-byte header) per URB */
- dev->hard_mtu = CX82310_MTU + 2;
- /* we can receive URBs up to 4KB from the device */
- dev->rx_urb_size = 4096;
-
- dev->partial_data = (unsigned long) kmalloc(dev->hard_mtu, GFP_KERNEL);
- if (!dev->partial_data)
- return -ENOMEM;
-
- /* enable ethernet mode (?) */
- ret = cx82310_cmd(dev, CMD_ETHERNET_MODE, true, "\x01", 1, NULL, 0);
- if (ret) {
- dev_err(&udev->dev, "unable to enable ethernet mode: %d\n",
- ret);
- goto err;
- }
-
- /* get the MAC address */
- ret = cx82310_cmd(dev, CMD_GET_MAC_ADDR, true, NULL, 0,
- dev->net->dev_addr, ETH_ALEN);
- if (ret) {
- dev_err(&udev->dev, "unable to read MAC address: %d\n", ret);
- goto err;
- }
-
- /* start (does not seem to have any effect?) */
- ret = cx82310_cmd(dev, CMD_START, false, NULL, 0, NULL, 0);
- if (ret)
- goto err;
-
- return 0;
-err:
- kfree((void *)dev->partial_data);
- return ret;
-}
-
-static void cx82310_unbind(struct usbnet *dev, struct usb_interface *intf)
-{
- kfree((void *)dev->partial_data);
-}
-
-/*
- * RX is NOT easy - we can receive multiple packets per skb, each having 2-byte
- * packet length at the beginning.
- * The last packet might be incomplete (when it crosses the 4KB URB size),
- * continuing in the next skb (without any headers).
- * If a packet has odd length, there is one extra byte at the end (before next
- * packet or at the end of the URB).
- */
-static int cx82310_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- int len;
- struct sk_buff *skb2;
-
- /*
- * If the last skb ended with an incomplete packet, this skb contains
- * end of that packet at the beginning.
- */
- if (dev->partial_rem) {
- len = dev->partial_len + dev->partial_rem;
- skb2 = alloc_skb(len, GFP_ATOMIC);
- if (!skb2)
- return 0;
- skb_put(skb2, len);
- memcpy(skb2->data, (void *)dev->partial_data,
- dev->partial_len);
- memcpy(skb2->data + dev->partial_len, skb->data,
- dev->partial_rem);
- usbnet_skb_return(dev, skb2);
- skb_pull(skb, (dev->partial_rem + 1) & ~1);
- dev->partial_rem = 0;
- if (skb->len < 2)
- return 1;
- }
-
- /* a skb can contain multiple packets */
- while (skb->len > 1) {
- /* first two bytes are packet length */
- len = skb->data[0] | (skb->data[1] << 8);
- skb_pull(skb, 2);
-
- /* if last packet in the skb, let usbnet to process it */
- if (len == skb->len || len + 1 == skb->len) {
- skb_trim(skb, len);
- break;
- }
-
- if (len > CX82310_MTU) {
- dev_err(&dev->udev->dev, "RX packet too long: %d B\n",
- len);
- return 0;
- }
-
- /* incomplete packet, save it for the next skb */
- if (len > skb->len) {
- dev->partial_len = skb->len;
- dev->partial_rem = len - skb->len;
- memcpy((void *)dev->partial_data, skb->data,
- dev->partial_len);
- skb_pull(skb, skb->len);
- break;
- }
-
- skb2 = alloc_skb(len, GFP_ATOMIC);
- if (!skb2)
- return 0;
- skb_put(skb2, len);
- memcpy(skb2->data, skb->data, len);
- /* process the packet */
- usbnet_skb_return(dev, skb2);
-
- skb_pull(skb, (len + 1) & ~1);
- }
-
- /* let usbnet process the last packet */
- return 1;
-}
-
-/* TX is easy, just add 2 bytes of length at the beginning */
-static struct sk_buff *cx82310_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
- gfp_t flags)
-{
- int len = skb->len;
-
- if (skb_headroom(skb) < 2) {
- struct sk_buff *skb2 = skb_copy_expand(skb, 2, 0, flags);
- dev_kfree_skb_any(skb);
- skb = skb2;
- if (!skb)
- return NULL;
- }
- skb_push(skb, 2);
-
- skb->data[0] = len;
- skb->data[1] = len >> 8;
-
- return skb;
-}
-
-
-static const struct driver_info cx82310_info = {
- .description = "Conexant CX82310 USB ethernet",
- .flags = FLAG_ETHER,
- .bind = cx82310_bind,
- .unbind = cx82310_unbind,
- .rx_fixup = cx82310_rx_fixup,
- .tx_fixup = cx82310_tx_fixup,
-};
-
-#define USB_DEVICE_CLASS(vend, prod, cl, sc, pr) \
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
- USB_DEVICE_ID_MATCH_DEV_INFO, \
- .idVendor = (vend), \
- .idProduct = (prod), \
- .bDeviceClass = (cl), \
- .bDeviceSubClass = (sc), \
- .bDeviceProtocol = (pr)
-
-static const struct usb_device_id products[] = {
- {
- USB_DEVICE_CLASS(0x0572, 0xcb01, 0xff, 0, 0),
- .driver_info = (unsigned long) &cx82310_info
- },
- { },
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver cx82310_driver = {
- .name = "cx82310_eth",
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
-};
-
-module_usb_driver(cx82310_driver);
-
-MODULE_AUTHOR("Ondrej Zary");
-MODULE_DESCRIPTION("Conexant CX82310-based ADSL router USB ethernet driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/dm9601.c b/ANDROID_3.4.5/drivers/net/usb/dm9601.c
deleted file mode 100644
index b9722631..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/dm9601.c
+++ /dev/null
@@ -1,679 +0,0 @@
-/*
- * Davicom DM9601 USB 1.1 10/100Mbps ethernet devices
- *
- * Peter Korsgaard <jacmet@sunsite.dk>
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-//#define DEBUG
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/stddef.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/crc32.h>
-#include <linux/usb/usbnet.h>
-#include <linux/slab.h>
-
-/* datasheet:
- http://ptm2.cc.utu.fi/ftp/network/cards/DM9601/From_NET/DM9601-DS-P01-930914.pdf
-*/
-
-/* control requests */
-#define DM_READ_REGS 0x00
-#define DM_WRITE_REGS 0x01
-#define DM_READ_MEMS 0x02
-#define DM_WRITE_REG 0x03
-#define DM_WRITE_MEMS 0x05
-#define DM_WRITE_MEM 0x07
-
-/* registers */
-#define DM_NET_CTRL 0x00
-#define DM_RX_CTRL 0x05
-#define DM_SHARED_CTRL 0x0b
-#define DM_SHARED_ADDR 0x0c
-#define DM_SHARED_DATA 0x0d /* low + high */
-#define DM_PHY_ADDR 0x10 /* 6 bytes */
-#define DM_MCAST_ADDR 0x16 /* 8 bytes */
-#define DM_GPR_CTRL 0x1e
-#define DM_GPR_DATA 0x1f
-
-#define DM_MAX_MCAST 64
-#define DM_MCAST_SIZE 8
-#define DM_EEPROM_LEN 256
-#define DM_TX_OVERHEAD 2 /* 2 byte header */
-#define DM_RX_OVERHEAD 7 /* 3 byte header + 4 byte crc tail */
-#define DM_TIMEOUT 1000
-
-
-static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data)
-{
- void *buf;
- int err = -ENOMEM;
-
- netdev_dbg(dev->net, "dm_read() reg=0x%02x length=%d\n", reg, length);
-
- buf = kmalloc(length, GFP_KERNEL);
- if (!buf)
- goto out;
-
- err = usb_control_msg(dev->udev,
- usb_rcvctrlpipe(dev->udev, 0),
- DM_READ_REGS,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, reg, buf, length, USB_CTRL_SET_TIMEOUT);
- if (err == length)
- memcpy(data, buf, length);
- else if (err >= 0)
- err = -EINVAL;
- kfree(buf);
-
- out:
- return err;
-}
-
-static int dm_read_reg(struct usbnet *dev, u8 reg, u8 *value)
-{
- return dm_read(dev, reg, 1, value);
-}
-
-static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data)
-{
- void *buf = NULL;
- int err = -ENOMEM;
-
- netdev_dbg(dev->net, "dm_write() reg=0x%02x, length=%d\n", reg, length);
-
- if (data) {
- buf = kmemdup(data, length, GFP_KERNEL);
- if (!buf)
- goto out;
- }
-
- err = usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- DM_WRITE_REGS,
- USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
- 0, reg, buf, length, USB_CTRL_SET_TIMEOUT);
- kfree(buf);
- if (err >= 0 && err < length)
- err = -EINVAL;
- out:
- return err;
-}
-
-static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value)
-{
- netdev_dbg(dev->net, "dm_write_reg() reg=0x%02x, value=0x%02x\n",
- reg, value);
- return usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- DM_WRITE_REG,
- USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
- value, reg, NULL, 0, USB_CTRL_SET_TIMEOUT);
-}
-
-static void dm_write_async_callback(struct urb *urb)
-{
- struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
- int status = urb->status;
-
- if (status < 0)
- printk(KERN_DEBUG "dm_write_async_callback() failed with %d\n",
- status);
-
- kfree(req);
- usb_free_urb(urb);
-}
-
-static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value,
- u16 length, void *data)
-{
- struct usb_ctrlrequest *req;
- struct urb *urb;
- int status;
-
- urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!urb) {
- netdev_err(dev->net, "Error allocating URB in dm_write_async_helper!\n");
- return;
- }
-
- req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
- if (!req) {
- netdev_err(dev->net, "Failed to allocate memory for control request\n");
- usb_free_urb(urb);
- return;
- }
-
- req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
- req->bRequest = length ? DM_WRITE_REGS : DM_WRITE_REG;
- req->wValue = cpu_to_le16(value);
- req->wIndex = cpu_to_le16(reg);
- req->wLength = cpu_to_le16(length);
-
- usb_fill_control_urb(urb, dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- (void *)req, data, length,
- dm_write_async_callback, req);
-
- status = usb_submit_urb(urb, GFP_ATOMIC);
- if (status < 0) {
- netdev_err(dev->net, "Error submitting the control message: status=%d\n",
- status);
- kfree(req);
- usb_free_urb(urb);
- }
-}
-
-static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
-{
- netdev_dbg(dev->net, "dm_write_async() reg=0x%02x length=%d\n", reg, length);
-
- dm_write_async_helper(dev, reg, 0, length, data);
-}
-
-static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
-{
- netdev_dbg(dev->net, "dm_write_reg_async() reg=0x%02x value=0x%02x\n",
- reg, value);
-
- dm_write_async_helper(dev, reg, value, 0, NULL);
-}
-
-static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 *value)
-{
- int ret, i;
-
- mutex_lock(&dev->phy_mutex);
-
- dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
- dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0xc : 0x4);
-
- for (i = 0; i < DM_TIMEOUT; i++) {
- u8 tmp;
-
- udelay(1);
- ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp);
- if (ret < 0)
- goto out;
-
- /* ready */
- if ((tmp & 1) == 0)
- break;
- }
-
- if (i == DM_TIMEOUT) {
- netdev_err(dev->net, "%s read timed out!\n", phy ? "phy" : "eeprom");
- ret = -EIO;
- goto out;
- }
-
- dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
- ret = dm_read(dev, DM_SHARED_DATA, 2, value);
-
- netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n",
- phy, reg, *value, ret);
-
- out:
- mutex_unlock(&dev->phy_mutex);
- return ret;
-}
-
-static int dm_write_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 value)
-{
- int ret, i;
-
- mutex_lock(&dev->phy_mutex);
-
- ret = dm_write(dev, DM_SHARED_DATA, 2, &value);
- if (ret < 0)
- goto out;
-
- dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
- dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1a : 0x12);
-
- for (i = 0; i < DM_TIMEOUT; i++) {
- u8 tmp;
-
- udelay(1);
- ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp);
- if (ret < 0)
- goto out;
-
- /* ready */
- if ((tmp & 1) == 0)
- break;
- }
-
- if (i == DM_TIMEOUT) {
- netdev_err(dev->net, "%s write timed out!\n", phy ? "phy" : "eeprom");
- ret = -EIO;
- goto out;
- }
-
- dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
-
-out:
- mutex_unlock(&dev->phy_mutex);
- return ret;
-}
-
-static int dm_read_eeprom_word(struct usbnet *dev, u8 offset, void *value)
-{
- return dm_read_shared_word(dev, 0, offset, value);
-}
-
-
-
-static int dm9601_get_eeprom_len(struct net_device *dev)
-{
- return DM_EEPROM_LEN;
-}
-
-static int dm9601_get_eeprom(struct net_device *net,
- struct ethtool_eeprom *eeprom, u8 * data)
-{
- struct usbnet *dev = netdev_priv(net);
- __le16 *ebuf = (__le16 *) data;
- int i;
-
- /* access is 16bit */
- if ((eeprom->offset % 2) || (eeprom->len % 2))
- return -EINVAL;
-
- for (i = 0; i < eeprom->len / 2; i++) {
- if (dm_read_eeprom_word(dev, eeprom->offset / 2 + i,
- &ebuf[i]) < 0)
- return -EINVAL;
- }
- return 0;
-}
-
-static int dm9601_mdio_read(struct net_device *netdev, int phy_id, int loc)
-{
- struct usbnet *dev = netdev_priv(netdev);
-
- __le16 res;
-
- if (phy_id) {
- netdev_dbg(dev->net, "Only internal phy supported\n");
- return 0;
- }
-
- dm_read_shared_word(dev, 1, loc, &res);
-
- netdev_dbg(dev->net,
- "dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
- phy_id, loc, le16_to_cpu(res));
-
- return le16_to_cpu(res);
-}
-
-static void dm9601_mdio_write(struct net_device *netdev, int phy_id, int loc,
- int val)
-{
- struct usbnet *dev = netdev_priv(netdev);
- __le16 res = cpu_to_le16(val);
-
- if (phy_id) {
- netdev_dbg(dev->net, "Only internal phy supported\n");
- return;
- }
-
- netdev_dbg(dev->net, "dm9601_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
- phy_id, loc, val);
-
- dm_write_shared_word(dev, 1, loc, res);
-}
-
-static void dm9601_get_drvinfo(struct net_device *net,
- struct ethtool_drvinfo *info)
-{
- /* Inherit standard device info */
- usbnet_get_drvinfo(net, info);
- info->eedump_len = DM_EEPROM_LEN;
-}
-
-static u32 dm9601_get_link(struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
-
- return mii_link_ok(&dev->mii);
-}
-
-static int dm9601_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
-{
- struct usbnet *dev = netdev_priv(net);
-
- return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
-}
-
-static const struct ethtool_ops dm9601_ethtool_ops = {
- .get_drvinfo = dm9601_get_drvinfo,
- .get_link = dm9601_get_link,
- .get_msglevel = usbnet_get_msglevel,
- .set_msglevel = usbnet_set_msglevel,
- .get_eeprom_len = dm9601_get_eeprom_len,
- .get_eeprom = dm9601_get_eeprom,
- .get_settings = usbnet_get_settings,
- .set_settings = usbnet_set_settings,
- .nway_reset = usbnet_nway_reset,
-};
-
-static void dm9601_set_multicast(struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
- /* We use the 20 byte dev->data for our 8 byte filter buffer
- * to avoid allocating memory that is tricky to free later */
- u8 *hashes = (u8 *) & dev->data;
- u8 rx_ctl = 0x31;
-
- memset(hashes, 0x00, DM_MCAST_SIZE);
- hashes[DM_MCAST_SIZE - 1] |= 0x80; /* broadcast address */
-
- if (net->flags & IFF_PROMISC) {
- rx_ctl |= 0x02;
- } else if (net->flags & IFF_ALLMULTI ||
- netdev_mc_count(net) > DM_MAX_MCAST) {
- rx_ctl |= 0x04;
- } else if (!netdev_mc_empty(net)) {
- struct netdev_hw_addr *ha;
-
- netdev_for_each_mc_addr(ha, net) {
- u32 crc = ether_crc(ETH_ALEN, ha->addr) >> 26;
- hashes[crc >> 3] |= 1 << (crc & 0x7);
- }
- }
-
- dm_write_async(dev, DM_MCAST_ADDR, DM_MCAST_SIZE, hashes);
- dm_write_reg_async(dev, DM_RX_CTRL, rx_ctl);
-}
-
-static void __dm9601_set_mac_address(struct usbnet *dev)
-{
- dm_write_async(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr);
-}
-
-static int dm9601_set_mac_address(struct net_device *net, void *p)
-{
- struct sockaddr *addr = p;
- struct usbnet *dev = netdev_priv(net);
-
- if (!is_valid_ether_addr(addr->sa_data)) {
- dev_err(&net->dev, "not setting invalid mac address %pM\n",
- addr->sa_data);
- return -EINVAL;
- }
-
- memcpy(net->dev_addr, addr->sa_data, net->addr_len);
- __dm9601_set_mac_address(dev);
-
- return 0;
-}
-
-static const struct net_device_ops dm9601_netdev_ops = {
- .ndo_open = usbnet_open,
- .ndo_stop = usbnet_stop,
- .ndo_start_xmit = usbnet_start_xmit,
- .ndo_tx_timeout = usbnet_tx_timeout,
- .ndo_change_mtu = usbnet_change_mtu,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_do_ioctl = dm9601_ioctl,
- .ndo_set_rx_mode = dm9601_set_multicast,
- .ndo_set_mac_address = dm9601_set_mac_address,
-};
-
-static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- int ret;
- u8 mac[ETH_ALEN];
-
- ret = usbnet_get_endpoints(dev, intf);
- if (ret)
- goto out;
-
- dev->net->netdev_ops = &dm9601_netdev_ops;
- dev->net->ethtool_ops = &dm9601_ethtool_ops;
- dev->net->hard_header_len += DM_TX_OVERHEAD;
- dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
- dev->rx_urb_size = dev->net->mtu + ETH_HLEN + DM_RX_OVERHEAD;
-
- dev->mii.dev = dev->net;
- dev->mii.mdio_read = dm9601_mdio_read;
- dev->mii.mdio_write = dm9601_mdio_write;
- dev->mii.phy_id_mask = 0x1f;
- dev->mii.reg_num_mask = 0x1f;
-
- /* reset */
- dm_write_reg(dev, DM_NET_CTRL, 1);
- udelay(20);
-
- /* read MAC */
- if (dm_read(dev, DM_PHY_ADDR, ETH_ALEN, mac) < 0) {
- printk(KERN_ERR "Error reading MAC address\n");
- ret = -ENODEV;
- goto out;
- }
-
- /*
- * Overwrite the auto-generated address only with good ones.
- */
- if (is_valid_ether_addr(mac))
- memcpy(dev->net->dev_addr, mac, ETH_ALEN);
- else {
- printk(KERN_WARNING
- "dm9601: No valid MAC address in EEPROM, using %pM\n",
- dev->net->dev_addr);
- __dm9601_set_mac_address(dev);
- }
-
- /* power up phy */
- dm_write_reg(dev, DM_GPR_CTRL, 1);
- dm_write_reg(dev, DM_GPR_DATA, 0);
-
- /* receive broadcast packets */
- dm9601_set_multicast(dev->net);
-
- dm9601_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
- dm9601_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
- ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
- mii_nway_restart(&dev->mii);
-
-out:
- return ret;
-}
-
-static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- u8 status;
- int len;
-
- /* format:
- b1: rx status
- b2: packet length (incl crc) low
- b3: packet length (incl crc) high
- b4..n-4: packet data
- bn-3..bn: ethernet crc
- */
-
- if (unlikely(skb->len < DM_RX_OVERHEAD)) {
- dev_err(&dev->udev->dev, "unexpected tiny rx frame\n");
- return 0;
- }
-
- status = skb->data[0];
- len = (skb->data[1] | (skb->data[2] << 8)) - 4;
-
- if (unlikely(status & 0xbf)) {
- if (status & 0x01) dev->net->stats.rx_fifo_errors++;
- if (status & 0x02) dev->net->stats.rx_crc_errors++;
- if (status & 0x04) dev->net->stats.rx_frame_errors++;
- if (status & 0x20) dev->net->stats.rx_missed_errors++;
- if (status & 0x90) dev->net->stats.rx_length_errors++;
- return 0;
- }
-
- skb_pull(skb, 3);
- skb_trim(skb, len);
-
- return 1;
-}
-
-static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
- gfp_t flags)
-{
- int len;
-
- /* format:
- b1: packet length low
- b2: packet length high
- b3..n: packet data
- */
-
- len = skb->len;
-
- if (skb_headroom(skb) < DM_TX_OVERHEAD) {
- struct sk_buff *skb2;
-
- skb2 = skb_copy_expand(skb, DM_TX_OVERHEAD, 0, flags);
- dev_kfree_skb_any(skb);
- skb = skb2;
- if (!skb)
- return NULL;
- }
-
- __skb_push(skb, DM_TX_OVERHEAD);
-
- /* usbnet adds padding if length is a multiple of packet size
- if so, adjust length value in header */
- if ((skb->len % dev->maxpacket) == 0)
- len++;
-
- skb->data[0] = len;
- skb->data[1] = len >> 8;
-
- return skb;
-}
-
-static void dm9601_status(struct usbnet *dev, struct urb *urb)
-{
- int link;
- u8 *buf;
-
- /* format:
- b0: net status
- b1: tx status 1
- b2: tx status 2
- b3: rx status
- b4: rx overflow
- b5: rx count
- b6: tx count
- b7: gpr
- */
-
- if (urb->actual_length < 8)
- return;
-
- buf = urb->transfer_buffer;
-
- link = !!(buf[0] & 0x40);
- if (netif_carrier_ok(dev->net) != link) {
- if (link) {
- netif_carrier_on(dev->net);
- usbnet_defer_kevent (dev, EVENT_LINK_RESET);
- }
- else
- netif_carrier_off(dev->net);
- netdev_dbg(dev->net, "Link Status is: %d\n", link);
- }
-}
-
-static int dm9601_link_reset(struct usbnet *dev)
-{
- struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
-
- mii_check_media(&dev->mii, 1, 1);
- mii_ethtool_gset(&dev->mii, &ecmd);
-
- netdev_dbg(dev->net, "link_reset() speed: %u duplex: %d\n",
- ethtool_cmd_speed(&ecmd), ecmd.duplex);
-
- return 0;
-}
-
-static const struct driver_info dm9601_info = {
- .description = "Davicom DM9601 USB Ethernet",
- .flags = FLAG_ETHER | FLAG_LINK_INTR,
- .bind = dm9601_bind,
- .rx_fixup = dm9601_rx_fixup,
- .tx_fixup = dm9601_tx_fixup,
- .status = dm9601_status,
- .link_reset = dm9601_link_reset,
- .reset = dm9601_link_reset,
-};
-
-static const struct usb_device_id products[] = {
- {
- USB_DEVICE(0x07aa, 0x9601), /* Corega FEther USB-TXC */
- .driver_info = (unsigned long)&dm9601_info,
- },
- {
- USB_DEVICE(0x0a46, 0x9601), /* Davicom USB-100 */
- .driver_info = (unsigned long)&dm9601_info,
- },
- {
- USB_DEVICE(0x0a46, 0x6688), /* ZT6688 USB NIC */
- .driver_info = (unsigned long)&dm9601_info,
- },
- {
- USB_DEVICE(0x0a46, 0x0268), /* ShanTou ST268 USB NIC */
- .driver_info = (unsigned long)&dm9601_info,
- },
- {
- USB_DEVICE(0x0a46, 0x8515), /* ADMtek ADM8515 USB NIC */
- .driver_info = (unsigned long)&dm9601_info,
- },
- {
- USB_DEVICE(0x0a47, 0x9601), /* Hirose USB-100 */
- .driver_info = (unsigned long)&dm9601_info,
- },
- {
- USB_DEVICE(0x0fe6, 0x8101), /* DM9601 USB to Fast Ethernet Adapter */
- .driver_info = (unsigned long)&dm9601_info,
- },
- {
- USB_DEVICE(0x0fe6, 0x9700), /* DM9601 USB to Fast Ethernet Adapter */
- .driver_info = (unsigned long)&dm9601_info,
- },
- {
- USB_DEVICE(0x0a46, 0x9000), /* DM9000E */
- .driver_info = (unsigned long)&dm9601_info,
- },
- {}, // END
-};
-
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver dm9601_driver = {
- .name = "dm9601",
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
-};
-
-module_usb_driver(dm9601_driver);
-
-MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
-MODULE_DESCRIPTION("Davicom DM9601 USB 1.1 ethernet devices");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/gl620a.c b/ANDROID_3.4.5/drivers/net/usb/gl620a.c
deleted file mode 100644
index 38266bda..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/gl620a.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * GeneSys GL620USB-A based links
- * Copyright (C) 2001 by Jiun-Jie Huang <huangjj@genesyslogic.com.tw>
- * Copyright (C) 2001 by Stanislav Brabec <utx@penguin.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-// #define DEBUG // error path messages, extra info
-// #define VERBOSE // more; success messages
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/workqueue.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/usb/usbnet.h>
-#include <linux/gfp.h>
-
-
-/*
- * GeneSys GL620USB-A (www.genesyslogic.com.tw)
- *
- * ... should partially interop with the Win32 driver for this hardware.
- * The GeneSys docs imply there's some NDIS issue motivating this framing.
- *
- * Some info from GeneSys:
- * - GL620USB-A is full duplex; GL620USB is only half duplex for bulk.
- * (Some cables, like the BAFO-100c, use the half duplex version.)
- * - For the full duplex model, the low bit of the version code says
- * which side is which ("left/right").
- * - For the half duplex type, a control/interrupt handshake settles
- * the transfer direction. (That's disabled here, partially coded.)
- * A control URB would block until other side writes an interrupt.
- *
- * Original code from Jiun-Jie Huang <huangjj@genesyslogic.com.tw>
- * and merged into "usbnet" by Stanislav Brabec <utx@penguin.cz>.
- */
-
-// control msg write command
-#define GENELINK_CONNECT_WRITE 0xF0
-// interrupt pipe index
-#define GENELINK_INTERRUPT_PIPE 0x03
-// interrupt read buffer size
-#define INTERRUPT_BUFSIZE 0x08
-// interrupt pipe interval value
-#define GENELINK_INTERRUPT_INTERVAL 0x10
-// max transmit packet number per transmit
-#define GL_MAX_TRANSMIT_PACKETS 32
-// max packet length
-#define GL_MAX_PACKET_LEN 1514
-// max receive buffer size
-#define GL_RCV_BUF_SIZE \
- (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4)
-
-struct gl_packet {
- __le32 packet_length;
- char packet_data [1];
-};
-
-struct gl_header {
- __le32 packet_count;
- struct gl_packet packets;
-};
-
-static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- struct gl_header *header;
- struct gl_packet *packet;
- struct sk_buff *gl_skb;
- u32 size;
- u32 count;
-
- header = (struct gl_header *) skb->data;
-
- // get the packet count of the received skb
- count = le32_to_cpu(header->packet_count);
- if (count > GL_MAX_TRANSMIT_PACKETS) {
- dbg("genelink: invalid received packet count %u", count);
- return 0;
- }
-
- // set the current packet pointer to the first packet
- packet = &header->packets;
-
- // decrement the length for the packet count size 4 bytes
- skb_pull(skb, 4);
-
- while (count > 1) {
- // get the packet length
- size = le32_to_cpu(packet->packet_length);
-
- // this may be a broken packet
- if (size > GL_MAX_PACKET_LEN) {
- dbg("genelink: invalid rx length %d", size);
- return 0;
- }
-
- // allocate the skb for the individual packet
- gl_skb = alloc_skb(size, GFP_ATOMIC);
- if (gl_skb) {
-
- // copy the packet data to the new skb
- memcpy(skb_put(gl_skb, size),
- packet->packet_data, size);
- usbnet_skb_return(dev, gl_skb);
- }
-
- // advance to the next packet
- packet = (struct gl_packet *)&packet->packet_data[size];
- count--;
-
- // shift the data pointer to the next gl_packet
- skb_pull(skb, size + 4);
- }
-
- // skip the packet length field 4 bytes
- skb_pull(skb, 4);
-
- if (skb->len > GL_MAX_PACKET_LEN) {
- dbg("genelink: invalid rx length %d", skb->len);
- return 0;
- }
- return 1;
-}
-
-static struct sk_buff *
-genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
-{
- int padlen;
- int length = skb->len;
- int headroom = skb_headroom(skb);
- int tailroom = skb_tailroom(skb);
- __le32 *packet_count;
- __le32 *packet_len;
-
- // FIXME: magic numbers, bleech
- padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1;
-
- if ((!skb_cloned(skb))
- && ((headroom + tailroom) >= (padlen + (4 + 4*1)))) {
- if ((headroom < (4 + 4*1)) || (tailroom < padlen)) {
- skb->data = memmove(skb->head + (4 + 4*1),
- skb->data, skb->len);
- skb_set_tail_pointer(skb, skb->len);
- }
- } else {
- struct sk_buff *skb2;
- skb2 = skb_copy_expand(skb, (4 + 4*1) , padlen, flags);
- dev_kfree_skb_any(skb);
- skb = skb2;
- if (!skb)
- return NULL;
- }
-
- // attach the packet count to the header
- packet_count = (__le32 *) skb_push(skb, (4 + 4*1));
- packet_len = packet_count + 1;
-
- *packet_count = cpu_to_le32(1);
- *packet_len = cpu_to_le32(length);
-
- // add padding byte
- if ((skb->len % dev->maxpacket) == 0)
- skb_put(skb, 1);
-
- return skb;
-}
-
-static int genelink_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- dev->hard_mtu = GL_RCV_BUF_SIZE;
- dev->net->hard_header_len += 4;
- dev->in = usb_rcvbulkpipe(dev->udev, dev->driver_info->in);
- dev->out = usb_sndbulkpipe(dev->udev, dev->driver_info->out);
- return 0;
-}
-
-static const struct driver_info genelink_info = {
- .description = "Genesys GeneLink",
- .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_GL | FLAG_NO_SETINT,
- .bind = genelink_bind,
- .rx_fixup = genelink_rx_fixup,
- .tx_fixup = genelink_tx_fixup,
-
- .in = 1, .out = 2,
-
-#ifdef GENELINK_ACK
- .check_connect =genelink_check_connect,
-#endif
-};
-
-static const struct usb_device_id products [] = {
-
-{
- USB_DEVICE(0x05e3, 0x0502), // GL620USB-A
- .driver_info = (unsigned long) &genelink_info,
-},
- /* NOT: USB_DEVICE(0x05e3, 0x0501), // GL620USB
- * that's half duplex, not currently supported
- */
- { }, // END
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver gl620a_driver = {
- .name = "gl620a",
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
-};
-
-module_usb_driver(gl620a_driver);
-
-MODULE_AUTHOR("Jiun-Jie Huang");
-MODULE_DESCRIPTION("GL620-USB-A Host-to-Host Link cables");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/drivers/net/usb/hso.c b/ANDROID_3.4.5/drivers/net/usb/hso.c
deleted file mode 100644
index 2d2a6882..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/hso.c
+++ /dev/null
@@ -1,3380 +0,0 @@
-/******************************************************************************
- *
- * Driver for Option High Speed Mobile Devices.
- *
- * Copyright (C) 2008 Option International
- * Filip Aben <f.aben@option.com>
- * Denis Joseph Barrow <d.barow@option.com>
- * Jan Dumon <j.dumon@option.com>
- * Copyright (C) 2007 Andrew Bird (Sphere Systems Ltd)
- * <ajb@spheresystems.co.uk>
- * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de>
- * Copyright (C) 2008 Novell, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA
- *
- *
- *****************************************************************************/
-
-/******************************************************************************
- *
- * Description of the device:
- *
- * Interface 0: Contains the IP network interface on the bulk end points.
- * The multiplexed serial ports are using the interrupt and
- * control endpoints.
- * Interrupt contains a bitmap telling which multiplexed
- * serialport needs servicing.
- *
- * Interface 1: Diagnostics port, uses bulk only, do not submit urbs until the
- * port is opened, as this have a huge impact on the network port
- * throughput.
- *
- * Interface 2: Standard modem interface - circuit switched interface, this
- * can be used to make a standard ppp connection however it
- * should not be used in conjunction with the IP network interface
- * enabled for USB performance reasons i.e. if using this set
- * ideally disable_net=1.
- *
- *****************************************************************************/
-
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/module.h>
-#include <linux/ethtool.h>
-#include <linux/usb.h>
-#include <linux/timer.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/tty_flip.h>
-#include <linux/kmod.h>
-#include <linux/rfkill.h>
-#include <linux/ip.h>
-#include <linux/uaccess.h>
-#include <linux/usb/cdc.h>
-#include <net/arp.h>
-#include <asm/byteorder.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-
-
-#define MOD_AUTHOR "Option Wireless"
-#define MOD_DESCRIPTION "USB High Speed Option driver"
-#define MOD_LICENSE "GPL"
-
-#define HSO_MAX_NET_DEVICES 10
-#define HSO__MAX_MTU 2048
-#define DEFAULT_MTU 1500
-#define DEFAULT_MRU 1500
-
-#define CTRL_URB_RX_SIZE 1024
-#define CTRL_URB_TX_SIZE 64
-
-#define BULK_URB_RX_SIZE 4096
-#define BULK_URB_TX_SIZE 8192
-
-#define MUX_BULK_RX_BUF_SIZE HSO__MAX_MTU
-#define MUX_BULK_TX_BUF_SIZE HSO__MAX_MTU
-#define MUX_BULK_RX_BUF_COUNT 4
-#define USB_TYPE_OPTION_VENDOR 0x20
-
-/* These definitions are used with the struct hso_net flags element */
-/* - use *_bit operations on it. (bit indices not values.) */
-#define HSO_NET_RUNNING 0
-
-#define HSO_NET_TX_TIMEOUT (HZ*10)
-
-#define HSO_SERIAL_MAGIC 0x48534f31
-
-/* Number of ttys to handle */
-#define HSO_SERIAL_TTY_MINORS 256
-
-#define MAX_RX_URBS 2
-
-static inline struct hso_serial *get_serial_by_tty(struct tty_struct *tty)
-{
- if (tty)
- return tty->driver_data;
- return NULL;
-}
-
-/*****************************************************************************/
-/* Debugging functions */
-/*****************************************************************************/
-#define D__(lvl_, fmt, arg...) \
- do { \
- printk(lvl_ "[%d:%s]: " fmt "\n", \
- __LINE__, __func__, ## arg); \
- } while (0)
-
-#define D_(lvl, args...) \
- do { \
- if (lvl & debug) \
- D__(KERN_INFO, args); \
- } while (0)
-
-#define D1(args...) D_(0x01, ##args)
-#define D2(args...) D_(0x02, ##args)
-#define D3(args...) D_(0x04, ##args)
-#define D4(args...) D_(0x08, ##args)
-#define D5(args...) D_(0x10, ##args)
-
-/*****************************************************************************/
-/* Enumerators */
-/*****************************************************************************/
-enum pkt_parse_state {
- WAIT_IP,
- WAIT_DATA,
- WAIT_SYNC
-};
-
-/*****************************************************************************/
-/* Structs */
-/*****************************************************************************/
-
-struct hso_shared_int {
- struct usb_endpoint_descriptor *intr_endp;
- void *shared_intr_buf;
- struct urb *shared_intr_urb;
- struct usb_device *usb;
- int use_count;
- int ref_count;
- struct mutex shared_int_lock;
-};
-
-struct hso_net {
- struct hso_device *parent;
- struct net_device *net;
- struct rfkill *rfkill;
-
- struct usb_endpoint_descriptor *in_endp;
- struct usb_endpoint_descriptor *out_endp;
-
- struct urb *mux_bulk_rx_urb_pool[MUX_BULK_RX_BUF_COUNT];
- struct urb *mux_bulk_tx_urb;
- void *mux_bulk_rx_buf_pool[MUX_BULK_RX_BUF_COUNT];
- void *mux_bulk_tx_buf;
-
- struct sk_buff *skb_rx_buf;
- struct sk_buff *skb_tx_buf;
-
- enum pkt_parse_state rx_parse_state;
- spinlock_t net_lock;
-
- unsigned short rx_buf_size;
- unsigned short rx_buf_missing;
- struct iphdr rx_ip_hdr;
-
- unsigned long flags;
-};
-
-enum rx_ctrl_state{
- RX_IDLE,
- RX_SENT,
- RX_PENDING
-};
-
-#define BM_REQUEST_TYPE (0xa1)
-#define B_NOTIFICATION (0x20)
-#define W_VALUE (0x0)
-#define W_INDEX (0x2)
-#define W_LENGTH (0x2)
-
-#define B_OVERRUN (0x1<<6)
-#define B_PARITY (0x1<<5)
-#define B_FRAMING (0x1<<4)
-#define B_RING_SIGNAL (0x1<<3)
-#define B_BREAK (0x1<<2)
-#define B_TX_CARRIER (0x1<<1)
-#define B_RX_CARRIER (0x1<<0)
-
-struct hso_serial_state_notification {
- u8 bmRequestType;
- u8 bNotification;
- u16 wValue;
- u16 wIndex;
- u16 wLength;
- u16 UART_state_bitmap;
-} __packed;
-
-struct hso_tiocmget {
- struct mutex mutex;
- wait_queue_head_t waitq;
- int intr_completed;
- struct usb_endpoint_descriptor *endp;
- struct urb *urb;
- struct hso_serial_state_notification serial_state_notification;
- u16 prev_UART_state_bitmap;
- struct uart_icount icount;
-};
-
-
-struct hso_serial {
- struct hso_device *parent;
- int magic;
- u8 minor;
-
- struct hso_shared_int *shared_int;
-
- /* rx/tx urb could be either a bulk urb or a control urb depending
- on which serial port it is used on. */
- struct urb *rx_urb[MAX_RX_URBS];
- u8 num_rx_urbs;
- u8 *rx_data[MAX_RX_URBS];
- u16 rx_data_length; /* should contain allocated length */
-
- struct urb *tx_urb;
- u8 *tx_data;
- u8 *tx_buffer;
- u16 tx_data_length; /* should contain allocated length */
- u16 tx_data_count;
- u16 tx_buffer_count;
- struct usb_ctrlrequest ctrl_req_tx;
- struct usb_ctrlrequest ctrl_req_rx;
-
- struct usb_endpoint_descriptor *in_endp;
- struct usb_endpoint_descriptor *out_endp;
-
- enum rx_ctrl_state rx_state;
- u8 rts_state;
- u8 dtr_state;
- unsigned tx_urb_used:1;
-
- /* from usb_serial_port */
- struct tty_struct *tty;
- int open_count;
- spinlock_t serial_lock;
-
- int (*write_data) (struct hso_serial *serial);
- struct hso_tiocmget *tiocmget;
- /* Hacks required to get flow control
- * working on the serial receive buffers
- * so as not to drop characters on the floor.
- */
- int curr_rx_urb_idx;
- u16 curr_rx_urb_offset;
- u8 rx_urb_filled[MAX_RX_URBS];
- struct tasklet_struct unthrottle_tasklet;
- struct work_struct retry_unthrottle_workqueue;
-};
-
-struct hso_device {
- union {
- struct hso_serial *dev_serial;
- struct hso_net *dev_net;
- } port_data;
-
- u32 port_spec;
-
- u8 is_active;
- u8 usb_gone;
- struct work_struct async_get_intf;
- struct work_struct async_put_intf;
- struct work_struct reset_device;
-
- struct usb_device *usb;
- struct usb_interface *interface;
-
- struct device *dev;
- struct kref ref;
- struct mutex mutex;
-};
-
-/* Type of interface */
-#define HSO_INTF_MASK 0xFF00
-#define HSO_INTF_MUX 0x0100
-#define HSO_INTF_BULK 0x0200
-
-/* Type of port */
-#define HSO_PORT_MASK 0xFF
-#define HSO_PORT_NO_PORT 0x0
-#define HSO_PORT_CONTROL 0x1
-#define HSO_PORT_APP 0x2
-#define HSO_PORT_GPS 0x3
-#define HSO_PORT_PCSC 0x4
-#define HSO_PORT_APP2 0x5
-#define HSO_PORT_GPS_CONTROL 0x6
-#define HSO_PORT_MSD 0x7
-#define HSO_PORT_VOICE 0x8
-#define HSO_PORT_DIAG2 0x9
-#define HSO_PORT_DIAG 0x10
-#define HSO_PORT_MODEM 0x11
-#define HSO_PORT_NETWORK 0x12
-
-/* Additional device info */
-#define HSO_INFO_MASK 0xFF000000
-#define HSO_INFO_CRC_BUG 0x01000000
-
-/*****************************************************************************/
-/* Prototypes */
-/*****************************************************************************/
-/* Serial driver functions */
-static int hso_serial_tiocmset(struct tty_struct *tty,
- unsigned int set, unsigned int clear);
-static void ctrl_callback(struct urb *urb);
-static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial);
-static void hso_kick_transmit(struct hso_serial *serial);
-/* Helper functions */
-static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int,
- struct usb_device *usb, gfp_t gfp);
-static void handle_usb_error(int status, const char *function,
- struct hso_device *hso_dev);
-static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf,
- int type, int dir);
-static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports);
-static void hso_free_interface(struct usb_interface *intf);
-static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags);
-static int hso_stop_serial_device(struct hso_device *hso_dev);
-static int hso_start_net_device(struct hso_device *hso_dev);
-static void hso_free_shared_int(struct hso_shared_int *shared_int);
-static int hso_stop_net_device(struct hso_device *hso_dev);
-static void hso_serial_ref_free(struct kref *ref);
-static void hso_std_serial_read_bulk_callback(struct urb *urb);
-static int hso_mux_serial_read(struct hso_serial *serial);
-static void async_get_intf(struct work_struct *data);
-static void async_put_intf(struct work_struct *data);
-static int hso_put_activity(struct hso_device *hso_dev);
-static int hso_get_activity(struct hso_device *hso_dev);
-static void tiocmget_intr_callback(struct urb *urb);
-static void reset_device(struct work_struct *data);
-/*****************************************************************************/
-/* Helping functions */
-/*****************************************************************************/
-
-/* #define DEBUG */
-
-static inline struct hso_net *dev2net(struct hso_device *hso_dev)
-{
- return hso_dev->port_data.dev_net;
-}
-
-static inline struct hso_serial *dev2ser(struct hso_device *hso_dev)
-{
- return hso_dev->port_data.dev_serial;
-}
-
-/* Debugging functions */
-#ifdef DEBUG
-static void dbg_dump(int line_count, const char *func_name, unsigned char *buf,
- unsigned int len)
-{
- static char name[255];
-
- sprintf(name, "hso[%d:%s]", line_count, func_name);
- print_hex_dump_bytes(name, DUMP_PREFIX_NONE, buf, len);
-}
-
-#define DUMP(buf_, len_) \
- dbg_dump(__LINE__, __func__, (unsigned char *)buf_, len_)
-
-#define DUMP1(buf_, len_) \
- do { \
- if (0x01 & debug) \
- DUMP(buf_, len_); \
- } while (0)
-#else
-#define DUMP(buf_, len_)
-#define DUMP1(buf_, len_)
-#endif
-
-/* module parameters */
-static int debug;
-static int tty_major;
-static int disable_net;
-
-/* driver info */
-static const char driver_name[] = "hso";
-static const char tty_filename[] = "ttyHS";
-static const char *version = __FILE__ ": " MOD_AUTHOR;
-/* the usb driver itself (registered in hso_init) */
-static struct usb_driver hso_driver;
-/* serial structures */
-static struct tty_driver *tty_drv;
-static struct hso_device *serial_table[HSO_SERIAL_TTY_MINORS];
-static struct hso_device *network_table[HSO_MAX_NET_DEVICES];
-static spinlock_t serial_table_lock;
-
-static const s32 default_port_spec[] = {
- HSO_INTF_MUX | HSO_PORT_NETWORK,
- HSO_INTF_BULK | HSO_PORT_DIAG,
- HSO_INTF_BULK | HSO_PORT_MODEM,
- 0
-};
-
-static const s32 icon321_port_spec[] = {
- HSO_INTF_MUX | HSO_PORT_NETWORK,
- HSO_INTF_BULK | HSO_PORT_DIAG2,
- HSO_INTF_BULK | HSO_PORT_MODEM,
- HSO_INTF_BULK | HSO_PORT_DIAG,
- 0
-};
-
-#define default_port_device(vendor, product) \
- USB_DEVICE(vendor, product), \
- .driver_info = (kernel_ulong_t)default_port_spec
-
-#define icon321_port_device(vendor, product) \
- USB_DEVICE(vendor, product), \
- .driver_info = (kernel_ulong_t)icon321_port_spec
-
-/* list of devices we support */
-static const struct usb_device_id hso_ids[] = {
- {default_port_device(0x0af0, 0x6711)},
- {default_port_device(0x0af0, 0x6731)},
- {default_port_device(0x0af0, 0x6751)},
- {default_port_device(0x0af0, 0x6771)},
- {default_port_device(0x0af0, 0x6791)},
- {default_port_device(0x0af0, 0x6811)},
- {default_port_device(0x0af0, 0x6911)},
- {default_port_device(0x0af0, 0x6951)},
- {default_port_device(0x0af0, 0x6971)},
- {default_port_device(0x0af0, 0x7011)},
- {default_port_device(0x0af0, 0x7031)},
- {default_port_device(0x0af0, 0x7051)},
- {default_port_device(0x0af0, 0x7071)},
- {default_port_device(0x0af0, 0x7111)},
- {default_port_device(0x0af0, 0x7211)},
- {default_port_device(0x0af0, 0x7251)},
- {default_port_device(0x0af0, 0x7271)},
- {default_port_device(0x0af0, 0x7311)},
- {default_port_device(0x0af0, 0xc031)}, /* Icon-Edge */
- {icon321_port_device(0x0af0, 0xd013)}, /* Module HSxPA */
- {icon321_port_device(0x0af0, 0xd031)}, /* Icon-321 */
- {icon321_port_device(0x0af0, 0xd033)}, /* Icon-322 */
- {USB_DEVICE(0x0af0, 0x7301)}, /* GE40x */
- {USB_DEVICE(0x0af0, 0x7361)}, /* GE40x */
- {USB_DEVICE(0x0af0, 0x7381)}, /* GE40x */
- {USB_DEVICE(0x0af0, 0x7401)}, /* GI 0401 */
- {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */
- {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */
- {USB_DEVICE(0x0af0, 0x7701)},
- {USB_DEVICE(0x0af0, 0x7706)},
- {USB_DEVICE(0x0af0, 0x7801)},
- {USB_DEVICE(0x0af0, 0x7901)},
- {USB_DEVICE(0x0af0, 0x7A01)},
- {USB_DEVICE(0x0af0, 0x7A05)},
- {USB_DEVICE(0x0af0, 0x8200)},
- {USB_DEVICE(0x0af0, 0x8201)},
- {USB_DEVICE(0x0af0, 0x8300)},
- {USB_DEVICE(0x0af0, 0x8302)},
- {USB_DEVICE(0x0af0, 0x8304)},
- {USB_DEVICE(0x0af0, 0x8400)},
- {USB_DEVICE(0x0af0, 0x8600)},
- {USB_DEVICE(0x0af0, 0x8800)},
- {USB_DEVICE(0x0af0, 0x8900)},
- {USB_DEVICE(0x0af0, 0x9000)},
- {USB_DEVICE(0x0af0, 0xd035)},
- {USB_DEVICE(0x0af0, 0xd055)},
- {USB_DEVICE(0x0af0, 0xd155)},
- {USB_DEVICE(0x0af0, 0xd255)},
- {USB_DEVICE(0x0af0, 0xd057)},
- {USB_DEVICE(0x0af0, 0xd157)},
- {USB_DEVICE(0x0af0, 0xd257)},
- {USB_DEVICE(0x0af0, 0xd357)},
- {USB_DEVICE(0x0af0, 0xd058)},
- {USB_DEVICE(0x0af0, 0xc100)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, hso_ids);
-
-/* Sysfs attribute */
-static ssize_t hso_sysfs_show_porttype(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hso_device *hso_dev = dev_get_drvdata(dev);
- char *port_name;
-
- if (!hso_dev)
- return 0;
-
- switch (hso_dev->port_spec & HSO_PORT_MASK) {
- case HSO_PORT_CONTROL:
- port_name = "Control";
- break;
- case HSO_PORT_APP:
- port_name = "Application";
- break;
- case HSO_PORT_APP2:
- port_name = "Application2";
- break;
- case HSO_PORT_GPS:
- port_name = "GPS";
- break;
- case HSO_PORT_GPS_CONTROL:
- port_name = "GPS Control";
- break;
- case HSO_PORT_PCSC:
- port_name = "PCSC";
- break;
- case HSO_PORT_DIAG:
- port_name = "Diagnostic";
- break;
- case HSO_PORT_DIAG2:
- port_name = "Diagnostic2";
- break;
- case HSO_PORT_MODEM:
- port_name = "Modem";
- break;
- case HSO_PORT_NETWORK:
- port_name = "Network";
- break;
- default:
- port_name = "Unknown";
- break;
- }
-
- return sprintf(buf, "%s\n", port_name);
-}
-static DEVICE_ATTR(hsotype, S_IRUGO, hso_sysfs_show_porttype, NULL);
-
-static int hso_urb_to_index(struct hso_serial *serial, struct urb *urb)
-{
- int idx;
-
- for (idx = 0; idx < serial->num_rx_urbs; idx++)
- if (serial->rx_urb[idx] == urb)
- return idx;
- dev_err(serial->parent->dev, "hso_urb_to_index failed\n");
- return -1;
-}
-
-/* converts mux value to a port spec value */
-static u32 hso_mux_to_port(int mux)
-{
- u32 result;
-
- switch (mux) {
- case 0x1:
- result = HSO_PORT_CONTROL;
- break;
- case 0x2:
- result = HSO_PORT_APP;
- break;
- case 0x4:
- result = HSO_PORT_PCSC;
- break;
- case 0x8:
- result = HSO_PORT_GPS;
- break;
- case 0x10:
- result = HSO_PORT_APP2;
- break;
- default:
- result = HSO_PORT_NO_PORT;
- }
- return result;
-}
-
-/* converts port spec value to a mux value */
-static u32 hso_port_to_mux(int port)
-{
- u32 result;
-
- switch (port & HSO_PORT_MASK) {
- case HSO_PORT_CONTROL:
- result = 0x0;
- break;
- case HSO_PORT_APP:
- result = 0x1;
- break;
- case HSO_PORT_PCSC:
- result = 0x2;
- break;
- case HSO_PORT_GPS:
- result = 0x3;
- break;
- case HSO_PORT_APP2:
- result = 0x4;
- break;
- default:
- result = 0x0;
- }
- return result;
-}
-
-static struct hso_serial *get_serial_by_shared_int_and_type(
- struct hso_shared_int *shared_int,
- int mux)
-{
- int i, port;
-
- port = hso_mux_to_port(mux);
-
- for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
- if (serial_table[i] &&
- (dev2ser(serial_table[i])->shared_int == shared_int) &&
- ((serial_table[i]->port_spec & HSO_PORT_MASK) == port)) {
- return dev2ser(serial_table[i]);
- }
- }
-
- return NULL;
-}
-
-static struct hso_serial *get_serial_by_index(unsigned index)
-{
- struct hso_serial *serial = NULL;
- unsigned long flags;
-
- spin_lock_irqsave(&serial_table_lock, flags);
- if (serial_table[index])
- serial = dev2ser(serial_table[index]);
- spin_unlock_irqrestore(&serial_table_lock, flags);
-
- return serial;
-}
-
-static int get_free_serial_index(void)
-{
- int index;
- unsigned long flags;
-
- spin_lock_irqsave(&serial_table_lock, flags);
- for (index = 0; index < HSO_SERIAL_TTY_MINORS; index++) {
- if (serial_table[index] == NULL) {
- spin_unlock_irqrestore(&serial_table_lock, flags);
- return index;
- }
- }
- spin_unlock_irqrestore(&serial_table_lock, flags);
-
- printk(KERN_ERR "%s: no free serial devices in table\n", __func__);
- return -1;
-}
-
-static void set_serial_by_index(unsigned index, struct hso_serial *serial)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&serial_table_lock, flags);
- if (serial)
- serial_table[index] = serial->parent;
- else
- serial_table[index] = NULL;
- spin_unlock_irqrestore(&serial_table_lock, flags);
-}
-
-static void handle_usb_error(int status, const char *function,
- struct hso_device *hso_dev)
-{
- char *explanation;
-
- switch (status) {
- case -ENODEV:
- explanation = "no device";
- break;
- case -ENOENT:
- explanation = "endpoint not enabled";
- break;
- case -EPIPE:
- explanation = "endpoint stalled";
- break;
- case -ENOSPC:
- explanation = "not enough bandwidth";
- break;
- case -ESHUTDOWN:
- explanation = "device disabled";
- break;
- case -EHOSTUNREACH:
- explanation = "device suspended";
- break;
- case -EINVAL:
- case -EAGAIN:
- case -EFBIG:
- case -EMSGSIZE:
- explanation = "internal error";
- break;
- case -EILSEQ:
- case -EPROTO:
- case -ETIME:
- case -ETIMEDOUT:
- explanation = "protocol error";
- if (hso_dev)
- schedule_work(&hso_dev->reset_device);
- break;
- default:
- explanation = "unknown status";
- break;
- }
-
- /* log a meaningful explanation of an USB status */
- D1("%s: received USB status - %s (%d)", function, explanation, status);
-}
-
-/* Network interface functions */
-
-/* called when net interface is brought up by ifconfig */
-static int hso_net_open(struct net_device *net)
-{
- struct hso_net *odev = netdev_priv(net);
- unsigned long flags = 0;
-
- if (!odev) {
- dev_err(&net->dev, "No net device !\n");
- return -ENODEV;
- }
-
- odev->skb_tx_buf = NULL;
-
- /* setup environment */
- spin_lock_irqsave(&odev->net_lock, flags);
- odev->rx_parse_state = WAIT_IP;
- odev->rx_buf_size = 0;
- odev->rx_buf_missing = sizeof(struct iphdr);
- spin_unlock_irqrestore(&odev->net_lock, flags);
-
- /* We are up and running. */
- set_bit(HSO_NET_RUNNING, &odev->flags);
- hso_start_net_device(odev->parent);
-
- /* Tell the kernel we are ready to start receiving from it */
- netif_start_queue(net);
-
- return 0;
-}
-
-/* called when interface is brought down by ifconfig */
-static int hso_net_close(struct net_device *net)
-{
- struct hso_net *odev = netdev_priv(net);
-
- /* we don't need the queue anymore */
- netif_stop_queue(net);
- /* no longer running */
- clear_bit(HSO_NET_RUNNING, &odev->flags);
-
- hso_stop_net_device(odev->parent);
-
- /* done */
- return 0;
-}
-
-/* USB tells is xmit done, we should start the netqueue again */
-static void write_bulk_callback(struct urb *urb)
-{
- struct hso_net *odev = urb->context;
- int status = urb->status;
-
- /* Sanity check */
- if (!odev || !test_bit(HSO_NET_RUNNING, &odev->flags)) {
- dev_err(&urb->dev->dev, "%s: device not running\n", __func__);
- return;
- }
-
- /* Do we still have a valid kernel network device? */
- if (!netif_device_present(odev->net)) {
- dev_err(&urb->dev->dev, "%s: net device not present\n",
- __func__);
- return;
- }
-
- /* log status, but don't act on it, we don't need to resubmit anything
- * anyhow */
- if (status)
- handle_usb_error(status, __func__, odev->parent);
-
- hso_put_activity(odev->parent);
-
- /* Tell the network interface we are ready for another frame */
- netif_wake_queue(odev->net);
-}
-
-/* called by kernel when we need to transmit a packet */
-static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb,
- struct net_device *net)
-{
- struct hso_net *odev = netdev_priv(net);
- int result;
-
- /* Tell the kernel, "No more frames 'til we are done with this one." */
- netif_stop_queue(net);
- if (hso_get_activity(odev->parent) == -EAGAIN) {
- odev->skb_tx_buf = skb;
- return NETDEV_TX_OK;
- }
-
- /* log if asked */
- DUMP1(skb->data, skb->len);
- /* Copy it from kernel memory to OUR memory */
- memcpy(odev->mux_bulk_tx_buf, skb->data, skb->len);
- D1("len: %d/%d", skb->len, MUX_BULK_TX_BUF_SIZE);
-
- /* Fill in the URB for shipping it out. */
- usb_fill_bulk_urb(odev->mux_bulk_tx_urb,
- odev->parent->usb,
- usb_sndbulkpipe(odev->parent->usb,
- odev->out_endp->
- bEndpointAddress & 0x7F),
- odev->mux_bulk_tx_buf, skb->len, write_bulk_callback,
- odev);
-
- /* Deal with the Zero Length packet problem, I hope */
- odev->mux_bulk_tx_urb->transfer_flags |= URB_ZERO_PACKET;
-
- /* Send the URB on its merry way. */
- result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC);
- if (result) {
- dev_warn(&odev->parent->interface->dev,
- "failed mux_bulk_tx_urb %d\n", result);
- net->stats.tx_errors++;
- netif_start_queue(net);
- } else {
- net->stats.tx_packets++;
- net->stats.tx_bytes += skb->len;
- }
- dev_kfree_skb(skb);
- /* we're done */
- return NETDEV_TX_OK;
-}
-
-static const struct ethtool_ops ops = {
- .get_link = ethtool_op_get_link
-};
-
-/* called when a packet did not ack after watchdogtimeout */
-static void hso_net_tx_timeout(struct net_device *net)
-{
- struct hso_net *odev = netdev_priv(net);
-
- if (!odev)
- return;
-
- /* Tell syslog we are hosed. */
- dev_warn(&net->dev, "Tx timed out.\n");
-
- /* Tear the waiting frame off the list */
- if (odev->mux_bulk_tx_urb &&
- (odev->mux_bulk_tx_urb->status == -EINPROGRESS))
- usb_unlink_urb(odev->mux_bulk_tx_urb);
-
- /* Update statistics */
- net->stats.tx_errors++;
-}
-
-/* make a real packet from the received USB buffer */
-static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
- unsigned int count, unsigned char is_eop)
-{
- unsigned short temp_bytes;
- unsigned short buffer_offset = 0;
- unsigned short frame_len;
- unsigned char *tmp_rx_buf;
-
- /* log if needed */
- D1("Rx %d bytes", count);
- DUMP(ip_pkt, min(128, (int)count));
-
- while (count) {
- switch (odev->rx_parse_state) {
- case WAIT_IP:
- /* waiting for IP header. */
- /* wanted bytes - size of ip header */
- temp_bytes =
- (count <
- odev->rx_buf_missing) ? count : odev->
- rx_buf_missing;
-
- memcpy(((unsigned char *)(&odev->rx_ip_hdr)) +
- odev->rx_buf_size, ip_pkt + buffer_offset,
- temp_bytes);
-
- odev->rx_buf_size += temp_bytes;
- buffer_offset += temp_bytes;
- odev->rx_buf_missing -= temp_bytes;
- count -= temp_bytes;
-
- if (!odev->rx_buf_missing) {
- /* header is complete allocate an sk_buffer and
- * continue to WAIT_DATA */
- frame_len = ntohs(odev->rx_ip_hdr.tot_len);
-
- if ((frame_len > DEFAULT_MRU) ||
- (frame_len < sizeof(struct iphdr))) {
- dev_err(&odev->net->dev,
- "Invalid frame (%d) length\n",
- frame_len);
- odev->rx_parse_state = WAIT_SYNC;
- continue;
- }
- /* Allocate an sk_buff */
- odev->skb_rx_buf = netdev_alloc_skb(odev->net,
- frame_len);
- if (!odev->skb_rx_buf) {
- /* We got no receive buffer. */
- D1("could not allocate memory");
- odev->rx_parse_state = WAIT_SYNC;
- return;
- }
-
- /* Copy what we got so far. make room for iphdr
- * after tail. */
- tmp_rx_buf =
- skb_put(odev->skb_rx_buf,
- sizeof(struct iphdr));
- memcpy(tmp_rx_buf, (char *)&(odev->rx_ip_hdr),
- sizeof(struct iphdr));
-
- /* ETH_HLEN */
- odev->rx_buf_size = sizeof(struct iphdr);
-
- /* Filip actually use .tot_len */
- odev->rx_buf_missing =
- frame_len - sizeof(struct iphdr);
- odev->rx_parse_state = WAIT_DATA;
- }
- break;
-
- case WAIT_DATA:
- temp_bytes = (count < odev->rx_buf_missing)
- ? count : odev->rx_buf_missing;
-
- /* Copy the rest of the bytes that are left in the
- * buffer into the waiting sk_buf. */
- /* Make room for temp_bytes after tail. */
- tmp_rx_buf = skb_put(odev->skb_rx_buf, temp_bytes);
- memcpy(tmp_rx_buf, ip_pkt + buffer_offset, temp_bytes);
-
- odev->rx_buf_missing -= temp_bytes;
- count -= temp_bytes;
- buffer_offset += temp_bytes;
- odev->rx_buf_size += temp_bytes;
- if (!odev->rx_buf_missing) {
- /* Packet is complete. Inject into stack. */
- /* We have IP packet here */
- odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP);
- skb_reset_mac_header(odev->skb_rx_buf);
-
- /* Ship it off to the kernel */
- netif_rx(odev->skb_rx_buf);
- /* No longer our buffer. */
- odev->skb_rx_buf = NULL;
-
- /* update out statistics */
- odev->net->stats.rx_packets++;
-
- odev->net->stats.rx_bytes += odev->rx_buf_size;
-
- odev->rx_buf_size = 0;
- odev->rx_buf_missing = sizeof(struct iphdr);
- odev->rx_parse_state = WAIT_IP;
- }
- break;
-
- case WAIT_SYNC:
- D1(" W_S");
- count = 0;
- break;
- default:
- D1(" ");
- count--;
- break;
- }
- }
-
- /* Recovery mechanism for WAIT_SYNC state. */
- if (is_eop) {
- if (odev->rx_parse_state == WAIT_SYNC) {
- odev->rx_parse_state = WAIT_IP;
- odev->rx_buf_size = 0;
- odev->rx_buf_missing = sizeof(struct iphdr);
- }
- }
-}
-
-static void fix_crc_bug(struct urb *urb, __le16 max_packet_size)
-{
- static const u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
- u32 rest = urb->actual_length % le16_to_cpu(max_packet_size);
-
- if (((rest == 5) || (rest == 6)) &&
- !memcmp(((u8 *)urb->transfer_buffer) + urb->actual_length - 4,
- crc_check, 4)) {
- urb->actual_length -= 4;
- }
-}
-
-/* Moving data from usb to kernel (in interrupt state) */
-static void read_bulk_callback(struct urb *urb)
-{
- struct hso_net *odev = urb->context;
- struct net_device *net;
- int result;
- int status = urb->status;
-
- /* is al ok? (Filip: Who's Al ?) */
- if (status) {
- handle_usb_error(status, __func__, odev->parent);
- return;
- }
-
- /* Sanity check */
- if (!odev || !test_bit(HSO_NET_RUNNING, &odev->flags)) {
- D1("BULK IN callback but driver is not active!");
- return;
- }
- usb_mark_last_busy(urb->dev);
-
- net = odev->net;
-
- if (!netif_device_present(net)) {
- /* Somebody killed our network interface... */
- return;
- }
-
- if (odev->parent->port_spec & HSO_INFO_CRC_BUG)
- fix_crc_bug(urb, odev->in_endp->wMaxPacketSize);
-
- /* do we even have a packet? */
- if (urb->actual_length) {
- /* Handle the IP stream, add header and push it onto network
- * stack if the packet is complete. */
- spin_lock(&odev->net_lock);
- packetizeRx(odev, urb->transfer_buffer, urb->actual_length,
- (urb->transfer_buffer_length >
- urb->actual_length) ? 1 : 0);
- spin_unlock(&odev->net_lock);
- }
-
- /* We are done with this URB, resubmit it. Prep the USB to wait for
- * another frame. Reuse same as received. */
- usb_fill_bulk_urb(urb,
- odev->parent->usb,
- usb_rcvbulkpipe(odev->parent->usb,
- odev->in_endp->
- bEndpointAddress & 0x7F),
- urb->transfer_buffer, MUX_BULK_RX_BUF_SIZE,
- read_bulk_callback, odev);
-
- /* Give this to the USB subsystem so it can tell us when more data
- * arrives. */
- result = usb_submit_urb(urb, GFP_ATOMIC);
- if (result)
- dev_warn(&odev->parent->interface->dev,
- "%s failed submit mux_bulk_rx_urb %d\n", __func__,
- result);
-}
-
-/* Serial driver functions */
-
-static void hso_init_termios(struct ktermios *termios)
-{
- /*
- * The default requirements for this device are:
- */
- termios->c_iflag &=
- ~(IGNBRK /* disable ignore break */
- | BRKINT /* disable break causes interrupt */
- | PARMRK /* disable mark parity errors */
- | ISTRIP /* disable clear high bit of input characters */
- | INLCR /* disable translate NL to CR */
- | IGNCR /* disable ignore CR */
- | ICRNL /* disable translate CR to NL */
- | IXON); /* disable enable XON/XOFF flow control */
-
- /* disable postprocess output characters */
- termios->c_oflag &= ~OPOST;
-
- termios->c_lflag &=
- ~(ECHO /* disable echo input characters */
- | ECHONL /* disable echo new line */
- | ICANON /* disable erase, kill, werase, and rprnt
- special characters */
- | ISIG /* disable interrupt, quit, and suspend special
- characters */
- | IEXTEN); /* disable non-POSIX special characters */
-
- termios->c_cflag &=
- ~(CSIZE /* no size */
- | PARENB /* disable parity bit */
- | CBAUD /* clear current baud rate */
- | CBAUDEX); /* clear current buad rate */
-
- termios->c_cflag |= CS8; /* character size 8 bits */
-
- /* baud rate 115200 */
- tty_termios_encode_baud_rate(termios, 115200, 115200);
-}
-
-static void _hso_serial_set_termios(struct tty_struct *tty,
- struct ktermios *old)
-{
- struct hso_serial *serial = get_serial_by_tty(tty);
- struct ktermios *termios;
-
- if (!serial) {
- printk(KERN_ERR "%s: no tty structures", __func__);
- return;
- }
-
- D4("port %d", serial->minor);
-
- /*
- * Fix up unsupported bits
- */
- termios = tty->termios;
- termios->c_iflag &= ~IXON; /* disable enable XON/XOFF flow control */
-
- termios->c_cflag &=
- ~(CSIZE /* no size */
- | PARENB /* disable parity bit */
- | CBAUD /* clear current baud rate */
- | CBAUDEX); /* clear current buad rate */
-
- termios->c_cflag |= CS8; /* character size 8 bits */
-
- /* baud rate 115200 */
- tty_encode_baud_rate(tty, 115200, 115200);
-}
-
-static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb)
-{
- int result;
- /* We are done with this URB, resubmit it. Prep the USB to wait for
- * another frame */
- usb_fill_bulk_urb(urb, serial->parent->usb,
- usb_rcvbulkpipe(serial->parent->usb,
- serial->in_endp->
- bEndpointAddress & 0x7F),
- urb->transfer_buffer, serial->rx_data_length,
- hso_std_serial_read_bulk_callback, serial);
- /* Give this to the USB subsystem so it can tell us when more data
- * arrives. */
- result = usb_submit_urb(urb, GFP_ATOMIC);
- if (result) {
- dev_err(&urb->dev->dev, "%s failed submit serial rx_urb %d\n",
- __func__, result);
- }
-}
-
-
-
-
-static void put_rxbuf_data_and_resubmit_bulk_urb(struct hso_serial *serial)
-{
- int count;
- struct urb *curr_urb;
-
- while (serial->rx_urb_filled[serial->curr_rx_urb_idx]) {
- curr_urb = serial->rx_urb[serial->curr_rx_urb_idx];
- count = put_rxbuf_data(curr_urb, serial);
- if (count == -1)
- return;
- if (count == 0) {
- serial->curr_rx_urb_idx++;
- if (serial->curr_rx_urb_idx >= serial->num_rx_urbs)
- serial->curr_rx_urb_idx = 0;
- hso_resubmit_rx_bulk_urb(serial, curr_urb);
- }
- }
-}
-
-static void put_rxbuf_data_and_resubmit_ctrl_urb(struct hso_serial *serial)
-{
- int count = 0;
- struct urb *urb;
-
- urb = serial->rx_urb[0];
- if (serial->open_count > 0) {
- count = put_rxbuf_data(urb, serial);
- if (count == -1)
- return;
- }
- /* Re issue a read as long as we receive data. */
-
- if (count == 0 && ((urb->actual_length != 0) ||
- (serial->rx_state == RX_PENDING))) {
- serial->rx_state = RX_SENT;
- hso_mux_serial_read(serial);
- } else
- serial->rx_state = RX_IDLE;
-}
-
-
-/* read callback for Diag and CS port */
-static void hso_std_serial_read_bulk_callback(struct urb *urb)
-{
- struct hso_serial *serial = urb->context;
- int status = urb->status;
-
- /* sanity check */
- if (!serial) {
- D1("serial == NULL");
- return;
- } else if (status) {
- handle_usb_error(status, __func__, serial->parent);
- return;
- }
-
- D4("\n--- Got serial_read_bulk callback %02x ---", status);
- D1("Actual length = %d\n", urb->actual_length);
- DUMP1(urb->transfer_buffer, urb->actual_length);
-
- /* Anyone listening? */
- if (serial->open_count == 0)
- return;
-
- if (status == 0) {
- if (serial->parent->port_spec & HSO_INFO_CRC_BUG)
- fix_crc_bug(urb, serial->in_endp->wMaxPacketSize);
- /* Valid data, handle RX data */
- spin_lock(&serial->serial_lock);
- serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1;
- put_rxbuf_data_and_resubmit_bulk_urb(serial);
- spin_unlock(&serial->serial_lock);
- } else if (status == -ENOENT || status == -ECONNRESET) {
- /* Unlinked - check for throttled port. */
- D2("Port %d, successfully unlinked urb", serial->minor);
- spin_lock(&serial->serial_lock);
- serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
- hso_resubmit_rx_bulk_urb(serial, urb);
- spin_unlock(&serial->serial_lock);
- } else {
- D2("Port %d, status = %d for read urb", serial->minor, status);
- return;
- }
-}
-
-/*
- * This needs to be a tasklet otherwise we will
- * end up recursively calling this function.
- */
-static void hso_unthrottle_tasklet(struct hso_serial *serial)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&serial->serial_lock, flags);
- if ((serial->parent->port_spec & HSO_INTF_MUX))
- put_rxbuf_data_and_resubmit_ctrl_urb(serial);
- else
- put_rxbuf_data_and_resubmit_bulk_urb(serial);
- spin_unlock_irqrestore(&serial->serial_lock, flags);
-}
-
-static void hso_unthrottle(struct tty_struct *tty)
-{
- struct hso_serial *serial = get_serial_by_tty(tty);
-
- tasklet_hi_schedule(&serial->unthrottle_tasklet);
-}
-
-static void hso_unthrottle_workfunc(struct work_struct *work)
-{
- struct hso_serial *serial =
- container_of(work, struct hso_serial,
- retry_unthrottle_workqueue);
- hso_unthrottle_tasklet(serial);
-}
-
-/* open the requested serial port */
-static int hso_serial_open(struct tty_struct *tty, struct file *filp)
-{
- struct hso_serial *serial = get_serial_by_index(tty->index);
- int result;
-
- /* sanity check */
- if (serial == NULL || serial->magic != HSO_SERIAL_MAGIC) {
- WARN_ON(1);
- tty->driver_data = NULL;
- D1("Failed to open port");
- return -ENODEV;
- }
-
- mutex_lock(&serial->parent->mutex);
- result = usb_autopm_get_interface(serial->parent->interface);
- if (result < 0)
- goto err_out;
-
- D1("Opening %d", serial->minor);
- kref_get(&serial->parent->ref);
-
- /* setup */
- spin_lock_irq(&serial->serial_lock);
- tty->driver_data = serial;
- tty_kref_put(serial->tty);
- serial->tty = tty_kref_get(tty);
- spin_unlock_irq(&serial->serial_lock);
-
- /* check for port already opened, if not set the termios */
- serial->open_count++;
- if (serial->open_count == 1) {
- serial->rx_state = RX_IDLE;
- /* Force default termio settings */
- _hso_serial_set_termios(tty, NULL);
- tasklet_init(&serial->unthrottle_tasklet,
- (void (*)(unsigned long))hso_unthrottle_tasklet,
- (unsigned long)serial);
- INIT_WORK(&serial->retry_unthrottle_workqueue,
- hso_unthrottle_workfunc);
- result = hso_start_serial_device(serial->parent, GFP_KERNEL);
- if (result) {
- hso_stop_serial_device(serial->parent);
- serial->open_count--;
- kref_put(&serial->parent->ref, hso_serial_ref_free);
- }
- } else {
- D1("Port was already open");
- }
-
- usb_autopm_put_interface(serial->parent->interface);
-
- /* done */
- if (result)
- hso_serial_tiocmset(tty, TIOCM_RTS | TIOCM_DTR, 0);
-err_out:
- mutex_unlock(&serial->parent->mutex);
- return result;
-}
-
-/* close the requested serial port */
-static void hso_serial_close(struct tty_struct *tty, struct file *filp)
-{
- struct hso_serial *serial = tty->driver_data;
- u8 usb_gone;
-
- D1("Closing serial port");
-
- /* Open failed, no close cleanup required */
- if (serial == NULL)
- return;
-
- mutex_lock(&serial->parent->mutex);
- usb_gone = serial->parent->usb_gone;
-
- if (!usb_gone)
- usb_autopm_get_interface(serial->parent->interface);
-
- /* reset the rts and dtr */
- /* do the actual close */
- serial->open_count--;
-
- if (serial->open_count <= 0) {
- serial->open_count = 0;
- spin_lock_irq(&serial->serial_lock);
- if (serial->tty == tty) {
- serial->tty->driver_data = NULL;
- serial->tty = NULL;
- tty_kref_put(tty);
- }
- spin_unlock_irq(&serial->serial_lock);
- if (!usb_gone)
- hso_stop_serial_device(serial->parent);
- tasklet_kill(&serial->unthrottle_tasklet);
- cancel_work_sync(&serial->retry_unthrottle_workqueue);
- }
-
- if (!usb_gone)
- usb_autopm_put_interface(serial->parent->interface);
-
- mutex_unlock(&serial->parent->mutex);
-
- kref_put(&serial->parent->ref, hso_serial_ref_free);
-}
-
-/* close the requested serial port */
-static int hso_serial_write(struct tty_struct *tty, const unsigned char *buf,
- int count)
-{
- struct hso_serial *serial = get_serial_by_tty(tty);
- int space, tx_bytes;
- unsigned long flags;
-
- /* sanity check */
- if (serial == NULL) {
- printk(KERN_ERR "%s: serial is NULL\n", __func__);
- return -ENODEV;
- }
-
- spin_lock_irqsave(&serial->serial_lock, flags);
-
- space = serial->tx_data_length - serial->tx_buffer_count;
- tx_bytes = (count < space) ? count : space;
-
- if (!tx_bytes)
- goto out;
-
- memcpy(serial->tx_buffer + serial->tx_buffer_count, buf, tx_bytes);
- serial->tx_buffer_count += tx_bytes;
-
-out:
- spin_unlock_irqrestore(&serial->serial_lock, flags);
-
- hso_kick_transmit(serial);
- /* done */
- return tx_bytes;
-}
-
-/* how much room is there for writing */
-static int hso_serial_write_room(struct tty_struct *tty)
-{
- struct hso_serial *serial = get_serial_by_tty(tty);
- int room;
- unsigned long flags;
-
- spin_lock_irqsave(&serial->serial_lock, flags);
- room = serial->tx_data_length - serial->tx_buffer_count;
- spin_unlock_irqrestore(&serial->serial_lock, flags);
-
- /* return free room */
- return room;
-}
-
-/* setup the term */
-static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old)
-{
- struct hso_serial *serial = get_serial_by_tty(tty);
- unsigned long flags;
-
- if (old)
- D5("Termios called with: cflags new[%d] - old[%d]",
- tty->termios->c_cflag, old->c_cflag);
-
- /* the actual setup */
- spin_lock_irqsave(&serial->serial_lock, flags);
- if (serial->open_count)
- _hso_serial_set_termios(tty, old);
- else
- tty->termios = old;
- spin_unlock_irqrestore(&serial->serial_lock, flags);
-
- /* done */
-}
-
-/* how many characters in the buffer */
-static int hso_serial_chars_in_buffer(struct tty_struct *tty)
-{
- struct hso_serial *serial = get_serial_by_tty(tty);
- int chars;
- unsigned long flags;
-
- /* sanity check */
- if (serial == NULL)
- return 0;
-
- spin_lock_irqsave(&serial->serial_lock, flags);
- chars = serial->tx_buffer_count;
- spin_unlock_irqrestore(&serial->serial_lock, flags);
-
- return chars;
-}
-static int tiocmget_submit_urb(struct hso_serial *serial,
- struct hso_tiocmget *tiocmget,
- struct usb_device *usb)
-{
- int result;
-
- if (serial->parent->usb_gone)
- return -ENODEV;
- usb_fill_int_urb(tiocmget->urb, usb,
- usb_rcvintpipe(usb,
- tiocmget->endp->
- bEndpointAddress & 0x7F),
- &tiocmget->serial_state_notification,
- sizeof(struct hso_serial_state_notification),
- tiocmget_intr_callback, serial,
- tiocmget->endp->bInterval);
- result = usb_submit_urb(tiocmget->urb, GFP_ATOMIC);
- if (result) {
- dev_warn(&usb->dev, "%s usb_submit_urb failed %d\n", __func__,
- result);
- }
- return result;
-
-}
-
-static void tiocmget_intr_callback(struct urb *urb)
-{
- struct hso_serial *serial = urb->context;
- struct hso_tiocmget *tiocmget;
- int status = urb->status;
- u16 UART_state_bitmap, prev_UART_state_bitmap;
- struct uart_icount *icount;
- struct hso_serial_state_notification *serial_state_notification;
- struct usb_device *usb;
-
- /* Sanity checks */
- if (!serial)
- return;
- if (status) {
- handle_usb_error(status, __func__, serial->parent);
- return;
- }
- tiocmget = serial->tiocmget;
- if (!tiocmget)
- return;
- usb = serial->parent->usb;
- serial_state_notification = &tiocmget->serial_state_notification;
- if (serial_state_notification->bmRequestType != BM_REQUEST_TYPE ||
- serial_state_notification->bNotification != B_NOTIFICATION ||
- le16_to_cpu(serial_state_notification->wValue) != W_VALUE ||
- le16_to_cpu(serial_state_notification->wIndex) != W_INDEX ||
- le16_to_cpu(serial_state_notification->wLength) != W_LENGTH) {
- dev_warn(&usb->dev,
- "hso received invalid serial state notification\n");
- DUMP(serial_state_notification,
- sizeof(struct hso_serial_state_notification));
- } else {
-
- UART_state_bitmap = le16_to_cpu(serial_state_notification->
- UART_state_bitmap);
- prev_UART_state_bitmap = tiocmget->prev_UART_state_bitmap;
- icount = &tiocmget->icount;
- spin_lock(&serial->serial_lock);
- if ((UART_state_bitmap & B_OVERRUN) !=
- (prev_UART_state_bitmap & B_OVERRUN))
- icount->parity++;
- if ((UART_state_bitmap & B_PARITY) !=
- (prev_UART_state_bitmap & B_PARITY))
- icount->parity++;
- if ((UART_state_bitmap & B_FRAMING) !=
- (prev_UART_state_bitmap & B_FRAMING))
- icount->frame++;
- if ((UART_state_bitmap & B_RING_SIGNAL) &&
- !(prev_UART_state_bitmap & B_RING_SIGNAL))
- icount->rng++;
- if ((UART_state_bitmap & B_BREAK) !=
- (prev_UART_state_bitmap & B_BREAK))
- icount->brk++;
- if ((UART_state_bitmap & B_TX_CARRIER) !=
- (prev_UART_state_bitmap & B_TX_CARRIER))
- icount->dsr++;
- if ((UART_state_bitmap & B_RX_CARRIER) !=
- (prev_UART_state_bitmap & B_RX_CARRIER))
- icount->dcd++;
- tiocmget->prev_UART_state_bitmap = UART_state_bitmap;
- spin_unlock(&serial->serial_lock);
- tiocmget->intr_completed = 1;
- wake_up_interruptible(&tiocmget->waitq);
- }
- memset(serial_state_notification, 0,
- sizeof(struct hso_serial_state_notification));
- tiocmget_submit_urb(serial,
- tiocmget,
- serial->parent->usb);
-}
-
-/*
- * next few functions largely stolen from drivers/serial/serial_core.c
- */
-/* Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
- * - mask passed in arg for lines of interest
- * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
- * Caller should use TIOCGICOUNT to see which one it was
- */
-static int
-hso_wait_modem_status(struct hso_serial *serial, unsigned long arg)
-{
- DECLARE_WAITQUEUE(wait, current);
- struct uart_icount cprev, cnow;
- struct hso_tiocmget *tiocmget;
- int ret;
-
- tiocmget = serial->tiocmget;
- if (!tiocmget)
- return -ENOENT;
- /*
- * note the counters on entry
- */
- spin_lock_irq(&serial->serial_lock);
- memcpy(&cprev, &tiocmget->icount, sizeof(struct uart_icount));
- spin_unlock_irq(&serial->serial_lock);
- add_wait_queue(&tiocmget->waitq, &wait);
- for (;;) {
- spin_lock_irq(&serial->serial_lock);
- memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount));
- spin_unlock_irq(&serial->serial_lock);
- set_current_state(TASK_INTERRUPTIBLE);
- if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
- ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
- ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd))) {
- ret = 0;
- break;
- }
- schedule();
- /* see if a signal did it */
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
- cprev = cnow;
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&tiocmget->waitq, &wait);
-
- return ret;
-}
-
-/*
- * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
- * Return: write counters to the user passed counter struct
- * NB: both 1->0 and 0->1 transitions are counted except for
- * RI where only 0->1 is counted.
- */
-static int hso_get_count(struct tty_struct *tty,
- struct serial_icounter_struct *icount)
-{
- struct uart_icount cnow;
- struct hso_serial *serial = get_serial_by_tty(tty);
- struct hso_tiocmget *tiocmget = serial->tiocmget;
-
- memset(icount, 0, sizeof(struct serial_icounter_struct));
-
- if (!tiocmget)
- return -ENOENT;
- spin_lock_irq(&serial->serial_lock);
- memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount));
- spin_unlock_irq(&serial->serial_lock);
-
- icount->cts = cnow.cts;
- icount->dsr = cnow.dsr;
- icount->rng = cnow.rng;
- icount->dcd = cnow.dcd;
- icount->rx = cnow.rx;
- icount->tx = cnow.tx;
- icount->frame = cnow.frame;
- icount->overrun = cnow.overrun;
- icount->parity = cnow.parity;
- icount->brk = cnow.brk;
- icount->buf_overrun = cnow.buf_overrun;
-
- return 0;
-}
-
-
-static int hso_serial_tiocmget(struct tty_struct *tty)
-{
- int retval;
- struct hso_serial *serial = get_serial_by_tty(tty);
- struct hso_tiocmget *tiocmget;
- u16 UART_state_bitmap;
-
- /* sanity check */
- if (!serial) {
- D1("no tty structures");
- return -EINVAL;
- }
- spin_lock_irq(&serial->serial_lock);
- retval = ((serial->rts_state) ? TIOCM_RTS : 0) |
- ((serial->dtr_state) ? TIOCM_DTR : 0);
- tiocmget = serial->tiocmget;
- if (tiocmget) {
-
- UART_state_bitmap = le16_to_cpu(
- tiocmget->prev_UART_state_bitmap);
- if (UART_state_bitmap & B_RING_SIGNAL)
- retval |= TIOCM_RNG;
- if (UART_state_bitmap & B_RX_CARRIER)
- retval |= TIOCM_CD;
- if (UART_state_bitmap & B_TX_CARRIER)
- retval |= TIOCM_DSR;
- }
- spin_unlock_irq(&serial->serial_lock);
- return retval;
-}
-
-static int hso_serial_tiocmset(struct tty_struct *tty,
- unsigned int set, unsigned int clear)
-{
- int val = 0;
- unsigned long flags;
- int if_num;
- struct hso_serial *serial = get_serial_by_tty(tty);
-
- /* sanity check */
- if (!serial) {
- D1("no tty structures");
- return -EINVAL;
- }
-
- if ((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM)
- return -EINVAL;
-
- if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber;
-
- spin_lock_irqsave(&serial->serial_lock, flags);
- if (set & TIOCM_RTS)
- serial->rts_state = 1;
- if (set & TIOCM_DTR)
- serial->dtr_state = 1;
-
- if (clear & TIOCM_RTS)
- serial->rts_state = 0;
- if (clear & TIOCM_DTR)
- serial->dtr_state = 0;
-
- if (serial->dtr_state)
- val |= 0x01;
- if (serial->rts_state)
- val |= 0x02;
-
- spin_unlock_irqrestore(&serial->serial_lock, flags);
-
- return usb_control_msg(serial->parent->usb,
- usb_rcvctrlpipe(serial->parent->usb, 0), 0x22,
- 0x21, val, if_num, NULL, 0,
- USB_CTRL_SET_TIMEOUT);
-}
-
-static int hso_serial_ioctl(struct tty_struct *tty,
- unsigned int cmd, unsigned long arg)
-{
- struct hso_serial *serial = get_serial_by_tty(tty);
- int ret = 0;
- D4("IOCTL cmd: %d, arg: %ld", cmd, arg);
-
- if (!serial)
- return -ENODEV;
- switch (cmd) {
- case TIOCMIWAIT:
- ret = hso_wait_modem_status(serial, arg);
- break;
- default:
- ret = -ENOIOCTLCMD;
- break;
- }
- return ret;
-}
-
-
-/* starts a transmit */
-static void hso_kick_transmit(struct hso_serial *serial)
-{
- u8 *temp;
- unsigned long flags;
- int res;
-
- spin_lock_irqsave(&serial->serial_lock, flags);
- if (!serial->tx_buffer_count)
- goto out;
-
- if (serial->tx_urb_used)
- goto out;
-
- /* Wakeup USB interface if necessary */
- if (hso_get_activity(serial->parent) == -EAGAIN)
- goto out;
-
- /* Switch pointers around to avoid memcpy */
- temp = serial->tx_buffer;
- serial->tx_buffer = serial->tx_data;
- serial->tx_data = temp;
- serial->tx_data_count = serial->tx_buffer_count;
- serial->tx_buffer_count = 0;
-
- /* If temp is set, it means we switched buffers */
- if (temp && serial->write_data) {
- res = serial->write_data(serial);
- if (res >= 0)
- serial->tx_urb_used = 1;
- }
-out:
- spin_unlock_irqrestore(&serial->serial_lock, flags);
-}
-
-/* make a request (for reading and writing data to muxed serial port) */
-static int mux_device_request(struct hso_serial *serial, u8 type, u16 port,
- struct urb *ctrl_urb,
- struct usb_ctrlrequest *ctrl_req,
- u8 *ctrl_urb_data, u32 size)
-{
- int result;
- int pipe;
-
- /* Sanity check */
- if (!serial || !ctrl_urb || !ctrl_req) {
- printk(KERN_ERR "%s: Wrong arguments\n", __func__);
- return -EINVAL;
- }
-
- /* initialize */
- ctrl_req->wValue = 0;
- ctrl_req->wIndex = cpu_to_le16(hso_port_to_mux(port));
- ctrl_req->wLength = cpu_to_le16(size);
-
- if (type == USB_CDC_GET_ENCAPSULATED_RESPONSE) {
- /* Reading command */
- ctrl_req->bRequestType = USB_DIR_IN |
- USB_TYPE_OPTION_VENDOR |
- USB_RECIP_INTERFACE;
- ctrl_req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE;
- pipe = usb_rcvctrlpipe(serial->parent->usb, 0);
- } else {
- /* Writing command */
- ctrl_req->bRequestType = USB_DIR_OUT |
- USB_TYPE_OPTION_VENDOR |
- USB_RECIP_INTERFACE;
- ctrl_req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
- pipe = usb_sndctrlpipe(serial->parent->usb, 0);
- }
- /* syslog */
- D2("%s command (%02x) len: %d, port: %d",
- type == USB_CDC_GET_ENCAPSULATED_RESPONSE ? "Read" : "Write",
- ctrl_req->bRequestType, ctrl_req->wLength, port);
-
- /* Load ctrl urb */
- ctrl_urb->transfer_flags = 0;
- usb_fill_control_urb(ctrl_urb,
- serial->parent->usb,
- pipe,
- (u8 *) ctrl_req,
- ctrl_urb_data, size, ctrl_callback, serial);
- /* Send it on merry way */
- result = usb_submit_urb(ctrl_urb, GFP_ATOMIC);
- if (result) {
- dev_err(&ctrl_urb->dev->dev,
- "%s failed submit ctrl_urb %d type %d\n", __func__,
- result, type);
- return result;
- }
-
- /* done */
- return size;
-}
-
-/* called by intr_callback when read occurs */
-static int hso_mux_serial_read(struct hso_serial *serial)
-{
- if (!serial)
- return -EINVAL;
-
- /* clean data */
- memset(serial->rx_data[0], 0, CTRL_URB_RX_SIZE);
- /* make the request */
-
- if (serial->num_rx_urbs != 1) {
- dev_err(&serial->parent->interface->dev,
- "ERROR: mux'd reads with multiple buffers "
- "not possible\n");
- return 0;
- }
- return mux_device_request(serial,
- USB_CDC_GET_ENCAPSULATED_RESPONSE,
- serial->parent->port_spec & HSO_PORT_MASK,
- serial->rx_urb[0],
- &serial->ctrl_req_rx,
- serial->rx_data[0], serial->rx_data_length);
-}
-
-/* used for muxed serial port callback (muxed serial read) */
-static void intr_callback(struct urb *urb)
-{
- struct hso_shared_int *shared_int = urb->context;
- struct hso_serial *serial;
- unsigned char *port_req;
- int status = urb->status;
- int i;
-
- usb_mark_last_busy(urb->dev);
-
- /* sanity check */
- if (!shared_int)
- return;
-
- /* status check */
- if (status) {
- handle_usb_error(status, __func__, NULL);
- return;
- }
- D4("\n--- Got intr callback 0x%02X ---", status);
-
- /* what request? */
- port_req = urb->transfer_buffer;
- D4(" port_req = 0x%.2X\n", *port_req);
- /* loop over all muxed ports to find the one sending this */
- for (i = 0; i < 8; i++) {
- /* max 8 channels on MUX */
- if (*port_req & (1 << i)) {
- serial = get_serial_by_shared_int_and_type(shared_int,
- (1 << i));
- if (serial != NULL) {
- D1("Pending read interrupt on port %d\n", i);
- spin_lock(&serial->serial_lock);
- if (serial->rx_state == RX_IDLE &&
- serial->open_count > 0) {
- /* Setup and send a ctrl req read on
- * port i */
- if (!serial->rx_urb_filled[0]) {
- serial->rx_state = RX_SENT;
- hso_mux_serial_read(serial);
- } else
- serial->rx_state = RX_PENDING;
- } else {
- D1("Already a read pending on "
- "port %d or port not open\n", i);
- }
- spin_unlock(&serial->serial_lock);
- }
- }
- }
- /* Resubmit interrupt urb */
- hso_mux_submit_intr_urb(shared_int, urb->dev, GFP_ATOMIC);
-}
-
-/* called for writing to muxed serial port */
-static int hso_mux_serial_write_data(struct hso_serial *serial)
-{
- if (NULL == serial)
- return -EINVAL;
-
- return mux_device_request(serial,
- USB_CDC_SEND_ENCAPSULATED_COMMAND,
- serial->parent->port_spec & HSO_PORT_MASK,
- serial->tx_urb,
- &serial->ctrl_req_tx,
- serial->tx_data, serial->tx_data_count);
-}
-
-/* write callback for Diag and CS port */
-static void hso_std_serial_write_bulk_callback(struct urb *urb)
-{
- struct hso_serial *serial = urb->context;
- int status = urb->status;
- struct tty_struct *tty;
-
- /* sanity check */
- if (!serial) {
- D1("serial == NULL");
- return;
- }
-
- spin_lock(&serial->serial_lock);
- serial->tx_urb_used = 0;
- tty = tty_kref_get(serial->tty);
- spin_unlock(&serial->serial_lock);
- if (status) {
- handle_usb_error(status, __func__, serial->parent);
- tty_kref_put(tty);
- return;
- }
- hso_put_activity(serial->parent);
- if (tty) {
- tty_wakeup(tty);
- tty_kref_put(tty);
- }
- hso_kick_transmit(serial);
-
- D1(" ");
-}
-
-/* called for writing diag or CS serial port */
-static int hso_std_serial_write_data(struct hso_serial *serial)
-{
- int count = serial->tx_data_count;
- int result;
-
- usb_fill_bulk_urb(serial->tx_urb,
- serial->parent->usb,
- usb_sndbulkpipe(serial->parent->usb,
- serial->out_endp->
- bEndpointAddress & 0x7F),
- serial->tx_data, serial->tx_data_count,
- hso_std_serial_write_bulk_callback, serial);
-
- result = usb_submit_urb(serial->tx_urb, GFP_ATOMIC);
- if (result) {
- dev_warn(&serial->parent->usb->dev,
- "Failed to submit urb - res %d\n", result);
- return result;
- }
-
- return count;
-}
-
-/* callback after read or write on muxed serial port */
-static void ctrl_callback(struct urb *urb)
-{
- struct hso_serial *serial = urb->context;
- struct usb_ctrlrequest *req;
- int status = urb->status;
- struct tty_struct *tty;
-
- /* sanity check */
- if (!serial)
- return;
-
- spin_lock(&serial->serial_lock);
- serial->tx_urb_used = 0;
- tty = tty_kref_get(serial->tty);
- spin_unlock(&serial->serial_lock);
- if (status) {
- handle_usb_error(status, __func__, serial->parent);
- tty_kref_put(tty);
- return;
- }
-
- /* what request? */
- req = (struct usb_ctrlrequest *)(urb->setup_packet);
- D4("\n--- Got muxed ctrl callback 0x%02X ---", status);
- D4("Actual length of urb = %d\n", urb->actual_length);
- DUMP1(urb->transfer_buffer, urb->actual_length);
-
- if (req->bRequestType ==
- (USB_DIR_IN | USB_TYPE_OPTION_VENDOR | USB_RECIP_INTERFACE)) {
- /* response to a read command */
- serial->rx_urb_filled[0] = 1;
- spin_lock(&serial->serial_lock);
- put_rxbuf_data_and_resubmit_ctrl_urb(serial);
- spin_unlock(&serial->serial_lock);
- } else {
- hso_put_activity(serial->parent);
- if (tty)
- tty_wakeup(tty);
- /* response to a write command */
- hso_kick_transmit(serial);
- }
- tty_kref_put(tty);
-}
-
-/* handle RX data for serial port */
-static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
-{
- struct tty_struct *tty;
- int write_length_remaining = 0;
- int curr_write_len;
-
- /* Sanity check */
- if (urb == NULL || serial == NULL) {
- D1("serial = NULL");
- return -2;
- }
-
- /* All callers to put_rxbuf_data hold serial_lock */
- tty = tty_kref_get(serial->tty);
-
- /* Push data to tty */
- if (tty) {
- write_length_remaining = urb->actual_length -
- serial->curr_rx_urb_offset;
- D1("data to push to tty");
- while (write_length_remaining) {
- if (test_bit(TTY_THROTTLED, &tty->flags)) {
- tty_kref_put(tty);
- return -1;
- }
- curr_write_len = tty_insert_flip_string
- (tty, urb->transfer_buffer +
- serial->curr_rx_urb_offset,
- write_length_remaining);
- serial->curr_rx_urb_offset += curr_write_len;
- write_length_remaining -= curr_write_len;
- tty_flip_buffer_push(tty);
- }
- }
- if (write_length_remaining == 0) {
- serial->curr_rx_urb_offset = 0;
- serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
- }
- tty_kref_put(tty);
- return write_length_remaining;
-}
-
-
-/* Base driver functions */
-
-static void hso_log_port(struct hso_device *hso_dev)
-{
- char *port_type;
- char port_dev[20];
-
- switch (hso_dev->port_spec & HSO_PORT_MASK) {
- case HSO_PORT_CONTROL:
- port_type = "Control";
- break;
- case HSO_PORT_APP:
- port_type = "Application";
- break;
- case HSO_PORT_GPS:
- port_type = "GPS";
- break;
- case HSO_PORT_GPS_CONTROL:
- port_type = "GPS control";
- break;
- case HSO_PORT_APP2:
- port_type = "Application2";
- break;
- case HSO_PORT_PCSC:
- port_type = "PCSC";
- break;
- case HSO_PORT_DIAG:
- port_type = "Diagnostic";
- break;
- case HSO_PORT_DIAG2:
- port_type = "Diagnostic2";
- break;
- case HSO_PORT_MODEM:
- port_type = "Modem";
- break;
- case HSO_PORT_NETWORK:
- port_type = "Network";
- break;
- default:
- port_type = "Unknown";
- break;
- }
- if ((hso_dev->port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) {
- sprintf(port_dev, "%s", dev2net(hso_dev)->net->name);
- } else
- sprintf(port_dev, "/dev/%s%d", tty_filename,
- dev2ser(hso_dev)->minor);
-
- dev_dbg(&hso_dev->interface->dev, "HSO: Found %s port %s\n",
- port_type, port_dev);
-}
-
-static int hso_start_net_device(struct hso_device *hso_dev)
-{
- int i, result = 0;
- struct hso_net *hso_net = dev2net(hso_dev);
-
- if (!hso_net)
- return -ENODEV;
-
- /* send URBs for all read buffers */
- for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
-
- /* Prep a receive URB */
- usb_fill_bulk_urb(hso_net->mux_bulk_rx_urb_pool[i],
- hso_dev->usb,
- usb_rcvbulkpipe(hso_dev->usb,
- hso_net->in_endp->
- bEndpointAddress & 0x7F),
- hso_net->mux_bulk_rx_buf_pool[i],
- MUX_BULK_RX_BUF_SIZE, read_bulk_callback,
- hso_net);
-
- /* Put it out there so the device can send us stuff */
- result = usb_submit_urb(hso_net->mux_bulk_rx_urb_pool[i],
- GFP_NOIO);
- if (result)
- dev_warn(&hso_dev->usb->dev,
- "%s failed mux_bulk_rx_urb[%d] %d\n", __func__,
- i, result);
- }
-
- return result;
-}
-
-static int hso_stop_net_device(struct hso_device *hso_dev)
-{
- int i;
- struct hso_net *hso_net = dev2net(hso_dev);
-
- if (!hso_net)
- return -ENODEV;
-
- for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
- if (hso_net->mux_bulk_rx_urb_pool[i])
- usb_kill_urb(hso_net->mux_bulk_rx_urb_pool[i]);
-
- }
- if (hso_net->mux_bulk_tx_urb)
- usb_kill_urb(hso_net->mux_bulk_tx_urb);
-
- return 0;
-}
-
-static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags)
-{
- int i, result = 0;
- struct hso_serial *serial = dev2ser(hso_dev);
-
- if (!serial)
- return -ENODEV;
-
- /* If it is not the MUX port fill in and submit a bulk urb (already
- * allocated in hso_serial_start) */
- if (!(serial->parent->port_spec & HSO_INTF_MUX)) {
- for (i = 0; i < serial->num_rx_urbs; i++) {
- usb_fill_bulk_urb(serial->rx_urb[i],
- serial->parent->usb,
- usb_rcvbulkpipe(serial->parent->usb,
- serial->in_endp->
- bEndpointAddress &
- 0x7F),
- serial->rx_data[i],
- serial->rx_data_length,
- hso_std_serial_read_bulk_callback,
- serial);
- result = usb_submit_urb(serial->rx_urb[i], flags);
- if (result) {
- dev_warn(&serial->parent->usb->dev,
- "Failed to submit urb - res %d\n",
- result);
- break;
- }
- }
- } else {
- mutex_lock(&serial->shared_int->shared_int_lock);
- if (!serial->shared_int->use_count) {
- result =
- hso_mux_submit_intr_urb(serial->shared_int,
- hso_dev->usb, flags);
- }
- serial->shared_int->use_count++;
- mutex_unlock(&serial->shared_int->shared_int_lock);
- }
- if (serial->tiocmget)
- tiocmget_submit_urb(serial,
- serial->tiocmget,
- serial->parent->usb);
- return result;
-}
-
-static int hso_stop_serial_device(struct hso_device *hso_dev)
-{
- int i;
- struct hso_serial *serial = dev2ser(hso_dev);
- struct hso_tiocmget *tiocmget;
-
- if (!serial)
- return -ENODEV;
-
- for (i = 0; i < serial->num_rx_urbs; i++) {
- if (serial->rx_urb[i]) {
- usb_kill_urb(serial->rx_urb[i]);
- serial->rx_urb_filled[i] = 0;
- }
- }
- serial->curr_rx_urb_idx = 0;
- serial->curr_rx_urb_offset = 0;
-
- if (serial->tx_urb)
- usb_kill_urb(serial->tx_urb);
-
- if (serial->shared_int) {
- mutex_lock(&serial->shared_int->shared_int_lock);
- if (serial->shared_int->use_count &&
- (--serial->shared_int->use_count == 0)) {
- struct urb *urb;
-
- urb = serial->shared_int->shared_intr_urb;
- if (urb)
- usb_kill_urb(urb);
- }
- mutex_unlock(&serial->shared_int->shared_int_lock);
- }
- tiocmget = serial->tiocmget;
- if (tiocmget) {
- wake_up_interruptible(&tiocmget->waitq);
- usb_kill_urb(tiocmget->urb);
- }
-
- return 0;
-}
-
-static void hso_serial_common_free(struct hso_serial *serial)
-{
- int i;
-
- if (serial->parent->dev)
- device_remove_file(serial->parent->dev, &dev_attr_hsotype);
-
- tty_unregister_device(tty_drv, serial->minor);
-
- for (i = 0; i < serial->num_rx_urbs; i++) {
- /* unlink and free RX URB */
- usb_free_urb(serial->rx_urb[i]);
- /* free the RX buffer */
- kfree(serial->rx_data[i]);
- }
-
- /* unlink and free TX URB */
- usb_free_urb(serial->tx_urb);
- kfree(serial->tx_data);
-}
-
-static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
- int rx_size, int tx_size)
-{
- struct device *dev;
- int minor;
- int i;
-
- minor = get_free_serial_index();
- if (minor < 0)
- goto exit;
-
- /* register our minor number */
- serial->parent->dev = tty_register_device(tty_drv, minor,
- &serial->parent->interface->dev);
- dev = serial->parent->dev;
- dev_set_drvdata(dev, serial->parent);
- i = device_create_file(dev, &dev_attr_hsotype);
-
- /* fill in specific data for later use */
- serial->minor = minor;
- serial->magic = HSO_SERIAL_MAGIC;
- spin_lock_init(&serial->serial_lock);
- serial->num_rx_urbs = num_urbs;
-
- /* RX, allocate urb and initialize */
-
- /* prepare our RX buffer */
- serial->rx_data_length = rx_size;
- for (i = 0; i < serial->num_rx_urbs; i++) {
- serial->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
- if (!serial->rx_urb[i]) {
- dev_err(dev, "Could not allocate urb?\n");
- goto exit;
- }
- serial->rx_urb[i]->transfer_buffer = NULL;
- serial->rx_urb[i]->transfer_buffer_length = 0;
- serial->rx_data[i] = kzalloc(serial->rx_data_length,
- GFP_KERNEL);
- if (!serial->rx_data[i]) {
- dev_err(dev, "%s - Out of memory\n", __func__);
- goto exit;
- }
- }
-
- /* TX, allocate urb and initialize */
- serial->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!serial->tx_urb) {
- dev_err(dev, "Could not allocate urb?\n");
- goto exit;
- }
- serial->tx_urb->transfer_buffer = NULL;
- serial->tx_urb->transfer_buffer_length = 0;
- /* prepare our TX buffer */
- serial->tx_data_count = 0;
- serial->tx_buffer_count = 0;
- serial->tx_data_length = tx_size;
- serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL);
- if (!serial->tx_data) {
- dev_err(dev, "%s - Out of memory\n", __func__);
- goto exit;
- }
- serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL);
- if (!serial->tx_buffer) {
- dev_err(dev, "%s - Out of memory\n", __func__);
- goto exit;
- }
-
- return 0;
-exit:
- hso_serial_common_free(serial);
- return -1;
-}
-
-/* Creates a general hso device */
-static struct hso_device *hso_create_device(struct usb_interface *intf,
- int port_spec)
-{
- struct hso_device *hso_dev;
-
- hso_dev = kzalloc(sizeof(*hso_dev), GFP_ATOMIC);
- if (!hso_dev)
- return NULL;
-
- hso_dev->port_spec = port_spec;
- hso_dev->usb = interface_to_usbdev(intf);
- hso_dev->interface = intf;
- kref_init(&hso_dev->ref);
- mutex_init(&hso_dev->mutex);
-
- INIT_WORK(&hso_dev->async_get_intf, async_get_intf);
- INIT_WORK(&hso_dev->async_put_intf, async_put_intf);
- INIT_WORK(&hso_dev->reset_device, reset_device);
-
- return hso_dev;
-}
-
-/* Removes a network device in the network device table */
-static int remove_net_device(struct hso_device *hso_dev)
-{
- int i;
-
- for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
- if (network_table[i] == hso_dev) {
- network_table[i] = NULL;
- break;
- }
- }
- if (i == HSO_MAX_NET_DEVICES)
- return -1;
- return 0;
-}
-
-/* Frees our network device */
-static void hso_free_net_device(struct hso_device *hso_dev)
-{
- int i;
- struct hso_net *hso_net = dev2net(hso_dev);
-
- if (!hso_net)
- return;
-
- remove_net_device(hso_net->parent);
-
- if (hso_net->net)
- unregister_netdev(hso_net->net);
-
- /* start freeing */
- for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
- usb_free_urb(hso_net->mux_bulk_rx_urb_pool[i]);
- kfree(hso_net->mux_bulk_rx_buf_pool[i]);
- hso_net->mux_bulk_rx_buf_pool[i] = NULL;
- }
- usb_free_urb(hso_net->mux_bulk_tx_urb);
- kfree(hso_net->mux_bulk_tx_buf);
- hso_net->mux_bulk_tx_buf = NULL;
-
- if (hso_net->net)
- free_netdev(hso_net->net);
-
- kfree(hso_dev);
-}
-
-static const struct net_device_ops hso_netdev_ops = {
- .ndo_open = hso_net_open,
- .ndo_stop = hso_net_close,
- .ndo_start_xmit = hso_net_start_xmit,
- .ndo_tx_timeout = hso_net_tx_timeout,
-};
-
-/* initialize the network interface */
-static void hso_net_init(struct net_device *net)
-{
- struct hso_net *hso_net = netdev_priv(net);
-
- D1("sizeof hso_net is %d", (int)sizeof(*hso_net));
-
- /* fill in the other fields */
- net->netdev_ops = &hso_netdev_ops;
- net->watchdog_timeo = HSO_NET_TX_TIMEOUT;
- net->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
- net->type = ARPHRD_NONE;
- net->mtu = DEFAULT_MTU - 14;
- net->tx_queue_len = 10;
- SET_ETHTOOL_OPS(net, &ops);
-
- /* and initialize the semaphore */
- spin_lock_init(&hso_net->net_lock);
-}
-
-/* Adds a network device in the network device table */
-static int add_net_device(struct hso_device *hso_dev)
-{
- int i;
-
- for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
- if (network_table[i] == NULL) {
- network_table[i] = hso_dev;
- break;
- }
- }
- if (i == HSO_MAX_NET_DEVICES)
- return -1;
- return 0;
-}
-
-static int hso_rfkill_set_block(void *data, bool blocked)
-{
- struct hso_device *hso_dev = data;
- int enabled = !blocked;
- int rv;
-
- mutex_lock(&hso_dev->mutex);
- if (hso_dev->usb_gone)
- rv = 0;
- else
- rv = usb_control_msg(hso_dev->usb, usb_rcvctrlpipe(hso_dev->usb, 0),
- enabled ? 0x82 : 0x81, 0x40, 0, 0, NULL, 0,
- USB_CTRL_SET_TIMEOUT);
- mutex_unlock(&hso_dev->mutex);
- return rv;
-}
-
-static const struct rfkill_ops hso_rfkill_ops = {
- .set_block = hso_rfkill_set_block,
-};
-
-/* Creates and sets up everything for rfkill */
-static void hso_create_rfkill(struct hso_device *hso_dev,
- struct usb_interface *interface)
-{
- struct hso_net *hso_net = dev2net(hso_dev);
- struct device *dev = &hso_net->net->dev;
- char *rfkn;
-
- rfkn = kzalloc(20, GFP_KERNEL);
- if (!rfkn)
- dev_err(dev, "%s - Out of memory\n", __func__);
-
- snprintf(rfkn, 20, "hso-%d",
- interface->altsetting->desc.bInterfaceNumber);
-
- hso_net->rfkill = rfkill_alloc(rfkn,
- &interface_to_usbdev(interface)->dev,
- RFKILL_TYPE_WWAN,
- &hso_rfkill_ops, hso_dev);
- if (!hso_net->rfkill) {
- dev_err(dev, "%s - Out of memory\n", __func__);
- kfree(rfkn);
- return;
- }
- if (rfkill_register(hso_net->rfkill) < 0) {
- rfkill_destroy(hso_net->rfkill);
- kfree(rfkn);
- hso_net->rfkill = NULL;
- dev_err(dev, "%s - Failed to register rfkill\n", __func__);
- return;
- }
-}
-
-static struct device_type hso_type = {
- .name = "wwan",
-};
-
-/* Creates our network device */
-static struct hso_device *hso_create_net_device(struct usb_interface *interface,
- int port_spec)
-{
- int result, i;
- struct net_device *net;
- struct hso_net *hso_net;
- struct hso_device *hso_dev;
-
- hso_dev = hso_create_device(interface, port_spec);
- if (!hso_dev)
- return NULL;
-
- /* allocate our network device, then we can put in our private data */
- /* call hso_net_init to do the basic initialization */
- net = alloc_netdev(sizeof(struct hso_net), "hso%d", hso_net_init);
- if (!net) {
- dev_err(&interface->dev, "Unable to create ethernet device\n");
- goto exit;
- }
-
- hso_net = netdev_priv(net);
-
- hso_dev->port_data.dev_net = hso_net;
- hso_net->net = net;
- hso_net->parent = hso_dev;
-
- hso_net->in_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK,
- USB_DIR_IN);
- if (!hso_net->in_endp) {
- dev_err(&interface->dev, "Can't find BULK IN endpoint\n");
- goto exit;
- }
- hso_net->out_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK,
- USB_DIR_OUT);
- if (!hso_net->out_endp) {
- dev_err(&interface->dev, "Can't find BULK OUT endpoint\n");
- goto exit;
- }
- SET_NETDEV_DEV(net, &interface->dev);
- SET_NETDEV_DEVTYPE(net, &hso_type);
-
- /* registering our net device */
- result = register_netdev(net);
- if (result) {
- dev_err(&interface->dev, "Failed to register device\n");
- goto exit;
- }
-
- /* start allocating */
- for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
- hso_net->mux_bulk_rx_urb_pool[i] = usb_alloc_urb(0, GFP_KERNEL);
- if (!hso_net->mux_bulk_rx_urb_pool[i]) {
- dev_err(&interface->dev, "Could not allocate rx urb\n");
- goto exit;
- }
- hso_net->mux_bulk_rx_buf_pool[i] = kzalloc(MUX_BULK_RX_BUF_SIZE,
- GFP_KERNEL);
- if (!hso_net->mux_bulk_rx_buf_pool[i]) {
- dev_err(&interface->dev, "Could not allocate rx buf\n");
- goto exit;
- }
- }
- hso_net->mux_bulk_tx_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!hso_net->mux_bulk_tx_urb) {
- dev_err(&interface->dev, "Could not allocate tx urb\n");
- goto exit;
- }
- hso_net->mux_bulk_tx_buf = kzalloc(MUX_BULK_TX_BUF_SIZE, GFP_KERNEL);
- if (!hso_net->mux_bulk_tx_buf) {
- dev_err(&interface->dev, "Could not allocate tx buf\n");
- goto exit;
- }
-
- add_net_device(hso_dev);
-
- hso_log_port(hso_dev);
-
- hso_create_rfkill(hso_dev, interface);
-
- return hso_dev;
-exit:
- hso_free_net_device(hso_dev);
- return NULL;
-}
-
-static void hso_free_tiomget(struct hso_serial *serial)
-{
- struct hso_tiocmget *tiocmget;
- if (!serial)
- return;
- tiocmget = serial->tiocmget;
- if (tiocmget) {
- usb_free_urb(tiocmget->urb);
- tiocmget->urb = NULL;
- serial->tiocmget = NULL;
- kfree(tiocmget);
- }
-}
-
-/* Frees an AT channel ( goes for both mux and non-mux ) */
-static void hso_free_serial_device(struct hso_device *hso_dev)
-{
- struct hso_serial *serial = dev2ser(hso_dev);
-
- if (!serial)
- return;
- set_serial_by_index(serial->minor, NULL);
-
- hso_serial_common_free(serial);
-
- if (serial->shared_int) {
- mutex_lock(&serial->shared_int->shared_int_lock);
- if (--serial->shared_int->ref_count == 0)
- hso_free_shared_int(serial->shared_int);
- else
- mutex_unlock(&serial->shared_int->shared_int_lock);
- }
- hso_free_tiomget(serial);
- kfree(serial);
- kfree(hso_dev);
-}
-
-/* Creates a bulk AT channel */
-static struct hso_device *hso_create_bulk_serial_device(
- struct usb_interface *interface, int port)
-{
- struct hso_device *hso_dev;
- struct hso_serial *serial;
- int num_urbs;
- struct hso_tiocmget *tiocmget;
-
- hso_dev = hso_create_device(interface, port);
- if (!hso_dev)
- return NULL;
-
- serial = kzalloc(sizeof(*serial), GFP_KERNEL);
- if (!serial)
- goto exit;
-
- serial->parent = hso_dev;
- hso_dev->port_data.dev_serial = serial;
-
- if ((port & HSO_PORT_MASK) == HSO_PORT_MODEM) {
- num_urbs = 2;
- serial->tiocmget = kzalloc(sizeof(struct hso_tiocmget),
- GFP_KERNEL);
- /* it isn't going to break our heart if serial->tiocmget
- * allocation fails don't bother checking this.
- */
- if (serial->tiocmget) {
- tiocmget = serial->tiocmget;
- tiocmget->urb = usb_alloc_urb(0, GFP_KERNEL);
- if (tiocmget->urb) {
- mutex_init(&tiocmget->mutex);
- init_waitqueue_head(&tiocmget->waitq);
- tiocmget->endp = hso_get_ep(
- interface,
- USB_ENDPOINT_XFER_INT,
- USB_DIR_IN);
- } else
- hso_free_tiomget(serial);
- }
- }
- else
- num_urbs = 1;
-
- if (hso_serial_common_create(serial, num_urbs, BULK_URB_RX_SIZE,
- BULK_URB_TX_SIZE))
- goto exit;
-
- serial->in_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK,
- USB_DIR_IN);
- if (!serial->in_endp) {
- dev_err(&interface->dev, "Failed to find BULK IN ep\n");
- goto exit2;
- }
-
- if (!
- (serial->out_endp =
- hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT))) {
- dev_err(&interface->dev, "Failed to find BULK IN ep\n");
- goto exit2;
- }
-
- serial->write_data = hso_std_serial_write_data;
-
- /* and record this serial */
- set_serial_by_index(serial->minor, serial);
-
- /* setup the proc dirs and files if needed */
- hso_log_port(hso_dev);
-
- /* done, return it */
- return hso_dev;
-
-exit2:
- hso_serial_common_free(serial);
-exit:
- hso_free_tiomget(serial);
- kfree(serial);
- kfree(hso_dev);
- return NULL;
-}
-
-/* Creates a multiplexed AT channel */
-static
-struct hso_device *hso_create_mux_serial_device(struct usb_interface *interface,
- int port,
- struct hso_shared_int *mux)
-{
- struct hso_device *hso_dev;
- struct hso_serial *serial;
- int port_spec;
-
- port_spec = HSO_INTF_MUX;
- port_spec &= ~HSO_PORT_MASK;
-
- port_spec |= hso_mux_to_port(port);
- if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NO_PORT)
- return NULL;
-
- hso_dev = hso_create_device(interface, port_spec);
- if (!hso_dev)
- return NULL;
-
- serial = kzalloc(sizeof(*serial), GFP_KERNEL);
- if (!serial)
- goto exit;
-
- hso_dev->port_data.dev_serial = serial;
- serial->parent = hso_dev;
-
- if (hso_serial_common_create
- (serial, 1, CTRL_URB_RX_SIZE, CTRL_URB_TX_SIZE))
- goto exit;
-
- serial->tx_data_length--;
- serial->write_data = hso_mux_serial_write_data;
-
- serial->shared_int = mux;
- mutex_lock(&serial->shared_int->shared_int_lock);
- serial->shared_int->ref_count++;
- mutex_unlock(&serial->shared_int->shared_int_lock);
-
- /* and record this serial */
- set_serial_by_index(serial->minor, serial);
-
- /* setup the proc dirs and files if needed */
- hso_log_port(hso_dev);
-
- /* done, return it */
- return hso_dev;
-
-exit:
- if (serial) {
- tty_unregister_device(tty_drv, serial->minor);
- kfree(serial);
- }
- if (hso_dev)
- kfree(hso_dev);
- return NULL;
-
-}
-
-static void hso_free_shared_int(struct hso_shared_int *mux)
-{
- usb_free_urb(mux->shared_intr_urb);
- kfree(mux->shared_intr_buf);
- mutex_unlock(&mux->shared_int_lock);
- kfree(mux);
-}
-
-static
-struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface)
-{
- struct hso_shared_int *mux = kzalloc(sizeof(*mux), GFP_KERNEL);
-
- if (!mux)
- return NULL;
-
- mux->intr_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_INT,
- USB_DIR_IN);
- if (!mux->intr_endp) {
- dev_err(&interface->dev, "Can't find INT IN endpoint\n");
- goto exit;
- }
-
- mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!mux->shared_intr_urb) {
- dev_err(&interface->dev, "Could not allocate intr urb?\n");
- goto exit;
- }
- mux->shared_intr_buf =
- kzalloc(le16_to_cpu(mux->intr_endp->wMaxPacketSize),
- GFP_KERNEL);
- if (!mux->shared_intr_buf) {
- dev_err(&interface->dev, "Could not allocate intr buf?\n");
- goto exit;
- }
-
- mutex_init(&mux->shared_int_lock);
-
- return mux;
-
-exit:
- kfree(mux->shared_intr_buf);
- usb_free_urb(mux->shared_intr_urb);
- kfree(mux);
- return NULL;
-}
-
-/* Gets the port spec for a certain interface */
-static int hso_get_config_data(struct usb_interface *interface)
-{
- struct usb_device *usbdev = interface_to_usbdev(interface);
- u8 config_data[17];
- u32 if_num = interface->altsetting->desc.bInterfaceNumber;
- s32 result;
-
- if (usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
- 0x86, 0xC0, 0, 0, config_data, 17,
- USB_CTRL_SET_TIMEOUT) != 0x11) {
- return -EIO;
- }
-
- switch (config_data[if_num]) {
- case 0x0:
- result = 0;
- break;
- case 0x1:
- result = HSO_PORT_DIAG;
- break;
- case 0x2:
- result = HSO_PORT_GPS;
- break;
- case 0x3:
- result = HSO_PORT_GPS_CONTROL;
- break;
- case 0x4:
- result = HSO_PORT_APP;
- break;
- case 0x5:
- result = HSO_PORT_APP2;
- break;
- case 0x6:
- result = HSO_PORT_CONTROL;
- break;
- case 0x7:
- result = HSO_PORT_NETWORK;
- break;
- case 0x8:
- result = HSO_PORT_MODEM;
- break;
- case 0x9:
- result = HSO_PORT_MSD;
- break;
- case 0xa:
- result = HSO_PORT_PCSC;
- break;
- case 0xb:
- result = HSO_PORT_VOICE;
- break;
- default:
- result = 0;
- }
-
- if (result)
- result |= HSO_INTF_BULK;
-
- if (config_data[16] & 0x1)
- result |= HSO_INFO_CRC_BUG;
-
- return result;
-}
-
-/* called once for each interface upon device insertion */
-static int hso_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- int mux, i, if_num, port_spec;
- unsigned char port_mask;
- struct hso_device *hso_dev = NULL;
- struct hso_shared_int *shared_int;
- struct hso_device *tmp_dev = NULL;
-
- if_num = interface->altsetting->desc.bInterfaceNumber;
-
- /* Get the interface/port specification from either driver_info or from
- * the device itself */
- if (id->driver_info)
- port_spec = ((u32 *)(id->driver_info))[if_num];
- else
- port_spec = hso_get_config_data(interface);
-
- if (interface->cur_altsetting->desc.bInterfaceClass != 0xFF) {
- dev_err(&interface->dev, "Not our interface\n");
- return -ENODEV;
- }
- /* Check if we need to switch to alt interfaces prior to port
- * configuration */
- if (interface->num_altsetting > 1)
- usb_set_interface(interface_to_usbdev(interface), if_num, 1);
- interface->needs_remote_wakeup = 1;
-
- /* Allocate new hso device(s) */
- switch (port_spec & HSO_INTF_MASK) {
- case HSO_INTF_MUX:
- if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) {
- /* Create the network device */
- if (!disable_net) {
- hso_dev = hso_create_net_device(interface,
- port_spec);
- if (!hso_dev)
- goto exit;
- tmp_dev = hso_dev;
- }
- }
-
- if (hso_get_mux_ports(interface, &port_mask))
- /* TODO: de-allocate everything */
- goto exit;
-
- shared_int = hso_create_shared_int(interface);
- if (!shared_int)
- goto exit;
-
- for (i = 1, mux = 0; i < 0x100; i = i << 1, mux++) {
- if (port_mask & i) {
- hso_dev = hso_create_mux_serial_device(
- interface, i, shared_int);
- if (!hso_dev)
- goto exit;
- }
- }
-
- if (tmp_dev)
- hso_dev = tmp_dev;
- break;
-
- case HSO_INTF_BULK:
- /* It's a regular bulk interface */
- if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) {
- if (!disable_net)
- hso_dev =
- hso_create_net_device(interface, port_spec);
- } else {
- hso_dev =
- hso_create_bulk_serial_device(interface, port_spec);
- }
- if (!hso_dev)
- goto exit;
- break;
- default:
- goto exit;
- }
-
- /* save our data pointer in this device */
- usb_set_intfdata(interface, hso_dev);
-
- /* done */
- return 0;
-exit:
- hso_free_interface(interface);
- return -ENODEV;
-}
-
-/* device removed, cleaning up */
-static void hso_disconnect(struct usb_interface *interface)
-{
- hso_free_interface(interface);
-
- /* remove reference of our private data */
- usb_set_intfdata(interface, NULL);
-}
-
-static void async_get_intf(struct work_struct *data)
-{
- struct hso_device *hso_dev =
- container_of(data, struct hso_device, async_get_intf);
- usb_autopm_get_interface(hso_dev->interface);
-}
-
-static void async_put_intf(struct work_struct *data)
-{
- struct hso_device *hso_dev =
- container_of(data, struct hso_device, async_put_intf);
- usb_autopm_put_interface(hso_dev->interface);
-}
-
-static int hso_get_activity(struct hso_device *hso_dev)
-{
- if (hso_dev->usb->state == USB_STATE_SUSPENDED) {
- if (!hso_dev->is_active) {
- hso_dev->is_active = 1;
- schedule_work(&hso_dev->async_get_intf);
- }
- }
-
- if (hso_dev->usb->state != USB_STATE_CONFIGURED)
- return -EAGAIN;
-
- usb_mark_last_busy(hso_dev->usb);
-
- return 0;
-}
-
-static int hso_put_activity(struct hso_device *hso_dev)
-{
- if (hso_dev->usb->state != USB_STATE_SUSPENDED) {
- if (hso_dev->is_active) {
- hso_dev->is_active = 0;
- schedule_work(&hso_dev->async_put_intf);
- return -EAGAIN;
- }
- }
- hso_dev->is_active = 0;
- return 0;
-}
-
-/* called by kernel when we need to suspend device */
-static int hso_suspend(struct usb_interface *iface, pm_message_t message)
-{
- int i, result;
-
- /* Stop all serial ports */
- for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
- if (serial_table[i] && (serial_table[i]->interface == iface)) {
- result = hso_stop_serial_device(serial_table[i]);
- if (result)
- goto out;
- }
- }
-
- /* Stop all network ports */
- for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
- if (network_table[i] &&
- (network_table[i]->interface == iface)) {
- result = hso_stop_net_device(network_table[i]);
- if (result)
- goto out;
- }
- }
-
-out:
- return 0;
-}
-
-/* called by kernel when we need to resume device */
-static int hso_resume(struct usb_interface *iface)
-{
- int i, result = 0;
- struct hso_net *hso_net;
-
- /* Start all serial ports */
- for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
- if (serial_table[i] && (serial_table[i]->interface == iface)) {
- if (dev2ser(serial_table[i])->open_count) {
- result =
- hso_start_serial_device(serial_table[i], GFP_NOIO);
- hso_kick_transmit(dev2ser(serial_table[i]));
- if (result)
- goto out;
- }
- }
- }
-
- /* Start all network ports */
- for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
- if (network_table[i] &&
- (network_table[i]->interface == iface)) {
- hso_net = dev2net(network_table[i]);
- if (hso_net->flags & IFF_UP) {
- /* First transmit any lingering data,
- then restart the device. */
- if (hso_net->skb_tx_buf) {
- dev_dbg(&iface->dev,
- "Transmitting"
- " lingering data\n");
- hso_net_start_xmit(hso_net->skb_tx_buf,
- hso_net->net);
- hso_net->skb_tx_buf = NULL;
- }
- result = hso_start_net_device(network_table[i]);
- if (result)
- goto out;
- }
- }
- }
-
-out:
- return result;
-}
-
-static void reset_device(struct work_struct *data)
-{
- struct hso_device *hso_dev =
- container_of(data, struct hso_device, reset_device);
- struct usb_device *usb = hso_dev->usb;
- int result;
-
- if (hso_dev->usb_gone) {
- D1("No reset during disconnect\n");
- } else {
- result = usb_lock_device_for_reset(usb, hso_dev->interface);
- if (result < 0)
- D1("unable to lock device for reset: %d\n", result);
- else {
- usb_reset_device(usb);
- usb_unlock_device(usb);
- }
- }
-}
-
-static void hso_serial_ref_free(struct kref *ref)
-{
- struct hso_device *hso_dev = container_of(ref, struct hso_device, ref);
-
- hso_free_serial_device(hso_dev);
-}
-
-static void hso_free_interface(struct usb_interface *interface)
-{
- struct hso_serial *hso_dev;
- struct tty_struct *tty;
- int i;
-
- for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
- if (serial_table[i] &&
- (serial_table[i]->interface == interface)) {
- hso_dev = dev2ser(serial_table[i]);
- spin_lock_irq(&hso_dev->serial_lock);
- tty = tty_kref_get(hso_dev->tty);
- spin_unlock_irq(&hso_dev->serial_lock);
- if (tty)
- tty_hangup(tty);
- mutex_lock(&hso_dev->parent->mutex);
- tty_kref_put(tty);
- hso_dev->parent->usb_gone = 1;
- mutex_unlock(&hso_dev->parent->mutex);
- kref_put(&serial_table[i]->ref, hso_serial_ref_free);
- }
- }
-
- for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
- if (network_table[i] &&
- (network_table[i]->interface == interface)) {
- struct rfkill *rfk = dev2net(network_table[i])->rfkill;
- /* hso_stop_net_device doesn't stop the net queue since
- * traffic needs to start it again when suspended */
- netif_stop_queue(dev2net(network_table[i])->net);
- hso_stop_net_device(network_table[i]);
- cancel_work_sync(&network_table[i]->async_put_intf);
- cancel_work_sync(&network_table[i]->async_get_intf);
- if (rfk) {
- rfkill_unregister(rfk);
- rfkill_destroy(rfk);
- }
- hso_free_net_device(network_table[i]);
- }
- }
-}
-
-/* Helper functions */
-
-/* Get the endpoint ! */
-static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf,
- int type, int dir)
-{
- int i;
- struct usb_host_interface *iface = intf->cur_altsetting;
- struct usb_endpoint_descriptor *endp;
-
- for (i = 0; i < iface->desc.bNumEndpoints; i++) {
- endp = &iface->endpoint[i].desc;
- if (((endp->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == dir) &&
- (usb_endpoint_type(endp) == type))
- return endp;
- }
-
- return NULL;
-}
-
-/* Get the byte that describes which ports are enabled */
-static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports)
-{
- int i;
- struct usb_host_interface *iface = intf->cur_altsetting;
-
- if (iface->extralen == 3) {
- *ports = iface->extra[2];
- return 0;
- }
-
- for (i = 0; i < iface->desc.bNumEndpoints; i++) {
- if (iface->endpoint[i].extralen == 3) {
- *ports = iface->endpoint[i].extra[2];
- return 0;
- }
- }
-
- return -1;
-}
-
-/* interrupt urb needs to be submitted, used for serial read of muxed port */
-static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int,
- struct usb_device *usb, gfp_t gfp)
-{
- int result;
-
- usb_fill_int_urb(shared_int->shared_intr_urb, usb,
- usb_rcvintpipe(usb,
- shared_int->intr_endp->bEndpointAddress & 0x7F),
- shared_int->shared_intr_buf,
- 1,
- intr_callback, shared_int,
- shared_int->intr_endp->bInterval);
-
- result = usb_submit_urb(shared_int->shared_intr_urb, gfp);
- if (result)
- dev_warn(&usb->dev, "%s failed mux_intr_urb %d\n", __func__,
- result);
-
- return result;
-}
-
-/* operations setup of the serial interface */
-static const struct tty_operations hso_serial_ops = {
- .open = hso_serial_open,
- .close = hso_serial_close,
- .write = hso_serial_write,
- .write_room = hso_serial_write_room,
- .ioctl = hso_serial_ioctl,
- .set_termios = hso_serial_set_termios,
- .chars_in_buffer = hso_serial_chars_in_buffer,
- .tiocmget = hso_serial_tiocmget,
- .tiocmset = hso_serial_tiocmset,
- .get_icount = hso_get_count,
- .unthrottle = hso_unthrottle
-};
-
-static struct usb_driver hso_driver = {
- .name = driver_name,
- .probe = hso_probe,
- .disconnect = hso_disconnect,
- .id_table = hso_ids,
- .suspend = hso_suspend,
- .resume = hso_resume,
- .reset_resume = hso_resume,
- .supports_autosuspend = 1,
-};
-
-static int __init hso_init(void)
-{
- int i;
- int result;
-
- /* put it in the log */
- printk(KERN_INFO "hso: %s\n", version);
-
- /* Initialise the serial table semaphore and table */
- spin_lock_init(&serial_table_lock);
- for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++)
- serial_table[i] = NULL;
-
- /* allocate our driver using the proper amount of supported minors */
- tty_drv = alloc_tty_driver(HSO_SERIAL_TTY_MINORS);
- if (!tty_drv)
- return -ENOMEM;
-
- /* fill in all needed values */
- tty_drv->magic = TTY_DRIVER_MAGIC;
- tty_drv->driver_name = driver_name;
- tty_drv->name = tty_filename;
-
- /* if major number is provided as parameter, use that one */
- if (tty_major)
- tty_drv->major = tty_major;
-
- tty_drv->minor_start = 0;
- tty_drv->type = TTY_DRIVER_TYPE_SERIAL;
- tty_drv->subtype = SERIAL_TYPE_NORMAL;
- tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
- tty_drv->init_termios = tty_std_termios;
- hso_init_termios(&tty_drv->init_termios);
- tty_set_operations(tty_drv, &hso_serial_ops);
-
- /* register the tty driver */
- result = tty_register_driver(tty_drv);
- if (result) {
- printk(KERN_ERR "%s - tty_register_driver failed(%d)\n",
- __func__, result);
- return result;
- }
-
- /* register this module as an usb driver */
- result = usb_register(&hso_driver);
- if (result) {
- printk(KERN_ERR "Could not register hso driver? error: %d\n",
- result);
- /* cleanup serial interface */
- tty_unregister_driver(tty_drv);
- return result;
- }
-
- /* done */
- return 0;
-}
-
-static void __exit hso_exit(void)
-{
- printk(KERN_INFO "hso: unloaded\n");
-
- tty_unregister_driver(tty_drv);
- /* deregister the usb driver */
- usb_deregister(&hso_driver);
-}
-
-/* Module definitions */
-module_init(hso_init);
-module_exit(hso_exit);
-
-MODULE_AUTHOR(MOD_AUTHOR);
-MODULE_DESCRIPTION(MOD_DESCRIPTION);
-MODULE_LICENSE(MOD_LICENSE);
-
-/* change the debug level (eg: insmod hso.ko debug=0x04) */
-MODULE_PARM_DESC(debug, "Level of debug [0x01 | 0x02 | 0x04 | 0x08 | 0x10]");
-module_param(debug, int, S_IRUGO | S_IWUSR);
-
-/* set the major tty number (eg: insmod hso.ko tty_major=245) */
-MODULE_PARM_DESC(tty_major, "Set the major tty number");
-module_param(tty_major, int, S_IRUGO | S_IWUSR);
-
-/* disable network interface (eg: insmod hso.ko disable_net=1) */
-MODULE_PARM_DESC(disable_net, "Disable the network interface");
-module_param(disable_net, int, S_IRUGO | S_IWUSR);
diff --git a/ANDROID_3.4.5/drivers/net/usb/int51x1.c b/ANDROID_3.4.5/drivers/net/usb/int51x1.c
deleted file mode 100644
index 12a22a45..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/int51x1.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (c) 2009 Peter Holik
- *
- * Intellon usb PLC (Powerline Communications) usb net driver
- *
- * http://www.tandel.be/downloads/INT51X1_Datasheet.pdf
- *
- * Based on the work of Jan 'RedBully' Seiffert
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or.
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/ctype.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/slab.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/usb/usbnet.h>
-
-#define INT51X1_VENDOR_ID 0x09e1
-#define INT51X1_PRODUCT_ID 0x5121
-
-#define INT51X1_HEADER_SIZE 2 /* 2 byte header */
-
-#define PACKET_TYPE_PROMISCUOUS (1 << 0)
-#define PACKET_TYPE_ALL_MULTICAST (1 << 1) /* no filter */
-#define PACKET_TYPE_DIRECTED (1 << 2)
-#define PACKET_TYPE_BROADCAST (1 << 3)
-#define PACKET_TYPE_MULTICAST (1 << 4) /* filtered */
-
-#define SET_ETHERNET_PACKET_FILTER 0x43
-
-static int int51x1_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- int len;
-
- if (!(pskb_may_pull(skb, INT51X1_HEADER_SIZE))) {
- netdev_err(dev->net, "unexpected tiny rx frame\n");
- return 0;
- }
-
- len = le16_to_cpu(*(__le16 *)&skb->data[skb->len - 2]);
-
- skb_trim(skb, len);
-
- return 1;
-}
-
-static struct sk_buff *int51x1_tx_fixup(struct usbnet *dev,
- struct sk_buff *skb, gfp_t flags)
-{
- int pack_len = skb->len;
- int pack_with_header_len = pack_len + INT51X1_HEADER_SIZE;
- int headroom = skb_headroom(skb);
- int tailroom = skb_tailroom(skb);
- int need_tail = 0;
- __le16 *len;
-
- /* if packet and our header is smaler than 64 pad to 64 (+ ZLP) */
- if ((pack_with_header_len) < dev->maxpacket)
- need_tail = dev->maxpacket - pack_with_header_len + 1;
- /*
- * usbnet would send a ZLP if packetlength mod urbsize == 0 for us,
- * but we need to know ourself, because this would add to the length
- * we send down to the device...
- */
- else if (!(pack_with_header_len % dev->maxpacket))
- need_tail = 1;
-
- if (!skb_cloned(skb) &&
- (headroom + tailroom >= need_tail + INT51X1_HEADER_SIZE)) {
- if (headroom < INT51X1_HEADER_SIZE || tailroom < need_tail) {
- skb->data = memmove(skb->head + INT51X1_HEADER_SIZE,
- skb->data, skb->len);
- skb_set_tail_pointer(skb, skb->len);
- }
- } else {
- struct sk_buff *skb2;
-
- skb2 = skb_copy_expand(skb,
- INT51X1_HEADER_SIZE,
- need_tail,
- flags);
- dev_kfree_skb_any(skb);
- if (!skb2)
- return NULL;
- skb = skb2;
- }
-
- pack_len += need_tail;
- pack_len &= 0x07ff;
-
- len = (__le16 *) __skb_push(skb, INT51X1_HEADER_SIZE);
- *len = cpu_to_le16(pack_len);
-
- if(need_tail)
- memset(__skb_put(skb, need_tail), 0, need_tail);
-
- return skb;
-}
-
-static void int51x1_async_cmd_callback(struct urb *urb)
-{
- struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
- int status = urb->status;
-
- if (status < 0)
- dev_warn(&urb->dev->dev, "async callback failed with %d\n", status);
-
- kfree(req);
- usb_free_urb(urb);
-}
-
-static void int51x1_set_multicast(struct net_device *netdev)
-{
- struct usb_ctrlrequest *req;
- int status;
- struct urb *urb;
- struct usbnet *dev = netdev_priv(netdev);
- u16 filter = PACKET_TYPE_DIRECTED | PACKET_TYPE_BROADCAST;
-
- if (netdev->flags & IFF_PROMISC) {
- /* do not expect to see traffic of other PLCs */
- filter |= PACKET_TYPE_PROMISCUOUS;
- netdev_info(dev->net, "promiscuous mode enabled\n");
- } else if (!netdev_mc_empty(netdev) ||
- (netdev->flags & IFF_ALLMULTI)) {
- filter |= PACKET_TYPE_ALL_MULTICAST;
- netdev_dbg(dev->net, "receive all multicast enabled\n");
- } else {
- /* ~PROMISCUOUS, ~MULTICAST */
- netdev_dbg(dev->net, "receive own packets only\n");
- }
-
- urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!urb) {
- netdev_warn(dev->net, "Error allocating URB\n");
- return;
- }
-
- req = kmalloc(sizeof(*req), GFP_ATOMIC);
- if (!req) {
- netdev_warn(dev->net, "Error allocating control msg\n");
- goto out;
- }
-
- req->bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
- req->bRequest = SET_ETHERNET_PACKET_FILTER;
- req->wValue = cpu_to_le16(filter);
- req->wIndex = 0;
- req->wLength = 0;
-
- usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0),
- (void *)req, NULL, 0,
- int51x1_async_cmd_callback,
- (void *)req);
-
- status = usb_submit_urb(urb, GFP_ATOMIC);
- if (status < 0) {
- netdev_warn(dev->net, "Error submitting control msg, sts=%d\n",
- status);
- goto out1;
- }
- return;
-out1:
- kfree(req);
-out:
- usb_free_urb(urb);
-}
-
-static const struct net_device_ops int51x1_netdev_ops = {
- .ndo_open = usbnet_open,
- .ndo_stop = usbnet_stop,
- .ndo_start_xmit = usbnet_start_xmit,
- .ndo_tx_timeout = usbnet_tx_timeout,
- .ndo_change_mtu = usbnet_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_rx_mode = int51x1_set_multicast,
-};
-
-static int int51x1_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- int status = usbnet_get_ethernet_addr(dev, 3);
-
- if (status)
- return status;
-
- dev->net->hard_header_len += INT51X1_HEADER_SIZE;
- dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
- dev->net->netdev_ops = &int51x1_netdev_ops;
-
- return usbnet_get_endpoints(dev, intf);
-}
-
-static const struct driver_info int51x1_info = {
- .description = "Intellon usb powerline adapter",
- .bind = int51x1_bind,
- .rx_fixup = int51x1_rx_fixup,
- .tx_fixup = int51x1_tx_fixup,
- .in = 1,
- .out = 2,
- .flags = FLAG_ETHER,
-};
-
-static const struct usb_device_id products[] = {
- {
- USB_DEVICE(INT51X1_VENDOR_ID, INT51X1_PRODUCT_ID),
- .driver_info = (unsigned long) &int51x1_info,
- },
- {},
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver int51x1_driver = {
- .name = "int51x1",
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
-};
-
-module_usb_driver(int51x1_driver);
-
-MODULE_AUTHOR("Peter Holik");
-MODULE_DESCRIPTION("Intellon usb powerline adapter");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/ipheth.c b/ANDROID_3.4.5/drivers/net/usb/ipheth.c
deleted file mode 100644
index 5cba4151..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/ipheth.c
+++ /dev/null
@@ -1,560 +0,0 @@
-/*
- * ipheth.c - Apple iPhone USB Ethernet driver
- *
- * Copyright (c) 2009 Diego Giagio <diego@giagio.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of GIAGIO.COM nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * Alternatively, provided that this notice is retained in full, this
- * software may be distributed under the terms of the GNU General
- * Public License ("GPL") version 2, in which case the provisions of the
- * GPL apply INSTEAD OF those given above.
- *
- * The provided data structures and external interfaces from this code
- * are not restricted to be used by modules with a GPL compatible license.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- *
- * Attention: iPhone device must be paired, otherwise it won't respond to our
- * driver. For more info: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/usb.h>
-#include <linux/workqueue.h>
-
-#define USB_VENDOR_APPLE 0x05ac
-#define USB_PRODUCT_IPHONE 0x1290
-#define USB_PRODUCT_IPHONE_3G 0x1292
-#define USB_PRODUCT_IPHONE_3GS 0x1294
-#define USB_PRODUCT_IPHONE_4 0x1297
-#define USB_PRODUCT_IPAD 0x129a
-#define USB_PRODUCT_IPHONE_4_VZW 0x129c
-#define USB_PRODUCT_IPHONE_4S 0x12a0
-
-#define IPHETH_USBINTF_CLASS 255
-#define IPHETH_USBINTF_SUBCLASS 253
-#define IPHETH_USBINTF_PROTO 1
-
-#define IPHETH_BUF_SIZE 1516
-#define IPHETH_IP_ALIGN 2 /* padding at front of URB */
-#define IPHETH_TX_TIMEOUT (5 * HZ)
-
-#define IPHETH_INTFNUM 2
-#define IPHETH_ALT_INTFNUM 1
-
-#define IPHETH_CTRL_ENDP 0x00
-#define IPHETH_CTRL_BUF_SIZE 0x40
-#define IPHETH_CTRL_TIMEOUT (5 * HZ)
-
-#define IPHETH_CMD_GET_MACADDR 0x00
-#define IPHETH_CMD_CARRIER_CHECK 0x45
-
-#define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ)
-#define IPHETH_CARRIER_ON 0x04
-
-static struct usb_device_id ipheth_table[] = {
- { USB_DEVICE_AND_INTERFACE_INFO(
- USB_VENDOR_APPLE, USB_PRODUCT_IPHONE,
- IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
- IPHETH_USBINTF_PROTO) },
- { USB_DEVICE_AND_INTERFACE_INFO(
- USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3G,
- IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
- IPHETH_USBINTF_PROTO) },
- { USB_DEVICE_AND_INTERFACE_INFO(
- USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS,
- IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
- IPHETH_USBINTF_PROTO) },
- { USB_DEVICE_AND_INTERFACE_INFO(
- USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4,
- IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
- IPHETH_USBINTF_PROTO) },
- { USB_DEVICE_AND_INTERFACE_INFO(
- USB_VENDOR_APPLE, USB_PRODUCT_IPAD,
- 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) },
- { USB_DEVICE_AND_INTERFACE_INFO(
- USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4S,
- IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
- IPHETH_USBINTF_PROTO) },
- { }
-};
-MODULE_DEVICE_TABLE(usb, ipheth_table);
-
-struct ipheth_device {
- struct usb_device *udev;
- struct usb_interface *intf;
- struct net_device *net;
- struct sk_buff *tx_skb;
- struct urb *tx_urb;
- struct urb *rx_urb;
- unsigned char *tx_buf;
- unsigned char *rx_buf;
- unsigned char *ctrl_buf;
- u8 bulk_in;
- u8 bulk_out;
- struct delayed_work carrier_work;
-};
-
-static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags);
-
-static int ipheth_alloc_urbs(struct ipheth_device *iphone)
-{
- struct urb *tx_urb = NULL;
- struct urb *rx_urb = NULL;
- u8 *tx_buf = NULL;
- u8 *rx_buf = NULL;
-
- tx_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (tx_urb == NULL)
- goto error_nomem;
-
- rx_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (rx_urb == NULL)
- goto free_tx_urb;
-
- tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE,
- GFP_KERNEL, &tx_urb->transfer_dma);
- if (tx_buf == NULL)
- goto free_rx_urb;
-
- rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE,
- GFP_KERNEL, &rx_urb->transfer_dma);
- if (rx_buf == NULL)
- goto free_tx_buf;
-
-
- iphone->tx_urb = tx_urb;
- iphone->rx_urb = rx_urb;
- iphone->tx_buf = tx_buf;
- iphone->rx_buf = rx_buf;
- return 0;
-
-free_tx_buf:
- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, tx_buf,
- tx_urb->transfer_dma);
-free_rx_urb:
- usb_free_urb(rx_urb);
-free_tx_urb:
- usb_free_urb(tx_urb);
-error_nomem:
- return -ENOMEM;
-}
-
-static void ipheth_free_urbs(struct ipheth_device *iphone)
-{
- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->rx_buf,
- iphone->rx_urb->transfer_dma);
- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf,
- iphone->tx_urb->transfer_dma);
- usb_free_urb(iphone->rx_urb);
- usb_free_urb(iphone->tx_urb);
-}
-
-static void ipheth_kill_urbs(struct ipheth_device *dev)
-{
- usb_kill_urb(dev->tx_urb);
- usb_kill_urb(dev->rx_urb);
-}
-
-static void ipheth_rcvbulk_callback(struct urb *urb)
-{
- struct ipheth_device *dev;
- struct sk_buff *skb;
- int status;
- char *buf;
- int len;
-
- dev = urb->context;
- if (dev == NULL)
- return;
-
- status = urb->status;
- switch (status) {
- case -ENOENT:
- case -ECONNRESET:
- case -ESHUTDOWN:
- return;
- case 0:
- break;
- default:
- err("%s: urb status: %d", __func__, status);
- return;
- }
-
- if (urb->actual_length <= IPHETH_IP_ALIGN) {
- dev->net->stats.rx_length_errors++;
- return;
- }
- len = urb->actual_length - IPHETH_IP_ALIGN;
- buf = urb->transfer_buffer + IPHETH_IP_ALIGN;
-
- skb = dev_alloc_skb(len);
- if (!skb) {
- err("%s: dev_alloc_skb: -ENOMEM", __func__);
- dev->net->stats.rx_dropped++;
- return;
- }
-
- memcpy(skb_put(skb, len), buf, len);
- skb->dev = dev->net;
- skb->protocol = eth_type_trans(skb, dev->net);
-
- dev->net->stats.rx_packets++;
- dev->net->stats.rx_bytes += len;
-
- netif_rx(skb);
- ipheth_rx_submit(dev, GFP_ATOMIC);
-}
-
-static void ipheth_sndbulk_callback(struct urb *urb)
-{
- struct ipheth_device *dev;
- int status = urb->status;
-
- dev = urb->context;
- if (dev == NULL)
- return;
-
- if (status != 0 &&
- status != -ENOENT &&
- status != -ECONNRESET &&
- status != -ESHUTDOWN)
- err("%s: urb status: %d", __func__, status);
-
- dev_kfree_skb_irq(dev->tx_skb);
- netif_wake_queue(dev->net);
-}
-
-static int ipheth_carrier_set(struct ipheth_device *dev)
-{
- struct usb_device *udev = dev->udev;
- int retval;
-
- retval = usb_control_msg(udev,
- usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP),
- IPHETH_CMD_CARRIER_CHECK, /* request */
- 0xc0, /* request type */
- 0x00, /* value */
- 0x02, /* index */
- dev->ctrl_buf, IPHETH_CTRL_BUF_SIZE,
- IPHETH_CTRL_TIMEOUT);
- if (retval < 0) {
- err("%s: usb_control_msg: %d", __func__, retval);
- return retval;
- }
-
- if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON)
- netif_carrier_on(dev->net);
- else
- netif_carrier_off(dev->net);
-
- return 0;
-}
-
-static void ipheth_carrier_check_work(struct work_struct *work)
-{
- struct ipheth_device *dev = container_of(work, struct ipheth_device,
- carrier_work.work);
-
- ipheth_carrier_set(dev);
- schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT);
-}
-
-static int ipheth_get_macaddr(struct ipheth_device *dev)
-{
- struct usb_device *udev = dev->udev;
- struct net_device *net = dev->net;
- int retval;
-
- retval = usb_control_msg(udev,
- usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP),
- IPHETH_CMD_GET_MACADDR, /* request */
- 0xc0, /* request type */
- 0x00, /* value */
- 0x02, /* index */
- dev->ctrl_buf,
- IPHETH_CTRL_BUF_SIZE,
- IPHETH_CTRL_TIMEOUT);
- if (retval < 0) {
- err("%s: usb_control_msg: %d", __func__, retval);
- } else if (retval < ETH_ALEN) {
- err("%s: usb_control_msg: short packet: %d bytes",
- __func__, retval);
- retval = -EINVAL;
- } else {
- memcpy(net->dev_addr, dev->ctrl_buf, ETH_ALEN);
- retval = 0;
- }
-
- return retval;
-}
-
-static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags)
-{
- struct usb_device *udev = dev->udev;
- int retval;
-
- usb_fill_bulk_urb(dev->rx_urb, udev,
- usb_rcvbulkpipe(udev, dev->bulk_in),
- dev->rx_buf, IPHETH_BUF_SIZE,
- ipheth_rcvbulk_callback,
- dev);
- dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- retval = usb_submit_urb(dev->rx_urb, mem_flags);
- if (retval)
- err("%s: usb_submit_urb: %d", __func__, retval);
- return retval;
-}
-
-static int ipheth_open(struct net_device *net)
-{
- struct ipheth_device *dev = netdev_priv(net);
- struct usb_device *udev = dev->udev;
- int retval = 0;
-
- usb_set_interface(udev, IPHETH_INTFNUM, IPHETH_ALT_INTFNUM);
-
- retval = ipheth_carrier_set(dev);
- if (retval)
- return retval;
-
- retval = ipheth_rx_submit(dev, GFP_KERNEL);
- if (retval)
- return retval;
-
- schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT);
- netif_start_queue(net);
- return retval;
-}
-
-static int ipheth_close(struct net_device *net)
-{
- struct ipheth_device *dev = netdev_priv(net);
-
- cancel_delayed_work_sync(&dev->carrier_work);
- netif_stop_queue(net);
- return 0;
-}
-
-static int ipheth_tx(struct sk_buff *skb, struct net_device *net)
-{
- struct ipheth_device *dev = netdev_priv(net);
- struct usb_device *udev = dev->udev;
- int retval;
-
- /* Paranoid */
- if (skb->len > IPHETH_BUF_SIZE) {
- WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len);
- dev->net->stats.tx_dropped++;
- dev_kfree_skb_irq(skb);
- return NETDEV_TX_OK;
- }
-
- memcpy(dev->tx_buf, skb->data, skb->len);
- if (skb->len < IPHETH_BUF_SIZE)
- memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb->len);
-
- usb_fill_bulk_urb(dev->tx_urb, udev,
- usb_sndbulkpipe(udev, dev->bulk_out),
- dev->tx_buf, IPHETH_BUF_SIZE,
- ipheth_sndbulk_callback,
- dev);
- dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC);
- if (retval) {
- err("%s: usb_submit_urb: %d", __func__, retval);
- dev->net->stats.tx_errors++;
- dev_kfree_skb_irq(skb);
- } else {
- dev->tx_skb = skb;
-
- dev->net->stats.tx_packets++;
- dev->net->stats.tx_bytes += skb->len;
- netif_stop_queue(net);
- }
-
- return NETDEV_TX_OK;
-}
-
-static void ipheth_tx_timeout(struct net_device *net)
-{
- struct ipheth_device *dev = netdev_priv(net);
-
- err("%s: TX timeout", __func__);
- dev->net->stats.tx_errors++;
- usb_unlink_urb(dev->tx_urb);
-}
-
-static u32 ipheth_ethtool_op_get_link(struct net_device *net)
-{
- struct ipheth_device *dev = netdev_priv(net);
- return netif_carrier_ok(dev->net);
-}
-
-static const struct ethtool_ops ops = {
- .get_link = ipheth_ethtool_op_get_link
-};
-
-static const struct net_device_ops ipheth_netdev_ops = {
- .ndo_open = ipheth_open,
- .ndo_stop = ipheth_close,
- .ndo_start_xmit = ipheth_tx,
- .ndo_tx_timeout = ipheth_tx_timeout,
-};
-
-static int ipheth_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct usb_host_interface *hintf;
- struct usb_endpoint_descriptor *endp;
- struct ipheth_device *dev;
- struct net_device *netdev;
- int i;
- int retval;
-
- netdev = alloc_etherdev(sizeof(struct ipheth_device));
- if (!netdev)
- return -ENOMEM;
-
- netdev->netdev_ops = &ipheth_netdev_ops;
- netdev->watchdog_timeo = IPHETH_TX_TIMEOUT;
- strcpy(netdev->name, "eth%d");
-
- dev = netdev_priv(netdev);
- dev->udev = udev;
- dev->net = netdev;
- dev->intf = intf;
-
- /* Set up endpoints */
- hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM);
- if (hintf == NULL) {
- retval = -ENODEV;
- err("Unable to find alternate settings interface");
- goto err_endpoints;
- }
-
- for (i = 0; i < hintf->desc.bNumEndpoints; i++) {
- endp = &hintf->endpoint[i].desc;
- if (usb_endpoint_is_bulk_in(endp))
- dev->bulk_in = endp->bEndpointAddress;
- else if (usb_endpoint_is_bulk_out(endp))
- dev->bulk_out = endp->bEndpointAddress;
- }
- if (!(dev->bulk_in && dev->bulk_out)) {
- retval = -ENODEV;
- err("Unable to find endpoints");
- goto err_endpoints;
- }
-
- dev->ctrl_buf = kmalloc(IPHETH_CTRL_BUF_SIZE, GFP_KERNEL);
- if (dev->ctrl_buf == NULL) {
- retval = -ENOMEM;
- goto err_alloc_ctrl_buf;
- }
-
- retval = ipheth_get_macaddr(dev);
- if (retval)
- goto err_get_macaddr;
-
- INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work);
-
- retval = ipheth_alloc_urbs(dev);
- if (retval) {
- err("error allocating urbs: %d", retval);
- goto err_alloc_urbs;
- }
-
- usb_set_intfdata(intf, dev);
-
- SET_NETDEV_DEV(netdev, &intf->dev);
- SET_ETHTOOL_OPS(netdev, &ops);
-
- retval = register_netdev(netdev);
- if (retval) {
- err("error registering netdev: %d", retval);
- retval = -EIO;
- goto err_register_netdev;
- }
-
- dev_info(&intf->dev, "Apple iPhone USB Ethernet device attached\n");
- return 0;
-
-err_register_netdev:
- ipheth_free_urbs(dev);
-err_alloc_urbs:
-err_get_macaddr:
-err_alloc_ctrl_buf:
- kfree(dev->ctrl_buf);
-err_endpoints:
- free_netdev(netdev);
- return retval;
-}
-
-static void ipheth_disconnect(struct usb_interface *intf)
-{
- struct ipheth_device *dev;
-
- dev = usb_get_intfdata(intf);
- if (dev != NULL) {
- unregister_netdev(dev->net);
- ipheth_kill_urbs(dev);
- ipheth_free_urbs(dev);
- kfree(dev->ctrl_buf);
- free_netdev(dev->net);
- }
- usb_set_intfdata(intf, NULL);
- dev_info(&intf->dev, "Apple iPhone USB Ethernet now disconnected\n");
-}
-
-static struct usb_driver ipheth_driver = {
- .name = "ipheth",
- .probe = ipheth_probe,
- .disconnect = ipheth_disconnect,
- .id_table = ipheth_table,
-};
-
-module_usb_driver(ipheth_driver);
-
-MODULE_AUTHOR("Diego Giagio <diego@giagio.com>");
-MODULE_DESCRIPTION("Apple iPhone USB Ethernet driver");
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/kalmia.c b/ANDROID_3.4.5/drivers/net/usb/kalmia.c
deleted file mode 100644
index 7562649b..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/kalmia.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * USB network interface driver for Samsung Kalmia based LTE USB modem like the
- * Samsung GT-B3730 and GT-B3710.
- *
- * Copyright (C) 2011 Marius Bjoernstad Kotsbak <marius@kotsbak.com>
- *
- * Sponsored by Quicklink Video Distribution Services Ltd.
- *
- * Based on the cdc_eem module.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ctype.h>
-#include <linux/ethtool.h>
-#include <linux/workqueue.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/crc32.h>
-#include <linux/usb/cdc.h>
-#include <linux/usb/usbnet.h>
-#include <linux/gfp.h>
-
-/*
- * The Samsung Kalmia based LTE USB modems have a CDC ACM port for modem control
- * handled by the "option" module and an ethernet data port handled by this
- * module.
- *
- * The stick must first be switched into modem mode by usb_modeswitch
- * or similar tool. Then the modem gets sent two initialization packets by
- * this module, which gives the MAC address of the device. User space can then
- * connect the modem using AT commands through the ACM port and then use
- * DHCP on the network interface exposed by this module. Network packets are
- * sent to and from the modem in a proprietary format discovered after watching
- * the behavior of the windows driver for the modem.
- *
- * More information about the use of the modem is available in usb_modeswitch
- * forum and the project page:
- *
- * http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=465
- * https://github.com/mkotsbak/Samsung-GT-B3730-linux-driver
- */
-
-/* #define DEBUG */
-/* #define VERBOSE */
-
-#define KALMIA_HEADER_LENGTH 6
-#define KALMIA_ALIGN_SIZE 4
-#define KALMIA_USB_TIMEOUT 10000
-
-/*-------------------------------------------------------------------------*/
-
-static int
-kalmia_send_init_packet(struct usbnet *dev, u8 *init_msg, u8 init_msg_len,
- u8 *buffer, u8 expected_len)
-{
- int act_len;
- int status;
-
- netdev_dbg(dev->net, "Sending init packet");
-
- status = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 0x02),
- init_msg, init_msg_len, &act_len, KALMIA_USB_TIMEOUT);
- if (status != 0) {
- netdev_err(dev->net,
- "Error sending init packet. Status %i, length %i\n",
- status, act_len);
- return status;
- }
- else if (act_len != init_msg_len) {
- netdev_err(dev->net,
- "Did not send all of init packet. Bytes sent: %i",
- act_len);
- }
- else {
- netdev_dbg(dev->net, "Successfully sent init packet.");
- }
-
- status = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, 0x81),
- buffer, expected_len, &act_len, KALMIA_USB_TIMEOUT);
-
- if (status != 0)
- netdev_err(dev->net,
- "Error receiving init result. Status %i, length %i\n",
- status, act_len);
- else if (act_len != expected_len)
- netdev_err(dev->net, "Unexpected init result length: %i\n",
- act_len);
-
- return status;
-}
-
-static int
-kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr)
-{
- static const char init_msg_1[] =
- { 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
- 0x00, 0x00 };
- static const char init_msg_2[] =
- { 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf4,
- 0x00, 0x00 };
- static const int buflen = 28;
- char *usb_buf;
- int status;
-
- usb_buf = kmalloc(buflen, GFP_DMA | GFP_KERNEL);
- if (!usb_buf)
- return -ENOMEM;
-
- memcpy(usb_buf, init_msg_1, 12);
- status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_1)
- / sizeof(init_msg_1[0]), usb_buf, 24);
- if (status != 0)
- return status;
-
- memcpy(usb_buf, init_msg_2, 12);
- status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_2)
- / sizeof(init_msg_2[0]), usb_buf, 28);
- if (status != 0)
- return status;
-
- memcpy(ethernet_addr, usb_buf + 10, ETH_ALEN);
-
- kfree(usb_buf);
- return status;
-}
-
-static int
-kalmia_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- int status;
- u8 ethernet_addr[ETH_ALEN];
-
- /* Don't bind to AT command interface */
- if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
- return -EINVAL;
-
- dev->in = usb_rcvbulkpipe(dev->udev, 0x81 & USB_ENDPOINT_NUMBER_MASK);
- dev->out = usb_sndbulkpipe(dev->udev, 0x02 & USB_ENDPOINT_NUMBER_MASK);
- dev->status = NULL;
-
- dev->net->hard_header_len += KALMIA_HEADER_LENGTH;
- dev->hard_mtu = 1400;
- dev->rx_urb_size = dev->hard_mtu * 10; // Found as optimal after testing
-
- status = kalmia_init_and_get_ethernet_addr(dev, ethernet_addr);
-
- if (status < 0) {
- usb_set_intfdata(intf, NULL);
- usb_driver_release_interface(driver_of(intf), intf);
- return status;
- }
-
- memcpy(dev->net->dev_addr, ethernet_addr, ETH_ALEN);
- memcpy(dev->net->perm_addr, ethernet_addr, ETH_ALEN);
-
- return status;
-}
-
-static struct sk_buff *
-kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
-{
- struct sk_buff *skb2 = NULL;
- u16 content_len;
- unsigned char *header_start;
- unsigned char ether_type_1, ether_type_2;
- u8 remainder, padlen = 0;
-
- if (!skb_cloned(skb)) {
- int headroom = skb_headroom(skb);
- int tailroom = skb_tailroom(skb);
-
- if ((tailroom >= KALMIA_ALIGN_SIZE) && (headroom
- >= KALMIA_HEADER_LENGTH))
- goto done;
-
- if ((headroom + tailroom) > (KALMIA_HEADER_LENGTH
- + KALMIA_ALIGN_SIZE)) {
- skb->data = memmove(skb->head + KALMIA_HEADER_LENGTH,
- skb->data, skb->len);
- skb_set_tail_pointer(skb, skb->len);
- goto done;
- }
- }
-
- skb2 = skb_copy_expand(skb, KALMIA_HEADER_LENGTH,
- KALMIA_ALIGN_SIZE, flags);
- if (!skb2)
- return NULL;
-
- dev_kfree_skb_any(skb);
- skb = skb2;
-
-done:
- header_start = skb_push(skb, KALMIA_HEADER_LENGTH);
- ether_type_1 = header_start[KALMIA_HEADER_LENGTH + 12];
- ether_type_2 = header_start[KALMIA_HEADER_LENGTH + 13];
-
- netdev_dbg(dev->net, "Sending etherType: %02x%02x", ether_type_1,
- ether_type_2);
-
- /* According to empiric data for data packages */
- header_start[0] = 0x57;
- header_start[1] = 0x44;
- content_len = skb->len - KALMIA_HEADER_LENGTH;
-
- put_unaligned_le16(content_len, &header_start[2]);
- header_start[4] = ether_type_1;
- header_start[5] = ether_type_2;
-
- /* Align to 4 bytes by padding with zeros */
- remainder = skb->len % KALMIA_ALIGN_SIZE;
- if (remainder > 0) {
- padlen = KALMIA_ALIGN_SIZE - remainder;
- 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]);
-
- return skb;
-}
-
-static int
-kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- /*
- * Our task here is to strip off framing, leaving skb with one
- * data frame for the usbnet framework code to process.
- */
- static const u8 HEADER_END_OF_USB_PACKET[] =
- { 0x57, 0x5a, 0x00, 0x00, 0x08, 0x00 };
- static const u8 EXPECTED_UNKNOWN_HEADER_1[] =
- { 0x57, 0x43, 0x1e, 0x00, 0x15, 0x02 };
- static const u8 EXPECTED_UNKNOWN_HEADER_2[] =
- { 0x57, 0x50, 0x0e, 0x00, 0x00, 0x00 };
- int i = 0;
-
- /* incomplete header? */
- if (skb->len < KALMIA_HEADER_LENGTH)
- return 0;
-
- do {
- struct sk_buff *skb2 = NULL;
- u8 *header_start;
- u16 usb_packet_length, ether_packet_length;
- int is_last;
-
- header_start = skb->data;
-
- if (unlikely(header_start[0] != 0x57 || header_start[1] != 0x44)) {
- if (!memcmp(header_start, EXPECTED_UNKNOWN_HEADER_1,
- 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],
- 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],
- 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);
-
- /* subtract start header and end header */
- usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH);
- ether_packet_length = get_unaligned_le16(&header_start[2]);
- skb_pull(skb, KALMIA_HEADER_LENGTH);
-
- /* Some small packets misses end marker */
- if (usb_packet_length < ether_packet_length) {
- ether_packet_length = usb_packet_length
- + KALMIA_HEADER_LENGTH;
- is_last = true;
- }
- else {
- netdev_dbg(dev->net, "Correct package length #%i", i
- + 1);
-
- is_last = (memcmp(skb->data + ether_packet_length,
- HEADER_END_OF_USB_PACKET,
- 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],
- skb->len - KALMIA_HEADER_LENGTH);
- }
- }
-
- if (is_last) {
- skb2 = skb;
- }
- else {
- skb2 = skb_clone(skb, GFP_ATOMIC);
- if (unlikely(!skb2))
- return 0;
- }
-
- skb_trim(skb2, ether_packet_length);
-
- if (is_last) {
- return 1;
- }
- else {
- usbnet_skb_return(dev, skb2);
- skb_pull(skb, ether_packet_length);
- }
-
- i++;
- }
- while (skb->len);
-
- return 1;
-}
-
-static const struct driver_info kalmia_info = {
- .description = "Samsung Kalmia LTE USB dongle",
- .flags = FLAG_WWAN,
- .bind = kalmia_bind,
- .rx_fixup = kalmia_rx_fixup,
- .tx_fixup = kalmia_tx_fixup
-};
-
-/*-------------------------------------------------------------------------*/
-
-static const struct usb_device_id products[] = {
- /* The unswitched USB ID, to get the module auto loaded: */
- { USB_DEVICE(0x04e8, 0x689a) },
- /* The stick swithed into modem (by e.g. usb_modeswitch): */
- { USB_DEVICE(0x04e8, 0x6889),
- .driver_info = (unsigned long) &kalmia_info, },
- { /* EMPTY == end of list */} };
-MODULE_DEVICE_TABLE( usb, products);
-
-static struct usb_driver kalmia_driver = {
- .name = "kalmia",
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume
-};
-
-module_usb_driver(kalmia_driver);
-
-MODULE_AUTHOR("Marius Bjoernstad Kotsbak <marius@kotsbak.com>");
-MODULE_DESCRIPTION("Samsung Kalmia USB network driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/kaweth.c b/ANDROID_3.4.5/drivers/net/usb/kaweth.c
deleted file mode 100644
index df2a2cf3..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/kaweth.c
+++ /dev/null
@@ -1,1321 +0,0 @@
-/****************************************************************
- *
- * kaweth.c - driver for KL5KUSB101 based USB->Ethernet
- *
- * (c) 2000 Interlan Communications
- * (c) 2000 Stephane Alnet
- * (C) 2001 Brad Hards
- * (C) 2002 Oliver Neukum
- *
- * Original author: The Zapman <zapman@interlan.net>
- * Inspired by, and much credit goes to Michael Rothwell
- * <rothwell@interlan.net> for the test equipment, help, and patience
- * Based off of (and with thanks to) Petko Manolov's pegaus.c driver.
- * Also many thanks to Joel Silverman and Ed Surprenant at Kawasaki
- * for providing the firmware and driver resources.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- ****************************************************************/
-
-/* TODO:
- * Develop test procedures for USB net interfaces
- * Run test procedures
- * Fix bugs from previous two steps
- * Snoop other OSs for any tricks we're not doing
- * Reduce arbitrary timeouts
- * Smart multicast support
- * Temporary MAC change support
- * Tunable SOFs parameter - ioctl()?
- * Ethernet stats collection
- * Code formatting improvements
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/usb.h>
-#include <linux/types.h>
-#include <linux/ethtool.h>
-#include <linux/dma-mapping.h>
-#include <linux/wait.h>
-#include <linux/firmware.h>
-#include <asm/uaccess.h>
-#include <asm/byteorder.h>
-
-#undef DEBUG
-
-#define KAWETH_MTU 1514
-#define KAWETH_BUF_SIZE 1664
-#define KAWETH_TX_TIMEOUT (5 * HZ)
-#define KAWETH_SCRATCH_SIZE 32
-#define KAWETH_FIRMWARE_BUF_SIZE 4096
-#define KAWETH_CONTROL_TIMEOUT (30000)
-
-#define KAWETH_STATUS_BROKEN 0x0000001
-#define KAWETH_STATUS_CLOSING 0x0000002
-#define KAWETH_STATUS_SUSPENDING 0x0000004
-
-#define KAWETH_STATUS_BLOCKED (KAWETH_STATUS_CLOSING | KAWETH_STATUS_SUSPENDING)
-
-#define KAWETH_PACKET_FILTER_PROMISCUOUS 0x01
-#define KAWETH_PACKET_FILTER_ALL_MULTICAST 0x02
-#define KAWETH_PACKET_FILTER_DIRECTED 0x04
-#define KAWETH_PACKET_FILTER_BROADCAST 0x08
-#define KAWETH_PACKET_FILTER_MULTICAST 0x10
-
-/* Table 7 */
-#define KAWETH_COMMAND_GET_ETHERNET_DESC 0x00
-#define KAWETH_COMMAND_MULTICAST_FILTERS 0x01
-#define KAWETH_COMMAND_SET_PACKET_FILTER 0x02
-#define KAWETH_COMMAND_STATISTICS 0x03
-#define KAWETH_COMMAND_SET_TEMP_MAC 0x06
-#define KAWETH_COMMAND_GET_TEMP_MAC 0x07
-#define KAWETH_COMMAND_SET_URB_SIZE 0x08
-#define KAWETH_COMMAND_SET_SOFS_WAIT 0x09
-#define KAWETH_COMMAND_SCAN 0xFF
-
-#define KAWETH_SOFS_TO_WAIT 0x05
-
-#define INTBUFFERSIZE 4
-
-#define STATE_OFFSET 0
-#define STATE_MASK 0x40
-#define STATE_SHIFT 5
-
-#define IS_BLOCKED(s) (s & KAWETH_STATUS_BLOCKED)
-
-
-MODULE_AUTHOR("Michael Zappe <zapman@interlan.net>, Stephane Alnet <stephane@u-picardie.fr>, Brad Hards <bhards@bigpond.net.au> and Oliver Neukum <oliver@neukum.org>");
-MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE("kaweth/new_code.bin");
-MODULE_FIRMWARE("kaweth/new_code_fix.bin");
-MODULE_FIRMWARE("kaweth/trigger_code.bin");
-MODULE_FIRMWARE("kaweth/trigger_code_fix.bin");
-
-static const char driver_name[] = "kaweth";
-
-static int kaweth_probe(
- struct usb_interface *intf,
- const struct usb_device_id *id /* from id_table */
- );
-static void kaweth_disconnect(struct usb_interface *intf);
-static int kaweth_internal_control_msg(struct usb_device *usb_dev,
- unsigned int pipe,
- struct usb_ctrlrequest *cmd, void *data,
- int len, int timeout);
-static int kaweth_suspend(struct usb_interface *intf, pm_message_t message);
-static int kaweth_resume(struct usb_interface *intf);
-
-/****************************************************************
- * usb_device_id
- ****************************************************************/
-static struct usb_device_id usb_klsi_table[] = {
- { USB_DEVICE(0x03e8, 0x0008) }, /* AOX Endpoints USB Ethernet */
- { USB_DEVICE(0x04bb, 0x0901) }, /* I-O DATA USB-ET/T */
- { USB_DEVICE(0x0506, 0x03e8) }, /* 3Com 3C19250 */
- { USB_DEVICE(0x0506, 0x11f8) }, /* 3Com 3C460 */
- { USB_DEVICE(0x0557, 0x2002) }, /* ATEN USB Ethernet */
- { USB_DEVICE(0x0557, 0x4000) }, /* D-Link DSB-650C */
- { USB_DEVICE(0x0565, 0x0002) }, /* Peracom Enet */
- { USB_DEVICE(0x0565, 0x0003) }, /* Optus@Home UEP1045A */
- { USB_DEVICE(0x0565, 0x0005) }, /* Peracom Enet2 */
- { USB_DEVICE(0x05e9, 0x0008) }, /* KLSI KL5KUSB101B */
- { USB_DEVICE(0x05e9, 0x0009) }, /* KLSI KL5KUSB101B (Board change) */
- { USB_DEVICE(0x066b, 0x2202) }, /* Linksys USB10T */
- { USB_DEVICE(0x06e1, 0x0008) }, /* ADS USB-10BT */
- { USB_DEVICE(0x06e1, 0x0009) }, /* ADS USB-10BT */
- { USB_DEVICE(0x0707, 0x0100) }, /* SMC 2202USB */
- { USB_DEVICE(0x07aa, 0x0001) }, /* Correga K.K. */
- { USB_DEVICE(0x07b8, 0x4000) }, /* D-Link DU-E10 */
- { USB_DEVICE(0x07c9, 0xb010) }, /* Allied Telesyn AT-USB10 USB Ethernet Adapter */
- { USB_DEVICE(0x0846, 0x1001) }, /* NetGear EA-101 */
- { USB_DEVICE(0x0846, 0x1002) }, /* NetGear EA-101 */
- { USB_DEVICE(0x085a, 0x0008) }, /* PortGear Ethernet Adapter */
- { USB_DEVICE(0x085a, 0x0009) }, /* PortGear Ethernet Adapter */
- { USB_DEVICE(0x087d, 0x5704) }, /* Jaton USB Ethernet Device Adapter */
- { USB_DEVICE(0x0951, 0x0008) }, /* Kingston Technology USB Ethernet Adapter */
- { USB_DEVICE(0x095a, 0x3003) }, /* Portsmith Express Ethernet Adapter */
- { USB_DEVICE(0x10bd, 0x1427) }, /* ASANTE USB To Ethernet Adapter */
- { USB_DEVICE(0x1342, 0x0204) }, /* Mobility USB-Ethernet Adapter */
- { USB_DEVICE(0x13d2, 0x0400) }, /* Shark Pocket Adapter */
- { USB_DEVICE(0x1485, 0x0001) }, /* Silicom U2E */
- { USB_DEVICE(0x1485, 0x0002) }, /* Psion Dacom Gold Port Ethernet */
- { USB_DEVICE(0x1645, 0x0005) }, /* Entrega E45 */
- { USB_DEVICE(0x1645, 0x0008) }, /* Entrega USB Ethernet Adapter */
- { USB_DEVICE(0x1645, 0x8005) }, /* PortGear Ethernet Adapter */
- { USB_DEVICE(0x1668, 0x0323) }, /* Actiontec USB Ethernet */
- { USB_DEVICE(0x2001, 0x4000) }, /* D-link DSB-650C */
- {} /* Null terminator */
-};
-
-MODULE_DEVICE_TABLE (usb, usb_klsi_table);
-
-/****************************************************************
- * kaweth_driver
- ****************************************************************/
-static struct usb_driver kaweth_driver = {
- .name = driver_name,
- .probe = kaweth_probe,
- .disconnect = kaweth_disconnect,
- .suspend = kaweth_suspend,
- .resume = kaweth_resume,
- .id_table = usb_klsi_table,
- .supports_autosuspend = 1,
-};
-
-typedef __u8 eth_addr_t[6];
-
-/****************************************************************
- * usb_eth_dev
- ****************************************************************/
-struct usb_eth_dev {
- char *name;
- __u16 vendor;
- __u16 device;
- void *pdata;
-};
-
-/****************************************************************
- * kaweth_ethernet_configuration
- * Refer Table 8
- ****************************************************************/
-struct kaweth_ethernet_configuration
-{
- __u8 size;
- __u8 reserved1;
- __u8 reserved2;
- eth_addr_t hw_addr;
- __u32 statistics_mask;
- __le16 segment_size;
- __u16 max_multicast_filters;
- __u8 reserved3;
-} __packed;
-
-/****************************************************************
- * kaweth_device
- ****************************************************************/
-struct kaweth_device
-{
- spinlock_t device_lock;
-
- __u32 status;
- int end;
- int suspend_lowmem_rx;
- int suspend_lowmem_ctrl;
- int linkstate;
- int opened;
- struct delayed_work lowmem_work;
-
- struct usb_device *dev;
- struct usb_interface *intf;
- struct net_device *net;
- wait_queue_head_t term_wait;
-
- struct urb *rx_urb;
- struct urb *tx_urb;
- struct urb *irq_urb;
-
- dma_addr_t intbufferhandle;
- __u8 *intbuffer;
- dma_addr_t rxbufferhandle;
- __u8 *rx_buf;
-
-
- struct sk_buff *tx_skb;
-
- __u8 *firmware_buf;
- __u8 scratch[KAWETH_SCRATCH_SIZE];
- __u16 packet_filter_bitmap;
-
- struct kaweth_ethernet_configuration configuration;
-
- struct net_device_stats stats;
-};
-
-/****************************************************************
- * kaweth_control
- ****************************************************************/
-static int kaweth_control(struct kaweth_device *kaweth,
- unsigned int pipe,
- __u8 request,
- __u8 requesttype,
- __u16 value,
- __u16 index,
- void *data,
- __u16 size,
- int timeout)
-{
- struct usb_ctrlrequest *dr;
- int retval;
-
- dbg("kaweth_control()");
-
- if(in_interrupt()) {
- dbg("in_interrupt()");
- return -EBUSY;
- }
-
- dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
-
- if (!dr) {
- dbg("kmalloc() failed");
- return -ENOMEM;
- }
-
- dr->bRequestType = requesttype;
- dr->bRequest = request;
- dr->wValue = cpu_to_le16(value);
- dr->wIndex = cpu_to_le16(index);
- dr->wLength = cpu_to_le16(size);
-
- retval = kaweth_internal_control_msg(kaweth->dev,
- pipe,
- dr,
- data,
- size,
- timeout);
-
- kfree(dr);
- return retval;
-}
-
-/****************************************************************
- * kaweth_read_configuration
- ****************************************************************/
-static int kaweth_read_configuration(struct kaweth_device *kaweth)
-{
- int retval;
-
- dbg("Reading kaweth configuration");
-
- retval = kaweth_control(kaweth,
- usb_rcvctrlpipe(kaweth->dev, 0),
- KAWETH_COMMAND_GET_ETHERNET_DESC,
- USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
- 0,
- 0,
- (void *)&kaweth->configuration,
- sizeof(kaweth->configuration),
- KAWETH_CONTROL_TIMEOUT);
-
- return retval;
-}
-
-/****************************************************************
- * kaweth_set_urb_size
- ****************************************************************/
-static int kaweth_set_urb_size(struct kaweth_device *kaweth, __u16 urb_size)
-{
- int retval;
-
- dbg("Setting URB size to %d", (unsigned)urb_size);
-
- retval = kaweth_control(kaweth,
- usb_sndctrlpipe(kaweth->dev, 0),
- KAWETH_COMMAND_SET_URB_SIZE,
- USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
- urb_size,
- 0,
- (void *)&kaweth->scratch,
- 0,
- KAWETH_CONTROL_TIMEOUT);
-
- return retval;
-}
-
-/****************************************************************
- * kaweth_set_sofs_wait
- ****************************************************************/
-static int kaweth_set_sofs_wait(struct kaweth_device *kaweth, __u16 sofs_wait)
-{
- int retval;
-
- dbg("Set SOFS wait to %d", (unsigned)sofs_wait);
-
- retval = kaweth_control(kaweth,
- usb_sndctrlpipe(kaweth->dev, 0),
- KAWETH_COMMAND_SET_SOFS_WAIT,
- USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
- sofs_wait,
- 0,
- (void *)&kaweth->scratch,
- 0,
- KAWETH_CONTROL_TIMEOUT);
-
- return retval;
-}
-
-/****************************************************************
- * kaweth_set_receive_filter
- ****************************************************************/
-static int kaweth_set_receive_filter(struct kaweth_device *kaweth,
- __u16 receive_filter)
-{
- int retval;
-
- dbg("Set receive filter to %d", (unsigned)receive_filter);
-
- retval = kaweth_control(kaweth,
- usb_sndctrlpipe(kaweth->dev, 0),
- KAWETH_COMMAND_SET_PACKET_FILTER,
- USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
- receive_filter,
- 0,
- (void *)&kaweth->scratch,
- 0,
- KAWETH_CONTROL_TIMEOUT);
-
- return retval;
-}
-
-/****************************************************************
- * kaweth_download_firmware
- ****************************************************************/
-static int kaweth_download_firmware(struct kaweth_device *kaweth,
- const char *fwname,
- __u8 interrupt,
- __u8 type)
-{
- const struct firmware *fw;
- int data_len;
- int ret;
-
- ret = request_firmware(&fw, fwname, &kaweth->dev->dev);
- if (ret) {
- err("Firmware request failed\n");
- return ret;
- }
-
- if (fw->size > KAWETH_FIRMWARE_BUF_SIZE) {
- err("Firmware too big: %zu", fw->size);
- release_firmware(fw);
- return -ENOSPC;
- }
- data_len = fw->size;
- memcpy(kaweth->firmware_buf, fw->data, fw->size);
-
- release_firmware(fw);
-
- kaweth->firmware_buf[2] = (data_len & 0xFF) - 7;
- kaweth->firmware_buf[3] = data_len >> 8;
- kaweth->firmware_buf[4] = type;
- kaweth->firmware_buf[5] = interrupt;
-
- dbg("High: %i, Low:%i", kaweth->firmware_buf[3],
- kaweth->firmware_buf[2]);
-
- dbg("Downloading firmware at %p to kaweth device at %p",
- fw->data, kaweth);
- dbg("Firmware length: %d", data_len);
-
- return kaweth_control(kaweth,
- usb_sndctrlpipe(kaweth->dev, 0),
- KAWETH_COMMAND_SCAN,
- USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
- 0,
- 0,
- (void *)kaweth->firmware_buf,
- data_len,
- KAWETH_CONTROL_TIMEOUT);
-}
-
-/****************************************************************
- * kaweth_trigger_firmware
- ****************************************************************/
-static int kaweth_trigger_firmware(struct kaweth_device *kaweth,
- __u8 interrupt)
-{
- kaweth->firmware_buf[0] = 0xB6;
- kaweth->firmware_buf[1] = 0xC3;
- kaweth->firmware_buf[2] = 0x01;
- kaweth->firmware_buf[3] = 0x00;
- kaweth->firmware_buf[4] = 0x06;
- kaweth->firmware_buf[5] = interrupt;
- kaweth->firmware_buf[6] = 0x00;
- kaweth->firmware_buf[7] = 0x00;
-
- dbg("Triggering firmware");
-
- return kaweth_control(kaweth,
- usb_sndctrlpipe(kaweth->dev, 0),
- KAWETH_COMMAND_SCAN,
- USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
- 0,
- 0,
- (void *)kaweth->firmware_buf,
- 8,
- KAWETH_CONTROL_TIMEOUT);
-}
-
-/****************************************************************
- * kaweth_reset
- ****************************************************************/
-static int kaweth_reset(struct kaweth_device *kaweth)
-{
- int result;
-
- dbg("kaweth_reset(%p)", kaweth);
- result = usb_reset_configuration(kaweth->dev);
- mdelay(10);
-
- dbg("kaweth_reset() returns %d.",result);
-
- return result;
-}
-
-static void kaweth_usb_receive(struct urb *);
-static int kaweth_resubmit_rx_urb(struct kaweth_device *, gfp_t);
-
-/****************************************************************
- int_callback
-*****************************************************************/
-
-static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, gfp_t mf)
-{
- int status;
-
- status = usb_submit_urb (kaweth->irq_urb, mf);
- if (unlikely(status == -ENOMEM)) {
- kaweth->suspend_lowmem_ctrl = 1;
- schedule_delayed_work(&kaweth->lowmem_work, HZ/4);
- } else {
- kaweth->suspend_lowmem_ctrl = 0;
- }
-
- if (status)
- err ("can't resubmit intr, %s-%s, status %d",
- kaweth->dev->bus->bus_name,
- kaweth->dev->devpath, status);
-}
-
-static void int_callback(struct urb *u)
-{
- struct kaweth_device *kaweth = u->context;
- int act_state;
- int status = u->status;
-
- switch (status) {
- case 0: /* success */
- break;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- /* -EPIPE: should clear the halt */
- default: /* error */
- goto resubmit;
- }
-
- /* we check the link state to report changes */
- if (kaweth->linkstate != (act_state = ( kaweth->intbuffer[STATE_OFFSET] | STATE_MASK) >> STATE_SHIFT)) {
- if (act_state)
- netif_carrier_on(kaweth->net);
- else
- netif_carrier_off(kaweth->net);
-
- kaweth->linkstate = act_state;
- }
-resubmit:
- kaweth_resubmit_int_urb(kaweth, GFP_ATOMIC);
-}
-
-static void kaweth_resubmit_tl(struct work_struct *work)
-{
- struct kaweth_device *kaweth =
- container_of(work, struct kaweth_device, lowmem_work.work);
-
- if (IS_BLOCKED(kaweth->status))
- return;
-
- if (kaweth->suspend_lowmem_rx)
- kaweth_resubmit_rx_urb(kaweth, GFP_NOIO);
-
- if (kaweth->suspend_lowmem_ctrl)
- kaweth_resubmit_int_urb(kaweth, GFP_NOIO);
-}
-
-
-/****************************************************************
- * kaweth_resubmit_rx_urb
- ****************************************************************/
-static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth,
- gfp_t mem_flags)
-{
- int result;
-
- usb_fill_bulk_urb(kaweth->rx_urb,
- kaweth->dev,
- usb_rcvbulkpipe(kaweth->dev, 1),
- kaweth->rx_buf,
- KAWETH_BUF_SIZE,
- kaweth_usb_receive,
- kaweth);
- kaweth->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- kaweth->rx_urb->transfer_dma = kaweth->rxbufferhandle;
-
- if((result = usb_submit_urb(kaweth->rx_urb, mem_flags))) {
- if (result == -ENOMEM) {
- kaweth->suspend_lowmem_rx = 1;
- schedule_delayed_work(&kaweth->lowmem_work, HZ/4);
- }
- err("resubmitting rx_urb %d failed", result);
- } else {
- kaweth->suspend_lowmem_rx = 0;
- }
-
- return result;
-}
-
-static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth);
-
-/****************************************************************
- * kaweth_usb_receive
- ****************************************************************/
-static void kaweth_usb_receive(struct urb *urb)
-{
- struct kaweth_device *kaweth = urb->context;
- struct net_device *net = kaweth->net;
- int status = urb->status;
-
- int count = urb->actual_length;
- int count2 = urb->transfer_buffer_length;
-
- __u16 pkt_len = le16_to_cpup((__le16 *)kaweth->rx_buf);
-
- struct sk_buff *skb;
-
- if (unlikely(status == -EPIPE)) {
- kaweth->stats.rx_errors++;
- kaweth->end = 1;
- wake_up(&kaweth->term_wait);
- dbg("Status was -EPIPE.");
- return;
- }
- if (unlikely(status == -ECONNRESET || status == -ESHUTDOWN)) {
- /* we are killed - set a flag and wake the disconnect handler */
- kaweth->end = 1;
- wake_up(&kaweth->term_wait);
- dbg("Status was -ECONNRESET or -ESHUTDOWN.");
- return;
- }
- if (unlikely(status == -EPROTO || status == -ETIME ||
- status == -EILSEQ)) {
- kaweth->stats.rx_errors++;
- dbg("Status was -EPROTO, -ETIME, or -EILSEQ.");
- return;
- }
- if (unlikely(status == -EOVERFLOW)) {
- kaweth->stats.rx_errors++;
- dbg("Status was -EOVERFLOW.");
- }
- spin_lock(&kaweth->device_lock);
- if (IS_BLOCKED(kaweth->status)) {
- spin_unlock(&kaweth->device_lock);
- return;
- }
- spin_unlock(&kaweth->device_lock);
-
- if(status && status != -EREMOTEIO && count != 1) {
- err("%s RX status: %d count: %d packet_len: %d",
- net->name,
- status,
- count,
- (int)pkt_len);
- kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
- return;
- }
-
- if(kaweth->net && (count > 2)) {
- if(pkt_len > (count - 2)) {
- err("Packet length too long for USB frame (pkt_len: %x, count: %x)",pkt_len, count);
- err("Packet len & 2047: %x", pkt_len & 2047);
- err("Count 2: %x", count2);
- kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
- return;
- }
-
- if(!(skb = dev_alloc_skb(pkt_len+2))) {
- kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
- return;
- }
-
- skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
-
- skb_copy_to_linear_data(skb, kaweth->rx_buf + 2, pkt_len);
-
- skb_put(skb, pkt_len);
-
- skb->protocol = eth_type_trans(skb, net);
-
- netif_rx(skb);
-
- kaweth->stats.rx_packets++;
- kaweth->stats.rx_bytes += pkt_len;
- }
-
- kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
-}
-
-/****************************************************************
- * kaweth_open
- ****************************************************************/
-static int kaweth_open(struct net_device *net)
-{
- struct kaweth_device *kaweth = netdev_priv(net);
- int res;
-
- dbg("Opening network device.");
-
- res = usb_autopm_get_interface(kaweth->intf);
- if (res) {
- err("Interface cannot be resumed.");
- return -EIO;
- }
- res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL);
- if (res)
- goto err_out;
-
- usb_fill_int_urb(
- kaweth->irq_urb,
- kaweth->dev,
- usb_rcvintpipe(kaweth->dev, 3),
- kaweth->intbuffer,
- INTBUFFERSIZE,
- int_callback,
- kaweth,
- 250); /* overriding the descriptor */
- kaweth->irq_urb->transfer_dma = kaweth->intbufferhandle;
- kaweth->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- res = usb_submit_urb(kaweth->irq_urb, GFP_KERNEL);
- if (res) {
- usb_kill_urb(kaweth->rx_urb);
- goto err_out;
- }
- kaweth->opened = 1;
-
- netif_start_queue(net);
-
- kaweth_async_set_rx_mode(kaweth);
- return 0;
-
-err_out:
- usb_autopm_put_interface(kaweth->intf);
- return -EIO;
-}
-
-/****************************************************************
- * kaweth_kill_urbs
- ****************************************************************/
-static void kaweth_kill_urbs(struct kaweth_device *kaweth)
-{
- usb_kill_urb(kaweth->irq_urb);
- usb_kill_urb(kaweth->rx_urb);
- usb_kill_urb(kaweth->tx_urb);
-
- cancel_delayed_work_sync(&kaweth->lowmem_work);
-
- /* a scheduled work may have resubmitted,
- we hit them again */
- usb_kill_urb(kaweth->irq_urb);
- usb_kill_urb(kaweth->rx_urb);
-}
-
-/****************************************************************
- * kaweth_close
- ****************************************************************/
-static int kaweth_close(struct net_device *net)
-{
- struct kaweth_device *kaweth = netdev_priv(net);
-
- netif_stop_queue(net);
- kaweth->opened = 0;
-
- kaweth->status |= KAWETH_STATUS_CLOSING;
-
- kaweth_kill_urbs(kaweth);
-
- kaweth->status &= ~KAWETH_STATUS_CLOSING;
-
- usb_autopm_put_interface(kaweth->intf);
-
- return 0;
-}
-
-static u32 kaweth_get_link(struct net_device *dev)
-{
- struct kaweth_device *kaweth = netdev_priv(dev);
-
- return kaweth->linkstate;
-}
-
-static const struct ethtool_ops ops = {
- .get_link = kaweth_get_link
-};
-
-/****************************************************************
- * kaweth_usb_transmit_complete
- ****************************************************************/
-static void kaweth_usb_transmit_complete(struct urb *urb)
-{
- struct kaweth_device *kaweth = urb->context;
- struct sk_buff *skb = kaweth->tx_skb;
- int status = urb->status;
-
- if (unlikely(status != 0))
- if (status != -ENOENT)
- dbg("%s: TX status %d.", kaweth->net->name, status);
-
- netif_wake_queue(kaweth->net);
- dev_kfree_skb_irq(skb);
-}
-
-/****************************************************************
- * kaweth_start_xmit
- ****************************************************************/
-static netdev_tx_t kaweth_start_xmit(struct sk_buff *skb,
- struct net_device *net)
-{
- struct kaweth_device *kaweth = netdev_priv(net);
- __le16 *private_header;
-
- int res;
-
- spin_lock_irq(&kaweth->device_lock);
-
- kaweth_async_set_rx_mode(kaweth);
- netif_stop_queue(net);
- if (IS_BLOCKED(kaweth->status)) {
- goto skip;
- }
-
- /* We now decide whether we can put our special header into the sk_buff */
- if (skb_cloned(skb) || skb_headroom(skb) < 2) {
- /* no such luck - we make our own */
- struct sk_buff *copied_skb;
- copied_skb = skb_copy_expand(skb, 2, 0, GFP_ATOMIC);
- dev_kfree_skb_irq(skb);
- skb = copied_skb;
- if (!copied_skb) {
- kaweth->stats.tx_errors++;
- netif_start_queue(net);
- spin_unlock_irq(&kaweth->device_lock);
- return NETDEV_TX_OK;
- }
- }
-
- private_header = (__le16 *)__skb_push(skb, 2);
- *private_header = cpu_to_le16(skb->len-2);
- kaweth->tx_skb = skb;
-
- usb_fill_bulk_urb(kaweth->tx_urb,
- kaweth->dev,
- usb_sndbulkpipe(kaweth->dev, 2),
- private_header,
- skb->len,
- kaweth_usb_transmit_complete,
- kaweth);
- kaweth->end = 0;
-
- if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC)))
- {
- dev_warn(&net->dev, "kaweth failed tx_urb %d\n", res);
-skip:
- kaweth->stats.tx_errors++;
-
- netif_start_queue(net);
- dev_kfree_skb_irq(skb);
- }
- else
- {
- kaweth->stats.tx_packets++;
- kaweth->stats.tx_bytes += skb->len;
- }
-
- spin_unlock_irq(&kaweth->device_lock);
-
- return NETDEV_TX_OK;
-}
-
-/****************************************************************
- * kaweth_set_rx_mode
- ****************************************************************/
-static void kaweth_set_rx_mode(struct net_device *net)
-{
- struct kaweth_device *kaweth = netdev_priv(net);
-
- __u16 packet_filter_bitmap = KAWETH_PACKET_FILTER_DIRECTED |
- KAWETH_PACKET_FILTER_BROADCAST |
- KAWETH_PACKET_FILTER_MULTICAST;
-
- dbg("Setting Rx mode to %d", packet_filter_bitmap);
-
- netif_stop_queue(net);
-
- if (net->flags & IFF_PROMISC) {
- packet_filter_bitmap |= KAWETH_PACKET_FILTER_PROMISCUOUS;
- }
- else if (!netdev_mc_empty(net) || (net->flags & IFF_ALLMULTI)) {
- packet_filter_bitmap |= KAWETH_PACKET_FILTER_ALL_MULTICAST;
- }
-
- kaweth->packet_filter_bitmap = packet_filter_bitmap;
- netif_wake_queue(net);
-}
-
-/****************************************************************
- * kaweth_async_set_rx_mode
- ****************************************************************/
-static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth)
-{
- int result;
- __u16 packet_filter_bitmap = kaweth->packet_filter_bitmap;
-
- kaweth->packet_filter_bitmap = 0;
- if (packet_filter_bitmap == 0)
- return;
-
- if (in_interrupt())
- return;
-
- result = kaweth_control(kaweth,
- usb_sndctrlpipe(kaweth->dev, 0),
- KAWETH_COMMAND_SET_PACKET_FILTER,
- USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
- packet_filter_bitmap,
- 0,
- (void *)&kaweth->scratch,
- 0,
- KAWETH_CONTROL_TIMEOUT);
-
- if(result < 0) {
- err("Failed to set Rx mode: %d", result);
- }
- else {
- dbg("Set Rx mode to %d", packet_filter_bitmap);
- }
-}
-
-/****************************************************************
- * kaweth_netdev_stats
- ****************************************************************/
-static struct net_device_stats *kaweth_netdev_stats(struct net_device *dev)
-{
- struct kaweth_device *kaweth = netdev_priv(dev);
- return &kaweth->stats;
-}
-
-/****************************************************************
- * kaweth_tx_timeout
- ****************************************************************/
-static void kaweth_tx_timeout(struct net_device *net)
-{
- struct kaweth_device *kaweth = netdev_priv(net);
-
- dev_warn(&net->dev, "%s: Tx timed out. Resetting.\n", net->name);
- kaweth->stats.tx_errors++;
- net->trans_start = jiffies;
-
- usb_unlink_urb(kaweth->tx_urb);
-}
-
-/****************************************************************
- * kaweth_suspend
- ****************************************************************/
-static int kaweth_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct kaweth_device *kaweth = usb_get_intfdata(intf);
- unsigned long flags;
-
- dbg("Suspending device");
- spin_lock_irqsave(&kaweth->device_lock, flags);
- kaweth->status |= KAWETH_STATUS_SUSPENDING;
- spin_unlock_irqrestore(&kaweth->device_lock, flags);
-
- kaweth_kill_urbs(kaweth);
- return 0;
-}
-
-/****************************************************************
- * kaweth_resume
- ****************************************************************/
-static int kaweth_resume(struct usb_interface *intf)
-{
- struct kaweth_device *kaweth = usb_get_intfdata(intf);
- unsigned long flags;
-
- dbg("Resuming device");
- spin_lock_irqsave(&kaweth->device_lock, flags);
- kaweth->status &= ~KAWETH_STATUS_SUSPENDING;
- spin_unlock_irqrestore(&kaweth->device_lock, flags);
-
- if (!kaweth->opened)
- return 0;
- kaweth_resubmit_rx_urb(kaweth, GFP_NOIO);
- kaweth_resubmit_int_urb(kaweth, GFP_NOIO);
-
- return 0;
-}
-
-/****************************************************************
- * kaweth_probe
- ****************************************************************/
-
-
-static const struct net_device_ops kaweth_netdev_ops = {
- .ndo_open = kaweth_open,
- .ndo_stop = kaweth_close,
- .ndo_start_xmit = kaweth_start_xmit,
- .ndo_tx_timeout = kaweth_tx_timeout,
- .ndo_set_rx_mode = kaweth_set_rx_mode,
- .ndo_get_stats = kaweth_netdev_stats,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-static int kaweth_probe(
- struct usb_interface *intf,
- const struct usb_device_id *id /* from id_table */
- )
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct kaweth_device *kaweth;
- struct net_device *netdev;
- const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
- int result = 0;
-
- dbg("Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x",
- dev->devnum,
- le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct),
- le16_to_cpu(dev->descriptor.bcdDevice));
-
- dbg("Device at %p", dev);
-
- dbg("Descriptor length: %x type: %x",
- (int)dev->descriptor.bLength,
- (int)dev->descriptor.bDescriptorType);
-
- netdev = alloc_etherdev(sizeof(*kaweth));
- if (!netdev)
- return -ENOMEM;
-
- kaweth = netdev_priv(netdev);
- kaweth->dev = dev;
- kaweth->net = netdev;
-
- spin_lock_init(&kaweth->device_lock);
- init_waitqueue_head(&kaweth->term_wait);
-
- dbg("Resetting.");
-
- kaweth_reset(kaweth);
-
- /*
- * If high byte of bcdDevice is nonzero, firmware is already
- * downloaded. Don't try to do it again, or we'll hang the device.
- */
-
- if (le16_to_cpu(dev->descriptor.bcdDevice) >> 8) {
- dev_info(&intf->dev, "Firmware present in device.\n");
- } else {
- /* Download the firmware */
- dev_info(&intf->dev, "Downloading firmware...\n");
- kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL);
- if ((result = kaweth_download_firmware(kaweth,
- "kaweth/new_code.bin",
- 100,
- 2)) < 0) {
- err("Error downloading firmware (%d)", result);
- goto err_fw;
- }
-
- if ((result = kaweth_download_firmware(kaweth,
- "kaweth/new_code_fix.bin",
- 100,
- 3)) < 0) {
- err("Error downloading firmware fix (%d)", result);
- goto err_fw;
- }
-
- if ((result = kaweth_download_firmware(kaweth,
- "kaweth/trigger_code.bin",
- 126,
- 2)) < 0) {
- err("Error downloading trigger code (%d)", result);
- goto err_fw;
-
- }
-
- if ((result = kaweth_download_firmware(kaweth,
- "kaweth/trigger_code_fix.bin",
- 126,
- 3)) < 0) {
- err("Error downloading trigger code fix (%d)", result);
- goto err_fw;
- }
-
-
- if ((result = kaweth_trigger_firmware(kaweth, 126)) < 0) {
- err("Error triggering firmware (%d)", result);
- goto err_fw;
- }
-
- /* Device will now disappear for a moment... */
- dev_info(&intf->dev, "Firmware loaded. I'll be back...\n");
-err_fw:
- free_page((unsigned long)kaweth->firmware_buf);
- free_netdev(netdev);
- return -EIO;
- }
-
- result = kaweth_read_configuration(kaweth);
-
- if(result < 0) {
- err("Error reading configuration (%d), no net device created", result);
- goto err_free_netdev;
- }
-
- dev_info(&intf->dev, "Statistics collection: %x\n", kaweth->configuration.statistics_mask);
- dev_info(&intf->dev, "Multicast filter limit: %x\n", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1));
- dev_info(&intf->dev, "MTU: %d\n", le16_to_cpu(kaweth->configuration.segment_size));
- dev_info(&intf->dev, "Read MAC address %pM\n", kaweth->configuration.hw_addr);
-
- if(!memcmp(&kaweth->configuration.hw_addr,
- &bcast_addr,
- sizeof(bcast_addr))) {
- err("Firmware not functioning properly, no net device created");
- goto err_free_netdev;
- }
-
- if(kaweth_set_urb_size(kaweth, KAWETH_BUF_SIZE) < 0) {
- dbg("Error setting URB size");
- goto err_free_netdev;
- }
-
- if(kaweth_set_sofs_wait(kaweth, KAWETH_SOFS_TO_WAIT) < 0) {
- err("Error setting SOFS wait");
- goto err_free_netdev;
- }
-
- result = kaweth_set_receive_filter(kaweth,
- KAWETH_PACKET_FILTER_DIRECTED |
- KAWETH_PACKET_FILTER_BROADCAST |
- KAWETH_PACKET_FILTER_MULTICAST);
-
- if(result < 0) {
- err("Error setting receive filter");
- goto err_free_netdev;
- }
-
- dbg("Initializing net device.");
-
- kaweth->intf = intf;
-
- kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!kaweth->tx_urb)
- goto err_free_netdev;
- kaweth->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!kaweth->rx_urb)
- goto err_only_tx;
- kaweth->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!kaweth->irq_urb)
- goto err_tx_and_rx;
-
- kaweth->intbuffer = usb_alloc_coherent( kaweth->dev,
- INTBUFFERSIZE,
- GFP_KERNEL,
- &kaweth->intbufferhandle);
- if (!kaweth->intbuffer)
- goto err_tx_and_rx_and_irq;
- kaweth->rx_buf = usb_alloc_coherent( kaweth->dev,
- KAWETH_BUF_SIZE,
- GFP_KERNEL,
- &kaweth->rxbufferhandle);
- if (!kaweth->rx_buf)
- goto err_all_but_rxbuf;
-
- memcpy(netdev->broadcast, &bcast_addr, sizeof(bcast_addr));
- memcpy(netdev->dev_addr, &kaweth->configuration.hw_addr,
- sizeof(kaweth->configuration.hw_addr));
-
- netdev->netdev_ops = &kaweth_netdev_ops;
- netdev->watchdog_timeo = KAWETH_TX_TIMEOUT;
- netdev->mtu = le16_to_cpu(kaweth->configuration.segment_size);
- SET_ETHTOOL_OPS(netdev, &ops);
-
- /* kaweth is zeroed as part of alloc_netdev */
- INIT_DELAYED_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl);
- usb_set_intfdata(intf, kaweth);
-
-#if 0
-// dma_supported() is deeply broken on almost all architectures
- if (dma_supported (&intf->dev, 0xffffffffffffffffULL))
- kaweth->net->features |= NETIF_F_HIGHDMA;
-#endif
-
- SET_NETDEV_DEV(netdev, &intf->dev);
- if (register_netdev(netdev) != 0) {
- err("Error registering netdev.");
- goto err_intfdata;
- }
-
- dev_info(&intf->dev, "kaweth interface created at %s\n",
- kaweth->net->name);
-
- dbg("Kaweth probe returning.");
-
- return 0;
-
-err_intfdata:
- usb_set_intfdata(intf, NULL);
- usb_free_coherent(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
-err_all_but_rxbuf:
- usb_free_coherent(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
-err_tx_and_rx_and_irq:
- usb_free_urb(kaweth->irq_urb);
-err_tx_and_rx:
- usb_free_urb(kaweth->rx_urb);
-err_only_tx:
- usb_free_urb(kaweth->tx_urb);
-err_free_netdev:
- free_netdev(netdev);
-
- return -EIO;
-}
-
-/****************************************************************
- * kaweth_disconnect
- ****************************************************************/
-static void kaweth_disconnect(struct usb_interface *intf)
-{
- struct kaweth_device *kaweth = usb_get_intfdata(intf);
- struct net_device *netdev;
-
- dev_info(&intf->dev, "Unregistering\n");
-
- usb_set_intfdata(intf, NULL);
- if (!kaweth) {
- dev_warn(&intf->dev, "unregistering non-existent device\n");
- return;
- }
- netdev = kaweth->net;
-
- dbg("Unregistering net device");
- unregister_netdev(netdev);
-
- usb_free_urb(kaweth->rx_urb);
- usb_free_urb(kaweth->tx_urb);
- usb_free_urb(kaweth->irq_urb);
-
- usb_free_coherent(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
- usb_free_coherent(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
-
- free_netdev(netdev);
-}
-
-
-// FIXME this completion stuff is a modified clone of
-// an OLD version of some stuff in usb.c ...
-struct usb_api_data {
- wait_queue_head_t wqh;
- int done;
-};
-
-/*-------------------------------------------------------------------*
- * completion handler for compatibility wrappers (sync control/bulk) *
- *-------------------------------------------------------------------*/
-static void usb_api_blocking_completion(struct urb *urb)
-{
- struct usb_api_data *awd = (struct usb_api_data *)urb->context;
-
- awd->done=1;
- wake_up(&awd->wqh);
-}
-
-/*-------------------------------------------------------------------*
- * COMPATIBILITY STUFF *
- *-------------------------------------------------------------------*/
-
-// Starts urb and waits for completion or timeout
-static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
-{
- struct usb_api_data awd;
- int status;
-
- init_waitqueue_head(&awd.wqh);
- awd.done = 0;
-
- urb->context = &awd;
- status = usb_submit_urb(urb, GFP_NOIO);
- if (status) {
- // something went wrong
- usb_free_urb(urb);
- return status;
- }
-
- if (!wait_event_timeout(awd.wqh, awd.done, timeout)) {
- // timeout
- dev_warn(&urb->dev->dev, "usb_control/bulk_msg: timeout\n");
- usb_kill_urb(urb); // remove urb safely
- status = -ETIMEDOUT;
- }
- else {
- status = urb->status;
- }
-
- if (actual_length) {
- *actual_length = urb->actual_length;
- }
-
- usb_free_urb(urb);
- return status;
-}
-
-/*-------------------------------------------------------------------*/
-// returns status (negative) or length (positive)
-static int kaweth_internal_control_msg(struct usb_device *usb_dev,
- unsigned int pipe,
- struct usb_ctrlrequest *cmd, void *data,
- int len, int timeout)
-{
- struct urb *urb;
- int retv;
- int length = 0; /* shut up GCC */
-
- urb = usb_alloc_urb(0, GFP_NOIO);
- if (!urb)
- return -ENOMEM;
-
- usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char*)cmd, data,
- len, usb_api_blocking_completion, NULL);
-
- retv = usb_start_wait_urb(urb, timeout, &length);
- if (retv < 0) {
- return retv;
- }
- else {
- return length;
- }
-}
-
-module_usb_driver(kaweth_driver);
diff --git a/ANDROID_3.4.5/drivers/net/usb/lg-vl600.c b/ANDROID_3.4.5/drivers/net/usb/lg-vl600.c
deleted file mode 100644
index 45a981fd..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/lg-vl600.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Ethernet interface part of the LG VL600 LTE modem (4G dongle)
- *
- * Copyright (C) 2011 Intel Corporation
- * Author: Andrzej Zaborowski <balrogg@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/usb/cdc.h>
-#include <linux/usb/usbnet.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <linux/inetdevice.h>
-#include <linux/module.h>
-
-/*
- * The device has a CDC ACM port for modem control (it claims to be
- * CDC ACM anyway) and a CDC Ethernet port for actual network data.
- * It will however ignore data on both ports that is not encapsulated
- * in a specific way, any data returned is also encapsulated the same
- * way. The headers don't seem to follow any popular standard.
- *
- * This driver adds and strips these headers from the ethernet frames
- * sent/received from the CDC Ethernet port. The proprietary header
- * replaces the standard ethernet header in a packet so only actual
- * ethernet frames are allowed. The headers allow some form of
- * multiplexing by using non standard values of the .h_proto field.
- * Windows/Mac drivers do send a couple of such frames to the device
- * during initialisation, with protocol set to 0x0906 or 0x0b06 and (what
- * seems to be) a flag in the .dummy_flags. This doesn't seem necessary
- * for modem operation but can possibly be used for GPS or other funcitons.
- */
-
-struct vl600_frame_hdr {
- __le32 len;
- __le32 serial;
- __le32 pkt_cnt;
- __le32 dummy_flags;
- __le32 dummy;
- __le32 magic;
-} __attribute__((packed));
-
-struct vl600_pkt_hdr {
- __le32 dummy[2];
- __le32 len;
- __be16 h_proto;
-} __attribute__((packed));
-
-struct vl600_state {
- struct sk_buff *current_rx_buf;
-};
-
-static int vl600_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- int ret;
- struct vl600_state *s = kzalloc(sizeof(struct vl600_state), GFP_KERNEL);
-
- if (!s)
- return -ENOMEM;
-
- ret = usbnet_cdc_bind(dev, intf);
- if (ret) {
- kfree(s);
- return ret;
- }
-
- dev->driver_priv = s;
-
- /* ARP packets don't go through, but they're also of no use. The
- * subnet has only two hosts anyway: us and the gateway / DHCP
- * server (probably simulated by modem firmware or network operator)
- * whose address changes everytime we connect to the intarwebz and
- * who doesn't bother answering ARP requests either. So hardware
- * addresses have no meaning, the destination and the source of every
- * packet depend only on whether it is on the IN or OUT endpoint. */
- dev->net->flags |= IFF_NOARP;
- /* IPv6 NDP relies on multicast. Enable it by default. */
- dev->net->flags |= IFF_MULTICAST;
-
- return ret;
-}
-
-static void vl600_unbind(struct usbnet *dev, struct usb_interface *intf)
-{
- struct vl600_state *s = dev->driver_priv;
-
- if (s->current_rx_buf)
- dev_kfree_skb(s->current_rx_buf);
-
- kfree(s);
-
- return usbnet_cdc_unbind(dev, intf);
-}
-
-static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- struct vl600_frame_hdr *frame;
- struct vl600_pkt_hdr *packet;
- struct ethhdr *ethhdr;
- int packet_len, count;
- struct sk_buff *buf = skb;
- struct sk_buff *clone;
- struct vl600_state *s = dev->driver_priv;
-
- /* Frame lengths are generally 4B multiplies but every couple of
- * hours there's an odd number of bytes sized yet correct frame,
- * so don't require this. */
-
- /* Allow a packet (or multiple packets batched together) to be
- * split across many frames. We don't allow a new batch to
- * begin in the same frame another one is ending however, and no
- * leading or trailing pad bytes. */
- if (s->current_rx_buf) {
- frame = (struct vl600_frame_hdr *) s->current_rx_buf->data;
- if (skb->len + s->current_rx_buf->len >
- le32_to_cpup(&frame->len)) {
- netif_err(dev, ifup, dev->net, "Fragment too long\n");
- dev->net->stats.rx_length_errors++;
- goto error;
- }
-
- buf = s->current_rx_buf;
- memcpy(skb_put(buf, skb->len), skb->data, skb->len);
- } else if (skb->len < 4) {
- netif_err(dev, ifup, dev->net, "Frame too short\n");
- dev->net->stats.rx_length_errors++;
- goto error;
- }
-
- frame = (struct vl600_frame_hdr *) buf->data;
- /* Yes, check that frame->magic == 0x53544448 (or 0x44544d48),
- * otherwise we may run out of memory w/a bad packet */
- if (ntohl(frame->magic) != 0x53544448 &&
- ntohl(frame->magic) != 0x44544d48)
- goto error;
-
- if (buf->len < sizeof(*frame) ||
- buf->len != le32_to_cpup(&frame->len)) {
- /* Save this fragment for later assembly */
- if (s->current_rx_buf)
- return 0;
-
- s->current_rx_buf = skb_copy_expand(skb, 0,
- le32_to_cpup(&frame->len), GFP_ATOMIC);
- if (!s->current_rx_buf) {
- netif_err(dev, ifup, dev->net, "Reserving %i bytes "
- "for packet assembly failed.\n",
- le32_to_cpup(&frame->len));
- dev->net->stats.rx_errors++;
- }
-
- return 0;
- }
-
- count = le32_to_cpup(&frame->pkt_cnt);
-
- skb_pull(buf, sizeof(*frame));
-
- while (count--) {
- if (buf->len < sizeof(*packet)) {
- netif_err(dev, ifup, dev->net, "Packet too short\n");
- goto error;
- }
-
- packet = (struct vl600_pkt_hdr *) buf->data;
- packet_len = sizeof(*packet) + le32_to_cpup(&packet->len);
- if (packet_len > buf->len) {
- netif_err(dev, ifup, dev->net,
- "Bad packet length stored in header\n");
- goto error;
- }
-
- /* Packet header is same size as the ethernet header
- * (sizeof(*packet) == sizeof(*ethhdr)), additionally
- * the h_proto field is in the same place so we just leave it
- * alone and fill in the remaining fields.
- */
- ethhdr = (struct ethhdr *) skb->data;
- if (be16_to_cpup(&ethhdr->h_proto) == ETH_P_ARP &&
- buf->len > 0x26) {
- /* Copy the addresses from packet contents */
- memcpy(ethhdr->h_source,
- &buf->data[sizeof(*ethhdr) + 0x8],
- ETH_ALEN);
- memcpy(ethhdr->h_dest,
- &buf->data[sizeof(*ethhdr) + 0x12],
- ETH_ALEN);
- } else {
- memset(ethhdr->h_source, 0, ETH_ALEN);
- memcpy(ethhdr->h_dest, dev->net->dev_addr, ETH_ALEN);
-
- /* Inbound IPv6 packets have an IPv4 ethertype (0x800)
- * for some reason. Peek at the L3 header to check
- * for IPv6 packets, and set the ethertype to IPv6
- * (0x86dd) so Linux can understand it.
- */
- if ((buf->data[sizeof(*ethhdr)] & 0xf0) == 0x60)
- ethhdr->h_proto = __constant_htons(ETH_P_IPV6);
- }
-
- if (count) {
- /* Not the last packet in this batch */
- clone = skb_clone(buf, GFP_ATOMIC);
- if (!clone)
- goto error;
-
- skb_trim(clone, packet_len);
- usbnet_skb_return(dev, clone);
-
- skb_pull(buf, (packet_len + 3) & ~3);
- } else {
- skb_trim(buf, packet_len);
-
- if (s->current_rx_buf) {
- usbnet_skb_return(dev, buf);
- s->current_rx_buf = NULL;
- return 0;
- }
-
- return 1;
- }
- }
-
-error:
- if (s->current_rx_buf) {
- dev_kfree_skb_any(s->current_rx_buf);
- s->current_rx_buf = NULL;
- }
- dev->net->stats.rx_errors++;
- return 0;
-}
-
-static struct sk_buff *vl600_tx_fixup(struct usbnet *dev,
- struct sk_buff *skb, gfp_t flags)
-{
- struct sk_buff *ret;
- struct vl600_frame_hdr *frame;
- struct vl600_pkt_hdr *packet;
- static uint32_t serial = 1;
- int orig_len = skb->len - sizeof(struct ethhdr);
- int full_len = (skb->len + sizeof(struct vl600_frame_hdr) + 3) & ~3;
-
- frame = (struct vl600_frame_hdr *) skb->data;
- if (skb->len > sizeof(*frame) && skb->len == le32_to_cpup(&frame->len))
- return skb; /* Already encapsulated? */
-
- if (skb->len < sizeof(struct ethhdr))
- /* Drop, device can only deal with ethernet packets */
- return NULL;
-
- if (!skb_cloned(skb)) {
- int headroom = skb_headroom(skb);
- int tailroom = skb_tailroom(skb);
-
- if (tailroom >= full_len - skb->len - sizeof(*frame) &&
- headroom >= sizeof(*frame))
- /* There's enough head and tail room */
- goto encapsulate;
-
- if (headroom + tailroom + skb->len >= full_len) {
- /* There's enough total room, just readjust */
- skb->data = memmove(skb->head + sizeof(*frame),
- skb->data, skb->len);
- skb_set_tail_pointer(skb, skb->len);
- goto encapsulate;
- }
- }
-
- /* Alloc a new skb with the required size */
- ret = skb_copy_expand(skb, sizeof(struct vl600_frame_hdr), full_len -
- skb->len - sizeof(struct vl600_frame_hdr), flags);
- dev_kfree_skb_any(skb);
- if (!ret)
- return ret;
- skb = ret;
-
-encapsulate:
- /* Packet header is same size as ethernet packet header
- * (sizeof(*packet) == sizeof(struct ethhdr)), additionally the
- * h_proto field is in the same place so we just leave it alone and
- * overwrite the remaining fields.
- */
- packet = (struct vl600_pkt_hdr *) skb->data;
- /* The VL600 wants IPv6 packets to have an IPv4 ethertype
- * Since this modem only supports IPv4 and IPv6, just set all
- * frames to 0x0800 (ETH_P_IP)
- */
- packet->h_proto = htons(ETH_P_IP);
- memset(&packet->dummy, 0, sizeof(packet->dummy));
- packet->len = cpu_to_le32(orig_len);
-
- frame = (struct vl600_frame_hdr *) skb_push(skb, sizeof(*frame));
- memset(frame, 0, sizeof(*frame));
- frame->len = cpu_to_le32(full_len);
- frame->serial = cpu_to_le32(serial++);
- frame->pkt_cnt = cpu_to_le32(1);
-
- if (skb->len < full_len) /* Pad */
- skb_put(skb, full_len - skb->len);
-
- return skb;
-}
-
-static const struct driver_info vl600_info = {
- .description = "LG VL600 modem",
- .flags = FLAG_RX_ASSEMBLE | FLAG_WWAN,
- .bind = vl600_bind,
- .unbind = vl600_unbind,
- .status = usbnet_cdc_status,
- .rx_fixup = vl600_rx_fixup,
- .tx_fixup = vl600_tx_fixup,
-};
-
-static const struct usb_device_id products[] = {
- {
- USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &vl600_info,
- },
- {}, /* End */
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver lg_vl600_driver = {
- .name = "lg-vl600",
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
-};
-
-module_usb_driver(lg_vl600_driver);
-
-MODULE_AUTHOR("Anrzej Zaborowski");
-MODULE_DESCRIPTION("LG-VL600 modem's ethernet link");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/mcs7830.c b/ANDROID_3.4.5/drivers/net/usb/mcs7830.c
deleted file mode 100644
index c434b6ba..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/mcs7830.c
+++ /dev/null
@@ -1,698 +0,0 @@
-/*
- * MOSCHIP MCS7830 based (7730/7830/7832) USB 2.0 Ethernet Devices
- *
- * based on usbnet.c, asix.c and the vendor provided mcs7830 driver
- *
- * Copyright (C) 2010 Andreas Mohr <andi@lisas.de>
- * Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>
- * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
- * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
- * Copyright (c) 2002-2003 TiVo Inc.
- *
- * Definitions gathered from MOSCHIP, Data Sheet_7830DA.pdf (thanks!).
- *
- * 2010-12-19: add 7832 USB PID ("functionality same as MCS7830"),
- * per active notification by manufacturer
- *
- * TODO:
- * - support HIF_REG_CONFIG_SLEEPMODE/HIF_REG_CONFIG_TXENABLE (via autopm?)
- * - implement ethtool_ops get_pauseparam/set_pauseparam
- * via HIF_REG_PAUSE_THRESHOLD (>= revision C only!)
- * - implement get_eeprom/[set_eeprom]
- * - switch PHY on/off on ifup/ifdown (perhaps in usbnet.c, via MII)
- * - mcs7830_get_regs() handling is weird: for rev 2 we return 32 regs,
- * can access only ~ 24, remaining user buffer is uninitialized garbage
- * - anything else?
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/crc32.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/init.h>
-#include <linux/mii.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/usbnet.h>
-
-/* requests */
-#define MCS7830_RD_BMREQ (USB_DIR_IN | USB_TYPE_VENDOR | \
- USB_RECIP_DEVICE)
-#define MCS7830_WR_BMREQ (USB_DIR_OUT | USB_TYPE_VENDOR | \
- USB_RECIP_DEVICE)
-#define MCS7830_RD_BREQ 0x0E
-#define MCS7830_WR_BREQ 0x0D
-
-#define MCS7830_CTRL_TIMEOUT 1000
-#define MCS7830_MAX_MCAST 64
-
-#define MCS7830_VENDOR_ID 0x9710
-#define MCS7832_PRODUCT_ID 0x7832
-#define MCS7830_PRODUCT_ID 0x7830
-#define MCS7730_PRODUCT_ID 0x7730
-
-#define SITECOM_VENDOR_ID 0x0DF6
-#define LN_030_PRODUCT_ID 0x0021
-
-#define MCS7830_MII_ADVERTISE (ADVERTISE_PAUSE_CAP | ADVERTISE_100FULL | \
- ADVERTISE_100HALF | ADVERTISE_10FULL | \
- ADVERTISE_10HALF | ADVERTISE_CSMA)
-
-/* HIF_REG_XX corresponding index value */
-enum {
- HIF_REG_MULTICAST_HASH = 0x00,
- HIF_REG_PACKET_GAP1 = 0x08,
- HIF_REG_PACKET_GAP2 = 0x09,
- HIF_REG_PHY_DATA = 0x0a,
- HIF_REG_PHY_CMD1 = 0x0c,
- HIF_REG_PHY_CMD1_READ = 0x40,
- HIF_REG_PHY_CMD1_WRITE = 0x20,
- HIF_REG_PHY_CMD1_PHYADDR = 0x01,
- HIF_REG_PHY_CMD2 = 0x0d,
- HIF_REG_PHY_CMD2_PEND_FLAG_BIT = 0x80,
- HIF_REG_PHY_CMD2_READY_FLAG_BIT = 0x40,
- HIF_REG_CONFIG = 0x0e,
- /* hmm, spec sez: "R/W", "Except bit 3" (likely TXENABLE). */
- HIF_REG_CONFIG_CFG = 0x80,
- HIF_REG_CONFIG_SPEED100 = 0x40,
- HIF_REG_CONFIG_FULLDUPLEX_ENABLE = 0x20,
- HIF_REG_CONFIG_RXENABLE = 0x10,
- HIF_REG_CONFIG_TXENABLE = 0x08,
- HIF_REG_CONFIG_SLEEPMODE = 0x04,
- HIF_REG_CONFIG_ALLMULTICAST = 0x02,
- HIF_REG_CONFIG_PROMISCUOUS = 0x01,
- HIF_REG_ETHERNET_ADDR = 0x0f,
- HIF_REG_FRAME_DROP_COUNTER = 0x15, /* 0..ff; reset: 0 */
- HIF_REG_PAUSE_THRESHOLD = 0x16,
- HIF_REG_PAUSE_THRESHOLD_DEFAULT = 0,
-};
-
-/* Trailing status byte in Ethernet Rx frame */
-enum {
- MCS7830_RX_SHORT_FRAME = 0x01, /* < 64 bytes */
- MCS7830_RX_LENGTH_ERROR = 0x02, /* framelen != Ethernet length field */
- MCS7830_RX_ALIGNMENT_ERROR = 0x04, /* non-even number of nibbles */
- MCS7830_RX_CRC_ERROR = 0x08,
- MCS7830_RX_LARGE_FRAME = 0x10, /* > 1518 bytes */
- MCS7830_RX_FRAME_CORRECT = 0x20, /* frame is correct */
- /* [7:6] reserved */
-};
-
-struct mcs7830_data {
- u8 multi_filter[8];
- u8 config;
-};
-
-static const char driver_name[] = "MOSCHIP usb-ethernet driver";
-
-static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data)
-{
- struct usb_device *xdev = dev->udev;
- int ret;
- void *buffer;
-
- buffer = kmalloc(size, GFP_NOIO);
- if (buffer == NULL)
- return -ENOMEM;
-
- ret = usb_control_msg(xdev, usb_rcvctrlpipe(xdev, 0), MCS7830_RD_BREQ,
- MCS7830_RD_BMREQ, 0x0000, index, buffer,
- size, MCS7830_CTRL_TIMEOUT);
- memcpy(data, buffer, size);
- kfree(buffer);
-
- return ret;
-}
-
-static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, const void *data)
-{
- struct usb_device *xdev = dev->udev;
- int ret;
- void *buffer;
-
- buffer = kmemdup(data, size, GFP_NOIO);
- if (buffer == NULL)
- return -ENOMEM;
-
- ret = usb_control_msg(xdev, usb_sndctrlpipe(xdev, 0), MCS7830_WR_BREQ,
- MCS7830_WR_BMREQ, 0x0000, index, buffer,
- size, MCS7830_CTRL_TIMEOUT);
- kfree(buffer);
- return ret;
-}
-
-static void mcs7830_async_cmd_callback(struct urb *urb)
-{
- struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
- int status = urb->status;
-
- if (status < 0)
- printk(KERN_DEBUG "%s() failed with %d\n",
- __func__, status);
-
- kfree(req);
- usb_free_urb(urb);
-}
-
-static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void *data)
-{
- struct usb_ctrlrequest *req;
- int ret;
- struct urb *urb;
-
- urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!urb) {
- dev_dbg(&dev->udev->dev,
- "Error allocating URB in write_cmd_async!\n");
- return;
- }
-
- req = kmalloc(sizeof *req, GFP_ATOMIC);
- if (!req) {
- dev_err(&dev->udev->dev,
- "Failed to allocate memory for control request\n");
- goto out;
- }
- req->bRequestType = MCS7830_WR_BMREQ;
- req->bRequest = MCS7830_WR_BREQ;
- req->wValue = 0;
- req->wIndex = cpu_to_le16(index);
- req->wLength = cpu_to_le16(size);
-
- usb_fill_control_urb(urb, dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- (void *)req, data, size,
- mcs7830_async_cmd_callback, req);
-
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0) {
- dev_err(&dev->udev->dev,
- "Error submitting the control message: ret=%d\n", ret);
- goto out;
- }
- return;
-out:
- kfree(req);
- usb_free_urb(urb);
-}
-
-static int mcs7830_hif_get_mac_address(struct usbnet *dev, unsigned char *addr)
-{
- int ret = mcs7830_get_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN, addr);
- if (ret < 0)
- return ret;
- return 0;
-}
-
-static int mcs7830_hif_set_mac_address(struct usbnet *dev, unsigned char *addr)
-{
- int ret = mcs7830_set_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN, addr);
-
- if (ret < 0)
- return ret;
- return 0;
-}
-
-static int mcs7830_set_mac_address(struct net_device *netdev, void *p)
-{
- int ret;
- struct usbnet *dev = netdev_priv(netdev);
- struct sockaddr *addr = p;
-
- if (netif_running(netdev))
- return -EBUSY;
-
- if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
-
- ret = mcs7830_hif_set_mac_address(dev, addr->sa_data);
-
- if (ret < 0)
- return ret;
-
- /* it worked --> adopt it on netdev side */
- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-
- return 0;
-}
-
-static int mcs7830_read_phy(struct usbnet *dev, u8 index)
-{
- int ret;
- int i;
- __le16 val;
-
- u8 cmd[2] = {
- HIF_REG_PHY_CMD1_READ | HIF_REG_PHY_CMD1_PHYADDR,
- HIF_REG_PHY_CMD2_PEND_FLAG_BIT | index,
- };
-
- mutex_lock(&dev->phy_mutex);
- /* write the MII command */
- ret = mcs7830_set_reg(dev, HIF_REG_PHY_CMD1, 2, cmd);
- if (ret < 0)
- goto out;
-
- /* wait for the data to become valid, should be within < 1ms */
- for (i = 0; i < 10; i++) {
- ret = mcs7830_get_reg(dev, HIF_REG_PHY_CMD1, 2, cmd);
- if ((ret < 0) || (cmd[1] & HIF_REG_PHY_CMD2_READY_FLAG_BIT))
- break;
- ret = -EIO;
- msleep(1);
- }
- if (ret < 0)
- goto out;
-
- /* read actual register contents */
- ret = mcs7830_get_reg(dev, HIF_REG_PHY_DATA, 2, &val);
- if (ret < 0)
- goto out;
- ret = le16_to_cpu(val);
- dev_dbg(&dev->udev->dev, "read PHY reg %02x: %04x (%d tries)\n",
- index, val, i);
-out:
- mutex_unlock(&dev->phy_mutex);
- return ret;
-}
-
-static int mcs7830_write_phy(struct usbnet *dev, u8 index, u16 val)
-{
- int ret;
- int i;
- __le16 le_val;
-
- u8 cmd[2] = {
- HIF_REG_PHY_CMD1_WRITE | HIF_REG_PHY_CMD1_PHYADDR,
- HIF_REG_PHY_CMD2_PEND_FLAG_BIT | (index & 0x1F),
- };
-
- mutex_lock(&dev->phy_mutex);
-
- /* write the new register contents */
- le_val = cpu_to_le16(val);
- ret = mcs7830_set_reg(dev, HIF_REG_PHY_DATA, 2, &le_val);
- if (ret < 0)
- goto out;
-
- /* write the MII command */
- ret = mcs7830_set_reg(dev, HIF_REG_PHY_CMD1, 2, cmd);
- if (ret < 0)
- goto out;
-
- /* wait for the command to be accepted by the PHY */
- for (i = 0; i < 10; i++) {
- ret = mcs7830_get_reg(dev, HIF_REG_PHY_CMD1, 2, cmd);
- if ((ret < 0) || (cmd[1] & HIF_REG_PHY_CMD2_READY_FLAG_BIT))
- break;
- ret = -EIO;
- msleep(1);
- }
- if (ret < 0)
- goto out;
-
- ret = 0;
- dev_dbg(&dev->udev->dev, "write PHY reg %02x: %04x (%d tries)\n",
- index, val, i);
-out:
- mutex_unlock(&dev->phy_mutex);
- return ret;
-}
-
-/*
- * This algorithm comes from the original mcs7830 version 1.4 driver,
- * not sure if it is needed.
- */
-static int mcs7830_set_autoneg(struct usbnet *dev, int ptrUserPhyMode)
-{
- int ret;
- /* Enable all media types */
- ret = mcs7830_write_phy(dev, MII_ADVERTISE, MCS7830_MII_ADVERTISE);
-
- /* First reset BMCR */
- if (!ret)
- ret = mcs7830_write_phy(dev, MII_BMCR, 0x0000);
- /* Enable Auto Neg */
- if (!ret)
- ret = mcs7830_write_phy(dev, MII_BMCR, BMCR_ANENABLE);
- /* Restart Auto Neg (Keep the Enable Auto Neg Bit Set) */
- if (!ret)
- ret = mcs7830_write_phy(dev, MII_BMCR,
- BMCR_ANENABLE | BMCR_ANRESTART );
- return ret;
-}
-
-
-/*
- * if we can read register 22, the chip revision is C or higher
- */
-static int mcs7830_get_rev(struct usbnet *dev)
-{
- u8 dummy[2];
- int ret;
- ret = mcs7830_get_reg(dev, HIF_REG_FRAME_DROP_COUNTER, 2, dummy);
- if (ret > 0)
- return 2; /* Rev C or later */
- return 1; /* earlier revision */
-}
-
-/*
- * On rev. C we need to set the pause threshold
- */
-static void mcs7830_rev_C_fixup(struct usbnet *dev)
-{
- u8 pause_threshold = HIF_REG_PAUSE_THRESHOLD_DEFAULT;
- int retry;
-
- for (retry = 0; retry < 2; retry++) {
- if (mcs7830_get_rev(dev) == 2) {
- dev_info(&dev->udev->dev, "applying rev.C fixup\n");
- mcs7830_set_reg(dev, HIF_REG_PAUSE_THRESHOLD,
- 1, &pause_threshold);
- }
- msleep(1);
- }
-}
-
-static int mcs7830_mdio_read(struct net_device *netdev, int phy_id,
- int location)
-{
- struct usbnet *dev = netdev_priv(netdev);
- return mcs7830_read_phy(dev, location);
-}
-
-static void mcs7830_mdio_write(struct net_device *netdev, int phy_id,
- int location, int val)
-{
- struct usbnet *dev = netdev_priv(netdev);
- mcs7830_write_phy(dev, location, val);
-}
-
-static int mcs7830_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
-{
- struct usbnet *dev = netdev_priv(net);
- return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
-}
-
-static inline struct mcs7830_data *mcs7830_get_data(struct usbnet *dev)
-{
- return (struct mcs7830_data *)&dev->data;
-}
-
-static void mcs7830_hif_update_multicast_hash(struct usbnet *dev)
-{
- struct mcs7830_data *data = mcs7830_get_data(dev);
- mcs7830_set_reg_async(dev, HIF_REG_MULTICAST_HASH,
- sizeof data->multi_filter,
- data->multi_filter);
-}
-
-static void mcs7830_hif_update_config(struct usbnet *dev)
-{
- /* implementation specific to data->config
- (argument needs to be heap-based anyway - USB DMA!) */
- struct mcs7830_data *data = mcs7830_get_data(dev);
- mcs7830_set_reg_async(dev, HIF_REG_CONFIG, 1, &data->config);
-}
-
-static void mcs7830_data_set_multicast(struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
- struct mcs7830_data *data = mcs7830_get_data(dev);
-
- memset(data->multi_filter, 0, sizeof data->multi_filter);
-
- data->config = HIF_REG_CONFIG_TXENABLE;
-
- /* this should not be needed, but it doesn't work otherwise */
- data->config |= HIF_REG_CONFIG_ALLMULTICAST;
-
- if (net->flags & IFF_PROMISC) {
- data->config |= HIF_REG_CONFIG_PROMISCUOUS;
- } else if (net->flags & IFF_ALLMULTI ||
- netdev_mc_count(net) > MCS7830_MAX_MCAST) {
- data->config |= HIF_REG_CONFIG_ALLMULTICAST;
- } else if (netdev_mc_empty(net)) {
- /* just broadcast and directed */
- } else {
- /* We use the 20 byte dev->data
- * for our 8 byte filter buffer
- * to avoid allocating memory that
- * is tricky to free later */
- struct netdev_hw_addr *ha;
- u32 crc_bits;
-
- /* Build the multicast hash filter. */
- netdev_for_each_mc_addr(ha, net) {
- crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26;
- data->multi_filter[crc_bits >> 3] |= 1 << (crc_bits & 7);
- }
- }
-}
-
-static int mcs7830_apply_base_config(struct usbnet *dev)
-{
- int ret;
-
- /* re-configure known MAC (suspend case etc.) */
- ret = mcs7830_hif_set_mac_address(dev, dev->net->dev_addr);
- if (ret) {
- dev_info(&dev->udev->dev, "Cannot set MAC address\n");
- goto out;
- }
-
- /* Set up PHY */
- ret = mcs7830_set_autoneg(dev, 0);
- if (ret) {
- dev_info(&dev->udev->dev, "Cannot set autoneg\n");
- goto out;
- }
-
- mcs7830_hif_update_multicast_hash(dev);
- mcs7830_hif_update_config(dev);
-
- mcs7830_rev_C_fixup(dev);
- ret = 0;
-out:
- return ret;
-}
-
-/* credits go to asix_set_multicast */
-static void mcs7830_set_multicast(struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
-
- mcs7830_data_set_multicast(net);
-
- mcs7830_hif_update_multicast_hash(dev);
- mcs7830_hif_update_config(dev);
-}
-
-static int mcs7830_get_regs_len(struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
-
- switch (mcs7830_get_rev(dev)) {
- case 1:
- return 21;
- case 2:
- return 32;
- }
- return 0;
-}
-
-static void mcs7830_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *drvinfo)
-{
- usbnet_get_drvinfo(net, drvinfo);
- drvinfo->regdump_len = mcs7830_get_regs_len(net);
-}
-
-static void mcs7830_get_regs(struct net_device *net, struct ethtool_regs *regs, void *data)
-{
- struct usbnet *dev = netdev_priv(net);
-
- regs->version = mcs7830_get_rev(dev);
- mcs7830_get_reg(dev, 0, regs->len, data);
-}
-
-static const struct ethtool_ops mcs7830_ethtool_ops = {
- .get_drvinfo = mcs7830_get_drvinfo,
- .get_regs_len = mcs7830_get_regs_len,
- .get_regs = mcs7830_get_regs,
-
- /* common usbnet calls */
- .get_link = usbnet_get_link,
- .get_msglevel = usbnet_get_msglevel,
- .set_msglevel = usbnet_set_msglevel,
- .get_settings = usbnet_get_settings,
- .set_settings = usbnet_set_settings,
- .nway_reset = usbnet_nway_reset,
-};
-
-static const struct net_device_ops mcs7830_netdev_ops = {
- .ndo_open = usbnet_open,
- .ndo_stop = usbnet_stop,
- .ndo_start_xmit = usbnet_start_xmit,
- .ndo_tx_timeout = usbnet_tx_timeout,
- .ndo_change_mtu = usbnet_change_mtu,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_do_ioctl = mcs7830_ioctl,
- .ndo_set_rx_mode = mcs7830_set_multicast,
- .ndo_set_mac_address = mcs7830_set_mac_address,
-};
-
-static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev)
-{
- struct net_device *net = dev->net;
- int ret;
- int retry;
-
- /* Initial startup: Gather MAC address setting from EEPROM */
- ret = -EINVAL;
- for (retry = 0; retry < 5 && ret; retry++)
- ret = mcs7830_hif_get_mac_address(dev, net->dev_addr);
- if (ret) {
- dev_warn(&dev->udev->dev, "Cannot read MAC address\n");
- goto out;
- }
-
- mcs7830_data_set_multicast(net);
-
- ret = mcs7830_apply_base_config(dev);
- if (ret)
- goto out;
-
- net->ethtool_ops = &mcs7830_ethtool_ops;
- net->netdev_ops = &mcs7830_netdev_ops;
-
- /* reserve space for the status byte on rx */
- dev->rx_urb_size = ETH_FRAME_LEN + 1;
-
- dev->mii.mdio_read = mcs7830_mdio_read;
- dev->mii.mdio_write = mcs7830_mdio_write;
- dev->mii.dev = net;
- dev->mii.phy_id_mask = 0x3f;
- dev->mii.reg_num_mask = 0x1f;
- dev->mii.phy_id = *((u8 *) net->dev_addr + 1);
-
- ret = usbnet_get_endpoints(dev, udev);
-out:
- return ret;
-}
-
-/* The chip always appends a status byte that we need to strip */
-static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- u8 status;
-
- if (skb->len == 0) {
- dev_err(&dev->udev->dev, "unexpected empty rx frame\n");
- return 0;
- }
-
- skb_trim(skb, skb->len - 1);
- status = skb->data[skb->len];
-
- if (status != MCS7830_RX_FRAME_CORRECT) {
- dev_dbg(&dev->udev->dev, "rx fixup status %x\n", status);
-
- /* hmm, perhaps usbnet.c already sees a globally visible
- frame error and increments rx_errors on its own already? */
- dev->net->stats.rx_errors++;
-
- if (status & (MCS7830_RX_SHORT_FRAME
- |MCS7830_RX_LENGTH_ERROR
- |MCS7830_RX_LARGE_FRAME))
- dev->net->stats.rx_length_errors++;
- if (status & MCS7830_RX_ALIGNMENT_ERROR)
- dev->net->stats.rx_frame_errors++;
- if (status & MCS7830_RX_CRC_ERROR)
- dev->net->stats.rx_crc_errors++;
- }
-
- return skb->len > 0;
-}
-
-static const struct driver_info moschip_info = {
- .description = "MOSCHIP 7830/7832/7730 usb-NET adapter",
- .bind = mcs7830_bind,
- .rx_fixup = mcs7830_rx_fixup,
- .flags = FLAG_ETHER,
- .in = 1,
- .out = 2,
-};
-
-static const struct driver_info sitecom_info = {
- .description = "Sitecom LN-30 usb-NET adapter",
- .bind = mcs7830_bind,
- .rx_fixup = mcs7830_rx_fixup,
- .flags = FLAG_ETHER,
- .in = 1,
- .out = 2,
-};
-
-static const struct usb_device_id products[] = {
- {
- USB_DEVICE(MCS7830_VENDOR_ID, MCS7832_PRODUCT_ID),
- .driver_info = (unsigned long) &moschip_info,
- },
- {
- USB_DEVICE(MCS7830_VENDOR_ID, MCS7830_PRODUCT_ID),
- .driver_info = (unsigned long) &moschip_info,
- },
- {
- USB_DEVICE(MCS7830_VENDOR_ID, MCS7730_PRODUCT_ID),
- .driver_info = (unsigned long) &moschip_info,
- },
- {
- USB_DEVICE(SITECOM_VENDOR_ID, LN_030_PRODUCT_ID),
- .driver_info = (unsigned long) &sitecom_info,
- },
- {},
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static int mcs7830_reset_resume (struct usb_interface *intf)
-{
- /* YES, this function is successful enough that ethtool -d
- does show same output pre-/post-suspend */
-
- struct usbnet *dev = usb_get_intfdata(intf);
-
- mcs7830_apply_base_config(dev);
-
- usbnet_resume(intf);
-
- return 0;
-}
-
-static struct usb_driver mcs7830_driver = {
- .name = driver_name,
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
- .reset_resume = mcs7830_reset_resume,
-};
-
-module_usb_driver(mcs7830_driver);
-
-MODULE_DESCRIPTION("USB to network adapter MCS7830)");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/net1080.c b/ANDROID_3.4.5/drivers/net/usb/net1080.c
deleted file mode 100644
index 83f965cb..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/net1080.c
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
- * Net1080 based USB host-to-host cables
- * Copyright (C) 2000-2005 by David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-// #define DEBUG // error path messages, extra info
-// #define VERBOSE // more; success messages
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/workqueue.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/usb/usbnet.h>
-#include <linux/slab.h>
-
-#include <asm/unaligned.h>
-
-
-/*
- * Netchip 1080 driver ... http://www.netchip.com
- * (Sept 2004: End-of-life announcement has been sent.)
- * Used in (some) LapLink cables
- */
-
-#define frame_errors data[1]
-
-/*
- * NetChip framing of ethernet packets, supporting additional error
- * checks for links that may drop bulk packets from inside messages.
- * Odd USB length == always short read for last usb packet.
- * - nc_header
- * - Ethernet header (14 bytes)
- * - payload
- * - (optional padding byte, if needed so length becomes odd)
- * - nc_trailer
- *
- * This framing is to be avoided for non-NetChip devices.
- */
-
-struct nc_header { // packed:
- __le16 hdr_len; // sizeof nc_header (LE, all)
- __le16 packet_len; // payload size (including ethhdr)
- __le16 packet_id; // detects dropped packets
-#define MIN_HEADER 6
-
- // all else is optional, and must start with:
- // __le16 vendorId; // from usb-if
- // __le16 productId;
-} __packed;
-
-#define PAD_BYTE ((unsigned char)0xAC)
-
-struct nc_trailer {
- __le16 packet_id;
-} __packed;
-
-// packets may use FLAG_FRAMING_NC and optional pad
-#define FRAMED_SIZE(mtu) (sizeof (struct nc_header) \
- + sizeof (struct ethhdr) \
- + (mtu) \
- + 1 \
- + sizeof (struct nc_trailer))
-
-#define MIN_FRAMED FRAMED_SIZE(0)
-
-/* packets _could_ be up to 64KB... */
-#define NC_MAX_PACKET 32767
-
-
-/*
- * Zero means no timeout; else, how long a 64 byte bulk packet may be queued
- * before the hardware drops it. If that's done, the driver will need to
- * frame network packets to guard against the dropped USB packets. The win32
- * driver sets this for both sides of the link.
- */
-#define NC_READ_TTL_MS ((u8)255) // ms
-
-/*
- * We ignore most registers and EEPROM contents.
- */
-#define REG_USBCTL ((u8)0x04)
-#define REG_TTL ((u8)0x10)
-#define REG_STATUS ((u8)0x11)
-
-/*
- * Vendor specific requests to read/write data
- */
-#define REQUEST_REGISTER ((u8)0x10)
-#define REQUEST_EEPROM ((u8)0x11)
-
-static int
-nc_vendor_read(struct usbnet *dev, u8 req, u8 regnum, u16 *retval_ptr)
-{
- int status = usb_control_msg(dev->udev,
- usb_rcvctrlpipe(dev->udev, 0),
- req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, regnum,
- retval_ptr, sizeof *retval_ptr,
- USB_CTRL_GET_TIMEOUT);
- if (status > 0)
- status = 0;
- if (!status)
- le16_to_cpus(retval_ptr);
- return status;
-}
-
-static inline int
-nc_register_read(struct usbnet *dev, u8 regnum, u16 *retval_ptr)
-{
- return nc_vendor_read(dev, REQUEST_REGISTER, regnum, retval_ptr);
-}
-
-// no retval ... can become async, usable in_interrupt()
-static void
-nc_vendor_write(struct usbnet *dev, u8 req, u8 regnum, u16 value)
-{
- usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, regnum,
- NULL, 0, // data is in setup packet
- USB_CTRL_SET_TIMEOUT);
-}
-
-static inline void
-nc_register_write(struct usbnet *dev, u8 regnum, u16 value)
-{
- nc_vendor_write(dev, REQUEST_REGISTER, regnum, value);
-}
-
-
-#if 0
-static void nc_dump_registers(struct usbnet *dev)
-{
- u8 reg;
- u16 *vp = kmalloc(sizeof (u16));
-
- if (!vp) {
- dbg("no memory?");
- return;
- }
-
- dbg("%s registers:", dev->net->name);
- for (reg = 0; reg < 0x20; reg++) {
- int retval;
-
- // reading some registers is trouble
- if (reg >= 0x08 && reg <= 0xf)
- continue;
- if (reg >= 0x12 && reg <= 0x1e)
- continue;
-
- retval = nc_register_read(dev, reg, vp);
- if (retval < 0)
- dbg("%s reg [0x%x] ==> error %d",
- dev->net->name, reg, retval);
- else
- dbg("%s reg [0x%x] = 0x%x",
- dev->net->name, reg, *vp);
- }
- kfree(vp);
-}
-#endif
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * Control register
- */
-
-#define USBCTL_WRITABLE_MASK 0x1f0f
-// bits 15-13 reserved, r/o
-#define USBCTL_ENABLE_LANG (1 << 12)
-#define USBCTL_ENABLE_MFGR (1 << 11)
-#define USBCTL_ENABLE_PROD (1 << 10)
-#define USBCTL_ENABLE_SERIAL (1 << 9)
-#define USBCTL_ENABLE_DEFAULTS (1 << 8)
-// bits 7-4 reserved, r/o
-#define USBCTL_FLUSH_OTHER (1 << 3)
-#define USBCTL_FLUSH_THIS (1 << 2)
-#define USBCTL_DISCONN_OTHER (1 << 1)
-#define USBCTL_DISCONN_THIS (1 << 0)
-
-static inline void nc_dump_usbctl(struct usbnet *dev, u16 usbctl)
-{
- netif_dbg(dev, link, dev->net,
- "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s; this%s%s; other%s%s; r/o 0x%x\n",
- dev->udev->bus->bus_name, dev->udev->devpath,
- usbctl,
- (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "",
- (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "",
- (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "",
- (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "",
- (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "",
-
- (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "",
- (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "",
-
- (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "",
- (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "",
-
- usbctl & ~USBCTL_WRITABLE_MASK);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * Status register
- */
-
-#define STATUS_PORT_A (1 << 15)
-
-#define STATUS_CONN_OTHER (1 << 14)
-#define STATUS_SUSPEND_OTHER (1 << 13)
-#define STATUS_MAILBOX_OTHER (1 << 12)
-#define STATUS_PACKETS_OTHER(n) (((n) >> 8) & 0x03)
-
-#define STATUS_CONN_THIS (1 << 6)
-#define STATUS_SUSPEND_THIS (1 << 5)
-#define STATUS_MAILBOX_THIS (1 << 4)
-#define STATUS_PACKETS_THIS(n) (((n) >> 0) & 0x03)
-
-#define STATUS_UNSPEC_MASK 0x0c8c
-#define STATUS_NOISE_MASK ((u16)~(0x0303|STATUS_UNSPEC_MASK))
-
-
-static inline void nc_dump_status(struct usbnet *dev, u16 status)
-{
- netif_dbg(dev, link, dev->net,
- "net1080 %s-%s status 0x%x: this (%c) PKT=%d%s%s%s; other PKT=%d%s%s%s; unspec 0x%x\n",
- dev->udev->bus->bus_name, dev->udev->devpath,
- status,
-
- // XXX the packet counts don't seem right
- // (1 at reset, not 0); maybe UNSPEC too
-
- (status & STATUS_PORT_A) ? 'A' : 'B',
- STATUS_PACKETS_THIS(status),
- (status & STATUS_CONN_THIS) ? " CON" : "",
- (status & STATUS_SUSPEND_THIS) ? " SUS" : "",
- (status & STATUS_MAILBOX_THIS) ? " MBOX" : "",
-
- STATUS_PACKETS_OTHER(status),
- (status & STATUS_CONN_OTHER) ? " CON" : "",
- (status & STATUS_SUSPEND_OTHER) ? " SUS" : "",
- (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "",
-
- status & STATUS_UNSPEC_MASK);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * TTL register
- */
-
-#define TTL_THIS(ttl) (0x00ff & ttl)
-#define TTL_OTHER(ttl) (0x00ff & (ttl >> 8))
-#define MK_TTL(this,other) ((u16)(((other)<<8)|(0x00ff&(this))))
-
-static inline void nc_dump_ttl(struct usbnet *dev, u16 ttl)
-{
- netif_dbg(dev, link, dev->net, "net1080 %s-%s ttl 0x%x this = %d, other = %d\n",
- dev->udev->bus->bus_name, dev->udev->devpath,
- ttl, TTL_THIS(ttl), TTL_OTHER(ttl));
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int net1080_reset(struct usbnet *dev)
-{
- u16 usbctl, status, ttl;
- u16 *vp = kmalloc(sizeof (u16), GFP_KERNEL);
- int retval;
-
- if (!vp)
- return -ENOMEM;
-
- // nc_dump_registers(dev);
-
- if ((retval = nc_register_read(dev, REG_STATUS, vp)) < 0) {
- dbg("can't read %s-%s status: %d",
- dev->udev->bus->bus_name, dev->udev->devpath, retval);
- goto done;
- }
- status = *vp;
- nc_dump_status(dev, status);
-
- if ((retval = nc_register_read(dev, REG_USBCTL, vp)) < 0) {
- dbg("can't read USBCTL, %d", retval);
- goto done;
- }
- usbctl = *vp;
- nc_dump_usbctl(dev, usbctl);
-
- nc_register_write(dev, REG_USBCTL,
- USBCTL_FLUSH_THIS | USBCTL_FLUSH_OTHER);
-
- if ((retval = nc_register_read(dev, REG_TTL, vp)) < 0) {
- dbg("can't read TTL, %d", retval);
- goto done;
- }
- ttl = *vp;
- // nc_dump_ttl(dev, ttl);
-
- nc_register_write(dev, REG_TTL,
- MK_TTL(NC_READ_TTL_MS, TTL_OTHER(ttl)) );
- dbg("%s: assigned TTL, %d ms", dev->net->name, NC_READ_TTL_MS);
-
- netif_info(dev, link, dev->net, "port %c, peer %sconnected\n",
- (status & STATUS_PORT_A) ? 'A' : 'B',
- (status & STATUS_CONN_OTHER) ? "" : "dis");
- retval = 0;
-
-done:
- kfree(vp);
- return retval;
-}
-
-static int net1080_check_connect(struct usbnet *dev)
-{
- int retval;
- u16 status;
- u16 *vp = kmalloc(sizeof (u16), GFP_KERNEL);
-
- if (!vp)
- return -ENOMEM;
- retval = nc_register_read(dev, REG_STATUS, vp);
- status = *vp;
- kfree(vp);
- if (retval != 0) {
- dbg("%s net1080_check_conn read - %d", dev->net->name, retval);
- return retval;
- }
- if ((status & STATUS_CONN_OTHER) != STATUS_CONN_OTHER)
- return -ENOLINK;
- return 0;
-}
-
-static void nc_flush_complete(struct urb *urb)
-{
- kfree(urb->context);
- usb_free_urb(urb);
-}
-
-static void nc_ensure_sync(struct usbnet *dev)
-{
- dev->frame_errors++;
- if (dev->frame_errors > 5) {
- struct urb *urb;
- struct usb_ctrlrequest *req;
- int status;
-
- /* Send a flush */
- urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!urb)
- return;
-
- req = kmalloc(sizeof *req, GFP_ATOMIC);
- if (!req) {
- usb_free_urb(urb);
- return;
- }
-
- req->bRequestType = USB_DIR_OUT
- | USB_TYPE_VENDOR
- | USB_RECIP_DEVICE;
- req->bRequest = REQUEST_REGISTER;
- req->wValue = cpu_to_le16(USBCTL_FLUSH_THIS
- | USBCTL_FLUSH_OTHER);
- req->wIndex = cpu_to_le16(REG_USBCTL);
- req->wLength = cpu_to_le16(0);
-
- /* queue an async control request, we don't need
- * to do anything when it finishes except clean up.
- */
- usb_fill_control_urb(urb, dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- (unsigned char *) req,
- NULL, 0,
- nc_flush_complete, req);
- status = usb_submit_urb(urb, GFP_ATOMIC);
- if (status) {
- kfree(req);
- usb_free_urb(urb);
- return;
- }
-
- netif_dbg(dev, rx_err, dev->net,
- "flush net1080; too many framing errors\n");
- dev->frame_errors = 0;
- }
-}
-
-static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- struct nc_header *header;
- struct nc_trailer *trailer;
- u16 hdr_len, packet_len;
-
- if (!(skb->len & 0x01)) {
-#ifdef DEBUG
- struct net_device *net = dev->net;
- dbg("rx framesize %d range %d..%d mtu %d", skb->len,
- net->hard_header_len, dev->hard_mtu, net->mtu);
-#endif
- dev->net->stats.rx_frame_errors++;
- nc_ensure_sync(dev);
- return 0;
- }
-
- header = (struct nc_header *) skb->data;
- hdr_len = le16_to_cpup(&header->hdr_len);
- packet_len = le16_to_cpup(&header->packet_len);
- if (FRAMED_SIZE(packet_len) > NC_MAX_PACKET) {
- dev->net->stats.rx_frame_errors++;
- dbg("packet too big, %d", packet_len);
- nc_ensure_sync(dev);
- return 0;
- } else if (hdr_len < MIN_HEADER) {
- dev->net->stats.rx_frame_errors++;
- dbg("header too short, %d", hdr_len);
- nc_ensure_sync(dev);
- return 0;
- } else if (hdr_len > MIN_HEADER) {
- // out of band data for us?
- dbg("header OOB, %d bytes", hdr_len - MIN_HEADER);
- nc_ensure_sync(dev);
- // switch (vendor/product ids) { ... }
- }
- skb_pull(skb, hdr_len);
-
- trailer = (struct nc_trailer *)
- (skb->data + skb->len - sizeof *trailer);
- skb_trim(skb, skb->len - sizeof *trailer);
-
- if ((packet_len & 0x01) == 0) {
- if (skb->data [packet_len] != PAD_BYTE) {
- dev->net->stats.rx_frame_errors++;
- dbg("bad pad");
- return 0;
- }
- skb_trim(skb, skb->len - 1);
- }
- if (skb->len != packet_len) {
- dev->net->stats.rx_frame_errors++;
- dbg("bad packet len %d (expected %d)",
- skb->len, packet_len);
- nc_ensure_sync(dev);
- return 0;
- }
- if (header->packet_id != get_unaligned(&trailer->packet_id)) {
- dev->net->stats.rx_fifo_errors++;
- dbg("(2+ dropped) rx packet_id mismatch 0x%x 0x%x",
- le16_to_cpu(header->packet_id),
- le16_to_cpu(trailer->packet_id));
- return 0;
- }
-#if 0
- netdev_dbg(dev->net, "frame <rx h %d p %d id %d\n", header->hdr_len,
- header->packet_len, header->packet_id);
-#endif
- dev->frame_errors = 0;
- return 1;
-}
-
-static struct sk_buff *
-net1080_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
-{
- struct sk_buff *skb2;
- struct nc_header *header = NULL;
- struct nc_trailer *trailer = NULL;
- int padlen = sizeof (struct nc_trailer);
- int len = skb->len;
-
- if (!((len + padlen + sizeof (struct nc_header)) & 0x01))
- padlen++;
- if (!skb_cloned(skb)) {
- int headroom = skb_headroom(skb);
- int tailroom = skb_tailroom(skb);
-
- if (padlen <= tailroom &&
- sizeof(struct nc_header) <= headroom)
- /* There's enough head and tail room */
- goto encapsulate;
-
- if ((sizeof (struct nc_header) + padlen) <
- (headroom + tailroom)) {
- /* There's enough total room, so just readjust */
- skb->data = memmove(skb->head
- + sizeof (struct nc_header),
- skb->data, skb->len);
- skb_set_tail_pointer(skb, len);
- goto encapsulate;
- }
- }
-
- /* Create a new skb to use with the correct size */
- skb2 = skb_copy_expand(skb,
- sizeof (struct nc_header),
- padlen,
- flags);
- dev_kfree_skb_any(skb);
- if (!skb2)
- return skb2;
- skb = skb2;
-
-encapsulate:
- /* header first */
- header = (struct nc_header *) skb_push(skb, sizeof *header);
- header->hdr_len = cpu_to_le16(sizeof (*header));
- header->packet_len = cpu_to_le16(len);
- header->packet_id = cpu_to_le16((u16)dev->xid++);
-
- /* maybe pad; then trailer */
- if (!((skb->len + sizeof *trailer) & 0x01))
- *skb_put(skb, 1) = PAD_BYTE;
- trailer = (struct nc_trailer *) skb_put(skb, sizeof *trailer);
- put_unaligned(header->packet_id, &trailer->packet_id);
-#if 0
- netdev_dbg(dev->net, "frame >tx h %d p %d id %d\n",
- header->hdr_len, header->packet_len,
- header->packet_id);
-#endif
- return skb;
-}
-
-static int net1080_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- unsigned extra = sizeof (struct nc_header)
- + 1
- + sizeof (struct nc_trailer);
-
- dev->net->hard_header_len += extra;
- dev->rx_urb_size = dev->net->hard_header_len + dev->net->mtu;
- dev->hard_mtu = NC_MAX_PACKET;
- return usbnet_get_endpoints (dev, intf);
-}
-
-static const struct driver_info net1080_info = {
- .description = "NetChip TurboCONNECT",
- .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_NC,
- .bind = net1080_bind,
- .reset = net1080_reset,
- .check_connect = net1080_check_connect,
- .rx_fixup = net1080_rx_fixup,
- .tx_fixup = net1080_tx_fixup,
-};
-
-static const struct usb_device_id products [] = {
-{
- USB_DEVICE(0x0525, 0x1080), // NetChip ref design
- .driver_info = (unsigned long) &net1080_info,
-}, {
- USB_DEVICE(0x06D0, 0x0622), // Laplink Gold
- .driver_info = (unsigned long) &net1080_info,
-},
- { }, // END
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver net1080_driver = {
- .name = "net1080",
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
-};
-
-module_usb_driver(net1080_driver);
-
-MODULE_AUTHOR("David Brownell");
-MODULE_DESCRIPTION("NetChip 1080 based USB Host-to-Host Links");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/pegasus.c b/ANDROID_3.4.5/drivers/net/usb/pegasus.c
deleted file mode 100644
index 75239309..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/pegasus.c
+++ /dev/null
@@ -1,1539 +0,0 @@
-/*
- * Copyright (c) 1999-2005 Petko Manolov (petkan@users.sourceforge.net)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * ChangeLog:
- * .... Most of the time spent on reading sources & docs.
- * v0.2.x First official release for the Linux kernel.
- * v0.3.0 Beutified and structured, some bugs fixed.
- * v0.3.x URBifying bulk requests and bugfixing. First relatively
- * stable release. Still can touch device's registers only
- * from top-halves.
- * v0.4.0 Control messages remained unurbified are now URBs.
- * Now we can touch the HW at any time.
- * v0.4.9 Control urbs again use process context to wait. Argh...
- * Some long standing bugs (enable_net_traffic) fixed.
- * Also nasty trick about resubmiting control urb from
- * interrupt context used. Please let me know how it
- * behaves. Pegasus II support added since this version.
- * TODO: suppressing HCD warnings spewage on disconnect.
- * v0.4.13 Ethernet address is now set at probe(), not at open()
- * time as this seems to break dhcpd.
- * v0.5.0 branch to 2.5.x kernels
- * v0.5.1 ethtool support added
- * v0.5.5 rx socket buffers are in a pool and the their allocation
- * is out of the interrupt routine.
- */
-
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/module.h>
-#include <asm/byteorder.h>
-#include <asm/uaccess.h>
-#include "pegasus.h"
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v0.6.14 (2006/09/27)"
-#define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
-#define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
-
-static const char driver_name[] = "pegasus";
-
-#undef PEGASUS_WRITE_EEPROM
-#define BMSR_MEDIA (BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | \
- BMSR_100FULL | BMSR_ANEGCAPABLE)
-
-static bool loopback;
-static bool mii_mode;
-static char *devid;
-
-static struct usb_eth_dev usb_dev_id[] = {
-#define PEGASUS_DEV(pn, vid, pid, flags) \
- {.name = pn, .vendor = vid, .device = pid, .private = flags},
-#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \
- PEGASUS_DEV(pn, vid, pid, flags)
-#include "pegasus.h"
-#undef PEGASUS_DEV
-#undef PEGASUS_DEV_CLASS
- {NULL, 0, 0, 0},
- {NULL, 0, 0, 0}
-};
-
-static struct usb_device_id pegasus_ids[] = {
-#define PEGASUS_DEV(pn, vid, pid, flags) \
- {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid},
-/*
- * The Belkin F8T012xx1 bluetooth adaptor has the same vendor and product
- * IDs as the Belkin F5D5050, so we need to teach the pegasus driver to
- * ignore adaptors belonging to the "Wireless" class 0xE0. For this one
- * case anyway, seeing as the pegasus is for "Wired" adaptors.
- */
-#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \
- {.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS), \
- .idVendor = vid, .idProduct = pid, .bDeviceClass = dclass},
-#include "pegasus.h"
-#undef PEGASUS_DEV
-#undef PEGASUS_DEV_CLASS
- {},
- {}
-};
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-module_param(loopback, bool, 0);
-module_param(mii_mode, bool, 0);
-module_param(devid, charp, 0);
-MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)");
-MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0");
-MODULE_PARM_DESC(devid, "The format is: 'DEV_name:VendorID:DeviceID:Flags'");
-
-/* use ethtool to change the level for any given device */
-static int msg_level = -1;
-module_param(msg_level, int, 0);
-MODULE_PARM_DESC(msg_level, "Override default message level");
-
-MODULE_DEVICE_TABLE(usb, pegasus_ids);
-static const struct net_device_ops pegasus_netdev_ops;
-
-static int update_eth_regs_async(pegasus_t *);
-/* Aargh!!! I _really_ hate such tweaks */
-static void ctrl_callback(struct urb *urb)
-{
- pegasus_t *pegasus = urb->context;
- int status = urb->status;
-
- if (!pegasus)
- return;
-
- switch (status) {
- case 0:
- if (pegasus->flags & ETH_REGS_CHANGE) {
- pegasus->flags &= ~ETH_REGS_CHANGE;
- pegasus->flags |= ETH_REGS_CHANGED;
- update_eth_regs_async(pegasus);
- return;
- }
- break;
- case -EINPROGRESS:
- return;
- case -ENOENT:
- break;
- default:
- if (net_ratelimit())
- netif_dbg(pegasus, drv, pegasus->net,
- "%s, status %d\n", __func__, status);
- break;
- }
- pegasus->flags &= ~ETH_REGS_CHANGED;
- wake_up(&pegasus->ctrl_wait);
-}
-
-static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
- void *data)
-{
- int ret;
- char *buffer;
- DECLARE_WAITQUEUE(wait, current);
-
- buffer = kmalloc(size, GFP_KERNEL);
- if (!buffer) {
- netif_warn(pegasus, drv, pegasus->net,
- "out of memory in %s\n", __func__);
- return -ENOMEM;
- }
- add_wait_queue(&pegasus->ctrl_wait, &wait);
- set_current_state(TASK_UNINTERRUPTIBLE);
- while (pegasus->flags & ETH_REGS_CHANGED)
- schedule();
- remove_wait_queue(&pegasus->ctrl_wait, &wait);
- set_current_state(TASK_RUNNING);
-
- pegasus->dr.bRequestType = PEGASUS_REQT_READ;
- pegasus->dr.bRequest = PEGASUS_REQ_GET_REGS;
- pegasus->dr.wValue = cpu_to_le16(0);
- pegasus->dr.wIndex = cpu_to_le16(indx);
- pegasus->dr.wLength = cpu_to_le16(size);
- pegasus->ctrl_urb->transfer_buffer_length = size;
-
- usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb,
- usb_rcvctrlpipe(pegasus->usb, 0),
- (char *) &pegasus->dr,
- buffer, size, ctrl_callback, pegasus);
-
- add_wait_queue(&pegasus->ctrl_wait, &wait);
- set_current_state(TASK_UNINTERRUPTIBLE);
-
- /* using ATOMIC, we'd never wake up if we slept */
- if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
- set_current_state(TASK_RUNNING);
- if (ret == -ENODEV)
- netif_device_detach(pegasus->net);
- if (net_ratelimit())
- netif_err(pegasus, drv, pegasus->net,
- "%s, status %d\n", __func__, ret);
- goto out;
- }
-
- schedule();
-out:
- remove_wait_queue(&pegasus->ctrl_wait, &wait);
- memcpy(data, buffer, size);
- kfree(buffer);
-
- return ret;
-}
-
-static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
- void *data)
-{
- int ret;
- char *buffer;
- DECLARE_WAITQUEUE(wait, current);
-
- buffer = kmemdup(data, size, GFP_KERNEL);
- if (!buffer) {
- netif_warn(pegasus, drv, pegasus->net,
- "out of memory in %s\n", __func__);
- return -ENOMEM;
- }
-
- add_wait_queue(&pegasus->ctrl_wait, &wait);
- set_current_state(TASK_UNINTERRUPTIBLE);
- while (pegasus->flags & ETH_REGS_CHANGED)
- schedule();
- remove_wait_queue(&pegasus->ctrl_wait, &wait);
- set_current_state(TASK_RUNNING);
-
- pegasus->dr.bRequestType = PEGASUS_REQT_WRITE;
- pegasus->dr.bRequest = PEGASUS_REQ_SET_REGS;
- pegasus->dr.wValue = cpu_to_le16(0);
- pegasus->dr.wIndex = cpu_to_le16(indx);
- pegasus->dr.wLength = cpu_to_le16(size);
- pegasus->ctrl_urb->transfer_buffer_length = size;
-
- usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb,
- usb_sndctrlpipe(pegasus->usb, 0),
- (char *) &pegasus->dr,
- buffer, size, ctrl_callback, pegasus);
-
- add_wait_queue(&pegasus->ctrl_wait, &wait);
- set_current_state(TASK_UNINTERRUPTIBLE);
-
- if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
- if (ret == -ENODEV)
- netif_device_detach(pegasus->net);
- netif_err(pegasus, drv, pegasus->net,
- "%s, status %d\n", __func__, ret);
- goto out;
- }
-
- schedule();
-out:
- remove_wait_queue(&pegasus->ctrl_wait, &wait);
- kfree(buffer);
-
- return ret;
-}
-
-static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data)
-{
- int ret;
- char *tmp;
- DECLARE_WAITQUEUE(wait, current);
-
- tmp = kmemdup(&data, 1, GFP_KERNEL);
- if (!tmp) {
- netif_warn(pegasus, drv, pegasus->net,
- "out of memory in %s\n", __func__);
- return -ENOMEM;
- }
- add_wait_queue(&pegasus->ctrl_wait, &wait);
- set_current_state(TASK_UNINTERRUPTIBLE);
- while (pegasus->flags & ETH_REGS_CHANGED)
- schedule();
- remove_wait_queue(&pegasus->ctrl_wait, &wait);
- set_current_state(TASK_RUNNING);
-
- pegasus->dr.bRequestType = PEGASUS_REQT_WRITE;
- pegasus->dr.bRequest = PEGASUS_REQ_SET_REG;
- pegasus->dr.wValue = cpu_to_le16(data);
- pegasus->dr.wIndex = cpu_to_le16(indx);
- pegasus->dr.wLength = cpu_to_le16(1);
- pegasus->ctrl_urb->transfer_buffer_length = 1;
-
- usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb,
- usb_sndctrlpipe(pegasus->usb, 0),
- (char *) &pegasus->dr,
- tmp, 1, ctrl_callback, pegasus);
-
- add_wait_queue(&pegasus->ctrl_wait, &wait);
- set_current_state(TASK_UNINTERRUPTIBLE);
-
- if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
- if (ret == -ENODEV)
- netif_device_detach(pegasus->net);
- if (net_ratelimit())
- netif_err(pegasus, drv, pegasus->net,
- "%s, status %d\n", __func__, ret);
- goto out;
- }
-
- schedule();
-out:
- remove_wait_queue(&pegasus->ctrl_wait, &wait);
- kfree(tmp);
-
- return ret;
-}
-
-static int update_eth_regs_async(pegasus_t *pegasus)
-{
- int ret;
-
- pegasus->dr.bRequestType = PEGASUS_REQT_WRITE;
- pegasus->dr.bRequest = PEGASUS_REQ_SET_REGS;
- pegasus->dr.wValue = cpu_to_le16(0);
- pegasus->dr.wIndex = cpu_to_le16(EthCtrl0);
- pegasus->dr.wLength = cpu_to_le16(3);
- pegasus->ctrl_urb->transfer_buffer_length = 3;
-
- usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb,
- usb_sndctrlpipe(pegasus->usb, 0),
- (char *) &pegasus->dr,
- pegasus->eth_regs, 3, ctrl_callback, pegasus);
-
- if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
- if (ret == -ENODEV)
- netif_device_detach(pegasus->net);
- netif_err(pegasus, drv, pegasus->net,
- "%s, status %d\n", __func__, ret);
- }
-
- return ret;
-}
-
-/* Returns 0 on success, error on failure */
-static int read_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 *regd)
-{
- int i;
- __u8 data[4] = { phy, 0, 0, indx };
- __le16 regdi;
- int ret;
-
- set_register(pegasus, PhyCtrl, 0);
- set_registers(pegasus, PhyAddr, sizeof(data), data);
- set_register(pegasus, PhyCtrl, (indx | PHY_READ));
- for (i = 0; i < REG_TIMEOUT; i++) {
- ret = get_registers(pegasus, PhyCtrl, 1, data);
- if (ret == -ESHUTDOWN)
- goto fail;
- if (data[0] & PHY_DONE)
- break;
- }
-
- if (i >= REG_TIMEOUT)
- goto fail;
-
- ret = get_registers(pegasus, PhyData, 2, &regdi);
- *regd = le16_to_cpu(regdi);
- return ret;
-
-fail:
- netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__);
-
- return ret;
-}
-
-static int mdio_read(struct net_device *dev, int phy_id, int loc)
-{
- pegasus_t *pegasus = netdev_priv(dev);
- u16 res;
-
- read_mii_word(pegasus, phy_id, loc, &res);
- return (int)res;
-}
-
-static int write_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 regd)
-{
- int i;
- __u8 data[4] = { phy, 0, 0, indx };
- int ret;
-
- data[1] = (u8) regd;
- data[2] = (u8) (regd >> 8);
- set_register(pegasus, PhyCtrl, 0);
- set_registers(pegasus, PhyAddr, sizeof(data), data);
- set_register(pegasus, PhyCtrl, (indx | PHY_WRITE));
- for (i = 0; i < REG_TIMEOUT; i++) {
- ret = get_registers(pegasus, PhyCtrl, 1, data);
- if (ret == -ESHUTDOWN)
- goto fail;
- if (data[0] & PHY_DONE)
- break;
- }
-
- if (i >= REG_TIMEOUT)
- goto fail;
-
- return ret;
-
-fail:
- netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__);
- return -ETIMEDOUT;
-}
-
-static void mdio_write(struct net_device *dev, int phy_id, int loc, int val)
-{
- pegasus_t *pegasus = netdev_priv(dev);
-
- write_mii_word(pegasus, phy_id, loc, val);
-}
-
-static int read_eprom_word(pegasus_t *pegasus, __u8 index, __u16 *retdata)
-{
- int i;
- __u8 tmp;
- __le16 retdatai;
- int ret;
-
- set_register(pegasus, EpromCtrl, 0);
- set_register(pegasus, EpromOffset, index);
- set_register(pegasus, EpromCtrl, EPROM_READ);
-
- for (i = 0; i < REG_TIMEOUT; i++) {
- ret = get_registers(pegasus, EpromCtrl, 1, &tmp);
- if (tmp & EPROM_DONE)
- break;
- if (ret == -ESHUTDOWN)
- goto fail;
- }
- if (i >= REG_TIMEOUT)
- goto fail;
-
- ret = get_registers(pegasus, EpromData, 2, &retdatai);
- *retdata = le16_to_cpu(retdatai);
- return ret;
-
-fail:
- netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__);
- return -ETIMEDOUT;
-}
-
-#ifdef PEGASUS_WRITE_EEPROM
-static inline void enable_eprom_write(pegasus_t *pegasus)
-{
- __u8 tmp;
- int ret;
-
- get_registers(pegasus, EthCtrl2, 1, &tmp);
- set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE);
-}
-
-static inline void disable_eprom_write(pegasus_t *pegasus)
-{
- __u8 tmp;
- int ret;
-
- get_registers(pegasus, EthCtrl2, 1, &tmp);
- set_register(pegasus, EpromCtrl, 0);
- set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE);
-}
-
-static int write_eprom_word(pegasus_t *pegasus, __u8 index, __u16 data)
-{
- int i;
- __u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE };
- int ret;
- __le16 le_data = cpu_to_le16(data);
-
- set_registers(pegasus, EpromOffset, 4, d);
- enable_eprom_write(pegasus);
- set_register(pegasus, EpromOffset, index);
- set_registers(pegasus, EpromData, 2, &le_data);
- set_register(pegasus, EpromCtrl, EPROM_WRITE);
-
- for (i = 0; i < REG_TIMEOUT; i++) {
- ret = get_registers(pegasus, EpromCtrl, 1, &tmp);
- if (ret == -ESHUTDOWN)
- goto fail;
- if (tmp & EPROM_DONE)
- break;
- }
- disable_eprom_write(pegasus);
- if (i >= REG_TIMEOUT)
- goto fail;
-
- return ret;
-
-fail:
- netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__);
- return -ETIMEDOUT;
-}
-#endif /* PEGASUS_WRITE_EEPROM */
-
-static inline void get_node_id(pegasus_t *pegasus, __u8 *id)
-{
- int i;
- __u16 w16;
-
- for (i = 0; i < 3; i++) {
- read_eprom_word(pegasus, i, &w16);
- ((__le16 *) id)[i] = cpu_to_le16(w16);
- }
-}
-
-static void set_ethernet_addr(pegasus_t *pegasus)
-{
- __u8 node_id[6];
-
- if (pegasus->features & PEGASUS_II) {
- get_registers(pegasus, 0x10, sizeof(node_id), node_id);
- } else {
- get_node_id(pegasus, node_id);
- set_registers(pegasus, EthID, sizeof(node_id), node_id);
- }
- memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id));
-}
-
-static inline int reset_mac(pegasus_t *pegasus)
-{
- __u8 data = 0x8;
- int i;
-
- set_register(pegasus, EthCtrl1, data);
- for (i = 0; i < REG_TIMEOUT; i++) {
- get_registers(pegasus, EthCtrl1, 1, &data);
- if (~data & 0x08) {
- if (loopback)
- break;
- if (mii_mode && (pegasus->features & HAS_HOME_PNA))
- set_register(pegasus, Gpio1, 0x34);
- else
- set_register(pegasus, Gpio1, 0x26);
- set_register(pegasus, Gpio0, pegasus->features);
- set_register(pegasus, Gpio0, DEFAULT_GPIO_SET);
- break;
- }
- }
- if (i == REG_TIMEOUT)
- return -ETIMEDOUT;
-
- if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
- usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) {
- set_register(pegasus, Gpio0, 0x24);
- set_register(pegasus, Gpio0, 0x26);
- }
- if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) {
- __u16 auxmode;
- read_mii_word(pegasus, 3, 0x1b, &auxmode);
- write_mii_word(pegasus, 3, 0x1b, auxmode | 4);
- }
-
- return 0;
-}
-
-static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
-{
- __u16 linkpart;
- __u8 data[4];
- pegasus_t *pegasus = netdev_priv(dev);
- int ret;
-
- read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart);
- data[0] = 0xc9;
- data[1] = 0;
- if (linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL))
- data[1] |= 0x20; /* set full duplex */
- if (linkpart & (ADVERTISE_100FULL | ADVERTISE_100HALF))
- data[1] |= 0x10; /* set 100 Mbps */
- if (mii_mode)
- data[1] = 0;
- data[2] = loopback ? 0x09 : 0x01;
-
- memcpy(pegasus->eth_regs, data, sizeof(data));
- ret = set_registers(pegasus, EthCtrl0, 3, data);
-
- if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
- usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS2 ||
- usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) {
- u16 auxmode;
- read_mii_word(pegasus, 0, 0x1b, &auxmode);
- write_mii_word(pegasus, 0, 0x1b, auxmode | 4);
- }
-
- return ret;
-}
-
-static void fill_skb_pool(pegasus_t *pegasus)
-{
- int i;
-
- for (i = 0; i < RX_SKBS; i++) {
- if (pegasus->rx_pool[i])
- continue;
- pegasus->rx_pool[i] = dev_alloc_skb(PEGASUS_MTU + 2);
- /*
- ** we give up if the allocation fail. the tasklet will be
- ** rescheduled again anyway...
- */
- if (pegasus->rx_pool[i] == NULL)
- return;
- skb_reserve(pegasus->rx_pool[i], 2);
- }
-}
-
-static void free_skb_pool(pegasus_t *pegasus)
-{
- int i;
-
- for (i = 0; i < RX_SKBS; i++) {
- if (pegasus->rx_pool[i]) {
- dev_kfree_skb(pegasus->rx_pool[i]);
- pegasus->rx_pool[i] = NULL;
- }
- }
-}
-
-static inline struct sk_buff *pull_skb(pegasus_t * pegasus)
-{
- int i;
- struct sk_buff *skb;
-
- for (i = 0; i < RX_SKBS; i++) {
- if (likely(pegasus->rx_pool[i] != NULL)) {
- skb = pegasus->rx_pool[i];
- pegasus->rx_pool[i] = NULL;
- return skb;
- }
- }
- return NULL;
-}
-
-static void read_bulk_callback(struct urb *urb)
-{
- pegasus_t *pegasus = urb->context;
- struct net_device *net;
- int rx_status, count = urb->actual_length;
- int status = urb->status;
- u8 *buf = urb->transfer_buffer;
- __u16 pkt_len;
-
- if (!pegasus)
- return;
-
- net = pegasus->net;
- if (!netif_device_present(net) || !netif_running(net))
- return;
-
- switch (status) {
- case 0:
- break;
- case -ETIME:
- netif_dbg(pegasus, rx_err, net, "reset MAC\n");
- pegasus->flags &= ~PEGASUS_RX_BUSY;
- break;
- case -EPIPE: /* stall, or disconnect from TT */
- /* FIXME schedule work to clear the halt */
- netif_warn(pegasus, rx_err, net, "no rx stall recovery\n");
- return;
- case -ENOENT:
- case -ECONNRESET:
- case -ESHUTDOWN:
- netif_dbg(pegasus, ifdown, net, "rx unlink, %d\n", status);
- return;
- default:
- netif_dbg(pegasus, rx_err, net, "RX status %d\n", status);
- goto goon;
- }
-
- if (!count || count < 4)
- goto goon;
-
- rx_status = buf[count - 2];
- if (rx_status & 0x1e) {
- netif_dbg(pegasus, rx_err, net,
- "RX packet error %x\n", rx_status);
- pegasus->stats.rx_errors++;
- if (rx_status & 0x06) /* long or runt */
- pegasus->stats.rx_length_errors++;
- if (rx_status & 0x08)
- pegasus->stats.rx_crc_errors++;
- if (rx_status & 0x10) /* extra bits */
- pegasus->stats.rx_frame_errors++;
- goto goon;
- }
- if (pegasus->chip == 0x8513) {
- pkt_len = le32_to_cpu(*(__le32 *)urb->transfer_buffer);
- pkt_len &= 0x0fff;
- pegasus->rx_skb->data += 2;
- } else {
- pkt_len = buf[count - 3] << 8;
- pkt_len += buf[count - 4];
- pkt_len &= 0xfff;
- pkt_len -= 8;
- }
-
- /*
- * If the packet is unreasonably long, quietly drop it rather than
- * kernel panicing by calling skb_put.
- */
- if (pkt_len > PEGASUS_MTU)
- goto goon;
-
- /*
- * at this point we are sure pegasus->rx_skb != NULL
- * so we go ahead and pass up the packet.
- */
- skb_put(pegasus->rx_skb, pkt_len);
- pegasus->rx_skb->protocol = eth_type_trans(pegasus->rx_skb, net);
- netif_rx(pegasus->rx_skb);
- pegasus->stats.rx_packets++;
- pegasus->stats.rx_bytes += pkt_len;
-
- if (pegasus->flags & PEGASUS_UNPLUG)
- return;
-
- spin_lock(&pegasus->rx_pool_lock);
- pegasus->rx_skb = pull_skb(pegasus);
- spin_unlock(&pegasus->rx_pool_lock);
-
- if (pegasus->rx_skb == NULL)
- goto tl_sched;
-goon:
- usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb,
- usb_rcvbulkpipe(pegasus->usb, 1),
- pegasus->rx_skb->data, PEGASUS_MTU + 8,
- read_bulk_callback, pegasus);
- rx_status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC);
- if (rx_status == -ENODEV)
- netif_device_detach(pegasus->net);
- else if (rx_status) {
- pegasus->flags |= PEGASUS_RX_URB_FAIL;
- goto tl_sched;
- } else {
- pegasus->flags &= ~PEGASUS_RX_URB_FAIL;
- }
-
- return;
-
-tl_sched:
- tasklet_schedule(&pegasus->rx_tl);
-}
-
-static void rx_fixup(unsigned long data)
-{
- pegasus_t *pegasus;
- unsigned long flags;
- int status;
-
- pegasus = (pegasus_t *) data;
- if (pegasus->flags & PEGASUS_UNPLUG)
- return;
-
- spin_lock_irqsave(&pegasus->rx_pool_lock, flags);
- fill_skb_pool(pegasus);
- if (pegasus->flags & PEGASUS_RX_URB_FAIL)
- if (pegasus->rx_skb)
- goto try_again;
- if (pegasus->rx_skb == NULL)
- pegasus->rx_skb = pull_skb(pegasus);
- if (pegasus->rx_skb == NULL) {
- netif_warn(pegasus, rx_err, pegasus->net, "low on memory\n");
- tasklet_schedule(&pegasus->rx_tl);
- goto done;
- }
- usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb,
- usb_rcvbulkpipe(pegasus->usb, 1),
- pegasus->rx_skb->data, PEGASUS_MTU + 8,
- read_bulk_callback, pegasus);
-try_again:
- status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC);
- if (status == -ENODEV)
- netif_device_detach(pegasus->net);
- else if (status) {
- pegasus->flags |= PEGASUS_RX_URB_FAIL;
- tasklet_schedule(&pegasus->rx_tl);
- } else {
- pegasus->flags &= ~PEGASUS_RX_URB_FAIL;
- }
-done:
- spin_unlock_irqrestore(&pegasus->rx_pool_lock, flags);
-}
-
-static void write_bulk_callback(struct urb *urb)
-{
- pegasus_t *pegasus = urb->context;
- struct net_device *net;
- int status = urb->status;
-
- if (!pegasus)
- return;
-
- net = pegasus->net;
-
- if (!netif_device_present(net) || !netif_running(net))
- return;
-
- switch (status) {
- case -EPIPE:
- /* FIXME schedule_work() to clear the tx halt */
- netif_stop_queue(net);
- netif_warn(pegasus, tx_err, net, "no tx stall recovery\n");
- return;
- case -ENOENT:
- case -ECONNRESET:
- case -ESHUTDOWN:
- netif_dbg(pegasus, ifdown, net, "tx unlink, %d\n", status);
- return;
- default:
- netif_info(pegasus, tx_err, net, "TX status %d\n", status);
- /* FALL THROUGH */
- case 0:
- break;
- }
-
- net->trans_start = jiffies; /* prevent tx timeout */
- netif_wake_queue(net);
-}
-
-static void intr_callback(struct urb *urb)
-{
- pegasus_t *pegasus = urb->context;
- struct net_device *net;
- int res, status = urb->status;
-
- if (!pegasus)
- return;
- net = pegasus->net;
-
- switch (status) {
- case 0:
- break;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- default:
- /* some Pegasus-I products report LOTS of data
- * toggle errors... avoid log spamming
- */
- netif_dbg(pegasus, timer, net, "intr status %d\n", status);
- }
-
- if (urb->actual_length >= 6) {
- u8 *d = urb->transfer_buffer;
-
- /* byte 0 == tx_status1, reg 2B */
- if (d[0] & (TX_UNDERRUN|EXCESSIVE_COL
- |LATE_COL|JABBER_TIMEOUT)) {
- pegasus->stats.tx_errors++;
- if (d[0] & TX_UNDERRUN)
- pegasus->stats.tx_fifo_errors++;
- if (d[0] & (EXCESSIVE_COL | JABBER_TIMEOUT))
- pegasus->stats.tx_aborted_errors++;
- if (d[0] & LATE_COL)
- pegasus->stats.tx_window_errors++;
- }
-
- /* d[5].LINK_STATUS lies on some adapters.
- * d[0].NO_CARRIER kicks in only with failed TX.
- * ... so monitoring with MII may be safest.
- */
-
- /* bytes 3-4 == rx_lostpkt, reg 2E/2F */
- pegasus->stats.rx_missed_errors += ((d[3] & 0x7f) << 8) | d[4];
- }
-
- res = usb_submit_urb(urb, GFP_ATOMIC);
- if (res == -ENODEV)
- netif_device_detach(pegasus->net);
- if (res)
- netif_err(pegasus, timer, net,
- "can't resubmit interrupt urb, %d\n", res);
-}
-
-static void pegasus_tx_timeout(struct net_device *net)
-{
- pegasus_t *pegasus = netdev_priv(net);
- netif_warn(pegasus, timer, net, "tx timeout\n");
- usb_unlink_urb(pegasus->tx_urb);
- pegasus->stats.tx_errors++;
-}
-
-static netdev_tx_t pegasus_start_xmit(struct sk_buff *skb,
- struct net_device *net)
-{
- pegasus_t *pegasus = netdev_priv(net);
- int count = ((skb->len + 2) & 0x3f) ? skb->len + 2 : skb->len + 3;
- int res;
- __u16 l16 = skb->len;
-
- netif_stop_queue(net);
-
- ((__le16 *) pegasus->tx_buff)[0] = cpu_to_le16(l16);
- skb_copy_from_linear_data(skb, pegasus->tx_buff + 2, skb->len);
- usb_fill_bulk_urb(pegasus->tx_urb, pegasus->usb,
- usb_sndbulkpipe(pegasus->usb, 2),
- pegasus->tx_buff, count,
- write_bulk_callback, pegasus);
- if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) {
- netif_warn(pegasus, tx_err, net, "fail tx, %d\n", res);
- switch (res) {
- case -EPIPE: /* stall, or disconnect from TT */
- /* cleanup should already have been scheduled */
- break;
- case -ENODEV: /* disconnect() upcoming */
- case -EPERM:
- netif_device_detach(pegasus->net);
- break;
- default:
- pegasus->stats.tx_errors++;
- netif_start_queue(net);
- }
- } else {
- pegasus->stats.tx_packets++;
- pegasus->stats.tx_bytes += skb->len;
- }
- dev_kfree_skb(skb);
-
- return NETDEV_TX_OK;
-}
-
-static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev)
-{
- return &((pegasus_t *) netdev_priv(dev))->stats;
-}
-
-static inline void disable_net_traffic(pegasus_t *pegasus)
-{
- __le16 tmp = cpu_to_le16(0);
-
- set_registers(pegasus, EthCtrl0, sizeof(tmp), &tmp);
-}
-
-static inline void get_interrupt_interval(pegasus_t *pegasus)
-{
- u16 data;
- u8 interval;
-
- read_eprom_word(pegasus, 4, &data);
- interval = data >> 8;
- if (pegasus->usb->speed != USB_SPEED_HIGH) {
- if (interval < 0x80) {
- netif_info(pegasus, timer, pegasus->net,
- "intr interval changed from %ums to %ums\n",
- interval, 0x80);
- interval = 0x80;
- data = (data & 0x00FF) | ((u16)interval << 8);
-#ifdef PEGASUS_WRITE_EEPROM
- write_eprom_word(pegasus, 4, data);
-#endif
- }
- }
- pegasus->intr_interval = interval;
-}
-
-static void set_carrier(struct net_device *net)
-{
- pegasus_t *pegasus = netdev_priv(net);
- u16 tmp;
-
- if (read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp))
- return;
-
- if (tmp & BMSR_LSTATUS)
- netif_carrier_on(net);
- else
- netif_carrier_off(net);
-}
-
-static void free_all_urbs(pegasus_t *pegasus)
-{
- usb_free_urb(pegasus->intr_urb);
- usb_free_urb(pegasus->tx_urb);
- usb_free_urb(pegasus->rx_urb);
- usb_free_urb(pegasus->ctrl_urb);
-}
-
-static void unlink_all_urbs(pegasus_t *pegasus)
-{
- usb_kill_urb(pegasus->intr_urb);
- usb_kill_urb(pegasus->tx_urb);
- usb_kill_urb(pegasus->rx_urb);
- usb_kill_urb(pegasus->ctrl_urb);
-}
-
-static int alloc_urbs(pegasus_t *pegasus)
-{
- pegasus->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!pegasus->ctrl_urb)
- return 0;
- pegasus->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!pegasus->rx_urb) {
- usb_free_urb(pegasus->ctrl_urb);
- return 0;
- }
- pegasus->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!pegasus->tx_urb) {
- usb_free_urb(pegasus->rx_urb);
- usb_free_urb(pegasus->ctrl_urb);
- return 0;
- }
- pegasus->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!pegasus->intr_urb) {
- usb_free_urb(pegasus->tx_urb);
- usb_free_urb(pegasus->rx_urb);
- usb_free_urb(pegasus->ctrl_urb);
- return 0;
- }
-
- return 1;
-}
-
-static int pegasus_open(struct net_device *net)
-{
- pegasus_t *pegasus = netdev_priv(net);
- int res;
-
- if (pegasus->rx_skb == NULL)
- pegasus->rx_skb = pull_skb(pegasus);
- /*
- ** Note: no point to free the pool. it is empty :-)
- */
- if (!pegasus->rx_skb)
- return -ENOMEM;
-
- res = set_registers(pegasus, EthID, 6, net->dev_addr);
-
- usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb,
- usb_rcvbulkpipe(pegasus->usb, 1),
- pegasus->rx_skb->data, PEGASUS_MTU + 8,
- read_bulk_callback, pegasus);
- if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) {
- if (res == -ENODEV)
- netif_device_detach(pegasus->net);
- netif_dbg(pegasus, ifup, net, "failed rx_urb, %d\n", res);
- goto exit;
- }
-
- usb_fill_int_urb(pegasus->intr_urb, pegasus->usb,
- usb_rcvintpipe(pegasus->usb, 3),
- pegasus->intr_buff, sizeof(pegasus->intr_buff),
- intr_callback, pegasus, pegasus->intr_interval);
- if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) {
- if (res == -ENODEV)
- netif_device_detach(pegasus->net);
- netif_dbg(pegasus, ifup, net, "failed intr_urb, %d\n", res);
- usb_kill_urb(pegasus->rx_urb);
- goto exit;
- }
- if ((res = enable_net_traffic(net, pegasus->usb))) {
- netif_dbg(pegasus, ifup, net,
- "can't enable_net_traffic() - %d\n", res);
- res = -EIO;
- usb_kill_urb(pegasus->rx_urb);
- usb_kill_urb(pegasus->intr_urb);
- free_skb_pool(pegasus);
- goto exit;
- }
- set_carrier(net);
- netif_start_queue(net);
- netif_dbg(pegasus, ifup, net, "open\n");
- res = 0;
-exit:
- return res;
-}
-
-static int pegasus_close(struct net_device *net)
-{
- pegasus_t *pegasus = netdev_priv(net);
-
- netif_stop_queue(net);
- if (!(pegasus->flags & PEGASUS_UNPLUG))
- disable_net_traffic(pegasus);
- tasklet_kill(&pegasus->rx_tl);
- unlink_all_urbs(pegasus);
-
- return 0;
-}
-
-static void pegasus_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- pegasus_t *pegasus = netdev_priv(dev);
- strncpy(info->driver, driver_name, sizeof(info->driver) - 1);
- strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
- usb_make_path(pegasus->usb, info->bus_info, sizeof(info->bus_info));
-}
-
-/* also handles three patterns of some kind in hardware */
-#define WOL_SUPPORTED (WAKE_MAGIC|WAKE_PHY)
-
-static void
-pegasus_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
- pegasus_t *pegasus = netdev_priv(dev);
-
- wol->supported = WAKE_MAGIC | WAKE_PHY;
- wol->wolopts = pegasus->wolopts;
-}
-
-static int
-pegasus_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
- pegasus_t *pegasus = netdev_priv(dev);
- u8 reg78 = 0x04;
-
- if (wol->wolopts & ~WOL_SUPPORTED)
- return -EINVAL;
-
- if (wol->wolopts & WAKE_MAGIC)
- reg78 |= 0x80;
- if (wol->wolopts & WAKE_PHY)
- reg78 |= 0x40;
- /* FIXME this 0x10 bit still needs to get set in the chip... */
- if (wol->wolopts)
- pegasus->eth_regs[0] |= 0x10;
- else
- pegasus->eth_regs[0] &= ~0x10;
- pegasus->wolopts = wol->wolopts;
- return set_register(pegasus, WakeupControl, reg78);
-}
-
-static inline void pegasus_reset_wol(struct net_device *dev)
-{
- struct ethtool_wolinfo wol;
-
- memset(&wol, 0, sizeof wol);
- (void) pegasus_set_wol(dev, &wol);
-}
-
-static int
-pegasus_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
- pegasus_t *pegasus;
-
- pegasus = netdev_priv(dev);
- mii_ethtool_gset(&pegasus->mii, ecmd);
- return 0;
-}
-
-static int
-pegasus_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
- pegasus_t *pegasus = netdev_priv(dev);
- return mii_ethtool_sset(&pegasus->mii, ecmd);
-}
-
-static int pegasus_nway_reset(struct net_device *dev)
-{
- pegasus_t *pegasus = netdev_priv(dev);
- return mii_nway_restart(&pegasus->mii);
-}
-
-static u32 pegasus_get_link(struct net_device *dev)
-{
- pegasus_t *pegasus = netdev_priv(dev);
- return mii_link_ok(&pegasus->mii);
-}
-
-static u32 pegasus_get_msglevel(struct net_device *dev)
-{
- pegasus_t *pegasus = netdev_priv(dev);
- return pegasus->msg_enable;
-}
-
-static void pegasus_set_msglevel(struct net_device *dev, u32 v)
-{
- pegasus_t *pegasus = netdev_priv(dev);
- pegasus->msg_enable = v;
-}
-
-static const struct ethtool_ops ops = {
- .get_drvinfo = pegasus_get_drvinfo,
- .get_settings = pegasus_get_settings,
- .set_settings = pegasus_set_settings,
- .nway_reset = pegasus_nway_reset,
- .get_link = pegasus_get_link,
- .get_msglevel = pegasus_get_msglevel,
- .set_msglevel = pegasus_set_msglevel,
- .get_wol = pegasus_get_wol,
- .set_wol = pegasus_set_wol,
-};
-
-static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
-{
- __u16 *data = (__u16 *) &rq->ifr_ifru;
- pegasus_t *pegasus = netdev_priv(net);
- int res;
-
- switch (cmd) {
- case SIOCDEVPRIVATE:
- data[0] = pegasus->phy;
- case SIOCDEVPRIVATE + 1:
- read_mii_word(pegasus, data[0], data[1] & 0x1f, &data[3]);
- res = 0;
- break;
- case SIOCDEVPRIVATE + 2:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- write_mii_word(pegasus, pegasus->phy, data[1] & 0x1f, data[2]);
- res = 0;
- break;
- default:
- res = -EOPNOTSUPP;
- }
- return res;
-}
-
-static void pegasus_set_multicast(struct net_device *net)
-{
- pegasus_t *pegasus = netdev_priv(net);
-
- if (net->flags & IFF_PROMISC) {
- pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS;
- netif_info(pegasus, link, net, "Promiscuous mode enabled\n");
- } else if (!netdev_mc_empty(net) || (net->flags & IFF_ALLMULTI)) {
- pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST;
- pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
- netif_dbg(pegasus, link, net, "set allmulti\n");
- } else {
- pegasus->eth_regs[EthCtrl0] &= ~RX_MULTICAST;
- pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
- }
-
- pegasus->ctrl_urb->status = 0;
-
- pegasus->flags |= ETH_REGS_CHANGE;
- ctrl_callback(pegasus->ctrl_urb);
-}
-
-static __u8 mii_phy_probe(pegasus_t *pegasus)
-{
- int i;
- __u16 tmp;
-
- for (i = 0; i < 32; i++) {
- read_mii_word(pegasus, i, MII_BMSR, &tmp);
- if (tmp == 0 || tmp == 0xffff || (tmp & BMSR_MEDIA) == 0)
- continue;
- else
- return i;
- }
-
- return 0xff;
-}
-
-static inline void setup_pegasus_II(pegasus_t *pegasus)
-{
- __u8 data = 0xa5;
-
- set_register(pegasus, Reg1d, 0);
- set_register(pegasus, Reg7b, 1);
- mdelay(100);
- if ((pegasus->features & HAS_HOME_PNA) && mii_mode)
- set_register(pegasus, Reg7b, 0);
- else
- set_register(pegasus, Reg7b, 2);
-
- set_register(pegasus, 0x83, data);
- get_registers(pegasus, 0x83, 1, &data);
-
- if (data == 0xa5)
- pegasus->chip = 0x8513;
- else
- pegasus->chip = 0;
-
- set_register(pegasus, 0x80, 0xc0);
- set_register(pegasus, 0x83, 0xff);
- set_register(pegasus, 0x84, 0x01);
-
- if (pegasus->features & HAS_HOME_PNA && mii_mode)
- set_register(pegasus, Reg81, 6);
- else
- set_register(pegasus, Reg81, 2);
-}
-
-
-static int pegasus_count;
-static struct workqueue_struct *pegasus_workqueue;
-#define CARRIER_CHECK_DELAY (2 * HZ)
-
-static void check_carrier(struct work_struct *work)
-{
- pegasus_t *pegasus = container_of(work, pegasus_t, carrier_check.work);
- set_carrier(pegasus->net);
- if (!(pegasus->flags & PEGASUS_UNPLUG)) {
- queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check,
- CARRIER_CHECK_DELAY);
- }
-}
-
-static int pegasus_blacklisted(struct usb_device *udev)
-{
- struct usb_device_descriptor *udd = &udev->descriptor;
-
- /* Special quirk to keep the driver from handling the Belkin Bluetooth
- * dongle which happens to have the same ID.
- */
- if ((udd->idVendor == cpu_to_le16(VENDOR_BELKIN)) &&
- (udd->idProduct == cpu_to_le16(0x0121)) &&
- (udd->bDeviceClass == USB_CLASS_WIRELESS_CONTROLLER) &&
- (udd->bDeviceProtocol == 1))
- return 1;
-
- return 0;
-}
-
-/* we rely on probe() and remove() being serialized so we
- * don't need extra locking on pegasus_count.
- */
-static void pegasus_dec_workqueue(void)
-{
- pegasus_count--;
- if (pegasus_count == 0) {
- destroy_workqueue(pegasus_workqueue);
- pegasus_workqueue = NULL;
- }
-}
-
-static int pegasus_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct net_device *net;
- pegasus_t *pegasus;
- int dev_index = id - pegasus_ids;
- int res = -ENOMEM;
-
- if (pegasus_blacklisted(dev))
- return -ENODEV;
-
- if (pegasus_count == 0) {
- pegasus_workqueue = create_singlethread_workqueue("pegasus");
- if (!pegasus_workqueue)
- return -ENOMEM;
- }
- pegasus_count++;
-
- usb_get_dev(dev);
-
- net = alloc_etherdev(sizeof(struct pegasus));
- if (!net)
- goto out;
-
- pegasus = netdev_priv(net);
- pegasus->dev_index = dev_index;
- init_waitqueue_head(&pegasus->ctrl_wait);
-
- if (!alloc_urbs(pegasus)) {
- dev_err(&intf->dev, "can't allocate %s\n", "urbs");
- goto out1;
- }
-
- tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long) pegasus);
-
- INIT_DELAYED_WORK(&pegasus->carrier_check, check_carrier);
-
- pegasus->intf = intf;
- pegasus->usb = dev;
- pegasus->net = net;
-
-
- net->watchdog_timeo = PEGASUS_TX_TIMEOUT;
- net->netdev_ops = &pegasus_netdev_ops;
- SET_ETHTOOL_OPS(net, &ops);
- pegasus->mii.dev = net;
- pegasus->mii.mdio_read = mdio_read;
- pegasus->mii.mdio_write = mdio_write;
- pegasus->mii.phy_id_mask = 0x1f;
- pegasus->mii.reg_num_mask = 0x1f;
- spin_lock_init(&pegasus->rx_pool_lock);
- pegasus->msg_enable = netif_msg_init(msg_level, NETIF_MSG_DRV
- | NETIF_MSG_PROBE | NETIF_MSG_LINK);
-
- pegasus->features = usb_dev_id[dev_index].private;
- get_interrupt_interval(pegasus);
- if (reset_mac(pegasus)) {
- dev_err(&intf->dev, "can't reset MAC\n");
- res = -EIO;
- goto out2;
- }
- set_ethernet_addr(pegasus);
- fill_skb_pool(pegasus);
- if (pegasus->features & PEGASUS_II) {
- dev_info(&intf->dev, "setup Pegasus II specific registers\n");
- setup_pegasus_II(pegasus);
- }
- pegasus->phy = mii_phy_probe(pegasus);
- if (pegasus->phy == 0xff) {
- dev_warn(&intf->dev, "can't locate MII phy, using default\n");
- pegasus->phy = 1;
- }
- pegasus->mii.phy_id = pegasus->phy;
- usb_set_intfdata(intf, pegasus);
- SET_NETDEV_DEV(net, &intf->dev);
- pegasus_reset_wol(net);
- res = register_netdev(net);
- if (res)
- goto out3;
- queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check,
- CARRIER_CHECK_DELAY);
-
- dev_info(&intf->dev, "%s, %s, %pM\n",
- net->name,
- usb_dev_id[dev_index].name,
- net->dev_addr);
- return 0;
-
-out3:
- usb_set_intfdata(intf, NULL);
- free_skb_pool(pegasus);
-out2:
- free_all_urbs(pegasus);
-out1:
- free_netdev(net);
-out:
- usb_put_dev(dev);
- pegasus_dec_workqueue();
- return res;
-}
-
-static void pegasus_disconnect(struct usb_interface *intf)
-{
- struct pegasus *pegasus = usb_get_intfdata(intf);
-
- usb_set_intfdata(intf, NULL);
- if (!pegasus) {
- dev_dbg(&intf->dev, "unregistering non-bound device?\n");
- return;
- }
-
- pegasus->flags |= PEGASUS_UNPLUG;
- cancel_delayed_work(&pegasus->carrier_check);
- unregister_netdev(pegasus->net);
- usb_put_dev(interface_to_usbdev(intf));
- unlink_all_urbs(pegasus);
- free_all_urbs(pegasus);
- free_skb_pool(pegasus);
- if (pegasus->rx_skb != NULL) {
- dev_kfree_skb(pegasus->rx_skb);
- pegasus->rx_skb = NULL;
- }
- free_netdev(pegasus->net);
- pegasus_dec_workqueue();
-}
-
-static int pegasus_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct pegasus *pegasus = usb_get_intfdata(intf);
-
- netif_device_detach(pegasus->net);
- cancel_delayed_work(&pegasus->carrier_check);
- if (netif_running(pegasus->net)) {
- usb_kill_urb(pegasus->rx_urb);
- usb_kill_urb(pegasus->intr_urb);
- }
- return 0;
-}
-
-static int pegasus_resume(struct usb_interface *intf)
-{
- struct pegasus *pegasus = usb_get_intfdata(intf);
-
- netif_device_attach(pegasus->net);
- if (netif_running(pegasus->net)) {
- pegasus->rx_urb->status = 0;
- pegasus->rx_urb->actual_length = 0;
- read_bulk_callback(pegasus->rx_urb);
-
- pegasus->intr_urb->status = 0;
- pegasus->intr_urb->actual_length = 0;
- intr_callback(pegasus->intr_urb);
- }
- queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check,
- CARRIER_CHECK_DELAY);
- return 0;
-}
-
-static const struct net_device_ops pegasus_netdev_ops = {
- .ndo_open = pegasus_open,
- .ndo_stop = pegasus_close,
- .ndo_do_ioctl = pegasus_ioctl,
- .ndo_start_xmit = pegasus_start_xmit,
- .ndo_set_rx_mode = pegasus_set_multicast,
- .ndo_get_stats = pegasus_netdev_stats,
- .ndo_tx_timeout = pegasus_tx_timeout,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-static struct usb_driver pegasus_driver = {
- .name = driver_name,
- .probe = pegasus_probe,
- .disconnect = pegasus_disconnect,
- .id_table = pegasus_ids,
- .suspend = pegasus_suspend,
- .resume = pegasus_resume,
-};
-
-static void __init parse_id(char *id)
-{
- unsigned int vendor_id = 0, device_id = 0, flags = 0, i = 0;
- char *token, *name = NULL;
-
- if ((token = strsep(&id, ":")) != NULL)
- name = token;
- /* name now points to a null terminated string*/
- if ((token = strsep(&id, ":")) != NULL)
- vendor_id = simple_strtoul(token, NULL, 16);
- if ((token = strsep(&id, ":")) != NULL)
- device_id = simple_strtoul(token, NULL, 16);
- flags = simple_strtoul(id, NULL, 16);
- pr_info("%s: new device %s, vendor ID 0x%04x, device ID 0x%04x, flags: 0x%x\n",
- driver_name, name, vendor_id, device_id, flags);
-
- if (vendor_id > 0x10000 || vendor_id == 0)
- return;
- if (device_id > 0x10000 || device_id == 0)
- return;
-
- for (i = 0; usb_dev_id[i].name; i++);
- usb_dev_id[i].name = name;
- usb_dev_id[i].vendor = vendor_id;
- usb_dev_id[i].device = device_id;
- usb_dev_id[i].private = flags;
- pegasus_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
- pegasus_ids[i].idVendor = vendor_id;
- pegasus_ids[i].idProduct = device_id;
-}
-
-static int __init pegasus_init(void)
-{
- pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION);
- if (devid)
- parse_id(devid);
- return usb_register(&pegasus_driver);
-}
-
-static void __exit pegasus_exit(void)
-{
- usb_deregister(&pegasus_driver);
-}
-
-module_init(pegasus_init);
-module_exit(pegasus_exit);
diff --git a/ANDROID_3.4.5/drivers/net/usb/pegasus.h b/ANDROID_3.4.5/drivers/net/usb/pegasus.h
deleted file mode 100644
index 65b78b35..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/pegasus.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (c) 1999-2003 Petko Manolov - Petkan (petkan@users.sourceforge.net)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-
-#ifndef PEGASUS_DEV
-
-#define PEGASUS_II 0x80000000
-#define HAS_HOME_PNA 0x40000000
-
-#define PEGASUS_MTU 1536
-#define RX_SKBS 4
-
-#define EPROM_WRITE 0x01
-#define EPROM_READ 0x02
-#define EPROM_DONE 0x04
-#define EPROM_WR_ENABLE 0x10
-#define EPROM_LOAD 0x20
-
-#define PHY_DONE 0x80
-#define PHY_READ 0x40
-#define PHY_WRITE 0x20
-#define DEFAULT_GPIO_RESET 0x24
-#define DEFAULT_GPIO_SET 0x26
-
-#define PEGASUS_PRESENT 0x00000001
-#define PEGASUS_TX_BUSY 0x00000004
-#define PEGASUS_RX_BUSY 0x00000008
-#define CTRL_URB_RUNNING 0x00000010
-#define CTRL_URB_SLEEP 0x00000020
-#define PEGASUS_UNPLUG 0x00000040
-#define PEGASUS_RX_URB_FAIL 0x00000080
-#define ETH_REGS_CHANGE 0x40000000
-#define ETH_REGS_CHANGED 0x80000000
-
-#define RX_MULTICAST 2
-#define RX_PROMISCUOUS 4
-
-#define REG_TIMEOUT (HZ)
-#define PEGASUS_TX_TIMEOUT (HZ*10)
-
-#define TX_UNDERRUN 0x80
-#define EXCESSIVE_COL 0x40
-#define LATE_COL 0x20
-#define NO_CARRIER 0x10
-#define LOSS_CARRIER 0x08
-#define JABBER_TIMEOUT 0x04
-
-#define LINK_STATUS 0x01
-
-#define PEGASUS_REQT_READ 0xc0
-#define PEGASUS_REQT_WRITE 0x40
-#define PEGASUS_REQ_GET_REGS 0xf0
-#define PEGASUS_REQ_SET_REGS 0xf1
-#define PEGASUS_REQ_SET_REG PEGASUS_REQ_SET_REGS
-
-enum pegasus_registers {
- EthCtrl0 = 0,
- EthCtrl1 = 1,
- EthCtrl2 = 2,
- EthID = 0x10,
- Reg1d = 0x1d,
- EpromOffset = 0x20,
- EpromData = 0x21, /* 0x21 low, 0x22 high byte */
- EpromCtrl = 0x23,
- PhyAddr = 0x25,
- PhyData = 0x26, /* 0x26 low, 0x27 high byte */
- PhyCtrl = 0x28,
- UsbStst = 0x2a,
- EthTxStat0 = 0x2b,
- EthTxStat1 = 0x2c,
- EthRxStat = 0x2d,
- WakeupControl = 0x78,
- Reg7b = 0x7b,
- Gpio0 = 0x7e,
- Gpio1 = 0x7f,
- Reg81 = 0x81,
-};
-
-
-typedef struct pegasus {
- struct usb_device *usb;
- struct usb_interface *intf;
- struct net_device *net;
- struct net_device_stats stats;
- struct mii_if_info mii;
- unsigned flags;
- unsigned features;
- u32 msg_enable;
- u32 wolopts;
- int dev_index;
- int intr_interval;
- struct tasklet_struct rx_tl;
- struct delayed_work carrier_check;
- struct urb *ctrl_urb, *rx_urb, *tx_urb, *intr_urb;
- struct sk_buff *rx_pool[RX_SKBS];
- struct sk_buff *rx_skb;
- struct usb_ctrlrequest dr;
- wait_queue_head_t ctrl_wait;
- spinlock_t rx_pool_lock;
- int chip;
- unsigned char intr_buff[8];
- __u8 tx_buff[PEGASUS_MTU];
- __u8 eth_regs[4];
- __u8 phy;
- __u8 gpio_res;
-} pegasus_t;
-
-
-struct usb_eth_dev {
- char *name;
- __u16 vendor;
- __u16 device;
- __u32 private; /* LSB is gpio reset value */
-};
-
-#define VENDOR_3COM 0x0506
-#define VENDOR_ABOCOM 0x07b8
-#define VENDOR_ACCTON 0x083a
-#define VENDOR_ADMTEK 0x07a6
-#define VENDOR_AEILAB 0x3334
-#define VENDOR_ALLIEDTEL 0x07c9
-#define VENDOR_ATEN 0x0557
-#define VENDOR_BELKIN 0x050d
-#define VENDOR_BILLIONTON 0x08dd
-#define VENDOR_COMPAQ 0x049f
-#define VENDOR_COREGA 0x07aa
-#define VENDOR_DLINK 0x2001
-#define VENDOR_ELCON 0x0db7
-#define VENDOR_ELECOM 0x056e
-#define VENDOR_ELSA 0x05cc
-#define VENDOR_GIGABYTE 0x1044
-#define VENDOR_HAWKING 0x0e66
-#define VENDOR_HP 0x03f0
-#define VENDOR_IODATA 0x04bb
-#define VENDOR_KINGSTON 0x0951
-#define VENDOR_LANEED 0x056e
-#define VENDOR_LINKSYS 0x066b
-#define VENDOR_LINKSYS2 0x077b
-#define VENDOR_MELCO 0x0411
-#define VENDOR_MICROSOFT 0x045e
-#define VENDOR_MOBILITY 0x1342
-#define VENDOR_NETGEAR 0x0846
-#define VENDOR_OCT 0x0b39
-#define VENDOR_SMARTBRIDGES 0x08d1
-#define VENDOR_SMC 0x0707
-#define VENDOR_SOHOWARE 0x15e8
-#define VENDOR_SIEMENS 0x067c
-
-
-#else /* PEGASUS_DEV */
-
-PEGASUS_DEV("3Com USB Ethernet 3C460B", VENDOR_3COM, 0x4601,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("ATEN USB Ethernet UC-110T", VENDOR_ATEN, 0x2007,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x110c,
- DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA)
-PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4104,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA)
-PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4004,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA)
-PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4007,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA)
-PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x4102,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x4002,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400b,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("Philips USB 10/100 Ethernet", VENDOR_ACCTON, 0xb004,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("ADMtek ADM8511 \"Pegasus II\" USB Ethernet",
- VENDOR_ADMTEK, 0x8511,
- DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA)
-PEGASUS_DEV("ADMtek ADM8513 \"Pegasus II\" USB Ethernet",
- VENDOR_ADMTEK, 0x8513,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("ADMtek ADM8515 \"Pegasus II\" USB-2.0 Ethernet",
- VENDOR_ADMTEK, 0x8515,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("ADMtek AN986 \"Pegasus\" USB Ethernet (evaluation board)",
- VENDOR_ADMTEK, 0x0986,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA)
-PEGASUS_DEV("AN986A USB MAC", VENDOR_ADMTEK, 1986,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("AEI USB Fast Ethernet Adapter", VENDOR_AEILAB, 0x1701,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-/*
- * Distinguish between this Belkin adaptor and the Belkin bluetooth adaptors
- * with the same product IDs by checking the device class too.
- */
-PEGASUS_DEV_CLASS("Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("Belkin F5U122 10/100 USB Ethernet", VENDOR_BELKIN, 0x0122,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA)
-PEGASUS_DEV("iPAQ Networking 10/100 USB", VENDOR_COMPAQ, 0x8511,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("Billionton USBEL-100", VENDOR_BILLIONTON, 0x0988,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("Billionton USBE-100", VENDOR_BILLIONTON, 0x8511,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("Corega FEther USB-TX", VENDOR_COREGA, 0x0004,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("Corega FEther USB-TXS", VENDOR_COREGA, 0x000d,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x4001,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x4002,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x4102,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x400b,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x200c,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("D-Link DSB-650TX(PNA)", VENDOR_DLINK, 0x4003,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA)
-PEGASUS_DEV("D-Link DSB-650", VENDOR_DLINK, 0xabc1,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("GOLDPFEIL USB Adapter", VENDOR_ELCON, 0x0002,
- DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA)
-PEGASUS_DEV("ELECOM USB Ethernet LD-USB20", VENDOR_ELECOM, 0x4010,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("EasiDock Ethernet", VENDOR_MOBILITY, 0x0304,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("GIGABYTE GN-BR402W Wireless Router", VENDOR_GIGABYTE, 0x8002,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("HP hn210c Ethernet USB", VENDOR_HP, 0x811c,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("IO DATA USB ETX-US2", VENDOR_IODATA, 0x093a,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("LANEED USB Ethernet LD-USBL/TX", VENDOR_LANEED, 0x4005,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("LANEED USB Ethernet LD-USB/T", VENDOR_LANEED, 0xabc1,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x200c,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("Linksys USB10TX", VENDOR_LINKSYS, 0x2202,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("Linksys USB100TX", VENDOR_LINKSYS, 0x2203,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("Linksys USB100TX", VENDOR_LINKSYS, 0x2204,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA)
-PEGASUS_DEV("Linksys USB10T Ethernet Adapter", VENDOR_LINKSYS, 0x2206,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("Linksys USBVPN1", VENDOR_LINKSYS2, 0x08b4,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("Linksys USB USB100TX", VENDOR_LINKSYS, 0x400b,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("Linksys USB10TX", VENDOR_LINKSYS, 0x200c,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0001,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("MELCO/BUFFALO LUA2-TX", VENDOR_MELCO, 0x0009,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("Microsoft MN-110", VENDOR_MICROSOFT, 0x007a,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("NETGEAR FA101", VENDOR_NETGEAR, 0x1020,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("OCT Inc.", VENDOR_OCT, 0x0109,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("OCT USB TO Ethernet", VENDOR_OCT, 0x0901,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("smartNIC 2 PnP Adapter", VENDOR_SMARTBRIDGES, 0x0003,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("SMC 202 USB Ethernet", VENDOR_SMC, 0x0200,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("SMC 2206 USB Ethernet", VENDOR_SMC, 0x0201,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("SOHOware NUB100 Ethernet", VENDOR_SOHOWARE, 0x9100,
- DEFAULT_GPIO_RESET)
-PEGASUS_DEV("SOHOware NUB110 Ethernet", VENDOR_SOHOWARE, 0x9110,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV("SpeedStream USB 10/100 Ethernet", VENDOR_SIEMENS, 0x1001,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-
-
-#endif /* PEGASUS_DEV */
diff --git a/ANDROID_3.4.5/drivers/net/usb/plusb.c b/ANDROID_3.4.5/drivers/net/usb/plusb.c
deleted file mode 100644
index b2b035e2..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/plusb.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * PL-2301/2302 USB host-to-host link cables
- * Copyright (C) 2000-2005 by David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-// #define DEBUG // error path messages, extra info
-// #define VERBOSE // more; success messages
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/workqueue.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/usb/usbnet.h>
-
-
-/*
- * Prolific PL-2301/PL-2302 driver ... http://www.prolific.com.tw/
- *
- * The protocol and handshaking used here should be bug-compatible
- * with the Linux 2.2 "plusb" driver, by Deti Fliegl.
- *
- * HEADS UP: this handshaking isn't all that robust. This driver
- * gets confused easily if you unplug one end of the cable then
- * try to connect it again; you'll need to restart both ends. The
- * "naplink" software (used by some PlayStation/2 deveopers) does
- * the handshaking much better! Also, sometimes this hardware
- * seems to get wedged under load. Prolific docs are weak, and
- * don't identify differences between PL2301 and PL2302, much less
- * anything to explain the different PL2302 versions observed.
- *
- * NOTE: pl2501 has several modes, including pl2301 and pl2302
- * compatibility. Some docs suggest the difference between 2301
- * and 2302 is only to make MS-Windows use a different driver...
- *
- * pl25a1 glue based on patch from Tony Gibbs. Prolific "docs" on
- * this chip are as usual incomplete about what control messages
- * are supported.
- */
-
-/*
- * Bits 0-4 can be used for software handshaking; they're set from
- * one end, cleared from the other, "read" with the interrupt byte.
- */
-#define PL_S_EN (1<<7) /* (feature only) suspend enable */
-/* reserved bit -- rx ready (6) ? */
-#define PL_TX_READY (1<<5) /* (interrupt only) transmit ready */
-#define PL_RESET_OUT (1<<4) /* reset output pipe */
-#define PL_RESET_IN (1<<3) /* reset input pipe */
-#define PL_TX_C (1<<2) /* transmission complete */
-#define PL_TX_REQ (1<<1) /* transmission received */
-#define PL_PEER_E (1<<0) /* peer exists */
-
-static inline int
-pl_vendor_req(struct usbnet *dev, u8 req, u8 val, u8 index)
-{
- return usb_control_msg(dev->udev,
- usb_rcvctrlpipe(dev->udev, 0),
- req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- val, index,
- NULL, 0,
- USB_CTRL_GET_TIMEOUT);
-}
-
-static inline int
-pl_clear_QuickLink_features(struct usbnet *dev, int val)
-{
- return pl_vendor_req(dev, 1, (u8) val, 0);
-}
-
-static inline int
-pl_set_QuickLink_features(struct usbnet *dev, int val)
-{
- return pl_vendor_req(dev, 3, (u8) val, 0);
-}
-
-static int pl_reset(struct usbnet *dev)
-{
- int status;
-
- /* some units seem to need this reset, others reject it utterly.
- * FIXME be more like "naplink" or windows drivers.
- */
- status = pl_set_QuickLink_features(dev,
- PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E);
- if (status != 0 && netif_msg_probe(dev))
- netif_dbg(dev, link, dev->net, "pl_reset --> %d\n", status);
- return 0;
-}
-
-static const struct driver_info prolific_info = {
- .description = "Prolific PL-2301/PL-2302/PL-25A1",
- .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT,
- /* some PL-2302 versions seem to fail usb_set_interface() */
- .reset = pl_reset,
-};
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * Proilific's name won't normally be on the cables, and
- * may not be on the device.
- */
-
-static const struct usb_device_id products [] = {
-
-/* full speed cables */
-{
- USB_DEVICE(0x067b, 0x0000), // PL-2301
- .driver_info = (unsigned long) &prolific_info,
-}, {
- USB_DEVICE(0x067b, 0x0001), // PL-2302
- .driver_info = (unsigned long) &prolific_info,
-},
-
-/* high speed cables */
-{
- USB_DEVICE(0x067b, 0x25a1), /* PL-25A1, no eeprom */
- .driver_info = (unsigned long) &prolific_info,
-}, {
- USB_DEVICE(0x050d, 0x258a), /* Belkin F5U258/F5U279 (PL-25A1) */
- .driver_info = (unsigned long) &prolific_info,
-},
-
- { }, // END
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver plusb_driver = {
- .name = "plusb",
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
-};
-
-module_usb_driver(plusb_driver);
-
-MODULE_AUTHOR("David Brownell");
-MODULE_DESCRIPTION("Prolific PL-2301/2302/25A1 USB Host to Host Link Driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/qmi_wwan.c b/ANDROID_3.4.5/drivers/net/usb/qmi_wwan.c
deleted file mode 100644
index c2ae4266..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/qmi_wwan.c
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Copyright (c) 2012 Bjørn Mork <bjorn@mork.no>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/usb/cdc.h>
-#include <linux/usb/usbnet.h>
-#include <linux/usb/cdc-wdm.h>
-
-/* The name of the CDC Device Management driver */
-#define DM_DRIVER "cdc_wdm"
-
-/*
- * This driver supports wwan (3G/LTE/?) devices using a vendor
- * specific management protocol called Qualcomm MSM Interface (QMI) -
- * in addition to the more common AT commands over serial interface
- * management
- *
- * QMI is wrapped in CDC, using CDC encapsulated commands on the
- * control ("master") interface of a two-interface CDC Union
- * resembling standard CDC ECM. The devices do not use the control
- * interface for any other CDC messages. Most likely because the
- * management protocol is used in place of the standard CDC
- * notifications NOTIFY_NETWORK_CONNECTION and NOTIFY_SPEED_CHANGE
- *
- * Handling a protocol like QMI is out of the scope for any driver.
- * It can be exported as a character device using the cdc-wdm driver,
- * which will enable userspace applications ("modem managers") to
- * handle it. This may be required to use the network interface
- * provided by the driver.
- *
- * These devices may alternatively/additionally be configured using AT
- * commands on any of the serial interfaces driven by the option driver
- *
- * This driver binds only to the data ("slave") interface to enable
- * the cdc-wdm driver to bind to the control interface. It still
- * parses the CDC functional descriptors on the control interface to
- * a) verify that this is indeed a handled interface (CDC Union
- * header lists it as slave)
- * b) get MAC address and other ethernet config from the CDC Ethernet
- * header
- * c) enable user bind requests against the control interface, which
- * is the common way to bind to CDC Ethernet Control Model type
- * interfaces
- * d) provide a hint to the user about which interface is the
- * corresponding management interface
- */
-
-static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- int status = -1;
- struct usb_interface *control = NULL;
- u8 *buf = intf->cur_altsetting->extra;
- int len = intf->cur_altsetting->extralen;
- struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc;
- struct usb_cdc_union_desc *cdc_union = NULL;
- struct usb_cdc_ether_desc *cdc_ether = NULL;
- u32 required = 1 << USB_CDC_HEADER_TYPE | 1 << USB_CDC_UNION_TYPE;
- u32 found = 0;
- atomic_t *pmcount = (void *)&dev->data[1];
-
- atomic_set(pmcount, 0);
-
- /*
- * assume a data interface has no additional descriptors and
- * that the control and data interface are numbered
- * consecutively - this holds for the Huawei device at least
- */
- if (len == 0 && desc->bInterfaceNumber > 0) {
- control = usb_ifnum_to_if(dev->udev, desc->bInterfaceNumber - 1);
- if (!control)
- goto err;
-
- buf = control->cur_altsetting->extra;
- len = control->cur_altsetting->extralen;
- dev_dbg(&intf->dev, "guessing \"control\" => %s, \"data\" => this\n",
- dev_name(&control->dev));
- }
-
- while (len > 3) {
- struct usb_descriptor_header *h = (void *)buf;
-
- /* ignore any misplaced descriptors */
- if (h->bDescriptorType != USB_DT_CS_INTERFACE)
- goto next_desc;
-
- /* buf[2] is CDC descriptor subtype */
- switch (buf[2]) {
- case USB_CDC_HEADER_TYPE:
- if (found & 1 << USB_CDC_HEADER_TYPE) {
- dev_dbg(&intf->dev, "extra CDC header\n");
- goto err;
- }
- if (h->bLength != sizeof(struct usb_cdc_header_desc)) {
- dev_dbg(&intf->dev, "CDC header len %u\n", h->bLength);
- goto err;
- }
- break;
- case USB_CDC_UNION_TYPE:
- if (found & 1 << USB_CDC_UNION_TYPE) {
- dev_dbg(&intf->dev, "extra CDC union\n");
- goto err;
- }
- if (h->bLength != sizeof(struct usb_cdc_union_desc)) {
- dev_dbg(&intf->dev, "CDC union len %u\n", h->bLength);
- goto err;
- }
- cdc_union = (struct usb_cdc_union_desc *)buf;
- break;
- case USB_CDC_ETHERNET_TYPE:
- if (found & 1 << USB_CDC_ETHERNET_TYPE) {
- dev_dbg(&intf->dev, "extra CDC ether\n");
- goto err;
- }
- if (h->bLength != sizeof(struct usb_cdc_ether_desc)) {
- dev_dbg(&intf->dev, "CDC ether len %u\n", h->bLength);
- goto err;
- }
- cdc_ether = (struct usb_cdc_ether_desc *)buf;
- break;
- }
-
- /*
- * Remember which CDC functional descriptors we've seen. Works
- * for all types we care about, of which USB_CDC_ETHERNET_TYPE
- * (0x0f) is the highest numbered
- */
- if (buf[2] < 32)
- found |= 1 << buf[2];
-
-next_desc:
- len -= h->bLength;
- buf += h->bLength;
- }
-
- /* did we find all the required ones? */
- if ((found & required) != required) {
- dev_err(&intf->dev, "CDC functional descriptors missing\n");
- goto err;
- }
-
- /* give the user a helpful hint if trying to bind to the wrong interface */
- if (cdc_union && desc->bInterfaceNumber == cdc_union->bMasterInterface0) {
- dev_err(&intf->dev, "leaving \"control\" interface for " DM_DRIVER " - try binding to %s instead!\n",
- dev_name(&usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0)->dev));
- goto err;
- }
-
- /* errors aren't fatal - we can live with the dynamic address */
- if (cdc_ether) {
- dev->hard_mtu = le16_to_cpu(cdc_ether->wMaxSegmentSize);
- usbnet_get_ethernet_addr(dev, cdc_ether->iMACAddress);
- }
-
- /* success! point the user to the management interface */
- if (control)
- dev_info(&intf->dev, "Use \"" DM_DRIVER "\" for QMI interface %s\n",
- dev_name(&control->dev));
-
- /* XXX: add a sysfs symlink somewhere to help management applications find it? */
-
- /* collect bulk endpoints now that we know intf == "data" interface */
- status = usbnet_get_endpoints(dev, intf);
-
-err:
- return status;
-}
-
-/* using a counter to merge subdriver requests with our own into a combined state */
-static int qmi_wwan_manage_power(struct usbnet *dev, int on)
-{
- atomic_t *pmcount = (void *)&dev->data[1];
- int rv = 0;
-
- dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, atomic_read(pmcount), on);
-
- if ((on && atomic_add_return(1, pmcount) == 1) || (!on && atomic_dec_and_test(pmcount))) {
- /* need autopm_get/put here to ensure the usbcore sees the new value */
- rv = usb_autopm_get_interface(dev->intf);
- if (rv < 0)
- goto err;
- dev->intf->needs_remote_wakeup = on;
- usb_autopm_put_interface(dev->intf);
- }
-err:
- return rv;
-}
-
-static int qmi_wwan_cdc_wdm_manage_power(struct usb_interface *intf, int on)
-{
- struct usbnet *dev = usb_get_intfdata(intf);
-
- /* can be called while disconnecting */
- if (!dev)
- return 0;
- return qmi_wwan_manage_power(dev, on);
-}
-
-/* Some devices combine the "control" and "data" functions into a
- * single interface with all three endpoints: interrupt + bulk in and
- * out
- *
- * Setting up cdc-wdm as a subdriver owning the interrupt endpoint
- * will let it provide userspace access to the encapsulated QMI
- * protocol without interfering with the usbnet operations.
- */
-static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf)
-{
- int rv;
- struct usb_driver *subdriver = NULL;
- atomic_t *pmcount = (void *)&dev->data[1];
-
- /* ZTE makes devices where the interface descriptors and endpoint
- * configurations of two or more interfaces are identical, even
- * though the functions are completely different. If set, then
- * driver_info->data is a bitmap of acceptable interface numbers
- * allowing us to bind to one such interface without binding to
- * all of them
- */
- if (dev->driver_info->data &&
- !test_bit(intf->cur_altsetting->desc.bInterfaceNumber, &dev->driver_info->data)) {
- dev_info(&intf->dev, "not on our whitelist - ignored");
- rv = -ENODEV;
- goto err;
- }
-
- atomic_set(pmcount, 0);
-
- /* collect all three endpoints */
- rv = usbnet_get_endpoints(dev, intf);
- if (rv < 0)
- goto err;
-
- /* require interrupt endpoint for subdriver */
- if (!dev->status) {
- rv = -EINVAL;
- goto err;
- }
-
- subdriver = usb_cdc_wdm_register(intf, &dev->status->desc, 512, &qmi_wwan_cdc_wdm_manage_power);
- if (IS_ERR(subdriver)) {
- rv = PTR_ERR(subdriver);
- goto err;
- }
-
- /* can't let usbnet use the interrupt endpoint */
- dev->status = NULL;
-
- /* save subdriver struct for suspend/resume wrappers */
- dev->data[0] = (unsigned long)subdriver;
-
-err:
- return rv;
-}
-
-static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *intf)
-{
- struct usb_driver *subdriver = (void *)dev->data[0];
-
- if (subdriver && subdriver->disconnect)
- subdriver->disconnect(intf);
-
- dev->data[0] = (unsigned long)NULL;
-}
-
-/* suspend/resume wrappers calling both usbnet and the cdc-wdm
- * subdriver if present.
- *
- * NOTE: cdc-wdm also supports pre/post_reset, but we cannot provide
- * wrappers for those without adding usbnet reset support first.
- */
-static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct usbnet *dev = usb_get_intfdata(intf);
- struct usb_driver *subdriver = (void *)dev->data[0];
- int ret;
-
- ret = usbnet_suspend(intf, message);
- if (ret < 0)
- goto err;
-
- if (subdriver && subdriver->suspend)
- ret = subdriver->suspend(intf, message);
- if (ret < 0)
- usbnet_resume(intf);
-err:
- return ret;
-}
-
-static int qmi_wwan_resume(struct usb_interface *intf)
-{
- struct usbnet *dev = usb_get_intfdata(intf);
- struct usb_driver *subdriver = (void *)dev->data[0];
- int ret = 0;
-
- if (subdriver && subdriver->resume)
- ret = subdriver->resume(intf);
- if (ret < 0)
- goto err;
- ret = usbnet_resume(intf);
- if (ret < 0 && subdriver && subdriver->resume && subdriver->suspend)
- subdriver->suspend(intf, PMSG_SUSPEND);
-err:
- return ret;
-}
-
-
-static const struct driver_info qmi_wwan_info = {
- .description = "QMI speaking wwan device",
- .flags = FLAG_WWAN,
- .bind = qmi_wwan_bind,
- .manage_power = qmi_wwan_manage_power,
-};
-
-static const struct driver_info qmi_wwan_shared = {
- .description = "QMI speaking wwan device with combined interface",
- .flags = FLAG_WWAN,
- .bind = qmi_wwan_bind_shared,
- .unbind = qmi_wwan_unbind_shared,
- .manage_power = qmi_wwan_manage_power,
-};
-
-static const struct driver_info qmi_wwan_force_int0 = {
- .description = "Qualcomm WWAN/QMI device",
- .flags = FLAG_WWAN,
- .bind = qmi_wwan_bind_shared,
- .unbind = qmi_wwan_unbind_shared,
- .manage_power = qmi_wwan_manage_power,
- .data = BIT(0), /* interface whitelist bitmap */
-};
-
-static const struct driver_info qmi_wwan_force_int1 = {
- .description = "Qualcomm WWAN/QMI device",
- .flags = FLAG_WWAN,
- .bind = qmi_wwan_bind_shared,
- .unbind = qmi_wwan_unbind_shared,
- .manage_power = qmi_wwan_manage_power,
- .data = BIT(1), /* interface whitelist bitmap */
-};
-
-static const struct driver_info qmi_wwan_force_int3 = {
- .description = "Qualcomm WWAN/QMI device",
- .flags = FLAG_WWAN,
- .bind = qmi_wwan_bind_shared,
- .unbind = qmi_wwan_unbind_shared,
- .manage_power = qmi_wwan_manage_power,
- .data = BIT(3), /* interface whitelist bitmap */
-};
-
-static const struct driver_info qmi_wwan_force_int4 = {
- .description = "Qualcomm WWAN/QMI device",
- .flags = FLAG_WWAN,
- .bind = qmi_wwan_bind_shared,
- .unbind = qmi_wwan_unbind_shared,
- .manage_power = qmi_wwan_manage_power,
- .data = BIT(4), /* interface whitelist bitmap */
-};
-
-/* Sierra Wireless provide equally useless interface descriptors
- * Devices in QMI mode can be switched between two different
- * configurations:
- * a) USB interface #8 is QMI/wwan
- * b) USB interfaces #8, #19 and #20 are QMI/wwan
- *
- * Both configurations provide a number of other interfaces (serial++),
- * some of which have the same endpoint configuration as we expect, so
- * a whitelist or blacklist is necessary.
- *
- * FIXME: The below whitelist should include BIT(20). It does not
- * because I cannot get it to work...
- */
-static const struct driver_info qmi_wwan_sierra = {
- .description = "Sierra Wireless wwan/QMI device",
- .flags = FLAG_WWAN,
- .bind = qmi_wwan_bind_shared,
- .unbind = qmi_wwan_unbind_shared,
- .manage_power = qmi_wwan_manage_power,
- .data = BIT(8) | BIT(19), /* interface whitelist bitmap */
-};
-
-#define HUAWEI_VENDOR_ID 0x12D1
-
-/* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */
-#define QMI_GOBI1K_DEVICE(vend, prod) \
- USB_DEVICE(vend, prod), \
- .driver_info = (unsigned long)&qmi_wwan_force_int3
-
-/* Gobi 2000 and Gobi 3000 QMI/wwan interface number is 0 according to qcserial */
-#define QMI_GOBI_DEVICE(vend, prod) \
- USB_DEVICE(vend, prod), \
- .driver_info = (unsigned long)&qmi_wwan_force_int0
-
-static const struct usb_device_id products[] = {
- { /* Huawei E392, E398 and possibly others sharing both device id and more... */
- .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = HUAWEI_VENDOR_ID,
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 8, /* NOTE: This is the *slave* interface of the CDC Union! */
- .driver_info = (unsigned long)&qmi_wwan_info,
- },
- { /* Huawei E392, E398 and possibly others in "Windows mode"
- * using a combined control and data interface without any CDC
- * functional descriptors
- */
- .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = HUAWEI_VENDOR_ID,
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 17,
- .driver_info = (unsigned long)&qmi_wwan_shared,
- },
- { /* Pantech UML290 */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x106c,
- .idProduct = 0x3718,
- .bInterfaceClass = 0xff,
- .bInterfaceSubClass = 0xf0,
- .bInterfaceProtocol = 0xff,
- .driver_info = (unsigned long)&qmi_wwan_shared,
- },
- { /* ZTE MF820D */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x19d2,
- .idProduct = 0x0167,
- .bInterfaceClass = 0xff,
- .bInterfaceSubClass = 0xff,
- .bInterfaceProtocol = 0xff,
- .driver_info = (unsigned long)&qmi_wwan_force_int4,
- },
- { /* ZTE (Vodafone) K3520-Z */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x19d2,
- .idProduct = 0x0055,
- .bInterfaceClass = 0xff,
- .bInterfaceSubClass = 0xff,
- .bInterfaceProtocol = 0xff,
- .driver_info = (unsigned long)&qmi_wwan_force_int1,
- },
- { /* ZTE (Vodafone) K3565-Z */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x19d2,
- .idProduct = 0x0063,
- .bInterfaceClass = 0xff,
- .bInterfaceSubClass = 0xff,
- .bInterfaceProtocol = 0xff,
- .driver_info = (unsigned long)&qmi_wwan_force_int4,
- },
- { /* ZTE (Vodafone) K3570-Z */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x19d2,
- .idProduct = 0x1008,
- .bInterfaceClass = 0xff,
- .bInterfaceSubClass = 0xff,
- .bInterfaceProtocol = 0xff,
- .driver_info = (unsigned long)&qmi_wwan_force_int4,
- },
- { /* ZTE (Vodafone) K3571-Z */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x19d2,
- .idProduct = 0x1010,
- .bInterfaceClass = 0xff,
- .bInterfaceSubClass = 0xff,
- .bInterfaceProtocol = 0xff,
- .driver_info = (unsigned long)&qmi_wwan_force_int4,
- },
- { /* ZTE (Vodafone) K4505-Z */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x19d2,
- .idProduct = 0x0104,
- .bInterfaceClass = 0xff,
- .bInterfaceSubClass = 0xff,
- .bInterfaceProtocol = 0xff,
- .driver_info = (unsigned long)&qmi_wwan_force_int4,
- },
- { /* Sierra Wireless MC77xx in QMI mode */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x1199,
- .idProduct = 0x68a2,
- .bInterfaceClass = 0xff,
- .bInterfaceSubClass = 0xff,
- .bInterfaceProtocol = 0xff,
- .driver_info = (unsigned long)&qmi_wwan_sierra,
- },
-
- /* Gobi 1000 devices */
- {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
- {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */
- {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */
- {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */
- {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */
- {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */
- {QMI_GOBI1K_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */
- {QMI_GOBI1K_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */
- {QMI_GOBI1K_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */
- {QMI_GOBI1K_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */
- {QMI_GOBI1K_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */
- {QMI_GOBI1K_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */
- {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */
- {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */
-
- /* Gobi 2000 and 3000 devices */
- {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */
- {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */
- {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */
- {QMI_GOBI_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */
- {QMI_GOBI_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */
- {QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */
- {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(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
- {QMI_GOBI_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
- {QMI_GOBI_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
- {QMI_GOBI_DEVICE(0x1199, 0x9004)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
- {QMI_GOBI_DEVICE(0x1199, 0x9005)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
- {QMI_GOBI_DEVICE(0x1199, 0x9006)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
- {QMI_GOBI_DEVICE(0x1199, 0x9007)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
- {QMI_GOBI_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
- {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_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) */
- { } /* END */
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver qmi_wwan_driver = {
- .name = "qmi_wwan",
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = qmi_wwan_suspend,
- .resume = qmi_wwan_resume,
- .reset_resume = qmi_wwan_resume,
- .supports_autosuspend = 1,
-};
-
-static int __init qmi_wwan_init(void)
-{
- return usb_register(&qmi_wwan_driver);
-}
-module_init(qmi_wwan_init);
-
-static void __exit qmi_wwan_exit(void)
-{
- usb_deregister(&qmi_wwan_driver);
-}
-module_exit(qmi_wwan_exit);
-
-MODULE_AUTHOR("Bjørn Mork <bjorn@mork.no>");
-MODULE_DESCRIPTION("Qualcomm MSM Interface (QMI) WWAN driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/r8152.c b/ANDROID_3.4.5/drivers/net/usb/r8152.c
deleted file mode 100755
index a1021d0c..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/r8152.c
+++ /dev/null
@@ -1,5481 +0,0 @@
-/*
- * Copyright (c) 2014 Realtek Semiconductor Corp. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This product is covered by one or more of the following patents:
- * US6,570,884, US6,115,776, and US6,327,625.
- */
-
-#include <linux/signal.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/mii.h>
-#include <linux/ethtool.h>
-#include <linux/usb.h>
-#include <linux/crc32.h>
-#include <linux/if_vlan.h>
-#include <linux/uaccess.h>
-#include <linux/list.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <net/ip6_checksum.h>
-#include "compatibility.h"
-
-/* Version Information */
-#define DRIVER_VERSION "v2.02.0 (2014/08/21)"
-#define DRIVER_AUTHOR "Realtek nic sw <nic_swsd@realtek.com>"
-#define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters"
-#define MODULENAME "r8152"
-
-#define PATENTS "This product is covered by one or more of the " \
- "following patents:\n" \
- "\t\tUS6,570,884, US6,115,776, and US6,327,625.\n"
-
-#define R8152_PHY_ID 32
-
-#define PLA_IDR 0xc000
-#define PLA_RCR 0xc010
-#define PLA_RMS 0xc016
-#define PLA_RXFIFO_CTRL0 0xc0a0
-#define PLA_RXFIFO_CTRL1 0xc0a4
-#define PLA_RXFIFO_CTRL2 0xc0a8
-#define PLA_FMC 0xc0b4
-#define PLA_CFG_WOL 0xc0b6
-#define PLA_TEREDO_CFG 0xc0bc
-#define PLA_MAR 0xcd00
-#define PLA_BACKUP 0xd000
-#define PAL_BDC_CR 0xd1a0
-#define PLA_TEREDO_TIMER 0xd2cc
-#define PLA_REALWOW_TIMER 0xd2e8
-#define PLA_LEDSEL 0xdd90
-#define PLA_LED_FEATURE 0xdd92
-#define PLA_PHYAR 0xde00
-#define PLA_BOOT_CTRL 0xe004
-#define PLA_GPHY_INTR_IMR 0xe022
-#define PLA_EEE_CR 0xe040
-#define PLA_EEEP_CR 0xe080
-#define PLA_MAC_PWR_CTRL 0xe0c0
-#define PLA_MAC_PWR_CTRL2 0xe0ca
-#define PLA_MAC_PWR_CTRL3 0xe0cc
-#define PLA_MAC_PWR_CTRL4 0xe0ce
-#define PLA_WDT6_CTRL 0xe428
-#define PLA_TCR0 0xe610
-#define PLA_TCR1 0xe612
-#define PLA_MTPS 0xe615
-#define PLA_TXFIFO_CTRL 0xe618
-#define PLA_RSTTALLY 0xe800
-#define PLA_CR 0xe813
-#define PLA_CRWECR 0xe81c
-#define PLA_CONFIG12 0xe81e /* CONFIG1, CONFIG2 */
-#define PLA_CONFIG34 0xe820 /* CONFIG3, CONFIG4 */
-#define PLA_CONFIG5 0xe822
-#define PLA_PHY_PWR 0xe84c
-#define PLA_OOB_CTRL 0xe84f
-#define PLA_CPCR 0xe854
-#define PLA_MISC_0 0xe858
-#define PLA_MISC_1 0xe85a
-#define PLA_OCP_GPHY_BASE 0xe86c
-#define PLA_TALLYCNT 0xe890
-#define PLA_SFF_STS_7 0xe8de
-#define PLA_PHYSTATUS 0xe908
-#define PLA_BP_BA 0xfc26
-#define PLA_BP_0 0xfc28
-#define PLA_BP_1 0xfc2a
-#define PLA_BP_2 0xfc2c
-#define PLA_BP_3 0xfc2e
-#define PLA_BP_4 0xfc30
-#define PLA_BP_5 0xfc32
-#define PLA_BP_6 0xfc34
-#define PLA_BP_7 0xfc36
-#define PLA_BP_EN 0xfc38
-
-#define USB_U2P3_CTRL 0xb460
-#define USB_DEV_STAT 0xb808
-#define USB_USB_CTRL 0xd406
-#define USB_PHY_CTRL 0xd408
-#define USB_TX_AGG 0xd40a
-#define USB_RX_BUF_TH 0xd40c
-#define USB_USB_TIMER 0xd428
-#define USB_RX_EARLY_AGG 0xd42c
-#define USB_PM_CTRL_STATUS 0xd432
-#define USB_TX_DMA 0xd434
-#define USB_TOLERANCE 0xd490
-#define USB_LPM_CTRL 0xd41a
-#define USB_UPS_CTRL 0xd800
-#define USB_MISC_0 0xd81a
-#define USB_POWER_CUT 0xd80a
-#define USB_AFE_CTRL2 0xd824
-#define USB_WDT11_CTRL 0xe43c
-#define USB_BP_BA 0xfc26
-#define USB_BP_0 0xfc28
-#define USB_BP_1 0xfc2a
-#define USB_BP_2 0xfc2c
-#define USB_BP_3 0xfc2e
-#define USB_BP_4 0xfc30
-#define USB_BP_5 0xfc32
-#define USB_BP_6 0xfc34
-#define USB_BP_7 0xfc36
-#define USB_BP_EN 0xfc38
-
-/* OCP Registers */
-#define OCP_ALDPS_CONFIG 0x2010
-#define OCP_EEE_CONFIG1 0x2080
-#define OCP_EEE_CONFIG2 0x2092
-#define OCP_EEE_CONFIG3 0x2094
-#define OCP_BASE_MII 0xa400
-#define OCP_EEE_AR 0xa41a
-#define OCP_EEE_DATA 0xa41c
-#define OCP_PHY_STATUS 0xa420
-#define OCP_POWER_CFG 0xa430
-#define OCP_EEE_CFG 0xa432
-#define OCP_SRAM_ADDR 0xa436
-#define OCP_SRAM_DATA 0xa438
-#define OCP_DOWN_SPEED 0xa442
-#define OCP_EEE_CFG2 0xa5d0
-#define OCP_ADC_CFG 0xbc06
-
-/* SRAM Register */
-#define SRAM_LPF_CFG 0x8012
-#define SRAM_10M_AMP1 0x8080
-#define SRAM_10M_AMP2 0x8082
-#define SRAM_IMPEDANCE 0x8084
-
-/* PLA_RCR */
-#define RCR_AAP 0x00000001
-#define RCR_APM 0x00000002
-#define RCR_AM 0x00000004
-#define RCR_AB 0x00000008
-#define RCR_ACPT_ALL (RCR_AAP | RCR_APM | RCR_AM | RCR_AB)
-
-/* PLA_RXFIFO_CTRL0 */
-#define RXFIFO_THR1_NORMAL 0x00080002
-#define RXFIFO_THR1_OOB 0x01800003
-
-/* PLA_RXFIFO_CTRL1 */
-#define RXFIFO_THR2_FULL 0x00000060
-#define RXFIFO_THR2_HIGH 0x00000038
-#define RXFIFO_THR2_OOB 0x0000004a
-#define RXFIFO_THR2_NORMAL 0x00a0
-
-/* PLA_RXFIFO_CTRL2 */
-#define RXFIFO_THR3_FULL 0x00000078
-#define RXFIFO_THR3_HIGH 0x00000048
-#define RXFIFO_THR3_OOB 0x0000005a
-#define RXFIFO_THR3_NORMAL 0x0110
-
-/* PLA_TXFIFO_CTRL */
-#define TXFIFO_THR_NORMAL 0x00400008
-#define TXFIFO_THR_NORMAL2 0x01000008
-
-/* PLA_FMC */
-#define FMC_FCR_MCU_EN 0x0001
-
-/* PLA_EEEP_CR */
-#define EEEP_CR_EEEP_TX 0x0002
-
-/* PLA_WDT6_CTRL */
-#define WDT6_SET_MODE 0x0010
-
-/* PLA_TCR0 */
-#define TCR0_TX_EMPTY 0x0800
-#define TCR0_AUTO_FIFO 0x0080
-
-/* PLA_TCR1 */
-#define VERSION_MASK 0x7cf0
-
-/* PLA_MTPS */
-#define MTPS_JUMBO (12 * 1024 / 64)
-#define MTPS_DEFAULT (6 * 1024 / 64)
-
-/* PLA_RSTTALLY */
-#define TALLY_RESET 0x0001
-
-/* PLA_CR */
-#define CR_RST 0x10
-#define CR_RE 0x08
-#define CR_TE 0x04
-
-/* PLA_CRWECR */
-#define CRWECR_NORAML 0x00
-#define CRWECR_CONFIG 0xc0
-
-/* PLA_OOB_CTRL */
-#define NOW_IS_OOB 0x80
-#define TXFIFO_EMPTY 0x20
-#define RXFIFO_EMPTY 0x10
-#define LINK_LIST_READY 0x02
-#define DIS_MCU_CLROOB 0x01
-#define FIFO_EMPTY (TXFIFO_EMPTY | RXFIFO_EMPTY)
-
-/* PLA_MISC_1 */
-#define RXDY_GATED_EN 0x0008
-
-/* PLA_SFF_STS_7 */
-#define RE_INIT_LL 0x8000
-#define MCU_BORW_EN 0x4000
-
-/* PLA_CPCR */
-#define CPCR_RX_VLAN 0x0040
-
-/* PLA_CFG_WOL */
-#define MAGIC_EN 0x0001
-
-/* PLA_TEREDO_CFG */
-#define TEREDO_SEL 0x8000
-#define TEREDO_WAKE_MASK 0x7f00
-#define TEREDO_RS_EVENT_MASK 0x00fe
-#define OOB_TEREDO_EN 0x0001
-
-/* PAL_BDC_CR */
-#define ALDPS_PROXY_MODE 0x0001
-
-/* PLA_CONFIG34 */
-#define LINK_ON_WAKE_EN 0x0010
-#define LINK_OFF_WAKE_EN 0x0008
-
-/* PLA_CONFIG5 */
-#define BWF_EN 0x0040
-#define MWF_EN 0x0020
-#define UWF_EN 0x0010
-#define LAN_WAKE_EN 0x0002
-
-/* PLA_LED_FEATURE */
-#define LED_MODE_MASK 0x0700
-
-/* PLA_PHY_PWR */
-#define TX_10M_IDLE_EN 0x0080
-#define PFM_PWM_SWITCH 0x0040
-
-/* PLA_MAC_PWR_CTRL */
-#define D3_CLK_GATED_EN 0x00004000
-#define MCU_CLK_RATIO 0x07010f07
-#define MCU_CLK_RATIO_MASK 0x0f0f0f0f
-#define ALDPS_SPDWN_RATIO 0x0f87
-
-/* PLA_MAC_PWR_CTRL2 */
-#define EEE_SPDWN_RATIO 0x8007
-
-/* PLA_MAC_PWR_CTRL3 */
-#define PKT_AVAIL_SPDWN_EN 0x0100
-#define SUSPEND_SPDWN_EN 0x0004
-#define U1U2_SPDWN_EN 0x0002
-#define L1_SPDWN_EN 0x0001
-
-/* PLA_MAC_PWR_CTRL4 */
-#define PWRSAVE_SPDWN_EN 0x1000
-#define RXDV_SPDWN_EN 0x0800
-#define TX10MIDLE_EN 0x0100
-#define TP100_SPDWN_EN 0x0020
-#define TP500_SPDWN_EN 0x0010
-#define TP1000_SPDWN_EN 0x0008
-#define EEE_SPDWN_EN 0x0001
-
-/* PLA_GPHY_INTR_IMR */
-#define GPHY_STS_MSK 0x0001
-#define SPEED_DOWN_MSK 0x0002
-#define SPDWN_RXDV_MSK 0x0004
-#define SPDWN_LINKCHG_MSK 0x0008
-
-/* PLA_PHYAR */
-#define PHYAR_FLAG 0x80000000
-
-/* PLA_EEE_CR */
-#define EEE_RX_EN 0x0001
-#define EEE_TX_EN 0x0002
-
-/* PLA_BOOT_CTRL */
-#define AUTOLOAD_DONE 0x0002
-
-/* USB_DEV_STAT */
-#define STAT_SPEED_MASK 0x0006
-#define STAT_SPEED_HIGH 0x0000
-#define STAT_SPEED_FULL 0x0002
-
-/* USB_TX_AGG */
-#define TX_AGG_MAX_THRESHOLD 0x03
-
-/* USB_RX_BUF_TH */
-#define RX_THR_SUPPER 0x0c350180
-#define RX_THR_HIGH 0x7a120180
-#define RX_THR_SLOW 0xffff0180
-
-/* USB_TX_DMA */
-#define TEST_MODE_DISABLE 0x00000001
-#define TX_SIZE_ADJUST1 0x00000100
-
-/* USB_UPS_CTRL */
-#define POWER_CUT 0x0100
-
-/* USB_PM_CTRL_STATUS */
-#define RESUME_INDICATE 0x0001
-
-/* USB_USB_CTRL */
-#define RX_AGG_DISABLE 0x0010
-
-/* USB_U2P3_CTRL */
-#define U2P3_ENABLE 0x0001
-
-/* USB_POWER_CUT */
-#define PWR_EN 0x0001
-#define PHASE2_EN 0x0008
-
-/* USB_MISC_0 */
-#define PCUT_STATUS 0x0001
-
-/* USB_RX_EARLY_AGG */
-#if defined(__i386__) || defined(__x86_64__)
- #define EARLY_AGG_SUPER 0x0e832981
-#else
- #define EARLY_AGG_SUPER 0x0e835000
-#endif
-#define EARLY_AGG_HIGH 0x0e837a12
-#define EARLY_AGG_SLOW 0x0e83ffff
-
-/* USB_WDT11_CTRL */
-#define TIMER11_EN 0x0001
-
-/* USB_LPM_CTRL */
-#define LPM_TIMER_MASK 0x0c
-#define LPM_TIMER_500MS 0x04 /* 500 ms */
-#define LPM_TIMER_500US 0x0c /* 500 us */
-
-/* USB_AFE_CTRL2 */
-#define SEN_VAL_MASK 0xf800
-#define SEN_VAL_NORMAL 0xa000
-#define SEL_RXIDLE 0x0100
-
-/* OCP_ALDPS_CONFIG */
-#define ENPWRSAVE 0x8000
-#define ENPDNPS 0x0200
-#define LINKENA 0x0100
-#define DIS_SDSAVE 0x0010
-
-/* OCP_PHY_STATUS */
-#define PHY_STAT_MASK 0x0007
-#define PHY_STAT_LAN_ON 3
-#define PHY_STAT_PWRDN 5
-
-/* OCP_POWER_CFG */
-#define EEE_CLKDIV_EN 0x8000
-#define EN_ALDPS 0x0004
-#define EN_10M_PLLOFF 0x0001
-
-/* OCP_EEE_CONFIG1 */
-#define RG_TXLPI_MSK_HFDUP 0x8000
-#define RG_MATCLR_EN 0x4000
-#define EEE_10_CAP 0x2000
-#define EEE_NWAY_EN 0x1000
-#define TX_QUIET_EN 0x0200
-#define RX_QUIET_EN 0x0100
-#define SDRISETIME 0x0010 /* bit 4 ~ 6 */
-#define RG_RXLPI_MSK_HFDUP 0x0008
-#define SDFALLTIME 0x0007 /* bit 0 ~ 2 */
-
-/* OCP_EEE_CONFIG2 */
-#define RG_LPIHYS_NUM 0x7000 /* bit 12 ~ 15 */
-#define RG_DACQUIET_EN 0x0400
-#define RG_LDVQUIET_EN 0x0200
-#define RG_CKRSEL 0x0020
-#define RG_EEEPRG_EN 0x0010
-
-/* OCP_EEE_CONFIG3 */
-#define FST_SNR_EYE_R 0x1500 /* bit 7 ~ 15 */
-#define RG_LFS_SEL 0x0060 /* bit 6 ~ 5 */
-#define MSK_PH 0x0006 /* bit 0 ~ 3 */
-
-/* OCP_EEE_AR */
-/* bit[15:14] function */
-#define FUN_ADDR 0x0000
-#define FUN_DATA 0x4000
-/* bit[4:0] device addr */
-#define DEVICE_ADDR 0x0007
-
-/* OCP_EEE_DATA */
-#define EEE_ADDR 0x003C
-#define EEE_DATA 0x0002
-
-/* OCP_EEE_CFG */
-#define CTAP_SHORT_EN 0x0040
-#define EEE10_EN 0x0010
-
-/* OCP_DOWN_SPEED */
-#define EN_10M_BGOFF 0x0080
-
-/* OCP_EEE_CFG2 */
-#define MY1000_EEE 0x0004
-#define MY100_EEE 0x0002
-
-/* OCP_ADC_CFG */
-#define CKADSEL_L 0x0100
-#define ADC_EN 0x0080
-#define EN_EMI_L 0x0040
-
-/* SRAM_LPF_CFG */
-#define LPF_AUTO_TUNE 0x8000
-
-/* SRAM_10M_AMP1 */
-#define GDAC_IB_UPALL 0x0008
-
-/* SRAM_10M_AMP2 */
-#define AMP_DN 0x0200
-
-/* SRAM_IMPEDANCE */
-#define RX_DRIVING_MASK 0x6000
-
-enum rtl_register_content {
- _1000bps = 0x10,
- _100bps = 0x08,
- _10bps = 0x04,
- LINK_STATUS = 0x02,
- FULL_DUP = 0x01,
-};
-
-#define RTL8152_MAX_TX 4
-#define RTL8152_MAX_RX 10
-#define INTBUFSIZE 2
-#define CRC_SIZE 4
-#define TX_ALIGN 4
-#define RX_ALIGN 8
-
-#define INTR_LINK 0x0004
-
-#define RTL8152_REQT_READ 0xc0
-#define RTL8152_REQT_WRITE 0x40
-#define RTL8152_REQ_GET_REGS 0x05
-#define RTL8152_REQ_SET_REGS 0x05
-
-#define BYTE_EN_DWORD 0xff
-#define BYTE_EN_WORD 0x33
-#define BYTE_EN_BYTE 0x11
-#define BYTE_EN_SIX_BYTES 0x3f
-#define BYTE_EN_START_MASK 0x0f
-#define BYTE_EN_END_MASK 0xf0
-
-#define RTL8153_MAX_PACKET 9216 /* 9K */
-#define RTL8153_MAX_MTU (RTL8153_MAX_PACKET - VLAN_ETH_HLEN - VLAN_HLEN)
-#define RTL8152_RMS (VLAN_ETH_FRAME_LEN + VLAN_HLEN)
-#define RTL8153_RMS RTL8153_MAX_PACKET
-#define RTL8152_TX_TIMEOUT (5 * HZ)
-
-/* rtl8152 flags */
-enum rtl8152_flags {
- RTL8152_UNPLUG = 0,
- RTL8152_SET_RX_MODE,
- WORK_ENABLE,
- RTL8152_LINK_CHG,
- SELECTIVE_SUSPEND,
- PHY_RESET,
- SCHEDULE_TASKLET,
-};
-
-/* Define these values to match your device */
-#define VENDOR_ID_REALTEK 0x0bda
-#define PRODUCT_ID_RTL8152 0x8152
-#define PRODUCT_ID_RTL8153 0x8153
-
-#define VENDOR_ID_SAMSUNG 0x04e8
-#define PRODUCT_ID_SAMSUNG 0xa101
-
-#define VENDOR_ID_LENOVO 0x17ef
-
-#define MCU_TYPE_PLA 0x0100
-#define MCU_TYPE_USB 0x0000
-
-struct tally_counter {
- __le64 tx_packets;
- __le64 rx_packets;
- __le64 tx_errors;
- __le32 rx_errors;
- __le16 rx_missed;
- __le16 align_errors;
- __le32 tx_one_collision;
- __le32 tx_multi_collision;
- __le64 rx_unicast;
- __le64 rx_broadcast;
- __le32 rx_multicast;
- __le16 tx_aborted;
- __le16 tx_underun;
-};
-
-struct rx_desc {
- __le32 opts1;
-#define RD_CRC (1 << 15)
-#define RX_LEN_MASK 0x7fff
-
- __le32 opts2;
-#define RD_UDP_CS (1 << 23)
-#define RD_TCP_CS (1 << 22)
-#define RD_IPV6_CS (1 << 20)
-#define RD_IPV4_CS (1 << 19)
-
- __le32 opts3;
-#define IPF (1 << 23) /* IP checksum fail */
-#define UDPF (1 << 22) /* UDP checksum fail */
-#define TCPF (1 << 21) /* TCP checksum fail */
-
- __le32 opts4;
- __le32 opts5;
- __le32 opts6;
-};
-
-struct tx_desc {
- __le32 opts1;
-#define TX_FS (1 << 31) /* First segment of a packet */
-#define TX_LS (1 << 30) /* Final segment of a packet */
-#define LGSEND (1 << 29)
-#define GTSENDV4 (1 << 28)
-#define GTSENDV6 (1 << 27)
-#define GTTCPHO_SHIFT 18
-#define GTTCPHO_MAX 0x7fU
-#define TX_LEN_MAX 0x3ffffU
-
- __le32 opts2;
-#define UDP_CS (1 << 31) /* Calculate UDP/IP checksum */
-#define TCP_CS (1 << 30) /* Calculate TCP/IP checksum */
-#define IPV4_CS (1 << 29) /* Calculate IPv4 checksum */
-#define IPV6_CS (1 << 28) /* Calculate IPv6 checksum */
-#define MSS_SHIFT 17
-#define MSS_MAX 0x7ffU
-#define TCPHO_SHIFT 17
-#define TCPHO_MAX 0x7ffU
-};
-
-struct r8152;
-
-struct rx_agg {
- struct list_head list;
- struct urb *urb;
- struct r8152 *context;
- void *buffer;
- void *head;
-};
-
-struct tx_agg {
- struct list_head list;
- struct urb *urb;
- struct r8152 *context;
- void *buffer;
- void *head;
- u32 skb_num;
- u32 skb_len;
-};
-
-struct r8152 {
- unsigned long flags;
- struct usb_device *udev;
- struct tasklet_struct tl;
- struct usb_interface *intf;
- struct net_device *netdev;
- struct urb *intr_urb;
- struct tx_agg tx_info[RTL8152_MAX_TX];
- struct rx_agg rx_info[RTL8152_MAX_RX];
- struct list_head rx_done, tx_free;
- struct sk_buff_head tx_queue;
- spinlock_t rx_lock, tx_lock;
- struct delayed_work schedule;
- struct mii_if_info mii;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
- struct net_device_stats stats;
-#endif
-
- struct rtl_ops {
- void (*init)(struct r8152 *);
- int (*enable)(struct r8152 *);
- void (*disable)(struct r8152 *);
- void (*up)(struct r8152 *);
- void (*down)(struct r8152 *);
- void (*unload)(struct r8152 *);
- } rtl_ops;
-
- int intr_interval;
- u32 saved_wolopts;
- u32 msg_enable;
- u32 tx_qlen;
- u16 ocp_base;
- u8 *intr_buff;
- u8 version;
- u8 speed;
- u8 rtk_enable_diag;
-};
-
-enum rtl_version {
- RTL_VER_UNKNOWN = 0,
- RTL_VER_01,
- RTL_VER_02,
- RTL_VER_03,
- RTL_VER_04,
- RTL_VER_05,
- RTL_VER_MAX
-};
-
-enum tx_csum_stat {
- TX_CSUM_SUCCESS = 0,
- TX_CSUM_TSO,
- TX_CSUM_NONE
-};
-
-/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
- * The RTL chips use a 64 element hash table based on the Ethernet CRC.
- */
-static const int multicast_filter_limit = 32;
-static unsigned int rx_buf_sz = 16384;
-
-#define RTL_LIMITED_TSO_SIZE (rx_buf_sz - sizeof(struct tx_desc) - \
- VLAN_ETH_HLEN - VLAN_HLEN)
-
-static
-int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
-{
- 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, 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)
-{
- int ret;
- void *tmp;
-
- tmp = kmemdup(data, size, GFP_KERNEL);
- if (!tmp)
- return -ENOMEM;
-
- ret = usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0),
- RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE,
- value, index, tmp, size, 500);
-
- kfree(tmp);
-
- return ret;
-}
-
-static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size,
- void *data, u16 type)
-{
- u16 limit = 64;
- int ret = 0;
-
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return -ENODEV;
-
- /* both size and indix must be 4 bytes align */
- if ((size & 3) || !size || (index & 3) || !data)
- return -EPERM;
-
- if ((u32)index + (u32)size > 0xffff)
- return -EPERM;
-
- while (size) {
- if (size > limit) {
- ret = get_registers(tp, index, type, limit, data);
- if (ret < 0)
- break;
-
- index += limit;
- data += limit;
- size -= limit;
- } else {
- ret = get_registers(tp, index, type, size, data);
- if (ret < 0)
- break;
-
- index += size;
- data += size;
- size = 0;
- break;
- }
- }
-
- return ret;
-}
-
-static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen,
- u16 size, void *data, u16 type)
-{
- int ret;
- u16 byteen_start, byteen_end, byen;
- u16 limit = 512;
-
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return -ENODEV;
-
- /* both size and indix must be 4 bytes align */
- if ((size & 3) || !size || (index & 3) || !data)
- return -EPERM;
-
- if ((u32)index + (u32)size > 0xffff)
- return -EPERM;
-
- byteen_start = byteen & BYTE_EN_START_MASK;
- byteen_end = byteen & BYTE_EN_END_MASK;
-
- byen = byteen_start | (byteen_start << 4);
- ret = set_registers(tp, index, type | byen, 4, data);
- if (ret < 0)
- goto error1;
-
- index += 4;
- data += 4;
- size -= 4;
-
- if (size) {
- size -= 4;
-
- while (size) {
- if (size > limit) {
- ret = set_registers(tp, index,
- type | BYTE_EN_DWORD,
- limit, data);
- if (ret < 0)
- goto error1;
-
- index += limit;
- data += limit;
- size -= limit;
- } else {
- ret = set_registers(tp, index,
- type | BYTE_EN_DWORD,
- size, data);
- if (ret < 0)
- goto error1;
-
- index += size;
- data += size;
- size = 0;
- break;
- }
- }
-
- byen = byteen_end | (byteen_end >> 4);
- ret = set_registers(tp, index, type | byen, 4, data);
- if (ret < 0)
- goto error1;
- }
-
-error1:
- return ret;
-}
-
-static inline
-int pla_ocp_read(struct r8152 *tp, u16 index, u16 size, void *data)
-{
- return generic_ocp_read(tp, index, size, data, MCU_TYPE_PLA);
-}
-
-static inline int pla_ocp_real_write(struct r8152 *tp, u16 index,
- u16 byteen, u16 size, void *data)
-{
- return generic_ocp_write(tp, index, byteen, size, data, MCU_TYPE_PLA);
-}
-
-static
-int pla_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data)
-{
- if (tp->rtk_enable_diag == 1)
- return 0;
-
- return pla_ocp_real_write(tp, index, byteen, size, data);
-}
-
-static inline
-int usb_ocp_read(struct r8152 *tp, u16 index, u16 size, void *data)
-{
- return generic_ocp_read(tp, index, size, data, MCU_TYPE_USB);
-}
-
-static inline int usb_ocp_real_write(struct r8152 *tp, u16 index,
- u16 byteen, u16 size, void *data)
-{
- return generic_ocp_write(tp, index, byteen, size, data, MCU_TYPE_USB);
-}
-
-static
-int usb_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data)
-{
- if (tp->rtk_enable_diag == 1)
- return 0;
-
- return usb_ocp_real_write(tp, index, byteen, size, data);
-}
-
-static u32 ocp_read_dword(struct r8152 *tp, u16 type, u16 index)
-{
- __le32 data;
-
- generic_ocp_read(tp, index, sizeof(data), &data, type);
-
- return __le32_to_cpu(data);
-}
-
-static
-void ocp_write_real_dword(struct r8152 *tp, u16 type, u16 index, u32 data)
-{
- __le32 tmp = __cpu_to_le32(data);
-
- generic_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(tmp), &tmp, type);
-}
-
-static void ocp_write_dword(struct r8152 *tp, u16 type, u16 index, u32 data)
-{
- if (tp->rtk_enable_diag == 1)
- return;
-
- ocp_write_real_dword(tp, type, index, data);
-}
-
-static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index)
-{
- u32 data;
- __le32 tmp;
- u8 shift = index & 2;
-
- index &= ~3;
-
- generic_ocp_read(tp, index, sizeof(tmp), &tmp, type);
-
- data = __le32_to_cpu(tmp);
- data >>= (shift * 8);
- data &= 0xffff;
-
- return (u16)data;
-}
-
-static void ocp_write_real_word(struct r8152 *tp, u16 type, u16 index, u32 data)
-{
- u32 mask = 0xffff;
- __le32 tmp;
- u16 byen = BYTE_EN_WORD;
- u8 shift = index & 2;
-
- data &= mask;
-
- if (index & 2) {
- byen <<= shift;
- mask <<= (shift * 8);
- data <<= (shift * 8);
- index &= ~3;
- }
-
- generic_ocp_read(tp, index, sizeof(tmp), &tmp, type);
-
- data |= __le32_to_cpu(tmp) & ~mask;
- tmp = __cpu_to_le32(data);
-
- generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type);
-}
-
-static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data)
-{
- if (tp->rtk_enable_diag == 1)
- return;
-
- ocp_write_real_word(tp, type, index, data);
-}
-
-static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index)
-{
- u32 data;
- __le32 tmp;
- u8 shift = index & 3;
-
- index &= ~3;
-
- generic_ocp_read(tp, index, sizeof(tmp), &tmp, type);
-
- data = __le32_to_cpu(tmp);
- data >>= (shift * 8);
- data &= 0xff;
-
- return (u8)data;
-}
-
-static void ocp_write_real_byte(struct r8152 *tp, u16 type, u16 index, u32 data)
-{
- u32 mask = 0xff;
- __le32 tmp;
- u16 byen = BYTE_EN_BYTE;
- u8 shift = index & 3;
-
- data &= mask;
-
- if (index & 3) {
- byen <<= shift;
- mask <<= (shift * 8);
- data <<= (shift * 8);
- index &= ~3;
- }
-
- generic_ocp_read(tp, index, sizeof(tmp), &tmp, type);
-
- data |= __le32_to_cpu(tmp) & ~mask;
- tmp = __cpu_to_le32(data);
-
- generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type);
-}
-
-static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data)
-{
- if (tp->rtk_enable_diag == 1)
- return;
-
- ocp_write_real_byte(tp, type, index, data);
-}
-
-static u16 ocp_reg_read(struct r8152 *tp, u16 addr)
-{
- u16 ocp_base, ocp_index;
-
- if (tp->rtk_enable_diag == 1)
- return -1;
-
- ocp_base = addr & 0xf000;
- if (ocp_base != tp->ocp_base) {
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, ocp_base);
- tp->ocp_base = ocp_base;
- }
-
- ocp_index = (addr & 0x0fff) | 0xb000;
- return ocp_read_word(tp, MCU_TYPE_PLA, ocp_index);
-}
-
-static void ocp_reg_write(struct r8152 *tp, u16 addr, u16 data)
-{
- u16 ocp_base, ocp_index;
-
- if (tp->rtk_enable_diag == 1)
- return;
-
- ocp_base = addr & 0xf000;
- if (ocp_base != tp->ocp_base) {
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, ocp_base);
- tp->ocp_base = ocp_base;
- }
-
- ocp_index = (addr & 0x0fff) | 0xb000;
- ocp_write_word(tp, MCU_TYPE_PLA, ocp_index, data);
-}
-
-static inline void r8152_mdio_write(struct r8152 *tp, u32 reg_addr, u32 value)
-{
- ocp_reg_write(tp, OCP_BASE_MII + reg_addr * 2, value);
-}
-
-static inline int r8152_mdio_read(struct r8152 *tp, u32 reg_addr)
-{
- return ocp_reg_read(tp, OCP_BASE_MII + reg_addr * 2);
-}
-
-static void sram_write(struct r8152 *tp, u16 addr, u16 data)
-{
- ocp_reg_write(tp, OCP_SRAM_ADDR, addr);
- ocp_reg_write(tp, OCP_SRAM_DATA, data);
-}
-
-static u16 sram_read(struct r8152 *tp, u16 addr)
-{
- ocp_reg_write(tp, OCP_SRAM_ADDR, addr);
- return ocp_reg_read(tp, OCP_SRAM_DATA);
-}
-
-static int read_mii_word(struct net_device *netdev, int phy_id, int reg)
-{
- struct r8152 *tp = netdev_priv(netdev);
- int ret;
-
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return -ENODEV;
-
- if (phy_id != R8152_PHY_ID)
- return -EINVAL;
-
- ret = usb_autopm_get_interface(tp->intf);
- if (ret < 0)
- goto out;
-
- ret = r8152_mdio_read(tp, reg);
-
- usb_autopm_put_interface(tp->intf);
-
-out:
- return ret;
-}
-
-static
-void write_mii_word(struct net_device *netdev, int phy_id, int reg, int val)
-{
- struct r8152 *tp = netdev_priv(netdev);
-
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return;
-
- if (phy_id != R8152_PHY_ID)
- return;
-
- if (usb_autopm_get_interface(tp->intf) < 0)
- return;
-
- r8152_mdio_write(tp, reg, val);
-
- usb_autopm_put_interface(tp->intf);
-}
-
-static int
-r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags);
-
-static int rtl8152_set_mac_address(struct net_device *netdev, void *p)
-{
- struct r8152 *tp = netdev_priv(netdev);
- struct sockaddr *addr = p;
-
- if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
-
- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG);
- pla_ocp_write(tp, PLA_IDR, BYTE_EN_SIX_BYTES, 8, addr->sa_data);
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML);
-
- return 0;
-}
-
-static int set_ethernet_addr(struct r8152 *tp)
-{
- struct net_device *dev = tp->netdev;
- struct sockaddr sa;
- int ret;
-
- if (tp->version == RTL_VER_01)
- ret = pla_ocp_read(tp, PLA_IDR, 8, sa.sa_data);
- else
- ret = pla_ocp_read(tp, PLA_BACKUP, 8, sa.sa_data);
-
- if (ret < 0) {
- netif_err(tp, probe, dev, "ether addr fail\n");
- } else if (!is_valid_ether_addr(sa.sa_data)) {
- netif_warn(tp, probe, dev, "Invalid ether addr\n");
- eth_hw_addr_random(dev);
- memcpy(sa.sa_data, dev->dev_addr, ETH_ALEN);
- rtl8152_set_mac_address(dev, &sa);
- } else {
- if (tp->version == RTL_VER_01)
- memcpy(dev->dev_addr, sa.sa_data, ETH_ALEN);
- else
- ret = rtl8152_set_mac_address(dev, &sa);
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)
- memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
-#endif
- }
-
- return ret;
-}
-
-static inline struct net_device_stats *rtl8152_get_stats(struct net_device *dev)
-{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
- struct rtl8152 *tp = netdev_priv(dev);
-
- return (struct net_device_stats *)&tp->stats;
-#else
- return &dev->stats;
-#endif
-}
-
-static void read_bulk_callback(struct urb *urb)
-{
- struct net_device *netdev;
- int status = urb->status;
- struct rx_agg *agg;
- struct r8152 *tp;
- int result;
-
- agg = urb->context;
- if (!agg)
- return;
-
- tp = agg->context;
- if (!tp)
- return;
-
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return;
-
- if (!test_bit(WORK_ENABLE, &tp->flags))
- return;
-
- netdev = tp->netdev;
-
- /* When link down, the driver would cancel all bulks. */
- /* This avoid the re-submitting bulk */
- if (!netif_carrier_ok(netdev))
- return;
-
- usb_mark_last_busy(tp->udev);
-
- switch (status) {
- case 0:
- if (urb->actual_length < ETH_ZLEN)
- break;
-
- spin_lock(&tp->rx_lock);
- list_add_tail(&agg->list, &tp->rx_done);
- spin_unlock(&tp->rx_lock);
- tasklet_schedule(&tp->tl);
- return;
- case -ESHUTDOWN:
- set_bit(RTL8152_UNPLUG, &tp->flags);
- netif_device_detach(tp->netdev);
- return;
- case -ENOENT:
- return; /* the urb is in unlink state */
- case -ETIME:
- if (net_ratelimit())
- netif_warn(tp, rx_err, netdev,
- "maybe reset is needed?\n");
- break;
- default:
- if (net_ratelimit())
- netif_warn(tp, rx_err, netdev,
- "Rx status %d\n", status);
- break;
- }
-
- result = r8152_submit_rx(tp, agg, GFP_ATOMIC);
- if (result == -ENODEV) {
- netif_device_detach(tp->netdev);
- } else if (result) {
- spin_lock(&tp->rx_lock);
- list_add_tail(&agg->list, &tp->rx_done);
- spin_unlock(&tp->rx_lock);
- tasklet_schedule(&tp->tl);
- }
-}
-
-static void write_bulk_callback(struct urb *urb)
-{
- struct net_device_stats *stats;
- struct net_device *netdev;
- struct tx_agg *agg;
- struct r8152 *tp;
- int status = urb->status;
-
- agg = urb->context;
- if (!agg)
- return;
-
- tp = agg->context;
- if (!tp)
- return;
-
- netdev = tp->netdev;
- stats = rtl8152_get_stats(netdev);
- if (status) {
- if (net_ratelimit())
- netif_warn(tp, tx_err, netdev,
- "Tx status %d\n", status);
- stats->tx_errors += agg->skb_num;
- } else {
- stats->tx_packets += agg->skb_num;
- stats->tx_bytes += agg->skb_len;
- }
-
- spin_lock(&tp->tx_lock);
- list_add_tail(&agg->list, &tp->tx_free);
- spin_unlock(&tp->tx_lock);
-
- usb_autopm_put_interface_async(tp->intf);
-
- if (!netif_carrier_ok(netdev))
- return;
-
- if (!test_bit(WORK_ENABLE, &tp->flags))
- return;
-
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return;
-
- if (!skb_queue_empty(&tp->tx_queue))
- tasklet_schedule(&tp->tl);
-}
-
-static void intr_callback(struct urb *urb)
-{
- struct r8152 *tp;
- __le16 *d;
- int status = urb->status;
- int res;
-
- tp = urb->context;
- if (!tp)
- return;
-
- if (!test_bit(WORK_ENABLE, &tp->flags))
- return;
-
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return;
-
- switch (status) {
- case 0: /* success */
- break;
- case -ECONNRESET: /* unlink */
- case -ESHUTDOWN:
- netif_device_detach(tp->netdev);
- case -ENOENT:
- return;
- case -EOVERFLOW:
- netif_info(tp, intr, tp->netdev, "intr status -EOVERFLOW\n");
- goto resubmit;
- /* -EPIPE: should clear the halt */
- default:
- netif_info(tp, intr, tp->netdev, "intr status %d\n", status);
- goto resubmit;
- }
-
- d = urb->transfer_buffer;
- if (INTR_LINK & __le16_to_cpu(d[0])) {
- if (!(tp->speed & LINK_STATUS)) {
- set_bit(RTL8152_LINK_CHG, &tp->flags);
- schedule_delayed_work(&tp->schedule, 0);
- }
- } else {
- if (tp->speed & LINK_STATUS) {
- set_bit(RTL8152_LINK_CHG, &tp->flags);
- schedule_delayed_work(&tp->schedule, 0);
- }
- }
-
-resubmit:
- res = usb_submit_urb(urb, GFP_ATOMIC);
- if (res == -ENODEV)
- netif_device_detach(tp->netdev);
- else if (res)
- netif_err(tp, intr, tp->netdev,
- "can't resubmit intr, status %d\n", res);
-}
-
-static inline void *rx_agg_align(void *data)
-{
- return (void *)ALIGN((uintptr_t)data, RX_ALIGN);
-}
-
-static inline void *tx_agg_align(void *data)
-{
- return (void *)ALIGN((uintptr_t)data, TX_ALIGN);
-}
-
-static void free_all_mem(struct r8152 *tp)
-{
- int i;
-
- for (i = 0; i < RTL8152_MAX_RX; i++) {
- usb_free_urb(tp->rx_info[i].urb);
- tp->rx_info[i].urb = NULL;
-
- kfree(tp->rx_info[i].buffer);
- tp->rx_info[i].buffer = NULL;
- tp->rx_info[i].head = NULL;
- }
-
- for (i = 0; i < RTL8152_MAX_TX; i++) {
- usb_free_urb(tp->tx_info[i].urb);
- tp->tx_info[i].urb = NULL;
-
- kfree(tp->tx_info[i].buffer);
- tp->tx_info[i].buffer = NULL;
- tp->tx_info[i].head = NULL;
- }
-
- usb_free_urb(tp->intr_urb);
- tp->intr_urb = NULL;
-
- kfree(tp->intr_buff);
- tp->intr_buff = NULL;
-}
-
-static int alloc_all_mem(struct r8152 *tp)
-{
- struct net_device *netdev = tp->netdev;
- struct usb_interface *intf = tp->intf;
- struct usb_host_interface *alt = intf->cur_altsetting;
- struct usb_host_endpoint *ep_intr = alt->endpoint + 2;
- struct urb *urb;
- int node, i;
- u8 *buf;
-
- node = netdev->dev.parent ? dev_to_node(netdev->dev.parent) : -1;
-
- spin_lock_init(&tp->rx_lock);
- spin_lock_init(&tp->tx_lock);
- INIT_LIST_HEAD(&tp->rx_done);
- INIT_LIST_HEAD(&tp->tx_free);
- skb_queue_head_init(&tp->tx_queue);
-
- for (i = 0; i < RTL8152_MAX_RX; i++) {
- buf = kmalloc_node(rx_buf_sz, GFP_KERNEL, node);
- if (!buf)
- goto err1;
-
- if (buf != rx_agg_align(buf)) {
- kfree(buf);
- buf = kmalloc_node(rx_buf_sz + RX_ALIGN, GFP_KERNEL,
- node);
- if (!buf)
- goto err1;
- }
-
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- kfree(buf);
- goto err1;
- }
-
- INIT_LIST_HEAD(&tp->rx_info[i].list);
- tp->rx_info[i].context = tp;
- tp->rx_info[i].urb = urb;
- tp->rx_info[i].buffer = buf;
- tp->rx_info[i].head = rx_agg_align(buf);
- }
-
- for (i = 0; i < RTL8152_MAX_TX; i++) {
- buf = kmalloc_node(rx_buf_sz, GFP_KERNEL, node);
- if (!buf)
- goto err1;
-
- if (buf != tx_agg_align(buf)) {
- kfree(buf);
- buf = kmalloc_node(rx_buf_sz + TX_ALIGN, GFP_KERNEL,
- node);
- if (!buf)
- goto err1;
- }
-
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- kfree(buf);
- goto err1;
- }
-
- INIT_LIST_HEAD(&tp->tx_info[i].list);
- tp->tx_info[i].context = tp;
- tp->tx_info[i].urb = urb;
- tp->tx_info[i].buffer = buf;
- tp->tx_info[i].head = tx_agg_align(buf);
-
- list_add_tail(&tp->tx_info[i].list, &tp->tx_free);
- }
-
- tp->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!tp->intr_urb)
- goto err1;
-
- tp->intr_buff = kmalloc(INTBUFSIZE, GFP_KERNEL);
- if (!tp->intr_buff)
- goto err1;
-
- tp->intr_interval = (int)ep_intr->desc.bInterval;
- usb_fill_int_urb(tp->intr_urb, tp->udev, usb_rcvintpipe(tp->udev, 3),
- tp->intr_buff, INTBUFSIZE, intr_callback,
- tp, tp->intr_interval);
-
- return 0;
-
-err1:
- free_all_mem(tp);
- return -ENOMEM;
-}
-
-static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp)
-{
- struct tx_agg *agg = NULL;
- unsigned long flags;
-
- if (list_empty(&tp->tx_free))
- return NULL;
-
- spin_lock_irqsave(&tp->tx_lock, flags);
- if (!list_empty(&tp->tx_free)) {
- struct list_head *cursor;
-
- cursor = tp->tx_free.next;
- list_del_init(cursor);
- agg = list_entry(cursor, struct tx_agg, list);
- }
- spin_unlock_irqrestore(&tp->tx_lock, flags);
-
- return agg;
-}
-
-static inline __be16 get_protocol(struct sk_buff *skb)
-{
- __be16 protocol;
-
- if (skb->protocol == htons(ETH_P_8021Q))
- protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
- else
- protocol = skb->protocol;
-
- return protocol;
-}
-
-/* r8152_csum_workaround()
- * The hw limites the value the transport offset. When the offset is out of the
- * range, calculate the checksum by sw.
- */
-static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb,
- struct sk_buff_head *list)
-{
- if (skb_shinfo(skb)->gso_size) {
- netdev_features_t features = tp->netdev->features;
- struct sk_buff_head seg_list;
- struct sk_buff *segs, *nskb;
-
- features &= ~(NETIF_F_SG | NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
- segs = skb_gso_segment(skb, features);
- if (IS_ERR(segs) || !segs)
- goto drop;
-
- __skb_queue_head_init(&seg_list);
-
- do {
- nskb = segs;
- segs = segs->next;
- nskb->next = NULL;
- __skb_queue_tail(&seg_list, nskb);
- } while (segs);
-
- skb_queue_splice(&seg_list, list);
- dev_kfree_skb(skb);
- } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
- if (skb_checksum_help(skb) < 0)
- goto drop;
-
- __skb_queue_head(list, skb);
- } else {
- struct net_device_stats *stats;
-
-drop:
- stats = rtl8152_get_stats(tp->netdev);
- stats->tx_dropped++;
- dev_kfree_skb(skb);
- }
-}
-
-/* msdn_giant_send_check()
- * According to the document of microsoft, the TCP Pseudo Header excludes the
- * packet length for IPv6 TCP large packets.
- */
-static int msdn_giant_send_check(struct sk_buff *skb)
-{
- const struct ipv6hdr *ipv6h;
- struct tcphdr *th;
- int ret;
-
- ret = skb_cow_head(skb, 0);
- if (ret)
- return ret;
-
- ipv6h = ipv6_hdr(skb);
- th = tcp_hdr(skb);
-
- th->check = 0;
- //th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
- {
- int i;
- for(i=0;i<100;i++)
- printk("msdn_giant_send_check ,this should not happen!!");
- }
-
- return ret;
-}
-
-static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
- struct sk_buff *skb, u32 len, u32 transport_offset)
-{
- u32 mss = skb_shinfo(skb)->gso_size;
- u32 opts1, opts2 = 0;
- int ret = TX_CSUM_SUCCESS;
-
- WARN_ON_ONCE(len > TX_LEN_MAX);
-
- opts1 = len | TX_FS | TX_LS;
-
- if (mss) {
- if (transport_offset > GTTCPHO_MAX) {
- netif_warn(tp, tx_err, tp->netdev,
- "Invalid transport offset 0x%x for TSO\n",
- transport_offset);
- ret = TX_CSUM_TSO;
- goto unavailable;
- }
-
- switch (get_protocol(skb)) {
- case htons(ETH_P_IP):
- opts1 |= GTSENDV4;
- break;
-
- case htons(ETH_P_IPV6):
- if (msdn_giant_send_check(skb)) {
- ret = TX_CSUM_TSO;
- goto unavailable;
- }
- opts1 |= GTSENDV6;
- break;
-
- default:
- WARN_ON_ONCE(1);
- break;
- }
-
- opts1 |= transport_offset << GTTCPHO_SHIFT;
- opts2 |= min(mss, MSS_MAX) << MSS_SHIFT;
- } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
- u8 ip_protocol;
-
- if (transport_offset > TCPHO_MAX) {
- netif_warn(tp, tx_err, tp->netdev,
- "Invalid transport offset 0x%x\n",
- transport_offset);
- ret = TX_CSUM_NONE;
- goto unavailable;
- }
-
- switch (get_protocol(skb)) {
- case htons(ETH_P_IP):
- opts2 |= IPV4_CS;
- ip_protocol = ip_hdr(skb)->protocol;
- break;
-
- case htons(ETH_P_IPV6):
- opts2 |= IPV6_CS;
- ip_protocol = ipv6_hdr(skb)->nexthdr;
- break;
-
- default:
- ip_protocol = IPPROTO_RAW;
- break;
- }
-
- if (ip_protocol == IPPROTO_TCP)
- opts2 |= TCP_CS;
- else if (ip_protocol == IPPROTO_UDP)
- opts2 |= UDP_CS;
- else
- WARN_ON_ONCE(1);
-
- opts2 |= transport_offset << TCPHO_SHIFT;
- }
-
- desc->opts2 = cpu_to_le32(opts2);
- desc->opts1 = cpu_to_le32(opts1);
-
-unavailable:
- return ret;
-}
-
-static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
-{
- struct sk_buff_head skb_head, *tx_queue = &tp->tx_queue;
- int remain, ret;
- u8 *tx_data;
-
- __skb_queue_head_init(&skb_head);
- spin_lock(&tx_queue->lock);
- skb_queue_splice_init(tx_queue, &skb_head);
- spin_unlock(&tx_queue->lock);
-
- tx_data = agg->head;
- agg->skb_num = 0;
- agg->skb_len = 0;
- remain = rx_buf_sz;
-
- while (remain >= ETH_ZLEN + sizeof(struct tx_desc)) {
- struct tx_desc *tx_desc;
- struct sk_buff *skb;
- unsigned int len;
- u32 offset;
-
- skb = __skb_dequeue(&skb_head);
- if (!skb)
- break;
-
- len = skb->len + sizeof(*tx_desc);
-
- if (len > remain) {
- __skb_queue_head(&skb_head, skb);
- break;
- }
-
- tx_data = tx_agg_align(tx_data);
- tx_desc = (struct tx_desc *)tx_data;
-
- offset = (u32)skb_transport_offset(skb);
-
- if (r8152_tx_csum(tp, tx_desc, skb, skb->len, offset)) {
- r8152_csum_workaround(tp, skb, &skb_head);
- continue;
- }
-
- tx_data += sizeof(*tx_desc);
-
- len = skb->len;
- if (skb_copy_bits(skb, 0, tx_data, len) < 0) {
- struct net_device_stats *stats = &tp->netdev->stats;
-
- stats->tx_dropped++;
- dev_kfree_skb_any(skb);
- tx_data -= sizeof(*tx_desc);
- continue;
- }
-
- tx_data += len;
- agg->skb_len += len;
- agg->skb_num++;
-
- dev_kfree_skb_any(skb);
-
- remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head);
- }
-
- if (!skb_queue_empty(&skb_head)) {
- spin_lock(&tx_queue->lock);
- skb_queue_splice(&skb_head, tx_queue);
- spin_unlock(&tx_queue->lock);
- }
-
- netif_tx_lock(tp->netdev);
-
- if (netif_queue_stopped(tp->netdev) &&
- skb_queue_len(&tp->tx_queue) < tp->tx_qlen)
- netif_wake_queue(tp->netdev);
-
- netif_tx_unlock(tp->netdev);
-
- ret = usb_autopm_get_interface_async(tp->intf);
- if (ret < 0)
- goto out_tx_fill;
-
- usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
- agg->head, (int)(tx_data - (u8 *)agg->head),
- (usb_complete_t)write_bulk_callback, agg);
-
- ret = usb_submit_urb(agg->urb, GFP_ATOMIC);
- if (ret < 0)
- usb_autopm_put_interface_async(tp->intf);
-
-out_tx_fill:
- return ret;
-}
-
-static u8 r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc)
-{
- u8 checksum = CHECKSUM_NONE;
- u32 opts2, opts3;
-
- if (tp->version == RTL_VER_01)
- goto return_result;
-
- opts2 = le32_to_cpu(rx_desc->opts2);
- opts3 = le32_to_cpu(rx_desc->opts3);
-
- if (opts2 & RD_IPV4_CS) {
- if (opts3 & IPF)
- checksum = CHECKSUM_NONE;
- else if ((opts2 & RD_UDP_CS) && (opts3 & UDPF))
- checksum = CHECKSUM_NONE;
- else if ((opts2 & RD_TCP_CS) && (opts3 & TCPF))
- checksum = CHECKSUM_NONE;
- else
- checksum = CHECKSUM_UNNECESSARY;
- } else if (RD_IPV6_CS) {
- if ((opts2 & RD_UDP_CS) && !(opts3 & UDPF))
- checksum = CHECKSUM_UNNECESSARY;
- else if ((opts2 & RD_TCP_CS) && !(opts3 & TCPF))
- checksum = CHECKSUM_UNNECESSARY;
- }
-
-return_result:
- return checksum;
-}
-
-static void rx_bottom(struct r8152 *tp)
-{
- unsigned long flags;
- struct list_head *cursor, *next, rx_queue;
-
- if (list_empty(&tp->rx_done))
- return;
-
- INIT_LIST_HEAD(&rx_queue);
- spin_lock_irqsave(&tp->rx_lock, flags);
- list_splice_init(&tp->rx_done, &rx_queue);
- spin_unlock_irqrestore(&tp->rx_lock, flags);
-
- list_for_each_safe(cursor, next, &rx_queue) {
- struct rx_desc *rx_desc;
- struct rx_agg *agg;
- int len_used = 0;
- struct urb *urb;
- u8 *rx_data;
- int ret;
-
- list_del_init(cursor);
-
- agg = list_entry(cursor, struct rx_agg, list);
- urb = agg->urb;
- if (urb->actual_length < ETH_ZLEN)
- goto submit;
-
- rx_desc = agg->head;
- rx_data = agg->head;
- len_used += sizeof(struct rx_desc);
-
- while (urb->actual_length > len_used) {
- struct net_device *netdev = tp->netdev;
- struct net_device_stats *stats;
- unsigned int pkt_len;
- struct sk_buff *skb;
-
- pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
- if (pkt_len < ETH_ZLEN)
- break;
-
- len_used += pkt_len;
- if (urb->actual_length < len_used)
- break;
-
- stats = rtl8152_get_stats(netdev);
-
- pkt_len -= CRC_SIZE;
- rx_data += sizeof(struct rx_desc);
-
- skb = netdev_alloc_skb_ip_align(netdev, pkt_len);
- if (!skb) {
- stats->rx_dropped++;
- goto find_next_rx;
- }
-
- skb->ip_summed = r8152_rx_csum(tp, rx_desc);
- memcpy(skb->data, rx_data, pkt_len);
- skb_put(skb, pkt_len);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
- skb->dev = netdev;
-#endif
- skb->protocol = eth_type_trans(skb, netdev);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
- netdev->last_rx = jiffies;
-#endif
- netif_receive_skb(skb);
- stats->rx_packets++;
- stats->rx_bytes += pkt_len;
-
-find_next_rx:
- rx_data = rx_agg_align(rx_data + pkt_len + CRC_SIZE);
- rx_desc = (struct rx_desc *)rx_data;
- len_used = (int)(rx_data - (u8 *)agg->head);
- len_used += sizeof(struct rx_desc);
- }
-
-submit:
- ret = r8152_submit_rx(tp, agg, GFP_ATOMIC);
- if (ret && ret != -ENODEV) {
- spin_lock_irqsave(&tp->rx_lock, flags);
- list_add_tail(&agg->list, &tp->rx_done);
- spin_unlock_irqrestore(&tp->rx_lock, flags);
- tasklet_schedule(&tp->tl);
- }
- }
-}
-
-static void tx_bottom(struct r8152 *tp)
-{
- int res;
-
- do {
- struct tx_agg *agg;
-
- if (skb_queue_empty(&tp->tx_queue))
- break;
-
- agg = r8152_get_tx_agg(tp);
- if (!agg)
- break;
-
- res = r8152_tx_agg_fill(tp, agg);
- if (res) {
- struct net_device *netdev = tp->netdev;
-
- if (res == -ENODEV) {
- netif_device_detach(netdev);
- } else {
- struct net_device_stats *stats;
- unsigned long flags;
-
- stats = rtl8152_get_stats(netdev);
- netif_warn(tp, tx_err, netdev,
- "failed tx_urb %d\n", res);
- stats->tx_dropped += agg->skb_num;
-
- spin_lock_irqsave(&tp->tx_lock, flags);
- list_add_tail(&agg->list, &tp->tx_free);
- spin_unlock_irqrestore(&tp->tx_lock, flags);
- }
- }
- } while (res == 0);
-}
-
-static void bottom_half(unsigned long data)
-{
- struct r8152 *tp;
-
- tp = (struct r8152 *)data;
-
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return;
-
- if (!test_bit(WORK_ENABLE, &tp->flags))
- return;
-
- /* When link down, the driver would cancel all bulks. */
- /* This avoid the re-submitting bulk */
- if (!netif_carrier_ok(tp->netdev))
- return;
-
- rx_bottom(tp);
- tx_bottom(tp);
-}
-
-static
-int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags)
-{
- usb_fill_bulk_urb(agg->urb, tp->udev, usb_rcvbulkpipe(tp->udev, 1),
- agg->head, rx_buf_sz,
- (usb_complete_t)read_bulk_callback, agg);
-
- return usb_submit_urb(agg->urb, mem_flags);
-}
-
-static void rtl_drop_queued_tx(struct r8152 *tp)
-{
- struct net_device_stats *stats = rtl8152_get_stats(tp->netdev);
- struct sk_buff_head skb_head, *tx_queue = &tp->tx_queue;
- struct sk_buff *skb;
-
- if (skb_queue_empty(tx_queue))
- return;
-
- __skb_queue_head_init(&skb_head);
- spin_lock_bh(&tx_queue->lock);
- skb_queue_splice_init(tx_queue, &skb_head);
- spin_unlock_bh(&tx_queue->lock);
-
- while ((skb = __skb_dequeue(&skb_head))) {
- dev_kfree_skb(skb);
- stats->tx_dropped++;
- }
-}
-
-static void rtl8152_tx_timeout(struct net_device *netdev)
-{
- struct r8152 *tp = netdev_priv(netdev);
- int i;
-
- netif_warn(tp, tx_err, netdev, "Tx timeout\n");
- for (i = 0; i < RTL8152_MAX_TX; i++)
- usb_unlink_urb(tp->tx_info[i].urb);
-}
-
-static void rtl8152_set_rx_mode(struct net_device *netdev)
-{
- struct r8152 *tp = netdev_priv(netdev);
- u32 mc_filter[2]; /* Multicast hash filter */
- __le32 tmp[2];
- u32 ocp_data;
-
- if (in_atomic()) {
- if (tp->speed & LINK_STATUS) {
- set_bit(RTL8152_SET_RX_MODE, &tp->flags);
- schedule_delayed_work(&tp->schedule, 0);
- }
- return;
- }
-
- clear_bit(RTL8152_SET_RX_MODE, &tp->flags);
- netif_stop_queue(netdev);
- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
- ocp_data &= ~RCR_ACPT_ALL;
- ocp_data |= RCR_AB | RCR_APM;
-
- if (netdev->flags & IFF_PROMISC) {
- /* Unconditionally log net taps. */
- netif_notice(tp, link, netdev, "Promiscuous mode enabled\n");
- ocp_data |= RCR_AM | RCR_AAP;
- mc_filter[1] = 0xffffffff;
- mc_filter[0] = 0xffffffff;
- } else if ((netdev_mc_count(netdev) > multicast_filter_limit) ||
- (netdev->flags & IFF_ALLMULTI)) {
- /* Too many to filter perfectly -- accept all multicasts. */
- ocp_data |= RCR_AM;
- mc_filter[1] = 0xffffffff;
- mc_filter[0] = 0xffffffff;
- } else {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
- struct dev_mc_list *mclist;
- unsigned int i;
-
- mc_filter[1] = mc_filter[0] = 0;
- for (i = 0, mclist = netdev->mc_list; mclist && i < netdev->mc_count;
- i++, mclist = mclist->next) {
- int bit_nr;
- bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
- mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
- ocp_data |= RCR_AM;
- }
-#else
- struct netdev_hw_addr *ha;
-
- mc_filter[1] = 0;
- mc_filter[0] = 0;
- netdev_for_each_mc_addr(ha, netdev) {
- int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
-
- mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
- ocp_data |= RCR_AM;
- }
-#endif
- }
-
- 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(tmp), tmp);
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
- netif_wake_queue(netdev);
-}
-
-static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
- struct net_device *netdev)
-{
- struct r8152 *tp = netdev_priv(netdev);
-
- skb_tx_timestamp(skb);
-
- skb_queue_tail(&tp->tx_queue, skb);
-
- if (!list_empty(&tp->tx_free)) {
- if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
- set_bit(SCHEDULE_TASKLET, &tp->flags);
- schedule_delayed_work(&tp->schedule, 0);
- } else {
- usb_mark_last_busy(tp->udev);
- tasklet_schedule(&tp->tl);
- }
- } else if (skb_queue_len(&tp->tx_queue) > tp->tx_qlen) {
- netif_stop_queue(netdev);
- }
-
- return NETDEV_TX_OK;
-}
-
-static void r8152b_reset_packet_filter(struct r8152 *tp)
-{
- u32 ocp_data;
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_FMC);
- ocp_data &= ~FMC_FCR_MCU_EN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_FMC, ocp_data);
- ocp_data |= FMC_FCR_MCU_EN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_FMC, ocp_data);
-}
-
-static void rtl8152_nic_reset(struct r8152 *tp)
-{
- int i;
-
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, CR_RST);
-
- for (i = 0; i < 1000; i++) {
- if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & CR_RST))
- break;
- usleep_range(100, 400);
- }
-}
-
-static void set_tx_qlen(struct r8152 *tp)
-{
- struct net_device *netdev = tp->netdev;
-
- tp->tx_qlen = rx_buf_sz / (netdev->mtu + VLAN_ETH_HLEN + VLAN_HLEN +
- sizeof(struct tx_desc));
-}
-
-static inline u8 rtl8152_get_speed(struct r8152 *tp)
-{
- return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS);
-}
-
-static void rtl_set_eee_plus(struct r8152 *tp)
-{
- u32 ocp_data;
- u8 speed;
-
- speed = rtl8152_get_speed(tp);
- if (speed & _10bps) {
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR);
- ocp_data |= EEEP_CR_EEEP_TX;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data);
- } else {
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR);
- ocp_data &= ~EEEP_CR_EEEP_TX;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data);
- }
-}
-
-static void rxdy_gated_en(struct r8152 *tp, bool enable)
-{
- u32 ocp_data;
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MISC_1);
- if (enable)
- ocp_data |= RXDY_GATED_EN;
- else
- ocp_data &= ~RXDY_GATED_EN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data);
-}
-
-static int rtl_enable(struct r8152 *tp)
-{
- u32 ocp_data;
- int i, ret;
-
- r8152b_reset_packet_filter(tp);
-
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR);
- ocp_data |= CR_RE | CR_TE;
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data);
-
- rxdy_gated_en(tp, false);
-
- INIT_LIST_HEAD(&tp->rx_done);
- ret = 0;
- for (i = 0; i < RTL8152_MAX_RX; i++) {
- INIT_LIST_HEAD(&tp->rx_info[i].list);
- ret |= r8152_submit_rx(tp, &tp->rx_info[i], GFP_KERNEL);
- }
-
- return ret;
-}
-
-static int rtl8152_enable(struct r8152 *tp)
-{
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return -ENODEV;
-
- set_tx_qlen(tp);
- rtl_set_eee_plus(tp);
-
- return rtl_enable(tp);
-}
-
-static void r8153_set_rx_agg(struct r8152 *tp)
-{
- u8 speed;
-
- speed = rtl8152_get_speed(tp);
- if (speed & _1000bps) {
- if (tp->udev->speed == USB_SPEED_SUPER) {
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
- RX_THR_SUPPER);
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
- EARLY_AGG_SUPER);
- } else {
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
- RX_THR_HIGH);
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
- EARLY_AGG_HIGH);
- }
- } else {
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_SLOW);
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
- EARLY_AGG_SLOW);
- }
-}
-
-static int rtl8153_enable(struct r8152 *tp)
-{
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return -ENODEV;
-
- set_tx_qlen(tp);
- rtl_set_eee_plus(tp);
- r8153_set_rx_agg(tp);
-
- return rtl_enable(tp);
-}
-
-static void rtl_disable(struct r8152 *tp)
-{
- u32 ocp_data;
- int i;
-
- if (test_bit(RTL8152_UNPLUG, &tp->flags)) {
- rtl_drop_queued_tx(tp);
- return;
- }
-
- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
- ocp_data &= ~RCR_ACPT_ALL;
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
-
- rtl_drop_queued_tx(tp);
-
- for (i = 0; i < RTL8152_MAX_TX; i++)
- usb_kill_urb(tp->tx_info[i].urb);
-
- rxdy_gated_en(tp, true);
-
- for (i = 0; i < 1000; i++) {
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- if ((ocp_data & FIFO_EMPTY) == FIFO_EMPTY)
- break;
- usleep_range(1000, 2000);
- }
-
- for (i = 0; i < 1000; i++) {
- if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0) & TCR0_TX_EMPTY)
- break;
- usleep_range(1000, 2000);
- }
-
- for (i = 0; i < RTL8152_MAX_RX; i++)
- usb_kill_urb(tp->rx_info[i].urb);
-
- rtl8152_nic_reset(tp);
-}
-
-static void r8152_power_cut_en(struct r8152 *tp, bool enable)
-{
- u32 ocp_data;
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CTRL);
- if (enable)
- ocp_data |= POWER_CUT;
- else
- ocp_data &= ~POWER_CUT;
- ocp_write_word(tp, MCU_TYPE_USB, USB_UPS_CTRL, ocp_data);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS);
- ocp_data &= ~RESUME_INDICATE;
- ocp_write_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS, ocp_data);
-}
-
-#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
-
-static u32 __rtl_get_wol(struct r8152 *tp)
-{
- u32 ocp_data;
- u32 wolopts = 0;
-
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG5);
- if (!(ocp_data & LAN_WAKE_EN))
- return 0;
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34);
- if (ocp_data & LINK_ON_WAKE_EN)
- wolopts |= WAKE_PHY;
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG5);
- if (ocp_data & UWF_EN)
- wolopts |= WAKE_UCAST;
- if (ocp_data & BWF_EN)
- wolopts |= WAKE_BCAST;
- if (ocp_data & MWF_EN)
- wolopts |= WAKE_MCAST;
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL);
- if (ocp_data & MAGIC_EN)
- wolopts |= WAKE_MAGIC;
-
- return wolopts;
-}
-
-static void __rtl_set_wol(struct r8152 *tp, u32 wolopts)
-{
- u32 ocp_data;
-
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34);
- ocp_data &= ~LINK_ON_WAKE_EN;
- if (wolopts & WAKE_PHY)
- ocp_data |= LINK_ON_WAKE_EN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG5);
- ocp_data &= ~(UWF_EN | BWF_EN | MWF_EN | LAN_WAKE_EN);
- if (wolopts & WAKE_UCAST)
- ocp_data |= UWF_EN;
- if (wolopts & WAKE_BCAST)
- ocp_data |= BWF_EN;
- if (wolopts & WAKE_MCAST)
- ocp_data |= MWF_EN;
- if (wolopts & WAKE_ANY)
- ocp_data |= LAN_WAKE_EN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG5, ocp_data);
-
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL);
- ocp_data &= ~MAGIC_EN;
- if (wolopts & WAKE_MAGIC)
- ocp_data |= MAGIC_EN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL, ocp_data);
-
- if (wolopts & WAKE_ANY)
- device_set_wakeup_enable(&tp->udev->dev, true);
- else
- device_set_wakeup_enable(&tp->udev->dev, false);
-}
-
-static void rtl_runtime_suspend_enable(struct r8152 *tp, bool enable)
-{
- if (enable) {
- u32 ocp_data;
-
- __rtl_set_wol(tp, WAKE_ANY);
-
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34);
- ocp_data |= LINK_OFF_WAKE_EN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data);
-
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML);
- } else {
- __rtl_set_wol(tp, tp->saved_wolopts);
- }
-}
-
-static void rtl_phy_reset(struct r8152 *tp)
-{
- u16 data;
- int i;
-
- clear_bit(PHY_RESET, &tp->flags);
-
- data = r8152_mdio_read(tp, MII_BMCR);
-
- /* don't reset again before the previous one complete */
- if (data & BMCR_RESET)
- return;
-
- data |= BMCR_RESET;
- r8152_mdio_write(tp, MII_BMCR, data);
-
- for (i = 0; i < 50; i++) {
- msleep(20);
- if ((r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET) == 0)
- break;
- }
-}
-
-static void rtl_clear_bp(struct r8152 *tp)
-{
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_0, 0);
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_2, 0);
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_4, 0);
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_6, 0);
- ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_0, 0);
- ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_2, 0);
- ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_4, 0);
- ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_6, 0);
- usleep_range(3000, 6000);
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0);
- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0);
-}
-
-static void r8153_clear_bp(struct r8152 *tp)
-{
- if (tp->version == RTL_VER_05) {
- u32 ocp_data;
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xcfca);
- ocp_data &= ~0x4000;
- ocp_write_word(tp, MCU_TYPE_USB, 0xcfca, ocp_data);
- }
-
- if (tp->version == RTL_VER_04 || tp->version == RTL_VER_05) {
- int i;
-
- for (i = 0; i < 104; i++) {
- usleep_range(1000, 2000);
- if (!(ocp_read_byte(tp, MCU_TYPE_USB, 0xe404) & 1))
- break;
- }
- }
-
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0);
- ocp_write_byte(tp, MCU_TYPE_USB, USB_BP_EN, 0);
- rtl_clear_bp(tp);
-}
-
-static void r8153_teredo_off(struct r8152 *tp)
-{
- u32 ocp_data;
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG);
- ocp_data &= ~(TEREDO_SEL | TEREDO_RS_EVENT_MASK | OOB_TEREDO_EN);
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ocp_data);
-
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_WDT6_CTRL, WDT6_SET_MODE);
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_REALWOW_TIMER, 0);
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TEREDO_TIMER, 0);
-}
-
-static void r8152b_firmware(struct r8152 *tp)
-{
- rtl_clear_bp(tp);
-
- if (tp->version == RTL_VER_01) {
- int i;
- static u8 pla_patch_a[] = {
- 0x08, 0xe0, 0x40, 0xe0,
- 0x78, 0xe0, 0x85, 0xe0,
- 0x5d, 0xe1, 0xa1, 0xe1,
- 0xa3, 0xe1, 0xab, 0xe1,
- 0x31, 0xc3, 0x60, 0x72,
- 0xa0, 0x49, 0x10, 0xf0,
- 0xa4, 0x49, 0x0e, 0xf0,
- 0x2c, 0xc3, 0x62, 0x72,
- 0x26, 0x70, 0x80, 0x49,
- 0x05, 0xf0, 0x2f, 0x48,
- 0x62, 0x9a, 0x24, 0x70,
- 0x60, 0x98, 0x24, 0xc3,
- 0x60, 0x99, 0x23, 0xc3,
- 0x00, 0xbb, 0x2c, 0x75,
- 0xdc, 0x21, 0xbc, 0x25,
- 0x04, 0x13, 0x0a, 0xf0,
- 0x03, 0x13, 0x08, 0xf0,
- 0x02, 0x13, 0x06, 0xf0,
- 0x01, 0x13, 0x04, 0xf0,
- 0x08, 0x13, 0x02, 0xf0,
- 0x03, 0xe0, 0xd4, 0x49,
- 0x04, 0xf1, 0x14, 0xc2,
- 0x12, 0xc3, 0x00, 0xbb,
- 0x12, 0xc3, 0x60, 0x75,
- 0xd0, 0x49, 0x05, 0xf1,
- 0x50, 0x48, 0x60, 0x9d,
- 0x09, 0xc6, 0x00, 0xbe,
- 0xd0, 0x48, 0x60, 0x9d,
- 0xf3, 0xe7, 0xc2, 0xc0,
- 0x38, 0xd2, 0xc6, 0xd2,
- 0x84, 0x17, 0xa2, 0x13,
- 0x0c, 0x17, 0xbc, 0xc0,
- 0xa2, 0xd1, 0x33, 0xc5,
- 0xa0, 0x74, 0xc0, 0x49,
- 0x1f, 0xf0, 0x30, 0xc5,
- 0xa0, 0x73, 0x00, 0x13,
- 0x04, 0xf1, 0xa2, 0x73,
- 0x00, 0x13, 0x14, 0xf0,
- 0x28, 0xc5, 0xa0, 0x74,
- 0xc8, 0x49, 0x1b, 0xf1,
- 0x26, 0xc5, 0xa0, 0x76,
- 0xa2, 0x74, 0x01, 0x06,
- 0x20, 0x37, 0xa0, 0x9e,
- 0xa2, 0x9c, 0x1e, 0xc5,
- 0xa2, 0x73, 0x23, 0x40,
- 0x10, 0xf8, 0x04, 0xf3,
- 0xa0, 0x73, 0x33, 0x40,
- 0x0c, 0xf8, 0x15, 0xc5,
- 0xa0, 0x74, 0x41, 0x48,
- 0xa0, 0x9c, 0x14, 0xc5,
- 0xa0, 0x76, 0x62, 0x48,
- 0xe0, 0x48, 0xa0, 0x9e,
- 0x10, 0xc6, 0x00, 0xbe,
- 0x0a, 0xc5, 0xa0, 0x74,
- 0x48, 0x48, 0xa0, 0x9c,
- 0x0b, 0xc5, 0x20, 0x1e,
- 0xa0, 0x9e, 0xe5, 0x48,
- 0xa0, 0x9e, 0xf0, 0xe7,
- 0xbc, 0xc0, 0xc8, 0xd2,
- 0xcc, 0xd2, 0x28, 0xe4,
- 0x22, 0x02, 0xf0, 0xc0,
- 0x0b, 0xc0, 0x00, 0x71,
- 0x0a, 0xc0, 0x00, 0x72,
- 0xa0, 0x49, 0x04, 0xf0,
- 0xa4, 0x49, 0x02, 0xf0,
- 0x93, 0x48, 0x04, 0xc0,
- 0x00, 0xb8, 0x00, 0xe4,
- 0xc2, 0xc0, 0x8c, 0x09,
- 0x14, 0xc2, 0x40, 0x73,
- 0xba, 0x48, 0x40, 0x9b,
- 0x11, 0xc2, 0x40, 0x73,
- 0xb0, 0x49, 0x17, 0xf0,
- 0xbf, 0x49, 0x03, 0xf1,
- 0x09, 0xc5, 0x00, 0xbd,
- 0xb1, 0x49, 0x11, 0xf0,
- 0xb1, 0x48, 0x40, 0x9b,
- 0x02, 0xc2, 0x00, 0xba,
- 0x82, 0x18, 0x00, 0xa0,
- 0x1e, 0xfc, 0xbc, 0xc0,
- 0xf0, 0xc0, 0xde, 0xe8,
- 0x00, 0x80, 0x00, 0x60,
- 0x2c, 0x75, 0xd4, 0x49,
- 0x12, 0xf1, 0x29, 0xe0,
- 0xf8, 0xc2, 0x46, 0x71,
- 0xf7, 0xc2, 0x40, 0x73,
- 0xbe, 0x49, 0x03, 0xf1,
- 0xf5, 0xc7, 0x02, 0xe0,
- 0xf2, 0xc7, 0x4f, 0x30,
- 0x26, 0x62, 0xa1, 0x49,
- 0xf0, 0xf1, 0x22, 0x72,
- 0xa0, 0x49, 0xed, 0xf1,
- 0x25, 0x25, 0x18, 0x1f,
- 0x97, 0x30, 0x91, 0x30,
- 0x36, 0x9a, 0x2c, 0x75,
- 0x32, 0xc3, 0x60, 0x73,
- 0xb1, 0x49, 0x0d, 0xf1,
- 0xdc, 0x21, 0xbc, 0x25,
- 0x27, 0xc6, 0xc0, 0x77,
- 0x04, 0x13, 0x18, 0xf0,
- 0x03, 0x13, 0x19, 0xf0,
- 0x02, 0x13, 0x1a, 0xf0,
- 0x01, 0x13, 0x1b, 0xf0,
- 0xd4, 0x49, 0x03, 0xf1,
- 0x1c, 0xc5, 0x00, 0xbd,
- 0xcd, 0xc6, 0xc6, 0x67,
- 0x2e, 0x75, 0xd7, 0x22,
- 0xdd, 0x26, 0x05, 0x15,
- 0x1a, 0xf0, 0x14, 0xc6,
- 0x00, 0xbe, 0x13, 0xc5,
- 0x00, 0xbd, 0x12, 0xc5,
- 0x00, 0xbd, 0xf1, 0x49,
- 0xfb, 0xf1, 0xef, 0xe7,
- 0xf4, 0x49, 0xfa, 0xf1,
- 0xec, 0xe7, 0xf3, 0x49,
- 0xf7, 0xf1, 0xe9, 0xe7,
- 0xf2, 0x49, 0xf4, 0xf1,
- 0xe6, 0xe7, 0xb6, 0xc0,
- 0x6a, 0x14, 0xac, 0x13,
- 0xd6, 0x13, 0xfa, 0x14,
- 0xa0, 0xd1, 0x00, 0x00,
- 0xc0, 0x75, 0xd0, 0x49,
- 0x46, 0xf0, 0x26, 0x72,
- 0xa7, 0x49, 0x43, 0xf0,
- 0x22, 0x72, 0x25, 0x25,
- 0x20, 0x1f, 0x97, 0x30,
- 0x91, 0x30, 0x40, 0x73,
- 0xf3, 0xc4, 0x1c, 0x40,
- 0x04, 0xf0, 0xd7, 0x49,
- 0x05, 0xf1, 0x37, 0xe0,
- 0x53, 0x48, 0xc0, 0x9d,
- 0x08, 0x02, 0x40, 0x66,
- 0x64, 0x27, 0x06, 0x16,
- 0x30, 0xf1, 0x46, 0x63,
- 0x3b, 0x13, 0x2d, 0xf1,
- 0x34, 0x9b, 0x18, 0x1b,
- 0x93, 0x30, 0x2b, 0xc3,
- 0x10, 0x1c, 0x2b, 0xe8,
- 0x01, 0x14, 0x25, 0xf1,
- 0x00, 0x1d, 0x26, 0x1a,
- 0x8a, 0x30, 0x22, 0x73,
- 0xb5, 0x25, 0x0e, 0x0b,
- 0x00, 0x1c, 0x2c, 0xe8,
- 0x1f, 0xc7, 0x27, 0x40,
- 0x1a, 0xf1, 0x38, 0xe8,
- 0x32, 0x1f, 0x8f, 0x30,
- 0x08, 0x1b, 0x24, 0xe8,
- 0x36, 0x72, 0x46, 0x77,
- 0x00, 0x17, 0x0d, 0xf0,
- 0x13, 0xc3, 0x1f, 0x40,
- 0x03, 0xf1, 0x00, 0x1f,
- 0x46, 0x9f, 0x44, 0x77,
- 0x9f, 0x44, 0x5f, 0x44,
- 0x17, 0xe8, 0x0a, 0xc7,
- 0x27, 0x40, 0x05, 0xf1,
- 0x02, 0xc3, 0x00, 0xbb,
- 0x50, 0x1a, 0x06, 0x1a,
- 0xff, 0xc7, 0x00, 0xbf,
- 0xb8, 0xcd, 0xff, 0xff,
- 0x02, 0x0c, 0x54, 0xa5,
- 0xdc, 0xa5, 0x2f, 0x40,
- 0x05, 0xf1, 0x00, 0x14,
- 0xfa, 0xf1, 0x01, 0x1c,
- 0x02, 0xe0, 0x00, 0x1c,
- 0x80, 0xff, 0xb0, 0x49,
- 0x04, 0xf0, 0x01, 0x0b,
- 0xd3, 0xa1, 0x03, 0xe0,
- 0x02, 0x0b, 0xd3, 0xa5,
- 0x27, 0x31, 0x20, 0x37,
- 0x02, 0x0b, 0xd3, 0xa5,
- 0x27, 0x31, 0x20, 0x37,
- 0x00, 0x13, 0xfb, 0xf1,
- 0x80, 0xff, 0x22, 0x73,
- 0xb5, 0x25, 0x18, 0x1e,
- 0xde, 0x30, 0xd9, 0x30,
- 0x64, 0x72, 0x11, 0x1e,
- 0x68, 0x23, 0x16, 0x31,
- 0x80, 0xff, 0xd4, 0x49,
- 0x28, 0xf0, 0x02, 0xb4,
- 0x2a, 0xc4, 0x00, 0x1d,
- 0x2e, 0xe8, 0xe0, 0x73,
- 0xb9, 0x21, 0xbd, 0x25,
- 0x04, 0x13, 0x02, 0xf0,
- 0x1a, 0xe0, 0x22, 0xc4,
- 0x23, 0xc3, 0x2f, 0xe8,
- 0x23, 0xc3, 0x2d, 0xe8,
- 0x00, 0x1d, 0x21, 0xe8,
- 0xe2, 0x73, 0xbb, 0x49,
- 0xfc, 0xf0, 0xe0, 0x73,
- 0xb7, 0x48, 0x03, 0xb4,
- 0x81, 0x1d, 0x19, 0xe8,
- 0x40, 0x1a, 0x84, 0x1d,
- 0x16, 0xe8, 0x12, 0xc3,
- 0x1e, 0xe8, 0x03, 0xb0,
- 0x81, 0x1d, 0x11, 0xe8,
- 0x0e, 0xc3, 0x19, 0xe8,
- 0x02, 0xb0, 0x06, 0xc7,
- 0x04, 0x1e, 0xe0, 0x9e,
- 0x02, 0xc6, 0x00, 0xbe,
- 0x22, 0x02, 0x20, 0xe4,
- 0x04, 0xb8, 0x34, 0xb0,
- 0x00, 0x02, 0x00, 0x03,
- 0x00, 0x0e, 0x00, 0x0c,
- 0x09, 0xc7, 0xe0, 0x9b,
- 0xe2, 0x9a, 0xe4, 0x9c,
- 0xe6, 0x8d, 0xe6, 0x76,
- 0xef, 0x49, 0xfe, 0xf1,
- 0x80, 0xff, 0x08, 0xea,
- 0x82, 0x1d, 0xf5, 0xef,
- 0x00, 0x1a, 0x88, 0x1d,
- 0xf2, 0xef, 0xed, 0xc2,
- 0xf0, 0xef, 0x80, 0xff,
- 0x02, 0xc6, 0x00, 0xbe,
- 0x46, 0x06, 0x08, 0xc2,
- 0x40, 0x73, 0x3a, 0x48,
- 0x40, 0x9b, 0x06, 0xff,
- 0x02, 0xc6, 0x00, 0xbe,
- 0x86, 0x17, 0x1e, 0xfc,
- 0x36, 0xf0, 0x08, 0x1c,
- 0xea, 0x8c, 0xe3, 0x64,
- 0xc7, 0x49, 0x25, 0xf1,
- 0xe0, 0x75, 0xff, 0x1b,
- 0xeb, 0x47, 0xff, 0x1b,
- 0x6b, 0x47, 0xe0, 0x9d,
- 0x15, 0xc3, 0x60, 0x75,
- 0xd8, 0x49, 0x04, 0xf0,
- 0x81, 0x1d, 0xe2, 0x8d,
- 0x05, 0xe0, 0xe2, 0x63,
- 0x81, 0x1d, 0xdd, 0x47,
- 0xe2, 0x8b, 0x0b, 0xc3,
- 0x00, 0x1d, 0x61, 0x8d,
- 0x3c, 0x03, 0x60, 0x75,
- 0xd8, 0x49, 0x06, 0xf1,
- 0xdf, 0x48, 0x61, 0x95,
- 0x16, 0xe0, 0x4e, 0xe8,
- 0x12, 0xe8, 0x21, 0xc5,
- 0xa0, 0x73, 0xb0, 0x49,
- 0x03, 0xf0, 0x31, 0x48,
- 0xa0, 0x9b, 0x0d, 0xe0,
- 0xc0, 0x49, 0x0b, 0xf1,
- 0xe2, 0x63, 0x7e, 0x1d,
- 0xdd, 0x46, 0xe2, 0x8b,
- 0xe0, 0x75, 0x83, 0x1b,
- 0xeb, 0x46, 0xfe, 0x1b,
- 0x6b, 0x46, 0xe0, 0x9d,
- 0xe4, 0x49, 0x11, 0xf0,
- 0x10, 0x1d, 0xea, 0x8d,
- 0xe3, 0x64, 0xc6, 0x49,
- 0x09, 0xf1, 0x07, 0xc5,
- 0xa0, 0x73, 0xb1, 0x48,
- 0xa0, 0x9b, 0x02, 0xc5,
- 0x00, 0xbd, 0xe6, 0x04,
- 0xa0, 0xd1, 0x02, 0xc5,
- 0x00, 0xbd, 0xfe, 0x04,
- 0x02, 0xc5, 0x00, 0xbd,
- 0x30, 0x05, 0x00, 0x00 };
- static u16 ram_code1[] = {
- 0x9700, 0x7fe0, 0x4c00, 0x4007,
- 0x4400, 0x4800, 0x7c1f, 0x4c00,
- 0x5310, 0x6000, 0x7c07, 0x6800,
- 0x673e, 0x0000, 0x0000, 0x571f,
- 0x5ffb, 0xaa05, 0x5b58, 0x7d80,
- 0x6100, 0x3019, 0x5b64, 0x7d80,
- 0x6080, 0xa6f8, 0xdcdb, 0x0015,
- 0xb915, 0xb511, 0xd16b, 0x000f,
- 0xb40f, 0xd06b, 0x000d, 0xb206,
- 0x7c01, 0x5800, 0x7c04, 0x5c00,
- 0x3011, 0x7c01, 0x5801, 0x7c04,
- 0x5c04, 0x3019, 0x30a5, 0x3127,
- 0x31d5, 0x7fe0, 0x4c60, 0x7c07,
- 0x6803, 0x7d00, 0x6900, 0x65a0,
- 0x0000, 0x0000, 0xaf03, 0x6015,
- 0x303e, 0x6017, 0x57e0, 0x580c,
- 0x588c, 0x7fdd, 0x5fa2, 0x4827,
- 0x7c1f, 0x4c00, 0x7c1f, 0x4c10,
- 0x8400, 0x7c30, 0x6020, 0x48bf,
- 0x7c1f, 0x4c00, 0x7c1f, 0x4c01,
- 0x7c07, 0x6803, 0xb806, 0x7c08,
- 0x6800, 0x0000, 0x0000, 0x305c,
- 0x7c08, 0x6808, 0x0000, 0x0000,
- 0xae06, 0x7c02, 0x5c02, 0x0000,
- 0x0000, 0x3067, 0x8e05, 0x7c02,
- 0x5c00, 0x0000, 0x0000, 0xad06,
- 0x7c20, 0x5c20, 0x0000, 0x0000,
- 0x3072, 0x8d05, 0x7c20, 0x5c00,
- 0x0000, 0x0000, 0xa008, 0x7c07,
- 0x6800, 0xb8db, 0x7c07, 0x6803,
- 0xd9b3, 0x00d7, 0x7fe0, 0x4c80,
- 0x7c08, 0x6800, 0x0000, 0x0000,
- 0x7c23, 0x5c23, 0x481d, 0x7c1f,
- 0x4c00, 0x7c1f, 0x4c02, 0x5310,
- 0x81ff, 0x30f5, 0x7fe0, 0x4d00,
- 0x4832, 0x7c1f, 0x4c00, 0x7c1f,
- 0x4c10, 0x7c08, 0x6000, 0xa49e,
- 0x7c07, 0x6800, 0xb89b, 0x7c07,
- 0x6803, 0xd9b3, 0x00f9, 0x7fe0,
- 0x4d20, 0x7e00, 0x6200, 0x3001,
- 0x7fe0, 0x4dc0, 0xd09d, 0x0002,
- 0xb4fe, 0x7fe0, 0x4d80, 0x7c04,
- 0x6004, 0x7c07, 0x6802, 0x6728,
- 0x0000, 0x0000, 0x7c08, 0x6000,
- 0x486c, 0x7c1f, 0x4c00, 0x7c1f,
- 0x4c01, 0x9503, 0x7e00, 0x6200,
- 0x571f, 0x5fbb, 0xaa05, 0x5b58,
- 0x7d80, 0x6100, 0x30c2, 0x5b64,
- 0x7d80, 0x6080, 0xcdab, 0x0063,
- 0xcd8d, 0x0061, 0xd96b, 0x005f,
- 0xd0a0, 0x00d7, 0xcba0, 0x0003,
- 0x80ec, 0x30cf, 0x30dc, 0x7fe0,
- 0x4ce0, 0x4832, 0x7c1f, 0x4c00,
- 0x7c1f, 0x4c08, 0x7c08, 0x6008,
- 0x8300, 0xb902, 0x30a5, 0x308a,
- 0x7fe0, 0x4da0, 0x65a8, 0x0000,
- 0x0000, 0x56a0, 0x590c, 0x7ffd,
- 0x5fa2, 0xae06, 0x7c02, 0x5c02,
- 0x0000, 0x0000, 0x30f0, 0x8e05,
- 0x7c02, 0x5c00, 0x0000, 0x0000,
- 0xcba4, 0x0004, 0xcd8d, 0x0002,
- 0x80f1, 0x7fe0, 0x4ca0, 0x7c08,
- 0x6408, 0x0000, 0x0000, 0x7d00,
- 0x6800, 0xb603, 0x7c10, 0x6010,
- 0x7d1f, 0x551f, 0x5fb3, 0xaa07,
- 0x7c80, 0x5800, 0x5b58, 0x7d80,
- 0x6100, 0x310f, 0x7c80, 0x5800,
- 0x5b64, 0x7d80, 0x6080, 0x4827,
- 0x7c1f, 0x4c00, 0x7c1f, 0x4c10,
- 0x8400, 0x7c10, 0x6000, 0x7fe0,
- 0x4cc0, 0x5fbb, 0x4824, 0x7c1f,
- 0x4c00, 0x7c1f, 0x4c04, 0x8200,
- 0x7ce0, 0x5400, 0x6728, 0x0000,
- 0x0000, 0x30cf, 0x3001, 0x7fe0,
- 0x4e00, 0x4007, 0x4400, 0x5310,
- 0x7c07, 0x6800, 0x673e, 0x0000,
- 0x0000, 0x570f, 0x5fff, 0xaa05,
- 0x585b, 0x7d80, 0x6100, 0x313b,
- 0x5867, 0x7d80, 0x6080, 0x9403,
- 0x7e00, 0x6200, 0xcda3, 0x00e7,
- 0xcd85, 0x00e5, 0xd96b, 0x00e3,
- 0x96e3, 0x7c07, 0x6800, 0x673e,
- 0x0000, 0x0000, 0x7fe0, 0x4e20,
- 0x96db, 0x8b04, 0x7c08, 0x5008,
- 0xab03, 0x7c08, 0x5000, 0x7c07,
- 0x6801, 0x677e, 0x0000, 0x0000,
- 0xdb7c, 0x00ec, 0x0000, 0x7fe1,
- 0x4f40, 0x4837, 0x4418, 0x41c7,
- 0x7fe0, 0x4e40, 0x7c40, 0x5400,
- 0x7c1f, 0x4c01, 0x7c1f, 0x4c01,
- 0x8fbf, 0xd2a0, 0x004b, 0x9204,
- 0xa042, 0x3168, 0x3127, 0x7fe1,
- 0x4f60, 0x489c, 0x4628, 0x7fe0,
- 0x4e60, 0x7e28, 0x4628, 0x7c40,
- 0x5400, 0x7c01, 0x5800, 0x7c04,
- 0x5c00, 0x41e8, 0x7c1f, 0x4c01,
- 0x7c1f, 0x4c01, 0x8fa5, 0xb241,
- 0xa02a, 0x3182, 0x7fe0, 0x4ea0,
- 0x7c02, 0x4402, 0x4448, 0x4894,
- 0x7c1f, 0x4c01, 0x7c1f, 0x4c03,
- 0x4824, 0x7c1f, 0x4c07, 0x41ef,
- 0x41ff, 0x4891, 0x7c1f, 0x4c07,
- 0x7c1f, 0x4c17, 0x8400, 0x8ef8,
- 0x41c7, 0x8f8a, 0x92d5, 0xa10f,
- 0xd480, 0x0008, 0xd580, 0x00b8,
- 0xa202, 0x319d, 0x7c04, 0x4404,
- 0x319d, 0xd484, 0x00f3, 0xd484,
- 0x00f1, 0x3127, 0x7fe0, 0x4ee0,
- 0x7c40, 0x5400, 0x4488, 0x41cf,
- 0x3127, 0x7fe0, 0x4ec0, 0x48f3,
- 0x7c1f, 0x4c01, 0x7c1f, 0x4c09,
- 0x4508, 0x41c7, 0x8fb0, 0xd218,
- 0x00ae, 0xd2a4, 0x009e, 0x31be,
- 0x7fe0, 0x4e80, 0x4832, 0x7c1f,
- 0x4c01, 0x7c1f, 0x4c11, 0x4428,
- 0x7c40, 0x5440, 0x7c01, 0x5801,
- 0x7c04, 0x5c04, 0x41e8, 0xa4b3,
- 0x31d3, 0x7fe0, 0x4f20, 0x7c07,
- 0x6800, 0x673e, 0x0000, 0x0000,
- 0x570f, 0x5fff, 0xaa04, 0x585b,
- 0x6100, 0x31e4, 0x5867, 0x6080,
- 0xbcf1, 0x3001 };
-
- generic_ocp_write(tp, 0xf800, 0x3f, sizeof(pla_patch_a),
- pla_patch_a, MCU_TYPE_PLA);
-
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc26, 0x8000);
-
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc28, 0x170b);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2a, 0x01e1);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2c, 0x0989);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2e, 0x1349);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc30, 0x01b7);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc32, 0x061d);
-
- ocp_write_word(tp, MCU_TYPE_PLA, 0xe422, 0x0020);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xe420, 0x0018);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc34, 0x1785);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc36, 0x047b);
-
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, 0x2000);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb092, 0x7070);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb098, 0x0600);
- for (i = 0; i < ARRAY_SIZE(ram_code1); i++) {
- __le32 ocp_data;
-
- ocp_data = __cpu_to_le32(ram_code1[i] << 16);
- pla_ocp_write(tp, 0xb098, 0xcc, sizeof(ocp_data),
- &ocp_data);
- }
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb098, 0x0200);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb092, 0x7030);
- } else if (tp->version == RTL_VER_02) {
- static u8 pla_patch_a2[] = {
- 0x08, 0xe0, 0x1a, 0xe0,
- 0xf2, 0xe0, 0xfa, 0xe0,
- 0x32, 0xe1, 0x34, 0xe1,
- 0x36, 0xe1, 0x38, 0xe1,
- 0x2c, 0x75, 0xdc, 0x21,
- 0xbc, 0x25, 0x04, 0x13,
- 0x0b, 0xf0, 0x03, 0x13,
- 0x09, 0xf0, 0x02, 0x13,
- 0x07, 0xf0, 0x01, 0x13,
- 0x05, 0xf0, 0x08, 0x13,
- 0x03, 0xf0, 0x04, 0xc3,
- 0x00, 0xbb, 0x03, 0xc3,
- 0x00, 0xbb, 0xd2, 0x17,
- 0xbc, 0x17, 0x14, 0xc2,
- 0x40, 0x73, 0xba, 0x48,
- 0x40, 0x9b, 0x11, 0xc2,
- 0x40, 0x73, 0xb0, 0x49,
- 0x17, 0xf0, 0xbf, 0x49,
- 0x03, 0xf1, 0x09, 0xc5,
- 0x00, 0xbd, 0xb1, 0x49,
- 0x11, 0xf0, 0xb1, 0x48,
- 0x40, 0x9b, 0x02, 0xc2,
- 0x00, 0xba, 0x4e, 0x19,
- 0x00, 0xa0, 0x1e, 0xfc,
- 0xbc, 0xc0, 0xf0, 0xc0,
- 0xde, 0xe8, 0x00, 0x80,
- 0x00, 0x60, 0x2c, 0x75,
- 0xd4, 0x49, 0x12, 0xf1,
- 0x29, 0xe0, 0xf8, 0xc2,
- 0x46, 0x71, 0xf7, 0xc2,
- 0x40, 0x73, 0xbe, 0x49,
- 0x03, 0xf1, 0xf5, 0xc7,
- 0x02, 0xe0, 0xf2, 0xc7,
- 0x4f, 0x30, 0x26, 0x62,
- 0xa1, 0x49, 0xf0, 0xf1,
- 0x22, 0x72, 0xa0, 0x49,
- 0xed, 0xf1, 0x25, 0x25,
- 0x18, 0x1f, 0x97, 0x30,
- 0x91, 0x30, 0x36, 0x9a,
- 0x2c, 0x75, 0x32, 0xc3,
- 0x60, 0x73, 0xb1, 0x49,
- 0x0d, 0xf1, 0xdc, 0x21,
- 0xbc, 0x25, 0x27, 0xc6,
- 0xc0, 0x77, 0x04, 0x13,
- 0x18, 0xf0, 0x03, 0x13,
- 0x19, 0xf0, 0x02, 0x13,
- 0x1a, 0xf0, 0x01, 0x13,
- 0x1b, 0xf0, 0xd4, 0x49,
- 0x03, 0xf1, 0x1c, 0xc5,
- 0x00, 0xbd, 0xcd, 0xc6,
- 0xc6, 0x67, 0x2e, 0x75,
- 0xd7, 0x22, 0xdd, 0x26,
- 0x05, 0x15, 0x1a, 0xf0,
- 0x14, 0xc6, 0x00, 0xbe,
- 0x13, 0xc5, 0x00, 0xbd,
- 0x12, 0xc5, 0x00, 0xbd,
- 0xf1, 0x49, 0xfb, 0xf1,
- 0xef, 0xe7, 0xf4, 0x49,
- 0xfa, 0xf1, 0xec, 0xe7,
- 0xf3, 0x49, 0xf7, 0xf1,
- 0xe9, 0xe7, 0xf2, 0x49,
- 0xf4, 0xf1, 0xe6, 0xe7,
- 0xb6, 0xc0, 0xf6, 0x14,
- 0x36, 0x14, 0x62, 0x14,
- 0x86, 0x15, 0xa0, 0xd1,
- 0x00, 0x00, 0xc0, 0x75,
- 0xd0, 0x49, 0x46, 0xf0,
- 0x26, 0x72, 0xa7, 0x49,
- 0x43, 0xf0, 0x22, 0x72,
- 0x25, 0x25, 0x20, 0x1f,
- 0x97, 0x30, 0x91, 0x30,
- 0x40, 0x73, 0xf3, 0xc4,
- 0x1c, 0x40, 0x04, 0xf0,
- 0xd7, 0x49, 0x05, 0xf1,
- 0x37, 0xe0, 0x53, 0x48,
- 0xc0, 0x9d, 0x08, 0x02,
- 0x40, 0x66, 0x64, 0x27,
- 0x06, 0x16, 0x30, 0xf1,
- 0x46, 0x63, 0x3b, 0x13,
- 0x2d, 0xf1, 0x34, 0x9b,
- 0x18, 0x1b, 0x93, 0x30,
- 0x2b, 0xc3, 0x10, 0x1c,
- 0x2b, 0xe8, 0x01, 0x14,
- 0x25, 0xf1, 0x00, 0x1d,
- 0x26, 0x1a, 0x8a, 0x30,
- 0x22, 0x73, 0xb5, 0x25,
- 0x0e, 0x0b, 0x00, 0x1c,
- 0x2c, 0xe8, 0x1f, 0xc7,
- 0x27, 0x40, 0x1a, 0xf1,
- 0x38, 0xe8, 0x32, 0x1f,
- 0x8f, 0x30, 0x08, 0x1b,
- 0x24, 0xe8, 0x36, 0x72,
- 0x46, 0x77, 0x00, 0x17,
- 0x0d, 0xf0, 0x13, 0xc3,
- 0x1f, 0x40, 0x03, 0xf1,
- 0x00, 0x1f, 0x46, 0x9f,
- 0x44, 0x77, 0x9f, 0x44,
- 0x5f, 0x44, 0x17, 0xe8,
- 0x0a, 0xc7, 0x27, 0x40,
- 0x05, 0xf1, 0x02, 0xc3,
- 0x00, 0xbb, 0x1c, 0x1b,
- 0xd2, 0x1a, 0xff, 0xc7,
- 0x00, 0xbf, 0xb8, 0xcd,
- 0xff, 0xff, 0x02, 0x0c,
- 0x54, 0xa5, 0xdc, 0xa5,
- 0x2f, 0x40, 0x05, 0xf1,
- 0x00, 0x14, 0xfa, 0xf1,
- 0x01, 0x1c, 0x02, 0xe0,
- 0x00, 0x1c, 0x80, 0xff,
- 0xb0, 0x49, 0x04, 0xf0,
- 0x01, 0x0b, 0xd3, 0xa1,
- 0x03, 0xe0, 0x02, 0x0b,
- 0xd3, 0xa5, 0x27, 0x31,
- 0x20, 0x37, 0x02, 0x0b,
- 0xd3, 0xa5, 0x27, 0x31,
- 0x20, 0x37, 0x00, 0x13,
- 0xfb, 0xf1, 0x80, 0xff,
- 0x22, 0x73, 0xb5, 0x25,
- 0x18, 0x1e, 0xde, 0x30,
- 0xd9, 0x30, 0x64, 0x72,
- 0x11, 0x1e, 0x68, 0x23,
- 0x16, 0x31, 0x80, 0xff,
- 0x08, 0xc2, 0x40, 0x73,
- 0x3a, 0x48, 0x40, 0x9b,
- 0x06, 0xff, 0x02, 0xc6,
- 0x00, 0xbe, 0x4e, 0x18,
- 0x1e, 0xfc, 0x33, 0xc5,
- 0xa0, 0x74, 0xc0, 0x49,
- 0x1f, 0xf0, 0x30, 0xc5,
- 0xa0, 0x73, 0x00, 0x13,
- 0x04, 0xf1, 0xa2, 0x73,
- 0x00, 0x13, 0x14, 0xf0,
- 0x28, 0xc5, 0xa0, 0x74,
- 0xc8, 0x49, 0x1b, 0xf1,
- 0x26, 0xc5, 0xa0, 0x76,
- 0xa2, 0x74, 0x01, 0x06,
- 0x20, 0x37, 0xa0, 0x9e,
- 0xa2, 0x9c, 0x1e, 0xc5,
- 0xa2, 0x73, 0x23, 0x40,
- 0x10, 0xf8, 0x04, 0xf3,
- 0xa0, 0x73, 0x33, 0x40,
- 0x0c, 0xf8, 0x15, 0xc5,
- 0xa0, 0x74, 0x41, 0x48,
- 0xa0, 0x9c, 0x14, 0xc5,
- 0xa0, 0x76, 0x62, 0x48,
- 0xe0, 0x48, 0xa0, 0x9e,
- 0x10, 0xc6, 0x00, 0xbe,
- 0x0a, 0xc5, 0xa0, 0x74,
- 0x48, 0x48, 0xa0, 0x9c,
- 0x0b, 0xc5, 0x20, 0x1e,
- 0xa0, 0x9e, 0xe5, 0x48,
- 0xa0, 0x9e, 0xf0, 0xe7,
- 0xbc, 0xc0, 0xc8, 0xd2,
- 0xcc, 0xd2, 0x28, 0xe4,
- 0x22, 0x02, 0xf0, 0xc0,
- 0x02, 0xc6, 0x00, 0xbe,
- 0x00, 0x00, 0x02, 0xc6,
- 0x00, 0xbe, 0x00, 0x00,
- 0x02, 0xc6, 0x00, 0xbe,
- 0x00, 0x00, 0x02, 0xc6,
- 0x00, 0xbe, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00 };
-
- generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch_a2),
- pla_patch_a2, MCU_TYPE_PLA);
-
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc26, 0x8000);
-
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc28, 0x17a5);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2a, 0x13ad);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2c, 0x1840);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2e, 0x01e1);
- }
-}
-
-static void r8152b_disable_aldps(struct r8152 *tp)
-{
- ocp_reg_write(tp, OCP_ALDPS_CONFIG, ENPDNPS | LINKENA | DIS_SDSAVE);
- msleep(20);
-}
-
-static inline void r8152b_enable_aldps(struct r8152 *tp)
-{
- ocp_reg_write(tp, OCP_ALDPS_CONFIG, ENPWRSAVE | ENPDNPS |
- LINKENA | DIS_SDSAVE);
-}
-
-static void rtl8152_disable(struct r8152 *tp)
-{
- r8152b_disable_aldps(tp);
- rtl_disable(tp);
- r8152b_enable_aldps(tp);
-}
-
-static void r8152b_hw_phy_cfg(struct r8152 *tp)
-{
- u16 data;
-
- data = r8152_mdio_read(tp, MII_BMCR);
- if (data & BMCR_PDOWN) {
- data &= ~BMCR_PDOWN;
- r8152_mdio_write(tp, MII_BMCR, data);
- }
-
- r8152b_firmware(tp);
-
- set_bit(PHY_RESET, &tp->flags);
-}
-
-static void r8152b_exit_oob(struct r8152 *tp)
-{
- u32 ocp_data;
- int i;
-
- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
- ocp_data &= ~RCR_ACPT_ALL;
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
-
- rxdy_gated_en(tp, true);
- r8153_teredo_off(tp);
- r8152b_hw_phy_cfg(tp);
-
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML);
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, 0x00);
-
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- ocp_data &= ~NOW_IS_OOB;
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7);
- ocp_data &= ~MCU_BORW_EN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data);
-
- for (i = 0; i < 1000; i++) {
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- if (ocp_data & LINK_LIST_READY)
- break;
- usleep_range(1000, 2000);
- }
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7);
- ocp_data |= RE_INIT_LL;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data);
-
- for (i = 0; i < 1000; i++) {
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- if (ocp_data & LINK_LIST_READY)
- break;
- usleep_range(1000, 2000);
- }
-
- rtl8152_nic_reset(tp);
-
- /* rx share fifo credit full threshold */
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_NORMAL);
-
- if (tp->udev->speed == USB_SPEED_FULL ||
- tp->udev->speed == USB_SPEED_LOW) {
- /* rx share fifo credit near full threshold */
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1,
- RXFIFO_THR2_FULL);
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2,
- RXFIFO_THR3_FULL);
- } else {
- /* rx share fifo credit near full threshold */
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1,
- RXFIFO_THR2_HIGH);
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2,
- RXFIFO_THR3_HIGH);
- }
-
- /* TX share fifo free credit full threshold */
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, TXFIFO_THR_NORMAL);
-
- ocp_write_byte(tp, MCU_TYPE_USB, USB_TX_AGG, TX_AGG_MAX_THRESHOLD);
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_HIGH);
- ocp_write_dword(tp, MCU_TYPE_USB, USB_TX_DMA,
- TEST_MODE_DISABLE | TX_SIZE_ADJUST1);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR);
- ocp_data &= ~CPCR_RX_VLAN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data);
-
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0);
- ocp_data |= TCR0_AUTO_FIFO;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR0, ocp_data);
-}
-
-static void r8152b_enter_oob(struct r8152 *tp)
-{
- u32 ocp_data;
- int i;
-
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- ocp_data &= ~NOW_IS_OOB;
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
-
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_OOB);
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, RXFIFO_THR2_OOB);
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, RXFIFO_THR3_OOB);
-
- rtl_disable(tp);
-
- for (i = 0; i < 1000; i++) {
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- if (ocp_data & LINK_LIST_READY)
- break;
- usleep_range(1000, 2000);
- }
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7);
- ocp_data |= RE_INIT_LL;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data);
-
- for (i = 0; i < 1000; i++) {
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- if (ocp_data & LINK_LIST_READY)
- break;
- usleep_range(1000, 2000);
- }
-
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR);
- ocp_data |= CPCR_RX_VLAN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PAL_BDC_CR);
- ocp_data |= ALDPS_PROXY_MODE;
- ocp_write_word(tp, MCU_TYPE_PLA, PAL_BDC_CR, ocp_data);
-
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB;
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
-
- rxdy_gated_en(tp, false);
-
- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
- ocp_data |= RCR_APM | RCR_AM | RCR_AB;
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
-}
-
-static void r8153_firmware(struct r8152 *tp)
-{
- u16 data;
-
- r8153_clear_bp(tp);
-
- if (tp->version == RTL_VER_03) {
- data = ocp_reg_read(tp, 0xb820);
- data |= 0x0010;
- ocp_reg_write(tp, 0xb820, data);
- while ((ocp_reg_read(tp, 0xb800) & 0x0040) == 0);
- ocp_reg_write(tp, 0xa436, 0x8146);
- ocp_reg_write(tp, 0xa438, 0x7000);
- ocp_reg_write(tp, 0xa436, 0xb82e);
- ocp_reg_write(tp, 0xa438, 0x0001);
- tp->ocp_base = 0xa000;
- ocp_write_word(tp, MCU_TYPE_PLA, 0xe86c, 0xa000);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb436, 0xb820);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x0290);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb436, 0xa012);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x0000);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb436, 0xa014);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x2c04);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x2c18);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x2c45);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x2c45);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd502);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x8301);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x8306);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd500);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x8208);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd501);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xe018);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x0308);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x60f2);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x8404);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x607d);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xc117);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x2c16);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xc116);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x2c16);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x607d);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xc117);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xa404);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd500);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x0800);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd501);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x62d2);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x615d);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xc115);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xa404);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xc307);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd502);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x8301);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x8306);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd500);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x8208);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x2c42);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xc114);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x8404);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xc317);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd701);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x435d);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd500);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xa208);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd502);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xa306);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xa301);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x2c42);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x8404);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x613d);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xc115);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xc307);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd502);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x8301);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x8306);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd500);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x8208);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x2c42);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xc114);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xc317);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd701);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x40dd);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd500);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xa208);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd502);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xa306);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xa301);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd500);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0xd702);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x0800);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb436, 0xa01a);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x0000);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb436, 0xa006);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x0fff);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb436, 0xa004);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x0fff);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb436, 0xa002);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x05a3);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb436, 0xa000);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x3591);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb436, 0xb820);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xb438, 0x0210);
- ocp_reg_write(tp, 0xa436, 0x0000);
- ocp_reg_write(tp, 0xa438, 0x0000);
- data = ocp_reg_read(tp, 0xb82e);
- data &= ~0x0001;
- ocp_reg_write(tp, 0xb82e, data);
- ocp_reg_write(tp, 0xa436, 0x8146);
- ocp_reg_write(tp, 0xa438, 0x0000);
-
- data = ocp_reg_read(tp, 0xb820);
- data &= ~0x0010;
- ocp_reg_write(tp, 0xb820, data);
- } else if (tp->version == RTL_VER_04) {
- static u8 usb_patch_b[] = {
- 0x08, 0xe0, 0x0f, 0xe0,
- 0x18, 0xe0, 0x24, 0xe0,
- 0x26, 0xe0, 0x3a, 0xe0,
- 0x84, 0xe0, 0x9c, 0xe0,
- 0xc2, 0x49, 0x04, 0xf0,
- 0x02, 0xc0, 0x00, 0xb8,
- 0x14, 0x18, 0x02, 0xc0,
- 0x00, 0xb8, 0x2e, 0x18,
- 0x06, 0x89, 0x08, 0xc0,
- 0x0c, 0x61, 0x92, 0x48,
- 0x93, 0x48, 0x0c, 0x89,
- 0x02, 0xc0, 0x00, 0xb8,
- 0x08, 0x05, 0x40, 0xb4,
- 0x16, 0x89, 0x6d, 0xc0,
- 0x00, 0x61, 0x95, 0x49,
- 0x06, 0xf0, 0xfa, 0xc0,
- 0x0c, 0x61, 0x92, 0x48,
- 0x93, 0x48, 0x0c, 0x89,
- 0x02, 0xc0, 0x00, 0xb8,
- 0xe2, 0x04, 0x02, 0xc2,
- 0x00, 0xba, 0xec, 0x11,
- 0x60, 0x60, 0x85, 0x49,
- 0x0d, 0xf1, 0x11, 0xc6,
- 0xd2, 0x61, 0x91, 0x49,
- 0xfd, 0xf0, 0x74, 0x60,
- 0x04, 0x48, 0x74, 0x88,
- 0x08, 0xc6, 0x08, 0xc0,
- 0xc4, 0x98, 0x01, 0x18,
- 0xc0, 0x88, 0x02, 0xc0,
- 0x00, 0xb8, 0x6e, 0x12,
- 0x04, 0xe4, 0x0d, 0x00,
- 0x00, 0xd4, 0xd1, 0x49,
- 0x3c, 0xf1, 0xd2, 0x49,
- 0x16, 0xf1, 0xd3, 0x49,
- 0x18, 0xf1, 0xd4, 0x49,
- 0x19, 0xf1, 0xd5, 0x49,
- 0x1a, 0xf1, 0xd6, 0x49,
- 0x1b, 0xf1, 0xd7, 0x49,
- 0x1c, 0xf1, 0xd8, 0x49,
- 0x1d, 0xf1, 0xd9, 0x49,
- 0x20, 0xf1, 0xda, 0x49,
- 0x23, 0xf1, 0xdb, 0x49,
- 0x24, 0xf1, 0x02, 0xc4,
- 0x00, 0xbc, 0x20, 0x04,
- 0xe5, 0x8e, 0x02, 0xc4,
- 0x00, 0xbc, 0x14, 0x02,
- 0x02, 0xc4, 0x00, 0xbc,
- 0x16, 0x02, 0x02, 0xc4,
- 0x00, 0xbc, 0x18, 0x02,
- 0x02, 0xc4, 0x00, 0xbc,
- 0x1a, 0x02, 0x02, 0xc4,
- 0x00, 0xbc, 0x1c, 0x02,
- 0x02, 0xc4, 0x00, 0xbc,
- 0x94, 0x02, 0x10, 0xc7,
- 0xe0, 0x8e, 0x02, 0xc4,
- 0x00, 0xbc, 0x8a, 0x02,
- 0x0b, 0xc7, 0xe4, 0x8e,
- 0x02, 0xc4, 0x00, 0xbc,
- 0x88, 0x02, 0x02, 0xc4,
- 0x00, 0xbc, 0x6e, 0x02,
- 0x02, 0xc4, 0x00, 0xbc,
- 0x5a, 0x02, 0x30, 0xe4,
- 0x0c, 0xc3, 0x60, 0x64,
- 0xc5, 0x49, 0x04, 0xf1,
- 0x74, 0x64, 0xc4, 0x48,
- 0x74, 0x8c, 0x06, 0xc3,
- 0x64, 0x8e, 0x02, 0xc4,
- 0x00, 0xbc, 0x20, 0x04,
- 0x00, 0xd8, 0x00, 0xe4,
- 0xb2, 0xc0, 0x00, 0x61,
- 0x90, 0x49, 0x09, 0xf1,
- 0x8b, 0xc6, 0xca, 0x61,
- 0x94, 0x49, 0x0e, 0xf1,
- 0xf6, 0xc6, 0xda, 0x60,
- 0x81, 0x49, 0x0a, 0xf0,
- 0x65, 0x60, 0x03, 0x48,
- 0x65, 0x88, 0xef, 0xc6,
- 0xdc, 0x60, 0x80, 0x48,
- 0xdc, 0x88, 0x05, 0xc6,
- 0x00, 0xbe, 0x02, 0xc6,
- 0x00, 0xbe, 0x36, 0x13,
- 0x4c, 0x17, 0x99, 0xc4,
- 0x80, 0x65, 0xd0, 0x49,
- 0x04, 0xf1, 0xfa, 0x75,
- 0x04, 0xc4, 0x00, 0xbc,
- 0x03, 0xc4, 0x00, 0xbc,
- 0x9a, 0x00, 0xee, 0x01 };
- static u8 pla_patch_b[] = {
- 0x08, 0xe0, 0xea, 0xe0,
- 0xf2, 0xe0, 0x04, 0xe1,
- 0x09, 0xe1, 0x0e, 0xe1,
- 0x46, 0xe1, 0xab, 0xe1,
- 0x14, 0xc2, 0x40, 0x73,
- 0xba, 0x48, 0x40, 0x9b,
- 0x11, 0xc2, 0x40, 0x73,
- 0xb0, 0x49, 0x17, 0xf0,
- 0xbf, 0x49, 0x03, 0xf1,
- 0x09, 0xc5, 0x00, 0xbd,
- 0xb1, 0x49, 0x11, 0xf0,
- 0xb1, 0x48, 0x40, 0x9b,
- 0x02, 0xc2, 0x00, 0xba,
- 0x1a, 0x17, 0x00, 0xe0,
- 0x1e, 0xfc, 0xbc, 0xc0,
- 0xf0, 0xc0, 0xde, 0xe8,
- 0x00, 0x80, 0x00, 0x20,
- 0x2c, 0x75, 0xd4, 0x49,
- 0x12, 0xf1, 0x32, 0xe0,
- 0xf8, 0xc2, 0x46, 0x71,
- 0xf7, 0xc2, 0x40, 0x73,
- 0xbe, 0x49, 0x03, 0xf1,
- 0xf5, 0xc7, 0x02, 0xe0,
- 0xf2, 0xc7, 0x4f, 0x30,
- 0x26, 0x62, 0xa1, 0x49,
- 0xf0, 0xf1, 0x22, 0x72,
- 0xa0, 0x49, 0xed, 0xf1,
- 0x25, 0x25, 0x18, 0x1f,
- 0x97, 0x30, 0x91, 0x30,
- 0x36, 0x9a, 0x2c, 0x75,
- 0x3c, 0xc3, 0x60, 0x73,
- 0xb1, 0x49, 0x0d, 0xf1,
- 0xdc, 0x21, 0xbc, 0x25,
- 0x30, 0xc6, 0xc0, 0x77,
- 0x04, 0x13, 0x21, 0xf0,
- 0x03, 0x13, 0x22, 0xf0,
- 0x02, 0x13, 0x23, 0xf0,
- 0x01, 0x13, 0x24, 0xf0,
- 0x08, 0x13, 0x08, 0xf1,
- 0x2e, 0x73, 0xba, 0x21,
- 0xbd, 0x25, 0x05, 0x13,
- 0x03, 0xf1, 0x24, 0xc5,
- 0x00, 0xbd, 0xd4, 0x49,
- 0x03, 0xf1, 0x1c, 0xc5,
- 0x00, 0xbd, 0xc4, 0xc6,
- 0xc6, 0x67, 0x2e, 0x75,
- 0xd7, 0x22, 0xdd, 0x26,
- 0x05, 0x15, 0x1b, 0xf0,
- 0x14, 0xc6, 0x00, 0xbe,
- 0x13, 0xc5, 0x00, 0xbd,
- 0x12, 0xc5, 0x00, 0xbd,
- 0xf1, 0x49, 0xfb, 0xf1,
- 0xef, 0xe7, 0xf4, 0x49,
- 0xfa, 0xf1, 0xec, 0xe7,
- 0xf3, 0x49, 0xf7, 0xf1,
- 0xe9, 0xe7, 0xf2, 0x49,
- 0xf4, 0xf1, 0xe6, 0xe7,
- 0xb6, 0xc0, 0x9e, 0x12,
- 0xde, 0x11, 0x0a, 0x12,
- 0x3c, 0x13, 0x00, 0xa0,
- 0xa0, 0xd1, 0x00, 0x00,
- 0xc0, 0x75, 0xd0, 0x49,
- 0x46, 0xf0, 0x26, 0x72,
- 0xa7, 0x49, 0x43, 0xf0,
- 0x22, 0x72, 0x25, 0x25,
- 0x20, 0x1f, 0x97, 0x30,
- 0x91, 0x30, 0x40, 0x73,
- 0xf3, 0xc4, 0x1c, 0x40,
- 0x04, 0xf0, 0xd7, 0x49,
- 0x05, 0xf1, 0x37, 0xe0,
- 0x53, 0x48, 0xc0, 0x9d,
- 0x08, 0x02, 0x40, 0x66,
- 0x64, 0x27, 0x06, 0x16,
- 0x30, 0xf1, 0x46, 0x63,
- 0x3b, 0x13, 0x2d, 0xf1,
- 0x34, 0x9b, 0x18, 0x1b,
- 0x93, 0x30, 0x2b, 0xc3,
- 0x10, 0x1c, 0x2b, 0xe8,
- 0x01, 0x14, 0x25, 0xf1,
- 0x00, 0x1d, 0x26, 0x1a,
- 0x8a, 0x30, 0x22, 0x73,
- 0xb5, 0x25, 0x0e, 0x0b,
- 0x00, 0x1c, 0x2c, 0xe8,
- 0x1f, 0xc7, 0x27, 0x40,
- 0x1a, 0xf1, 0x38, 0xe8,
- 0x32, 0x1f, 0x8f, 0x30,
- 0x08, 0x1b, 0x24, 0xe8,
- 0x36, 0x72, 0x46, 0x77,
- 0x00, 0x17, 0x0d, 0xf0,
- 0x13, 0xc3, 0x1f, 0x40,
- 0x03, 0xf1, 0x00, 0x1f,
- 0x46, 0x9f, 0x44, 0x77,
- 0x9f, 0x44, 0x5f, 0x44,
- 0x17, 0xe8, 0x0a, 0xc7,
- 0x27, 0x40, 0x05, 0xf1,
- 0x02, 0xc3, 0x00, 0xbb,
- 0xfa, 0x18, 0xb0, 0x18,
- 0xff, 0xc7, 0x00, 0xbf,
- 0xb8, 0xcd, 0xff, 0xff,
- 0x02, 0x0c, 0x54, 0xa5,
- 0xdc, 0xa5, 0x2f, 0x40,
- 0x05, 0xf1, 0x00, 0x14,
- 0xfa, 0xf1, 0x01, 0x1c,
- 0x02, 0xe0, 0x00, 0x1c,
- 0x80, 0xff, 0xb0, 0x49,
- 0x04, 0xf0, 0x01, 0x0b,
- 0xd3, 0xa1, 0x03, 0xe0,
- 0x02, 0x0b, 0xd3, 0xa5,
- 0x27, 0x31, 0x20, 0x37,
- 0x02, 0x0b, 0xd3, 0xa5,
- 0x27, 0x31, 0x20, 0x37,
- 0x00, 0x13, 0xfb, 0xf1,
- 0x80, 0xff, 0x22, 0x73,
- 0xb5, 0x25, 0x18, 0x1e,
- 0xde, 0x30, 0xd9, 0x30,
- 0x64, 0x72, 0x11, 0x1e,
- 0x68, 0x23, 0x16, 0x31,
- 0x80, 0xff, 0x08, 0xc2,
- 0x40, 0x73, 0x3a, 0x48,
- 0x40, 0x9b, 0x06, 0xff,
- 0x02, 0xc6, 0x00, 0xbe,
- 0x08, 0x16, 0x1e, 0xfc,
- 0x2c, 0x75, 0xdc, 0x21,
- 0xbc, 0x25, 0x04, 0x13,
- 0x0b, 0xf0, 0x03, 0x13,
- 0x09, 0xf0, 0x02, 0x13,
- 0x07, 0xf0, 0x01, 0x13,
- 0x05, 0xf0, 0x08, 0x13,
- 0x03, 0xf0, 0x04, 0xc3,
- 0x00, 0xbb, 0x03, 0xc3,
- 0x00, 0xbb, 0x8c, 0x15,
- 0x76, 0x15, 0xa0, 0x64,
- 0x40, 0x48, 0xa0, 0x8c,
- 0x02, 0xc4, 0x00, 0xbc,
- 0x82, 0x00, 0xa0, 0x62,
- 0x21, 0x48, 0xa0, 0x8a,
- 0x02, 0xc2, 0x00, 0xba,
- 0x40, 0x03, 0x33, 0xc5,
- 0xa0, 0x74, 0xc0, 0x49,
- 0x1f, 0xf0, 0x30, 0xc5,
- 0xa0, 0x73, 0x00, 0x13,
- 0x04, 0xf1, 0xa2, 0x73,
- 0x00, 0x13, 0x14, 0xf0,
- 0x28, 0xc5, 0xa0, 0x74,
- 0xc8, 0x49, 0x1b, 0xf1,
- 0x26, 0xc5, 0xa0, 0x76,
- 0xa2, 0x74, 0x01, 0x06,
- 0x20, 0x37, 0xa0, 0x9e,
- 0xa2, 0x9c, 0x1e, 0xc5,
- 0xa2, 0x73, 0x23, 0x40,
- 0x10, 0xf8, 0x04, 0xf3,
- 0xa0, 0x73, 0x33, 0x40,
- 0x0c, 0xf8, 0x15, 0xc5,
- 0xa0, 0x74, 0x41, 0x48,
- 0xa0, 0x9c, 0x14, 0xc5,
- 0xa0, 0x76, 0x62, 0x48,
- 0xe0, 0x48, 0xa0, 0x9e,
- 0x10, 0xc6, 0x00, 0xbe,
- 0x0a, 0xc5, 0xa0, 0x74,
- 0x48, 0x48, 0xa0, 0x9c,
- 0x0b, 0xc5, 0x20, 0x1e,
- 0xa0, 0x9e, 0xe5, 0x48,
- 0xa0, 0x9e, 0xf0, 0xe7,
- 0xbc, 0xc0, 0xc8, 0xd2,
- 0xcc, 0xd2, 0x28, 0xe4,
- 0xe6, 0x01, 0xf0, 0xc0,
- 0x18, 0x89, 0x00, 0x1d,
- 0x5a, 0xc0, 0x5a, 0xc1,
- 0x02, 0x99, 0x00, 0x61,
- 0x67, 0x11, 0x35, 0xf1,
- 0x69, 0x33, 0x55, 0xc0,
- 0x28, 0x40, 0xf7, 0xf1,
- 0x54, 0xc0, 0x00, 0x19,
- 0x81, 0x1b, 0x44, 0xe8,
- 0x53, 0xc0, 0x04, 0x1a,
- 0x84, 0x1b, 0x40, 0xe8,
- 0x35, 0xe8, 0xa3, 0x49,
- 0xfe, 0xf0, 0x4a, 0xc0,
- 0x31, 0xe8, 0xa1, 0x48,
- 0x47, 0xc0, 0x84, 0x1b,
- 0x37, 0xe8, 0x00, 0x1d,
- 0x69, 0x33, 0x00, 0x1e,
- 0x01, 0x06, 0xff, 0x18,
- 0x30, 0x40, 0xfd, 0xf1,
- 0x40, 0xc0, 0x00, 0x76,
- 0x2e, 0x40, 0xf7, 0xf1,
- 0x21, 0x48, 0x38, 0xc0,
- 0x84, 0x1b, 0x28, 0xe8,
- 0x36, 0xc0, 0x1c, 0xe8,
- 0xa1, 0x49, 0xfd, 0xf0,
- 0x33, 0xc0, 0x00, 0x1a,
- 0x84, 0x1b, 0x20, 0xe8,
- 0x15, 0xe8, 0xa5, 0x49,
- 0xfe, 0xf0, 0x29, 0xc0,
- 0x01, 0x19, 0x81, 0x1b,
- 0x19, 0xe8, 0x0b, 0xe0,
- 0x9c, 0x20, 0x9c, 0x24,
- 0x06, 0x11, 0x07, 0xf1,
- 0x25, 0xc0, 0x08, 0xe8,
- 0x23, 0xc0, 0x12, 0x48,
- 0x81, 0x1b, 0x0e, 0xe8,
- 0x02, 0xc0, 0x00, 0xb8,
- 0x96, 0x07, 0x16, 0xc4,
- 0x84, 0x98, 0x00, 0x1b,
- 0x86, 0x8b, 0x86, 0x73,
- 0xbf, 0x49, 0xfe, 0xf1,
- 0x80, 0x71, 0x82, 0x72,
- 0x80, 0xff, 0x0c, 0xc4,
- 0x84, 0x98, 0x80, 0x99,
- 0x82, 0x9a, 0x86, 0x8b,
- 0x86, 0x73, 0xbf, 0x49,
- 0xfe, 0xf1, 0x80, 0xff,
- 0x50, 0xe8, 0x82, 0x00,
- 0xb8, 0x0b, 0x08, 0xea,
- 0x20, 0xb4, 0x84, 0xd4,
- 0x10, 0xd4, 0x10, 0xd8,
- 0x88, 0xd3, 0x30, 0xd4,
- 0x02, 0xc6, 0x00, 0xbe,
- 0x00, 0x00, 0x00, 0x00 };
-
- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x0000);
- generic_ocp_write(tp, 0xf800, 0xff, sizeof(usb_patch_b),
- usb_patch_b, MCU_TYPE_USB);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc26, 0xa000);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc28, 0x180c);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc2a, 0x0506);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc2c, 0x04E0);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc2e, 0x11E4);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc30, 0x125C);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc32, 0x0232);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc34, 0x131E);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc36, 0x0098);
- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x00FF);
-
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0000);
- generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch_b),
- pla_patch_b, MCU_TYPE_PLA);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc26, 0x8000);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc28, 0x1154);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2a, 0x1606);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2c, 0x155a);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2e, 0x0080);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc30, 0x033c);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc32, 0x01a0);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc34, 0x0794);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc36, 0x0000);
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x007f);
-
- ocp_write_word(tp, MCU_TYPE_PLA, 0xd388, 0x08ca);
- } else if (tp->version == RTL_VER_05) {
- u32 ocp_data;
- static u8 usb_patch_c[] = {
- 0x08, 0xe0, 0x0a, 0xe0,
- 0x14, 0xe0, 0x26, 0xe0,
- 0x2d, 0xe0, 0x34, 0xe0,
- 0x36, 0xe0, 0x38, 0xe0,
- 0x02, 0xc5, 0x00, 0xbd,
- 0x38, 0x3b, 0xdb, 0x49,
- 0x04, 0xf1, 0x06, 0xc3,
- 0x00, 0xbb, 0x5a, 0x02,
- 0x05, 0xc4, 0x03, 0xc3,
- 0x00, 0xbb, 0xa4, 0x04,
- 0x7e, 0x02, 0x30, 0xd4,
- 0x32, 0x48, 0x30, 0x18,
- 0x10, 0xc1, 0x04, 0xe8,
- 0x02, 0xc2, 0x00, 0xba,
- 0x3e, 0x16, 0x02, 0xb4,
- 0x09, 0xc2, 0x40, 0x99,
- 0x0e, 0x48, 0x42, 0x98,
- 0x42, 0x70, 0x8e, 0x49,
- 0xfe, 0xf1, 0x02, 0xb0,
- 0x80, 0xff, 0xc0, 0xd4,
- 0xe4, 0x40, 0xe7, 0x8d,
- 0x30, 0x18, 0x05, 0xc1,
- 0xf1, 0xef, 0x02, 0xc0,
- 0x00, 0xb8, 0xd8, 0x10,
- 0xe4, 0x4b, 0x07, 0xc3,
- 0x70, 0x61, 0x12, 0x48,
- 0x70, 0x89, 0x02, 0xc3,
- 0x00, 0xbb, 0x9c, 0x15,
- 0x20, 0xd4, 0x02, 0xc6,
- 0x00, 0xbe, 0x00, 0x00,
- 0x02, 0xc6, 0x00, 0xbe,
- 0x00, 0x00, 0x02, 0xc6,
- 0x00, 0xbe, 0x00, 0x00 };
- static u8 pla_patch_c[] = {
- 0x08, 0xe0, 0xea, 0xe0,
- 0xf2, 0xe0, 0x04, 0xe1,
- 0x06, 0xe1, 0x08, 0xe1,
- 0x40, 0xe1, 0xa5, 0xe1,
- 0x14, 0xc2, 0x40, 0x73,
- 0xba, 0x48, 0x40, 0x9b,
- 0x11, 0xc2, 0x40, 0x73,
- 0xb0, 0x49, 0x17, 0xf0,
- 0xbf, 0x49, 0x03, 0xf1,
- 0x09, 0xc5, 0x00, 0xbd,
- 0xb1, 0x49, 0x11, 0xf0,
- 0xb1, 0x48, 0x40, 0x9b,
- 0x02, 0xc2, 0x00, 0xba,
- 0xde, 0x18, 0x00, 0xe0,
- 0x1e, 0xfc, 0xbc, 0xc0,
- 0xf0, 0xc0, 0xde, 0xe8,
- 0x00, 0x80, 0x00, 0x20,
- 0x2c, 0x75, 0xd4, 0x49,
- 0x12, 0xf1, 0x32, 0xe0,
- 0xf8, 0xc2, 0x46, 0x71,
- 0xf7, 0xc2, 0x40, 0x73,
- 0xbe, 0x49, 0x03, 0xf1,
- 0xf5, 0xc7, 0x02, 0xe0,
- 0xf2, 0xc7, 0x4f, 0x30,
- 0x26, 0x62, 0xa1, 0x49,
- 0xf0, 0xf1, 0x22, 0x72,
- 0xa0, 0x49, 0xed, 0xf1,
- 0x25, 0x25, 0x18, 0x1f,
- 0x97, 0x30, 0x91, 0x30,
- 0x36, 0x9a, 0x2c, 0x75,
- 0x3c, 0xc3, 0x60, 0x73,
- 0xb1, 0x49, 0x0d, 0xf1,
- 0xdc, 0x21, 0xbc, 0x25,
- 0x30, 0xc6, 0xc0, 0x77,
- 0x04, 0x13, 0x21, 0xf0,
- 0x03, 0x13, 0x22, 0xf0,
- 0x02, 0x13, 0x23, 0xf0,
- 0x01, 0x13, 0x24, 0xf0,
- 0x08, 0x13, 0x08, 0xf1,
- 0x2e, 0x73, 0xba, 0x21,
- 0xbd, 0x25, 0x05, 0x13,
- 0x03, 0xf1, 0x24, 0xc5,
- 0x00, 0xbd, 0xd4, 0x49,
- 0x03, 0xf1, 0x1c, 0xc5,
- 0x00, 0xbd, 0xc4, 0xc6,
- 0xc6, 0x67, 0x2e, 0x75,
- 0xd7, 0x22, 0xdd, 0x26,
- 0x05, 0x15, 0x1b, 0xf0,
- 0x14, 0xc6, 0x00, 0xbe,
- 0x13, 0xc5, 0x00, 0xbd,
- 0x12, 0xc5, 0x00, 0xbd,
- 0xf1, 0x49, 0xfb, 0xf1,
- 0xef, 0xe7, 0xf4, 0x49,
- 0xfa, 0xf1, 0xec, 0xe7,
- 0xf3, 0x49, 0xf7, 0xf1,
- 0xe9, 0xe7, 0xf2, 0x49,
- 0xf4, 0xf1, 0xe6, 0xe7,
- 0xb6, 0xc0, 0x50, 0x14,
- 0x90, 0x13, 0xbc, 0x13,
- 0xf2, 0x14, 0x00, 0xa0,
- 0xa0, 0xd1, 0x00, 0x00,
- 0xc0, 0x75, 0xd0, 0x49,
- 0x46, 0xf0, 0x26, 0x72,
- 0xa7, 0x49, 0x43, 0xf0,
- 0x22, 0x72, 0x25, 0x25,
- 0x20, 0x1f, 0x97, 0x30,
- 0x91, 0x30, 0x40, 0x73,
- 0xf3, 0xc4, 0x1c, 0x40,
- 0x04, 0xf0, 0xd7, 0x49,
- 0x05, 0xf1, 0x37, 0xe0,
- 0x53, 0x48, 0xc0, 0x9d,
- 0x08, 0x02, 0x40, 0x66,
- 0x64, 0x27, 0x06, 0x16,
- 0x30, 0xf1, 0x46, 0x63,
- 0x3b, 0x13, 0x2d, 0xf1,
- 0x34, 0x9b, 0x18, 0x1b,
- 0x93, 0x30, 0x2b, 0xc3,
- 0x10, 0x1c, 0x2b, 0xe8,
- 0x01, 0x14, 0x25, 0xf1,
- 0x00, 0x1d, 0x26, 0x1a,
- 0x8a, 0x30, 0x22, 0x73,
- 0xb5, 0x25, 0x0e, 0x0b,
- 0x00, 0x1c, 0x2c, 0xe8,
- 0x1f, 0xc7, 0x27, 0x40,
- 0x1a, 0xf1, 0x38, 0xe8,
- 0x32, 0x1f, 0x8f, 0x30,
- 0x08, 0x1b, 0x24, 0xe8,
- 0x36, 0x72, 0x46, 0x77,
- 0x00, 0x17, 0x0d, 0xf0,
- 0x13, 0xc3, 0x1f, 0x40,
- 0x03, 0xf1, 0x00, 0x1f,
- 0x46, 0x9f, 0x44, 0x77,
- 0x9f, 0x44, 0x5f, 0x44,
- 0x17, 0xe8, 0x0a, 0xc7,
- 0x27, 0x40, 0x05, 0xf1,
- 0x02, 0xc3, 0x00, 0xbb,
- 0xbe, 0x1a, 0x74, 0x14,
- 0xff, 0xc7, 0x00, 0xbf,
- 0xb8, 0xcd, 0xff, 0xff,
- 0x02, 0x0c, 0x54, 0xa5,
- 0xdc, 0xa5, 0x2f, 0x40,
- 0x05, 0xf1, 0x00, 0x14,
- 0xfa, 0xf1, 0x01, 0x1c,
- 0x02, 0xe0, 0x00, 0x1c,
- 0x80, 0xff, 0xb0, 0x49,
- 0x04, 0xf0, 0x01, 0x0b,
- 0xd3, 0xa1, 0x03, 0xe0,
- 0x02, 0x0b, 0xd3, 0xa5,
- 0x27, 0x31, 0x20, 0x37,
- 0x02, 0x0b, 0xd3, 0xa5,
- 0x27, 0x31, 0x20, 0x37,
- 0x00, 0x13, 0xfb, 0xf1,
- 0x80, 0xff, 0x22, 0x73,
- 0xb5, 0x25, 0x18, 0x1e,
- 0xde, 0x30, 0xd9, 0x30,
- 0x64, 0x72, 0x11, 0x1e,
- 0x68, 0x23, 0x16, 0x31,
- 0x80, 0xff, 0x08, 0xc2,
- 0x40, 0x73, 0x3a, 0x48,
- 0x40, 0x9b, 0x06, 0xff,
- 0x02, 0xc6, 0x00, 0xbe,
- 0xcc, 0x17, 0x1e, 0xfc,
- 0x2c, 0x75, 0xdc, 0x21,
- 0xbc, 0x25, 0x04, 0x13,
- 0x0b, 0xf0, 0x03, 0x13,
- 0x09, 0xf0, 0x02, 0x13,
- 0x07, 0xf0, 0x01, 0x13,
- 0x05, 0xf0, 0x08, 0x13,
- 0x03, 0xf0, 0x04, 0xc3,
- 0x00, 0xbb, 0x03, 0xc3,
- 0x00, 0xbb, 0x50, 0x17,
- 0x3a, 0x17, 0x02, 0xc6,
- 0x00, 0xbe, 0x00, 0x00,
- 0x02, 0xc6, 0x00, 0xbe,
- 0x00, 0x00, 0x33, 0xc5,
- 0xa0, 0x74, 0xc0, 0x49,
- 0x1f, 0xf0, 0x30, 0xc5,
- 0xa0, 0x73, 0x00, 0x13,
- 0x04, 0xf1, 0xa2, 0x73,
- 0x00, 0x13, 0x14, 0xf0,
- 0x28, 0xc5, 0xa0, 0x74,
- 0xc8, 0x49, 0x1b, 0xf1,
- 0x26, 0xc5, 0xa0, 0x76,
- 0xa2, 0x74, 0x01, 0x06,
- 0x20, 0x37, 0xa0, 0x9e,
- 0xa2, 0x9c, 0x1e, 0xc5,
- 0xa2, 0x73, 0x23, 0x40,
- 0x10, 0xf8, 0x04, 0xf3,
- 0xa0, 0x73, 0x33, 0x40,
- 0x0c, 0xf8, 0x15, 0xc5,
- 0xa0, 0x74, 0x41, 0x48,
- 0xa0, 0x9c, 0x14, 0xc5,
- 0xa0, 0x76, 0x62, 0x48,
- 0xe0, 0x48, 0xa0, 0x9e,
- 0x10, 0xc6, 0x00, 0xbe,
- 0x0a, 0xc5, 0xa0, 0x74,
- 0x48, 0x48, 0xa0, 0x9c,
- 0x0b, 0xc5, 0x20, 0x1e,
- 0xa0, 0x9e, 0xe5, 0x48,
- 0xa0, 0x9e, 0xf0, 0xe7,
- 0xbc, 0xc0, 0xc8, 0xd2,
- 0xcc, 0xd2, 0x28, 0xe4,
- 0xfa, 0x01, 0xf0, 0xc0,
- 0x18, 0x89, 0x00, 0x1d,
- 0x5a, 0xc0, 0x5a, 0xc1,
- 0x02, 0x99, 0x00, 0x61,
- 0x67, 0x11, 0x35, 0xf1,
- 0x69, 0x33, 0x55, 0xc0,
- 0x28, 0x40, 0xf7, 0xf1,
- 0x54, 0xc0, 0x00, 0x19,
- 0x81, 0x1b, 0x44, 0xe8,
- 0x53, 0xc0, 0x04, 0x1a,
- 0x84, 0x1b, 0x40, 0xe8,
- 0x35, 0xe8, 0xa3, 0x49,
- 0xfe, 0xf0, 0x4a, 0xc0,
- 0x31, 0xe8, 0xa1, 0x48,
- 0x47, 0xc0, 0x84, 0x1b,
- 0x37, 0xe8, 0x00, 0x1d,
- 0x69, 0x33, 0x00, 0x1e,
- 0x01, 0x06, 0xff, 0x18,
- 0x30, 0x40, 0xfd, 0xf1,
- 0x40, 0xc0, 0x00, 0x76,
- 0x2e, 0x40, 0xf7, 0xf1,
- 0x21, 0x48, 0x38, 0xc0,
- 0x84, 0x1b, 0x28, 0xe8,
- 0x36, 0xc0, 0x1c, 0xe8,
- 0xa1, 0x49, 0xfd, 0xf0,
- 0x33, 0xc0, 0x00, 0x1a,
- 0x84, 0x1b, 0x20, 0xe8,
- 0x15, 0xe8, 0xa5, 0x49,
- 0xfe, 0xf0, 0x29, 0xc0,
- 0x01, 0x19, 0x81, 0x1b,
- 0x19, 0xe8, 0x0b, 0xe0,
- 0x9c, 0x20, 0x9c, 0x24,
- 0x06, 0x11, 0x07, 0xf1,
- 0x25, 0xc0, 0x08, 0xe8,
- 0x23, 0xc0, 0x12, 0x48,
- 0x81, 0x1b, 0x0e, 0xe8,
- 0x02, 0xc0, 0x00, 0xb8,
- 0xd6, 0x07, 0x16, 0xc4,
- 0x84, 0x98, 0x00, 0x1b,
- 0x86, 0x8b, 0x86, 0x73,
- 0xbf, 0x49, 0xfe, 0xf1,
- 0x80, 0x71, 0x82, 0x72,
- 0x80, 0xff, 0x0c, 0xc4,
- 0x84, 0x98, 0x80, 0x99,
- 0x82, 0x9a, 0x86, 0x8b,
- 0x86, 0x73, 0xbf, 0x49,
- 0xfe, 0xf1, 0x80, 0xff,
- 0x50, 0xe8, 0x82, 0x00,
- 0xb8, 0x0b, 0x08, 0xea,
- 0x20, 0xb4, 0x84, 0xd4,
- 0x10, 0xd4, 0x10, 0xd8,
- 0x88, 0xd3, 0x30, 0xd4,
- 0x02, 0xc0, 0x00, 0xb8,
- 0xe0, 0x08, 0x00, 0x00 };
-
- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x0000);
- generic_ocp_write(tp, 0xf800, 0xff, sizeof(usb_patch_c),
- usb_patch_c, MCU_TYPE_USB);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc26, 0xa000);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc28, 0x3b34);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc2a, 0x027c);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc2c, 0x1634);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc2e, 0x10d6);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc30, 0x0000);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc32, 0x0000);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc34, 0x0000);
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc36, 0x0000);
- if (ocp_read_byte(tp, MCU_TYPE_USB, 0xcfef) & 1) {
- ocp_write_word(tp, MCU_TYPE_USB, 0xfc30, 0x1578);
- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x001F);
- } else {
- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x000F);
- }
-
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0000);
- generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch_c),
- pla_patch_c, MCU_TYPE_PLA);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc26, 0x8000);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc28, 0x1306);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2a, 0x17ca);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2c, 0x171e);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2e, 0x0000);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc30, 0x0000);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc32, 0x01b4);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc34, 0x07d4);
- ocp_write_word(tp, MCU_TYPE_PLA, 0xfc36, 0x0894);
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x00e7);
-
- ocp_write_word(tp, MCU_TYPE_PLA, 0xd388, 0x08ca);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xcfca);
- ocp_data |= 0x4000;
- ocp_write_word(tp, MCU_TYPE_USB, 0xcfca, ocp_data);
- }
-}
-
-static void r8153_hw_phy_cfg(struct r8152 *tp)
-{
- u32 ocp_data;
- u16 data;
-
- ocp_reg_write(tp, OCP_ADC_CFG, CKADSEL_L | ADC_EN | EN_EMI_L);
- data = r8152_mdio_read(tp, MII_BMCR);
- if (data & BMCR_PDOWN) {
- data &= ~BMCR_PDOWN;
- r8152_mdio_write(tp, MII_BMCR, data);
- }
-
- r8153_firmware(tp);
-
- if (tp->version == RTL_VER_03) {
- data = ocp_reg_read(tp, OCP_EEE_CFG);
- data &= ~CTAP_SHORT_EN;
- ocp_reg_write(tp, OCP_EEE_CFG, data);
- }
-
- data = ocp_reg_read(tp, OCP_POWER_CFG);
- data |= EEE_CLKDIV_EN;
- ocp_reg_write(tp, OCP_POWER_CFG, data);
-
- data = ocp_reg_read(tp, OCP_DOWN_SPEED);
- data |= EN_10M_BGOFF;
- ocp_reg_write(tp, OCP_DOWN_SPEED, data);
- data = ocp_reg_read(tp, OCP_POWER_CFG);
- data |= EN_10M_PLLOFF;
- ocp_reg_write(tp, OCP_POWER_CFG, data);
- data = sram_read(tp, SRAM_IMPEDANCE);
- data &= ~RX_DRIVING_MASK;
- sram_write(tp, SRAM_IMPEDANCE, data);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR);
- ocp_data |= PFM_PWM_SWITCH;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data);
-
- data = sram_read(tp, SRAM_LPF_CFG);
- data |= LPF_AUTO_TUNE;
- sram_write(tp, SRAM_LPF_CFG, data);
-
- data = sram_read(tp, SRAM_10M_AMP1);
- data |= GDAC_IB_UPALL;
- sram_write(tp, SRAM_10M_AMP1, data);
- data = sram_read(tp, SRAM_10M_AMP2);
- data |= AMP_DN;
- sram_write(tp, SRAM_10M_AMP2, data);
-
- set_bit(PHY_RESET, &tp->flags);
-}
-
-static void r8153_u1u2en(struct r8152 *tp, bool enable)
-{
- u8 u1u2[8];
-
- if (enable)
- memset(u1u2, 0xff, sizeof(u1u2));
- else
- memset(u1u2, 0x00, sizeof(u1u2));
-
- usb_ocp_write(tp, USB_TOLERANCE, BYTE_EN_SIX_BYTES, sizeof(u1u2), u1u2);
-}
-
-static void r8153_u2p3en(struct r8152 *tp, bool enable)
-{
- u32 ocp_data;
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL);
- if (enable)
- ocp_data |= U2P3_ENABLE;
- else
- ocp_data &= ~U2P3_ENABLE;
- ocp_write_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL, ocp_data);
-}
-
-static void r8153_power_cut_en(struct r8152 *tp, bool enable)
-{
- u32 ocp_data;
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_POWER_CUT);
- if (enable)
- ocp_data |= PWR_EN | PHASE2_EN;
- else
- ocp_data &= ~(PWR_EN | PHASE2_EN);
- ocp_write_word(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0);
- ocp_data &= ~PCUT_STATUS;
- ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data);
-}
-
-static void r8153_first_init(struct r8152 *tp)
-{
- u32 ocp_data;
- int i;
-
- rxdy_gated_en(tp, true);
- r8153_teredo_off(tp);
-
- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
- ocp_data &= ~RCR_ACPT_ALL;
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
-
- r8153_hw_phy_cfg(tp);
-
- rtl8152_nic_reset(tp);
-
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- ocp_data &= ~NOW_IS_OOB;
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7);
- ocp_data &= ~MCU_BORW_EN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data);
-
- for (i = 0; i < 1000; i++) {
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- if (ocp_data & LINK_LIST_READY)
- break;
- usleep_range(1000, 2000);
- }
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7);
- ocp_data |= RE_INIT_LL;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data);
-
- for (i = 0; i < 1000; i++) {
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- if (ocp_data & LINK_LIST_READY)
- break;
- usleep_range(1000, 2000);
- }
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR);
- ocp_data &= ~CPCR_RX_VLAN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data);
-
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8153_RMS);
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0);
- ocp_data |= TCR0_AUTO_FIFO;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR0, ocp_data);
-
- rtl8152_nic_reset(tp);
-
- /* rx share fifo credit full threshold */
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_NORMAL);
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, RXFIFO_THR2_NORMAL);
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, RXFIFO_THR3_NORMAL);
- /* TX share fifo free credit full threshold */
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, TXFIFO_THR_NORMAL2);
-
- /* rx aggregation */
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL);
- ocp_data &= ~RX_AGG_DISABLE;
- ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data);
-}
-
-static void r8153_enter_oob(struct r8152 *tp)
-{
- u32 ocp_data;
- int i;
-
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- ocp_data &= ~NOW_IS_OOB;
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
-
- rtl_disable(tp);
-
- for (i = 0; i < 1000; i++) {
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- if (ocp_data & LINK_LIST_READY)
- break;
- usleep_range(1000, 2000);
- }
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7);
- ocp_data |= RE_INIT_LL;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data);
-
- for (i = 0; i < 1000; i++) {
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- if (ocp_data & LINK_LIST_READY)
- break;
- usleep_range(1000, 2000);
- }
-
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8153_RMS);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG);
- ocp_data &= ~TEREDO_WAKE_MASK;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ocp_data);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR);
- ocp_data |= CPCR_RX_VLAN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PAL_BDC_CR);
- ocp_data |= ALDPS_PROXY_MODE;
- ocp_write_word(tp, MCU_TYPE_PLA, PAL_BDC_CR, ocp_data);
-
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
- ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB;
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
-
- rxdy_gated_en(tp, false);
-
- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
- ocp_data |= RCR_APM | RCR_AM | RCR_AB;
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
-}
-
-static void r8153_disable_aldps(struct r8152 *tp)
-{
- u16 data;
-
- data = ocp_reg_read(tp, OCP_POWER_CFG);
- data &= ~EN_ALDPS;
- ocp_reg_write(tp, OCP_POWER_CFG, data);
- msleep(20);
-}
-
-static void r8153_enable_aldps(struct r8152 *tp)
-{
- u16 data;
-
- data = ocp_reg_read(tp, OCP_POWER_CFG);
- data |= EN_ALDPS;
- ocp_reg_write(tp, OCP_POWER_CFG, data);
-}
-
-static void rtl8153_disable(struct r8152 *tp)
-{
- r8153_disable_aldps(tp);
- rtl_disable(tp);
- r8153_enable_aldps(tp);
-}
-
-static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u16 speed, u8 duplex)
-{
- u16 bmcr, anar, gbcr;
- int ret = 0;
-
- cancel_delayed_work_sync(&tp->schedule);
- anar = r8152_mdio_read(tp, MII_ADVERTISE);
- anar &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL |
- ADVERTISE_100HALF | ADVERTISE_100FULL);
- if (tp->mii.supports_gmii) {
- gbcr = r8152_mdio_read(tp, MII_CTRL1000);
- gbcr &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
- } else {
- gbcr = 0;
- }
-
- if (autoneg == AUTONEG_DISABLE) {
- if (speed == SPEED_10) {
- bmcr = 0;
- anar |= ADVERTISE_10HALF | ADVERTISE_10FULL;
- } else if (speed == SPEED_100) {
- bmcr = BMCR_SPEED100;
- anar |= ADVERTISE_100HALF | ADVERTISE_100FULL;
- } else if (speed == SPEED_1000 && tp->mii.supports_gmii) {
- bmcr = BMCR_SPEED1000;
- gbcr |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
- } else {
- ret = -EINVAL;
- goto out;
- }
-
- if (duplex == DUPLEX_FULL)
- bmcr |= BMCR_FULLDPLX;
- } else {
- if (speed == SPEED_10) {
- if (duplex == DUPLEX_FULL)
- anar |= ADVERTISE_10HALF | ADVERTISE_10FULL;
- else
- anar |= ADVERTISE_10HALF;
- } else if (speed == SPEED_100) {
- if (duplex == DUPLEX_FULL) {
- anar |= ADVERTISE_10HALF | ADVERTISE_10FULL;
- anar |= ADVERTISE_100HALF | ADVERTISE_100FULL;
- } else {
- anar |= ADVERTISE_10HALF;
- anar |= ADVERTISE_100HALF;
- }
- } else if (speed == SPEED_1000 && tp->mii.supports_gmii) {
- if (duplex == DUPLEX_FULL) {
- anar |= ADVERTISE_10HALF | ADVERTISE_10FULL;
- anar |= ADVERTISE_100HALF | ADVERTISE_100FULL;
- gbcr |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
- } else {
- anar |= ADVERTISE_10HALF;
- anar |= ADVERTISE_100HALF;
- gbcr |= ADVERTISE_1000HALF;
- }
- } else {
- ret = -EINVAL;
- goto out;
- }
-
- bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
- }
-
- if (test_bit(PHY_RESET, &tp->flags))
- bmcr |= BMCR_RESET;
-
- if (tp->mii.supports_gmii)
- r8152_mdio_write(tp, MII_CTRL1000, gbcr);
-
- r8152_mdio_write(tp, MII_ADVERTISE, anar);
- r8152_mdio_write(tp, MII_BMCR, bmcr);
-
- if (test_bit(PHY_RESET, &tp->flags)) {
- int i;
-
- clear_bit(PHY_RESET, &tp->flags);
- for (i = 0; i < 50; i++) {
- msleep(20);
- if ((r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET) == 0)
- break;
- }
- }
-
-out:
-
- return ret;
-}
-
-static void rtl8152_up(struct r8152 *tp)
-{
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return;
-
- r8152b_disable_aldps(tp);
- r8152b_exit_oob(tp);
- r8152b_enable_aldps(tp);
-}
-
-static void rtl8152_down(struct r8152 *tp)
-{
- if (test_bit(RTL8152_UNPLUG, &tp->flags)) {
- rtl_drop_queued_tx(tp);
- return;
- }
-
- r8152_power_cut_en(tp, false);
- r8152b_disable_aldps(tp);
- r8152b_enter_oob(tp);
- r8152b_enable_aldps(tp);
- if (tp->version == RTL_VER_01)
- rtl8152_set_speed(tp, AUTONEG_ENABLE, SPEED_10, DUPLEX_FULL);
-}
-
-static void rtl8153_up(struct r8152 *tp)
-{
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return;
-
- r8153_disable_aldps(tp);
- r8153_first_init(tp);
- r8153_enable_aldps(tp);
-}
-
-static void rtl8153_down(struct r8152 *tp)
-{
- if (test_bit(RTL8152_UNPLUG, &tp->flags)) {
- rtl_drop_queued_tx(tp);
- return;
- }
-
- r8153_u1u2en(tp, false);
- r8153_power_cut_en(tp, false);
- r8153_disable_aldps(tp);
- r8153_enter_oob(tp);
- r8153_enable_aldps(tp);
-}
-
-static void set_carrier(struct r8152 *tp)
-{
- struct net_device *netdev = tp->netdev;
- u8 speed;
-
- clear_bit(RTL8152_LINK_CHG, &tp->flags);
- speed = rtl8152_get_speed(tp);
-
- if (speed & LINK_STATUS) {
- if (!(tp->speed & LINK_STATUS)) {
- tp->rtl_ops.enable(tp);
- set_bit(RTL8152_SET_RX_MODE, &tp->flags);
- netif_carrier_on(netdev);
- }
- } else {
- if (tp->speed & LINK_STATUS) {
- netif_carrier_off(netdev);
- tasklet_disable(&tp->tl);
- tp->rtl_ops.disable(tp);
- tasklet_enable(&tp->tl);
- }
- }
- tp->speed = speed;
-}
-
-static inline void __rtl_work_func(struct r8152 *tp)
-{
- if (usb_autopm_get_interface(tp->intf) < 0)
- return;
-
- if (!test_bit(WORK_ENABLE, &tp->flags))
- goto out1;
-
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- goto out1;
-
- if (test_bit(RTL8152_LINK_CHG, &tp->flags))
- set_carrier(tp);
-
- if (test_bit(RTL8152_SET_RX_MODE, &tp->flags))
- rtl8152_set_rx_mode(tp->netdev);
-
- /* don't schedule tasklet before linking */
- if (test_bit(SCHEDULE_TASKLET, &tp->flags) &&
- (tp->speed & LINK_STATUS)) {
- clear_bit(SCHEDULE_TASKLET, &tp->flags);
- tasklet_schedule(&tp->tl);
- }
-
- if (test_bit(PHY_RESET, &tp->flags))
- rtl_phy_reset(tp);
-
-out1:
- usb_autopm_put_interface(tp->intf);
-}
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-
-static void rtl_work_func_t(void *data)
-{
- struct r8152 *tp = (struct r8152 *)data;
-
- __rtl_work_func(tp);
-}
-
-#else
-
-static void rtl_work_func_t(struct work_struct *work)
-{
- struct r8152 *tp = container_of(work, struct r8152, schedule.work);
-
- __rtl_work_func(tp);
-}
-
-#endif
-
-static int rtl8152_open(struct net_device *netdev)
-{
- struct r8152 *tp = netdev_priv(netdev);
- int res = 0;
-
- res = alloc_all_mem(tp);
- if (res)
- goto out;
-
- res = usb_autopm_get_interface(tp->intf);
- if (res < 0) {
- free_all_mem(tp);
- goto out;
- }
-
- /* The WORK_ENABLE may be set when autoresume occurs */
- if (test_bit(WORK_ENABLE, &tp->flags)) {
- clear_bit(WORK_ENABLE, &tp->flags);
- usb_kill_urb(tp->intr_urb);
- cancel_delayed_work_sync(&tp->schedule);
- if (tp->speed & LINK_STATUS)
- tp->rtl_ops.disable(tp);
- }
-
- tp->rtl_ops.up(tp);
-
- rtl8152_set_speed(tp, AUTONEG_ENABLE,
- tp->mii.supports_gmii ? SPEED_1000 : SPEED_100,
- DUPLEX_FULL);
- tp->speed = 0;
- netif_carrier_off(netdev);
- netif_start_queue(netdev);
- set_bit(WORK_ENABLE, &tp->flags);
-
- res = usb_submit_urb(tp->intr_urb, GFP_KERNEL);
- if (res) {
- if (res == -ENODEV)
- netif_device_detach(tp->netdev);
- netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n",
- res);
- free_all_mem(tp);
- }
-
- usb_autopm_put_interface(tp->intf);
-
-out:
- return res;
-}
-
-static int rtl8152_close(struct net_device *netdev)
-{
- struct r8152 *tp = netdev_priv(netdev);
- int res = 0;
-
- clear_bit(WORK_ENABLE, &tp->flags);
- usb_kill_urb(tp->intr_urb);
- cancel_delayed_work_sync(&tp->schedule);
- netif_stop_queue(netdev);
-
- res = usb_autopm_get_interface(tp->intf);
- if (res < 0) {
- rtl_drop_queued_tx(tp);
- } else {
- /* The autosuspend may have been enabled and wouldn't
- * be disable when autoresume occurs, because the
- * netif_running() would be false.
- */
- if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
- rtl_runtime_suspend_enable(tp, false);
- clear_bit(SELECTIVE_SUSPEND, &tp->flags);
- }
-
- tasklet_disable(&tp->tl);
- tp->rtl_ops.down(tp);
- tasklet_enable(&tp->tl);
- usb_autopm_put_interface(tp->intf);
- }
-
- free_all_mem(tp);
-
- return res;
-}
-
-static void patch4(struct r8152 *tp)
-{
- u8 data;
-
- data = ocp_read_byte(tp, MCU_TYPE_USB, 0xd429);
- data |= 0x80;
- ocp_write_byte(tp, MCU_TYPE_USB, 0xd429, data);
- ocp_write_word(tp, MCU_TYPE_USB, 0xc0ce, 0x0210);
- data = ocp_read_byte(tp, MCU_TYPE_USB, 0xd429);
- data &= ~0x80;
- ocp_write_byte(tp, MCU_TYPE_USB, 0xd429, data);
-}
-
-static void r8152b_enable_eee(struct r8152 *tp)
-{
- u32 ocp_data;
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
- ocp_data |= EEE_RX_EN | EEE_TX_EN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data);
- ocp_reg_write(tp, OCP_EEE_CONFIG1, RG_TXLPI_MSK_HFDUP | RG_MATCLR_EN |
- EEE_10_CAP | EEE_NWAY_EN |
- TX_QUIET_EN | RX_QUIET_EN |
- SDRISETIME | RG_RXLPI_MSK_HFDUP |
- SDFALLTIME);
- ocp_reg_write(tp, OCP_EEE_CONFIG2, RG_LPIHYS_NUM | RG_DACQUIET_EN |
- RG_LDVQUIET_EN | RG_CKRSEL |
- RG_EEEPRG_EN);
- ocp_reg_write(tp, OCP_EEE_CONFIG3, FST_SNR_EYE_R | RG_LFS_SEL | MSK_PH);
- ocp_reg_write(tp, OCP_EEE_AR, FUN_ADDR | DEVICE_ADDR);
- ocp_reg_write(tp, OCP_EEE_DATA, EEE_ADDR);
- ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | DEVICE_ADDR);
- ocp_reg_write(tp, OCP_EEE_DATA, EEE_DATA);
- ocp_reg_write(tp, OCP_EEE_AR, 0x0000);
-}
-
-static void r8153_enable_eee(struct r8152 *tp)
-{
- u32 ocp_data;
- u16 data;
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
- ocp_data |= EEE_RX_EN | EEE_TX_EN;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data);
- data = ocp_reg_read(tp, OCP_EEE_CFG);
- data |= EEE10_EN;
- ocp_reg_write(tp, OCP_EEE_CFG, data);
- data = ocp_reg_read(tp, OCP_EEE_CFG2);
- data |= MY1000_EEE | MY100_EEE;
- ocp_reg_write(tp, OCP_EEE_CFG2, data);
-}
-
-static void r8152b_enable_fc(struct r8152 *tp)
-{
- u16 anar;
-
- anar = r8152_mdio_read(tp, MII_ADVERTISE);
- anar |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
- r8152_mdio_write(tp, MII_ADVERTISE, anar);
-}
-
-static void rtl_tally_reset(struct r8152 *tp)
-{
- u32 ocp_data;
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY);
- ocp_data |= TALLY_RESET;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data);
-}
-
-static void r8152b_init(struct r8152 *tp)
-{
- u32 ocp_data;
-
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return;
-
- r8152b_disable_aldps(tp);
-#if 0
- /* Clear EP3 Fifo before using interrupt transfer */
- if (ocp_read_byte(tp, MCU_TYPE_USB, 0xb963) & 0x80) {
- ocp_write_byte(tp, MCU_TYPE_USB, 0xb963, 0x08);
- ocp_write_byte(tp, MCU_TYPE_USB, 0xb963, 0x40);
- ocp_write_byte(tp, MCU_TYPE_USB, 0xb963, 0x00);
- ocp_write_byte(tp, MCU_TYPE_USB, 0xb968, 0x00);
- ocp_write_word(tp, MCU_TYPE_USB, 0xb010, 0x00e0);
- ocp_write_byte(tp, MCU_TYPE_USB, 0xb963, 0x04);
- }
-#endif
-
- if (tp->version == RTL_VER_01) {
- patch4(tp);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE);
- ocp_data &= ~LED_MODE_MASK;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ocp_data);
- }
-
- r8152_power_cut_en(tp, false);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR);
- ocp_data |= TX_10M_IDLE_EN | PFM_PWM_SWITCH;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data);
- ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL);
- ocp_data &= ~MCU_CLK_RATIO_MASK;
- ocp_data |= MCU_CLK_RATIO | D3_CLK_GATED_EN;
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, ocp_data);
- ocp_data = GPHY_STS_MSK | SPEED_DOWN_MSK |
- SPDWN_RXDV_MSK | SPDWN_LINKCHG_MSK;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_GPHY_INTR_IMR, ocp_data);
-
- r8152b_enable_eee(tp);
- r8152b_enable_aldps(tp);
- r8152b_enable_fc(tp);
- rtl_tally_reset(tp);
-
-#if 0
- /* disable rx aggregation */
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL);
- ocp_data |= RX_AGG_DISABLE;
- ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data);
-#else
- /* enable rx aggregation */
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL);
- ocp_data &= ~RX_AGG_DISABLE;
- ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data);
-#endif
-}
-
-static void r8153_init(struct r8152 *tp)
-{
- u32 ocp_data;
- int i;
-
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return;
-
- r8153_disable_aldps(tp);
- r8153_u1u2en(tp, false);
-
- for (i = 0; i < 500; i++) {
- if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) &
- AUTOLOAD_DONE)
- break;
- msleep(20);
- }
-
- for (i = 0; i < 500; i++) {
- ocp_data = ocp_reg_read(tp, OCP_PHY_STATUS) & PHY_STAT_MASK;
- if (ocp_data == PHY_STAT_LAN_ON || ocp_data == PHY_STAT_PWRDN)
- break;
- msleep(20);
- }
-
- r8153_u2p3en(tp, false);
-
- if (tp->version == RTL_VER_04) {
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xb428);
- ocp_data &= ~0x3fff;
- ocp_data |= 0x012c;
- ocp_write_word(tp, MCU_TYPE_USB, 0xb428, ocp_data);
-
- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, 0xb41e);
- ocp_data |= 0x03;
- ocp_write_byte(tp, MCU_TYPE_USB, 0xb41e, ocp_data);
-
- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, 0xb466);
- ocp_data |= 0x01;
- ocp_write_byte(tp, MCU_TYPE_USB, 0xb466, ocp_data);
- } else if (tp->version == RTL_VER_05) {
- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, 0xc0b0);
- ocp_data &= ~0x02;
- ocp_write_byte(tp, MCU_TYPE_PLA, 0xc0b0, ocp_data);
-
- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, 0xb466);
- ocp_data |= 0x01;
- ocp_write_byte(tp, MCU_TYPE_USB, 0xb466, ocp_data);
- }
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL);
- ocp_data &= ~TIMER11_EN;
- ocp_write_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL, ocp_data);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE);
- ocp_data &= ~LED_MODE_MASK;
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ocp_data);
-
- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_LPM_CTRL);
- ocp_data &= ~LPM_TIMER_MASK;
- if (tp->version == RTL_VER_04 && tp->udev->speed != USB_SPEED_SUPER)
- ocp_data |= LPM_TIMER_500MS;
- else
- ocp_data |= LPM_TIMER_500US;
- ocp_write_byte(tp, MCU_TYPE_USB, USB_LPM_CTRL, ocp_data);
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_AFE_CTRL2);
- ocp_data &= ~SEN_VAL_MASK;
- ocp_data |= SEN_VAL_NORMAL | SEL_RXIDLE;
- ocp_write_word(tp, MCU_TYPE_USB, USB_AFE_CTRL2, ocp_data);
-
- r8153_power_cut_en(tp, false);
- ocp_write_word(tp, MCU_TYPE_USB, 0xcbf8, 0x0001);
- r8153_u1u2en(tp, true);
-
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, ALDPS_SPDWN_RATIO);
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, EEE_SPDWN_RATIO);
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3,
- PKT_AVAIL_SPDWN_EN | SUSPEND_SPDWN_EN |
- U1U2_SPDWN_EN | L1_SPDWN_EN);
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4,
- PWRSAVE_SPDWN_EN | RXDV_SPDWN_EN | TX10MIDLE_EN |
- TP100_SPDWN_EN | TP500_SPDWN_EN | TP1000_SPDWN_EN |
- EEE_SPDWN_EN);
-
- r8153_enable_eee(tp);
- r8153_enable_aldps(tp);
- r8152b_enable_fc(tp);
- rtl_tally_reset(tp);
-}
-
-static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct r8152 *tp = usb_get_intfdata(intf);
-
- if (PMSG_IS_AUTO(message))
- set_bit(SELECTIVE_SUSPEND, &tp->flags);
- else
- netif_device_detach(tp->netdev);
-
- if (netif_running(tp->netdev)) {
- clear_bit(WORK_ENABLE, &tp->flags);
- usb_kill_urb(tp->intr_urb);
- cancel_delayed_work_sync(&tp->schedule);
- if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
- rtl_runtime_suspend_enable(tp, true);
- } else {
- tasklet_disable(&tp->tl);
- tp->rtl_ops.down(tp);
- tasklet_enable(&tp->tl);
- }
- }
-
- return 0;
-}
-
-static int rtl8152_resume(struct usb_interface *intf)
-{
- struct r8152 *tp = usb_get_intfdata(intf);
-
- if (!test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
- tp->rtl_ops.init(tp);
- netif_device_attach(tp->netdev);
- }
-
- if (netif_running(tp->netdev)) {
- if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
- rtl_runtime_suspend_enable(tp, false);
- clear_bit(SELECTIVE_SUSPEND, &tp->flags);
- if (tp->speed & LINK_STATUS)
- tp->rtl_ops.disable(tp);
- } else {
- tp->rtl_ops.up(tp);
- rtl8152_set_speed(tp, AUTONEG_ENABLE,
- tp->mii.supports_gmii ?
- SPEED_1000 : SPEED_100,
- DUPLEX_FULL);
- }
- tp->speed = 0;
- netif_carrier_off(tp->netdev);
- set_bit(WORK_ENABLE, &tp->flags);
- usb_submit_urb(tp->intr_urb, GFP_KERNEL);
- }
-
- return 0;
-}
-
-static void rtl8152_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
- struct r8152 *tp = netdev_priv(dev);
-
- if (usb_autopm_get_interface(tp->intf) < 0)
- return;
-
- wol->supported = WAKE_ANY;
- wol->wolopts = __rtl_get_wol(tp);
-
- usb_autopm_put_interface(tp->intf);
-}
-
-static int rtl8152_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
- struct r8152 *tp = netdev_priv(dev);
- int ret;
-
- ret = usb_autopm_get_interface(tp->intf);
- if (ret < 0)
- goto out_set_wol;
-
- __rtl_set_wol(tp, wol->wolopts);
- tp->saved_wolopts = wol->wolopts & WAKE_ANY;
-
- usb_autopm_put_interface(tp->intf);
-
-out_set_wol:
- return ret;
-}
-
-static u32 rtl8152_get_msglevel(struct net_device *dev)
-{
- struct r8152 *tp = netdev_priv(dev);
-
- return tp->msg_enable;
-}
-
-static void rtl8152_set_msglevel(struct net_device *dev, u32 value)
-{
- struct r8152 *tp = netdev_priv(dev);
-
- tp->msg_enable = value;
-}
-
-static void rtl8152_get_drvinfo(struct net_device *netdev,
- struct ethtool_drvinfo *info)
-{
- struct r8152 *tp = netdev_priv(netdev);
-
- strlcpy(info->driver, MODULENAME, sizeof(info->driver));
- strlcpy(info->version, DRIVER_VERSION, sizeof(info->version));
- usb_make_path(tp->udev, info->bus_info, sizeof(info->bus_info));
-}
-
-static
-int rtl8152_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
-{
- struct r8152 *tp = netdev_priv(netdev);
- u16 bmcr, bmsr, ctrl1000 = 0, stat1000 = 0;
- int ret;
-
- ret = usb_autopm_get_interface(tp->intf);
- if (ret < 0)
- goto out;
-
- cmd->supported =
- (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
- SUPPORTED_Autoneg | SUPPORTED_MII);
- if (tp->mii.supports_gmii)
- cmd->supported |= SUPPORTED_1000baseT_Half |
- SUPPORTED_1000baseT_Full;
-
- /* only supports twisted-pair */
- cmd->port = PORT_MII;
-
- /* only supports internal transceiver */
- cmd->transceiver = XCVR_INTERNAL;
- cmd->phy_address = 32;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
- cmd->mdio_support = ETH_MDIO_SUPPORTS_C22;
-#endif
- cmd->advertising = ADVERTISED_MII;
-
- bmcr = r8152_mdio_read(tp, MII_BMCR);
- bmsr = r8152_mdio_read(tp, MII_BMSR);
- if (tp->mii.supports_gmii) {
- ctrl1000 = r8152_mdio_read(tp, MII_CTRL1000);
- stat1000 = r8152_mdio_read(tp, MII_STAT1000);
- }
-
- if (bmcr & BMCR_ANENABLE) {
- int advert;
-
- cmd->advertising |= ADVERTISED_Autoneg;
- cmd->autoneg = AUTONEG_ENABLE;
-
- advert = r8152_mdio_read(tp, MII_ADVERTISE);
- if (advert & ADVERTISE_10HALF)
- cmd->advertising |= ADVERTISED_10baseT_Half;
- if (advert & ADVERTISE_10FULL)
- cmd->advertising |= ADVERTISED_10baseT_Full;
- if (advert & ADVERTISE_100HALF)
- cmd->advertising |= ADVERTISED_100baseT_Half;
- if (advert & ADVERTISE_100FULL)
- cmd->advertising |= ADVERTISED_100baseT_Full;
- if (advert & ADVERTISE_PAUSE_CAP)
- cmd->advertising |= ADVERTISED_Pause;
- if (advert & ADVERTISE_PAUSE_ASYM)
- cmd->advertising |= ADVERTISED_Asym_Pause;
- if (tp->mii.supports_gmii) {
- if (ctrl1000 & ADVERTISE_1000HALF)
- cmd->advertising |= ADVERTISED_1000baseT_Half;
- if (ctrl1000 & ADVERTISE_1000FULL)
- cmd->advertising |= ADVERTISED_1000baseT_Full;
- }
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
- if (bmsr & BMSR_ANEGCOMPLETE) {
- advert = r8152_mdio_read(tp, MII_LPA);
- if (advert & LPA_LPACK)
- cmd->lp_advertising |= ADVERTISED_Autoneg;
- if (advert & ADVERTISE_10HALF)
- cmd->lp_advertising |=
- ADVERTISED_10baseT_Half;
- if (advert & ADVERTISE_10FULL)
- cmd->lp_advertising |=
- ADVERTISED_10baseT_Full;
- if (advert & ADVERTISE_100HALF)
- cmd->lp_advertising |=
- ADVERTISED_100baseT_Half;
- if (advert & ADVERTISE_100FULL)
- cmd->lp_advertising |=
- ADVERTISED_100baseT_Full;
-
- if (tp->mii.supports_gmii) {
- if (stat1000 & LPA_1000HALF)
- cmd->lp_advertising |=
- ADVERTISED_1000baseT_Half;
- if (stat1000 & LPA_1000FULL)
- cmd->lp_advertising |=
- ADVERTISED_1000baseT_Full;
- }
- } else {
- cmd->lp_advertising = 0;
- }
-#endif
- } else {
- cmd->autoneg = AUTONEG_DISABLE;
- }
-
- if (tp->speed & _100bps)
- cmd->speed = SPEED_100;
- else if (tp->speed & _10bps)
- cmd->speed = SPEED_10;
- else if (tp->mii.supports_gmii && tp->speed & _1000bps)
- cmd->speed = SPEED_1000;
-
- cmd->duplex = (tp->speed & FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
-
- usb_autopm_put_interface(tp->intf);
-
-out:
- return ret;
-}
-
-static int rtl8152_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct r8152 *tp = netdev_priv(dev);
- int ret;
-
- ret = usb_autopm_get_interface(tp->intf);
- if (ret < 0)
- goto out;
-
- ret = rtl8152_set_speed(tp, cmd->autoneg, cmd->speed, cmd->duplex);
-
- usb_autopm_put_interface(tp->intf);
-
-out:
- return ret;
-}
-
-static const char rtl8152_gstrings[][ETH_GSTRING_LEN] = {
- "tx_packets",
- "rx_packets",
- "tx_errors",
- "rx_errors",
- "rx_missed",
- "align_errors",
- "tx_single_collisions",
- "tx_multi_collisions",
- "rx_unicast",
- "rx_broadcast",
- "rx_multicast",
- "tx_aborted",
- "tx_underrun",
-};
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
-static int rtl8152_get_sset_count(struct net_device *dev)
-{
- return ARRAY_SIZE(rtl8152_gstrings);
-}
-#else
-static int rtl8152_get_sset_count(struct net_device *dev, int sset)
-{
- switch (sset) {
- case ETH_SS_STATS:
- return ARRAY_SIZE(rtl8152_gstrings);
- default:
- return -EOPNOTSUPP;
- }
-}
-#endif
-
-static void rtl8152_get_ethtool_stats(struct net_device *dev,
- struct ethtool_stats *stats, u64 *data)
-{
- struct r8152 *tp = netdev_priv(dev);
- struct tally_counter tally;
-
- if (usb_autopm_get_interface(tp->intf) < 0)
- return;
-
- generic_ocp_read(tp, PLA_TALLYCNT, sizeof(tally), &tally, MCU_TYPE_PLA);
-
- usb_autopm_put_interface(tp->intf);
-
- data[0] = le64_to_cpu(tally.tx_packets);
- data[1] = le64_to_cpu(tally.rx_packets);
- data[2] = le64_to_cpu(tally.tx_errors);
- data[3] = le32_to_cpu(tally.rx_errors);
- data[4] = le16_to_cpu(tally.rx_missed);
- data[5] = le16_to_cpu(tally.align_errors);
- data[6] = le32_to_cpu(tally.tx_one_collision);
- data[7] = le32_to_cpu(tally.tx_multi_collision);
- data[8] = le64_to_cpu(tally.rx_unicast);
- data[9] = le64_to_cpu(tally.rx_broadcast);
- data[10] = le32_to_cpu(tally.rx_multicast);
- data[11] = le16_to_cpu(tally.tx_aborted);
- data[12] = le16_to_cpu(tally.tx_underun);
-}
-
-static void rtl8152_get_strings(struct net_device *dev, u32 stringset, u8 *data)
-{
- switch (stringset) {
- case ETH_SS_STATS:
- memcpy(data, *rtl8152_gstrings, sizeof(rtl8152_gstrings));
- break;
- }
-}
-
-static struct ethtool_ops ops = {
- .get_drvinfo = rtl8152_get_drvinfo,
- .get_settings = rtl8152_get_settings,
- .set_settings = rtl8152_set_settings,
- .get_link = ethtool_op_get_link,
- .get_msglevel = rtl8152_get_msglevel,
- .set_msglevel = rtl8152_set_msglevel,
- .get_wol = rtl8152_get_wol,
- .set_wol = rtl8152_set_wol,
- .get_strings = rtl8152_get_strings,
- .get_sset_count = rtl8152_get_sset_count,
- .get_ethtool_stats = rtl8152_get_ethtool_stats,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
-#ifdef NETIF_F_TSO
- .get_tso = ethtool_op_get_tso,
- .set_tso = ethtool_op_set_tso,
-#endif
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) */
-};
-
-static int rtltool_ioctl(struct r8152 *tp, struct ifreq *ifr)
-{
- struct rtltool_cmd my_cmd, *myptr;
- struct usb_device_info *uinfo;
- struct usb_device *udev;
- __le32 ocp_data;
- void *buffer;
- int ret;
-
- myptr = (struct rtltool_cmd *)ifr->ifr_data;
- if (copy_from_user(&my_cmd, myptr, sizeof(my_cmd)))
- return -EFAULT;
-
- ret = 0;
-
- switch (my_cmd.cmd) {
- case RTLTOOL_PLA_OCP_READ_DWORD:
- pla_ocp_read(tp, (u16)my_cmd.offset, sizeof(ocp_data),
- &ocp_data);
- my_cmd.data = __le32_to_cpu(ocp_data);
-
- if (copy_to_user(myptr, &my_cmd, sizeof(my_cmd))) {
- ret = -EFAULT;
- break;
- }
- break;
-
- case RTLTOOL_PLA_OCP_WRITE_DWORD:
- ocp_data = __cpu_to_le32(my_cmd.data);
- pla_ocp_real_write(tp, (u16)my_cmd.offset, (u16)my_cmd.byteen,
- sizeof(ocp_data), &ocp_data);
- break;
-
- case RTLTOOL_USB_OCP_READ_DWORD:
- usb_ocp_read(tp, (u16)my_cmd.offset, sizeof(ocp_data),
- &ocp_data);
- my_cmd.data = __le32_to_cpu(ocp_data);
-
- if (copy_to_user(myptr, &my_cmd, sizeof(my_cmd))) {
- ret = -EFAULT;
- break;
- }
- break;
-
-
- case RTLTOOL_USB_OCP_WRITE_DWORD:
- ocp_data = __cpu_to_le32(my_cmd.data);
- usb_ocp_real_write(tp, (u16)my_cmd.offset, (u16)my_cmd.byteen,
- sizeof(ocp_data), &ocp_data);
- break;
-
- case RTLTOOL_PLA_OCP_READ:
- buffer = kmalloc(my_cmd.data, GFP_KERNEL);
- if (!buffer) {
- ret = -ENOMEM;
- break;
- }
-
- pla_ocp_read(tp, (u16)my_cmd.offset, my_cmd.data, buffer);
-
- if (copy_to_user(myptr->buf, buffer, my_cmd.data))
- ret = -EFAULT;
-
- kfree(buffer);
- break;
-
- case RTLTOOL_PLA_OCP_WRITE:
- buffer = kmalloc(my_cmd.data, GFP_KERNEL);
- if (!buffer) {
- ret = -ENOMEM;
- break;
- }
-
- if (copy_from_user(buffer, myptr->buf, my_cmd.data)) {
- ret = -EFAULT;
- kfree(buffer);
- break;
- }
-
- pla_ocp_real_write(tp, (u16)my_cmd.offset, (u16)my_cmd.byteen,
- my_cmd.data, buffer);
- kfree(buffer);
- break;
-
- case RTLTOOL_USB_OCP_READ:
- buffer = kmalloc(my_cmd.data, GFP_KERNEL);
- if (!buffer) {
- ret = -ENOMEM;
- break;
- }
-
- usb_ocp_read(tp, (u16)my_cmd.offset, my_cmd.data, buffer);
-
- if (copy_to_user(myptr->buf, buffer, my_cmd.data))
- ret = -EFAULT;
-
- kfree(buffer);
- break;
-
- case RTLTOOL_USB_OCP_WRITE:
- buffer = kmalloc(my_cmd.data, GFP_KERNEL);
- if (!buffer) {
- ret = -ENOMEM;
- break;
- }
-
- if (copy_from_user(buffer, myptr->buf, my_cmd.data)) {
- ret = -EFAULT;
- kfree(buffer);
- break;
- }
-
- usb_ocp_real_write(tp, (u16)my_cmd.offset, (u16)my_cmd.byteen,
- my_cmd.data, buffer);
- kfree(buffer);
- break;
-
- case RTLTOOL_USB_INFO:
- uinfo = (struct usb_device_info *)&my_cmd.nic_info;
- udev = tp->udev;
- uinfo->idVendor = __le16_to_cpu(udev->descriptor.idVendor);
- uinfo->idProduct = __le16_to_cpu(udev->descriptor.idProduct);
- uinfo->bcdDevice = __le16_to_cpu(udev->descriptor.bcdDevice);
- memcpy(uinfo->devpath, udev->devpath, sizeof(udev->devpath));
- pla_ocp_read(tp, PLA_IDR, sizeof(uinfo->dev_addr),
- uinfo->dev_addr);
-
- if (copy_to_user(myptr, &my_cmd, sizeof(my_cmd)))
- ret = -EFAULT;
-
- break;
-
- case RTL_ENABLE_USB_DIAG:
- tp->rtk_enable_diag = 1;
- netif_info(tp, drv, tp->netdev,"enable rtk diag\n");
- break;
-
- case RTL_DISABLE_USB_DIAG:
- tp->rtk_enable_diag = 0;
- netif_info(tp, drv, tp->netdev,"disable rtk diag\n");
- break;
-
- default:
- ret = -EOPNOTSUPP;
- break;
- }
-
- return ret;
-}
-
-static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
-{
- struct r8152 *tp = netdev_priv(netdev);
- struct mii_ioctl_data *data = if_mii(rq);
- int res;
-
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return -ENODEV;
-
- res = usb_autopm_get_interface(tp->intf);
- if (res < 0)
- goto out;
-
- switch (cmd) {
- case SIOCGMIIPHY:
- data->phy_id = R8152_PHY_ID; /* Internal PHY */
- break;
-
- case SIOCGMIIREG:
- data->val_out = r8152_mdio_read(tp, data->reg_num);
- break;
-
- case SIOCSMIIREG:
- if (!capable(CAP_NET_ADMIN)) {
- res = -EPERM;
- break;
- }
- r8152_mdio_write(tp, data->reg_num, data->val_in);
- break;
-
- case SIOCDEVPRIVATE:
- res = rtltool_ioctl(tp, rq);
- break;
-
- default:
- res = -EOPNOTSUPP;
- }
-
- usb_autopm_put_interface(tp->intf);
-
-out:
- return res;
-}
-
-static int rtl8152_change_mtu(struct net_device *dev, int new_mtu)
-{
- struct r8152 *tp = netdev_priv(dev);
-
- switch (tp->version) {
- case RTL_VER_01:
- case RTL_VER_02:
- return eth_change_mtu(dev, new_mtu);
- default:
- break;
- }
-
- if (new_mtu < 68 || new_mtu > RTL8153_MAX_MTU)
- return -EINVAL;
-
- dev->mtu = new_mtu;
-
- return 0;
-}
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
-static const struct net_device_ops rtl8152_netdev_ops = {
- .ndo_open = rtl8152_open,
- .ndo_stop = rtl8152_close,
- .ndo_do_ioctl = rtl8152_ioctl,
- .ndo_start_xmit = rtl8152_start_xmit,
- .ndo_tx_timeout = rtl8152_tx_timeout,
- .ndo_set_rx_mode = rtl8152_set_rx_mode,
- .ndo_set_mac_address = rtl8152_set_mac_address,
- .ndo_change_mtu = rtl8152_change_mtu,
- .ndo_validate_addr = eth_validate_addr,
-};
-#endif
-
-static void r8152b_get_version(struct r8152 *tp)
-{
- u32 ocp_data;
- u16 version;
-
- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR1);
- version = (u16)(ocp_data & VERSION_MASK);
-
- switch (version) {
- case 0x4c00:
- tp->version = RTL_VER_01;
- break;
- case 0x4c10:
- tp->version = RTL_VER_02;
- break;
- case 0x5c00:
- tp->version = RTL_VER_03;
- tp->mii.supports_gmii = 1;
- break;
- case 0x5c10:
- tp->version = RTL_VER_04;
- tp->mii.supports_gmii = 1;
- break;
- case 0x5c20:
- tp->version = RTL_VER_05;
- tp->mii.supports_gmii = 1;
- break;
- default:
- netif_info(tp, probe, tp->netdev,
- "Unknown version 0x%04x\n", version);
- break;
- }
-}
-
-static void rtl8152_unload(struct r8152 *tp)
-{
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return;
-
- if (tp->version != RTL_VER_01)
- r8152_power_cut_en(tp, true);
-}
-
-static void rtl8153_unload(struct r8152 *tp)
-{
- if (test_bit(RTL8152_UNPLUG, &tp->flags))
- return;
-
- r8153_power_cut_en(tp, true);
-}
-
-static int rtl_ops_init(struct r8152 *tp, const struct usb_device_id *id)
-{
- struct rtl_ops *ops = &tp->rtl_ops;
- int ret = -ENODEV;
-
- switch (id->idVendor) {
- case VENDOR_ID_REALTEK:
- switch (id->idProduct) {
- case PRODUCT_ID_RTL8152:
- ops->init = r8152b_init;
- ops->enable = rtl8152_enable;
- ops->disable = rtl8152_disable;
- ops->up = rtl8152_up;
- ops->down = rtl8152_down;
- ops->unload = rtl8152_unload;
- ret = 0;
- break;
- case PRODUCT_ID_RTL8153:
- ops->init = r8153_init;
- ops->enable = rtl8153_enable;
- ops->disable = rtl8153_disable;
- ops->up = rtl8153_up;
- ops->down = rtl8153_down;
- ops->unload = rtl8153_unload;
- ret = 0;
- break;
- default:
- break;
- }
- break;
-
- case VENDOR_ID_SAMSUNG:
- switch (id->idProduct) {
- case PRODUCT_ID_SAMSUNG:
- ops->init = r8153_init;
- ops->enable = rtl8153_enable;
- ops->disable = rtl8153_disable;
- ops->up = rtl8153_up;
- ops->down = rtl8153_down;
- ops->unload = rtl8153_unload;
- ret = 0;
- break;
- default:
- break;
- }
- break;
-
- case VENDOR_ID_LENOVO:
- switch (id->idProduct) {
- case 0x7205:
- case 0x3052:
- case 0x304f:
- ops->init = r8153_init;
- ops->enable = rtl8153_enable;
- ops->disable = rtl8153_disable;
- ops->up = rtl8153_up;
- ops->down = rtl8153_down;
- ops->unload = rtl8153_unload;
- ret = 0;
- break;
- default:
- break;
- }
- break;
-
- default:
- break;
- }
-
- if (ret)
- netif_err(tp, probe, tp->netdev, "Unknown Device\n");
-
- return ret;
-}
-extern struct usb_driver cdc_driver;
-
-static int rtl8152_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct r8152 *tp;
- struct net_device *netdev;
- int ret;
-
- if (udev->actconfig->desc.bConfigurationValue != 1) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
- dev_err(&intf->dev, "The kernel too old to set configuration\n");
-#else
- usb_driver_set_configuration(udev, 1);
-#endif
- return -ENODEV;
- }
-
- usb_reset_device(udev);
- netdev = alloc_etherdev(sizeof(struct r8152));
- if (!netdev) {
- dev_err(&intf->dev, "Out of memory\n");
- return -ENOMEM;
- }
-
- SET_NETDEV_DEV(netdev, &intf->dev);
- tp = netdev_priv(netdev);
- tp->msg_enable = 0x7FFF;
-
- tp->udev = udev;
- tp->netdev = netdev;
- tp->intf = intf;
-
- ret = rtl_ops_init(tp, id);
- if (ret)
- goto out;
-
- tasklet_init(&tp->tl, bottom_half, (unsigned long)tp);
- INIT_DELAYED_WORK(&tp->schedule, rtl_work_func_t);
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
- netdev->netdev_ops = &rtl8152_netdev_ops;
-#else
- netdev->open = rtl8152_open;
- netdev->stop = rtl8152_close;
- netdev->get_stats = rtl8152_get_stats;
- netdev->hard_start_xmit = rtl8152_start_xmit;
- netdev->tx_timeout = rtl8152_tx_timeout;
- netdev->change_mtu = rtl8152_change_mtu;
- netdev->set_mac_address = rtl8152_set_mac_address;
- netdev->do_ioctl = rtl8152_ioctl;
- netdev->set_multicast_list = rtl8152_set_rx_mode;
-#endif /* HAVE_NET_DEVICE_OPS */
- netdev->watchdog_timeo = RTL8152_TX_TIMEOUT;
-
- netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
- NETIF_F_FRAGLIST | NETIF_F_IPV6_CSUM;
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
- netdev->features |= NETIF_F_TSO | NETIF_F_TSO6;
- netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38)
- netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
- NETIF_F_TSO | NETIF_F_FRAGLIST |
- NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
-#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38) */
-#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25) */
-
- netdev->ethtool_ops = &ops;
-
- tp->mii.dev = netdev;
- tp->mii.mdio_read = read_mii_word;
- tp->mii.mdio_write = write_mii_word;
- tp->mii.phy_id_mask = 0x3f;
- tp->mii.reg_num_mask = 0x1f;
- tp->mii.phy_id = R8152_PHY_ID;
- tp->mii.supports_gmii = 0;
-
- intf->needs_remote_wakeup = 1;
-
- r8152b_get_version(tp);
- tp->rtl_ops.init(tp);
- set_ethernet_addr(tp);
-
- usb_set_intfdata(intf, tp);
-
- ret = register_netdev(netdev);
- if (ret != 0) {
- netif_err(tp, probe, netdev, "couldn't register the device\n");
- goto out1;
- }
-
- tp->saved_wolopts = __rtl_get_wol(tp);
- if (tp->saved_wolopts)
- device_set_wakeup_enable(&udev->dev, true);
- else
- device_set_wakeup_enable(&udev->dev, false);
-
- netif_info(tp, probe, netdev, "%s\n", DRIVER_VERSION);
- netif_info(tp, probe, netdev, "%s\n", PATENTS);
-
- return 0;
-
-out1:
- usb_set_intfdata(intf, NULL);
-out:
- free_netdev(netdev);
- return ret;
-}
-
-static void rtl8152_disconnect(struct usb_interface *intf)
-{
- struct r8152 *tp = usb_get_intfdata(intf);
-
- usb_set_intfdata(intf, NULL);
- if (tp) {
- set_bit(RTL8152_UNPLUG, &tp->flags);
- tasklet_kill(&tp->tl);
- unregister_netdev(tp->netdev);
- tp->rtl_ops.unload(tp);
- free_netdev(tp->netdev);
- }
-}
-
-/* table of devices that work with this driver */
-static struct usb_device_id rtl8152_table[] = {
- {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8152)},
- {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8153)},
- {USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG)},
- {USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)},
- {USB_DEVICE(VENDOR_ID_LENOVO, 0x3052)},
- {USB_DEVICE(VENDOR_ID_LENOVO, 0x304f)},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, rtl8152_table);
-
-static struct usb_driver rtl8152_driver = {
- .name = MODULENAME,
- .id_table = rtl8152_table,
- .probe = rtl8152_probe,
- .disconnect = rtl8152_disconnect,
- .suspend = rtl8152_suspend,
- .resume = rtl8152_resume,
- .reset_resume = rtl8152_resume,
- .supports_autosuspend = 1,
-#if LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0)
-// .disable_hub_initiated_lpm = 1,
-#endif
-};
-
-extern struct usb_driver cdc_driver;
-static int __init usb_rtl8152_init(void)
-{
-
- usb_deregister(&cdc_driver);
-
- 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);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/rndis_host.c b/ANDROID_3.4.5/drivers/net/usb/rndis_host.c
deleted file mode 100644
index c8f1b5b3..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/rndis_host.c
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- * Host Side support for RNDIS Networking Links
- * Copyright (C) 2005 by David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/workqueue.h>
-#include <linux/slab.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/usb/cdc.h>
-#include <linux/usb/usbnet.h>
-#include <linux/usb/rndis_host.h>
-
-
-/*
- * RNDIS is NDIS remoted over USB. It's a MSFT variant of CDC ACM ... of
- * course ACM was intended for modems, not Ethernet links! USB's standard
- * for Ethernet links is "CDC Ethernet", which is significantly simpler.
- *
- * NOTE that Microsoft's "RNDIS 1.0" specification is incomplete. Issues
- * include:
- * - Power management in particular relies on information that's scattered
- * through other documentation, and which is incomplete or incorrect even
- * there.
- * - There are various undocumented protocol requirements, such as the
- * need to send unused garbage in control-OUT messages.
- * - In some cases, MS-Windows will emit undocumented requests; this
- * matters more to peripheral implementations than host ones.
- *
- * Moreover there's a no-open-specs variant of RNDIS called "ActiveSync".
- *
- * For these reasons and others, ** USE OF RNDIS IS STRONGLY DISCOURAGED ** in
- * favor of such non-proprietary alternatives as CDC Ethernet or the newer (and
- * currently rare) "Ethernet Emulation Model" (EEM).
- */
-
-/*
- * RNDIS notifications from device: command completion; "reverse"
- * keepalives; etc
- */
-void rndis_status(struct usbnet *dev, struct urb *urb)
-{
- netdev_dbg(dev->net, "rndis status urb, len %d stat %d\n",
- urb->actual_length, urb->status);
- // FIXME for keepalives, respond immediately (asynchronously)
- // if not an RNDIS status, do like cdc_status(dev,urb) does
-}
-EXPORT_SYMBOL_GPL(rndis_status);
-
-/*
- * RNDIS indicate messages.
- */
-static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
- int buflen)
-{
- struct cdc_state *info = (void *)&dev->data;
- struct device *udev = &info->control->dev;
-
- if (dev->driver_info->indication) {
- dev->driver_info->indication(dev, msg, buflen);
- } else {
- switch (msg->status) {
- case RNDIS_STATUS_MEDIA_CONNECT:
- dev_info(udev, "rndis media connect\n");
- break;
- case RNDIS_STATUS_MEDIA_DISCONNECT:
- dev_info(udev, "rndis media disconnect\n");
- break;
- default:
- dev_info(udev, "rndis indication: 0x%08x\n",
- le32_to_cpu(msg->status));
- }
- }
-}
-
-/*
- * RPC done RNDIS-style. Caller guarantees:
- * - message is properly byteswapped
- * - there's no other request pending
- * - buf can hold up to 1KB response (required by RNDIS spec)
- * On return, the first few entries are already byteswapped.
- *
- * Call context is likely probe(), before interface name is known,
- * which is why we won't try to use it in the diagnostics.
- */
-int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
-{
- struct cdc_state *info = (void *) &dev->data;
- struct usb_cdc_notification notification;
- int master_ifnum;
- int retval;
- int partial;
- unsigned count;
- __le32 rsp;
- u32 xid = 0, msg_len, request_id;
-
- /* REVISIT when this gets called from contexts other than probe() or
- * disconnect(): either serialize, or dispatch responses on xid
- */
-
- /* Issue the request; xid is unique, don't bother byteswapping it */
- if (likely(buf->msg_type != RNDIS_MSG_HALT &&
- buf->msg_type != RNDIS_MSG_RESET)) {
- xid = dev->xid++;
- if (!xid)
- xid = dev->xid++;
- buf->request_id = (__force __le32) xid;
- }
- master_ifnum = info->control->cur_altsetting->desc.bInterfaceNumber;
- retval = usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- USB_CDC_SEND_ENCAPSULATED_COMMAND,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- 0, master_ifnum,
- buf, le32_to_cpu(buf->msg_len),
- RNDIS_CONTROL_TIMEOUT_MS);
- if (unlikely(retval < 0 || xid == 0))
- return retval;
-
- /* Some devices don't respond on the control channel until
- * polled on the status channel, so do that first. */
- if (dev->driver_info->data & RNDIS_DRIVER_DATA_POLL_STATUS) {
- retval = usb_interrupt_msg(
- dev->udev,
- usb_rcvintpipe(dev->udev,
- dev->status->desc.bEndpointAddress),
- &notification, sizeof(notification), &partial,
- RNDIS_CONTROL_TIMEOUT_MS);
- if (unlikely(retval < 0))
- return retval;
- }
-
- /* Poll the control channel; the request probably completed immediately */
- rsp = buf->msg_type | RNDIS_MSG_COMPLETION;
- for (count = 0; count < 10; count++) {
- memset(buf, 0, CONTROL_BUFFER_SIZE);
- retval = usb_control_msg(dev->udev,
- usb_rcvctrlpipe(dev->udev, 0),
- USB_CDC_GET_ENCAPSULATED_RESPONSE,
- USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- 0, master_ifnum,
- buf, buflen,
- RNDIS_CONTROL_TIMEOUT_MS);
- if (likely(retval >= 8)) {
- msg_len = le32_to_cpu(buf->msg_len);
- request_id = (__force u32) buf->request_id;
- if (likely(buf->msg_type == rsp)) {
- if (likely(request_id == xid)) {
- if (unlikely(rsp == RNDIS_MSG_RESET_C))
- return 0;
- if (likely(RNDIS_STATUS_SUCCESS
- == buf->status))
- return 0;
- dev_dbg(&info->control->dev,
- "rndis reply status %08x\n",
- le32_to_cpu(buf->status));
- return -EL3RST;
- }
- dev_dbg(&info->control->dev,
- "rndis reply id %d expected %d\n",
- request_id, xid);
- /* then likely retry */
- } else switch (buf->msg_type) {
- case RNDIS_MSG_INDICATE: /* fault/event */
- rndis_msg_indicate(dev, (void *)buf, buflen);
-
- break;
- case RNDIS_MSG_KEEPALIVE: { /* ping */
- struct rndis_keepalive_c *msg = (void *)buf;
-
- msg->msg_type = RNDIS_MSG_KEEPALIVE_C;
- msg->msg_len = cpu_to_le32(sizeof *msg);
- msg->status = RNDIS_STATUS_SUCCESS;
- retval = usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- USB_CDC_SEND_ENCAPSULATED_COMMAND,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- 0, master_ifnum,
- msg, sizeof *msg,
- RNDIS_CONTROL_TIMEOUT_MS);
- if (unlikely(retval < 0))
- dev_dbg(&info->control->dev,
- "rndis keepalive err %d\n",
- retval);
- }
- break;
- default:
- dev_dbg(&info->control->dev,
- "unexpected rndis msg %08x len %d\n",
- le32_to_cpu(buf->msg_type), msg_len);
- }
- } else {
- /* device probably issued a protocol stall; ignore */
- dev_dbg(&info->control->dev,
- "rndis response error, code %d\n", retval);
- }
- msleep(20);
- }
- dev_dbg(&info->control->dev, "rndis response timeout\n");
- return -ETIMEDOUT;
-}
-EXPORT_SYMBOL_GPL(rndis_command);
-
-/*
- * rndis_query:
- *
- * Performs a query for @oid along with 0 or more bytes of payload as
- * specified by @in_len. If @reply_len is not set to -1 then the reply
- * length is checked against this value, resulting in an error if it
- * doesn't match.
- *
- * NOTE: Adding a payload exactly or greater than the size of the expected
- * response payload is an evident requirement MSFT added for ActiveSync.
- *
- * The only exception is for OIDs that return a variably sized response,
- * in which case no payload should be added. This undocumented (and
- * nonsensical!) issue was found by sniffing protocol requests from the
- * ActiveSync 4.1 Windows driver.
- */
-static int rndis_query(struct usbnet *dev, struct usb_interface *intf,
- void *buf, __le32 oid, u32 in_len,
- void **reply, int *reply_len)
-{
- int retval;
- union {
- void *buf;
- struct rndis_msg_hdr *header;
- struct rndis_query *get;
- struct rndis_query_c *get_c;
- } u;
- u32 off, len;
-
- u.buf = buf;
-
- memset(u.get, 0, sizeof *u.get + in_len);
- u.get->msg_type = RNDIS_MSG_QUERY;
- u.get->msg_len = cpu_to_le32(sizeof *u.get + in_len);
- u.get->oid = oid;
- u.get->len = cpu_to_le32(in_len);
- u.get->offset = cpu_to_le32(20);
-
- retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
- if (unlikely(retval < 0)) {
- dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) failed, %d\n",
- oid, retval);
- return retval;
- }
-
- off = le32_to_cpu(u.get_c->offset);
- len = le32_to_cpu(u.get_c->len);
- if (unlikely((8 + off + len) > CONTROL_BUFFER_SIZE))
- goto response_error;
-
- if (*reply_len != -1 && len != *reply_len)
- goto response_error;
-
- *reply = (unsigned char *) &u.get_c->request_id + off;
- *reply_len = len;
-
- return retval;
-
-response_error:
- dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) "
- "invalid response - off %d len %d\n",
- oid, off, len);
- return -EDOM;
-}
-
-/* same as usbnet_netdev_ops but MTU change not allowed */
-static const struct net_device_ops rndis_netdev_ops = {
- .ndo_open = usbnet_open,
- .ndo_stop = usbnet_stop,
- .ndo_start_xmit = usbnet_start_xmit,
- .ndo_tx_timeout = usbnet_tx_timeout,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-int
-generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
-{
- int retval;
- struct net_device *net = dev->net;
- struct cdc_state *info = (void *) &dev->data;
- union {
- void *buf;
- struct rndis_msg_hdr *header;
- struct rndis_init *init;
- struct rndis_init_c *init_c;
- struct rndis_query *get;
- struct rndis_query_c *get_c;
- struct rndis_set *set;
- struct rndis_set_c *set_c;
- struct rndis_halt *halt;
- } u;
- u32 tmp;
- __le32 phym_unspec, *phym;
- int reply_len;
- unsigned char *bp;
-
- /* we can't rely on i/o from stack working, or stack allocation */
- u.buf = kmalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
- if (!u.buf)
- return -ENOMEM;
- retval = usbnet_generic_cdc_bind(dev, intf);
- if (retval < 0)
- goto fail;
-
- u.init->msg_type = RNDIS_MSG_INIT;
- u.init->msg_len = cpu_to_le32(sizeof *u.init);
- u.init->major_version = cpu_to_le32(1);
- u.init->minor_version = cpu_to_le32(0);
-
- /* max transfer (in spec) is 0x4000 at full speed, but for
- * TX we'll stick to one Ethernet packet plus RNDIS framing.
- * For RX we handle drivers that zero-pad to end-of-packet.
- * Don't let userspace change these settings.
- *
- * NOTE: there still seems to be wierdness here, as if we need
- * to do some more things to make sure WinCE targets accept this.
- * They default to jumbograms of 8KB or 16KB, which is absurd
- * for such low data rates and which is also more than Linux
- * can usually expect to allocate for SKB data...
- */
- net->hard_header_len += sizeof (struct rndis_data_hdr);
- dev->hard_mtu = net->mtu + net->hard_header_len;
-
- dev->maxpacket = usb_maxpacket(dev->udev, dev->out, 1);
- if (dev->maxpacket == 0) {
- netif_dbg(dev, probe, dev->net,
- "dev->maxpacket can't be 0\n");
- retval = -EINVAL;
- goto fail_and_release;
- }
-
- dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1);
- dev->rx_urb_size &= ~(dev->maxpacket - 1);
- u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size);
-
- net->netdev_ops = &rndis_netdev_ops;
-
- retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
- if (unlikely(retval < 0)) {
- /* it might not even be an RNDIS device!! */
- dev_err(&intf->dev, "RNDIS init failed, %d\n", retval);
- goto fail_and_release;
- }
- tmp = le32_to_cpu(u.init_c->max_transfer_size);
- if (tmp < dev->hard_mtu) {
- if (tmp <= net->hard_header_len) {
- dev_err(&intf->dev,
- "dev can't take %u byte packets (max %u)\n",
- dev->hard_mtu, tmp);
- retval = -EINVAL;
- goto halt_fail_and_release;
- }
- dev_warn(&intf->dev,
- "dev can't take %u byte packets (max %u), "
- "adjusting MTU to %u\n",
- dev->hard_mtu, tmp, tmp - net->hard_header_len);
- dev->hard_mtu = tmp;
- net->mtu = dev->hard_mtu - net->hard_header_len;
- }
-
- /* REVISIT: peripheral "alignment" request is ignored ... */
- dev_dbg(&intf->dev,
- "hard mtu %u (%u from dev), rx buflen %Zu, align %d\n",
- dev->hard_mtu, tmp, dev->rx_urb_size,
- 1 << le32_to_cpu(u.init_c->packet_alignment));
-
- /* module has some device initialization code needs to be done right
- * after RNDIS_INIT */
- if (dev->driver_info->early_init &&
- dev->driver_info->early_init(dev) != 0)
- goto halt_fail_and_release;
-
- /* Check physical medium */
- phym = NULL;
- reply_len = sizeof *phym;
- retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM,
- 0, (void **) &phym, &reply_len);
- if (retval != 0 || !phym) {
- /* OID is optional so don't fail here. */
- phym_unspec = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED;
- phym = &phym_unspec;
- }
- if ((flags & FLAG_RNDIS_PHYM_WIRELESS) &&
- *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
- netif_dbg(dev, probe, dev->net,
- "driver requires wireless physical medium, but device is not\n");
- retval = -ENODEV;
- goto halt_fail_and_release;
- }
- if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) &&
- *phym == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
- netif_dbg(dev, probe, dev->net,
- "driver requires non-wireless physical medium, but device is wireless.\n");
- retval = -ENODEV;
- goto halt_fail_and_release;
- }
-
- /* Get designated host ethernet address */
- reply_len = ETH_ALEN;
- retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS,
- 48, (void **) &bp, &reply_len);
- if (unlikely(retval< 0)) {
- dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval);
- goto halt_fail_and_release;
- }
- memcpy(net->dev_addr, bp, ETH_ALEN);
- memcpy(net->perm_addr, bp, ETH_ALEN);
-
- /* set a nonzero filter to enable data transfers */
- memset(u.set, 0, sizeof *u.set);
- u.set->msg_type = RNDIS_MSG_SET;
- u.set->msg_len = cpu_to_le32(4 + sizeof *u.set);
- u.set->oid = OID_GEN_CURRENT_PACKET_FILTER;
- u.set->len = cpu_to_le32(4);
- u.set->offset = cpu_to_le32((sizeof *u.set) - 8);
- *(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER;
-
- retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
- if (unlikely(retval < 0)) {
- dev_err(&intf->dev, "rndis set packet filter, %d\n", retval);
- goto halt_fail_and_release;
- }
-
- retval = 0;
-
- kfree(u.buf);
- return retval;
-
-halt_fail_and_release:
- memset(u.halt, 0, sizeof *u.halt);
- u.halt->msg_type = RNDIS_MSG_HALT;
- u.halt->msg_len = cpu_to_le32(sizeof *u.halt);
- (void) rndis_command(dev, (void *)u.halt, CONTROL_BUFFER_SIZE);
-fail_and_release:
- usb_set_intfdata(info->data, NULL);
- usb_driver_release_interface(driver_of(intf), info->data);
- info->data = NULL;
-fail:
- kfree(u.buf);
- return retval;
-}
-EXPORT_SYMBOL_GPL(generic_rndis_bind);
-
-static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- return generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_NOT_WIRELESS);
-}
-
-void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
-{
- struct rndis_halt *halt;
-
- /* try to clear any rndis state/activity (no i/o from stack!) */
- halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
- if (halt) {
- halt->msg_type = RNDIS_MSG_HALT;
- halt->msg_len = cpu_to_le32(sizeof *halt);
- (void) rndis_command(dev, (void *)halt, CONTROL_BUFFER_SIZE);
- kfree(halt);
- }
-
- usbnet_cdc_unbind(dev, intf);
-}
-EXPORT_SYMBOL_GPL(rndis_unbind);
-
-/*
- * DATA -- host must not write zlps
- */
-int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- /* peripheral may have batched packets to us... */
- while (likely(skb->len)) {
- struct rndis_data_hdr *hdr = (void *)skb->data;
- struct sk_buff *skb2;
- u32 msg_len, data_offset, data_len;
-
- msg_len = le32_to_cpu(hdr->msg_len);
- data_offset = le32_to_cpu(hdr->data_offset);
- data_len = le32_to_cpu(hdr->data_len);
-
- /* don't choke if we see oob, per-packet data, etc */
- if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET ||
- skb->len < msg_len ||
- (data_offset + data_len + 8) > msg_len)) {
- dev->net->stats.rx_frame_errors++;
- netdev_dbg(dev->net, "bad rndis message %d/%d/%d/%d, len %d\n",
- le32_to_cpu(hdr->msg_type),
- msg_len, data_offset, data_len, skb->len);
- return 0;
- }
- skb_pull(skb, 8 + data_offset);
-
- /* at most one packet left? */
- if (likely((data_len - skb->len) <= sizeof *hdr)) {
- skb_trim(skb, data_len);
- break;
- }
-
- /* try to return all the packets in the batch */
- skb2 = skb_clone(skb, GFP_ATOMIC);
- if (unlikely(!skb2))
- break;
- skb_pull(skb, msg_len - sizeof *hdr);
- skb_trim(skb2, data_len);
- usbnet_skb_return(dev, skb2);
- }
-
- /* caller will usbnet_skb_return the remaining packet */
- return 1;
-}
-EXPORT_SYMBOL_GPL(rndis_rx_fixup);
-
-struct sk_buff *
-rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
-{
- struct rndis_data_hdr *hdr;
- struct sk_buff *skb2;
- unsigned len = skb->len;
-
- if (likely(!skb_cloned(skb))) {
- int room = skb_headroom(skb);
-
- /* enough head room as-is? */
- if (unlikely((sizeof *hdr) <= room))
- goto fill;
-
- /* enough room, but needs to be readjusted? */
- room += skb_tailroom(skb);
- if (likely((sizeof *hdr) <= room)) {
- skb->data = memmove(skb->head + sizeof *hdr,
- skb->data, len);
- skb_set_tail_pointer(skb, len);
- goto fill;
- }
- }
-
- /* create a new skb, with the correct size (and tailpad) */
- skb2 = skb_copy_expand(skb, sizeof *hdr, 1, flags);
- dev_kfree_skb_any(skb);
- if (unlikely(!skb2))
- return skb2;
- skb = skb2;
-
- /* fill out the RNDIS header. we won't bother trying to batch
- * packets; Linux minimizes wasted bandwidth through tx queues.
- */
-fill:
- hdr = (void *) __skb_push(skb, sizeof *hdr);
- memset(hdr, 0, sizeof *hdr);
- hdr->msg_type = RNDIS_MSG_PACKET;
- hdr->msg_len = cpu_to_le32(skb->len);
- hdr->data_offset = cpu_to_le32(sizeof(*hdr) - 8);
- hdr->data_len = cpu_to_le32(len);
-
- /* FIXME make the last packet always be short ... */
- return skb;
-}
-EXPORT_SYMBOL_GPL(rndis_tx_fixup);
-
-
-static const struct driver_info rndis_info = {
- .description = "RNDIS device",
- .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
- .bind = rndis_bind,
- .unbind = rndis_unbind,
- .status = rndis_status,
- .rx_fixup = rndis_rx_fixup,
- .tx_fixup = rndis_tx_fixup,
-};
-
-static const struct driver_info rndis_poll_status_info = {
- .description = "RNDIS device (poll status before control)",
- .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
- .data = RNDIS_DRIVER_DATA_POLL_STATUS,
- .bind = rndis_bind,
- .unbind = rndis_unbind,
- .status = rndis_status,
- .rx_fixup = rndis_rx_fixup,
- .tx_fixup = rndis_tx_fixup,
-};
-
-/*-------------------------------------------------------------------------*/
-
-static const struct usb_device_id products [] = {
-{
- /* 2Wire HomePortal 1000SW */
- USB_DEVICE_AND_INTERFACE_INFO(0x1630, 0x0042,
- USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
- .driver_info = (unsigned long) &rndis_poll_status_info,
-}, {
- /* RNDIS is MSFT's un-official variant of CDC ACM */
- USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
- .driver_info = (unsigned long) &rndis_info,
-}, {
- /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
- USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
- .driver_info = (unsigned long) &rndis_poll_status_info,
-}, {
- /* RNDIS for tethering */
- USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
- .driver_info = (unsigned long) &rndis_info,
-},
- { }, // END
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver rndis_driver = {
- .name = "rndis_host",
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
-};
-
-module_usb_driver(rndis_driver);
-
-MODULE_AUTHOR("David Brownell");
-MODULE_DESCRIPTION("USB Host side RNDIS driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/rtl8150.c b/ANDROID_3.4.5/drivers/net/usb/rtl8150.c
deleted file mode 100644
index d363b310..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/rtl8150.c
+++ /dev/null
@@ -1,957 +0,0 @@
-/*
- * Copyright (c) 2002 Petko Manolov (petkan@users.sourceforge.net)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/signal.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/mii.h>
-#include <linux/ethtool.h>
-#include <linux/usb.h>
-#include <asm/uaccess.h>
-
-/* Version Information */
-#define DRIVER_VERSION "v0.6.2 (2004/08/27)"
-#define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
-#define DRIVER_DESC "rtl8150 based usb-ethernet driver"
-
-#define IDR 0x0120
-#define MAR 0x0126
-#define CR 0x012e
-#define TCR 0x012f
-#define RCR 0x0130
-#define TSR 0x0132
-#define RSR 0x0133
-#define CON0 0x0135
-#define CON1 0x0136
-#define MSR 0x0137
-#define PHYADD 0x0138
-#define PHYDAT 0x0139
-#define PHYCNT 0x013b
-#define GPPC 0x013d
-#define BMCR 0x0140
-#define BMSR 0x0142
-#define ANAR 0x0144
-#define ANLP 0x0146
-#define AER 0x0148
-#define CSCR 0x014C /* This one has the link status */
-#define CSCR_LINK_STATUS (1 << 3)
-
-#define IDR_EEPROM 0x1202
-
-#define PHY_READ 0
-#define PHY_WRITE 0x20
-#define PHY_GO 0x40
-
-#define MII_TIMEOUT 10
-#define INTBUFSIZE 8
-
-#define RTL8150_REQT_READ 0xc0
-#define RTL8150_REQT_WRITE 0x40
-#define RTL8150_REQ_GET_REGS 0x05
-#define RTL8150_REQ_SET_REGS 0x05
-
-
-/* Transmit status register errors */
-#define TSR_ECOL (1<<5)
-#define TSR_LCOL (1<<4)
-#define TSR_LOSS_CRS (1<<3)
-#define TSR_JBR (1<<2)
-#define TSR_ERRORS (TSR_ECOL | TSR_LCOL | TSR_LOSS_CRS | TSR_JBR)
-/* Receive status register errors */
-#define RSR_CRC (1<<2)
-#define RSR_FAE (1<<1)
-#define RSR_ERRORS (RSR_CRC | RSR_FAE)
-
-/* Media status register definitions */
-#define MSR_DUPLEX (1<<4)
-#define MSR_SPEED (1<<3)
-#define MSR_LINK (1<<2)
-
-/* Interrupt pipe data */
-#define INT_TSR 0x00
-#define INT_RSR 0x01
-#define INT_MSR 0x02
-#define INT_WAKSR 0x03
-#define INT_TXOK_CNT 0x04
-#define INT_RXLOST_CNT 0x05
-#define INT_CRERR_CNT 0x06
-#define INT_COL_CNT 0x07
-
-
-#define RTL8150_MTU 1540
-#define RTL8150_TX_TIMEOUT (HZ)
-#define RX_SKB_POOL_SIZE 4
-
-/* rtl8150 flags */
-#define RTL8150_HW_CRC 0
-#define RX_REG_SET 1
-#define RTL8150_UNPLUG 2
-#define RX_URB_FAIL 3
-
-/* Define these values to match your device */
-#define VENDOR_ID_REALTEK 0x0bda
-#define VENDOR_ID_MELCO 0x0411
-#define VENDOR_ID_MICRONET 0x3980
-#define VENDOR_ID_LONGSHINE 0x07b8
-#define VENDOR_ID_OQO 0x1557
-#define VENDOR_ID_ZYXEL 0x0586
-
-#define PRODUCT_ID_RTL8150 0x8150
-#define PRODUCT_ID_LUAKTX 0x0012
-#define PRODUCT_ID_LCS8138TX 0x401a
-#define PRODUCT_ID_SP128AR 0x0003
-#define PRODUCT_ID_PRESTIGE 0x401a
-
-#undef EEPROM_WRITE
-
-/* table of devices that work with this driver */
-static struct usb_device_id rtl8150_table[] = {
- {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8150)},
- {USB_DEVICE(VENDOR_ID_MELCO, PRODUCT_ID_LUAKTX)},
- {USB_DEVICE(VENDOR_ID_MICRONET, PRODUCT_ID_SP128AR)},
- {USB_DEVICE(VENDOR_ID_LONGSHINE, PRODUCT_ID_LCS8138TX)},
- {USB_DEVICE(VENDOR_ID_OQO, PRODUCT_ID_RTL8150)},
- {USB_DEVICE(VENDOR_ID_ZYXEL, PRODUCT_ID_PRESTIGE)},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, rtl8150_table);
-
-struct rtl8150 {
- unsigned long flags;
- struct usb_device *udev;
- struct tasklet_struct tl;
- struct net_device *netdev;
- struct urb *rx_urb, *tx_urb, *intr_urb, *ctrl_urb;
- struct sk_buff *tx_skb, *rx_skb;
- struct sk_buff *rx_skb_pool[RX_SKB_POOL_SIZE];
- spinlock_t rx_pool_lock;
- struct usb_ctrlrequest dr;
- int intr_interval;
- __le16 rx_creg;
- u8 *intr_buff;
- u8 phy;
-};
-
-typedef struct rtl8150 rtl8150_t;
-
-static const char driver_name [] = "rtl8150";
-
-/*
-**
-** device related part of the code
-**
-*/
-static int get_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
-{
- return usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
- RTL8150_REQ_GET_REGS, RTL8150_REQT_READ,
- indx, 0, data, size, 500);
-}
-
-static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
-{
- return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
- RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE,
- indx, 0, data, size, 500);
-}
-
-static void ctrl_callback(struct urb *urb)
-{
- rtl8150_t *dev;
- int status = urb->status;
-
- switch (status) {
- case 0:
- break;
- case -EINPROGRESS:
- break;
- case -ENOENT:
- break;
- default:
- if (printk_ratelimit())
- dev_warn(&urb->dev->dev, "ctrl urb status %d\n", status);
- }
- dev = urb->context;
- clear_bit(RX_REG_SET, &dev->flags);
-}
-
-static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size)
-{
- int ret;
-
- if (test_bit(RX_REG_SET, &dev->flags))
- return -EAGAIN;
-
- dev->dr.bRequestType = RTL8150_REQT_WRITE;
- dev->dr.bRequest = RTL8150_REQ_SET_REGS;
- dev->dr.wValue = cpu_to_le16(indx);
- dev->dr.wIndex = 0;
- dev->dr.wLength = cpu_to_le16(size);
- dev->ctrl_urb->transfer_buffer_length = size;
- usb_fill_control_urb(dev->ctrl_urb, dev->udev,
- usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr,
- &dev->rx_creg, size, ctrl_callback, dev);
- if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) {
- if (ret == -ENODEV)
- netif_device_detach(dev->netdev);
- err("control request submission failed: %d", ret);
- } else
- set_bit(RX_REG_SET, &dev->flags);
-
- return ret;
-}
-
-static int read_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 * reg)
-{
- int i;
- u8 data[3], tmp;
-
- data[0] = phy;
- data[1] = data[2] = 0;
- tmp = indx | PHY_READ | PHY_GO;
- i = 0;
-
- set_registers(dev, PHYADD, sizeof(data), data);
- set_registers(dev, PHYCNT, 1, &tmp);
- do {
- get_registers(dev, PHYCNT, 1, data);
- } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT));
-
- if (i <= MII_TIMEOUT) {
- get_registers(dev, PHYDAT, 2, data);
- *reg = data[0] | (data[1] << 8);
- return 0;
- } else
- return 1;
-}
-
-static int write_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 reg)
-{
- int i;
- u8 data[3], tmp;
-
- data[0] = phy;
- data[1] = reg & 0xff;
- data[2] = (reg >> 8) & 0xff;
- tmp = indx | PHY_WRITE | PHY_GO;
- i = 0;
-
- set_registers(dev, PHYADD, sizeof(data), data);
- set_registers(dev, PHYCNT, 1, &tmp);
- do {
- get_registers(dev, PHYCNT, 1, data);
- } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT));
-
- if (i <= MII_TIMEOUT)
- return 0;
- else
- return 1;
-}
-
-static inline void set_ethernet_addr(rtl8150_t * dev)
-{
- u8 node_id[6];
-
- get_registers(dev, IDR, sizeof(node_id), node_id);
- memcpy(dev->netdev->dev_addr, node_id, sizeof(node_id));
-}
-
-static int rtl8150_set_mac_address(struct net_device *netdev, void *p)
-{
- struct sockaddr *addr = p;
- rtl8150_t *dev = netdev_priv(netdev);
-
- if (netif_running(netdev))
- return -EBUSY;
-
- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
- dbg("%s: Setting MAC address to %pM\n", netdev->name, netdev->dev_addr);
- /* Set the IDR registers. */
- set_registers(dev, IDR, netdev->addr_len, netdev->dev_addr);
-#ifdef EEPROM_WRITE
- {
- int i;
- u8 cr;
- /* Get the CR contents. */
- get_registers(dev, CR, 1, &cr);
- /* Set the WEPROM bit (eeprom write enable). */
- cr |= 0x20;
- set_registers(dev, CR, 1, &cr);
- /* Write the MAC address into eeprom. Eeprom writes must be word-sized,
- so we need to split them up. */
- for (i = 0; i * 2 < netdev->addr_len; i++) {
- set_registers(dev, IDR_EEPROM + (i * 2), 2,
- netdev->dev_addr + (i * 2));
- }
- /* Clear the WEPROM bit (preventing accidental eeprom writes). */
- cr &= 0xdf;
- set_registers(dev, CR, 1, &cr);
- }
-#endif
- return 0;
-}
-
-static int rtl8150_reset(rtl8150_t * dev)
-{
- u8 data = 0x10;
- int i = HZ;
-
- set_registers(dev, CR, 1, &data);
- do {
- get_registers(dev, CR, 1, &data);
- } while ((data & 0x10) && --i);
-
- return (i > 0) ? 1 : 0;
-}
-
-static int alloc_all_urbs(rtl8150_t * dev)
-{
- dev->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->rx_urb)
- return 0;
- dev->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->tx_urb) {
- usb_free_urb(dev->rx_urb);
- return 0;
- }
- dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->intr_urb) {
- usb_free_urb(dev->rx_urb);
- usb_free_urb(dev->tx_urb);
- return 0;
- }
- dev->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->ctrl_urb) {
- usb_free_urb(dev->rx_urb);
- usb_free_urb(dev->tx_urb);
- usb_free_urb(dev->intr_urb);
- return 0;
- }
-
- return 1;
-}
-
-static void free_all_urbs(rtl8150_t * dev)
-{
- usb_free_urb(dev->rx_urb);
- usb_free_urb(dev->tx_urb);
- usb_free_urb(dev->intr_urb);
- usb_free_urb(dev->ctrl_urb);
-}
-
-static void unlink_all_urbs(rtl8150_t * dev)
-{
- usb_kill_urb(dev->rx_urb);
- usb_kill_urb(dev->tx_urb);
- usb_kill_urb(dev->intr_urb);
- usb_kill_urb(dev->ctrl_urb);
-}
-
-static inline struct sk_buff *pull_skb(rtl8150_t *dev)
-{
- struct sk_buff *skb;
- int i;
-
- for (i = 0; i < RX_SKB_POOL_SIZE; i++) {
- if (dev->rx_skb_pool[i]) {
- skb = dev->rx_skb_pool[i];
- dev->rx_skb_pool[i] = NULL;
- return skb;
- }
- }
- return NULL;
-}
-
-static void read_bulk_callback(struct urb *urb)
-{
- rtl8150_t *dev;
- unsigned pkt_len, res;
- struct sk_buff *skb;
- struct net_device *netdev;
- u16 rx_stat;
- int status = urb->status;
- int result;
-
- dev = urb->context;
- if (!dev)
- return;
- if (test_bit(RTL8150_UNPLUG, &dev->flags))
- return;
- netdev = dev->netdev;
- if (!netif_device_present(netdev))
- return;
-
- switch (status) {
- case 0:
- break;
- case -ENOENT:
- return; /* the urb is in unlink state */
- case -ETIME:
- if (printk_ratelimit())
- dev_warn(&urb->dev->dev, "may be reset is needed?..\n");
- goto goon;
- default:
- if (printk_ratelimit())
- dev_warn(&urb->dev->dev, "Rx status %d\n", status);
- goto goon;
- }
-
- if (!dev->rx_skb)
- goto resched;
- /* protect against short packets (tell me why we got some?!?) */
- if (urb->actual_length < 4)
- goto goon;
-
- res = urb->actual_length;
- rx_stat = le16_to_cpu(*(__le16 *)(urb->transfer_buffer + res - 4));
- pkt_len = res - 4;
-
- skb_put(dev->rx_skb, pkt_len);
- dev->rx_skb->protocol = eth_type_trans(dev->rx_skb, netdev);
- netif_rx(dev->rx_skb);
- netdev->stats.rx_packets++;
- netdev->stats.rx_bytes += pkt_len;
-
- spin_lock(&dev->rx_pool_lock);
- skb = pull_skb(dev);
- spin_unlock(&dev->rx_pool_lock);
- if (!skb)
- goto resched;
-
- dev->rx_skb = skb;
-goon:
- usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
- dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
- result = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
- if (result == -ENODEV)
- netif_device_detach(dev->netdev);
- else if (result) {
- set_bit(RX_URB_FAIL, &dev->flags);
- goto resched;
- } else {
- clear_bit(RX_URB_FAIL, &dev->flags);
- }
-
- return;
-resched:
- tasklet_schedule(&dev->tl);
-}
-
-static void write_bulk_callback(struct urb *urb)
-{
- rtl8150_t *dev;
- int status = urb->status;
-
- dev = urb->context;
- if (!dev)
- return;
- dev_kfree_skb_irq(dev->tx_skb);
- if (!netif_device_present(dev->netdev))
- return;
- if (status)
- dev_info(&urb->dev->dev, "%s: Tx status %d\n",
- dev->netdev->name, status);
- dev->netdev->trans_start = jiffies;
- netif_wake_queue(dev->netdev);
-}
-
-static void intr_callback(struct urb *urb)
-{
- rtl8150_t *dev;
- __u8 *d;
- int status = urb->status;
- int res;
-
- dev = urb->context;
- if (!dev)
- return;
- switch (status) {
- case 0: /* success */
- break;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- /* -EPIPE: should clear the halt */
- default:
- dev_info(&urb->dev->dev, "%s: intr status %d\n",
- dev->netdev->name, status);
- goto resubmit;
- }
-
- d = urb->transfer_buffer;
- if (d[0] & TSR_ERRORS) {
- dev->netdev->stats.tx_errors++;
- if (d[INT_TSR] & (TSR_ECOL | TSR_JBR))
- dev->netdev->stats.tx_aborted_errors++;
- if (d[INT_TSR] & TSR_LCOL)
- dev->netdev->stats.tx_window_errors++;
- if (d[INT_TSR] & TSR_LOSS_CRS)
- dev->netdev->stats.tx_carrier_errors++;
- }
- /* Report link status changes to the network stack */
- if ((d[INT_MSR] & MSR_LINK) == 0) {
- if (netif_carrier_ok(dev->netdev)) {
- netif_carrier_off(dev->netdev);
- dbg("%s: LINK LOST\n", __func__);
- }
- } else {
- if (!netif_carrier_ok(dev->netdev)) {
- netif_carrier_on(dev->netdev);
- dbg("%s: LINK CAME BACK\n", __func__);
- }
- }
-
-resubmit:
- res = usb_submit_urb (urb, GFP_ATOMIC);
- if (res == -ENODEV)
- netif_device_detach(dev->netdev);
- else if (res)
- err ("can't resubmit intr, %s-%s/input0, status %d",
- dev->udev->bus->bus_name,
- dev->udev->devpath, res);
-}
-
-static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message)
-{
- rtl8150_t *dev = usb_get_intfdata(intf);
-
- netif_device_detach(dev->netdev);
-
- if (netif_running(dev->netdev)) {
- usb_kill_urb(dev->rx_urb);
- usb_kill_urb(dev->intr_urb);
- }
- return 0;
-}
-
-static int rtl8150_resume(struct usb_interface *intf)
-{
- rtl8150_t *dev = usb_get_intfdata(intf);
-
- netif_device_attach(dev->netdev);
- if (netif_running(dev->netdev)) {
- dev->rx_urb->status = 0;
- dev->rx_urb->actual_length = 0;
- read_bulk_callback(dev->rx_urb);
-
- dev->intr_urb->status = 0;
- dev->intr_urb->actual_length = 0;
- intr_callback(dev->intr_urb);
- }
- return 0;
-}
-
-/*
-**
-** network related part of the code
-**
-*/
-
-static void fill_skb_pool(rtl8150_t *dev)
-{
- struct sk_buff *skb;
- int i;
-
- for (i = 0; i < RX_SKB_POOL_SIZE; i++) {
- if (dev->rx_skb_pool[i])
- continue;
- skb = dev_alloc_skb(RTL8150_MTU + 2);
- if (!skb) {
- return;
- }
- skb_reserve(skb, 2);
- dev->rx_skb_pool[i] = skb;
- }
-}
-
-static void free_skb_pool(rtl8150_t *dev)
-{
- int i;
-
- for (i = 0; i < RX_SKB_POOL_SIZE; i++)
- if (dev->rx_skb_pool[i])
- dev_kfree_skb(dev->rx_skb_pool[i]);
-}
-
-static void rx_fixup(unsigned long data)
-{
- struct rtl8150 *dev = (struct rtl8150 *)data;
- struct sk_buff *skb;
- int status;
-
- spin_lock_irq(&dev->rx_pool_lock);
- fill_skb_pool(dev);
- spin_unlock_irq(&dev->rx_pool_lock);
- if (test_bit(RX_URB_FAIL, &dev->flags))
- if (dev->rx_skb)
- goto try_again;
- spin_lock_irq(&dev->rx_pool_lock);
- skb = pull_skb(dev);
- spin_unlock_irq(&dev->rx_pool_lock);
- if (skb == NULL)
- goto tlsched;
- dev->rx_skb = skb;
- usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
- dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
-try_again:
- status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
- if (status == -ENODEV) {
- netif_device_detach(dev->netdev);
- } else if (status) {
- set_bit(RX_URB_FAIL, &dev->flags);
- goto tlsched;
- } else {
- clear_bit(RX_URB_FAIL, &dev->flags);
- }
-
- return;
-tlsched:
- tasklet_schedule(&dev->tl);
-}
-
-static int enable_net_traffic(rtl8150_t * dev)
-{
- u8 cr, tcr, rcr, msr;
-
- if (!rtl8150_reset(dev)) {
- dev_warn(&dev->udev->dev, "device reset failed\n");
- }
- /* RCR bit7=1 attach Rx info at the end; =0 HW CRC (which is broken) */
- rcr = 0x9e;
- dev->rx_creg = cpu_to_le16(rcr);
- tcr = 0xd8;
- cr = 0x0c;
- if (!(rcr & 0x80))
- set_bit(RTL8150_HW_CRC, &dev->flags);
- set_registers(dev, RCR, 1, &rcr);
- set_registers(dev, TCR, 1, &tcr);
- set_registers(dev, CR, 1, &cr);
- get_registers(dev, MSR, 1, &msr);
-
- return 0;
-}
-
-static void disable_net_traffic(rtl8150_t * dev)
-{
- u8 cr;
-
- get_registers(dev, CR, 1, &cr);
- cr &= 0xf3;
- set_registers(dev, CR, 1, &cr);
-}
-
-static void rtl8150_tx_timeout(struct net_device *netdev)
-{
- rtl8150_t *dev = netdev_priv(netdev);
- dev_warn(&netdev->dev, "Tx timeout.\n");
- usb_unlink_urb(dev->tx_urb);
- netdev->stats.tx_errors++;
-}
-
-static void rtl8150_set_multicast(struct net_device *netdev)
-{
- rtl8150_t *dev = netdev_priv(netdev);
- netif_stop_queue(netdev);
- if (netdev->flags & IFF_PROMISC) {
- dev->rx_creg |= cpu_to_le16(0x0001);
- dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name);
- } else if (!netdev_mc_empty(netdev) ||
- (netdev->flags & IFF_ALLMULTI)) {
- dev->rx_creg &= cpu_to_le16(0xfffe);
- dev->rx_creg |= cpu_to_le16(0x0002);
- dev_info(&netdev->dev, "%s: allmulti set\n", netdev->name);
- } else {
- /* ~RX_MULTICAST, ~RX_PROMISCUOUS */
- dev->rx_creg &= cpu_to_le16(0x00fc);
- }
- async_set_registers(dev, RCR, 2);
- netif_wake_queue(netdev);
-}
-
-static netdev_tx_t rtl8150_start_xmit(struct sk_buff *skb,
- struct net_device *netdev)
-{
- rtl8150_t *dev = netdev_priv(netdev);
- int count, res;
-
- netif_stop_queue(netdev);
- count = (skb->len < 60) ? 60 : skb->len;
- count = (count & 0x3f) ? count : count + 1;
- dev->tx_skb = skb;
- usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2),
- skb->data, count, write_bulk_callback, dev);
- if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) {
- /* Can we get/handle EPIPE here? */
- if (res == -ENODEV)
- netif_device_detach(dev->netdev);
- else {
- dev_warn(&netdev->dev, "failed tx_urb %d\n", res);
- netdev->stats.tx_errors++;
- netif_start_queue(netdev);
- }
- } else {
- netdev->stats.tx_packets++;
- netdev->stats.tx_bytes += skb->len;
- netdev->trans_start = jiffies;
- }
-
- return NETDEV_TX_OK;
-}
-
-
-static void set_carrier(struct net_device *netdev)
-{
- rtl8150_t *dev = netdev_priv(netdev);
- short tmp;
-
- get_registers(dev, CSCR, 2, &tmp);
- if (tmp & CSCR_LINK_STATUS)
- netif_carrier_on(netdev);
- else
- netif_carrier_off(netdev);
-}
-
-static int rtl8150_open(struct net_device *netdev)
-{
- rtl8150_t *dev = netdev_priv(netdev);
- int res;
-
- if (dev->rx_skb == NULL)
- dev->rx_skb = pull_skb(dev);
- if (!dev->rx_skb)
- return -ENOMEM;
-
- set_registers(dev, IDR, 6, netdev->dev_addr);
-
- usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
- dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
- if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) {
- if (res == -ENODEV)
- netif_device_detach(dev->netdev);
- dev_warn(&netdev->dev, "rx_urb submit failed: %d\n", res);
- return res;
- }
- usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3),
- dev->intr_buff, INTBUFSIZE, intr_callback,
- dev, dev->intr_interval);
- if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) {
- if (res == -ENODEV)
- netif_device_detach(dev->netdev);
- dev_warn(&netdev->dev, "intr_urb submit failed: %d\n", res);
- usb_kill_urb(dev->rx_urb);
- return res;
- }
- enable_net_traffic(dev);
- set_carrier(netdev);
- netif_start_queue(netdev);
-
- return res;
-}
-
-static int rtl8150_close(struct net_device *netdev)
-{
- rtl8150_t *dev = netdev_priv(netdev);
- int res = 0;
-
- netif_stop_queue(netdev);
- if (!test_bit(RTL8150_UNPLUG, &dev->flags))
- disable_net_traffic(dev);
- unlink_all_urbs(dev);
-
- return res;
-}
-
-static void rtl8150_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info)
-{
- rtl8150_t *dev = netdev_priv(netdev);
-
- strncpy(info->driver, driver_name, ETHTOOL_BUSINFO_LEN);
- strncpy(info->version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
- usb_make_path(dev->udev, info->bus_info, sizeof info->bus_info);
-}
-
-static int rtl8150_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
-{
- rtl8150_t *dev = netdev_priv(netdev);
- short lpa, bmcr;
-
- ecmd->supported = (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_Autoneg |
- SUPPORTED_TP | SUPPORTED_MII);
- ecmd->port = PORT_TP;
- ecmd->transceiver = XCVR_INTERNAL;
- ecmd->phy_address = dev->phy;
- get_registers(dev, BMCR, 2, &bmcr);
- get_registers(dev, ANLP, 2, &lpa);
- if (bmcr & BMCR_ANENABLE) {
- u32 speed = ((lpa & (LPA_100HALF | LPA_100FULL)) ?
- SPEED_100 : SPEED_10);
- ethtool_cmd_speed_set(ecmd, speed);
- ecmd->autoneg = AUTONEG_ENABLE;
- if (speed == SPEED_100)
- ecmd->duplex = (lpa & LPA_100FULL) ?
- DUPLEX_FULL : DUPLEX_HALF;
- else
- ecmd->duplex = (lpa & LPA_10FULL) ?
- DUPLEX_FULL : DUPLEX_HALF;
- } else {
- ecmd->autoneg = AUTONEG_DISABLE;
- ethtool_cmd_speed_set(ecmd, ((bmcr & BMCR_SPEED100) ?
- SPEED_100 : SPEED_10));
- ecmd->duplex = (bmcr & BMCR_FULLDPLX) ?
- DUPLEX_FULL : DUPLEX_HALF;
- }
- return 0;
-}
-
-static const struct ethtool_ops ops = {
- .get_drvinfo = rtl8150_get_drvinfo,
- .get_settings = rtl8150_get_settings,
- .get_link = ethtool_op_get_link
-};
-
-static int rtl8150_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
-{
- rtl8150_t *dev = netdev_priv(netdev);
- u16 *data = (u16 *) & rq->ifr_ifru;
- int res = 0;
-
- switch (cmd) {
- case SIOCDEVPRIVATE:
- data[0] = dev->phy;
- case SIOCDEVPRIVATE + 1:
- read_mii_word(dev, dev->phy, (data[1] & 0x1f), &data[3]);
- break;
- case SIOCDEVPRIVATE + 2:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- write_mii_word(dev, dev->phy, (data[1] & 0x1f), data[2]);
- break;
- default:
- res = -EOPNOTSUPP;
- }
-
- return res;
-}
-
-static const struct net_device_ops rtl8150_netdev_ops = {
- .ndo_open = rtl8150_open,
- .ndo_stop = rtl8150_close,
- .ndo_do_ioctl = rtl8150_ioctl,
- .ndo_start_xmit = rtl8150_start_xmit,
- .ndo_tx_timeout = rtl8150_tx_timeout,
- .ndo_set_rx_mode = rtl8150_set_multicast,
- .ndo_set_mac_address = rtl8150_set_mac_address,
-
- .ndo_change_mtu = eth_change_mtu,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-static int rtl8150_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- rtl8150_t *dev;
- struct net_device *netdev;
-
- netdev = alloc_etherdev(sizeof(rtl8150_t));
- if (!netdev)
- return -ENOMEM;
-
- dev = netdev_priv(netdev);
-
- dev->intr_buff = kmalloc(INTBUFSIZE, GFP_KERNEL);
- if (!dev->intr_buff) {
- free_netdev(netdev);
- return -ENOMEM;
- }
-
- tasklet_init(&dev->tl, rx_fixup, (unsigned long)dev);
- spin_lock_init(&dev->rx_pool_lock);
-
- dev->udev = udev;
- dev->netdev = netdev;
- netdev->netdev_ops = &rtl8150_netdev_ops;
- netdev->watchdog_timeo = RTL8150_TX_TIMEOUT;
- SET_ETHTOOL_OPS(netdev, &ops);
- dev->intr_interval = 100; /* 100ms */
-
- if (!alloc_all_urbs(dev)) {
- err("out of memory");
- goto out;
- }
- if (!rtl8150_reset(dev)) {
- err("couldn't reset the device");
- goto out1;
- }
- fill_skb_pool(dev);
- set_ethernet_addr(dev);
-
- usb_set_intfdata(intf, dev);
- SET_NETDEV_DEV(netdev, &intf->dev);
- if (register_netdev(netdev) != 0) {
- err("couldn't register the device");
- goto out2;
- }
-
- dev_info(&intf->dev, "%s: rtl8150 is detected\n", netdev->name);
-
- return 0;
-
-out2:
- usb_set_intfdata(intf, NULL);
- free_skb_pool(dev);
-out1:
- free_all_urbs(dev);
-out:
- kfree(dev->intr_buff);
- free_netdev(netdev);
- return -EIO;
-}
-
-static void rtl8150_disconnect(struct usb_interface *intf)
-{
- rtl8150_t *dev = usb_get_intfdata(intf);
-
- usb_set_intfdata(intf, NULL);
- if (dev) {
- set_bit(RTL8150_UNPLUG, &dev->flags);
- tasklet_kill(&dev->tl);
- unregister_netdev(dev->netdev);
- unlink_all_urbs(dev);
- free_all_urbs(dev);
- free_skb_pool(dev);
- if (dev->rx_skb)
- dev_kfree_skb(dev->rx_skb);
- kfree(dev->intr_buff);
- free_netdev(dev->netdev);
- }
-}
-
-static struct usb_driver rtl8150_driver = {
- .name = driver_name,
- .probe = rtl8150_probe,
- .disconnect = rtl8150_disconnect,
- .id_table = rtl8150_table,
- .suspend = rtl8150_suspend,
- .resume = rtl8150_resume
-};
-
-module_usb_driver(rtl8150_driver);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/sierra_net.c b/ANDROID_3.4.5/drivers/net/usb/sierra_net.c
deleted file mode 100644
index cc9776c2..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/sierra_net.c
+++ /dev/null
@@ -1,998 +0,0 @@
-/*
- * USB-to-WWAN Driver for Sierra Wireless modems
- *
- * Copyright (C) 2008, 2009, 2010 Paxton Smith, Matthew Safar, Rory Filer
- * <linux@sierrawireless.com>
- *
- * Portions of this based on the cdc_ether driver by David Brownell (2003-2005)
- * and Ole Andre Vadla Ravnas (ActiveSync) (2006).
- *
- * IMPORTANT DISCLAIMER: This driver is not commercially supported by
- * Sierra Wireless. Use at your own risk.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define DRIVER_VERSION "v.2.0"
-#define DRIVER_AUTHOR "Paxton Smith, Matthew Safar, Rory Filer"
-#define DRIVER_DESC "USB-to-WWAN Driver for Sierra Wireless modems"
-static const char driver_name[] = "sierra_net";
-
-/* if defined debug messages enabled */
-/*#define DEBUG*/
-
-#include <linux/module.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/usb.h>
-#include <linux/usb/cdc.h>
-#include <net/ip.h>
-#include <net/udp.h>
-#include <asm/unaligned.h>
-#include <linux/usb/usbnet.h>
-
-#define SWI_USB_REQUEST_GET_FW_ATTR 0x06
-#define SWI_GET_FW_ATTR_MASK 0x08
-
-/* atomic counter partially included in MAC address to make sure 2 devices
- * do not end up with the same MAC - concept breaks in case of > 255 ifaces
- */
-static atomic_t iface_counter = ATOMIC_INIT(0);
-
-/*
- * SYNC Timer Delay definition used to set the expiry time
- */
-#define SIERRA_NET_SYNCDELAY (2*HZ)
-
-/* Max. MTU supported. The modem buffers are limited to 1500 */
-#define SIERRA_NET_MAX_SUPPORTED_MTU 1500
-
-/* The SIERRA_NET_USBCTL_BUF_LEN defines a buffer size allocated for control
- * message reception ... and thus the max. received packet.
- * (May be the cause for parse_hip returning -EINVAL)
- */
-#define SIERRA_NET_USBCTL_BUF_LEN 1024
-
-/* list of interface numbers - used for constructing interface lists */
-struct sierra_net_iface_info {
- const u32 infolen; /* number of interface numbers on list */
- const u8 *ifaceinfo; /* pointer to the array holding the numbers */
-};
-
-struct sierra_net_info_data {
- u16 rx_urb_size;
- struct sierra_net_iface_info whitelist;
-};
-
-/* Private data structure */
-struct sierra_net_data {
-
- u8 ethr_hdr_tmpl[ETH_HLEN]; /* ethernet header template for rx'd pkts */
-
- u16 link_up; /* air link up or down */
- u8 tx_hdr_template[4]; /* part of HIP hdr for tx'd packets */
-
- u8 sync_msg[4]; /* SYNC message */
- u8 shdwn_msg[4]; /* Shutdown message */
-
- /* Backpointer to the container */
- struct usbnet *usbnet;
-
- u8 ifnum; /* interface number */
-
-/* Bit masks, must be a power of 2 */
-#define SIERRA_NET_EVENT_RESP_AVAIL 0x01
-#define SIERRA_NET_TIMER_EXPIRY 0x02
- unsigned long kevent_flags;
- struct work_struct sierra_net_kevent;
- struct timer_list sync_timer; /* For retrying SYNC sequence */
-};
-
-struct param {
- int is_present;
- union {
- void *ptr;
- u32 dword;
- u16 word;
- u8 byte;
- };
-};
-
-/* HIP message type */
-#define SIERRA_NET_HIP_EXTENDEDID 0x7F
-#define SIERRA_NET_HIP_HSYNC_ID 0x60 /* Modem -> host */
-#define SIERRA_NET_HIP_RESTART_ID 0x62 /* Modem -> host */
-#define SIERRA_NET_HIP_MSYNC_ID 0x20 /* Host -> modem */
-#define SIERRA_NET_HIP_SHUTD_ID 0x26 /* Host -> modem */
-
-#define SIERRA_NET_HIP_EXT_IP_IN_ID 0x0202
-#define SIERRA_NET_HIP_EXT_IP_OUT_ID 0x0002
-
-/* 3G UMTS Link Sense Indication definitions */
-#define SIERRA_NET_HIP_LSI_UMTSID 0x78
-
-/* Reverse Channel Grant Indication HIP message */
-#define SIERRA_NET_HIP_RCGI 0x64
-
-/* LSI Protocol types */
-#define SIERRA_NET_PROTOCOL_UMTS 0x01
-/* LSI Coverage */
-#define SIERRA_NET_COVERAGE_NONE 0x00
-#define SIERRA_NET_COVERAGE_NOPACKET 0x01
-
-/* LSI Session */
-#define SIERRA_NET_SESSION_IDLE 0x00
-/* LSI Link types */
-#define SIERRA_NET_AS_LINK_TYPE_IPv4 0x00
-
-struct lsi_umts {
- u8 protocol;
- u8 unused1;
- __be16 length;
- /* eventually use a union for the rest - assume umts for now */
- u8 coverage;
- u8 unused2[41];
- u8 session_state;
- u8 unused3[33];
- u8 link_type;
- u8 pdp_addr_len; /* NW-supplied PDP address len */
- u8 pdp_addr[16]; /* NW-supplied PDP address (bigendian)) */
- u8 unused4[23];
- u8 dns1_addr_len; /* NW-supplied 1st DNS address len (bigendian) */
- u8 dns1_addr[16]; /* NW-supplied 1st DNS address */
- u8 dns2_addr_len; /* NW-supplied 2nd DNS address len */
- u8 dns2_addr[16]; /* NW-supplied 2nd DNS address (bigendian)*/
- u8 wins1_addr_len; /* NW-supplied 1st Wins address len */
- u8 wins1_addr[16]; /* NW-supplied 1st Wins address (bigendian)*/
- u8 wins2_addr_len; /* NW-supplied 2nd Wins address len */
- u8 wins2_addr[16]; /* NW-supplied 2nd Wins address (bigendian) */
- u8 unused5[4];
- u8 gw_addr_len; /* NW-supplied GW address len */
- u8 gw_addr[16]; /* NW-supplied GW address (bigendian) */
- u8 reserved[8];
-} __packed;
-
-#define SIERRA_NET_LSI_COMMON_LEN 4
-#define SIERRA_NET_LSI_UMTS_LEN (sizeof(struct lsi_umts))
-#define SIERRA_NET_LSI_UMTS_STATUS_LEN \
- (SIERRA_NET_LSI_UMTS_LEN - SIERRA_NET_LSI_COMMON_LEN)
-
-/* Forward definitions */
-static void sierra_sync_timer(unsigned long syncdata);
-static int sierra_net_change_mtu(struct net_device *net, int new_mtu);
-
-/* Our own net device operations structure */
-static const struct net_device_ops sierra_net_device_ops = {
- .ndo_open = usbnet_open,
- .ndo_stop = usbnet_stop,
- .ndo_start_xmit = usbnet_start_xmit,
- .ndo_tx_timeout = usbnet_tx_timeout,
- .ndo_change_mtu = sierra_net_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/* get private data associated with passed in usbnet device */
-static inline struct sierra_net_data *sierra_net_get_private(struct usbnet *dev)
-{
- return (struct sierra_net_data *)dev->data[0];
-}
-
-/* set private data associated with passed in usbnet device */
-static inline void sierra_net_set_private(struct usbnet *dev,
- struct sierra_net_data *priv)
-{
- dev->data[0] = (unsigned long)priv;
-}
-
-/* is packet IPv4 */
-static inline int is_ip(struct sk_buff *skb)
-{
- return skb->protocol == cpu_to_be16(ETH_P_IP);
-}
-
-/*
- * check passed in packet and make sure that:
- * - it is linear (no scatter/gather)
- * - it is ethernet (mac_header properly set)
- */
-static int check_ethip_packet(struct sk_buff *skb, struct usbnet *dev)
-{
- skb_reset_mac_header(skb); /* ethernet header */
-
- if (skb_is_nonlinear(skb)) {
- netdev_err(dev->net, "Non linear buffer-dropping\n");
- return 0;
- }
-
- if (!pskb_may_pull(skb, ETH_HLEN))
- return 0;
- skb->protocol = eth_hdr(skb)->h_proto;
-
- return 1;
-}
-
-static const u8 *save16bit(struct param *p, const u8 *datap)
-{
- p->is_present = 1;
- p->word = get_unaligned_be16(datap);
- return datap + sizeof(p->word);
-}
-
-static const u8 *save8bit(struct param *p, const u8 *datap)
-{
- p->is_present = 1;
- p->byte = *datap;
- return datap + sizeof(p->byte);
-}
-
-/*----------------------------------------------------------------------------*
- * BEGIN HIP *
- *----------------------------------------------------------------------------*/
-/* HIP header */
-#define SIERRA_NET_HIP_HDR_LEN 4
-/* Extended HIP header */
-#define SIERRA_NET_HIP_EXT_HDR_LEN 6
-
-struct hip_hdr {
- int hdrlen;
- struct param payload_len;
- struct param msgid;
- struct param msgspecific;
- struct param extmsgid;
-};
-
-static int parse_hip(const u8 *buf, const u32 buflen, struct hip_hdr *hh)
-{
- const u8 *curp = buf;
- int padded;
-
- if (buflen < SIERRA_NET_HIP_HDR_LEN)
- return -EPROTO;
-
- curp = save16bit(&hh->payload_len, curp);
- curp = save8bit(&hh->msgid, curp);
- curp = save8bit(&hh->msgspecific, curp);
-
- padded = hh->msgid.byte & 0x80;
- hh->msgid.byte &= 0x7F; /* 7 bits */
-
- hh->extmsgid.is_present = (hh->msgid.byte == SIERRA_NET_HIP_EXTENDEDID);
- if (hh->extmsgid.is_present) {
- if (buflen < SIERRA_NET_HIP_EXT_HDR_LEN)
- return -EPROTO;
-
- hh->payload_len.word &= 0x3FFF; /* 14 bits */
-
- curp = save16bit(&hh->extmsgid, curp);
- hh->extmsgid.word &= 0x03FF; /* 10 bits */
-
- hh->hdrlen = SIERRA_NET_HIP_EXT_HDR_LEN;
- } else {
- hh->payload_len.word &= 0x07FF; /* 11 bits */
- hh->hdrlen = SIERRA_NET_HIP_HDR_LEN;
- }
-
- if (padded) {
- hh->hdrlen++;
- hh->payload_len.word--;
- }
-
- /* if real packet shorter than the claimed length */
- if (buflen < (hh->hdrlen + hh->payload_len.word))
- return -EINVAL;
-
- return 0;
-}
-
-static void build_hip(u8 *buf, const u16 payloadlen,
- struct sierra_net_data *priv)
-{
- /* the following doesn't have the full functionality. We
- * currently build only one kind of header, so it is faster this way
- */
- put_unaligned_be16(payloadlen, buf);
- memcpy(buf+2, priv->tx_hdr_template, sizeof(priv->tx_hdr_template));
-}
-/*----------------------------------------------------------------------------*
- * END HIP *
- *----------------------------------------------------------------------------*/
-
-static int sierra_net_send_cmd(struct usbnet *dev,
- u8 *cmd, int cmdlen, const char * cmd_name)
-{
- struct sierra_net_data *priv = sierra_net_get_private(dev);
- int status;
-
- status = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
- USB_CDC_SEND_ENCAPSULATED_COMMAND,
- USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE, 0,
- priv->ifnum, cmd, cmdlen, USB_CTRL_SET_TIMEOUT);
-
- if (status != cmdlen && status != -ENODEV)
- netdev_err(dev->net, "Submit %s failed %d\n", cmd_name, status);
-
- return status;
-}
-
-static int sierra_net_send_sync(struct usbnet *dev)
-{
- int status;
- struct sierra_net_data *priv = sierra_net_get_private(dev);
-
- dev_dbg(&dev->udev->dev, "%s", __func__);
-
- status = sierra_net_send_cmd(dev, priv->sync_msg,
- sizeof(priv->sync_msg), "SYNC");
-
- return status;
-}
-
-static void sierra_net_set_ctx_index(struct sierra_net_data *priv, u8 ctx_ix)
-{
- dev_dbg(&(priv->usbnet->udev->dev), "%s %d", __func__, ctx_ix);
- priv->tx_hdr_template[0] = 0x3F;
- priv->tx_hdr_template[1] = ctx_ix;
- *((u16 *)&priv->tx_hdr_template[2]) =
- cpu_to_be16(SIERRA_NET_HIP_EXT_IP_OUT_ID);
-}
-
-static inline int sierra_net_is_valid_addrlen(u8 len)
-{
- return len == sizeof(struct in_addr);
-}
-
-static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen)
-{
- struct lsi_umts *lsi = (struct lsi_umts *)data;
-
- if (datalen < sizeof(struct lsi_umts)) {
- netdev_err(dev->net, "%s: Data length %d, exp %Zu\n",
- __func__, datalen,
- sizeof(struct lsi_umts));
- return -1;
- }
-
- if (lsi->length != cpu_to_be16(SIERRA_NET_LSI_UMTS_STATUS_LEN)) {
- netdev_err(dev->net, "%s: LSI_UMTS_STATUS_LEN %d, exp %u\n",
- __func__, be16_to_cpu(lsi->length),
- (u32)SIERRA_NET_LSI_UMTS_STATUS_LEN);
- return -1;
- }
-
- /* Validate the protocol - only support UMTS for now */
- if (lsi->protocol != SIERRA_NET_PROTOCOL_UMTS) {
- netdev_err(dev->net, "Protocol unsupported, 0x%02x\n",
- lsi->protocol);
- return -1;
- }
-
- /* Validate the link type */
- if (lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv4) {
- netdev_err(dev->net, "Link type unsupported: 0x%02x\n",
- lsi->link_type);
- return -1;
- }
-
- /* Validate the coverage */
- if (lsi->coverage == SIERRA_NET_COVERAGE_NONE
- || lsi->coverage == SIERRA_NET_COVERAGE_NOPACKET) {
- netdev_err(dev->net, "No coverage, 0x%02x\n", lsi->coverage);
- return 0;
- }
-
- /* Validate the session state */
- if (lsi->session_state == SIERRA_NET_SESSION_IDLE) {
- netdev_err(dev->net, "Session idle, 0x%02x\n",
- lsi->session_state);
- return 0;
- }
-
- /* Set link_sense true */
- return 1;
-}
-
-static void sierra_net_handle_lsi(struct usbnet *dev, char *data,
- struct hip_hdr *hh)
-{
- struct sierra_net_data *priv = sierra_net_get_private(dev);
- int link_up;
-
- link_up = sierra_net_parse_lsi(dev, data + hh->hdrlen,
- hh->payload_len.word);
- if (link_up < 0) {
- netdev_err(dev->net, "Invalid LSI\n");
- return;
- }
- if (link_up) {
- sierra_net_set_ctx_index(priv, hh->msgspecific.byte);
- priv->link_up = 1;
- netif_carrier_on(dev->net);
- } else {
- priv->link_up = 0;
- netif_carrier_off(dev->net);
- }
-}
-
-static void sierra_net_dosync(struct usbnet *dev)
-{
- int status;
- struct sierra_net_data *priv = sierra_net_get_private(dev);
-
- dev_dbg(&dev->udev->dev, "%s", __func__);
-
- /* tell modem we are ready */
- status = sierra_net_send_sync(dev);
- if (status < 0)
- netdev_err(dev->net,
- "Send SYNC failed, status %d\n", status);
- status = sierra_net_send_sync(dev);
- if (status < 0)
- netdev_err(dev->net,
- "Send SYNC failed, status %d\n", status);
-
- /* Now, start a timer and make sure we get the Restart Indication */
- priv->sync_timer.function = sierra_sync_timer;
- priv->sync_timer.data = (unsigned long) dev;
- priv->sync_timer.expires = jiffies + SIERRA_NET_SYNCDELAY;
- add_timer(&priv->sync_timer);
-}
-
-static void sierra_net_kevent(struct work_struct *work)
-{
- struct sierra_net_data *priv =
- container_of(work, struct sierra_net_data, sierra_net_kevent);
- struct usbnet *dev = priv->usbnet;
- int len;
- int err;
- u8 *buf;
- u8 ifnum;
-
- if (test_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags)) {
- clear_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags);
-
- /* Query the modem for the LSI message */
- buf = kzalloc(SIERRA_NET_USBCTL_BUF_LEN, GFP_KERNEL);
- if (!buf) {
- netdev_err(dev->net,
- "failed to allocate buf for LS msg\n");
- return;
- }
- ifnum = priv->ifnum;
- len = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
- USB_CDC_GET_ENCAPSULATED_RESPONSE,
- USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE,
- 0, ifnum, buf, SIERRA_NET_USBCTL_BUF_LEN,
- USB_CTRL_SET_TIMEOUT);
-
- if (len < 0) {
- netdev_err(dev->net,
- "usb_control_msg failed, status %d\n", len);
- } else {
- struct hip_hdr hh;
-
- dev_dbg(&dev->udev->dev, "%s: Received status message,"
- " %04x bytes", __func__, len);
-
- err = parse_hip(buf, len, &hh);
- if (err) {
- netdev_err(dev->net, "%s: Bad packet,"
- " parse result %d\n", __func__, err);
- kfree(buf);
- return;
- }
-
- /* Validate packet length */
- if (len != hh.hdrlen + hh.payload_len.word) {
- netdev_err(dev->net, "%s: Bad packet, received"
- " %d, expected %d\n", __func__, len,
- hh.hdrlen + hh.payload_len.word);
- kfree(buf);
- return;
- }
-
- /* Switch on received message types */
- switch (hh.msgid.byte) {
- case SIERRA_NET_HIP_LSI_UMTSID:
- dev_dbg(&dev->udev->dev, "LSI for ctx:%d",
- hh.msgspecific.byte);
- sierra_net_handle_lsi(dev, buf, &hh);
- break;
- case SIERRA_NET_HIP_RESTART_ID:
- dev_dbg(&dev->udev->dev, "Restart reported: %d,"
- " stopping sync timer",
- hh.msgspecific.byte);
- /* Got sync resp - stop timer & clear mask */
- del_timer_sync(&priv->sync_timer);
- clear_bit(SIERRA_NET_TIMER_EXPIRY,
- &priv->kevent_flags);
- break;
- case SIERRA_NET_HIP_HSYNC_ID:
- dev_dbg(&dev->udev->dev, "SYNC received");
- err = sierra_net_send_sync(dev);
- if (err < 0)
- netdev_err(dev->net,
- "Send SYNC failed %d\n", err);
- break;
- case SIERRA_NET_HIP_EXTENDEDID:
- netdev_err(dev->net, "Unrecognized HIP msg, "
- "extmsgid 0x%04x\n", hh.extmsgid.word);
- break;
- case SIERRA_NET_HIP_RCGI:
- /* Ignored */
- break;
- default:
- netdev_err(dev->net, "Unrecognized HIP msg, "
- "msgid 0x%02x\n", hh.msgid.byte);
- break;
- }
- }
- kfree(buf);
- }
- /* The sync timer bit might be set */
- if (test_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags)) {
- clear_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags);
- dev_dbg(&dev->udev->dev, "Deferred sync timer expiry");
- sierra_net_dosync(priv->usbnet);
- }
-
- if (priv->kevent_flags)
- dev_dbg(&dev->udev->dev, "sierra_net_kevent done, "
- "kevent_flags = 0x%lx", priv->kevent_flags);
-}
-
-static void sierra_net_defer_kevent(struct usbnet *dev, int work)
-{
- struct sierra_net_data *priv = sierra_net_get_private(dev);
-
- set_bit(work, &priv->kevent_flags);
- schedule_work(&priv->sierra_net_kevent);
-}
-
-/*
- * Sync Retransmit Timer Handler. On expiry, kick the work queue
- */
-void sierra_sync_timer(unsigned long syncdata)
-{
- struct usbnet *dev = (struct usbnet *)syncdata;
-
- dev_dbg(&dev->udev->dev, "%s", __func__);
- /* Kick the tasklet */
- sierra_net_defer_kevent(dev, SIERRA_NET_TIMER_EXPIRY);
-}
-
-static void sierra_net_status(struct usbnet *dev, struct urb *urb)
-{
- struct usb_cdc_notification *event;
-
- dev_dbg(&dev->udev->dev, "%s", __func__);
-
- if (urb->actual_length < sizeof *event)
- return;
-
- /* Add cases to handle other standard notifications. */
- event = urb->transfer_buffer;
- switch (event->bNotificationType) {
- case USB_CDC_NOTIFY_NETWORK_CONNECTION:
- case USB_CDC_NOTIFY_SPEED_CHANGE:
- /* USB 305 sends those */
- break;
- case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
- sierra_net_defer_kevent(dev, SIERRA_NET_EVENT_RESP_AVAIL);
- break;
- default:
- netdev_err(dev->net, ": unexpected notification %02x!\n",
- event->bNotificationType);
- break;
- }
-}
-
-static void sierra_net_get_drvinfo(struct net_device *net,
- struct ethtool_drvinfo *info)
-{
- /* Inherit standard device info */
- usbnet_get_drvinfo(net, info);
- strncpy(info->driver, driver_name, sizeof info->driver);
- strncpy(info->version, DRIVER_VERSION, sizeof info->version);
-}
-
-static u32 sierra_net_get_link(struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
- /* Report link is down whenever the interface is down */
- return sierra_net_get_private(dev)->link_up && netif_running(net);
-}
-
-static const struct ethtool_ops sierra_net_ethtool_ops = {
- .get_drvinfo = sierra_net_get_drvinfo,
- .get_link = sierra_net_get_link,
- .get_msglevel = usbnet_get_msglevel,
- .set_msglevel = usbnet_set_msglevel,
- .get_settings = usbnet_get_settings,
- .set_settings = usbnet_set_settings,
- .nway_reset = usbnet_nway_reset,
-};
-
-/* MTU can not be more than 1500 bytes, enforce it. */
-static int sierra_net_change_mtu(struct net_device *net, int new_mtu)
-{
- if (new_mtu > SIERRA_NET_MAX_SUPPORTED_MTU)
- return -EINVAL;
-
- return usbnet_change_mtu(net, new_mtu);
-}
-
-static int is_whitelisted(const u8 ifnum,
- const struct sierra_net_iface_info *whitelist)
-{
- if (whitelist) {
- const u8 *list = whitelist->ifaceinfo;
- int i;
-
- for (i = 0; i < whitelist->infolen; i++) {
- if (list[i] == ifnum)
- return 1;
- }
- }
- return 0;
-}
-
-static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap)
-{
- int result = 0;
- u16 *attrdata;
-
- attrdata = kmalloc(sizeof(*attrdata), GFP_KERNEL);
- if (!attrdata)
- return -ENOMEM;
-
- result = usb_control_msg(
- dev->udev,
- usb_rcvctrlpipe(dev->udev, 0),
- /* _u8 vendor specific request */
- SWI_USB_REQUEST_GET_FW_ATTR,
- USB_DIR_IN | USB_TYPE_VENDOR, /* __u8 request type */
- 0x0000, /* __u16 value not used */
- 0x0000, /* __u16 index not used */
- attrdata, /* char *data */
- sizeof(*attrdata), /* __u16 size */
- USB_CTRL_SET_TIMEOUT); /* int timeout */
-
- if (result < 0) {
- kfree(attrdata);
- return -EIO;
- }
-
- *datap = *attrdata;
-
- kfree(attrdata);
- return result;
-}
-
-/*
- * collects the bulk endpoints, the status endpoint.
- */
-static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- u8 ifacenum;
- u8 numendpoints;
- u16 fwattr = 0;
- int status;
- struct ethhdr *eth;
- struct sierra_net_data *priv;
- static const u8 sync_tmplate[sizeof(priv->sync_msg)] = {
- 0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00};
- static const u8 shdwn_tmplate[sizeof(priv->shdwn_msg)] = {
- 0x00, 0x00, SIERRA_NET_HIP_SHUTD_ID, 0x00};
-
- struct sierra_net_info_data *data =
- (struct sierra_net_info_data *)dev->driver_info->data;
-
- dev_dbg(&dev->udev->dev, "%s", __func__);
-
- ifacenum = intf->cur_altsetting->desc.bInterfaceNumber;
- /* We only accept certain interfaces */
- if (!is_whitelisted(ifacenum, &data->whitelist)) {
- dev_dbg(&dev->udev->dev, "Ignoring interface: %d", ifacenum);
- return -ENODEV;
- }
- numendpoints = intf->cur_altsetting->desc.bNumEndpoints;
- /* We have three endpoints, bulk in and out, and a status */
- if (numendpoints != 3) {
- dev_err(&dev->udev->dev, "Expected 3 endpoints, found: %d",
- numendpoints);
- return -ENODEV;
- }
- /* Status endpoint set in usbnet_get_endpoints() */
- dev->status = NULL;
- status = usbnet_get_endpoints(dev, intf);
- if (status < 0) {
- dev_err(&dev->udev->dev, "Error in usbnet_get_endpoints (%d)",
- status);
- return -ENODEV;
- }
- /* Initialize sierra private data */
- priv = kzalloc(sizeof *priv, GFP_KERNEL);
- if (!priv) {
- dev_err(&dev->udev->dev, "No memory");
- return -ENOMEM;
- }
-
- priv->usbnet = dev;
- priv->ifnum = ifacenum;
- dev->net->netdev_ops = &sierra_net_device_ops;
-
- /* change MAC addr to include, ifacenum, and to be unique */
- dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter);
- dev->net->dev_addr[ETH_ALEN-1] = ifacenum;
-
- /* we will have to manufacture ethernet headers, prepare template */
- eth = (struct ethhdr *)priv->ethr_hdr_tmpl;
- memcpy(&eth->h_dest, dev->net->dev_addr, ETH_ALEN);
- eth->h_proto = cpu_to_be16(ETH_P_IP);
-
- /* prepare shutdown message template */
- memcpy(priv->shdwn_msg, shdwn_tmplate, sizeof(priv->shdwn_msg));
- /* set context index initially to 0 - prepares tx hdr template */
- sierra_net_set_ctx_index(priv, 0);
-
- /* decrease the rx_urb_size and max_tx_size to 4k on USB 1.1 */
- dev->rx_urb_size = data->rx_urb_size;
- if (dev->udev->speed != USB_SPEED_HIGH)
- dev->rx_urb_size = min_t(size_t, 4096, data->rx_urb_size);
-
- dev->net->hard_header_len += SIERRA_NET_HIP_EXT_HDR_LEN;
- dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
-
- /* Set up the netdev */
- dev->net->flags |= IFF_NOARP;
- dev->net->ethtool_ops = &sierra_net_ethtool_ops;
- netif_carrier_off(dev->net);
-
- sierra_net_set_private(dev, priv);
-
- priv->kevent_flags = 0;
-
- /* Use the shared workqueue */
- INIT_WORK(&priv->sierra_net_kevent, sierra_net_kevent);
-
- /* Only need to do this once */
- init_timer(&priv->sync_timer);
-
- /* verify fw attributes */
- status = sierra_net_get_fw_attr(dev, &fwattr);
- dev_dbg(&dev->udev->dev, "Fw attr: %x\n", fwattr);
-
- /* test whether firmware supports DHCP */
- if (!(status == sizeof(fwattr) && (fwattr & SWI_GET_FW_ATTR_MASK))) {
- /* found incompatible firmware version */
- dev_err(&dev->udev->dev, "Incompatible driver and firmware"
- " versions\n");
- kfree(priv);
- return -ENODEV;
- }
- /* prepare sync message from template */
- memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg));
-
- /* initiate the sync sequence */
- sierra_net_dosync(dev);
-
- return 0;
-}
-
-static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf)
-{
- int status;
- struct sierra_net_data *priv = sierra_net_get_private(dev);
-
- dev_dbg(&dev->udev->dev, "%s", __func__);
-
- /* kill the timer and work */
- del_timer_sync(&priv->sync_timer);
- cancel_work_sync(&priv->sierra_net_kevent);
-
- /* tell modem we are going away */
- status = sierra_net_send_cmd(dev, priv->shdwn_msg,
- sizeof(priv->shdwn_msg), "Shutdown");
- if (status < 0)
- netdev_err(dev->net,
- "usb_control_msg failed, status %d\n", status);
-
- sierra_net_set_private(dev, NULL);
-
- kfree(priv);
-}
-
-static struct sk_buff *sierra_net_skb_clone(struct usbnet *dev,
- struct sk_buff *skb, int len)
-{
- struct sk_buff *new_skb;
-
- /* clone skb */
- new_skb = skb_clone(skb, GFP_ATOMIC);
-
- /* remove len bytes from original */
- skb_pull(skb, len);
-
- /* trim next packet to it's length */
- if (new_skb) {
- skb_trim(new_skb, len);
- } else {
- if (netif_msg_rx_err(dev))
- netdev_err(dev->net, "failed to get skb\n");
- dev->net->stats.rx_dropped++;
- }
-
- return new_skb;
-}
-
-/* ---------------------------- Receive data path ----------------------*/
-static int sierra_net_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- int err;
- struct hip_hdr hh;
- struct sk_buff *new_skb;
-
- dev_dbg(&dev->udev->dev, "%s", __func__);
-
- /* could contain multiple packets */
- while (likely(skb->len)) {
- err = parse_hip(skb->data, skb->len, &hh);
- if (err) {
- if (netif_msg_rx_err(dev))
- netdev_err(dev->net, "Invalid HIP header %d\n",
- err);
- /* dev->net->stats.rx_errors incremented by caller */
- dev->net->stats.rx_length_errors++;
- return 0;
- }
-
- /* Validate Extended HIP header */
- if (!hh.extmsgid.is_present
- || hh.extmsgid.word != SIERRA_NET_HIP_EXT_IP_IN_ID) {
- if (netif_msg_rx_err(dev))
- netdev_err(dev->net, "HIP/ETH: Invalid pkt\n");
-
- dev->net->stats.rx_frame_errors++;
- /* dev->net->stats.rx_errors incremented by caller */;
- return 0;
- }
-
- skb_pull(skb, hh.hdrlen);
-
- /* We are going to accept this packet, prepare it */
- memcpy(skb->data, sierra_net_get_private(dev)->ethr_hdr_tmpl,
- ETH_HLEN);
-
- /* Last packet in batch handled by usbnet */
- if (hh.payload_len.word == skb->len)
- return 1;
-
- new_skb = sierra_net_skb_clone(dev, skb, hh.payload_len.word);
- if (new_skb)
- usbnet_skb_return(dev, new_skb);
-
- } /* while */
-
- return 0;
-}
-
-/* ---------------------------- Transmit data path ----------------------*/
-struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
- gfp_t flags)
-{
- struct sierra_net_data *priv = sierra_net_get_private(dev);
- u16 len;
- bool need_tail;
-
- BUILD_BUG_ON(FIELD_SIZEOF(struct usbnet, data)
- < sizeof(struct cdc_state));
-
- dev_dbg(&dev->udev->dev, "%s", __func__);
- if (priv->link_up && check_ethip_packet(skb, dev) && is_ip(skb)) {
- /* enough head room as is? */
- if (SIERRA_NET_HIP_EXT_HDR_LEN <= skb_headroom(skb)) {
- /* Save the Eth/IP length and set up HIP hdr */
- len = skb->len;
- skb_push(skb, SIERRA_NET_HIP_EXT_HDR_LEN);
- /* Handle ZLP issue */
- need_tail = ((len + SIERRA_NET_HIP_EXT_HDR_LEN)
- % dev->maxpacket == 0);
- if (need_tail) {
- if (unlikely(skb_tailroom(skb) == 0)) {
- netdev_err(dev->net, "tx_fixup:"
- "no room for packet\n");
- dev_kfree_skb_any(skb);
- return NULL;
- } else {
- skb->data[skb->len] = 0;
- __skb_put(skb, 1);
- len = len + 1;
- }
- }
- build_hip(skb->data, len, priv);
- return skb;
- } else {
- /*
- * compensate in the future if necessary
- */
- netdev_err(dev->net, "tx_fixup: no room for HIP\n");
- } /* headroom */
- }
-
- if (!priv->link_up)
- dev->net->stats.tx_carrier_errors++;
-
- /* tx_dropped incremented by usbnet */
-
- /* filter the packet out, release it */
- dev_kfree_skb_any(skb);
- return NULL;
-}
-
-static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 };
-static const struct sierra_net_info_data sierra_net_info_data_direct_ip = {
- .rx_urb_size = 8 * 1024,
- .whitelist = {
- .infolen = ARRAY_SIZE(sierra_net_ifnum_list),
- .ifaceinfo = sierra_net_ifnum_list
- }
-};
-
-static const struct driver_info sierra_net_info_direct_ip = {
- .description = "Sierra Wireless USB-to-WWAN Modem",
- .flags = FLAG_WWAN | FLAG_SEND_ZLP,
- .bind = sierra_net_bind,
- .unbind = sierra_net_unbind,
- .status = sierra_net_status,
- .rx_fixup = sierra_net_rx_fixup,
- .tx_fixup = sierra_net_tx_fixup,
- .data = (unsigned long)&sierra_net_info_data_direct_ip,
-};
-
-static const struct usb_device_id products[] = {
- {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */
- .driver_info = (unsigned long) &sierra_net_info_direct_ip},
- {USB_DEVICE(0x0F3D, 0x68A3), /* AT&T Direct IP modem */
- .driver_info = (unsigned long) &sierra_net_info_direct_ip},
- {USB_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */
- .driver_info = (unsigned long) &sierra_net_info_direct_ip},
- {USB_DEVICE(0x0F3D, 0x68AA), /* AT&T Direct IP LTE modem */
- .driver_info = (unsigned long) &sierra_net_info_direct_ip},
-
- {}, /* last item */
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-/* We are based on usbnet, so let it handle the USB driver specifics */
-static struct usb_driver sierra_net_driver = {
- .name = "sierra_net",
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
- .no_dynamic_id = 1,
-};
-
-module_usb_driver(sierra_net_driver);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/smsc75xx.c b/ANDROID_3.4.5/drivers/net/usb/smsc75xx.c
deleted file mode 100644
index 00103a8c..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/smsc75xx.c
+++ /dev/null
@@ -1,1260 +0,0 @@
- /***************************************************************************
- *
- * Copyright (C) 2007-2010 SMSC
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/kmod.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/crc32.h>
-#include <linux/usb/usbnet.h>
-#include <linux/slab.h>
-#include "smsc75xx.h"
-
-#define SMSC_CHIPNAME "smsc75xx"
-#define SMSC_DRIVER_VERSION "1.0.0"
-#define HS_USB_PKT_SIZE (512)
-#define FS_USB_PKT_SIZE (64)
-#define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE)
-#define DEFAULT_FS_BURST_CAP_SIZE (6 * 1024 + 33 * FS_USB_PKT_SIZE)
-#define DEFAULT_BULK_IN_DELAY (0x00002000)
-#define MAX_SINGLE_PACKET_SIZE (9000)
-#define LAN75XX_EEPROM_MAGIC (0x7500)
-#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)
-#define MAX_TX_FIFO_SIZE (12 * 1024)
-#define USB_VENDOR_ID_SMSC (0x0424)
-#define USB_PRODUCT_ID_LAN7500 (0x7500)
-#define USB_PRODUCT_ID_LAN7505 (0x7505)
-#define RXW_PADDING 2
-
-#define check_warn(ret, fmt, args...) \
- ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
-
-#define check_warn_return(ret, fmt, args...) \
- ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); return ret; } })
-
-#define check_warn_goto_done(ret, fmt, args...) \
- ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); goto done; } })
-
-struct smsc75xx_priv {
- struct usbnet *dev;
- u32 rfe_ctl;
- u32 multicast_hash_table[DP_SEL_VHF_HASH_LEN];
- struct mutex dataport_mutex;
- spinlock_t rfe_ctl_lock;
- struct work_struct set_multicast;
-};
-
-struct usb_context {
- struct usb_ctrlrequest req;
- struct usbnet *dev;
-};
-
-static bool turbo_mode = true;
-module_param(turbo_mode, bool, 0644);
-MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
-
-static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index,
- u32 *data)
-{
- u32 *buf = kmalloc(4, GFP_KERNEL);
- int ret;
-
- BUG_ON(!dev);
-
- if (!buf)
- return -ENOMEM;
-
- ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
- USB_VENDOR_REQUEST_READ_REGISTER,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 00, index, buf, 4, USB_CTRL_GET_TIMEOUT);
-
- if (unlikely(ret < 0))
- netdev_warn(dev->net,
- "Failed to read reg index 0x%08x: %d", index, ret);
-
- le32_to_cpus(buf);
- *data = *buf;
- kfree(buf);
-
- return ret;
-}
-
-static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index,
- u32 data)
-{
- u32 *buf = kmalloc(4, GFP_KERNEL);
- int ret;
-
- BUG_ON(!dev);
-
- if (!buf)
- return -ENOMEM;
-
- *buf = data;
- cpu_to_le32s(buf);
-
- ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
- USB_VENDOR_REQUEST_WRITE_REGISTER,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 00, index, buf, 4, USB_CTRL_SET_TIMEOUT);
-
- if (unlikely(ret < 0))
- netdev_warn(dev->net,
- "Failed to write reg index 0x%08x: %d", index, ret);
-
- kfree(buf);
-
- return ret;
-}
-
-/* Loop until the read is completed with timeout
- * called with phy_mutex held */
-static int smsc75xx_phy_wait_not_busy(struct usbnet *dev)
-{
- unsigned long start_time = jiffies;
- u32 val;
- int ret;
-
- do {
- ret = smsc75xx_read_reg(dev, MII_ACCESS, &val);
- check_warn_return(ret, "Error reading MII_ACCESS");
-
- if (!(val & MII_ACCESS_BUSY))
- return 0;
- } while (!time_after(jiffies, start_time + HZ));
-
- return -EIO;
-}
-
-static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx)
-{
- struct usbnet *dev = netdev_priv(netdev);
- u32 val, addr;
- int ret;
-
- mutex_lock(&dev->phy_mutex);
-
- /* confirm MII not busy */
- ret = smsc75xx_phy_wait_not_busy(dev);
- check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_read");
-
- /* set the address, index & direction (read from PHY) */
- phy_id &= dev->mii.phy_id_mask;
- idx &= dev->mii.reg_num_mask;
- addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
- | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
- | MII_ACCESS_READ | MII_ACCESS_BUSY;
- ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
- check_warn_goto_done(ret, "Error writing MII_ACCESS");
-
- ret = smsc75xx_phy_wait_not_busy(dev);
- check_warn_goto_done(ret, "Timed out reading MII reg %02X", idx);
-
- ret = smsc75xx_read_reg(dev, MII_DATA, &val);
- check_warn_goto_done(ret, "Error reading MII_DATA");
-
- ret = (u16)(val & 0xFFFF);
-
-done:
- mutex_unlock(&dev->phy_mutex);
- return ret;
-}
-
-static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
- int regval)
-{
- struct usbnet *dev = netdev_priv(netdev);
- u32 val, addr;
- int ret;
-
- mutex_lock(&dev->phy_mutex);
-
- /* confirm MII not busy */
- ret = smsc75xx_phy_wait_not_busy(dev);
- check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_write");
-
- val = regval;
- ret = smsc75xx_write_reg(dev, MII_DATA, val);
- check_warn_goto_done(ret, "Error writing MII_DATA");
-
- /* set the address, index & direction (write to PHY) */
- phy_id &= dev->mii.phy_id_mask;
- idx &= dev->mii.reg_num_mask;
- addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
- | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
- | MII_ACCESS_WRITE | MII_ACCESS_BUSY;
- ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
- check_warn_goto_done(ret, "Error writing MII_ACCESS");
-
- ret = smsc75xx_phy_wait_not_busy(dev);
- check_warn_goto_done(ret, "Timed out writing MII reg %02X", idx);
-
-done:
- mutex_unlock(&dev->phy_mutex);
-}
-
-static int smsc75xx_wait_eeprom(struct usbnet *dev)
-{
- unsigned long start_time = jiffies;
- u32 val;
- int ret;
-
- do {
- ret = smsc75xx_read_reg(dev, E2P_CMD, &val);
- check_warn_return(ret, "Error reading E2P_CMD");
-
- if (!(val & E2P_CMD_BUSY) || (val & E2P_CMD_TIMEOUT))
- break;
- udelay(40);
- } while (!time_after(jiffies, start_time + HZ));
-
- if (val & (E2P_CMD_TIMEOUT | E2P_CMD_BUSY)) {
- netdev_warn(dev->net, "EEPROM read operation timeout");
- return -EIO;
- }
-
- return 0;
-}
-
-static int smsc75xx_eeprom_confirm_not_busy(struct usbnet *dev)
-{
- unsigned long start_time = jiffies;
- u32 val;
- int ret;
-
- do {
- ret = smsc75xx_read_reg(dev, E2P_CMD, &val);
- check_warn_return(ret, "Error reading E2P_CMD");
-
- if (!(val & E2P_CMD_BUSY))
- return 0;
-
- udelay(40);
- } while (!time_after(jiffies, start_time + HZ));
-
- netdev_warn(dev->net, "EEPROM is busy");
- return -EIO;
-}
-
-static int smsc75xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length,
- u8 *data)
-{
- u32 val;
- int i, ret;
-
- BUG_ON(!dev);
- BUG_ON(!data);
-
- ret = smsc75xx_eeprom_confirm_not_busy(dev);
- if (ret)
- return ret;
-
- for (i = 0; i < length; i++) {
- val = E2P_CMD_BUSY | E2P_CMD_READ | (offset & E2P_CMD_ADDR);
- ret = smsc75xx_write_reg(dev, E2P_CMD, val);
- check_warn_return(ret, "Error writing E2P_CMD");
-
- ret = smsc75xx_wait_eeprom(dev);
- if (ret < 0)
- return ret;
-
- ret = smsc75xx_read_reg(dev, E2P_DATA, &val);
- check_warn_return(ret, "Error reading E2P_DATA");
-
- data[i] = val & 0xFF;
- offset++;
- }
-
- return 0;
-}
-
-static int smsc75xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length,
- u8 *data)
-{
- u32 val;
- int i, ret;
-
- BUG_ON(!dev);
- BUG_ON(!data);
-
- ret = smsc75xx_eeprom_confirm_not_busy(dev);
- if (ret)
- return ret;
-
- /* Issue write/erase enable command */
- val = E2P_CMD_BUSY | E2P_CMD_EWEN;
- ret = smsc75xx_write_reg(dev, E2P_CMD, val);
- check_warn_return(ret, "Error writing E2P_CMD");
-
- ret = smsc75xx_wait_eeprom(dev);
- if (ret < 0)
- return ret;
-
- for (i = 0; i < length; i++) {
-
- /* Fill data register */
- val = data[i];
- ret = smsc75xx_write_reg(dev, E2P_DATA, val);
- check_warn_return(ret, "Error writing E2P_DATA");
-
- /* Send "write" command */
- val = E2P_CMD_BUSY | E2P_CMD_WRITE | (offset & E2P_CMD_ADDR);
- ret = smsc75xx_write_reg(dev, E2P_CMD, val);
- check_warn_return(ret, "Error writing E2P_CMD");
-
- ret = smsc75xx_wait_eeprom(dev);
- if (ret < 0)
- return ret;
-
- offset++;
- }
-
- return 0;
-}
-
-static int smsc75xx_dataport_wait_not_busy(struct usbnet *dev)
-{
- int i, ret;
-
- for (i = 0; i < 100; i++) {
- u32 dp_sel;
- ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel);
- check_warn_return(ret, "Error reading DP_SEL");
-
- if (dp_sel & DP_SEL_DPRDY)
- return 0;
-
- udelay(40);
- }
-
- netdev_warn(dev->net, "smsc75xx_dataport_wait_not_busy timed out");
-
- return -EIO;
-}
-
-static int smsc75xx_dataport_write(struct usbnet *dev, u32 ram_select, u32 addr,
- u32 length, u32 *buf)
-{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
- u32 dp_sel;
- int i, ret;
-
- mutex_lock(&pdata->dataport_mutex);
-
- ret = smsc75xx_dataport_wait_not_busy(dev);
- check_warn_goto_done(ret, "smsc75xx_dataport_write busy on entry");
-
- ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel);
- check_warn_goto_done(ret, "Error reading DP_SEL");
-
- dp_sel &= ~DP_SEL_RSEL;
- dp_sel |= ram_select;
- ret = smsc75xx_write_reg(dev, DP_SEL, dp_sel);
- check_warn_goto_done(ret, "Error writing DP_SEL");
-
- for (i = 0; i < length; i++) {
- ret = smsc75xx_write_reg(dev, DP_ADDR, addr + i);
- check_warn_goto_done(ret, "Error writing DP_ADDR");
-
- ret = smsc75xx_write_reg(dev, DP_DATA, buf[i]);
- check_warn_goto_done(ret, "Error writing DP_DATA");
-
- ret = smsc75xx_write_reg(dev, DP_CMD, DP_CMD_WRITE);
- check_warn_goto_done(ret, "Error writing DP_CMD");
-
- ret = smsc75xx_dataport_wait_not_busy(dev);
- check_warn_goto_done(ret, "smsc75xx_dataport_write timeout");
- }
-
-done:
- mutex_unlock(&pdata->dataport_mutex);
- return ret;
-}
-
-/* returns hash bit number for given MAC address */
-static u32 smsc75xx_hash(char addr[ETH_ALEN])
-{
- return (ether_crc(ETH_ALEN, addr) >> 23) & 0x1ff;
-}
-
-static void smsc75xx_deferred_multicast_write(struct work_struct *param)
-{
- struct smsc75xx_priv *pdata =
- container_of(param, struct smsc75xx_priv, set_multicast);
- struct usbnet *dev = pdata->dev;
- int ret;
-
- netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x",
- pdata->rfe_ctl);
-
- smsc75xx_dataport_write(dev, DP_SEL_VHF, DP_SEL_VHF_VLAN_LEN,
- DP_SEL_VHF_HASH_LEN, pdata->multicast_hash_table);
-
- ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
- check_warn(ret, "Error writing RFE_CRL");
-}
-
-static void smsc75xx_set_multicast(struct net_device *netdev)
-{
- struct usbnet *dev = netdev_priv(netdev);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);
-
- pdata->rfe_ctl &=
- ~(RFE_CTL_AU | RFE_CTL_AM | RFE_CTL_DPF | RFE_CTL_MHF);
- pdata->rfe_ctl |= RFE_CTL_AB;
-
- for (i = 0; i < DP_SEL_VHF_HASH_LEN; i++)
- pdata->multicast_hash_table[i] = 0;
-
- if (dev->net->flags & IFF_PROMISC) {
- netif_dbg(dev, drv, dev->net, "promiscuous mode enabled");
- pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_AU;
- } else if (dev->net->flags & IFF_ALLMULTI) {
- netif_dbg(dev, drv, dev->net, "receive all multicast enabled");
- pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_DPF;
- } else if (!netdev_mc_empty(dev->net)) {
- struct netdev_hw_addr *ha;
-
- netif_dbg(dev, drv, dev->net, "receive multicast hash filter");
-
- pdata->rfe_ctl |= RFE_CTL_MHF | RFE_CTL_DPF;
-
- netdev_for_each_mc_addr(ha, netdev) {
- u32 bitnum = smsc75xx_hash(ha->addr);
- pdata->multicast_hash_table[bitnum / 32] |=
- (1 << (bitnum % 32));
- }
- } else {
- netif_dbg(dev, drv, dev->net, "receive own packets only");
- pdata->rfe_ctl |= RFE_CTL_DPF;
- }
-
- spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);
-
- /* defer register writes to a sleepable context */
- schedule_work(&pdata->set_multicast);
-}
-
-static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex,
- u16 lcladv, u16 rmtadv)
-{
- u32 flow = 0, fct_flow = 0;
- int ret;
-
- if (duplex == DUPLEX_FULL) {
- u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv);
-
- if (cap & FLOW_CTRL_TX) {
- flow = (FLOW_TX_FCEN | 0xFFFF);
- /* set fct_flow thresholds to 20% and 80% */
- fct_flow = (8 << 8) | 32;
- }
-
- if (cap & FLOW_CTRL_RX)
- flow |= FLOW_RX_FCEN;
-
- netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s",
- (cap & FLOW_CTRL_RX ? "enabled" : "disabled"),
- (cap & FLOW_CTRL_TX ? "enabled" : "disabled"));
- } else {
- netif_dbg(dev, link, dev->net, "half duplex");
- }
-
- ret = smsc75xx_write_reg(dev, FLOW, flow);
- check_warn_return(ret, "Error writing FLOW");
-
- ret = smsc75xx_write_reg(dev, FCT_FLOW, fct_flow);
- check_warn_return(ret, "Error writing FCT_FLOW");
-
- return 0;
-}
-
-static int smsc75xx_link_reset(struct usbnet *dev)
-{
- struct mii_if_info *mii = &dev->mii;
- struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
- u16 lcladv, rmtadv;
- int ret;
-
- /* read and write to clear phy interrupt status */
- ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);
- check_warn_return(ret, "Error reading PHY_INT_SRC");
- smsc75xx_mdio_write(dev->net, mii->phy_id, PHY_INT_SRC, 0xffff);
-
- ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
- check_warn_return(ret, "Error writing INT_STS");
-
- mii_check_media(mii, 1, 1);
- mii_ethtool_gset(&dev->mii, &ecmd);
- lcladv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
- rmtadv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
-
- netif_dbg(dev, link, dev->net, "speed: %u duplex: %d lcladv: %04x"
- " rmtadv: %04x", ethtool_cmd_speed(&ecmd),
- ecmd.duplex, lcladv, rmtadv);
-
- return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv);
-}
-
-static void smsc75xx_status(struct usbnet *dev, struct urb *urb)
-{
- u32 intdata;
-
- if (urb->actual_length != 4) {
- netdev_warn(dev->net,
- "unexpected urb length %d", urb->actual_length);
- return;
- }
-
- memcpy(&intdata, urb->transfer_buffer, 4);
- le32_to_cpus(&intdata);
-
- netif_dbg(dev, link, dev->net, "intdata: 0x%08X", intdata);
-
- if (intdata & INT_ENP_PHY_INT)
- usbnet_defer_kevent(dev, EVENT_LINK_RESET);
- else
- netdev_warn(dev->net,
- "unexpected interrupt, intdata=0x%08X", intdata);
-}
-
-static int smsc75xx_ethtool_get_eeprom_len(struct net_device *net)
-{
- return MAX_EEPROM_SIZE;
-}
-
-static int smsc75xx_ethtool_get_eeprom(struct net_device *netdev,
- struct ethtool_eeprom *ee, u8 *data)
-{
- struct usbnet *dev = netdev_priv(netdev);
-
- ee->magic = LAN75XX_EEPROM_MAGIC;
-
- return smsc75xx_read_eeprom(dev, ee->offset, ee->len, data);
-}
-
-static int smsc75xx_ethtool_set_eeprom(struct net_device *netdev,
- struct ethtool_eeprom *ee, u8 *data)
-{
- struct usbnet *dev = netdev_priv(netdev);
-
- if (ee->magic != LAN75XX_EEPROM_MAGIC) {
- netdev_warn(dev->net,
- "EEPROM: magic value mismatch: 0x%x", ee->magic);
- return -EINVAL;
- }
-
- return smsc75xx_write_eeprom(dev, ee->offset, ee->len, data);
-}
-
-static const struct ethtool_ops smsc75xx_ethtool_ops = {
- .get_link = usbnet_get_link,
- .nway_reset = usbnet_nway_reset,
- .get_drvinfo = usbnet_get_drvinfo,
- .get_msglevel = usbnet_get_msglevel,
- .set_msglevel = usbnet_set_msglevel,
- .get_settings = usbnet_get_settings,
- .set_settings = usbnet_set_settings,
- .get_eeprom_len = smsc75xx_ethtool_get_eeprom_len,
- .get_eeprom = smsc75xx_ethtool_get_eeprom,
- .set_eeprom = smsc75xx_ethtool_set_eeprom,
-};
-
-static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
-{
- struct usbnet *dev = netdev_priv(netdev);
-
- if (!netif_running(netdev))
- return -EINVAL;
-
- return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
-}
-
-static void smsc75xx_init_mac_address(struct usbnet *dev)
-{
- /* try reading mac address from EEPROM */
- if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
- dev->net->dev_addr) == 0) {
- if (is_valid_ether_addr(dev->net->dev_addr)) {
- /* eeprom values are valid so use them */
- netif_dbg(dev, ifup, dev->net,
- "MAC address read from EEPROM");
- return;
- }
- }
-
- /* no eeprom, or eeprom values are invalid. generate random MAC */
- eth_hw_addr_random(dev->net);
- netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr");
-}
-
-static int smsc75xx_set_mac_address(struct usbnet *dev)
-{
- u32 addr_lo = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 |
- dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24;
- u32 addr_hi = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8;
-
- int ret = smsc75xx_write_reg(dev, RX_ADDRH, addr_hi);
- check_warn_return(ret, "Failed to write RX_ADDRH: %d", ret);
-
- ret = smsc75xx_write_reg(dev, RX_ADDRL, addr_lo);
- check_warn_return(ret, "Failed to write RX_ADDRL: %d", ret);
-
- addr_hi |= ADDR_FILTX_FB_VALID;
- ret = smsc75xx_write_reg(dev, ADDR_FILTX, addr_hi);
- check_warn_return(ret, "Failed to write ADDR_FILTX: %d", ret);
-
- ret = smsc75xx_write_reg(dev, ADDR_FILTX + 4, addr_lo);
- check_warn_return(ret, "Failed to write ADDR_FILTX+4: %d", ret);
-
- return 0;
-}
-
-static int smsc75xx_phy_initialize(struct usbnet *dev)
-{
- int bmcr, ret, timeout = 0;
-
- /* Initialize MII structure */
- dev->mii.dev = dev->net;
- dev->mii.mdio_read = smsc75xx_mdio_read;
- dev->mii.mdio_write = smsc75xx_mdio_write;
- dev->mii.phy_id_mask = 0x1f;
- dev->mii.reg_num_mask = 0x1f;
- dev->mii.supports_gmii = 1;
- dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID;
-
- /* reset phy and wait for reset to complete */
- smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
-
- do {
- msleep(10);
- bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
- check_warn_return(bmcr, "Error reading MII_BMCR");
- timeout++;
- } while ((bmcr & BMCR_RESET) && (timeout < 100));
-
- if (timeout >= 100) {
- netdev_warn(dev->net, "timeout on PHY Reset");
- return -EIO;
- }
-
- smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
- ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
- ADVERTISE_PAUSE_ASYM);
- smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000,
- ADVERTISE_1000FULL);
-
- /* read and write to clear phy interrupt status */
- ret = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
- check_warn_return(ret, "Error reading PHY_INT_SRC");
- smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_SRC, 0xffff);
-
- smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,
- PHY_INT_MASK_DEFAULT);
- mii_nway_restart(&dev->mii);
-
- netif_dbg(dev, ifup, dev->net, "phy initialised successfully");
- return 0;
-}
-
-static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size)
-{
- int ret = 0;
- u32 buf;
- bool rxenabled;
-
- ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
- check_warn_return(ret, "Failed to read MAC_RX: %d", ret);
-
- rxenabled = ((buf & MAC_RX_RXEN) != 0);
-
- if (rxenabled) {
- buf &= ~MAC_RX_RXEN;
- ret = smsc75xx_write_reg(dev, MAC_RX, buf);
- check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
- }
-
- /* add 4 to size for FCS */
- buf &= ~MAC_RX_MAX_SIZE;
- buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT) & MAC_RX_MAX_SIZE);
-
- ret = smsc75xx_write_reg(dev, MAC_RX, buf);
- check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
-
- if (rxenabled) {
- buf |= MAC_RX_RXEN;
- ret = smsc75xx_write_reg(dev, MAC_RX, buf);
- check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
- }
-
- return 0;
-}
-
-static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu)
-{
- struct usbnet *dev = netdev_priv(netdev);
-
- int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu);
- check_warn_return(ret, "Failed to set mac rx frame length");
-
- return usbnet_change_mtu(netdev, new_mtu);
-}
-
-/* Enable or disable Rx checksum offload engine */
-static int smsc75xx_set_features(struct net_device *netdev,
- netdev_features_t features)
-{
- struct usbnet *dev = netdev_priv(netdev);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);
-
- if (features & NETIF_F_RXCSUM)
- pdata->rfe_ctl |= RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM;
- else
- pdata->rfe_ctl &= ~(RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM);
-
- spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);
- /* it's racing here! */
-
- ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
- check_warn_return(ret, "Error writing RFE_CTL");
-
- return 0;
-}
-
-static int smsc75xx_reset(struct usbnet *dev)
-{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
- u32 buf;
- int ret = 0, timeout;
-
- netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset");
-
- ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
- check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
-
- buf |= HW_CFG_LRST;
-
- ret = smsc75xx_write_reg(dev, HW_CFG, buf);
- check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
-
- timeout = 0;
- do {
- msleep(10);
- ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
- check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
- timeout++;
- } while ((buf & HW_CFG_LRST) && (timeout < 100));
-
- if (timeout >= 100) {
- netdev_warn(dev->net, "timeout on completion of Lite Reset");
- return -EIO;
- }
-
- netif_dbg(dev, ifup, dev->net, "Lite reset complete, resetting PHY");
-
- ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
- check_warn_return(ret, "Failed to read PMT_CTL: %d", ret);
-
- buf |= PMT_CTL_PHY_RST;
-
- ret = smsc75xx_write_reg(dev, PMT_CTL, buf);
- check_warn_return(ret, "Failed to write PMT_CTL: %d", ret);
-
- timeout = 0;
- do {
- msleep(10);
- ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
- check_warn_return(ret, "Failed to read PMT_CTL: %d", ret);
- timeout++;
- } while ((buf & PMT_CTL_PHY_RST) && (timeout < 100));
-
- if (timeout >= 100) {
- netdev_warn(dev->net, "timeout waiting for PHY Reset");
- return -EIO;
- }
-
- netif_dbg(dev, ifup, dev->net, "PHY reset complete");
-
- smsc75xx_init_mac_address(dev);
-
- ret = smsc75xx_set_mac_address(dev);
- check_warn_return(ret, "Failed to set mac address");
-
- netif_dbg(dev, ifup, dev->net, "MAC Address: %pM", dev->net->dev_addr);
-
- ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
- check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
-
- netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG : 0x%08x", buf);
-
- buf |= HW_CFG_BIR;
-
- ret = smsc75xx_write_reg(dev, HW_CFG, buf);
- check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
-
- ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
- check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
-
- netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG after "
- "writing HW_CFG_BIR: 0x%08x", buf);
-
- if (!turbo_mode) {
- buf = 0;
- dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE;
- } else if (dev->udev->speed == USB_SPEED_HIGH) {
- buf = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
- dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE;
- } else {
- buf = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE;
- dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE;
- }
-
- netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld",
- (ulong)dev->rx_urb_size);
-
- ret = smsc75xx_write_reg(dev, BURST_CAP, buf);
- check_warn_return(ret, "Failed to write BURST_CAP: %d", ret);
-
- ret = smsc75xx_read_reg(dev, BURST_CAP, &buf);
- check_warn_return(ret, "Failed to read BURST_CAP: %d", ret);
-
- netif_dbg(dev, ifup, dev->net,
- "Read Value from BURST_CAP after writing: 0x%08x", buf);
-
- ret = smsc75xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY);
- check_warn_return(ret, "Failed to write BULK_IN_DLY: %d", ret);
-
- ret = smsc75xx_read_reg(dev, BULK_IN_DLY, &buf);
- check_warn_return(ret, "Failed to read BULK_IN_DLY: %d", ret);
-
- netif_dbg(dev, ifup, dev->net,
- "Read Value from BULK_IN_DLY after writing: 0x%08x", buf);
-
- if (turbo_mode) {
- ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
- check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
-
- netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf);
-
- buf |= (HW_CFG_MEF | HW_CFG_BCE);
-
- ret = smsc75xx_write_reg(dev, HW_CFG, buf);
- check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
-
- ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
- check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
-
- netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf);
- }
-
- /* set FIFO sizes */
- buf = (MAX_RX_FIFO_SIZE - 512) / 512;
- ret = smsc75xx_write_reg(dev, FCT_RX_FIFO_END, buf);
- check_warn_return(ret, "Failed to write FCT_RX_FIFO_END: %d", ret);
-
- netif_dbg(dev, ifup, dev->net, "FCT_RX_FIFO_END set to 0x%08x", buf);
-
- buf = (MAX_TX_FIFO_SIZE - 512) / 512;
- ret = smsc75xx_write_reg(dev, FCT_TX_FIFO_END, buf);
- check_warn_return(ret, "Failed to write FCT_TX_FIFO_END: %d", ret);
-
- netif_dbg(dev, ifup, dev->net, "FCT_TX_FIFO_END set to 0x%08x", buf);
-
- ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
- check_warn_return(ret, "Failed to write INT_STS: %d", ret);
-
- ret = smsc75xx_read_reg(dev, ID_REV, &buf);
- check_warn_return(ret, "Failed to read ID_REV: %d", ret);
-
- netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x", buf);
-
- /* Configure GPIO pins as LED outputs */
- ret = smsc75xx_read_reg(dev, LED_GPIO_CFG, &buf);
- check_warn_return(ret, "Failed to read LED_GPIO_CFG: %d", ret);
-
- buf &= ~(LED_GPIO_CFG_LED2_FUN_SEL | LED_GPIO_CFG_LED10_FUN_SEL);
- buf |= LED_GPIO_CFG_LEDGPIO_EN | LED_GPIO_CFG_LED2_FUN_SEL;
-
- ret = smsc75xx_write_reg(dev, LED_GPIO_CFG, buf);
- check_warn_return(ret, "Failed to write LED_GPIO_CFG: %d", ret);
-
- ret = smsc75xx_write_reg(dev, FLOW, 0);
- check_warn_return(ret, "Failed to write FLOW: %d", ret);
-
- ret = smsc75xx_write_reg(dev, FCT_FLOW, 0);
- check_warn_return(ret, "Failed to write FCT_FLOW: %d", ret);
-
- /* Don't need rfe_ctl_lock during initialisation */
- ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
- check_warn_return(ret, "Failed to read RFE_CTL: %d", ret);
-
- pdata->rfe_ctl |= RFE_CTL_AB | RFE_CTL_DPF;
-
- ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
- check_warn_return(ret, "Failed to write RFE_CTL: %d", ret);
-
- ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
- check_warn_return(ret, "Failed to read RFE_CTL: %d", ret);
-
- netif_dbg(dev, ifup, dev->net, "RFE_CTL set to 0x%08x", pdata->rfe_ctl);
-
- /* Enable or disable checksum offload engines */
- smsc75xx_set_features(dev->net, dev->net->features);
-
- smsc75xx_set_multicast(dev->net);
-
- ret = smsc75xx_phy_initialize(dev);
- check_warn_return(ret, "Failed to initialize PHY: %d", ret);
-
- ret = smsc75xx_read_reg(dev, INT_EP_CTL, &buf);
- check_warn_return(ret, "Failed to read INT_EP_CTL: %d", ret);
-
- /* enable PHY interrupts */
- buf |= INT_ENP_PHY_INT;
-
- ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf);
- check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret);
-
- /* allow mac to detect speed and duplex from phy */
- ret = smsc75xx_read_reg(dev, MAC_CR, &buf);
- check_warn_return(ret, "Failed to read MAC_CR: %d", ret);
-
- buf |= (MAC_CR_ADD | MAC_CR_ASD);
- ret = smsc75xx_write_reg(dev, MAC_CR, buf);
- check_warn_return(ret, "Failed to write MAC_CR: %d", ret);
-
- ret = smsc75xx_read_reg(dev, MAC_TX, &buf);
- check_warn_return(ret, "Failed to read MAC_TX: %d", ret);
-
- buf |= MAC_TX_TXEN;
-
- ret = smsc75xx_write_reg(dev, MAC_TX, buf);
- check_warn_return(ret, "Failed to write MAC_TX: %d", ret);
-
- netif_dbg(dev, ifup, dev->net, "MAC_TX set to 0x%08x", buf);
-
- ret = smsc75xx_read_reg(dev, FCT_TX_CTL, &buf);
- check_warn_return(ret, "Failed to read FCT_TX_CTL: %d", ret);
-
- buf |= FCT_TX_CTL_EN;
-
- ret = smsc75xx_write_reg(dev, FCT_TX_CTL, buf);
- check_warn_return(ret, "Failed to write FCT_TX_CTL: %d", ret);
-
- netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x", buf);
-
- ret = smsc75xx_set_rx_max_frame_length(dev, 1514);
- check_warn_return(ret, "Failed to set max rx frame length");
-
- ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
- check_warn_return(ret, "Failed to read MAC_RX: %d", ret);
-
- buf |= MAC_RX_RXEN;
-
- ret = smsc75xx_write_reg(dev, MAC_RX, buf);
- check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
-
- netif_dbg(dev, ifup, dev->net, "MAC_RX set to 0x%08x", buf);
-
- ret = smsc75xx_read_reg(dev, FCT_RX_CTL, &buf);
- check_warn_return(ret, "Failed to read FCT_RX_CTL: %d", ret);
-
- buf |= FCT_RX_CTL_EN;
-
- ret = smsc75xx_write_reg(dev, FCT_RX_CTL, buf);
- check_warn_return(ret, "Failed to write FCT_RX_CTL: %d", ret);
-
- netif_dbg(dev, ifup, dev->net, "FCT_RX_CTL set to 0x%08x", buf);
-
- netif_dbg(dev, ifup, dev->net, "smsc75xx_reset, return 0");
- return 0;
-}
-
-static const struct net_device_ops smsc75xx_netdev_ops = {
- .ndo_open = usbnet_open,
- .ndo_stop = usbnet_stop,
- .ndo_start_xmit = usbnet_start_xmit,
- .ndo_tx_timeout = usbnet_tx_timeout,
- .ndo_change_mtu = smsc75xx_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_do_ioctl = smsc75xx_ioctl,
- .ndo_set_rx_mode = smsc75xx_set_multicast,
- .ndo_set_features = smsc75xx_set_features,
-};
-
-static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- struct smsc75xx_priv *pdata = NULL;
- int ret;
-
- printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n");
-
- ret = usbnet_get_endpoints(dev, intf);
- check_warn_return(ret, "usbnet_get_endpoints failed: %d", ret);
-
- dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc75xx_priv),
- GFP_KERNEL);
-
- pdata = (struct smsc75xx_priv *)(dev->data[0]);
- if (!pdata) {
- netdev_warn(dev->net, "Unable to allocate smsc75xx_priv");
- return -ENOMEM;
- }
-
- pdata->dev = dev;
-
- spin_lock_init(&pdata->rfe_ctl_lock);
- mutex_init(&pdata->dataport_mutex);
-
- INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write);
-
- 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;
-
- /* Init all registers */
- ret = smsc75xx_reset(dev);
-
- dev->net->netdev_ops = &smsc75xx_netdev_ops;
- dev->net->ethtool_ops = &smsc75xx_ethtool_ops;
- dev->net->flags |= IFF_MULTICAST;
- dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD;
- dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
- return 0;
-}
-
-static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)
-{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
- if (pdata) {
- netif_dbg(dev, ifdown, dev->net, "free pdata");
- kfree(pdata);
- pdata = NULL;
- dev->data[0] = 0;
- }
-}
-
-static void smsc75xx_rx_csum_offload(struct usbnet *dev, struct sk_buff *skb,
- u32 rx_cmd_a, u32 rx_cmd_b)
-{
- if (!(dev->net->features & NETIF_F_RXCSUM) ||
- unlikely(rx_cmd_a & RX_CMD_A_LCSM)) {
- skb->ip_summed = CHECKSUM_NONE;
- } else {
- skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT));
- skb->ip_summed = CHECKSUM_COMPLETE;
- }
-}
-
-static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- while (skb->len > 0) {
- u32 rx_cmd_a, rx_cmd_b, align_count, size;
- struct sk_buff *ax_skb;
- unsigned char *packet;
-
- memcpy(&rx_cmd_a, skb->data, sizeof(rx_cmd_a));
- le32_to_cpus(&rx_cmd_a);
- skb_pull(skb, 4);
-
- memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b));
- le32_to_cpus(&rx_cmd_b);
- skb_pull(skb, 4 + RXW_PADDING);
-
- packet = skb->data;
-
- /* get the packet length */
- size = (rx_cmd_a & RX_CMD_A_LEN) - RXW_PADDING;
- align_count = (4 - ((size + RXW_PADDING) % 4)) % 4;
-
- if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {
- netif_dbg(dev, rx_err, dev->net,
- "Error rx_cmd_a=0x%08x", rx_cmd_a);
- dev->net->stats.rx_errors++;
- dev->net->stats.rx_dropped++;
-
- if (rx_cmd_a & RX_CMD_A_FCS)
- dev->net->stats.rx_crc_errors++;
- else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT))
- dev->net->stats.rx_frame_errors++;
- } else {
- /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */
- if (unlikely(size > (ETH_FRAME_LEN + 12))) {
- netif_dbg(dev, rx_err, dev->net,
- "size err rx_cmd_a=0x%08x", rx_cmd_a);
- return 0;
- }
-
- /* last frame in this batch */
- if (skb->len == size) {
- smsc75xx_rx_csum_offload(dev, skb, rx_cmd_a,
- rx_cmd_b);
-
- skb_trim(skb, skb->len - 4); /* remove fcs */
- skb->truesize = size + sizeof(struct sk_buff);
-
- return 1;
- }
-
- ax_skb = skb_clone(skb, GFP_ATOMIC);
- if (unlikely(!ax_skb)) {
- netdev_warn(dev->net, "Error allocating skb");
- return 0;
- }
-
- ax_skb->len = size;
- ax_skb->data = packet;
- skb_set_tail_pointer(ax_skb, size);
-
- smsc75xx_rx_csum_offload(dev, ax_skb, rx_cmd_a,
- rx_cmd_b);
-
- skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
- ax_skb->truesize = size + sizeof(struct sk_buff);
-
- usbnet_skb_return(dev, ax_skb);
- }
-
- skb_pull(skb, size);
-
- /* padding bytes before the next frame starts */
- if (skb->len)
- skb_pull(skb, align_count);
- }
-
- if (unlikely(skb->len < 0)) {
- netdev_warn(dev->net, "invalid rx length<0 %d", skb->len);
- return 0;
- }
-
- return 1;
-}
-
-static struct sk_buff *smsc75xx_tx_fixup(struct usbnet *dev,
- struct sk_buff *skb, gfp_t flags)
-{
- 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);
- dev_kfree_skb_any(skb);
- skb = skb2;
- if (!skb)
- return NULL;
- }
-
- tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN) | TX_CMD_A_FCS;
-
- if (skb->ip_summed == CHECKSUM_PARTIAL)
- tx_cmd_a |= TX_CMD_A_IPE | TX_CMD_A_TPE;
-
- if (skb_is_gso(skb)) {
- u16 mss = max(skb_shinfo(skb)->gso_size, TX_MSS_MIN);
- tx_cmd_b = (mss << TX_CMD_B_MSS_SHIFT) & TX_CMD_B_MSS;
-
- tx_cmd_a |= TX_CMD_A_LSO;
- } else {
- tx_cmd_b = 0;
- }
-
- skb_push(skb, 4);
- cpu_to_le32s(&tx_cmd_b);
- memcpy(skb->data, &tx_cmd_b, 4);
-
- skb_push(skb, 4);
- cpu_to_le32s(&tx_cmd_a);
- memcpy(skb->data, &tx_cmd_a, 4);
-
- return skb;
-}
-
-static const struct driver_info smsc75xx_info = {
- .description = "smsc75xx USB 2.0 Gigabit Ethernet",
- .bind = smsc75xx_bind,
- .unbind = smsc75xx_unbind,
- .link_reset = smsc75xx_link_reset,
- .reset = smsc75xx_reset,
- .rx_fixup = smsc75xx_rx_fixup,
- .tx_fixup = smsc75xx_tx_fixup,
- .status = smsc75xx_status,
- .flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,
-};
-
-static const struct usb_device_id products[] = {
- {
- /* SMSC7500 USB Gigabit Ethernet Device */
- USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7500),
- .driver_info = (unsigned long) &smsc75xx_info,
- },
- {
- /* SMSC7500 USB Gigabit Ethernet Device */
- USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7505),
- .driver_info = (unsigned long) &smsc75xx_info,
- },
- { }, /* END */
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver smsc75xx_driver = {
- .name = SMSC_CHIPNAME,
- .id_table = products,
- .probe = usbnet_probe,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
- .disconnect = usbnet_disconnect,
-};
-
-module_usb_driver(smsc75xx_driver);
-
-MODULE_AUTHOR("Nancy Lin");
-MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>");
-MODULE_DESCRIPTION("SMSC75XX USB 2.0 Gigabit Ethernet Devices");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/smsc75xx.h b/ANDROID_3.4.5/drivers/net/usb/smsc75xx.h
deleted file mode 100644
index 16e98c77..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/smsc75xx.h
+++ /dev/null
@@ -1,421 +0,0 @@
- /***************************************************************************
- *
- * Copyright (C) 2007-2010 SMSC
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *****************************************************************************/
-
-#ifndef _SMSC75XX_H
-#define _SMSC75XX_H
-
-/* Tx command words */
-#define TX_CMD_A_LSO (0x08000000)
-#define TX_CMD_A_IPE (0x04000000)
-#define TX_CMD_A_TPE (0x02000000)
-#define TX_CMD_A_IVTG (0x01000000)
-#define TX_CMD_A_RVTG (0x00800000)
-#define TX_CMD_A_FCS (0x00400000)
-#define TX_CMD_A_LEN (0x000FFFFF)
-
-#define TX_CMD_B_MSS (0x3FFF0000)
-#define TX_CMD_B_MSS_SHIFT (16)
-#define TX_MSS_MIN ((u16)8)
-#define TX_CMD_B_VTAG (0x0000FFFF)
-
-/* Rx command words */
-#define RX_CMD_A_ICE (0x80000000)
-#define RX_CMD_A_TCE (0x40000000)
-#define RX_CMD_A_IPV (0x20000000)
-#define RX_CMD_A_PID (0x18000000)
-#define RX_CMD_A_PID_NIP (0x00000000)
-#define RX_CMD_A_PID_TCP (0x08000000)
-#define RX_CMD_A_PID_UDP (0x10000000)
-#define RX_CMD_A_PID_PP (0x18000000)
-#define RX_CMD_A_PFF (0x04000000)
-#define RX_CMD_A_BAM (0x02000000)
-#define RX_CMD_A_MAM (0x01000000)
-#define RX_CMD_A_FVTG (0x00800000)
-#define RX_CMD_A_RED (0x00400000)
-#define RX_CMD_A_RWT (0x00200000)
-#define RX_CMD_A_RUNT (0x00100000)
-#define RX_CMD_A_LONG (0x00080000)
-#define RX_CMD_A_RXE (0x00040000)
-#define RX_CMD_A_DRB (0x00020000)
-#define RX_CMD_A_FCS (0x00010000)
-#define RX_CMD_A_UAM (0x00008000)
-#define RX_CMD_A_LCSM (0x00004000)
-#define RX_CMD_A_LEN (0x00003FFF)
-
-#define RX_CMD_B_CSUM (0xFFFF0000)
-#define RX_CMD_B_CSUM_SHIFT (16)
-#define RX_CMD_B_VTAG (0x0000FFFF)
-
-/* SCSRs */
-#define ID_REV (0x0000)
-
-#define FPGA_REV (0x0004)
-
-#define BOND_CTL (0x0008)
-
-#define INT_STS (0x000C)
-#define INT_STS_RDFO_INT (0x00400000)
-#define INT_STS_TXE_INT (0x00200000)
-#define INT_STS_MACRTO_INT (0x00100000)
-#define INT_STS_TX_DIS_INT (0x00080000)
-#define INT_STS_RX_DIS_INT (0x00040000)
-#define INT_STS_PHY_INT_ (0x00020000)
-#define INT_STS_MAC_ERR_INT (0x00008000)
-#define INT_STS_TDFU (0x00004000)
-#define INT_STS_TDFO (0x00002000)
-#define INT_STS_GPIOS (0x00000FFF)
-#define INT_STS_CLEAR_ALL (0xFFFFFFFF)
-
-#define HW_CFG (0x0010)
-#define HW_CFG_SMDET_STS (0x00008000)
-#define HW_CFG_SMDET_EN (0x00004000)
-#define HW_CFG_EEM (0x00002000)
-#define HW_CFG_RST_PROTECT (0x00001000)
-#define HW_CFG_PORT_SWAP (0x00000800)
-#define HW_CFG_PHY_BOOST (0x00000600)
-#define HW_CFG_PHY_BOOST_NORMAL (0x00000000)
-#define HW_CFG_PHY_BOOST_4 (0x00002000)
-#define HW_CFG_PHY_BOOST_8 (0x00004000)
-#define HW_CFG_PHY_BOOST_12 (0x00006000)
-#define HW_CFG_LEDB (0x00000100)
-#define HW_CFG_BIR (0x00000080)
-#define HW_CFG_SBP (0x00000040)
-#define HW_CFG_IME (0x00000020)
-#define HW_CFG_MEF (0x00000010)
-#define HW_CFG_ETC (0x00000008)
-#define HW_CFG_BCE (0x00000004)
-#define HW_CFG_LRST (0x00000002)
-#define HW_CFG_SRST (0x00000001)
-
-#define PMT_CTL (0x0014)
-#define PMT_CTL_PHY_PWRUP (0x00000400)
-#define PMT_CTL_RES_CLR_WKP_EN (0x00000100)
-#define PMT_CTL_DEV_RDY (0x00000080)
-#define PMT_CTL_SUS_MODE (0x00000060)
-#define PMT_CTL_SUS_MODE_0 (0x00000000)
-#define PMT_CTL_SUS_MODE_1 (0x00000020)
-#define PMT_CTL_SUS_MODE_2 (0x00000040)
-#define PMT_CTL_SUS_MODE_3 (0x00000060)
-#define PMT_CTL_PHY_RST (0x00000010)
-#define PMT_CTL_WOL_EN (0x00000008)
-#define PMT_CTL_ED_EN (0x00000004)
-#define PMT_CTL_WUPS (0x00000003)
-#define PMT_CTL_WUPS_NO (0x00000000)
-#define PMT_CTL_WUPS_ED (0x00000001)
-#define PMT_CTL_WUPS_WOL (0x00000002)
-#define PMT_CTL_WUPS_MULTI (0x00000003)
-
-#define LED_GPIO_CFG (0x0018)
-#define LED_GPIO_CFG_LED2_FUN_SEL (0x80000000)
-#define LED_GPIO_CFG_LED10_FUN_SEL (0x40000000)
-#define LED_GPIO_CFG_LEDGPIO_EN (0x0000F000)
-#define LED_GPIO_CFG_LEDGPIO_EN_0 (0x00001000)
-#define LED_GPIO_CFG_LEDGPIO_EN_1 (0x00002000)
-#define LED_GPIO_CFG_LEDGPIO_EN_2 (0x00004000)
-#define LED_GPIO_CFG_LEDGPIO_EN_3 (0x00008000)
-#define LED_GPIO_CFG_GPBUF (0x00000F00)
-#define LED_GPIO_CFG_GPBUF_0 (0x00000100)
-#define LED_GPIO_CFG_GPBUF_1 (0x00000200)
-#define LED_GPIO_CFG_GPBUF_2 (0x00000400)
-#define LED_GPIO_CFG_GPBUF_3 (0x00000800)
-#define LED_GPIO_CFG_GPDIR (0x000000F0)
-#define LED_GPIO_CFG_GPDIR_0 (0x00000010)
-#define LED_GPIO_CFG_GPDIR_1 (0x00000020)
-#define LED_GPIO_CFG_GPDIR_2 (0x00000040)
-#define LED_GPIO_CFG_GPDIR_3 (0x00000080)
-#define LED_GPIO_CFG_GPDATA (0x0000000F)
-#define LED_GPIO_CFG_GPDATA_0 (0x00000001)
-#define LED_GPIO_CFG_GPDATA_1 (0x00000002)
-#define LED_GPIO_CFG_GPDATA_2 (0x00000004)
-#define LED_GPIO_CFG_GPDATA_3 (0x00000008)
-
-#define GPIO_CFG (0x001C)
-#define GPIO_CFG_SHIFT (24)
-#define GPIO_CFG_GPEN (0xFF000000)
-#define GPIO_CFG_GPBUF (0x00FF0000)
-#define GPIO_CFG_GPDIR (0x0000FF00)
-#define GPIO_CFG_GPDATA (0x000000FF)
-
-#define GPIO_WAKE (0x0020)
-#define GPIO_WAKE_PHY_LINKUP_EN (0x80000000)
-#define GPIO_WAKE_POL (0x0FFF0000)
-#define GPIO_WAKE_POL_SHIFT (16)
-#define GPIO_WAKE_WK (0x00000FFF)
-
-#define DP_SEL (0x0024)
-#define DP_SEL_DPRDY (0x80000000)
-#define DP_SEL_RSEL (0x0000000F)
-#define DP_SEL_URX (0x00000000)
-#define DP_SEL_VHF (0x00000001)
-#define DP_SEL_VHF_HASH_LEN (16)
-#define DP_SEL_VHF_VLAN_LEN (128)
-#define DP_SEL_LSO_HEAD (0x00000002)
-#define DP_SEL_FCT_RX (0x00000003)
-#define DP_SEL_FCT_TX (0x00000004)
-#define DP_SEL_DESCRIPTOR (0x00000005)
-#define DP_SEL_WOL (0x00000006)
-
-#define DP_CMD (0x0028)
-#define DP_CMD_WRITE (0x01)
-#define DP_CMD_READ (0x00)
-
-#define DP_ADDR (0x002C)
-
-#define DP_DATA (0x0030)
-
-#define BURST_CAP (0x0034)
-#define BURST_CAP_MASK (0x0000000F)
-
-#define INT_EP_CTL (0x0038)
-#define INT_EP_CTL_INTEP_ON (0x80000000)
-#define INT_EP_CTL_RDFO_EN (0x00400000)
-#define INT_EP_CTL_TXE_EN (0x00200000)
-#define INT_EP_CTL_MACROTO_EN (0x00100000)
-#define INT_EP_CTL_TX_DIS_EN (0x00080000)
-#define INT_EP_CTL_RX_DIS_EN (0x00040000)
-#define INT_EP_CTL_PHY_EN_ (0x00020000)
-#define INT_EP_CTL_MAC_ERR_EN (0x00008000)
-#define INT_EP_CTL_TDFU_EN (0x00004000)
-#define INT_EP_CTL_TDFO_EN (0x00002000)
-#define INT_EP_CTL_RX_FIFO_EN (0x00001000)
-#define INT_EP_CTL_GPIOX_EN (0x00000FFF)
-
-#define BULK_IN_DLY (0x003C)
-#define BULK_IN_DLY_MASK (0xFFFF)
-
-#define E2P_CMD (0x0040)
-#define E2P_CMD_BUSY (0x80000000)
-#define E2P_CMD_MASK (0x70000000)
-#define E2P_CMD_READ (0x00000000)
-#define E2P_CMD_EWDS (0x10000000)
-#define E2P_CMD_EWEN (0x20000000)
-#define E2P_CMD_WRITE (0x30000000)
-#define E2P_CMD_WRAL (0x40000000)
-#define E2P_CMD_ERASE (0x50000000)
-#define E2P_CMD_ERAL (0x60000000)
-#define E2P_CMD_RELOAD (0x70000000)
-#define E2P_CMD_TIMEOUT (0x00000400)
-#define E2P_CMD_LOADED (0x00000200)
-#define E2P_CMD_ADDR (0x000001FF)
-
-#define MAX_EEPROM_SIZE (512)
-
-#define E2P_DATA (0x0044)
-#define E2P_DATA_MASK_ (0x000000FF)
-
-#define RFE_CTL (0x0060)
-#define RFE_CTL_TCPUDP_CKM (0x00001000)
-#define RFE_CTL_IP_CKM (0x00000800)
-#define RFE_CTL_AB (0x00000400)
-#define RFE_CTL_AM (0x00000200)
-#define RFE_CTL_AU (0x00000100)
-#define RFE_CTL_VS (0x00000080)
-#define RFE_CTL_UF (0x00000040)
-#define RFE_CTL_VF (0x00000020)
-#define RFE_CTL_SPF (0x00000010)
-#define RFE_CTL_MHF (0x00000008)
-#define RFE_CTL_DHF (0x00000004)
-#define RFE_CTL_DPF (0x00000002)
-#define RFE_CTL_RST_RF (0x00000001)
-
-#define VLAN_TYPE (0x0064)
-#define VLAN_TYPE_MASK (0x0000FFFF)
-
-#define FCT_RX_CTL (0x0090)
-#define FCT_RX_CTL_EN (0x80000000)
-#define FCT_RX_CTL_RST (0x40000000)
-#define FCT_RX_CTL_SBF (0x02000000)
-#define FCT_RX_CTL_OVERFLOW (0x01000000)
-#define FCT_RX_CTL_FRM_DROP (0x00800000)
-#define FCT_RX_CTL_RX_NOT_EMPTY (0x00400000)
-#define FCT_RX_CTL_RX_EMPTY (0x00200000)
-#define FCT_RX_CTL_RX_DISABLED (0x00100000)
-#define FCT_RX_CTL_RXUSED (0x0000FFFF)
-
-#define FCT_TX_CTL (0x0094)
-#define FCT_TX_CTL_EN (0x80000000)
-#define FCT_TX_CTL_RST (0x40000000)
-#define FCT_TX_CTL_TX_NOT_EMPTY (0x00400000)
-#define FCT_TX_CTL_TX_EMPTY (0x00200000)
-#define FCT_TX_CTL_TX_DISABLED (0x00100000)
-#define FCT_TX_CTL_TXUSED (0x0000FFFF)
-
-#define FCT_RX_FIFO_END (0x0098)
-#define FCT_RX_FIFO_END_MASK (0x0000007F)
-
-#define FCT_TX_FIFO_END (0x009C)
-#define FCT_TX_FIFO_END_MASK (0x0000003F)
-
-#define FCT_FLOW (0x00A0)
-#define FCT_FLOW_THRESHOLD_OFF (0x00007F00)
-#define FCT_FLOW_THRESHOLD_OFF_SHIFT (8)
-#define FCT_FLOW_THRESHOLD_ON (0x0000007F)
-
-/* MAC CSRs */
-#define MAC_CR (0x100)
-#define MAC_CR_ADP (0x00002000)
-#define MAC_CR_ADD (0x00001000)
-#define MAC_CR_ASD (0x00000800)
-#define MAC_CR_INT_LOOP (0x00000400)
-#define MAC_CR_BOLMT (0x000000C0)
-#define MAC_CR_FDPX (0x00000008)
-#define MAC_CR_CFG (0x00000006)
-#define MAC_CR_CFG_10 (0x00000000)
-#define MAC_CR_CFG_100 (0x00000002)
-#define MAC_CR_CFG_1000 (0x00000004)
-#define MAC_CR_RST (0x00000001)
-
-#define MAC_RX (0x104)
-#define MAC_RX_MAX_SIZE (0x3FFF0000)
-#define MAC_RX_MAX_SIZE_SHIFT (16)
-#define MAC_RX_FCS_STRIP (0x00000010)
-#define MAC_RX_FSE (0x00000004)
-#define MAC_RX_RXD (0x00000002)
-#define MAC_RX_RXEN (0x00000001)
-
-#define MAC_TX (0x108)
-#define MAC_TX_BFCS (0x00000004)
-#define MAC_TX_TXD (0x00000002)
-#define MAC_TX_TXEN (0x00000001)
-
-#define FLOW (0x10C)
-#define FLOW_FORCE_FC (0x80000000)
-#define FLOW_TX_FCEN (0x40000000)
-#define FLOW_RX_FCEN (0x20000000)
-#define FLOW_FPF (0x10000000)
-#define FLOW_PAUSE_TIME (0x0000FFFF)
-
-#define RAND_SEED (0x110)
-#define RAND_SEED_MASK (0x0000FFFF)
-
-#define ERR_STS (0x114)
-#define ERR_STS_FCS_ERR (0x00000100)
-#define ERR_STS_LFRM_ERR (0x00000080)
-#define ERR_STS_RUNT_ERR (0x00000040)
-#define ERR_STS_COLLISION_ERR (0x00000010)
-#define ERR_STS_ALIGN_ERR (0x00000008)
-#define ERR_STS_URUN_ERR (0x00000004)
-
-#define RX_ADDRH (0x118)
-#define RX_ADDRH_MASK (0x0000FFFF)
-
-#define RX_ADDRL (0x11C)
-
-#define MII_ACCESS (0x120)
-#define MII_ACCESS_PHY_ADDR (0x0000F800)
-#define MII_ACCESS_PHY_ADDR_SHIFT (11)
-#define MII_ACCESS_REG_ADDR (0x000007C0)
-#define MII_ACCESS_REG_ADDR_SHIFT (6)
-#define MII_ACCESS_READ (0x00000000)
-#define MII_ACCESS_WRITE (0x00000002)
-#define MII_ACCESS_BUSY (0x00000001)
-
-#define MII_DATA (0x124)
-#define MII_DATA_MASK (0x0000FFFF)
-
-#define WUCSR (0x140)
-#define WUCSR_PFDA_FR (0x00000080)
-#define WUCSR_WUFR (0x00000040)
-#define WUCSR_MPR (0x00000020)
-#define WUCSR_BCAST_FR (0x00000010)
-#define WUCSR_PFDA_EN (0x00000008)
-#define WUCSR_WUEN (0x00000004)
-#define WUCSR_MPEN (0x00000002)
-#define WUCSR_BCST_EN (0x00000001)
-
-#define WUF_CFGX (0x144)
-#define WUF_CFGX_EN (0x80000000)
-#define WUF_CFGX_ATYPE (0x03000000)
-#define WUF_CFGX_ATYPE_UNICAST (0x00000000)
-#define WUF_CFGX_ATYPE_MULTICAST (0x02000000)
-#define WUF_CFGX_ATYPE_ALL (0x03000000)
-#define WUF_CFGX_PATTERN_OFFSET (0x007F0000)
-#define WUF_CFGX_PATTERN_OFFSET_SHIFT (16)
-#define WUF_CFGX_CRC16 (0x0000FFFF)
-#define WUF_NUM (8)
-
-#define WUF_MASKX (0x170)
-#define WUF_MASKX_AVALID (0x80000000)
-#define WUF_MASKX_ATYPE (0x40000000)
-
-#define ADDR_FILTX (0x300)
-#define ADDR_FILTX_FB_VALID (0x80000000)
-#define ADDR_FILTX_FB_TYPE (0x40000000)
-#define ADDR_FILTX_FB_ADDRHI (0x0000FFFF)
-#define ADDR_FILTX_SB_ADDRLO (0xFFFFFFFF)
-
-#define WUCSR2 (0x500)
-#define WUCSR2_NS_RCD (0x00000040)
-#define WUCSR2_ARP_RCD (0x00000020)
-#define WUCSR2_TCPSYN_RCD (0x00000010)
-#define WUCSR2_NS_OFFLOAD (0x00000004)
-#define WUCSR2_ARP_OFFLOAD (0x00000002)
-#define WUCSR2_TCPSYN_OFFLOAD (0x00000001)
-
-#define WOL_FIFO_STS (0x504)
-
-#define IPV6_ADDRX (0x510)
-
-#define IPV4_ADDRX (0x590)
-
-
-/* Vendor-specific PHY Definitions */
-
-/* Mode Control/Status Register */
-#define PHY_MODE_CTRL_STS (17)
-#define MODE_CTRL_STS_EDPWRDOWN ((u16)0x2000)
-#define MODE_CTRL_STS_ENERGYON ((u16)0x0002)
-
-#define PHY_INT_SRC (29)
-#define PHY_INT_SRC_ENERGY_ON ((u16)0x0080)
-#define PHY_INT_SRC_ANEG_COMP ((u16)0x0040)
-#define PHY_INT_SRC_REMOTE_FAULT ((u16)0x0020)
-#define PHY_INT_SRC_LINK_DOWN ((u16)0x0010)
-
-#define PHY_INT_MASK (30)
-#define PHY_INT_MASK_ENERGY_ON ((u16)0x0080)
-#define PHY_INT_MASK_ANEG_COMP ((u16)0x0040)
-#define PHY_INT_MASK_REMOTE_FAULT ((u16)0x0020)
-#define PHY_INT_MASK_LINK_DOWN ((u16)0x0010)
-#define PHY_INT_MASK_DEFAULT (PHY_INT_MASK_ANEG_COMP | \
- PHY_INT_MASK_LINK_DOWN)
-
-#define PHY_SPECIAL (31)
-#define PHY_SPECIAL_SPD ((u16)0x001C)
-#define PHY_SPECIAL_SPD_10HALF ((u16)0x0004)
-#define PHY_SPECIAL_SPD_10FULL ((u16)0x0014)
-#define PHY_SPECIAL_SPD_100HALF ((u16)0x0008)
-#define PHY_SPECIAL_SPD_100FULL ((u16)0x0018)
-
-/* USB Vendor Requests */
-#define USB_VENDOR_REQUEST_WRITE_REGISTER 0xA0
-#define USB_VENDOR_REQUEST_READ_REGISTER 0xA1
-#define USB_VENDOR_REQUEST_GET_STATS 0xA2
-
-/* Interrupt Endpoint status word bitfields */
-#define INT_ENP_RDFO_INT ((u32)BIT(22))
-#define INT_ENP_TXE_INT ((u32)BIT(21))
-#define INT_ENP_TX_DIS_INT ((u32)BIT(19))
-#define INT_ENP_RX_DIS_INT ((u32)BIT(18))
-#define INT_ENP_PHY_INT ((u32)BIT(17))
-#define INT_ENP_MAC_ERR_INT ((u32)BIT(15))
-#define INT_ENP_RX_FIFO_DATA_INT ((u32)BIT(12))
-
-#endif /* _SMSC75XX_H */
diff --git a/ANDROID_3.4.5/drivers/net/usb/smsc95xx.c b/ANDROID_3.4.5/drivers/net/usb/smsc95xx.c
deleted file mode 100644
index 94ae6699..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/smsc95xx.c
+++ /dev/null
@@ -1,1307 +0,0 @@
- /***************************************************************************
- *
- * Copyright (C) 2007-2008 SMSC
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/kmod.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/crc32.h>
-#include <linux/usb/usbnet.h>
-#include <linux/slab.h>
-#include "smsc95xx.h"
-
-#define SMSC_CHIPNAME "smsc95xx"
-#define SMSC_DRIVER_VERSION "1.0.4"
-#define HS_USB_PKT_SIZE (512)
-#define FS_USB_PKT_SIZE (64)
-#define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE)
-#define DEFAULT_FS_BURST_CAP_SIZE (6 * 1024 + 33 * FS_USB_PKT_SIZE)
-#define DEFAULT_BULK_IN_DELAY (0x00002000)
-#define MAX_SINGLE_PACKET_SIZE (2048)
-#define LAN95XX_EEPROM_MAGIC (0x9500)
-#define EEPROM_MAC_OFFSET (0x01)
-#define DEFAULT_TX_CSUM_ENABLE (true)
-#define DEFAULT_RX_CSUM_ENABLE (true)
-#define SMSC95XX_INTERNAL_PHY_ID (1)
-#define SMSC95XX_TX_OVERHEAD (8)
-#define SMSC95XX_TX_OVERHEAD_CSUM (12)
-
-struct smsc95xx_priv {
- u32 mac_cr;
- u32 hash_hi;
- u32 hash_lo;
- spinlock_t mac_cr_lock;
-};
-
-struct usb_context {
- struct usb_ctrlrequest req;
- struct usbnet *dev;
-};
-
-static bool turbo_mode = true;
-module_param(turbo_mode, bool, 0644);
-MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
-
-static int smsc95xx_read_reg(struct usbnet *dev, u32 index, u32 *data)
-{
- u32 *buf = kmalloc(4, GFP_KERNEL);
- int ret;
-
- BUG_ON(!dev);
-
- if (!buf)
- return -ENOMEM;
-
- ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
- USB_VENDOR_REQUEST_READ_REGISTER,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 00, index, buf, 4, USB_CTRL_GET_TIMEOUT);
-
- if (unlikely(ret < 0))
- netdev_warn(dev->net, "Failed to read register index 0x%08x\n", index);
-
- le32_to_cpus(buf);
- *data = *buf;
- kfree(buf);
-
- return ret;
-}
-
-static int smsc95xx_write_reg(struct usbnet *dev, u32 index, u32 data)
-{
- u32 *buf = kmalloc(4, GFP_KERNEL);
- int ret;
-
- BUG_ON(!dev);
-
- if (!buf)
- return -ENOMEM;
-
- *buf = data;
- cpu_to_le32s(buf);
-
- ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
- USB_VENDOR_REQUEST_WRITE_REGISTER,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 00, index, buf, 4, USB_CTRL_SET_TIMEOUT);
-
- if (unlikely(ret < 0))
- netdev_warn(dev->net, "Failed to write register index 0x%08x\n", index);
-
- kfree(buf);
-
- return ret;
-}
-
-/* Loop until the read is completed with timeout
- * called with phy_mutex held */
-static int smsc95xx_phy_wait_not_busy(struct usbnet *dev)
-{
- unsigned long start_time = jiffies;
- u32 val;
-
- do {
- smsc95xx_read_reg(dev, MII_ADDR, &val);
- if (!(val & MII_BUSY_))
- return 0;
- } while (!time_after(jiffies, start_time + HZ));
-
- return -EIO;
-}
-
-static int smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx)
-{
- struct usbnet *dev = netdev_priv(netdev);
- u32 val, addr;
-
- mutex_lock(&dev->phy_mutex);
-
- /* confirm MII not busy */
- if (smsc95xx_phy_wait_not_busy(dev)) {
- netdev_warn(dev->net, "MII is busy in smsc95xx_mdio_read\n");
- mutex_unlock(&dev->phy_mutex);
- return -EIO;
- }
-
- /* set the address, index & direction (read from PHY) */
- phy_id &= dev->mii.phy_id_mask;
- idx &= dev->mii.reg_num_mask;
- addr = (phy_id << 11) | (idx << 6) | MII_READ_;
- smsc95xx_write_reg(dev, MII_ADDR, addr);
-
- if (smsc95xx_phy_wait_not_busy(dev)) {
- netdev_warn(dev->net, "Timed out reading MII reg %02X\n", idx);
- mutex_unlock(&dev->phy_mutex);
- return -EIO;
- }
-
- smsc95xx_read_reg(dev, MII_DATA, &val);
-
- mutex_unlock(&dev->phy_mutex);
-
- return (u16)(val & 0xFFFF);
-}
-
-static void smsc95xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
- int regval)
-{
- struct usbnet *dev = netdev_priv(netdev);
- u32 val, addr;
-
- mutex_lock(&dev->phy_mutex);
-
- /* confirm MII not busy */
- if (smsc95xx_phy_wait_not_busy(dev)) {
- netdev_warn(dev->net, "MII is busy in smsc95xx_mdio_write\n");
- mutex_unlock(&dev->phy_mutex);
- return;
- }
-
- val = regval;
- smsc95xx_write_reg(dev, MII_DATA, val);
-
- /* set the address, index & direction (write to PHY) */
- phy_id &= dev->mii.phy_id_mask;
- idx &= dev->mii.reg_num_mask;
- addr = (phy_id << 11) | (idx << 6) | MII_WRITE_;
- smsc95xx_write_reg(dev, MII_ADDR, addr);
-
- if (smsc95xx_phy_wait_not_busy(dev))
- netdev_warn(dev->net, "Timed out writing MII reg %02X\n", idx);
-
- mutex_unlock(&dev->phy_mutex);
-}
-
-static int smsc95xx_wait_eeprom(struct usbnet *dev)
-{
- unsigned long start_time = jiffies;
- u32 val;
-
- do {
- smsc95xx_read_reg(dev, E2P_CMD, &val);
- if (!(val & E2P_CMD_BUSY_) || (val & E2P_CMD_TIMEOUT_))
- break;
- udelay(40);
- } while (!time_after(jiffies, start_time + HZ));
-
- if (val & (E2P_CMD_TIMEOUT_ | E2P_CMD_BUSY_)) {
- netdev_warn(dev->net, "EEPROM read operation timeout\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static int smsc95xx_eeprom_confirm_not_busy(struct usbnet *dev)
-{
- unsigned long start_time = jiffies;
- u32 val;
-
- do {
- smsc95xx_read_reg(dev, E2P_CMD, &val);
-
- if (!(val & E2P_CMD_BUSY_))
- return 0;
-
- udelay(40);
- } while (!time_after(jiffies, start_time + HZ));
-
- netdev_warn(dev->net, "EEPROM is busy\n");
- return -EIO;
-}
-
-static int smsc95xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length,
- u8 *data)
-{
- u32 val;
- int i, ret;
-
- BUG_ON(!dev);
- BUG_ON(!data);
-
- ret = smsc95xx_eeprom_confirm_not_busy(dev);
- if (ret)
- return ret;
-
- for (i = 0; i < length; i++) {
- val = E2P_CMD_BUSY_ | E2P_CMD_READ_ | (offset & E2P_CMD_ADDR_);
- smsc95xx_write_reg(dev, E2P_CMD, val);
-
- ret = smsc95xx_wait_eeprom(dev);
- if (ret < 0)
- return ret;
-
- smsc95xx_read_reg(dev, E2P_DATA, &val);
-
- data[i] = val & 0xFF;
- offset++;
- }
-
- return 0;
-}
-
-static int smsc95xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length,
- u8 *data)
-{
- u32 val;
- int i, ret;
-
- BUG_ON(!dev);
- BUG_ON(!data);
-
- ret = smsc95xx_eeprom_confirm_not_busy(dev);
- if (ret)
- return ret;
-
- /* Issue write/erase enable command */
- val = E2P_CMD_BUSY_ | E2P_CMD_EWEN_;
- smsc95xx_write_reg(dev, E2P_CMD, val);
-
- ret = smsc95xx_wait_eeprom(dev);
- if (ret < 0)
- return ret;
-
- for (i = 0; i < length; i++) {
-
- /* Fill data register */
- val = data[i];
- smsc95xx_write_reg(dev, E2P_DATA, val);
-
- /* Send "write" command */
- val = E2P_CMD_BUSY_ | E2P_CMD_WRITE_ | (offset & E2P_CMD_ADDR_);
- smsc95xx_write_reg(dev, E2P_CMD, val);
-
- ret = smsc95xx_wait_eeprom(dev);
- if (ret < 0)
- return ret;
-
- offset++;
- }
-
- return 0;
-}
-
-static void smsc95xx_async_cmd_callback(struct urb *urb)
-{
- struct usb_context *usb_context = urb->context;
- struct usbnet *dev = usb_context->dev;
- int status = urb->status;
-
- if (status < 0)
- netdev_warn(dev->net, "async callback failed with %d\n", status);
-
- kfree(usb_context);
- usb_free_urb(urb);
-}
-
-static int smsc95xx_write_reg_async(struct usbnet *dev, u16 index, u32 *data)
-{
- struct usb_context *usb_context;
- int status;
- struct urb *urb;
- const u16 size = 4;
-
- urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!urb) {
- netdev_warn(dev->net, "Error allocating URB\n");
- return -ENOMEM;
- }
-
- usb_context = kmalloc(sizeof(struct usb_context), GFP_ATOMIC);
- if (usb_context == NULL) {
- netdev_warn(dev->net, "Error allocating control msg\n");
- usb_free_urb(urb);
- return -ENOMEM;
- }
-
- usb_context->req.bRequestType =
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
- usb_context->req.bRequest = USB_VENDOR_REQUEST_WRITE_REGISTER;
- usb_context->req.wValue = 00;
- usb_context->req.wIndex = cpu_to_le16(index);
- usb_context->req.wLength = cpu_to_le16(size);
-
- usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0),
- (void *)&usb_context->req, data, size,
- smsc95xx_async_cmd_callback,
- (void *)usb_context);
-
- status = usb_submit_urb(urb, GFP_ATOMIC);
- if (status < 0) {
- netdev_warn(dev->net, "Error submitting control msg, sts=%d\n",
- status);
- kfree(usb_context);
- usb_free_urb(urb);
- }
-
- return status;
-}
-
-/* returns hash bit number for given MAC address
- * example:
- * 01 00 5E 00 00 01 -> returns bit number 31 */
-static unsigned int smsc95xx_hash(char addr[ETH_ALEN])
-{
- return (ether_crc(ETH_ALEN, addr) >> 26) & 0x3f;
-}
-
-static void smsc95xx_set_multicast(struct net_device *netdev)
-{
- struct usbnet *dev = netdev_priv(netdev);
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
- unsigned long flags;
-
- pdata->hash_hi = 0;
- pdata->hash_lo = 0;
-
- spin_lock_irqsave(&pdata->mac_cr_lock, flags);
-
- if (dev->net->flags & IFF_PROMISC) {
- netif_dbg(dev, drv, dev->net, "promiscuous mode enabled\n");
- pdata->mac_cr |= MAC_CR_PRMS_;
- pdata->mac_cr &= ~(MAC_CR_MCPAS_ | MAC_CR_HPFILT_);
- } else if (dev->net->flags & IFF_ALLMULTI) {
- netif_dbg(dev, drv, dev->net, "receive all multicast enabled\n");
- pdata->mac_cr |= MAC_CR_MCPAS_;
- pdata->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_HPFILT_);
- } else if (!netdev_mc_empty(dev->net)) {
- struct netdev_hw_addr *ha;
-
- pdata->mac_cr |= MAC_CR_HPFILT_;
- pdata->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_);
-
- netdev_for_each_mc_addr(ha, netdev) {
- u32 bitnum = smsc95xx_hash(ha->addr);
- u32 mask = 0x01 << (bitnum & 0x1F);
- if (bitnum & 0x20)
- pdata->hash_hi |= mask;
- else
- pdata->hash_lo |= mask;
- }
-
- netif_dbg(dev, drv, dev->net, "HASHH=0x%08X, HASHL=0x%08X\n",
- pdata->hash_hi, pdata->hash_lo);
- } else {
- netif_dbg(dev, drv, dev->net, "receive own packets only\n");
- pdata->mac_cr &=
- ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_);
- }
-
- spin_unlock_irqrestore(&pdata->mac_cr_lock, flags);
-
- /* Initiate async writes, as we can't wait for completion here */
- smsc95xx_write_reg_async(dev, HASHH, &pdata->hash_hi);
- smsc95xx_write_reg_async(dev, HASHL, &pdata->hash_lo);
- smsc95xx_write_reg_async(dev, MAC_CR, &pdata->mac_cr);
-}
-
-static void smsc95xx_phy_update_flowcontrol(struct usbnet *dev, u8 duplex,
- u16 lcladv, u16 rmtadv)
-{
- u32 flow, afc_cfg = 0;
-
- int ret = smsc95xx_read_reg(dev, AFC_CFG, &afc_cfg);
- if (ret < 0) {
- netdev_warn(dev->net, "error reading AFC_CFG\n");
- return;
- }
-
- if (duplex == DUPLEX_FULL) {
- u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv);
-
- if (cap & FLOW_CTRL_RX)
- flow = 0xFFFF0002;
- else
- flow = 0;
-
- if (cap & FLOW_CTRL_TX)
- afc_cfg |= 0xF;
- else
- afc_cfg &= ~0xF;
-
- netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s\n",
- cap & FLOW_CTRL_RX ? "enabled" : "disabled",
- cap & FLOW_CTRL_TX ? "enabled" : "disabled");
- } else {
- netif_dbg(dev, link, dev->net, "half duplex\n");
- flow = 0;
- afc_cfg |= 0xF;
- }
-
- smsc95xx_write_reg(dev, FLOW, flow);
- smsc95xx_write_reg(dev, AFC_CFG, afc_cfg);
-}
-
-static int smsc95xx_link_reset(struct usbnet *dev)
-{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
- struct mii_if_info *mii = &dev->mii;
- struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
- unsigned long flags;
- u16 lcladv, rmtadv;
- u32 intdata;
-
- /* clear interrupt status */
- smsc95xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);
- intdata = 0xFFFFFFFF;
- smsc95xx_write_reg(dev, INT_STS, intdata);
-
- mii_check_media(mii, 1, 1);
- mii_ethtool_gset(&dev->mii, &ecmd);
- lcladv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
- rmtadv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
-
- netif_dbg(dev, link, dev->net,
- "speed: %u duplex: %d lcladv: %04x rmtadv: %04x\n",
- ethtool_cmd_speed(&ecmd), ecmd.duplex, lcladv, rmtadv);
-
- spin_lock_irqsave(&pdata->mac_cr_lock, flags);
- if (ecmd.duplex != DUPLEX_FULL) {
- pdata->mac_cr &= ~MAC_CR_FDPX_;
- pdata->mac_cr |= MAC_CR_RCVOWN_;
- } else {
- pdata->mac_cr &= ~MAC_CR_RCVOWN_;
- pdata->mac_cr |= MAC_CR_FDPX_;
- }
- spin_unlock_irqrestore(&pdata->mac_cr_lock, flags);
-
- smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr);
-
- smsc95xx_phy_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv);
-
- return 0;
-}
-
-static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
-{
- u32 intdata;
-
- if (urb->actual_length != 4) {
- netdev_warn(dev->net, "unexpected urb length %d\n",
- urb->actual_length);
- return;
- }
-
- memcpy(&intdata, urb->transfer_buffer, 4);
- le32_to_cpus(&intdata);
-
- netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata);
-
- if (intdata & INT_ENP_PHY_INT_)
- usbnet_defer_kevent(dev, EVENT_LINK_RESET);
- else
- netdev_warn(dev->net, "unexpected interrupt, intdata=0x%08X\n",
- intdata);
-}
-
-/* Enable or disable Tx & Rx checksum offload engines */
-static int smsc95xx_set_features(struct net_device *netdev,
- netdev_features_t features)
-{
- struct usbnet *dev = netdev_priv(netdev);
- u32 read_buf;
- int ret;
-
- ret = smsc95xx_read_reg(dev, COE_CR, &read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to read COE_CR: %d\n", ret);
- return ret;
- }
-
- if (features & NETIF_F_HW_CSUM)
- read_buf |= Tx_COE_EN_;
- else
- read_buf &= ~Tx_COE_EN_;
-
- if (features & NETIF_F_RXCSUM)
- read_buf |= Rx_COE_EN_;
- else
- read_buf &= ~Rx_COE_EN_;
-
- ret = smsc95xx_write_reg(dev, COE_CR, read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to write COE_CR: %d\n", ret);
- return ret;
- }
-
- netif_dbg(dev, hw, dev->net, "COE_CR = 0x%08x\n", read_buf);
- return 0;
-}
-
-static int smsc95xx_ethtool_get_eeprom_len(struct net_device *net)
-{
- return MAX_EEPROM_SIZE;
-}
-
-static int smsc95xx_ethtool_get_eeprom(struct net_device *netdev,
- struct ethtool_eeprom *ee, u8 *data)
-{
- struct usbnet *dev = netdev_priv(netdev);
-
- ee->magic = LAN95XX_EEPROM_MAGIC;
-
- return smsc95xx_read_eeprom(dev, ee->offset, ee->len, data);
-}
-
-static int smsc95xx_ethtool_set_eeprom(struct net_device *netdev,
- struct ethtool_eeprom *ee, u8 *data)
-{
- struct usbnet *dev = netdev_priv(netdev);
-
- if (ee->magic != LAN95XX_EEPROM_MAGIC) {
- netdev_warn(dev->net, "EEPROM: magic value mismatch, magic = 0x%x\n",
- ee->magic);
- return -EINVAL;
- }
-
- return smsc95xx_write_eeprom(dev, ee->offset, ee->len, data);
-}
-
-static const struct ethtool_ops smsc95xx_ethtool_ops = {
- .get_link = usbnet_get_link,
- .nway_reset = usbnet_nway_reset,
- .get_drvinfo = usbnet_get_drvinfo,
- .get_msglevel = usbnet_get_msglevel,
- .set_msglevel = usbnet_set_msglevel,
- .get_settings = usbnet_get_settings,
- .set_settings = usbnet_set_settings,
- .get_eeprom_len = smsc95xx_ethtool_get_eeprom_len,
- .get_eeprom = smsc95xx_ethtool_get_eeprom,
- .set_eeprom = smsc95xx_ethtool_set_eeprom,
-};
-
-static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
-{
- struct usbnet *dev = netdev_priv(netdev);
-
- if (!netif_running(netdev))
- return -EINVAL;
-
- return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
-}
-
-static void smsc95xx_init_mac_address(struct usbnet *dev)
-{
- /* try reading mac address from EEPROM */
- if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
- dev->net->dev_addr) == 0) {
- if (is_valid_ether_addr(dev->net->dev_addr)) {
- /* eeprom values are valid so use them */
- netif_dbg(dev, ifup, dev->net, "MAC address read from EEPROM\n");
- return;
- }
- }
-
- /* no eeprom, or eeprom values are invalid. generate random MAC */
- eth_hw_addr_random(dev->net);
- netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr\n");
-}
-
-static int smsc95xx_set_mac_address(struct usbnet *dev)
-{
- u32 addr_lo = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 |
- dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24;
- u32 addr_hi = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8;
- int ret;
-
- ret = smsc95xx_write_reg(dev, ADDRL, addr_lo);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to write ADDRL: %d\n", ret);
- return ret;
- }
-
- ret = smsc95xx_write_reg(dev, ADDRH, addr_hi);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to write ADDRH: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-/* starts the TX path */
-static void smsc95xx_start_tx_path(struct usbnet *dev)
-{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
- unsigned long flags;
- u32 reg_val;
-
- /* Enable Tx at MAC */
- spin_lock_irqsave(&pdata->mac_cr_lock, flags);
- pdata->mac_cr |= MAC_CR_TXEN_;
- spin_unlock_irqrestore(&pdata->mac_cr_lock, flags);
-
- smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr);
-
- /* Enable Tx at SCSRs */
- reg_val = TX_CFG_ON_;
- smsc95xx_write_reg(dev, TX_CFG, reg_val);
-}
-
-/* Starts the Receive path */
-static void smsc95xx_start_rx_path(struct usbnet *dev)
-{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
- unsigned long flags;
-
- spin_lock_irqsave(&pdata->mac_cr_lock, flags);
- pdata->mac_cr |= MAC_CR_RXEN_;
- spin_unlock_irqrestore(&pdata->mac_cr_lock, flags);
-
- smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr);
-}
-
-static int smsc95xx_phy_initialize(struct usbnet *dev)
-{
- int bmcr, timeout = 0;
-
- /* Initialize MII structure */
- dev->mii.dev = dev->net;
- dev->mii.mdio_read = smsc95xx_mdio_read;
- dev->mii.mdio_write = smsc95xx_mdio_write;
- dev->mii.phy_id_mask = 0x1f;
- dev->mii.reg_num_mask = 0x1f;
- dev->mii.phy_id = SMSC95XX_INTERNAL_PHY_ID;
-
- /* reset phy and wait for reset to complete */
- smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
-
- do {
- msleep(10);
- bmcr = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
- timeout++;
- } while ((bmcr & BMCR_RESET) && (timeout < 100));
-
- if (timeout >= 100) {
- netdev_warn(dev->net, "timeout on PHY Reset");
- return -EIO;
- }
-
- smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
- ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
- ADVERTISE_PAUSE_ASYM);
-
- /* read to clear */
- smsc95xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
-
- smsc95xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,
- PHY_INT_MASK_DEFAULT_);
- mii_nway_restart(&dev->mii);
-
- netif_dbg(dev, ifup, dev->net, "phy initialised successfully\n");
- return 0;
-}
-
-static int smsc95xx_reset(struct usbnet *dev)
-{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
- u32 read_buf, write_buf, burst_cap;
- int ret = 0, timeout;
-
- netif_dbg(dev, ifup, dev->net, "entering smsc95xx_reset\n");
-
- write_buf = HW_CFG_LRST_;
- ret = smsc95xx_write_reg(dev, HW_CFG, write_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to write HW_CFG_LRST_ bit in HW_CFG register, ret = %d\n",
- ret);
- return ret;
- }
-
- timeout = 0;
- do {
- ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
- return ret;
- }
- msleep(10);
- timeout++;
- } while ((read_buf & HW_CFG_LRST_) && (timeout < 100));
-
- if (timeout >= 100) {
- netdev_warn(dev->net, "timeout waiting for completion of Lite Reset\n");
- return ret;
- }
-
- write_buf = PM_CTL_PHY_RST_;
- ret = smsc95xx_write_reg(dev, PM_CTRL, write_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to write PM_CTRL: %d\n", ret);
- return ret;
- }
-
- timeout = 0;
- do {
- ret = smsc95xx_read_reg(dev, PM_CTRL, &read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to read PM_CTRL: %d\n", ret);
- return ret;
- }
- msleep(10);
- timeout++;
- } while ((read_buf & PM_CTL_PHY_RST_) && (timeout < 100));
-
- if (timeout >= 100) {
- netdev_warn(dev->net, "timeout waiting for PHY Reset\n");
- return ret;
- }
-
- ret = smsc95xx_set_mac_address(dev);
- if (ret < 0)
- return ret;
-
- netif_dbg(dev, ifup, dev->net,
- "MAC Address: %pM\n", dev->net->dev_addr);
-
- ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
- return ret;
- }
-
- netif_dbg(dev, ifup, dev->net,
- "Read Value from HW_CFG : 0x%08x\n", read_buf);
-
- read_buf |= HW_CFG_BIR_;
-
- ret = smsc95xx_write_reg(dev, HW_CFG, read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to write HW_CFG_BIR_ bit in HW_CFG register, ret = %d\n",
- ret);
- return ret;
- }
-
- ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
- return ret;
- }
- netif_dbg(dev, ifup, dev->net,
- "Read Value from HW_CFG after writing HW_CFG_BIR_: 0x%08x\n",
- read_buf);
-
- if (!turbo_mode) {
- burst_cap = 0;
- dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE;
- } else if (dev->udev->speed == USB_SPEED_HIGH) {
- burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
- dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE;
- } else {
- burst_cap = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE;
- dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE;
- }
-
- netif_dbg(dev, ifup, dev->net,
- "rx_urb_size=%ld\n", (ulong)dev->rx_urb_size);
-
- ret = smsc95xx_write_reg(dev, BURST_CAP, burst_cap);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to write BURST_CAP: %d\n", ret);
- return ret;
- }
-
- ret = smsc95xx_read_reg(dev, BURST_CAP, &read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to read BURST_CAP: %d\n", ret);
- return ret;
- }
- netif_dbg(dev, ifup, dev->net,
- "Read Value from BURST_CAP after writing: 0x%08x\n",
- read_buf);
-
- read_buf = DEFAULT_BULK_IN_DELAY;
- ret = smsc95xx_write_reg(dev, BULK_IN_DLY, read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "ret = %d\n", ret);
- return ret;
- }
-
- ret = smsc95xx_read_reg(dev, BULK_IN_DLY, &read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to read BULK_IN_DLY: %d\n", ret);
- return ret;
- }
- netif_dbg(dev, ifup, dev->net,
- "Read Value from BULK_IN_DLY after writing: 0x%08x\n",
- read_buf);
-
- ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
- return ret;
- }
- netif_dbg(dev, ifup, dev->net,
- "Read Value from HW_CFG: 0x%08x\n", read_buf);
-
- if (turbo_mode)
- read_buf |= (HW_CFG_MEF_ | HW_CFG_BCE_);
-
- read_buf &= ~HW_CFG_RXDOFF_;
-
- /* set Rx data offset=2, Make IP header aligns on word boundary. */
- read_buf |= NET_IP_ALIGN << 9;
-
- ret = smsc95xx_write_reg(dev, HW_CFG, read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to write HW_CFG register, ret=%d\n",
- ret);
- return ret;
- }
-
- ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
- return ret;
- }
- netif_dbg(dev, ifup, dev->net,
- "Read Value from HW_CFG after writing: 0x%08x\n", read_buf);
-
- write_buf = 0xFFFFFFFF;
- ret = smsc95xx_write_reg(dev, INT_STS, write_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to write INT_STS register, ret=%d\n",
- ret);
- return ret;
- }
-
- ret = smsc95xx_read_reg(dev, ID_REV, &read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to read ID_REV: %d\n", ret);
- return ret;
- }
- netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x\n", read_buf);
-
- /* Configure GPIO pins as LED outputs */
- write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED |
- LED_GPIO_CFG_FDX_LED;
- ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to write LED_GPIO_CFG register, ret=%d\n",
- ret);
- return ret;
- }
-
- /* Init Tx */
- write_buf = 0;
- ret = smsc95xx_write_reg(dev, FLOW, write_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to write FLOW: %d\n", ret);
- return ret;
- }
-
- read_buf = AFC_CFG_DEFAULT;
- ret = smsc95xx_write_reg(dev, AFC_CFG, read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to write AFC_CFG: %d\n", ret);
- return ret;
- }
-
- /* Don't need mac_cr_lock during initialisation */
- ret = smsc95xx_read_reg(dev, MAC_CR, &pdata->mac_cr);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to read MAC_CR: %d\n", ret);
- return ret;
- }
-
- /* Init Rx */
- /* Set Vlan */
- write_buf = (u32)ETH_P_8021Q;
- ret = smsc95xx_write_reg(dev, VLAN1, write_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to write VAN1: %d\n", ret);
- return ret;
- }
-
- /* Enable or disable checksum offload engines */
- smsc95xx_set_features(dev->net, dev->net->features);
-
- smsc95xx_set_multicast(dev->net);
-
- if (smsc95xx_phy_initialize(dev) < 0)
- return -EIO;
-
- ret = smsc95xx_read_reg(dev, INT_EP_CTL, &read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to read INT_EP_CTL: %d\n", ret);
- return ret;
- }
-
- /* enable PHY interrupts */
- read_buf |= INT_EP_CTL_PHY_INT_;
-
- ret = smsc95xx_write_reg(dev, INT_EP_CTL, read_buf);
- if (ret < 0) {
- netdev_warn(dev->net, "Failed to write INT_EP_CTL: %d\n", ret);
- return ret;
- }
-
- smsc95xx_start_tx_path(dev);
- smsc95xx_start_rx_path(dev);
-
- netif_dbg(dev, ifup, dev->net, "smsc95xx_reset, return 0\n");
- return 0;
-}
-
-static const struct net_device_ops smsc95xx_netdev_ops = {
- .ndo_open = usbnet_open,
- .ndo_stop = usbnet_stop,
- .ndo_start_xmit = usbnet_start_xmit,
- .ndo_tx_timeout = usbnet_tx_timeout,
- .ndo_change_mtu = usbnet_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_do_ioctl = smsc95xx_ioctl,
- .ndo_set_rx_mode = smsc95xx_set_multicast,
- .ndo_set_features = smsc95xx_set_features,
-};
-
-static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- struct smsc95xx_priv *pdata = NULL;
- int ret;
-
- printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n");
-
- ret = usbnet_get_endpoints(dev, intf);
- if (ret < 0) {
- netdev_warn(dev->net, "usbnet_get_endpoints failed: %d\n", ret);
- return ret;
- }
-
- dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc95xx_priv),
- GFP_KERNEL);
-
- pdata = (struct smsc95xx_priv *)(dev->data[0]);
- if (!pdata) {
- netdev_warn(dev->net, "Unable to allocate struct smsc95xx_priv\n");
- return -ENOMEM;
- }
-
- spin_lock_init(&pdata->mac_cr_lock);
-
- if (DEFAULT_TX_CSUM_ENABLE)
- dev->net->features |= NETIF_F_HW_CSUM;
- if (DEFAULT_RX_CSUM_ENABLE)
- dev->net->features |= NETIF_F_RXCSUM;
-
- dev->net->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
-
- smsc95xx_init_mac_address(dev);
-
- /* Init all registers */
- ret = smsc95xx_reset(dev);
-
- dev->net->netdev_ops = &smsc95xx_netdev_ops;
- dev->net->ethtool_ops = &smsc95xx_ethtool_ops;
- dev->net->flags |= IFF_MULTICAST;
- dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM;
- dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
- return 0;
-}
-
-static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf)
-{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
- if (pdata) {
- netif_dbg(dev, ifdown, dev->net, "free pdata\n");
- kfree(pdata);
- pdata = NULL;
- dev->data[0] = 0;
- }
-}
-
-static void smsc95xx_rx_csum_offload(struct sk_buff *skb)
-{
- skb->csum = *(u16 *)(skb_tail_pointer(skb) - 2);
- skb->ip_summed = CHECKSUM_COMPLETE;
- skb_trim(skb, skb->len - 2);
-}
-
-static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- while (skb->len > 0) {
- u32 header, align_count;
- struct sk_buff *ax_skb;
- unsigned char *packet;
- u16 size;
-
- memcpy(&header, skb->data, sizeof(header));
- le32_to_cpus(&header);
- skb_pull(skb, 4 + NET_IP_ALIGN);
- packet = skb->data;
-
- /* get the packet length */
- size = (u16)((header & RX_STS_FL_) >> 16);
- align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4;
-
- if (unlikely(header & RX_STS_ES_)) {
- netif_dbg(dev, rx_err, dev->net,
- "Error header=0x%08x\n", header);
- dev->net->stats.rx_errors++;
- dev->net->stats.rx_dropped++;
-
- if (header & RX_STS_CRC_) {
- dev->net->stats.rx_crc_errors++;
- } else {
- if (header & (RX_STS_TL_ | RX_STS_RF_))
- dev->net->stats.rx_frame_errors++;
-
- if ((header & RX_STS_LE_) &&
- (!(header & RX_STS_FT_)))
- dev->net->stats.rx_length_errors++;
- }
- } else {
- /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */
- if (unlikely(size > (ETH_FRAME_LEN + 12))) {
- netif_dbg(dev, rx_err, dev->net,
- "size err header=0x%08x\n", header);
- return 0;
- }
-
- /* last frame in this batch */
- if (skb->len == size) {
- if (dev->net->features & NETIF_F_RXCSUM)
- smsc95xx_rx_csum_offload(skb);
- skb_trim(skb, skb->len - 4); /* remove fcs */
- skb->truesize = size + sizeof(struct sk_buff);
-
- return 1;
- }
-
- ax_skb = skb_clone(skb, GFP_ATOMIC);
- if (unlikely(!ax_skb)) {
- netdev_warn(dev->net, "Error allocating skb\n");
- return 0;
- }
-
- ax_skb->len = size;
- ax_skb->data = packet;
- skb_set_tail_pointer(ax_skb, size);
-
- if (dev->net->features & NETIF_F_RXCSUM)
- smsc95xx_rx_csum_offload(ax_skb);
- skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
- ax_skb->truesize = size + sizeof(struct sk_buff);
-
- usbnet_skb_return(dev, ax_skb);
- }
-
- skb_pull(skb, size);
-
- /* padding bytes before the next frame starts */
- if (skb->len)
- skb_pull(skb, align_count);
- }
-
- if (unlikely(skb->len < 0)) {
- netdev_warn(dev->net, "invalid rx length<0 %d\n", skb->len);
- return 0;
- }
-
- return 1;
-}
-
-static u32 smsc95xx_calc_csum_preamble(struct sk_buff *skb)
-{
- u16 low_16 = (u16)skb_checksum_start_offset(skb);
- u16 high_16 = low_16 + skb->csum_offset;
- return (high_16 << 16) | low_16;
-}
-
-static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
- struct sk_buff *skb, gfp_t flags)
-{
- bool csum = skb->ip_summed == CHECKSUM_PARTIAL;
- int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD;
- u32 tx_cmd_a, tx_cmd_b;
-
- /* We do not advertise SG, so skbs should be already linearized */
- BUG_ON(skb_shinfo(skb)->nr_frags);
-
- if (skb_headroom(skb) < overhead) {
- struct sk_buff *skb2 = skb_copy_expand(skb,
- overhead, 0, flags);
- dev_kfree_skb_any(skb);
- skb = skb2;
- if (!skb)
- return NULL;
- }
-
- if (csum) {
- if (skb->len <= 45) {
- /* workaround - hardware tx checksum does not work
- * properly with extremely small packets */
- long csstart = skb_checksum_start_offset(skb);
- __wsum calc = csum_partial(skb->data + csstart,
- skb->len - csstart, 0);
- *((__sum16 *)(skb->data + csstart
- + skb->csum_offset)) = csum_fold(calc);
-
- csum = false;
- } else {
- u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
- skb_push(skb, 4);
- memcpy(skb->data, &csum_preamble, 4);
- }
- }
-
- skb_push(skb, 4);
- tx_cmd_b = (u32)(skb->len - 4);
- if (csum)
- tx_cmd_b |= TX_CMD_B_CSUM_ENABLE;
- cpu_to_le32s(&tx_cmd_b);
- memcpy(skb->data, &tx_cmd_b, 4);
-
- skb_push(skb, 4);
- tx_cmd_a = (u32)(skb->len - 8) | TX_CMD_A_FIRST_SEG_ |
- TX_CMD_A_LAST_SEG_;
- cpu_to_le32s(&tx_cmd_a);
- memcpy(skb->data, &tx_cmd_a, 4);
-
- return skb;
-}
-
-static const struct driver_info smsc95xx_info = {
- .description = "smsc95xx USB 2.0 Ethernet",
- .bind = smsc95xx_bind,
- .unbind = smsc95xx_unbind,
- .link_reset = smsc95xx_link_reset,
- .reset = smsc95xx_reset,
- .rx_fixup = smsc95xx_rx_fixup,
- .tx_fixup = smsc95xx_tx_fixup,
- .status = smsc95xx_status,
- .flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,
-};
-
-static const struct usb_device_id products[] = {
- {
- /* SMSC9500 USB Ethernet Device */
- USB_DEVICE(0x0424, 0x9500),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC9505 USB Ethernet Device */
- USB_DEVICE(0x0424, 0x9505),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC9500A USB Ethernet Device */
- USB_DEVICE(0x0424, 0x9E00),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC9505A USB Ethernet Device */
- USB_DEVICE(0x0424, 0x9E01),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC9512/9514 USB Hub & Ethernet Device */
- USB_DEVICE(0x0424, 0xec00),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC9500 USB Ethernet Device (SAL10) */
- USB_DEVICE(0x0424, 0x9900),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC9505 USB Ethernet Device (SAL10) */
- USB_DEVICE(0x0424, 0x9901),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC9500A USB Ethernet Device (SAL10) */
- USB_DEVICE(0x0424, 0x9902),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC9505A USB Ethernet Device (SAL10) */
- USB_DEVICE(0x0424, 0x9903),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC9512/9514 USB Hub & Ethernet Device (SAL10) */
- USB_DEVICE(0x0424, 0x9904),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC9500A USB Ethernet Device (HAL) */
- USB_DEVICE(0x0424, 0x9905),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC9505A USB Ethernet Device (HAL) */
- USB_DEVICE(0x0424, 0x9906),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC9500 USB Ethernet Device (Alternate ID) */
- USB_DEVICE(0x0424, 0x9907),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC9500A USB Ethernet Device (Alternate ID) */
- USB_DEVICE(0x0424, 0x9908),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC9512/9514 USB Hub & Ethernet Device (Alternate ID) */
- USB_DEVICE(0x0424, 0x9909),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC LAN9530 USB Ethernet Device */
- USB_DEVICE(0x0424, 0x9530),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC LAN9730 USB Ethernet Device */
- USB_DEVICE(0x0424, 0x9730),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- {
- /* SMSC LAN89530 USB Ethernet Device */
- USB_DEVICE(0x0424, 0x9E08),
- .driver_info = (unsigned long) &smsc95xx_info,
- },
- { }, /* END */
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver smsc95xx_driver = {
- .name = "smsc95xx",
- .id_table = products,
- .probe = usbnet_probe,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
- .disconnect = usbnet_disconnect,
-};
-
-module_usb_driver(smsc95xx_driver);
-
-MODULE_AUTHOR("Nancy Lin");
-MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>");
-MODULE_DESCRIPTION("SMSC95XX USB 2.0 Ethernet Devices");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/smsc95xx.h b/ANDROID_3.4.5/drivers/net/usb/smsc95xx.h
deleted file mode 100644
index 86bc4497..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/smsc95xx.h
+++ /dev/null
@@ -1,256 +0,0 @@
- /***************************************************************************
- *
- * Copyright (C) 2007-2008 SMSC
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *****************************************************************************/
-
-#ifndef _SMSC95XX_H
-#define _SMSC95XX_H
-
-/* Tx command words */
-#define TX_CMD_A_DATA_OFFSET_ (0x001F0000)
-#define TX_CMD_A_FIRST_SEG_ (0x00002000)
-#define TX_CMD_A_LAST_SEG_ (0x00001000)
-#define TX_CMD_A_BUF_SIZE_ (0x000007FF)
-
-#define TX_CMD_B_CSUM_ENABLE (0x00004000)
-#define TX_CMD_B_ADD_CRC_DISABLE_ (0x00002000)
-#define TX_CMD_B_DISABLE_PADDING_ (0x00001000)
-#define TX_CMD_B_PKT_BYTE_LENGTH_ (0x000007FF)
-
-/* Rx status word */
-#define RX_STS_FF_ (0x40000000) /* Filter Fail */
-#define RX_STS_FL_ (0x3FFF0000) /* Frame Length */
-#define RX_STS_ES_ (0x00008000) /* Error Summary */
-#define RX_STS_BF_ (0x00002000) /* Broadcast Frame */
-#define RX_STS_LE_ (0x00001000) /* Length Error */
-#define RX_STS_RF_ (0x00000800) /* Runt Frame */
-#define RX_STS_MF_ (0x00000400) /* Multicast Frame */
-#define RX_STS_TL_ (0x00000080) /* Frame too long */
-#define RX_STS_CS_ (0x00000040) /* Collision Seen */
-#define RX_STS_FT_ (0x00000020) /* Frame Type */
-#define RX_STS_RW_ (0x00000010) /* Receive Watchdog */
-#define RX_STS_ME_ (0x00000008) /* Mii Error */
-#define RX_STS_DB_ (0x00000004) /* Dribbling */
-#define RX_STS_CRC_ (0x00000002) /* CRC Error */
-
-/* SCSRs */
-#define ID_REV (0x00)
-#define ID_REV_CHIP_ID_MASK_ (0xFFFF0000)
-#define ID_REV_CHIP_REV_MASK_ (0x0000FFFF)
-#define ID_REV_CHIP_ID_9500_ (0x9500)
-
-#define INT_STS (0x08)
-#define INT_STS_TX_STOP_ (0x00020000)
-#define INT_STS_RX_STOP_ (0x00010000)
-#define INT_STS_PHY_INT_ (0x00008000)
-#define INT_STS_TXE_ (0x00004000)
-#define INT_STS_TDFU_ (0x00002000)
-#define INT_STS_TDFO_ (0x00001000)
-#define INT_STS_RXDF_ (0x00000800)
-#define INT_STS_GPIOS_ (0x000007FF)
-
-#define RX_CFG (0x0C)
-#define RX_FIFO_FLUSH_ (0x00000001)
-
-#define TX_CFG (0x10)
-#define TX_CFG_ON_ (0x00000004)
-#define TX_CFG_STOP_ (0x00000002)
-#define TX_CFG_FIFO_FLUSH_ (0x00000001)
-
-#define HW_CFG (0x14)
-#define HW_CFG_BIR_ (0x00001000)
-#define HW_CFG_LEDB_ (0x00000800)
-#define HW_CFG_RXDOFF_ (0x00000600)
-#define HW_CFG_DRP_ (0x00000040)
-#define HW_CFG_MEF_ (0x00000020)
-#define HW_CFG_LRST_ (0x00000008)
-#define HW_CFG_PSEL_ (0x00000004)
-#define HW_CFG_BCE_ (0x00000002)
-#define HW_CFG_SRST_ (0x00000001)
-
-#define PM_CTRL (0x20)
-#define PM_CTL_DEV_RDY_ (0x00000080)
-#define PM_CTL_SUS_MODE_ (0x00000060)
-#define PM_CTL_SUS_MODE_0 (0x00000000)
-#define PM_CTL_SUS_MODE_1 (0x00000020)
-#define PM_CTL_SUS_MODE_2 (0x00000060)
-#define PM_CTL_PHY_RST_ (0x00000010)
-#define PM_CTL_WOL_EN_ (0x00000008)
-#define PM_CTL_ED_EN_ (0x00000004)
-#define PM_CTL_WUPS_ (0x00000003)
-#define PM_CTL_WUPS_NO_ (0x00000000)
-#define PM_CTL_WUPS_ED_ (0x00000001)
-#define PM_CTL_WUPS_WOL_ (0x00000002)
-#define PM_CTL_WUPS_MULTI_ (0x00000003)
-
-#define LED_GPIO_CFG (0x24)
-#define LED_GPIO_CFG_SPD_LED (0x01000000)
-#define LED_GPIO_CFG_LNK_LED (0x00100000)
-#define LED_GPIO_CFG_FDX_LED (0x00010000)
-
-#define GPIO_CFG (0x28)
-
-#define AFC_CFG (0x2C)
-
-/* Hi watermark = 15.5Kb (~10 mtu pkts) */
-/* low watermark = 3k (~2 mtu pkts) */
-/* backpressure duration = ~ 350us */
-/* Apply FC on any frame. */
-#define AFC_CFG_DEFAULT (0x00F830A1)
-
-#define E2P_CMD (0x30)
-#define E2P_CMD_BUSY_ (0x80000000)
-#define E2P_CMD_MASK_ (0x70000000)
-#define E2P_CMD_READ_ (0x00000000)
-#define E2P_CMD_EWDS_ (0x10000000)
-#define E2P_CMD_EWEN_ (0x20000000)
-#define E2P_CMD_WRITE_ (0x30000000)
-#define E2P_CMD_WRAL_ (0x40000000)
-#define E2P_CMD_ERASE_ (0x50000000)
-#define E2P_CMD_ERAL_ (0x60000000)
-#define E2P_CMD_RELOAD_ (0x70000000)
-#define E2P_CMD_TIMEOUT_ (0x00000400)
-#define E2P_CMD_LOADED_ (0x00000200)
-#define E2P_CMD_ADDR_ (0x000001FF)
-
-#define MAX_EEPROM_SIZE (512)
-
-#define E2P_DATA (0x34)
-#define E2P_DATA_MASK_ (0x000000FF)
-
-#define BURST_CAP (0x38)
-
-#define GPIO_WAKE (0x64)
-
-#define INT_EP_CTL (0x68)
-#define INT_EP_CTL_INTEP_ (0x80000000)
-#define INT_EP_CTL_MACRTO_ (0x00080000)
-#define INT_EP_CTL_TX_STOP_ (0x00020000)
-#define INT_EP_CTL_RX_STOP_ (0x00010000)
-#define INT_EP_CTL_PHY_INT_ (0x00008000)
-#define INT_EP_CTL_TXE_ (0x00004000)
-#define INT_EP_CTL_TDFU_ (0x00002000)
-#define INT_EP_CTL_TDFO_ (0x00001000)
-#define INT_EP_CTL_RXDF_ (0x00000800)
-#define INT_EP_CTL_GPIOS_ (0x000007FF)
-
-#define BULK_IN_DLY (0x6C)
-
-/* MAC CSRs */
-#define MAC_CR (0x100)
-#define MAC_CR_RXALL_ (0x80000000)
-#define MAC_CR_RCVOWN_ (0x00800000)
-#define MAC_CR_LOOPBK_ (0x00200000)
-#define MAC_CR_FDPX_ (0x00100000)
-#define MAC_CR_MCPAS_ (0x00080000)
-#define MAC_CR_PRMS_ (0x00040000)
-#define MAC_CR_INVFILT_ (0x00020000)
-#define MAC_CR_PASSBAD_ (0x00010000)
-#define MAC_CR_HFILT_ (0x00008000)
-#define MAC_CR_HPFILT_ (0x00002000)
-#define MAC_CR_LCOLL_ (0x00001000)
-#define MAC_CR_BCAST_ (0x00000800)
-#define MAC_CR_DISRTY_ (0x00000400)
-#define MAC_CR_PADSTR_ (0x00000100)
-#define MAC_CR_BOLMT_MASK (0x000000C0)
-#define MAC_CR_DFCHK_ (0x00000020)
-#define MAC_CR_TXEN_ (0x00000008)
-#define MAC_CR_RXEN_ (0x00000004)
-
-#define ADDRH (0x104)
-
-#define ADDRL (0x108)
-
-#define HASHH (0x10C)
-
-#define HASHL (0x110)
-
-#define MII_ADDR (0x114)
-#define MII_WRITE_ (0x02)
-#define MII_BUSY_ (0x01)
-#define MII_READ_ (0x00) /* ~of MII Write bit */
-
-#define MII_DATA (0x118)
-
-#define FLOW (0x11C)
-#define FLOW_FCPT_ (0xFFFF0000)
-#define FLOW_FCPASS_ (0x00000004)
-#define FLOW_FCEN_ (0x00000002)
-#define FLOW_FCBSY_ (0x00000001)
-
-#define VLAN1 (0x120)
-
-#define VLAN2 (0x124)
-
-#define WUFF (0x128)
-
-#define WUCSR (0x12C)
-
-#define COE_CR (0x130)
-#define Tx_COE_EN_ (0x00010000)
-#define Rx_COE_MODE_ (0x00000002)
-#define Rx_COE_EN_ (0x00000001)
-
-/* Vendor-specific PHY Definitions */
-
-/* Mode Control/Status Register */
-#define PHY_MODE_CTRL_STS (17)
-#define MODE_CTRL_STS_EDPWRDOWN_ ((u16)0x2000)
-#define MODE_CTRL_STS_ENERGYON_ ((u16)0x0002)
-
-#define SPECIAL_CTRL_STS (27)
-#define SPECIAL_CTRL_STS_OVRRD_AMDIX_ ((u16)0x8000)
-#define SPECIAL_CTRL_STS_AMDIX_ENABLE_ ((u16)0x4000)
-#define SPECIAL_CTRL_STS_AMDIX_STATE_ ((u16)0x2000)
-
-#define PHY_INT_SRC (29)
-#define PHY_INT_SRC_ENERGY_ON_ ((u16)0x0080)
-#define PHY_INT_SRC_ANEG_COMP_ ((u16)0x0040)
-#define PHY_INT_SRC_REMOTE_FAULT_ ((u16)0x0020)
-#define PHY_INT_SRC_LINK_DOWN_ ((u16)0x0010)
-
-#define PHY_INT_MASK (30)
-#define PHY_INT_MASK_ENERGY_ON_ ((u16)0x0080)
-#define PHY_INT_MASK_ANEG_COMP_ ((u16)0x0040)
-#define PHY_INT_MASK_REMOTE_FAULT_ ((u16)0x0020)
-#define PHY_INT_MASK_LINK_DOWN_ ((u16)0x0010)
-#define PHY_INT_MASK_DEFAULT_ (PHY_INT_MASK_ANEG_COMP_ | \
- PHY_INT_MASK_LINK_DOWN_)
-
-#define PHY_SPECIAL (31)
-#define PHY_SPECIAL_SPD_ ((u16)0x001C)
-#define PHY_SPECIAL_SPD_10HALF_ ((u16)0x0004)
-#define PHY_SPECIAL_SPD_10FULL_ ((u16)0x0014)
-#define PHY_SPECIAL_SPD_100HALF_ ((u16)0x0008)
-#define PHY_SPECIAL_SPD_100FULL_ ((u16)0x0018)
-
-/* USB Vendor Requests */
-#define USB_VENDOR_REQUEST_WRITE_REGISTER 0xA0
-#define USB_VENDOR_REQUEST_READ_REGISTER 0xA1
-#define USB_VENDOR_REQUEST_GET_STATS 0xA2
-
-/* Interrupt Endpoint status word bitfields */
-#define INT_ENP_TX_STOP_ ((u32)BIT(17))
-#define INT_ENP_RX_STOP_ ((u32)BIT(16))
-#define INT_ENP_PHY_INT_ ((u32)BIT(15))
-#define INT_ENP_TXE_ ((u32)BIT(14))
-#define INT_ENP_TDFU_ ((u32)BIT(13))
-#define INT_ENP_TDFO_ ((u32)BIT(12))
-#define INT_ENP_RXDF_ ((u32)BIT(11))
-
-#endif /* _SMSC95XX_H */
diff --git a/ANDROID_3.4.5/drivers/net/usb/usbnet.c b/ANDROID_3.4.5/drivers/net/usb/usbnet.c
deleted file mode 100644
index 20838aba..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/usbnet.c
+++ /dev/null
@@ -1,1668 +0,0 @@
-/*
- * USB Network driver infrastructure
- * Copyright (C) 2000-2005 by David Brownell
- * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * This is a generic "USB networking" framework that works with several
- * kinds of full and high speed networking devices: host-to-host cables,
- * smart usb peripherals, and actual Ethernet adapters.
- *
- * These devices usually differ in terms of control protocols (if they
- * even have one!) and sometimes they define new framing to wrap or batch
- * Ethernet packets. Otherwise, they talk to USB pretty much the same,
- * so interface (un)binding, endpoint I/O queues, fault handling, and other
- * issues can usefully be addressed by this framework.
- */
-
-// #define DEBUG // error path messages, extra info
-// #define VERBOSE // more; success messages
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ctype.h>
-#include <linux/ethtool.h>
-#include <linux/workqueue.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/usb/usbnet.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/pm_runtime.h>
-
-#define DRIVER_VERSION "22-Aug-2005"
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * Nineteen USB 1.1 max size bulk transactions per frame (ms), max.
- * Several dozen bytes of IPv4 data can fit in two such transactions.
- * One maximum size Ethernet packet takes twenty four of them.
- * For high speed, each frame comfortably fits almost 36 max size
- * Ethernet packets (so queues should be bigger).
- *
- * REVISIT qlens should be members of 'struct usbnet'; the goal is to
- * let the USB host controller be busy for 5msec or more before an irq
- * is required, under load. Jumbograms change the equation.
- */
-#define RX_MAX_QUEUE_MEMORY (60 * 1518)
-#define RX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? \
- (RX_MAX_QUEUE_MEMORY/(dev)->rx_urb_size) : 4)
-#define TX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? \
- (RX_MAX_QUEUE_MEMORY/(dev)->hard_mtu) : 4)
-
-// reawaken network queue this soon after stopping; else watchdog barks
-#define TX_TIMEOUT_JIFFIES (5*HZ)
-
-// throttle rx/tx briefly after some faults, so khubd might disconnect()
-// us (it polls at HZ/4 usually) before we report too many false errors.
-#define THROTTLE_JIFFIES (HZ/8)
-
-// between wakeups
-#define UNLINK_TIMEOUT_MS 3
-
-/*-------------------------------------------------------------------------*/
-
-// randomly generated ethernet address
-static u8 node_id [ETH_ALEN];
-
-static const char driver_name [] = "usbnet";
-
-/* use ethtool to change the level for any given device */
-static int msg_level = -1;
-module_param (msg_level, int, 0);
-MODULE_PARM_DESC (msg_level, "Override default message level");
-
-/*-------------------------------------------------------------------------*/
-
-
-//add by kevin
-extern int wmt_getsyspara(const char *varname, char *varval, int * varlen);
-static unsigned char char2hex(char c){
- unsigned char ret=0xff;
- if(c>='0'&&c<='9')
- ret= c-'0';
- if(c>='a'&&c<='f')
- ret= c-'a'+10;
- if(c>='A'&&c<='F')
- ret= c-'A'+10;
- return ret;
-}
-
-void check_set_mac(unsigned char *buf){
-
- char ethbuf[50];
- int len = sizeof(ethbuf);
- memset((void*)ethbuf, 0, len);
-
- //wondermedia set bt mac addr
- if(!wmt_getsyspara("ethaddr", ethbuf, &len)){
-
- printk("wmt eth addr %s %d\n",ethbuf,strlen(ethbuf));
- //ethaddr=00:40:63:70:13:37
- if(strlen(ethbuf)==17){
- buf[0] = (char2hex(ethbuf[0])<<4)|char2hex(ethbuf[1]);
- buf[1] = (char2hex(ethbuf[3])<<4)|char2hex(ethbuf[4]);
- buf[2] = (char2hex(ethbuf[6])<<4)|char2hex(ethbuf[7]);
- buf[3] = (char2hex(ethbuf[9])<<4)|char2hex(ethbuf[10]);
- buf[4] = (char2hex(ethbuf[12])<<4)|char2hex(ethbuf[13]);
- buf[5] = (char2hex(ethbuf[15])<<4)|char2hex(ethbuf[16]);
-
- }
- //ethaddr=004063701337
- if(strlen(ethbuf)==12){
- buf[0] = (char2hex(ethbuf[0])<<4)|char2hex(ethbuf[1]);
- buf[1] = (char2hex(ethbuf[2])<<4)|char2hex(ethbuf[3]);
- buf[2] = (char2hex(ethbuf[4])<<4)|char2hex(ethbuf[5]);
- buf[3] = (char2hex(ethbuf[6])<<4)|char2hex(ethbuf[7]);
- buf[4] = (char2hex(ethbuf[8])<<4)|char2hex(ethbuf[9]);
- buf[5] = (char2hex(ethbuf[10])<<4)|char2hex(ethbuf[11]);
- }
- }
-}
-
-
-/* handles CDC Ethernet and many other network "bulk data" interfaces */
-int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
-{
- int tmp;
- struct usb_host_interface *alt = NULL;
- struct usb_host_endpoint *in = NULL, *out = NULL;
- struct usb_host_endpoint *status = NULL;
-
- for (tmp = 0; tmp < intf->num_altsetting; tmp++) {
- unsigned ep;
-
- in = out = status = NULL;
- alt = intf->altsetting + tmp;
-
- /* take the first altsetting with in-bulk + out-bulk;
- * remember any status endpoint, just in case;
- * ignore other endpoints and altsettings.
- */
- for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) {
- struct usb_host_endpoint *e;
- int intr = 0;
-
- e = alt->endpoint + ep;
- switch (e->desc.bmAttributes) {
- case USB_ENDPOINT_XFER_INT:
- if (!usb_endpoint_dir_in(&e->desc))
- continue;
- intr = 1;
- /* FALLTHROUGH */
- case USB_ENDPOINT_XFER_BULK:
- break;
- default:
- continue;
- }
- if (usb_endpoint_dir_in(&e->desc)) {
- if (!intr && !in)
- in = e;
- else if (intr && !status)
- status = e;
- } else {
- if (!out)
- out = e;
- }
- }
- if (in && out)
- break;
- }
- if (!alt || !in || !out)
- return -EINVAL;
-
- if (alt->desc.bAlternateSetting != 0 ||
- !(dev->driver_info->flags & FLAG_NO_SETINT)) {
- tmp = usb_set_interface (dev->udev, alt->desc.bInterfaceNumber,
- alt->desc.bAlternateSetting);
- if (tmp < 0)
- return tmp;
- }
-
- dev->in = usb_rcvbulkpipe (dev->udev,
- in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
- dev->out = usb_sndbulkpipe (dev->udev,
- out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
- dev->status = status;
- return 0;
-}
-EXPORT_SYMBOL_GPL(usbnet_get_endpoints);
-
-int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress)
-{
- int tmp, i;
- unsigned char buf [13];
-
- tmp = usb_string(dev->udev, iMACAddress, buf, sizeof buf);
- if (tmp != 12) {
- dev_dbg(&dev->udev->dev,
- "bad MAC string %d fetch, %d\n", iMACAddress, tmp);
- if (tmp >= 0)
- tmp = -EINVAL;
- return tmp;
- }
- for (i = tmp = 0; i < 6; i++, tmp += 2)
- dev->net->dev_addr [i] =
- (hex_to_bin(buf[tmp]) << 4) + hex_to_bin(buf[tmp + 1]);
- return 0;
-}
-EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr);
-
-static void intr_complete (struct urb *urb);
-
-static int init_status (struct usbnet *dev, struct usb_interface *intf)
-{
- char *buf = NULL;
- unsigned pipe = 0;
- unsigned maxp;
- unsigned period;
-
- if (!dev->driver_info->status)
- return 0;
-
- pipe = usb_rcvintpipe (dev->udev,
- dev->status->desc.bEndpointAddress
- & USB_ENDPOINT_NUMBER_MASK);
- maxp = usb_maxpacket (dev->udev, pipe, 0);
-
- /* avoid 1 msec chatter: min 8 msec poll rate */
- period = max ((int) dev->status->desc.bInterval,
- (dev->udev->speed == USB_SPEED_HIGH) ? 7 : 3);
-
- buf = kmalloc (maxp, GFP_KERNEL);
- if (buf) {
- dev->interrupt = usb_alloc_urb (0, GFP_KERNEL);
- if (!dev->interrupt) {
- kfree (buf);
- return -ENOMEM;
- } else {
- usb_fill_int_urb(dev->interrupt, dev->udev, pipe,
- buf, maxp, intr_complete, dev, period);
- dev->interrupt->transfer_flags |= URB_FREE_BUFFER;
- dev_dbg(&intf->dev,
- "status ep%din, %d bytes period %d\n",
- usb_pipeendpoint(pipe), maxp, period);
- }
- }
- return 0;
-}
-
-/* Passes this packet up the stack, updating its accounting.
- * Some link protocols batch packets, so their rx_fixup paths
- * can return clones as well as just modify the original skb.
- */
-void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb)
-{
- int status;
-
- if (test_bit(EVENT_RX_PAUSED, &dev->flags)) {
- skb_queue_tail(&dev->rxq_pause, skb);
- return;
- }
-
- skb->protocol = eth_type_trans (skb, dev->net);
- dev->net->stats.rx_packets++;
- dev->net->stats.rx_bytes += skb->len;
-
- netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n",
- skb->len + sizeof (struct ethhdr), skb->protocol);
- memset (skb->cb, 0, sizeof (struct skb_data));
-
- if (skb_defer_rx_timestamp(skb))
- return;
-
- status = netif_rx (skb);
- if (status != NET_RX_SUCCESS)
- netif_dbg(dev, rx_err, dev->net,
- "netif_rx status %d\n", status);
-}
-EXPORT_SYMBOL_GPL(usbnet_skb_return);
-
-
-/*-------------------------------------------------------------------------
- *
- * Network Device Driver (peer link to "Host Device", from USB host)
- *
- *-------------------------------------------------------------------------*/
-
-int usbnet_change_mtu (struct net_device *net, int new_mtu)
-{
- struct usbnet *dev = netdev_priv(net);
- int ll_mtu = new_mtu + net->hard_header_len;
- int old_hard_mtu = dev->hard_mtu;
- int old_rx_urb_size = dev->rx_urb_size;
-
- if (new_mtu <= 0)
- return -EINVAL;
- // no second zero-length packet read wanted after mtu-sized packets
- if ((ll_mtu % dev->maxpacket) == 0)
- return -EDOM;
- net->mtu = new_mtu;
-
- dev->hard_mtu = net->mtu + net->hard_header_len;
- if (dev->rx_urb_size == old_hard_mtu) {
- dev->rx_urb_size = dev->hard_mtu;
- if (dev->rx_urb_size > old_rx_urb_size)
- usbnet_unlink_rx_urbs(dev);
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(usbnet_change_mtu);
-
-/* The caller must hold list->lock */
-static void __usbnet_queue_skb(struct sk_buff_head *list,
- struct sk_buff *newsk, enum skb_state state)
-{
- struct skb_data *entry = (struct skb_data *) newsk->cb;
-
- __skb_queue_tail(list, newsk);
- entry->state = state;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* some LK 2.4 HCDs oopsed if we freed or resubmitted urbs from
- * completion callbacks. 2.5 should have fixed those bugs...
- */
-
-static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb,
- struct sk_buff_head *list, enum skb_state state)
-{
- unsigned long flags;
- enum skb_state old_state;
- struct skb_data *entry = (struct skb_data *) skb->cb;
-
- spin_lock_irqsave(&list->lock, flags);
- old_state = entry->state;
- entry->state = state;
- __skb_unlink(skb, list);
- spin_unlock(&list->lock);
- spin_lock(&dev->done.lock);
- __skb_queue_tail(&dev->done, skb);
- if (dev->done.qlen == 1)
- tasklet_schedule(&dev->bh);
- spin_unlock_irqrestore(&dev->done.lock, flags);
- return old_state;
-}
-
-/* some work can't be done in tasklets, so we use keventd
- *
- * NOTE: annoying asymmetry: if it's active, schedule_work() fails,
- * but tasklet_schedule() doesn't. hope the failure is rare.
- */
-void usbnet_defer_kevent (struct usbnet *dev, int work)
-{
- set_bit (work, &dev->flags);
- if (!schedule_work (&dev->kevent))
- netdev_err(dev->net, "kevent %d may have been dropped\n", work);
- else
- netdev_dbg(dev->net, "kevent %d scheduled\n", work);
-}
-EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
-
-/*-------------------------------------------------------------------------*/
-
-static void rx_complete (struct urb *urb);
-
-static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
-{
- struct sk_buff *skb;
- struct skb_data *entry;
- int retval = 0;
- unsigned long lockflags;
- size_t size = dev->rx_urb_size;
-
- skb = __netdev_alloc_skb_ip_align(dev->net, size, flags);
- if (!skb) {
- netif_dbg(dev, rx_err, dev->net, "no rx skb\n");
- usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
- usb_free_urb (urb);
- return -ENOMEM;
- }
-
- entry = (struct skb_data *) skb->cb;
- entry->urb = urb;
- entry->dev = dev;
- entry->length = 0;
-
- usb_fill_bulk_urb (urb, dev->udev, dev->in,
- skb->data, size, rx_complete, skb);
-
- spin_lock_irqsave (&dev->rxq.lock, lockflags);
-
- if (netif_running (dev->net) &&
- netif_device_present (dev->net) &&
- !test_bit (EVENT_RX_HALT, &dev->flags) &&
- !test_bit (EVENT_DEV_ASLEEP, &dev->flags)) {
- switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) {
- case -EPIPE:
- usbnet_defer_kevent (dev, EVENT_RX_HALT);
- break;
- case -ENOMEM:
- usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
- break;
- case -ENODEV:
- netif_dbg(dev, ifdown, dev->net, "device gone\n");
- netif_device_detach (dev->net);
- break;
- case -EHOSTUNREACH:
- retval = -ENOLINK;
- break;
- default:
- netif_dbg(dev, rx_err, dev->net,
- "rx submit, %d\n", retval);
- tasklet_schedule (&dev->bh);
- break;
- case 0:
- __usbnet_queue_skb(&dev->rxq, skb, rx_start);
- }
- } else {
- netif_dbg(dev, ifdown, dev->net, "rx: stopped\n");
- retval = -ENOLINK;
- }
- spin_unlock_irqrestore (&dev->rxq.lock, lockflags);
- if (retval) {
- dev_kfree_skb_any (skb);
- usb_free_urb (urb);
- }
- return retval;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
-{
- if (dev->driver_info->rx_fixup &&
- !dev->driver_info->rx_fixup (dev, skb)) {
- /* With RX_ASSEMBLE, rx_fixup() must update counters */
- if (!(dev->driver_info->flags & FLAG_RX_ASSEMBLE))
- dev->net->stats.rx_errors++;
- goto done;
- }
- // else network stack removes extra byte if we forced a short packet
-
- if (skb->len) {
- /* all data was already cloned from skb inside the driver */
- if (dev->driver_info->flags & FLAG_MULTI_PACKET)
- dev_kfree_skb_any(skb);
- else
- usbnet_skb_return(dev, skb);
- return;
- }
-
- netif_dbg(dev, rx_err, dev->net, "drop\n");
- dev->net->stats.rx_errors++;
-done:
- skb_queue_tail(&dev->done, skb);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void rx_complete (struct urb *urb)
-{
- struct sk_buff *skb = (struct sk_buff *) urb->context;
- struct skb_data *entry = (struct skb_data *) skb->cb;
- struct usbnet *dev = entry->dev;
- int urb_status = urb->status;
- enum skb_state state;
-
- skb_put (skb, urb->actual_length);
- state = rx_done;
- entry->urb = NULL;
-
- switch (urb_status) {
- /* success */
- case 0:
- if (skb->len < dev->net->hard_header_len) {
- state = rx_cleanup;
- dev->net->stats.rx_errors++;
- dev->net->stats.rx_length_errors++;
- netif_dbg(dev, rx_err, dev->net,
- "rx length %d\n", skb->len);
- }
- break;
-
- /* stalls need manual reset. this is rare ... except that
- * when going through USB 2.0 TTs, unplug appears this way.
- * we avoid the highspeed version of the ETIMEDOUT/EILSEQ
- * storm, recovering as needed.
- */
- case -EPIPE:
- dev->net->stats.rx_errors++;
- usbnet_defer_kevent (dev, EVENT_RX_HALT);
- // FALLTHROUGH
-
- /* software-driven interface shutdown */
- case -ECONNRESET: /* async unlink */
- case -ESHUTDOWN: /* hardware gone */
- netif_dbg(dev, ifdown, dev->net,
- "rx shutdown, code %d\n", urb_status);
- goto block;
-
- /* we get controller i/o faults during khubd disconnect() delays.
- * throttle down resubmits, to avoid log floods; just temporarily,
- * so we still recover when the fault isn't a khubd delay.
- */
- case -EPROTO:
- case -ETIME:
- case -EILSEQ:
- dev->net->stats.rx_errors++;
- if (!timer_pending (&dev->delay)) {
- mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES);
- netif_dbg(dev, link, dev->net,
- "rx throttle %d\n", urb_status);
- }
-block:
- state = rx_cleanup;
- entry->urb = urb;
- urb = NULL;
- break;
-
- /* data overrun ... flush fifo? */
- case -EOVERFLOW:
- dev->net->stats.rx_over_errors++;
- // FALLTHROUGH
-
- default:
- state = rx_cleanup;
- dev->net->stats.rx_errors++;
- netif_dbg(dev, rx_err, dev->net, "rx status %d\n", urb_status);
- break;
- }
-
- state = defer_bh(dev, skb, &dev->rxq, state);
-
- if (urb) {
- if (netif_running (dev->net) &&
- !test_bit (EVENT_RX_HALT, &dev->flags) &&
- state != unlink_start) {
- rx_submit (dev, urb, GFP_ATOMIC);
- usb_mark_last_busy(dev->udev);
- return;
- }
- usb_free_urb (urb);
- }
- netif_dbg(dev, rx_err, dev->net, "no read resubmitted\n");
-}
-
-static void intr_complete (struct urb *urb)
-{
- struct usbnet *dev = urb->context;
- int status = urb->status;
-
- switch (status) {
- /* success */
- case 0:
- dev->driver_info->status(dev, urb);
- break;
-
- /* software-driven interface shutdown */
- case -ENOENT: /* urb killed */
- case -ESHUTDOWN: /* hardware gone */
- netif_dbg(dev, ifdown, dev->net,
- "intr shutdown, code %d\n", status);
- return;
-
- /* NOTE: not throttling like RX/TX, since this endpoint
- * already polls infrequently
- */
- default:
- netdev_dbg(dev->net, "intr status %d\n", status);
- break;
- }
-
- if (!netif_running (dev->net))
- return;
-
- memset(urb->transfer_buffer, 0, urb->transfer_buffer_length);
- status = usb_submit_urb (urb, GFP_ATOMIC);
- if (status != 0)
- netif_err(dev, timer, dev->net,
- "intr resubmit --> %d\n", status);
-}
-
-/*-------------------------------------------------------------------------*/
-void usbnet_pause_rx(struct usbnet *dev)
-{
- set_bit(EVENT_RX_PAUSED, &dev->flags);
-
- netif_dbg(dev, rx_status, dev->net, "paused rx queue enabled\n");
-}
-EXPORT_SYMBOL_GPL(usbnet_pause_rx);
-
-void usbnet_resume_rx(struct usbnet *dev)
-{
- struct sk_buff *skb;
- int num = 0;
-
- clear_bit(EVENT_RX_PAUSED, &dev->flags);
-
- while ((skb = skb_dequeue(&dev->rxq_pause)) != NULL) {
- usbnet_skb_return(dev, skb);
- num++;
- }
-
- tasklet_schedule(&dev->bh);
-
- netif_dbg(dev, rx_status, dev->net,
- "paused rx queue disabled, %d skbs requeued\n", num);
-}
-EXPORT_SYMBOL_GPL(usbnet_resume_rx);
-
-void usbnet_purge_paused_rxq(struct usbnet *dev)
-{
- skb_queue_purge(&dev->rxq_pause);
-}
-EXPORT_SYMBOL_GPL(usbnet_purge_paused_rxq);
-
-/*-------------------------------------------------------------------------*/
-
-// unlink pending rx/tx; completion handlers do all other cleanup
-
-static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
-{
- unsigned long flags;
- struct sk_buff *skb;
- int count = 0;
-
- spin_lock_irqsave (&q->lock, flags);
- while (!skb_queue_empty(q)) {
- struct skb_data *entry;
- struct urb *urb;
- int retval;
-
- skb_queue_walk(q, skb) {
- entry = (struct skb_data *) skb->cb;
- if (entry->state != unlink_start)
- goto found;
- }
- break;
-found:
- entry->state = unlink_start;
- urb = entry->urb;
-
- /*
- * Get reference count of the URB to avoid it to be
- * freed during usb_unlink_urb, which may trigger
- * use-after-free problem inside usb_unlink_urb since
- * usb_unlink_urb is always racing with .complete
- * handler(include defer_bh).
- */
- usb_get_urb(urb);
- spin_unlock_irqrestore(&q->lock, flags);
- // during some PM-driven resume scenarios,
- // these (async) unlinks complete immediately
- retval = usb_unlink_urb (urb);
- if (retval != -EINPROGRESS && retval != 0)
- netdev_dbg(dev->net, "unlink urb err, %d\n", retval);
- else
- count++;
- usb_put_urb(urb);
- spin_lock_irqsave(&q->lock, flags);
- }
- spin_unlock_irqrestore (&q->lock, flags);
- return count;
-}
-
-// Flush all pending rx urbs
-// minidrivers may need to do this when the MTU changes
-
-void usbnet_unlink_rx_urbs(struct usbnet *dev)
-{
- if (netif_running(dev->net)) {
- (void) unlink_urbs (dev, &dev->rxq);
- tasklet_schedule(&dev->bh);
- }
-}
-EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs);
-
-/*-------------------------------------------------------------------------*/
-
-// precondition: never called in_interrupt
-static void usbnet_terminate_urbs(struct usbnet *dev)
-{
- DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
- DECLARE_WAITQUEUE(wait, current);
- int temp;
-
- /* ensure there are no more active urbs */
- add_wait_queue(&unlink_wakeup, &wait);
- set_current_state(TASK_UNINTERRUPTIBLE);
- dev->wait = &unlink_wakeup;
- temp = unlink_urbs(dev, &dev->txq) +
- unlink_urbs(dev, &dev->rxq);
-
- /* maybe wait for deletions to finish. */
- while (!skb_queue_empty(&dev->rxq)
- && !skb_queue_empty(&dev->txq)
- && !skb_queue_empty(&dev->done)) {
- schedule_timeout(msecs_to_jiffies(UNLINK_TIMEOUT_MS));
- set_current_state(TASK_UNINTERRUPTIBLE);
- netif_dbg(dev, ifdown, dev->net,
- "waited for %d urb completions\n", temp);
- }
- set_current_state(TASK_RUNNING);
- dev->wait = NULL;
- remove_wait_queue(&unlink_wakeup, &wait);
-}
-
-int usbnet_stop (struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
- struct driver_info *info = dev->driver_info;
- int retval;
-
- clear_bit(EVENT_DEV_OPEN, &dev->flags);
- netif_stop_queue (net);
-
- netif_info(dev, ifdown, dev->net,
- "stop stats: rx/tx %lu/%lu, errs %lu/%lu\n",
- net->stats.rx_packets, net->stats.tx_packets,
- net->stats.rx_errors, net->stats.tx_errors);
-
- /* allow minidriver to stop correctly (wireless devices to turn off
- * radio etc) */
- if (info->stop) {
- retval = info->stop(dev);
- if (retval < 0)
- netif_info(dev, ifdown, dev->net,
- "stop fail (%d) usbnet usb-%s-%s, %s\n",
- retval,
- dev->udev->bus->bus_name, dev->udev->devpath,
- info->description);
- }
-
- if (!(info->flags & FLAG_AVOID_UNLINK_URBS))
- usbnet_terminate_urbs(dev);
-
- usb_kill_urb(dev->interrupt);
-
- usbnet_purge_paused_rxq(dev);
-
- /* deferred work (task, timer, softirq) must also stop.
- * can't flush_scheduled_work() until we drop rtnl (later),
- * else workers could deadlock; so make workers a NOP.
- */
- dev->flags = 0;
- del_timer_sync (&dev->delay);
- tasklet_kill (&dev->bh);
- if (info->manage_power)
- info->manage_power(dev, 0);
- else
- usb_autopm_put_interface(dev->intf);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(usbnet_stop);
-
-/*-------------------------------------------------------------------------*/
-
-// posts reads, and enables write queuing
-
-// precondition: never called in_interrupt
-
-int usbnet_open (struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
- int retval;
- struct driver_info *info = dev->driver_info;
-
- if ((retval = usb_autopm_get_interface(dev->intf)) < 0) {
- netif_info(dev, ifup, dev->net,
- "resumption fail (%d) usbnet usb-%s-%s, %s\n",
- retval,
- dev->udev->bus->bus_name,
- dev->udev->devpath,
- info->description);
- goto done_nopm;
- }
-
- // put into "known safe" state
- if (info->reset && (retval = info->reset (dev)) < 0) {
- netif_info(dev, ifup, dev->net,
- "open reset fail (%d) usbnet usb-%s-%s, %s\n",
- retval,
- dev->udev->bus->bus_name,
- dev->udev->devpath,
- info->description);
- goto done;
- }
-
- // insist peer be connected
- if (info->check_connect && (retval = info->check_connect (dev)) < 0) {
- netif_dbg(dev, ifup, dev->net, "can't open; %d\n", retval);
- goto done;
- }
-
- /* start any status interrupt transfer */
- if (dev->interrupt) {
- retval = usb_submit_urb (dev->interrupt, GFP_KERNEL);
- if (retval < 0) {
- netif_err(dev, ifup, dev->net,
- "intr submit %d\n", retval);
- goto done;
- }
- }
-
- set_bit(EVENT_DEV_OPEN, &dev->flags);
- netif_start_queue (net);
- netif_info(dev, ifup, dev->net,
- "open: enable queueing (rx %d, tx %d) mtu %d %s framing\n",
- (int)RX_QLEN(dev), (int)TX_QLEN(dev),
- dev->net->mtu,
- (dev->driver_info->flags & FLAG_FRAMING_NC) ? "NetChip" :
- (dev->driver_info->flags & FLAG_FRAMING_GL) ? "GeneSys" :
- (dev->driver_info->flags & FLAG_FRAMING_Z) ? "Zaurus" :
- (dev->driver_info->flags & FLAG_FRAMING_RN) ? "RNDIS" :
- (dev->driver_info->flags & FLAG_FRAMING_AX) ? "ASIX" :
- "simple");
-
- // delay posting reads until we're fully open
- tasklet_schedule (&dev->bh);
- if (info->manage_power) {
- retval = info->manage_power(dev, 1);
- if (retval < 0)
- goto done;
- usb_autopm_put_interface(dev->intf);
- }
- return retval;
-
-done:
- usb_autopm_put_interface(dev->intf);
-done_nopm:
- return retval;
-}
-EXPORT_SYMBOL_GPL(usbnet_open);
-
-/*-------------------------------------------------------------------------*/
-
-/* ethtool methods; minidrivers may need to add some more, but
- * they'll probably want to use this base set.
- */
-
-int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd)
-{
- struct usbnet *dev = netdev_priv(net);
-
- if (!dev->mii.mdio_read)
- return -EOPNOTSUPP;
-
- return mii_ethtool_gset(&dev->mii, cmd);
-}
-EXPORT_SYMBOL_GPL(usbnet_get_settings);
-
-int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd)
-{
- struct usbnet *dev = netdev_priv(net);
- int retval;
-
- if (!dev->mii.mdio_write)
- return -EOPNOTSUPP;
-
- retval = mii_ethtool_sset(&dev->mii, cmd);
-
- /* link speed/duplex might have changed */
- if (dev->driver_info->link_reset)
- dev->driver_info->link_reset(dev);
-
- return retval;
-
-}
-EXPORT_SYMBOL_GPL(usbnet_set_settings);
-
-u32 usbnet_get_link (struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
-
- /* If a check_connect is defined, return its result */
- if (dev->driver_info->check_connect)
- return dev->driver_info->check_connect (dev) == 0;
-
- /* if the device has mii operations, use those */
- if (dev->mii.mdio_read)
- return mii_link_ok(&dev->mii);
-
- /* Otherwise, dtrt for drivers calling netif_carrier_{on,off} */
- return ethtool_op_get_link(net);
-}
-EXPORT_SYMBOL_GPL(usbnet_get_link);
-
-int usbnet_nway_reset(struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
-
- if (!dev->mii.mdio_write)
- return -EOPNOTSUPP;
-
- return mii_nway_restart(&dev->mii);
-}
-EXPORT_SYMBOL_GPL(usbnet_nway_reset);
-
-void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
-{
- struct usbnet *dev = netdev_priv(net);
-
- strncpy (info->driver, dev->driver_name, sizeof info->driver);
- strncpy (info->version, DRIVER_VERSION, sizeof info->version);
- strncpy (info->fw_version, dev->driver_info->description,
- sizeof info->fw_version);
- usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info);
-}
-EXPORT_SYMBOL_GPL(usbnet_get_drvinfo);
-
-u32 usbnet_get_msglevel (struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
-
- return dev->msg_enable;
-}
-EXPORT_SYMBOL_GPL(usbnet_get_msglevel);
-
-void usbnet_set_msglevel (struct net_device *net, u32 level)
-{
- struct usbnet *dev = netdev_priv(net);
-
- dev->msg_enable = level;
-}
-EXPORT_SYMBOL_GPL(usbnet_set_msglevel);
-
-/* drivers may override default ethtool_ops in their bind() routine */
-static const struct ethtool_ops usbnet_ethtool_ops = {
- .get_settings = usbnet_get_settings,
- .set_settings = usbnet_set_settings,
- .get_link = usbnet_get_link,
- .nway_reset = usbnet_nway_reset,
- .get_drvinfo = usbnet_get_drvinfo,
- .get_msglevel = usbnet_get_msglevel,
- .set_msglevel = usbnet_set_msglevel,
-};
-
-/*-------------------------------------------------------------------------*/
-
-/* work that cannot be done in interrupt context uses keventd.
- *
- * NOTE: with 2.5 we could do more of this using completion callbacks,
- * especially now that control transfers can be queued.
- */
-static void
-kevent (struct work_struct *work)
-{
- struct usbnet *dev =
- container_of(work, struct usbnet, kevent);
- int status;
-
- /* usb_clear_halt() needs a thread context */
- if (test_bit (EVENT_TX_HALT, &dev->flags)) {
- unlink_urbs (dev, &dev->txq);
- status = usb_autopm_get_interface(dev->intf);
- if (status < 0)
- goto fail_pipe;
- status = usb_clear_halt (dev->udev, dev->out);
- usb_autopm_put_interface(dev->intf);
- if (status < 0 &&
- status != -EPIPE &&
- status != -ESHUTDOWN) {
- if (netif_msg_tx_err (dev))
-fail_pipe:
- netdev_err(dev->net, "can't clear tx halt, status %d\n",
- status);
- } else {
- clear_bit (EVENT_TX_HALT, &dev->flags);
- if (status != -ESHUTDOWN)
- netif_wake_queue (dev->net);
- }
- }
- if (test_bit (EVENT_RX_HALT, &dev->flags)) {
- unlink_urbs (dev, &dev->rxq);
- status = usb_autopm_get_interface(dev->intf);
- if (status < 0)
- goto fail_halt;
- status = usb_clear_halt (dev->udev, dev->in);
- usb_autopm_put_interface(dev->intf);
- if (status < 0 &&
- status != -EPIPE &&
- status != -ESHUTDOWN) {
- if (netif_msg_rx_err (dev))
-fail_halt:
- netdev_err(dev->net, "can't clear rx halt, status %d\n",
- status);
- } else {
- clear_bit (EVENT_RX_HALT, &dev->flags);
- tasklet_schedule (&dev->bh);
- }
- }
-
- /* tasklet could resubmit itself forever if memory is tight */
- if (test_bit (EVENT_RX_MEMORY, &dev->flags)) {
- struct urb *urb = NULL;
- int resched = 1;
-
- if (netif_running (dev->net))
- urb = usb_alloc_urb (0, GFP_KERNEL);
- else
- clear_bit (EVENT_RX_MEMORY, &dev->flags);
- if (urb != NULL) {
- clear_bit (EVENT_RX_MEMORY, &dev->flags);
- status = usb_autopm_get_interface(dev->intf);
- if (status < 0) {
- usb_free_urb(urb);
- goto fail_lowmem;
- }
- if (rx_submit (dev, urb, GFP_KERNEL) == -ENOLINK)
- resched = 0;
- usb_autopm_put_interface(dev->intf);
-fail_lowmem:
- if (resched)
- tasklet_schedule (&dev->bh);
- }
- }
-
- if (test_bit (EVENT_LINK_RESET, &dev->flags)) {
- struct driver_info *info = dev->driver_info;
- int retval = 0;
-
- clear_bit (EVENT_LINK_RESET, &dev->flags);
- status = usb_autopm_get_interface(dev->intf);
- if (status < 0)
- goto skip_reset;
- if(info->link_reset && (retval = info->link_reset(dev)) < 0) {
- usb_autopm_put_interface(dev->intf);
-skip_reset:
- netdev_info(dev->net, "link reset failed (%d) usbnet usb-%s-%s, %s\n",
- retval,
- dev->udev->bus->bus_name,
- dev->udev->devpath,
- info->description);
- } else {
- usb_autopm_put_interface(dev->intf);
- }
- }
-
- if (dev->flags)
- netdev_dbg(dev->net, "kevent done, flags = 0x%lx\n", dev->flags);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void tx_complete (struct urb *urb)
-{
- struct sk_buff *skb = (struct sk_buff *) urb->context;
- struct skb_data *entry = (struct skb_data *) skb->cb;
- struct usbnet *dev = entry->dev;
-
- if (urb->status == 0) {
- if (!(dev->driver_info->flags & FLAG_MULTI_PACKET))
- dev->net->stats.tx_packets++;
- dev->net->stats.tx_bytes += entry->length;
- } else {
- dev->net->stats.tx_errors++;
-
- switch (urb->status) {
- case -EPIPE:
- usbnet_defer_kevent (dev, EVENT_TX_HALT);
- break;
-
- /* software-driven interface shutdown */
- case -ECONNRESET: // async unlink
- case -ESHUTDOWN: // hardware gone
- break;
-
- // like rx, tx gets controller i/o faults during khubd delays
- // and so it uses the same throttling mechanism.
- case -EPROTO:
- case -ETIME:
- case -EILSEQ:
- usb_mark_last_busy(dev->udev);
- if (!timer_pending (&dev->delay)) {
- mod_timer (&dev->delay,
- jiffies + THROTTLE_JIFFIES);
- netif_dbg(dev, link, dev->net,
- "tx throttle %d\n", urb->status);
- }
- netif_stop_queue (dev->net);
- break;
- default:
- netif_dbg(dev, tx_err, dev->net,
- "tx err %d\n", entry->urb->status);
- break;
- }
- }
-
- usb_autopm_put_interface_async(dev->intf);
- (void) defer_bh(dev, skb, &dev->txq, tx_done);
-}
-
-/*-------------------------------------------------------------------------*/
-
-void usbnet_tx_timeout (struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
-
- unlink_urbs (dev, &dev->txq);
- tasklet_schedule (&dev->bh);
-
- // FIXME: device recovery -- reset?
-}
-EXPORT_SYMBOL_GPL(usbnet_tx_timeout);
-
-/*-------------------------------------------------------------------------*/
-
-netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
- struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
- int length;
- struct urb *urb = NULL;
- struct skb_data *entry;
- struct driver_info *info = dev->driver_info;
- unsigned long flags;
- int retval;
-
- if (skb)
- skb_tx_timestamp(skb);
-
- // some devices want funky USB-level framing, for
- // win32 driver (usually) and/or hardware quirks
- if (info->tx_fixup) {
- skb = info->tx_fixup (dev, skb, GFP_ATOMIC);
- if (!skb) {
- if (netif_msg_tx_err(dev)) {
- netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n");
- goto drop;
- } else {
- /* cdc_ncm collected packet; waits for more */
- goto not_drop;
- }
- }
- }
- length = skb->len;
-
- if (!(urb = usb_alloc_urb (0, GFP_ATOMIC))) {
- netif_dbg(dev, tx_err, dev->net, "no urb\n");
- goto drop;
- }
-
- entry = (struct skb_data *) skb->cb;
- entry->urb = urb;
- entry->dev = dev;
- entry->length = length;
-
- usb_fill_bulk_urb (urb, dev->udev, dev->out,
- skb->data, skb->len, tx_complete, skb);
-
- /* don't assume the hardware handles USB_ZERO_PACKET
- * NOTE: strictly conforming cdc-ether devices should expect
- * the ZLP here, but ignore the one-byte packet.
- * NOTE2: CDC NCM specification is different from CDC ECM when
- * handling ZLP/short packets, so cdc_ncm driver will make short
- * packet itself if needed.
- */
- if (length % dev->maxpacket == 0) {
- if (!(info->flags & FLAG_SEND_ZLP)) {
- if (!(info->flags & FLAG_MULTI_PACKET)) {
- urb->transfer_buffer_length++;
- if (skb_tailroom(skb)) {
- skb->data[skb->len] = 0;
- __skb_put(skb, 1);
- }
- }
- } else
- urb->transfer_flags |= URB_ZERO_PACKET;
- }
-
- spin_lock_irqsave(&dev->txq.lock, flags);
- retval = usb_autopm_get_interface_async(dev->intf);
- if (retval < 0) {
- spin_unlock_irqrestore(&dev->txq.lock, flags);
- goto drop;
- }
-
-#ifdef CONFIG_PM
- /* if this triggers the device is still a sleep */
- if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) {
- /* transmission will be done in resume */
- usb_anchor_urb(urb, &dev->deferred);
- /* no use to process more packets */
- netif_stop_queue(net);
- spin_unlock_irqrestore(&dev->txq.lock, flags);
- netdev_dbg(dev->net, "Delaying transmission for resumption\n");
- goto deferred;
- }
-#endif
-
- switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) {
- case -EPIPE:
- netif_stop_queue (net);
- usbnet_defer_kevent (dev, EVENT_TX_HALT);
- usb_autopm_put_interface_async(dev->intf);
- break;
- default:
- usb_autopm_put_interface_async(dev->intf);
- netif_dbg(dev, tx_err, dev->net,
- "tx: submit urb err %d\n", retval);
- break;
- case 0:
- net->trans_start = jiffies;
- __usbnet_queue_skb(&dev->txq, skb, tx_start);
- if (dev->txq.qlen >= TX_QLEN (dev))
- netif_stop_queue (net);
- }
- spin_unlock_irqrestore (&dev->txq.lock, flags);
-
- if (retval) {
- netif_dbg(dev, tx_err, dev->net, "drop, code %d\n", retval);
-drop:
- dev->net->stats.tx_dropped++;
-not_drop:
- if (skb)
- dev_kfree_skb_any (skb);
- usb_free_urb (urb);
- } else
- netif_dbg(dev, tx_queued, dev->net,
- "> tx, len %d, type 0x%x\n", length, skb->protocol);
-#ifdef CONFIG_PM
-deferred:
-#endif
- return NETDEV_TX_OK;
-}
-EXPORT_SYMBOL_GPL(usbnet_start_xmit);
-
-/*-------------------------------------------------------------------------*/
-
-// tasklet (work deferred from completions, in_irq) or timer
-
-static void usbnet_bh (unsigned long param)
-{
- struct usbnet *dev = (struct usbnet *) param;
- struct sk_buff *skb;
- struct skb_data *entry;
-
- while ((skb = skb_dequeue (&dev->done))) {
- entry = (struct skb_data *) skb->cb;
- switch (entry->state) {
- case rx_done:
- entry->state = rx_cleanup;
- rx_process (dev, skb);
- continue;
- case tx_done:
- case rx_cleanup:
- usb_free_urb (entry->urb);
- dev_kfree_skb (skb);
- continue;
- default:
- netdev_dbg(dev->net, "bogus skb state %d\n", entry->state);
- }
- }
-
- // waiting for all pending urbs to complete?
- if (dev->wait) {
- if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) {
- wake_up (dev->wait);
- }
-
- // or are we maybe short a few urbs?
- } else if (netif_running (dev->net) &&
- netif_device_present (dev->net) &&
- !timer_pending (&dev->delay) &&
- !test_bit (EVENT_RX_HALT, &dev->flags)) {
- int temp = dev->rxq.qlen;
- int qlen = RX_QLEN (dev);
-
- if (temp < qlen) {
- struct urb *urb;
- int i;
-
- // don't refill the queue all at once
- for (i = 0; i < 10 && dev->rxq.qlen < qlen; i++) {
- urb = usb_alloc_urb (0, GFP_ATOMIC);
- if (urb != NULL) {
- if (rx_submit (dev, urb, GFP_ATOMIC) ==
- -ENOLINK)
- return;
- }
- }
- if (temp != dev->rxq.qlen)
- netif_dbg(dev, link, dev->net,
- "rxqlen %d --> %d\n",
- temp, dev->rxq.qlen);
- if (dev->rxq.qlen < qlen)
- tasklet_schedule (&dev->bh);
- }
- if (dev->txq.qlen < TX_QLEN (dev))
- netif_wake_queue (dev->net);
- }
-}
-
-
-/*-------------------------------------------------------------------------
- *
- * USB Device Driver support
- *
- *-------------------------------------------------------------------------*/
-
-// precondition: never called in_interrupt
-
-void usbnet_disconnect (struct usb_interface *intf)
-{
- struct usbnet *dev;
- struct usb_device *xdev;
- struct net_device *net;
-
- dev = usb_get_intfdata(intf);
- usb_set_intfdata(intf, NULL);
- if (!dev)
- return;
-
- xdev = interface_to_usbdev (intf);
-
- netif_info(dev, probe, dev->net, "unregister '%s' usb-%s-%s, %s\n",
- intf->dev.driver->name,
- xdev->bus->bus_name, xdev->devpath,
- dev->driver_info->description);
-
- net = dev->net;
- unregister_netdev (net);
-
- cancel_work_sync(&dev->kevent);
-
- if (dev->driver_info->unbind)
- dev->driver_info->unbind (dev, intf);
-
- usb_kill_urb(dev->interrupt);
- usb_free_urb(dev->interrupt);
-
- free_netdev(net);
- usb_put_dev (xdev);
-}
-EXPORT_SYMBOL_GPL(usbnet_disconnect);
-
-static const struct net_device_ops usbnet_netdev_ops = {
- .ndo_open = usbnet_open,
- .ndo_stop = usbnet_stop,
- .ndo_start_xmit = usbnet_start_xmit,
- .ndo_tx_timeout = usbnet_tx_timeout,
- .ndo_change_mtu = usbnet_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/*-------------------------------------------------------------------------*/
-
-// precondition: never called in_interrupt
-
-static struct device_type wlan_type = {
- .name = "wlan",
-};
-
-static struct device_type wwan_type = {
- .name = "wwan",
-};
-
-int
-usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
-{
- struct usbnet *dev;
- struct net_device *net;
- struct usb_host_interface *interface;
- struct driver_info *info;
- struct usb_device *xdev;
- int status;
- const char *name;
- struct usb_driver *driver = to_usb_driver(udev->dev.driver);
-
- /* usbnet already took usb runtime pm, so have to enable the feature
- * for usb interface, otherwise usb_autopm_get_interface may return
- * failure if USB_SUSPEND(RUNTIME_PM) is enabled.
- */
- if (!driver->supports_autosuspend) {
- driver->supports_autosuspend = 1;
- pm_runtime_enable(&udev->dev);
- }
-
- name = udev->dev.driver->name;
- info = (struct driver_info *) prod->driver_info;
- if (!info) {
- dev_dbg (&udev->dev, "blacklisted by %s\n", name);
- return -ENODEV;
- }
- xdev = interface_to_usbdev (udev);
- interface = udev->cur_altsetting;
-
- usb_get_dev (xdev);
-
- status = -ENOMEM;
-
-#if 1
- //huawei mu609,skip it's cdc ether device
- if(xdev->descriptor.idVendor==0x12d1&&xdev->descriptor.idProduct==0x1573){
- printk("skip %x:%x cdc ether\n",xdev->descriptor.idVendor,xdev->descriptor.idProduct);
- goto out;
- }
-#else
-{
- char buf[256];
- int varlen = 256;
- int disable = 0;
- if( wmt_getsyspara("wmt.cdc.disable",buf,&varlen) == 0)
- {
- sscanf(buf,"%d",&disable);
- if(disable>0)
- goto out;
-
- }
-}
-#endif
- // set up our own records
- net = alloc_etherdev(sizeof(*dev));
- if (!net)
- goto out;
-
- /* netdev_printk() needs this so do it as early as possible */
- SET_NETDEV_DEV(net, &udev->dev);
-
- dev = netdev_priv(net);
- dev->udev = xdev;
- dev->intf = udev;
- dev->driver_info = info;
- dev->driver_name = name;
- dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV
- | NETIF_MSG_PROBE | NETIF_MSG_LINK);
- skb_queue_head_init (&dev->rxq);
- skb_queue_head_init (&dev->txq);
- skb_queue_head_init (&dev->done);
- skb_queue_head_init(&dev->rxq_pause);
- dev->bh.func = usbnet_bh;
- dev->bh.data = (unsigned long) dev;
- INIT_WORK (&dev->kevent, kevent);
- init_usb_anchor(&dev->deferred);
- dev->delay.function = usbnet_bh;
- dev->delay.data = (unsigned long) dev;
- init_timer (&dev->delay);
- mutex_init (&dev->phy_mutex);
-
- dev->net = net;
- strcpy (net->name, "usb%d");
- memcpy (net->dev_addr, node_id, sizeof node_id);
-
- /* rx and tx sides can use different message sizes;
- * bind() should set rx_urb_size in that case.
- */
- dev->hard_mtu = net->mtu + net->hard_header_len;
-#if 0
-// dma_supported() is deeply broken on almost all architectures
- // possible with some EHCI controllers
- if (dma_supported (&udev->dev, DMA_BIT_MASK(64)))
- net->features |= NETIF_F_HIGHDMA;
-#endif
-
- net->netdev_ops = &usbnet_netdev_ops;
- net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
- net->ethtool_ops = &usbnet_ethtool_ops;
-
- // allow device-specific bind/init procedures
- // NOTE net->name still not usable ...
- if (info->bind) {
- status = info->bind (dev, udev);
- if (status < 0)
- goto out1;
-
- // heuristic: "usb%d" for links we know are two-host,
- // else "eth%d" when there's reasonable doubt. userspace
- // can rename the link if it knows better.
- if ((dev->driver_info->flags & FLAG_ETHER) != 0 &&
- ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 ||
- (net->dev_addr [0] & 0x02) == 0))
- strcpy (net->name, "eth%d");
- /* WLAN devices should always be named "wlan%d" */
- if ((dev->driver_info->flags & FLAG_WLAN) != 0)
- strcpy(net->name, "wlan%d");
- /* WWAN devices should always be named "wwan%d" */
- if ((dev->driver_info->flags & FLAG_WWAN) != 0)
- strcpy(net->name, "wwan%d");
-
- /* maybe the remote can't receive an Ethernet MTU */
- if (net->mtu > (dev->hard_mtu - net->hard_header_len))
- net->mtu = dev->hard_mtu - net->hard_header_len;
- } else if (!info->in || !info->out)
- status = usbnet_get_endpoints (dev, udev);
- else {
- dev->in = usb_rcvbulkpipe (xdev, info->in);
- dev->out = usb_sndbulkpipe (xdev, info->out);
- if (!(info->flags & FLAG_NO_SETINT))
- status = usb_set_interface (xdev,
- interface->desc.bInterfaceNumber,
- interface->desc.bAlternateSetting);
- else
- status = 0;
-
- }
- if (status >= 0 && dev->status)
- status = init_status (dev, udev);
- if (status < 0)
- goto out3;
-
- if (!dev->rx_urb_size)
- dev->rx_urb_size = dev->hard_mtu;
- dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
-
- if ((dev->driver_info->flags & FLAG_WLAN) != 0)
- SET_NETDEV_DEVTYPE(net, &wlan_type);
- if ((dev->driver_info->flags & FLAG_WWAN) != 0)
- SET_NETDEV_DEVTYPE(net, &wwan_type);
-
- status = register_netdev (net);
- if (status)
- goto out4;
- netif_info(dev, probe, dev->net,
- "register '%s' at usb-%s-%s, %s, %pM\n",
- udev->dev.driver->name,
- xdev->bus->bus_name, xdev->devpath,
- dev->driver_info->description,
- net->dev_addr);
-
- // ok, it's ready to go.
- usb_set_intfdata (udev, dev);
-
- netif_device_attach (net);
-
- if (dev->driver_info->flags & FLAG_LINK_INTR)
- netif_carrier_off(net);
-
- return 0;
-
-out4:
- usb_free_urb(dev->interrupt);
-out3:
- if (info->unbind)
- info->unbind (dev, udev);
-out1:
- free_netdev(net);
-out:
- usb_put_dev(xdev);
- return status;
-}
-EXPORT_SYMBOL_GPL(usbnet_probe);
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * suspend the whole driver as soon as the first interface is suspended
- * resume only when the last interface is resumed
- */
-
-int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
-{
- struct usbnet *dev = usb_get_intfdata(intf);
-
- if (!dev->suspend_count++) {
- spin_lock_irq(&dev->txq.lock);
- /* don't autosuspend while transmitting */
- if (dev->txq.qlen && PMSG_IS_AUTO(message)) {
- spin_unlock_irq(&dev->txq.lock);
- return -EBUSY;
- } else {
- set_bit(EVENT_DEV_ASLEEP, &dev->flags);
- spin_unlock_irq(&dev->txq.lock);
- }
- /*
- * accelerate emptying of the rx and queues, to avoid
- * having everything error out.
- */
- netif_device_detach (dev->net);
- usbnet_terminate_urbs(dev);
- usb_kill_urb(dev->interrupt);
-
- /*
- * reattach so runtime management can use and
- * wake the device
- */
- netif_device_attach (dev->net);
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(usbnet_suspend);
-
-int usbnet_resume (struct usb_interface *intf)
-{
- struct usbnet *dev = usb_get_intfdata(intf);
- struct sk_buff *skb;
- struct urb *res;
- int retval;
-
- if (!--dev->suspend_count) {
- /* resume interrupt URBs */
- if (dev->interrupt && test_bit(EVENT_DEV_OPEN, &dev->flags))
- usb_submit_urb(dev->interrupt, GFP_NOIO);
-
- spin_lock_irq(&dev->txq.lock);
- while ((res = usb_get_from_anchor(&dev->deferred))) {
-
- skb = (struct sk_buff *)res->context;
- retval = usb_submit_urb(res, GFP_ATOMIC);
- if (retval < 0) {
- dev_kfree_skb_any(skb);
- usb_free_urb(res);
- usb_autopm_put_interface_async(dev->intf);
- } else {
- dev->net->trans_start = jiffies;
- __skb_queue_tail(&dev->txq, skb);
- }
- }
-
- smp_mb();
- clear_bit(EVENT_DEV_ASLEEP, &dev->flags);
- spin_unlock_irq(&dev->txq.lock);
-
- if (test_bit(EVENT_DEV_OPEN, &dev->flags)) {
- if (!(dev->txq.qlen >= TX_QLEN(dev)))
- netif_tx_wake_all_queues(dev->net);
- tasklet_schedule (&dev->bh);
- }
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(usbnet_resume);
-
-
-/*-------------------------------------------------------------------------*/
-
-static int __init usbnet_init(void)
-{
- /* Compiler should optimize this out. */
- BUILD_BUG_ON(
- FIELD_SIZEOF(struct sk_buff, cb) < sizeof(struct skb_data));
-
- random_ether_addr(node_id);
- return 0;
-}
-module_init(usbnet_init);
-
-static void __exit usbnet_exit(void)
-{
-}
-module_exit(usbnet_exit);
-
-MODULE_AUTHOR("David Brownell");
-MODULE_DESCRIPTION("USB network driver framework");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/usb/zaurus.c b/ANDROID_3.4.5/drivers/net/usb/zaurus.c
deleted file mode 100644
index 34db195f..00000000
--- a/ANDROID_3.4.5/drivers/net/usb/zaurus.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Copyright (C) 2002 Pavel Machek <pavel@ucw.cz>
- * Copyright (C) 2002-2005 by David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-// #define DEBUG // error path messages, extra info
-// #define VERBOSE // more; success messages
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/ethtool.h>
-#include <linux/workqueue.h>
-#include <linux/mii.h>
-#include <linux/crc32.h>
-#include <linux/usb.h>
-#include <linux/usb/cdc.h>
-#include <linux/usb/usbnet.h>
-
-
-/*
- * All known Zaurii lie about their standards conformance. At least
- * the earliest SA-1100 models lie by saying they support CDC Ethernet.
- * Some later models (especially PXA-25x and PXA-27x based ones) lie
- * and say they support CDC MDLM (for access to cell phone modems).
- *
- * There are non-Zaurus products that use these same protocols too.
- *
- * The annoying thing is that at the same time Sharp was developing
- * that annoying standards-breaking software, the Linux community had
- * a simple "CDC Subset" working reliably on the same SA-1100 hardware.
- * That is, the same functionality but not violating standards.
- *
- * The CDC Ethernet nonconformance points are troublesome to hosts
- * with a true CDC Ethernet implementation:
- * - Framing appends a CRC, which the spec says drivers "must not" do;
- * - Transfers data in altsetting zero, instead of altsetting 1;
- * - All these peripherals use the same ethernet address.
- *
- * The CDC MDLM nonconformance is less immediately troublesome, since all
- * MDLM implementations are quasi-proprietary anyway.
- */
-
-static struct sk_buff *
-zaurus_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
-{
- int padlen;
- struct sk_buff *skb2;
-
- padlen = 2;
- if (!skb_cloned(skb)) {
- int tailroom = skb_tailroom(skb);
- if ((padlen + 4) <= tailroom)
- goto done;
- }
- skb2 = skb_copy_expand(skb, 0, 4 + padlen, flags);
- dev_kfree_skb_any(skb);
- skb = skb2;
- if (skb) {
- u32 fcs;
-done:
- fcs = crc32_le(~0, skb->data, skb->len);
- fcs = ~fcs;
-
- *skb_put (skb, 1) = fcs & 0xff;
- *skb_put (skb, 1) = (fcs>> 8) & 0xff;
- *skb_put (skb, 1) = (fcs>>16) & 0xff;
- *skb_put (skb, 1) = (fcs>>24) & 0xff;
- }
- return skb;
-}
-
-static int zaurus_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- /* Belcarra's funky framing has other options; mostly
- * TRAILERS (!) with 4 bytes CRC, and maybe 2 pad bytes.
- */
- dev->net->hard_header_len += 6;
- dev->rx_urb_size = dev->net->hard_header_len + dev->net->mtu;
- return usbnet_generic_cdc_bind(dev, intf);
-}
-
-/* PDA style devices are always connected if present */
-static int always_connected (struct usbnet *dev)
-{
- return 0;
-}
-
-static const struct driver_info zaurus_sl5x00_info = {
- .description = "Sharp Zaurus SL-5x00",
- .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z,
- .check_connect = always_connected,
- .bind = zaurus_bind,
- .unbind = usbnet_cdc_unbind,
- .tx_fixup = zaurus_tx_fixup,
-};
-#define ZAURUS_STRONGARM_INFO ((unsigned long)&zaurus_sl5x00_info)
-
-static const struct driver_info zaurus_pxa_info = {
- .description = "Sharp Zaurus, PXA-2xx based",
- .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z,
- .check_connect = always_connected,
- .bind = zaurus_bind,
- .unbind = usbnet_cdc_unbind,
- .tx_fixup = zaurus_tx_fixup,
-};
-#define ZAURUS_PXA_INFO ((unsigned long)&zaurus_pxa_info)
-
-static const struct driver_info olympus_mxl_info = {
- .description = "Olympus R1000",
- .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z,
- .check_connect = always_connected,
- .bind = zaurus_bind,
- .unbind = usbnet_cdc_unbind,
- .tx_fixup = zaurus_tx_fixup,
-};
-#define OLYMPUS_MXL_INFO ((unsigned long)&olympus_mxl_info)
-
-
-/* Some more recent products using Lineo/Belcarra code will wrongly claim
- * CDC MDLM conformance. They aren't conformant: data endpoints live
- * in the control interface, there's no data interface, and it's not used
- * to talk to a cell phone radio. But at least we can detect these two
- * pseudo-classes, rather than growing this product list with entries for
- * each new nonconformant product (sigh).
- */
-static const u8 safe_guid[16] = {
- 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
- 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
-};
-static const u8 blan_guid[16] = {
- 0x74, 0xf0, 0x3d, 0xbd, 0x1e, 0xc1, 0x44, 0x70,
- 0xa3, 0x67, 0x71, 0x34, 0xc9, 0xf5, 0x54, 0x37,
-};
-
-static int blan_mdlm_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- u8 *buf = intf->cur_altsetting->extra;
- int len = intf->cur_altsetting->extralen;
- struct usb_cdc_mdlm_desc *desc = NULL;
- struct usb_cdc_mdlm_detail_desc *detail = NULL;
-
- while (len > 3) {
- if (buf [1] != USB_DT_CS_INTERFACE)
- goto next_desc;
-
- /* use bDescriptorSubType, and just verify that we get a
- * "BLAN" (or "SAFE") descriptor.
- */
- switch (buf [2]) {
- case USB_CDC_MDLM_TYPE:
- if (desc) {
- dev_dbg(&intf->dev, "extra MDLM\n");
- goto bad_desc;
- }
- desc = (void *) buf;
- if (desc->bLength != sizeof *desc) {
- dev_dbg(&intf->dev, "MDLM len %u\n",
- desc->bLength);
- goto bad_desc;
- }
- /* expect bcdVersion 1.0, ignore */
- if (memcmp(&desc->bGUID, blan_guid, 16) &&
- memcmp(&desc->bGUID, safe_guid, 16)) {
- /* hey, this one might _really_ be MDLM! */
- dev_dbg(&intf->dev, "MDLM guid\n");
- goto bad_desc;
- }
- break;
- case USB_CDC_MDLM_DETAIL_TYPE:
- if (detail) {
- dev_dbg(&intf->dev, "extra MDLM detail\n");
- goto bad_desc;
- }
- detail = (void *) buf;
- switch (detail->bGuidDescriptorType) {
- case 0: /* "SAFE" */
- if (detail->bLength != (sizeof *detail + 2))
- goto bad_detail;
- break;
- case 1: /* "BLAN" */
- if (detail->bLength != (sizeof *detail + 3))
- goto bad_detail;
- break;
- default:
- goto bad_detail;
- }
-
- /* assuming we either noticed BLAN already, or will
- * find it soon, there are some data bytes here:
- * - bmNetworkCapabilities (unused)
- * - bmDataCapabilities (bits, see below)
- * - bPad (ignored, for PADAFTER -- BLAN-only)
- * bits are:
- * - 0x01 -- Zaurus framing (add CRC)
- * - 0x02 -- PADBEFORE (CRC includes some padding)
- * - 0x04 -- PADAFTER (some padding after CRC)
- * - 0x08 -- "fermat" packet mangling (for hw bugs)
- * the PADBEFORE appears not to matter; we interop
- * with devices that use it and those that don't.
- */
- if ((detail->bDetailData[1] & ~0x02) != 0x01) {
- /* bmDataCapabilities == 0 would be fine too,
- * but framing is minidriver-coupled for now.
- */
-bad_detail:
- dev_dbg(&intf->dev,
- "bad MDLM detail, %d %d %d\n",
- detail->bLength,
- detail->bDetailData[0],
- detail->bDetailData[2]);
- goto bad_desc;
- }
-
- /* same extra framing as for non-BLAN mode */
- dev->net->hard_header_len += 6;
- dev->rx_urb_size = dev->net->hard_header_len
- + dev->net->mtu;
- break;
- }
-next_desc:
- len -= buf [0]; /* bLength */
- buf += buf [0];
- }
-
- if (!desc || !detail) {
- dev_dbg(&intf->dev, "missing cdc mdlm %s%sdescriptor\n",
- desc ? "" : "func ",
- detail ? "" : "detail ");
- goto bad_desc;
- }
-
- /* There's probably a CDC Ethernet descriptor there, but we can't
- * rely on the Ethernet address it provides since not all vendors
- * bother to make it unique. Likewise there's no point in tracking
- * of the CDC event notifications.
- */
- return usbnet_get_endpoints(dev, intf);
-
-bad_desc:
- dev_info(&dev->udev->dev, "unsupported MDLM descriptors\n");
- return -ENODEV;
-}
-
-static const struct driver_info bogus_mdlm_info = {
- .description = "pseudo-MDLM (BLAN) device",
- .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z,
- .check_connect = always_connected,
- .tx_fixup = zaurus_tx_fixup,
- .bind = blan_mdlm_bind,
-};
-
-static const struct usb_device_id products [] = {
-#define ZAURUS_MASTER_INTERFACE \
- .bInterfaceClass = USB_CLASS_COMM, \
- .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \
- .bInterfaceProtocol = USB_CDC_PROTO_NONE
-
-/* SA-1100 based Sharp Zaurus ("collie"), or compatible. */
-{
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x8004,
- ZAURUS_MASTER_INTERFACE,
- .driver_info = ZAURUS_STRONGARM_INFO,
-},
-
-/* PXA-2xx based models are also lying-about-cdc. If you add any
- * more devices that claim to be CDC Ethernet, make sure they get
- * added to the blacklist in cdc_ether too.
- *
- * NOTE: OpenZaurus versions with 2.6 kernels won't use these entries,
- * unlike the older ones with 2.4 "embedix" kernels.
- */
-{
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x8005, /* A-300 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = ZAURUS_PXA_INFO,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x8006, /* B-500/SL-5600 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = ZAURUS_PXA_INFO,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x8007, /* C-700 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = ZAURUS_PXA_INFO,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x9031, /* C-750 C-760 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = ZAURUS_PXA_INFO,
-}, {
- /* C-750/C-760/C-860/SL-C3000 PDA in MDLM mode */
- USB_DEVICE_AND_INTERFACE_INFO(0x04DD, 0x9031, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &bogus_mdlm_info,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x9032, /* SL-6000 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = ZAURUS_PXA_INFO,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- /* reported with some C860 units */
- .idProduct = 0x9050, /* C-860 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = ZAURUS_PXA_INFO,
-},
-{
- /* Motorola Rokr E6 */
- USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6027, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &bogus_mdlm_info,
-}, {
- /* Motorola MOTOMAGX phones */
- USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6425, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &bogus_mdlm_info,
-},
-
-/* Olympus has some models with a Zaurus-compatible option.
- * R-1000 uses a FreeScale i.MXL cpu (ARMv4T)
- */
-{
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x07B4,
- .idProduct = 0x0F02, /* R-1000 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = OLYMPUS_MXL_INFO,
-},
-
-/* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */
-{
- USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &bogus_mdlm_info,
-},
- { }, // END
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver zaurus_driver = {
- .name = "zaurus",
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
-};
-
-module_usb_driver(zaurus_driver);
-
-MODULE_AUTHOR("Pavel Machek, David Brownell");
-MODULE_DESCRIPTION("Sharp Zaurus PDA, and compatible products");
-MODULE_LICENSE("GPL");