Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk@flint.arm.linux.org.uk>2002-02-20 20:00:54 +0000
committerRussell King <rmk@flint.arm.linux.org.uk>2002-02-20 20:00:54 +0000
commit8847b8e61c030fded3e86cec0a3da3bea801f0df (patch)
treeb166eaf0071caf1ba357eb6ac00dc1c061352423
parent8a7f3127b977a3006b14aef983e719264ff9b60d (diff)
parenta814d16fe3abd6e8e5e2413425611833f07485a5 (diff)
Merge flint.arm.linux.org.uk:/usr/src/linux-bk-2.5/linux-2.5
into flint.arm.linux.org.uk:/usr/src/linux-bk-2.5/linux-2.5-rmk
-rw-r--r--Documentation/networking/3c359.txt58
-rw-r--r--Documentation/networking/e1000.txt245
-rw-r--r--MAINTAINERS15
-rw-r--r--drivers/ieee1394/video1394.c20
-rw-r--r--drivers/media/video/bttv-driver.c58
-rw-r--r--drivers/media/video/cpia.c5
-rw-r--r--drivers/media/video/meye.c5
-rw-r--r--drivers/net/Config.help36
-rw-r--r--drivers/net/Config.in1
-rw-r--r--drivers/net/Makefile5
-rw-r--r--drivers/net/e1000/LICENSE69
-rw-r--r--drivers/net/e1000/Makefile16
-rw-r--r--drivers/net/e1000/e1000.h233
-rw-r--r--drivers/net/e1000/e1000_ethtool.c377
-rw-r--r--drivers/net/e1000/e1000_mac.c1821
-rw-r--r--drivers/net/e1000/e1000_mac.h1383
-rw-r--r--drivers/net/e1000/e1000_main.c2036
-rw-r--r--drivers/net/e1000/e1000_osdep.h142
-rw-r--r--drivers/net/e1000/e1000_param.c709
-rw-r--r--drivers/net/e1000/e1000_phy.c1485
-rw-r--r--drivers/net/e1000/e1000_phy.h422
-rw-r--r--drivers/net/e1000/e1000_proc.c760
-rw-r--r--drivers/net/tokenring/3c359.c1816
-rw-r--r--drivers/net/tokenring/3c359.h290
-rw-r--r--drivers/net/tokenring/3c359_microcode.h1585
-rw-r--r--drivers/net/tokenring/Config.help18
-rw-r--r--drivers/net/tokenring/Config.in1
-rw-r--r--drivers/net/tokenring/Makefile1
-rw-r--r--drivers/net/via-rhine.c3
-rw-r--r--drivers/usb/ov511.c5
-rw-r--r--drivers/usb/pwc-if.c5
-rw-r--r--drivers/usb/se401.c5
-rw-r--r--drivers/usb/usbvideo.c5
-rw-r--r--include/linux/mm.h2
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--mm/memory.c3
36 files changed, 13577 insertions, 64 deletions
diff --git a/Documentation/networking/3c359.txt b/Documentation/networking/3c359.txt
new file mode 100644
index 000000000000..2babc3628acc
--- /dev/null
+++ b/Documentation/networking/3c359.txt
@@ -0,0 +1,58 @@
+
+3COM PCI TOKEN LINK VELOCITY XL TOKEN RING CARDS README
+
+Release 0.9.0 - Release
+ Jul 17th 2000 Mike Phillips
+
+ 1.2.0 - Final
+ Feb 17th 2002 Mike Phillips
+ Updated for submission to the 2.4.x kernel.
+
+Thanks:
+ Terry Murphy from 3Com for tech docs and support,
+ Adam D. Ligas for testing the driver.
+
+Note:
+ This driver will NOT work with the 3C339 Token Ring cards, you need
+to use the tms380 driver instead.
+
+Options:
+
+The driver accepts three options: ringspeed, pkt_buf_sz and message_level.
+
+These options can be specified differently for each card found.
+
+ringspeed: Has one of three settings 0 (default), 4 or 16. 0 will
+make the card autosense the ringspeed and join at the appropriate speed,
+this will be the default option for most people. 4 or 16 allow you to
+explicitly force the card to operate at a certain speed. The card will fail
+if you try to insert it at the wrong speed. (Although some hubs will allow
+this so be *very* careful). The main purpose for explicitly setting the ring
+speed is for when the card is first on the ring. In autosense mode, if the card
+cannot detect any active monitors on the ring it will open at the same speed as
+its last opening. This can be hazardous if this speed does not match the speed
+you want the ring to operate at.
+
+pkt_buf_sz: This is this initial receive buffer allocation size. This will
+default to 4096 if no value is entered. You may increase performance of the
+driver by setting this to a value larger than the network packet size, although
+the driver now re-sizes buffers based on MTU settings as well.
+
+message_level: Controls level of messages created by the driver. Defaults to 0:
+which only displays start-up and critical messages. Presently any non-zero
+value will display all soft messages as well. NB This does not turn
+debuging messages on, that must be done by modified the source code.
+
+Variable MTU size:
+
+The driver can handle a MTU size upto either 4500 or 18000 depending upon
+ring speed. The driver also changes the size of the receive buffers as part
+of the mtu re-sizing, so if you set mtu = 18000, you will need to be able
+to allocate 16 * (sk_buff with 18000 buffer size) call it 18500 bytes per ring
+position = 296,000 bytes of memory space, plus of course anything
+necessary for the tx sk_buff's. Remember this is per card, so if you are
+building routers, gateway's etc, you could start to use a lot of memory
+real fast.
+
+2/17/02 Mike Phillips
+
diff --git a/Documentation/networking/e1000.txt b/Documentation/networking/e1000.txt
new file mode 100644
index 000000000000..2ce10f26fcf4
--- /dev/null
+++ b/Documentation/networking/e1000.txt
@@ -0,0 +1,245 @@
+Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters
+===============================================================
+
+February 5, 2002
+
+
+Contents
+========
+
+- In This Release
+- Supported Adapters
+- Command Line Parameters
+- Speed and Duplex Configuration
+- Known Issues
+- Support
+
+
+In This Release
+===============
+
+This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family
+of Adapters, version 4.2.x.
+This driver includes support for Itanium(TM)-based systems.
+
+This release version includes the following:
+
+ - support for the ethtool 1.4 interface. A third-party application can use
+ the ethtool interface to get and set driver parameters.
+
+ - the zero copy feature. Zero copy provides faster information throughput.
+ By default, this feature is enabled if using a kernel that supports it.
+ Zero copy is not supported on the original PWLA8490 (plain) adapter.
+
+
+Supported Adapters
+==================
+
+The following Intel network adapters are compatible with the drivers in this
+release:
+
+ Controller Adapter Name Board IDs
+ ---------- ------------ ---------
+
+ 82542 PRO/1000 Gigabit Server Adapter 700262-xxx, 717037-xxx
+
+ 82543 PRO/1000 F Server Adapter 738640-xxx, A38888-xxx,
+ A06512-xxx
+
+ 82543 PRO/1000 T Server Adapter A19845-xxx, A33948-xxx
+
+ 82544 PRO/1000 XT Server Adapter A51580-xxx
+
+ 82544 PRO/1000 XF Server Adapter A50484-xxx
+
+ 82544 PRO/1000 T Desktop Adapter A62947-xxx
+
+
+To verify your Intel adapter is supported, find the board ID number on the
+adapter. Look for a label that has a barcode and a number in the format of
+123456-001 (six digits hyphen three digits). Match this to the list of
+numbers above.
+
+For more information on how to identify your adapter, go to the Adapter &
+Driver ID Guide at:
+
+ http://support.intel.com/support/network/adapter/pro100/21397.htm
+
+For the latest Intel network drivers for Linux, go to:
+
+ http://appsr.intel.com/scripts-df/support_intel.asp
+
+
+Command Line Parameters
+=======================
+
+If the driver is built as a module, the following parameters are used by
+entering them on the command line with the modprobe or insmod command.
+For example, with two PRO/1000 PCI adapters, entering:
+
+ insmod e1000 TxDescriptors=80,128
+
+loads the e1000 driver with 80 TX resources for the first adapter and 128 TX
+resources for the second adapter.
+
+For more information about the AutoNeg, Duplex, and Speed parameters, see the
+"Speed and Duplex Configuration" section in this document.
+
+
+AutoNeg (Intel PRO/1000 T and PRO/1000 XT server adapters only)
+Valid Range: 0-0x0F, 0x20-0x2F
+Default Value: 0x2F
+ This parameter is a bit mask that specifies which speed and duplex
+ settings the board advertises. When this parameter is used, the Speed and
+ Duplex parameters must not be specified.
+
+Duplex (Intel PRO/1000 T and PRO/1000 XT server adapters only)
+Valid Range: 0-2 (0=auto-negotiate, 1=half, 2=full)
+Default Value: 0
+ Defines the direction in which data is allowed to flow. Can by either one
+ or two-directional. If both Duplex and the link partner are set to auto-
+ negotiate, the board auto-detects the correct duplex. If the link partner
+ is forced (either full or half), Duplex defaults to half-duplex.
+
+FlowControl
+Valid Range: 0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx)
+Default: Read flow control settings from the EEPROM
+ This parameter controls the automatic generation(Tx) and response(Rx) to
+ Ethernet PAUSE frames.
+
+RxDescriptors
+Valid Range: 80-256 for 82542 and 82543-based adapters
+ 80-4096 for 82544-based adapters
+Default Value: 256
+ This value is the number of receive descriptors allocated by the driver.
+ Increasing this value allows the driver to buffer more incoming packets.
+ Each descriptor is 16 bytes. A receive buffer is also allocated for each
+ descriptor and can be either 2048, 4096, 8192, or 16384 bytes, depending
+ on the MTU setting.
+
+RxIntDelay
+Valid Range: 0-65535 (0=off)
+Default Value: 64
+ This value delays the generation of receive interrupts in units of 1.024
+ microseconds. Receive interrupt reduction can improve CPU efficiency if
+ properly tuned for specific network traffic. Increasing this value adds
+ extra latency to frame reception and can end up decreasing the throughput
+ of TCP traffic. If the system is reporting dropped receives, this value
+ may be set too high, causing the driver to run out of available receive
+ descriptors.
+
+Speed (Intel PRO/1000 T and PRO/1000 XT server adapters only)
+Valid Settings: 0, 10, 100, 1000
+Default Value: 0 (auto-negotiate at all supported speeds)
+ Speed forces the line speed to the specified value in megabits per second
+ (Mbps). If this parameter is not specified or is set to 0 and the link
+ partner is set to auto-negotiate, the board will auto-detect the correct
+ speed. Duplex must also be set when Speed is set to either 10 or 100.
+
+TxDescriptors
+Valid Range: 80-256 for 82542 and 82543-based adapters
+ 80-4096 for 82544-based adapters
+Default Value: 256
+ This value is the number of transmit descriptors allocated by the driver.
+ Increasing this value allows the driver to queue more transmits. Each
+ descriptor is 16 bytes.
+
+TxIntDelay
+Valid Range: 0-65535 (0=off)
+Default Value: 64
+ This value delays the generation of transmit interrupts in units of 1.024
+ microseconds. Transmit interrupt reduction can improve CPU efficiency if
+ properly tuned for specific network traffic. If the system is reporting
+ dropped transmits, this value may be set too high causing the driver to
+ run out of available transmit descriptors.
+
+XsumRX (not available on the PRO/1000 Gigabit Server Adapter)
+Valid Range: 0-1
+Default Value: 1
+ A value of '1' indicates that the driver should enable IP checksum
+ offload for received packets (both UDP and TCP) to the adapter hardware.
+
+
+Speed and Duplex Configuration
+==============================
+
+Three keywords are used to control the speed and duplex configuration of the
+PRO/1000 T and PRO/1000 XT server adapters. These keywords are Speed, Duplex,
+and AutoNeg.
+
+If the board uses a fiber interface, these keywords are ignored, and the
+fiber interface board only links at 1000 Mbps full-duplex.
+
+For copper-based boards, the keywords interact as follows:
+
+ The default operation is auto-negotiate. The board advertises all supported
+ speed and duplex combinations, and it links at the highest common speed and
+ duplex mode IF the link partner is set to auto-negotiate.
+
+ If Speed = 1000, limited auto-negotiation is enabled and only 1000 Mbps is
+ advertised (The 1000BaseT spec requires auto-negotiation.)
+
+ If Speed = 10 or 100, then both Speed and Duplex must be set. Auto-
+ negotiation is disabled, and the AutoNeg parameter is ignored. Partner MUST
+ also be forced.
+
+The AutoNeg parameter is used when more control is required over the auto-
+negotiation process. When this parameter is used, Speed and Duplex must not
+be specified. This parameter is a bitmap that specifies which speed and
+duplex settings are advertised to the link partner.
+
+Bit 7 6 5 4 3 2 1 0
+Speed (Mbps) N/A N/A 1000 N/A 100 100 10 10
+Duplex Full Full Half Full Half
+
+Note that setting AutoNeg does not guarantee that the board will link at the
+highest specified speed or duplex mode, but the board will link at the
+highest possible speed/duplex of the link partner IF the link partner is also
+set to auto-negotiate. If the link partner is forced speed/duplex, the
+adapter MUST be forced to the same speed/duplex.
+
+
+Known Issues
+============
+
+ Driver Hangs Under Heavy Traffic Loads
+ --------------------------------------
+
+ Intel is aware that previously released e1000 drivers may hang under very
+ specific types of heavy traffic loads. This version includes a workaround
+ that resets the adapter automatically if a hang condition is detected. This
+ workaround ensures network traffic flow is not affected when a hang occurs.
+
+ Jumbo Frames System Requirement
+ -------------------------------
+
+ Memory allocation failures have been observed on Linux systems with 64 MB
+ of RAM or less that are running Jumbo Frames. If you are using Jumbo
+ Frames, your system may require more than the advertised minimum
+ requirement of 64 MB of system memory.
+
+
+Support
+=======
+
+For general information and support, go to the Intel support website at:
+
+ http://support.intel.com
+
+If an issue is identified with the released source code on the supported
+kernel with a supported adapter, email the specific information related to
+the issue to linux.nics@intel.com.
+
+
+License
+=======
+
+This software program is released under the terms of a license agreement
+between you ('Licensee') and Intel. Do not use or load this software or any
+associated materials (collectively, the 'Software') until you have carefully
+read the full terms and conditions of the LICENSE located in this software
+package. By loading or using the Software, you agree to the terms of this
+Agreement. If you do not agree with the terms of this Agreement, do not
+install or use the Software.
+
+* Other names and brands may be claimed as the property of others.
diff --git a/MAINTAINERS b/MAINTAINERS
index fe66daa2de63..e902b40ab377 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -69,6 +69,14 @@ S: Status, one of the following:
it has been replaced by a better system and you
should be using that.
+3C359 NETWORK DRIVER
+P: Mike Phillips
+M: mikep@linuxtr.net
+L: linux-net@vger.rutgers.edu
+L: linux-tr@linuxtr.net
+W: http://www.linuxtr.net
+S: Maintained
+
3C501 NETWORK DRIVER
P: Alan Cox
M: alan@the.3c501.cabal.tm
@@ -777,6 +785,13 @@ P: Tigran Aivazian
M: tigran@veritas.com
S: Maintained
+INTEL PRO/1000 GIGABIT ETHERNET SUPPORT
+P: Chris Leech
+M: christopher.leech@intel.com
+P: Scott Feldman
+M: scott.feldman@intel.com
+S: Supported
+
INTERMEZZO FILE SYSTEM
P: Peter J. Braam
M: braam@clusterfs.com
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index adf706a9dd93..58b8afbf1e21 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -173,22 +173,11 @@ static struct hpsb_highlevel *hl_handle = NULL;
* defined way to get at the kernel page tables.
*/
-static inline unsigned long uvirt_to_bus(unsigned long adr)
-{
- unsigned long kva, ret;
-
- kva = page_address(vmalloc_to_page(adr));
- ret = virt_to_bus((void *)kva);
- MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
- return ret;
-}
-
static inline unsigned long kvirt_to_bus(unsigned long adr)
{
- unsigned long va, kva, ret;
+ unsigned long kva, ret;
- va = VMALLOC_VMADDR(adr);
- kva = page_address(vmalloc_to_page(va));
+ kva = page_address(vmalloc_to_page((void *)adr));
ret = virt_to_bus((void *)kva);
MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
return ret;
@@ -200,10 +189,9 @@ static inline unsigned long kvirt_to_bus(unsigned long adr)
*/
static inline unsigned long kvirt_to_pa(unsigned long adr)
{
- unsigned long va, kva, ret;
+ unsigned long kva, ret;
- va = VMALLOC_VMADDR(adr);
- kva = page_address(vmalloc_to_page(va));
+ kva = page_address(vmalloc_to_page((void *)adr));
ret = __pa(kva);
MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
return ret;
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 0aa1f4faf44f..44641b9ce187 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -141,24 +141,33 @@ __setup("bttv.radio=", p_radio);
* defined way to get at the kernel page tables.
*/
-static inline unsigned long uvirt_to_bus(unsigned long adr)
-{
- unsigned long kva, ret;
- kva = page_address(vmalloc_to_page(adr));
- ret = virt_to_bus((void *)kva);
- MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
- return ret;
+/*
+ * Take a vmalloc address, and turn it into
+ * the aliased kernel virtual address..
+ *
+ * CAREFUL! Anybody who does this gets to sit
+ * in their own cr*p when it comes to virtual
+ * cache aliases. It's _your_ problem.
+ *
+ * Also, note how it only works within one page.
+ * If you're doing page-crossing stuff, you're on
+ * your own.
+ *
+ * THIS IS BROKEN CODE! You shouldn't do things
+ * like this.
+ */
+static inline void *vmalloc_to_virt(void *addr)
+{
+ struct page *page = vmalloc_to_page(addr);
+ return page_address(page) + (~PAGE_MASK & (unsigned long)addr);
}
-static inline unsigned long kvirt_to_bus(unsigned long adr)
+static inline unsigned long kvirt_to_bus(unsigned long addr)
{
- unsigned long va, kva, ret;
-
- va = VMALLOC_VMADDR(adr);
- kva = page_address(vmalloc_to_page(va));
- ret = virt_to_bus((void *)kva);
- MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
+ unsigned long ret;
+ ret = virt_to_bus(vmalloc_to_virt((void *)addr));
+ MDEBUG(printk("kv2b(%lx-->%lx)", addr, ret));
return ret;
}
@@ -166,21 +175,18 @@ static inline unsigned long kvirt_to_bus(unsigned long adr)
* This is used when initializing the contents of the
* area and marking the pages as reserved.
*/
-static inline unsigned long kvirt_to_pa(unsigned long adr)
+static inline unsigned long kvirt_to_pa(unsigned long addr)
{
- unsigned long va, kva, ret;
-
- va = VMALLOC_VMADDR(adr);
- kva = page_address(vmalloc_to_page(va));
- ret = __pa(kva);
- MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
+ unsigned long ret;
+ ret = virt_to_phys(vmalloc_to_virt((void *)addr));
+ MDEBUG(printk("kv2pa(%lx-->%lx)", addr, ret));
return ret;
}
static void * rvmalloc(signed long size)
{
void * mem;
- unsigned long adr, page;
+ unsigned long adr;
mem=vmalloc_32(size);
if (NULL == mem)
@@ -191,8 +197,7 @@ static void * rvmalloc(signed long size)
adr=(unsigned long) mem;
while (size > 0)
{
- page = kvirt_to_pa(adr);
- mem_map_reserve(virt_to_page(__va(page)));
+ mem_map_reserve(vmalloc_to_page((void *)adr));
adr+=PAGE_SIZE;
size-=PAGE_SIZE;
}
@@ -202,15 +207,14 @@ static void * rvmalloc(signed long size)
static void rvfree(void * mem, signed long size)
{
- unsigned long adr, page;
+ unsigned long adr;
if (mem)
{
adr=(unsigned long) mem;
while (size > 0)
{
- page = kvirt_to_pa(adr);
- mem_map_unreserve(virt_to_page(__va(page)));
+ mem_map_unreserve(vmalloc_to_page((void *)adr));
adr+=PAGE_SIZE;
size-=PAGE_SIZE;
}
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 55a472c4d98d..4b066463f253 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -186,10 +186,9 @@ static void reset_camera_struct(struct cam_data *cam);
*/
static inline unsigned long kvirt_to_pa(unsigned long adr)
{
- unsigned long va, kva, ret;
+ unsigned long kva, ret;
- va = VMALLOC_VMADDR(adr);
- kva = page_address(vmalloc_to_page(va));
+ kva = page_address(vmalloc_to_page((void *)adr));
ret = __pa(kva);
return ret;
}
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index a7e503e4ddd7..62f649d7f210 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -123,10 +123,9 @@ static inline int meye_emptyq(struct meye_queue *queue, int *elem) {
* area and marking the pages as reserved.
*/
static inline unsigned long kvirt_to_pa(unsigned long adr) {
- unsigned long va, kva, ret;
+ unsigned long kva, ret;
- va = VMALLOC_VMADDR(adr);
- kva = page_address(vmalloc_to_page(va));
+ kva = page_address(vmalloc_to_page((void *) adr));
ret = __pa(kva);
MDEBUG(printk("kv2pa(%lx-->%lx)\n", adr, ret));
return ret;
diff --git a/drivers/net/Config.help b/drivers/net/Config.help
index fe7ba7ec616a..e4f99625536f 100644
--- a/drivers/net/Config.help
+++ b/drivers/net/Config.help
@@ -806,6 +806,42 @@ CONFIG_DL2K
say M here and read <file:Documentation/modules.txt>. This is
recommended. The module will be called dl2k.o.
+CONFIG_E1000
+ This driver supports Intel(R) PRO/1000 gigabit ethernet family of
+ adapters, which includes:
+
+ Controller Adapter Name Board IDs
+ ---------- ------------ ---------
+ 82542 PRO/1000 Gigabit Server Adapter 700262-xxx,
+ 717037-xxx
+ 82543 PRO/1000 F Server Adapter 738640-xxx,
+ A38888-xxx,
+ A06512-xxx
+ 82543 PRO/1000 T Server Adapter A19845-xxx,
+ A33948-xxx
+ 82544 PRO/1000 XT Server Adapter A51580-xxx
+ 82544 PRO/1000 XF Server Adapter A50484-xxx
+ 82544 PRO/1000 T Desktop Adapter A62947-xxx
+
+ For more information on how to identify your adapter, go to the
+ Adapter & Driver ID Guide at:
+
+ <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+ For general information and support, go to the Intel support
+ website at:
+
+ <http://support.intel.com>
+
+ More specific information on configuring the driver is in
+ <file:Documentation/networking/e1000.txt>.
+
+ This driver is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want).
+ The module will be called e1000.o. If you want to compile it as a
+ module, say M here and read <file:Documentation/modules.txt> as well
+ as <file:Documentation/networking/net-modules.txt>.
+
CONFIG_LANCE
If you have a network (Ethernet) card of this type, say Y and read
the Ethernet-HOWTO, available from
diff --git a/drivers/net/Config.in b/drivers/net/Config.in
index 3209bc3cef17..a752f38279b1 100644
--- a/drivers/net/Config.in
+++ b/drivers/net/Config.in
@@ -231,6 +231,7 @@ if [ "$CONFIG_ACENIC" != "n" ]; then
bool ' Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I
fi
dep_tristate 'D-Link DL2000-based Gigabit Ethernet support' CONFIG_DL2K $CONFIG_PCI
+dep_tristate 'Intel(R) PRO/1000 Gigabit Ethernet support' CONFIG_E1000 $CONFIG_PCI
dep_tristate 'MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS $CONFIG_SBUS
dep_tristate 'National Semiconduct DP83820 support' CONFIG_NS83820 $CONFIG_PCI
dep_tristate 'Packet Engines Hamachi GNIC-II support' CONFIG_HAMACHI $CONFIG_PCI
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 46fb29b5a0f2..cda7f30811cf 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -25,6 +25,10 @@ ifeq ($(CONFIG_TULIP),y)
obj-y += tulip/tulip.o
endif
+ifeq ($(CONFIG_E1000),y)
+ obj-y += e1000/e1000.o
+endif
+
ifeq ($(CONFIG_ISDN_PPP),y)
obj-$(CONFIG_ISDN) += slhc.o
endif
@@ -32,6 +36,7 @@ endif
subdir-$(CONFIG_NET_PCMCIA) += pcmcia
subdir-$(CONFIG_NET_WIRELESS) += wireless
subdir-$(CONFIG_TULIP) += tulip
+subdir-$(CONFIG_E1000) += e1000
subdir-$(CONFIG_IRDA) += irda
subdir-$(CONFIG_TR) += tokenring
subdir-$(CONFIG_WAN) += wan
diff --git a/drivers/net/e1000/LICENSE b/drivers/net/e1000/LICENSE
new file mode 100644
index 000000000000..8dbf9d9ee04c
--- /dev/null
+++ b/drivers/net/e1000/LICENSE
@@ -0,0 +1,69 @@
+This software program is available to you under a choice of one of two
+licenses. You may choose to be licensed under either the GNU General Public
+License (GPL) Version 2, June 1991, available at
+http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
+text of which follows:
+
+Recipient has requested a license and Intel Corporation ("Intel") is willing
+to grant a license for the software entitled Linux Base Driver for the
+Intel(R) PRO/1000 Family of Adapters (e1000) (the "Software") being provided
+by Intel Corporation. The following definitions apply to this license:
+
+"Licensed Patents" means patent claims licensable by Intel Corporation which
+are necessarily infringed by the use of sale of the Software alone or when
+combined with the operating system referred to below.
+
+"Recipient" means the party to whom Intel delivers this Software.
+
+"Licensee" means Recipient and those third parties that receive a license to
+any operating system available under the GNU Public License version 2.0 or
+later.
+
+Copyright (c) 1999 - 2002 Intel Corporation.
+All rights reserved.
+
+The license is provided to Recipient and Recipient's Licensees under the
+following terms.
+
+Redistribution and use in source and binary forms of the Software, with or
+without modification, are permitted provided that the following conditions
+are met:
+
+Redistributions of source code of the Software may retain the above
+copyright notice, this list of conditions and the following disclaimer.
+
+Redistributions in binary form of the Software may reproduce the above
+copyright notice, this list of conditions and the following disclaimer in
+the documentation and/or materials provided with the distribution.
+
+Neither the name of Intel Corporation nor the names of its contributors
+shall be used to endorse or promote products derived from this Software
+without specific prior written permission.
+
+Intel hereby grants Recipient and Licensees a non-exclusive, worldwide,
+royalty-free patent license under Licensed Patents to make, use, sell, offer
+to sell, import and otherwise transfer the Software, if any, in source code
+and object code form. This license shall include changes to the Software
+that are error corrections or other minor changes to the Software that do
+not add functionality or features when the Software is incorporated in any
+version of an operating system that has been distributed under the GNU
+General Public License 2.0 or later. This patent license shall apply to the
+combination of the Software and any operating system licensed under the GNU
+Public License version 2.0 or later if, at the time Intel provides the
+Software to Recipient, such addition of the Software to the then publicly
+available versions of such operating systems available under the GNU Public
+License version 2.0 or later (whether in gold, beta or alpha form) causes
+such combination to be covered by the Licensed Patents. The patent license
+shall not apply to any other combinations which include the Software. NO
+hardware per se is licensed hereunder.
+
+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 MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR IT CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ANY LOSS OF USE; DATA, OR PROFITS; OR BUSINESS INTERUPTION) 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.
diff --git a/drivers/net/e1000/Makefile b/drivers/net/e1000/Makefile
new file mode 100644
index 000000000000..6fc1468d012b
--- /dev/null
+++ b/drivers/net/e1000/Makefile
@@ -0,0 +1,16 @@
+#
+# Makefile for the Intel(R) PRO/1000 ethernet driver
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+O_TARGET := e1000.o
+
+obj-y := e1000_main.o e1000_mac.o e1000_phy.o \
+ e1000_ethtool.o e1000_param.o e1000_proc.o
+obj-m := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
new file mode 100644
index 000000000000..3bbace7feebe
--- /dev/null
+++ b/drivers/net/e1000/e1000.h
@@ -0,0 +1,233 @@
+/*******************************************************************************
+
+ This software program is available to you under a choice of one of two
+ licenses. You may choose to be licensed under either the GNU General Public
+ License (GPL) Version 2, June 1991, available at
+ http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
+ text of which follows:
+
+ Recipient has requested a license and Intel Corporation ("Intel") is willing
+ to grant a license for the software entitled Linux Base Driver for the
+ Intel(R) PRO/1000 Family of Adapters (e1000) (the "Software") being provided
+ by Intel Corporation. The following definitions apply to this license:
+
+ "Licensed Patents" means patent claims licensable by Intel Corporation which
+ are necessarily infringed by the use of sale of the Software alone or when
+ combined with the operating system referred to below.
+
+ "Recipient" means the party to whom Intel delivers this Software.
+
+ "Licensee" means Recipient and those third parties that receive a license to
+ any operating system available under the GNU Public License version 2.0 or
+ later.
+
+ Copyright (c) 1999 - 2002 Intel Corporation.
+ All rights reserved.
+
+ The license is provided to Recipient and Recipient's Licensees under the
+ following terms.
+
+ Redistribution and use in source and binary forms of the Software, with or
+ without modification, are permitted provided that the following conditions
+ are met:
+
+ Redistributions of source code of the Software may retain the above
+ copyright notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form of the Software may reproduce the above
+ copyright notice, this list of conditions and the following disclaimer in
+ the documentation and/or materials provided with the distribution.
+
+ Neither the name of Intel Corporation nor the names of its contributors
+ shall be used to endorse or promote products derived from this Software
+ without specific prior written permission.
+
+ Intel hereby grants Recipient and Licensees a non-exclusive, worldwide,
+ royalty-free patent license under Licensed Patents to make, use, sell, offer
+ to sell, import and otherwise transfer the Software, if any, in source code
+ and object code form. This license shall include changes to the Software
+ that are error corrections or other minor changes to the Software that do
+ not add functionality or features when the Software is incorporated in any
+ version of an operating system that has been distributed under the GNU
+ General Public License 2.0 or later. This patent license shall apply to the
+ combination of the Software and any operating system licensed under the GNU
+ Public License version 2.0 or later if, at the time Intel provides the
+ Software to Recipient, such addition of the Software to the then publicly
+ available versions of such operating systems available under the GNU Public
+ License version 2.0 or later (whether in gold, beta or alpha form) causes
+ such combination to be covered by the Licensed Patents. The patent license
+ shall not apply to any other combinations which include the Software. NO
+ hardware per se is licensed hereunder.
+
+ 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 MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR IT CONTRIBUTORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ ANY LOSS OF USE; DATA, OR PROFITS; OR BUSINESS INTERUPTION) 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.
+
+*******************************************************************************/
+
+
+/* Linux PRO/1000 Ethernet Driver main header file */
+
+#ifndef _E1000_H_
+#define _E1000_H_
+
+#include <linux/stddef.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+#include <linux/pagemap.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <linux/capability.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include <net/pkt_sched.h>
+#include <linux/list.h>
+#include <asm/uaccess.h>
+
+struct e1000_adapter;
+
+#include "e1000_mac.h"
+#include "e1000_phy.h"
+
+#define BAR_0 0
+
+/* Advertise that we can DMA from any address location */
+#define E1000_DMA_MASK (~0x0UL)
+
+#if DBG
+#define E1000_DBG(args...) printk(KERN_DEBUG "e1000: " args)
+#else
+#define E1000_DBG(args...)
+#endif
+
+#define E1000_ERR(args...) printk(KERN_ERR "e1000: " args)
+
+#ifdef CONFIG_PPC
+#define E1000_MAX_INTR 1
+#else
+#define E1000_MAX_INTR 10
+#endif
+
+/* Supported Rx Buffer Sizes */
+#define E1000_RXBUFFER_2048 2048
+#define E1000_RXBUFFER_4096 4096
+#define E1000_RXBUFFER_8192 8192
+#define E1000_RXBUFFER_16384 16384
+
+/* How many Tx Descriptors do we need to call netif_wake_queue ? */
+#define E1000_TX_QUEUE_WAKE 16
+
+#define E1000_JUMBO_PBA 0x00000028
+#define E1000_DEFAULT_PBA 0x00000030
+
+/* only works for sizes that are powers of 2 */
+#define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
+
+/* wrapper around a pointer to a socket buffer,
+ * so a DMA handle can be stored along with the buffer */
+struct e1000_buffer {
+ struct sk_buff *skb;
+ uint64_t dma;
+ unsigned long length;
+};
+
+struct e1000_desc_ring {
+ /* pointer to the descriptor ring memory */
+ void *desc;
+ /* physical address of the descriptor ring */
+ dma_addr_t dma;
+ /* length of descriptor ring in bytes */
+ unsigned int size;
+ /* number of descriptors in the ring */
+ unsigned int count;
+ /* (atomic) number of desc with no buffer */
+ atomic_t unused;
+ /* number of desc with no buffer */
+ unsigned int unused_count;
+ /* next descriptor to associate a buffer with */
+ unsigned int next_to_use;
+ /* next descriptor to check for DD status bit */
+ unsigned int next_to_clean;
+ /* array of buffer information structs */
+ struct e1000_buffer *buffer_info;
+};
+
+#define E1000_RX_DESC(ring, i) \
+ (&(((struct e1000_rx_desc *)((ring).desc))[i]))
+
+#define E1000_TX_DESC(ring, i) \
+ (&(((struct e1000_tx_desc *)((ring).desc))[i]))
+
+#define E1000_CONTEXT_DESC(ring, i) \
+ (&(((struct e1000_context_desc *)((ring).desc))[i]))
+
+/* board specific private data structure */
+
+struct e1000_adapter {
+ struct timer_list watchdog_timer;
+ struct timer_list phy_info_timer;
+#ifdef CONFIG_PROC_FS
+ struct list_head proc_list_head;
+#endif
+ char *id_string;
+ uint32_t bd_number;
+ uint32_t rx_buffer_len;
+ uint32_t part_num;
+ uint32_t wol;
+ uint16_t link_speed;
+ uint16_t link_duplex;
+ spinlock_t stats_lock;
+ atomic_t irq_sem;
+ boolean_t rx_csum;
+
+ /* TX */
+ struct e1000_desc_ring tx_ring;
+ unsigned long trans_finish;
+ uint32_t tx_int_delay;
+ uint32_t txd_cmd;
+
+ /* RX */
+ struct e1000_desc_ring rx_ring;
+ uint64_t hw_csum_err;
+ uint64_t hw_csum_good;
+ uint32_t rx_int_delay;
+
+ /* OS defined structs */
+ struct net_device *netdev;
+ struct pci_dev *pdev;
+ struct net_device_stats net_stats;
+
+ /* structs defined in e1000_mac.h or e1000_phy.h */
+ struct e1000_shared_adapter shared;
+ struct e1000_shared_stats stats;
+ struct e1000_phy_info phy_info;
+ struct e1000_phy_stats phy_stats;
+};
+
+#endif /* _E1000_H_ */
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
new file mode 100644
index 000000000000..2d609aed890f
--- /dev/null
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -0,0 +1,377 @@
+/*******************************************************************************
+
+ This software program is available to you under a choice of one of two
+ licenses. You may choose to be licensed under either the GNU General Public
+ License (GPL) Version 2, June 1991, available at
+ http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
+ text of which follows:
+
+ Recipient has requested a license and Intel Corporation ("Intel") is willing
+ to grant a license for the software entitled Linux Base Driver for the
+ Intel(R) PRO/1000 Family of Adapters (e1000) (the "Software") being provided
+ by Intel Corporation. The following definitions apply to this license:
+
+ "Licensed Patents" means patent claims licensable by Intel Corporation which
+ are necessarily infringed by the use of sale of the Software alone or when
+ combined with the operating system referred to below.
+
+ "Recipient" means the party to whom Intel delivers this Software.
+
+ "Licensee" means Recipient and those third parties that receive a license to
+ any operating system available under the GNU Public License version 2.0 or
+ later.
+
+ Copyright (c) 1999 - 2002 Intel Corporation.
+ All rights reserved.
+
+ The license is provided to Recipient and Recipient's Licensees under the
+ following terms.
+
+ Redistribution and use in source and binary forms of the Software, with or
+ without modification, are permitted provided that the following conditions
+ are met:
+
+ Redistributions of source code of the Software may retain the above
+ copyright notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form of the Software may reproduce the above
+ copyright notice, this list of conditions and the following disclaimer in
+ the documentation and/or materials provided with the distribution.
+
+ Neither the name of Intel Corporation nor the names of its contributors
+ shall be used to endorse or promote products derived from this Software
+ without specific prior written permission.
+
+ Intel hereby grants Recipient and Licensees a non-exclusive, worldwide,
+ royalty-free patent license under Licensed Patents to make, use, sell, offer
+ to sell, import and otherwise transfer the Software, if any, in source code
+ and object code form. This license shall include changes to the Software
+ that are error corrections or other minor changes to the Software that do
+ not add functionality or features when the Software is incorporated in any
+ version of an operating system that has been distributed under the GNU
+ General Public License 2.0 or later. This patent license shall apply to the
+ combination of the Software and any operating system licensed under the GNU
+ Public License version 2.0 or later if, at the time Intel provides the
+ Software to Recipient, such addition of the Software to the then publicly
+ available versions of such operating systems available under the GNU Public
+ License version 2.0 or later (whether in gold, beta or alpha form) causes
+ such combination to be covered by the Licensed Patents. The patent license
+ shall not apply to any other combinations which include the Software. NO
+ hardware per se is licensed hereunder.
+
+ 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 MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR IT CONTRIBUTORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ ANY LOSS OF USE; DATA, OR PROFITS; OR BUSINESS INTERUPTION) 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.
+
+*******************************************************************************/
+
+/* ethtool support for e1000 */
+
+#include "e1000.h"
+
+#include <linux/ethtool.h>
+#include <asm/uaccess.h>
+
+extern char e1000_driver_name[];
+extern char e1000_driver_version[];
+
+extern int e1000_up(struct e1000_adapter *adapter);
+extern void e1000_down(struct e1000_adapter *adapter);
+extern void e1000_enable_WOL(struct e1000_adapter *adapter);
+
+static void
+e1000_ethtool_gset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
+{
+ struct e1000_shared_adapter *shared = &adapter->shared;
+
+ if(shared->media_type == e1000_media_type_copper) {
+
+ ecmd->supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full|
+ SUPPORTED_Autoneg |
+ SUPPORTED_TP);
+
+ ecmd->advertising = ADVERTISED_TP;
+
+ if(shared->autoneg == 1) {
+ ecmd->advertising |= ADVERTISED_Autoneg;
+
+ /* the e1000 autoneg seems to match ethtool nicely */
+
+ ecmd->advertising |= shared->autoneg_advertised;
+ }
+
+ ecmd->port = PORT_TP;
+ ecmd->phy_address = shared->phy_addr;
+
+ if(shared->mac_type == e1000_82543)
+ ecmd->transceiver = XCVR_EXTERNAL;
+ else
+ ecmd->transceiver = XCVR_INTERNAL;
+
+ } else {
+ ecmd->supported = (SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg);
+
+ ecmd->advertising = (SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg);
+
+ ecmd->port = PORT_FIBRE;
+
+ ecmd->transceiver = XCVR_EXTERNAL;
+ }
+
+ if(netif_carrier_ok(adapter->netdev)) {
+
+ e1000_get_speed_and_duplex(shared, &adapter->link_speed,
+ &adapter->link_duplex);
+ ecmd->speed = adapter->link_speed;
+
+ /* unfortunatly FULL_DUPLEX != DUPLEX_FULL
+ * and HALF_DUPLEX != DUPLEX_HALF */
+
+ if(adapter->link_duplex == FULL_DUPLEX)
+ ecmd->duplex = DUPLEX_FULL;
+ else
+ ecmd->duplex = DUPLEX_HALF;
+ } else {
+ ecmd->speed = -1;
+ ecmd->duplex = -1;
+ }
+
+ ecmd->autoneg = (shared->autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
+
+ return;
+}
+
+static int
+e1000_ethtool_sset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
+{
+ struct e1000_shared_adapter *shared = &adapter->shared;
+
+ if(ecmd->autoneg == AUTONEG_ENABLE) {
+ shared->autoneg = 1;
+ shared->autoneg_advertised = (ecmd->advertising & 0x002F);
+ } else {
+ shared->autoneg = 0;
+ switch(ecmd->speed + ecmd->duplex) {
+ case SPEED_10 + DUPLEX_HALF:
+ shared->forced_speed_duplex = e1000_10_half;
+ break;
+ case SPEED_10 + DUPLEX_FULL:
+ shared->forced_speed_duplex = e1000_10_full;
+ break;
+ case SPEED_100 + DUPLEX_HALF:
+ shared->forced_speed_duplex = e1000_100_half;
+ break;
+ case SPEED_100 + DUPLEX_FULL:
+ shared->forced_speed_duplex = e1000_100_full;
+ break;
+ case SPEED_1000 + DUPLEX_FULL:
+ shared->autoneg = 1;
+ shared->autoneg_advertised = ADVERTISE_1000_FULL;
+ break;
+ case SPEED_1000 + DUPLEX_HALF: /* not supported */
+ default:
+ return -EINVAL;
+ }
+ }
+
+ /* reset the link */
+
+ e1000_down(adapter);
+ e1000_up(adapter);
+
+ return 0;
+}
+
+static inline int
+e1000_eeprom_size(struct e1000_shared_adapter *shared)
+{
+ return 128;
+}
+
+static void
+e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
+ struct ethtool_drvinfo *drvinfo)
+{
+ strncpy(drvinfo->driver, e1000_driver_name, 32);
+ strncpy(drvinfo->version, e1000_driver_version, 32);
+ strncpy(drvinfo->fw_version, "", 32);
+ strncpy(drvinfo->bus_info, adapter->pdev->slot_name, 32);
+ drvinfo->eedump_len = e1000_eeprom_size(&adapter->shared);
+ return;
+}
+
+static void
+e1000_ethtool_geeprom(struct e1000_adapter *adapter,
+ struct ethtool_eeprom *eeprom, uint16_t *eeprom_buff)
+{
+ struct e1000_shared_adapter *shared = &adapter->shared;
+ int i, max_len;
+
+ eeprom->magic = shared->vendor_id | (shared->device_id << 16);
+
+ max_len = e1000_eeprom_size(shared);
+
+ if ((eeprom->offset + eeprom->len) > max_len)
+ eeprom->len = (max_len - eeprom->offset);
+
+ for(i = 0; i < max_len; i++)
+ eeprom_buff[i] = e1000_read_eeprom(&adapter->shared, i);
+
+ return;
+}
+
+static void
+e1000_ethtool_gwol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
+{
+ struct e1000_shared_adapter *shared = &adapter->shared;
+
+ if(shared->mac_type < e1000_82544) {
+ wol->supported = 0;
+ wol->wolopts = 0;
+ return;
+ }
+
+ wol->supported = WAKE_PHY | WAKE_UCAST |
+ WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
+
+ wol->wolopts = 0;
+ if(adapter->wol & E1000_WUFC_LNKC)
+ wol->wolopts |= WAKE_PHY;
+ if(adapter->wol & E1000_WUFC_EX)
+ wol->wolopts |= WAKE_UCAST;
+ if(adapter->wol & E1000_WUFC_MC)
+ wol->wolopts |= WAKE_MCAST;
+ if(adapter->wol & E1000_WUFC_BC)
+ wol->wolopts |= WAKE_BCAST;
+ if(adapter->wol & E1000_WUFC_MAG)
+ wol->wolopts |= WAKE_MAGIC;
+
+ return;
+}
+
+static int
+e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
+{
+ struct e1000_shared_adapter *shared = &adapter->shared;
+
+ if(shared->mac_type < e1000_82544)
+ return wol->wolopts == 0 ? 0 : -EOPNOTSUPP;
+
+ adapter->wol = 0;
+
+ if(wol->wolopts & WAKE_PHY)
+ adapter->wol |= E1000_WUFC_LNKC;
+ if(wol->wolopts & WAKE_UCAST)
+ adapter->wol |= E1000_WUFC_EX;
+ if(wol->wolopts & WAKE_MCAST)
+ adapter->wol |= E1000_WUFC_MC;
+ if(wol->wolopts & WAKE_BCAST)
+ adapter->wol |= E1000_WUFC_BC;
+ if(wol->wolopts & WAKE_MAGIC)
+ adapter->wol |= E1000_WUFC_MAG;
+
+ e1000_enable_WOL(adapter);
+ return 0;
+}
+
+int
+e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
+{
+ struct e1000_adapter *adapter = netdev->priv;
+ void *addr = ifr->ifr_data;
+ uint32_t cmd;
+
+ if(get_user(cmd, (uint32_t *) addr))
+ return -EFAULT;
+
+ switch(cmd) {
+ case ETHTOOL_GSET: {
+ struct ethtool_cmd ecmd = {ETHTOOL_GSET};
+ e1000_ethtool_gset(adapter, &ecmd);
+ if(copy_to_user(addr, &ecmd, sizeof(ecmd)))
+ return -EFAULT;
+ return 0;
+ }
+ case ETHTOOL_SSET: {
+ struct ethtool_cmd ecmd;
+ if(!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ if(copy_from_user(&ecmd, addr, sizeof(ecmd)))
+ return -EFAULT;
+ return e1000_ethtool_sset(adapter, &ecmd);
+ }
+ case ETHTOOL_GDRVINFO: {
+ struct ethtool_drvinfo drvinfo = {ETHTOOL_GDRVINFO};
+ e1000_ethtool_gdrvinfo(adapter, &drvinfo);
+ if(copy_to_user(addr, &drvinfo, sizeof(drvinfo)))
+ return -EFAULT;
+ return 0;
+ }
+ case ETHTOOL_NWAY_RST: {
+ if(!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ e1000_down(adapter);
+ e1000_up(adapter);
+ return 0;
+ }
+ case ETHTOOL_GLINK: {
+ struct ethtool_value link = {ETHTOOL_GLINK};
+ link.data = netif_carrier_ok(netdev);
+ if(copy_to_user(addr, &link, sizeof(link)))
+ return -EFAULT;
+ return 0;
+ }
+ case ETHTOOL_GWOL: {
+ struct ethtool_wolinfo wol = {ETHTOOL_GWOL};
+ e1000_ethtool_gwol(adapter, &wol);
+ if(copy_to_user(addr, &wol, sizeof(wol)) != 0)
+ return -EFAULT;
+ return 0;
+ }
+ case ETHTOOL_SWOL: {
+ struct ethtool_wolinfo wol;
+ if(!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ if(copy_from_user(&wol, addr, sizeof(wol)) != 0)
+ return -EFAULT;
+ return e1000_ethtool_swol(adapter, &wol);
+ }
+ case ETHTOOL_GEEPROM: {
+ struct ethtool_eeprom eeprom = {ETHTOOL_GEEPROM};
+ uint16_t eeprom_buff[256];
+
+ if(copy_from_user(&eeprom, addr, sizeof(eeprom)))
+ return -EFAULT;
+
+ e1000_ethtool_geeprom(adapter, &eeprom, eeprom_buff);
+
+ if(copy_to_user(addr, &eeprom, sizeof(eeprom)))
+ return -EFAULT;
+
+ addr += offsetof(struct ethtool_eeprom, data);
+
+ if(copy_to_user(addr, eeprom_buff + eeprom.offset, eeprom.len))
+ return -EFAULT;
+ return 0;
+ }
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+
diff --git a/drivers/net/e1000/e1000_mac.c b/drivers/net/e1000/e1000_mac.c
new file mode 100644
index 000000000000..fcbba64b1cb3
--- /dev/null
+++ b/drivers/net/e1000/e1000_mac.c
@@ -0,0 +1,1821 @@
+/*******************************************************************************
+
+ This software program is available to you under a choice of one of two
+ licenses. You may choose to be licensed under either the GNU General Public
+ License (GPL) Version 2, June 1991, available at
+ http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
+ text of which follows:
+
+ Recipient has requested a license and Intel Corporation ("Intel") is willing
+ to grant a license for the software entitled Linux Base Driver for the
+ Intel(R) PRO/1000 Family of Adapters (e1000) (the "Software") being provided
+ by Intel Corporation. The following definitions apply to this license:
+
+ "Licensed Patents" means patent claims licensable by Intel Corporation which
+ are necessarily infringed by the use of sale of the Software alone or when
+ combined with the operating system referred to below.
+
+ "Recipient" means the party to whom Intel delivers this Software.
+
+ "Licensee" means Recipient and those third parties that receive a license to
+ any operating system available under the GNU Public License version 2.0 or
+ later.
+
+ Copyright (c) 1999 - 2002 Intel Corporation.
+ All rights reserved.
+
+ The license is provided to Recipient and Recipient's Licensees under the
+ following terms.
+
+ Redistribution and use in source and binary forms of the Software, with or
+ without modification, are permitted provided that the following conditions
+ are met:
+
+ Redistributions of source code of the Software may retain the above
+ copyright notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form of the Software may reproduce the above
+ copyright notice, this list of conditions and the following disclaimer in
+ the documentation and/or materials provided with the distribution.
+
+ Neither the name of Intel Corporation nor the names of its contributors
+ shall be used to endorse or promote products derived from this Software
+ without specific prior written permission.
+
+ Intel hereby grants Recipient and Licensees a non-exclusive, worldwide,
+ royalty-free patent license under Licensed Patents to make, use, sell, offer
+ to sell, import and otherwise transfer the Software, if any, in source code
+ and object code form. This license shall include changes to the Software
+ that are error corrections or other minor changes to the Software that do
+ not add functionality or features when the Software is incorporated in any
+ version of an operating system that has been distributed under the GNU
+ General Public License 2.0 or later. This patent license shall apply to the
+ combination of the Software and any operating system licensed under the GNU
+ Public License version 2.0 or later if, at the time Intel provides the
+ Software to Recipient, such addition of the Software to the then publicly
+ available versions of such operating systems available under the GNU Public
+ License version 2.0 or later (whether in gold, beta or alpha form) causes
+ such combination to be covered by the Licensed Patents. The patent license
+ shall not apply to any other combinations which include the Software. NO
+ hardware per se is licensed hereunder.
+
+ 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 MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR IT CONTRIBUTORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ ANY LOSS OF USE; DATA, OR PROFITS; OR BUSINESS INTERUPTION) 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.
+
+*******************************************************************************/
+
+/* e1000_mac.c
+ * Shared functions for accessing and configuring the MAC
+ */
+
+#include "e1000_mac.h"
+#include "e1000_phy.h"
+
+/******************************************************************************
+ * Raises the EEPROM's clock input.
+ *
+ * shared - Struct containing variables accessed by shared code
+ * eecd_reg - EECD's current value
+ *****************************************************************************/
+static void
+e1000_raise_clock(struct e1000_shared_adapter *shared,
+ uint32_t *eecd_reg)
+{
+ /* Raise the clock input to the EEPROM (by setting the SK bit), and then
+ * wait 50 microseconds.
+ */
+ *eecd_reg = *eecd_reg | E1000_EECD_SK;
+ E1000_WRITE_REG(shared, EECD, *eecd_reg);
+ usec_delay(50);
+ return;
+}
+
+/******************************************************************************
+ * Lowers the EEPROM's clock input.
+ *
+ * shared - Struct containing variables accessed by shared code
+ * eecd_reg - EECD's current value
+ *****************************************************************************/
+static void
+e1000_lower_clock(struct e1000_shared_adapter *shared,
+ uint32_t *eecd_reg)
+{
+ /* Lower the clock input to the EEPROM (by clearing the SK bit), and then
+ * wait 50 microseconds.
+ */
+ *eecd_reg = *eecd_reg & ~E1000_EECD_SK;
+ E1000_WRITE_REG(shared, EECD, *eecd_reg);
+ usec_delay(50);
+ return;
+}
+
+/******************************************************************************
+ * Shift data bits out to the EEPROM.
+ *
+ * shared - Struct containing variables accessed by shared code
+ * data - data to send to the EEPROM
+ * count - number of bits to shift out
+ *****************************************************************************/
+static void
+e1000_shift_out_bits(struct e1000_shared_adapter *shared,
+ uint16_t data,
+ uint16_t count)
+{
+ uint32_t eecd_reg;
+ uint32_t mask;
+
+ /* We need to shift "count" bits out to the EEPROM. So, value in the
+ * "data" parameter will be shifted out to the EEPROM one bit at a time.
+ * In order to do this, "data" must be broken down into bits.
+ */
+ mask = 0x01 << (count - 1);
+ eecd_reg = E1000_READ_REG(shared, EECD);
+ eecd_reg &= ~(E1000_EECD_DO | E1000_EECD_DI);
+ do {
+ /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
+ * and then raising and then lowering the clock (the SK bit controls
+ * the clock input to the EEPROM). A "0" is shifted out to the EEPROM
+ * by setting "DI" to "0" and then raising and then lowering the clock.
+ */
+ eecd_reg &= ~E1000_EECD_DI;
+
+ if(data & mask)
+ eecd_reg |= E1000_EECD_DI;
+
+ E1000_WRITE_REG(shared, EECD, eecd_reg);
+
+ usec_delay(50);
+
+ e1000_raise_clock(shared, &eecd_reg);
+ e1000_lower_clock(shared, &eecd_reg);
+
+ mask = mask >> 1;
+
+ } while(mask);
+
+ /* We leave the "DI" bit set to "0" when we leave this routine. */
+ eecd_reg &= ~E1000_EECD_DI;
+ E1000_WRITE_REG(shared, EECD, eecd_reg);
+ return;
+}
+
+/******************************************************************************
+ * Shift data bits in from the EEPROM
+ *
+ * shared - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static uint16_t
+e1000_shift_in_bits(struct e1000_shared_adapter *shared)
+{
+ uint32_t eecd_reg;
+ uint32_t i;
+ uint16_t data;
+
+ /* In order to read a register from the EEPROM, we need to shift 16 bits
+ * in from the EEPROM. Bits are "shifted in" by raising the clock input to
+ * the EEPROM (setting the SK bit), and then reading the value of the "DO"
+ * bit. During this "shifting in" process the "DI" bit should always be
+ * clear..
+ */
+
+ eecd_reg = E1000_READ_REG(shared, EECD);
+
+ eecd_reg &= ~(E1000_EECD_DO | E1000_EECD_DI);
+ data = 0;
+
+ for(i = 0; i < 16; i++) {
+ data = data << 1;
+ e1000_raise_clock(shared, &eecd_reg);
+
+ eecd_reg = E1000_READ_REG(shared, EECD);
+
+ eecd_reg &= ~(E1000_EECD_DI);
+ if(eecd_reg & E1000_EECD_DO)
+ data |= 1;
+
+ e1000_lower_clock(shared, &eecd_reg);
+ }
+
+ return data;
+}
+
+/******************************************************************************
+ * Prepares EEPROM for access
+ *
+ * shared - Struct containing variables accessed by shared code
+ *
+ * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
+ * function should be called before issuing a command to the EEPROM.
+ *****************************************************************************/
+static void
+e1000_setup_eeprom(struct e1000_shared_adapter *shared)
+{
+ uint32_t eecd_reg;
+
+ eecd_reg = E1000_READ_REG(shared, EECD);
+
+ /* Clear SK and DI */
+ eecd_reg &= ~(E1000_EECD_SK | E1000_EECD_DI);
+ E1000_WRITE_REG(shared, EECD, eecd_reg);
+
+ /* Set CS */
+ eecd_reg |= E1000_EECD_CS;
+ E1000_WRITE_REG(shared, EECD, eecd_reg);
+ return;
+}
+
+/******************************************************************************
+ * Returns EEPROM to a "standby" state
+ *
+ * shared - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_standby_eeprom(struct e1000_shared_adapter *shared)
+{
+ uint32_t eecd_reg;
+
+ eecd_reg = E1000_READ_REG(shared, EECD);
+
+ /* Deselct EEPROM */
+ eecd_reg &= ~(E1000_EECD_CS | E1000_EECD_SK);
+ E1000_WRITE_REG(shared, EECD, eecd_reg);
+ usec_delay(50);
+
+ /* Clock high */
+ eecd_reg |= E1000_EECD_SK;
+ E1000_WRITE_REG(shared, EECD, eecd_reg);
+ usec_delay(50);
+
+ /* Select EEPROM */
+ eecd_reg |= E1000_EECD_CS;
+ E1000_WRITE_REG(shared, EECD, eecd_reg);
+ usec_delay(50);
+
+ /* Clock low */
+ eecd_reg &= ~E1000_EECD_SK;
+ E1000_WRITE_REG(shared, EECD, eecd_reg);
+ usec_delay(50);
+ return;
+}
+
+
+/******************************************************************************
+ * Forces the MAC's flow control settings.
+ *
+ * shared - Struct containing variables accessed by shared code
+ *
+ * Sets the TFCE and RFCE bits in the device control register to reflect
+ * the adapter settings. TFCE and RFCE need to be explicitly set by
+ * software when a Copper PHY is used because autonegotiation is managed
+ * by the PHY rather than the MAC. Software must also configure these
+ * bits when link is forced on a fiber connection.
+ *****************************************************************************/
+static void
+e1000_force_mac_fc(struct e1000_shared_adapter *shared)
+{
+ uint32_t ctrl_reg;
+
+ DEBUGFUNC("e1000_force_mac_fc");
+
+ /* Get the current configuration of the Device Control Register */
+ ctrl_reg = E1000_READ_REG(shared, CTRL);
+
+ /* Because we didn't get link via the internal auto-negotiation
+ * mechanism (we either forced link or we got link via PHY
+ * auto-neg), we have to manually enable/disable transmit an
+ * receive flow control.
+ *
+ * The "Case" statement below enables/disable flow control
+ * according to the "shared->fc" parameter.
+ *
+ * The possible values of the "fc" parameter are:
+ * 0: Flow control is completely disabled
+ * 1: Rx flow control is enabled (we can receive pause
+ * frames but not send pause frames).
+ * 2: Tx flow control is enabled (we can send pause frames
+ * frames but we do not receive pause frames).
+ * 3: Both Rx and TX flow control (symmetric) is enabled.
+ * other: No other values should be possible at this point.
+ */
+
+ switch (shared->fc) {
+ case e1000_fc_none:
+ ctrl_reg &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
+ break;
+ case e1000_fc_rx_pause:
+ ctrl_reg &= (~E1000_CTRL_TFCE);
+ ctrl_reg |= E1000_CTRL_RFCE;
+ break;
+ case e1000_fc_tx_pause:
+ ctrl_reg &= (~E1000_CTRL_RFCE);
+ ctrl_reg |= E1000_CTRL_TFCE;
+ break;
+ case e1000_fc_full:
+ ctrl_reg |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
+ break;
+ default:
+ DEBUGOUT("Flow control param set incorrectly\n");
+ ASSERT(0);
+ break;
+ }
+
+ /* Disable TX Flow Control for 82542 (rev 2.0) */
+ if(shared->mac_type == e1000_82542_rev2_0)
+ ctrl_reg &= (~E1000_CTRL_TFCE);
+
+
+ E1000_WRITE_REG(shared, CTRL, ctrl_reg);
+ return;
+}
+
+/******************************************************************************
+ * Reset the transmit and receive units; mask and clear all interrupts.
+ *
+ * shared - Struct containing variables accessed by shared code
+ *****************************************************************************/
+void
+e1000_adapter_stop(struct e1000_shared_adapter *shared)
+{
+ uint32_t ctrl_reg;
+ uint32_t ctrl_ext_reg;
+ uint32_t icr_reg;
+ uint16_t pci_cmd_word;
+
+ DEBUGFUNC("e1000_shared_adapter_stop");
+
+ /* If we are stopped or resetting exit gracefully and wait to be
+ * started again before accessing the hardware.
+ */
+ if(shared->adapter_stopped) {
+ DEBUGOUT("Exiting because the adapter is already stopped!!!\n");
+ return;
+ }
+
+ /* Set the Adapter Stopped flag so other driver functions stop
+ * touching the Hardware.
+ */
+ shared->adapter_stopped = TRUE;
+
+ /* For 82542 (rev 2.0), disable MWI before issuing a device reset */
+ if(shared->mac_type == e1000_82542_rev2_0) {
+ if(shared->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {
+ DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
+
+ pci_cmd_word = shared->pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE;
+
+ e1000_write_pci_cfg(shared, PCI_COMMAND_REGISTER, &pci_cmd_word);
+ }
+ }
+
+ /* Clear interrupt mask to stop board from generating interrupts */
+ DEBUGOUT("Masking off all interrupts\n");
+ E1000_WRITE_REG(shared, IMC, 0xffffffff);
+
+ /* Disable the Transmit and Receive units. Then delay to allow
+ * any pending transactions to complete before we hit the MAC with
+ * the global reset.
+ */
+ E1000_WRITE_REG(shared, RCTL, 0);
+ E1000_WRITE_REG(shared, TCTL, E1000_TCTL_PSP);
+
+ /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
+ shared->tbi_compatibility_on = FALSE;
+
+ msec_delay(10);
+
+ /* Issue a global reset to the MAC. This will reset the chip's
+ * transmit, receive, DMA, and link units. It will not effect
+ * the current PCI configuration. The global reset bit is self-
+ * clearing, and should clear within a microsecond.
+ */
+ DEBUGOUT("Issuing a global reset to MAC\n");
+ ctrl_reg = E1000_READ_REG(shared, CTRL);
+ E1000_WRITE_REG(shared, CTRL, (ctrl_reg | E1000_CTRL_RST));
+
+ /* Delay a few ms just to allow the reset to complete */
+ msec_delay(10);
+
+#if DBG
+ /* Make sure the self-clearing global reset bit did self clear */
+ ctrl_reg = E1000_READ_REG(shared, CTRL);
+
+ ASSERT(!(ctrl_reg & E1000_CTRL_RST));
+#endif
+
+ /* Force a reload from the EEPROM */
+ ctrl_ext_reg = E1000_READ_REG(shared, CTRL_EXT);
+ ctrl_ext_reg |= E1000_CTRL_EXT_EE_RST;
+ E1000_WRITE_REG(shared, CTRL_EXT, ctrl_ext_reg);
+ msec_delay(2);
+
+ /* Clear interrupt mask to stop board from generating interrupts */
+ DEBUGOUT("Masking off all interrupts\n");
+ E1000_WRITE_REG(shared, IMC, 0xffffffff);
+
+ /* Clear any pending interrupt events. */
+ icr_reg = E1000_READ_REG(shared, ICR);
+
+ /* If MWI was previously enabled, reenable it. */
+ if(shared->mac_type == e1000_82542_rev2_0) {
+ if(shared->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {
+ e1000_write_pci_cfg(shared,
+ PCI_COMMAND_REGISTER, &shared->pci_cmd_word);
+ }
+ }
+ return;
+}
+
+/******************************************************************************
+ * Performs basic configuration of the adapter.
+ *
+ * shared - Struct containing variables accessed by shared code
+ *
+ * Assumes that the controller has previously been reset and is in a
+ * post-reset uninitialized state. Initializes the receive address registers,
+ * multicast table, and VLAN filter table. Calls routines to setup link
+ * configuration and flow control settings. Clears all on-chip counters. Leaves
+ * the transmit and receive units disabled and uninitialized.
+ *****************************************************************************/
+boolean_t
+e1000_init_hw(struct e1000_shared_adapter *shared)
+{
+ uint32_t status_reg;
+ uint32_t i;
+ uint16_t pci_cmd_word;
+ boolean_t status;
+
+ DEBUGFUNC("e1000_init_hw");
+
+ /* Set the Media Type and exit with error if it is not valid. */
+ if(shared->mac_type != e1000_82543) {
+ /* tbi_compatibility is only valid on 82543 */
+ shared->tbi_compatibility_en = FALSE;
+ }
+
+ if(shared->mac_type >= e1000_82543) {
+ status_reg = E1000_READ_REG(shared, STATUS);
+ if(status_reg & E1000_STATUS_TBIMODE) {
+ shared->media_type = e1000_media_type_fiber;
+ /* tbi_compatibility not valid on fiber */
+ shared->tbi_compatibility_en = FALSE;
+ } else {
+ shared->media_type = e1000_media_type_copper;
+ }
+ } else {
+ /* This is an 82542 (fiber only) */
+ shared->media_type = e1000_media_type_fiber;
+ }
+
+ /* Disabling VLAN filtering. */
+ DEBUGOUT("Initializing the IEEE VLAN\n");
+ E1000_WRITE_REG(shared, VET, 0);
+
+ e1000_clear_vfta(shared);
+
+ /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
+ if(shared->mac_type == e1000_82542_rev2_0) {
+ if(shared->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {
+ DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
+ pci_cmd_word = shared->pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE;
+ e1000_write_pci_cfg(shared, PCI_COMMAND_REGISTER, &pci_cmd_word);
+ }
+ E1000_WRITE_REG(shared, RCTL, E1000_RCTL_RST);
+
+ msec_delay(5);
+ }
+
+ /* Setup the receive address. This involves initializing all of the Receive
+ * Address Registers (RARs 0 - 15).
+ */
+ e1000_init_rx_addrs(shared);
+
+ /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
+ if(shared->mac_type == e1000_82542_rev2_0) {
+ E1000_WRITE_REG(shared, RCTL, 0);
+
+ msec_delay(1);
+
+ if(shared->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {
+ e1000_write_pci_cfg(shared,
+ PCI_COMMAND_REGISTER, &shared->pci_cmd_word);
+ }
+ }
+
+ /* Zero out the Multicast HASH table */
+ DEBUGOUT("Zeroing the MTA\n");
+ for(i = 0; i < E1000_MC_TBL_SIZE; i++)
+ E1000_WRITE_REG_ARRAY(shared, MTA, i, 0);
+
+ /* Call a subroutine to configure the link and setup flow control. */
+ status = e1000_setup_fc_and_link(shared);
+
+ /* Clear all of the statistics registers (clear on read). It is
+ * important that we do this after we have tried to establish link
+ * because the symbol error count will increment wildly if there
+ * is no link.
+ */
+ e1000_clear_hw_cntrs(shared);
+
+ return (status);
+}
+
+/******************************************************************************
+ * Initializes receive address filters.
+ *
+ * shared - Struct containing variables accessed by shared code
+ *
+ * Places the MAC address in receive address register 0 and clears the rest
+ * of the receive addresss registers. Clears the multicast table. Assumes
+ * the receiver is in reset when the routine is called.
+ *****************************************************************************/
+void
+e1000_init_rx_addrs(struct e1000_shared_adapter *shared)
+{
+ uint32_t i;
+ uint32_t addr_low;
+ uint32_t addr_high;
+
+ DEBUGFUNC("e1000_init_rx_addrs");
+
+ /* Setup the receive address. */
+ DEBUGOUT("Programming MAC Address into RAR[0]\n");
+ addr_low = (shared->mac_addr[0] |
+ (shared->mac_addr[1] << 8) |
+ (shared->mac_addr[2] << 16) | (shared->mac_addr[3] << 24));
+
+ addr_high = (shared->mac_addr[4] |
+ (shared->mac_addr[5] << 8) | E1000_RAH_AV);
+
+ E1000_WRITE_REG_ARRAY(shared, RA, 0, addr_low);
+ E1000_WRITE_REG_ARRAY(shared, RA, 1, addr_high);
+
+ /* Zero out the other 15 receive addresses. */
+ DEBUGOUT("Clearing RAR[1-15]\n");
+ for(i = 1; i < E1000_RAR_ENTRIES; i++) {
+ E1000_WRITE_REG_ARRAY(shared, RA, (i << 1), 0);
+ E1000_WRITE_REG_ARRAY(shared, RA, ((i << 1) + 1), 0);
+ }
+
+ return;
+}
+
+/******************************************************************************
+ * Updates the MAC's list of multicast addresses.
+ *
+ * shared - Struct containing variables accessed by shared code
+ * mc_addr_list - the list of new multicast addresses
+ * mc_addr_count - number of addresses
+ * pad - number of bytes between addresses in the list
+ *
+ * The given list replaces any existing list. Clears the last 15 receive
+ * address registers and the multicast table. Uses receive address registers
+ * for the first 15 multicast addresses, and hashes the rest into the
+ * multicast table.
+ *****************************************************************************/
+void
+e1000_mc_addr_list_update(struct e1000_shared_adapter *shared,
+ uint8_t *mc_addr_list,
+ uint32_t mc_addr_count,
+ uint32_t pad)
+{
+ uint32_t hash_value;
+ uint32_t i;
+ uint32_t rar_used_count = 1; /* RAR[0] is used for our MAC address */
+
+ DEBUGFUNC("e1000_mc_addr_list_update");
+
+ /* Set the new number of MC addresses that we are being requested to use. */
+ shared->num_mc_addrs = mc_addr_count;
+
+ /* Clear RAR[1-15] */
+ DEBUGOUT(" Clearing RAR[1-15]\n");
+ for(i = rar_used_count; i < E1000_RAR_ENTRIES; i++) {
+ E1000_WRITE_REG_ARRAY(shared, RA, (i << 1), 0);
+ E1000_WRITE_REG_ARRAY(shared, RA, ((i << 1) + 1), 0);
+ }
+
+ /* Clear the MTA */
+ DEBUGOUT(" Clearing MTA\n");
+ for(i = 0; i < E1000_NUM_MTA_REGISTERS; i++) {
+ E1000_WRITE_REG_ARRAY(shared, MTA, i, 0);
+ }
+
+ /* Add the new addresses */
+ for(i = 0; i < mc_addr_count; i++) {
+ DEBUGOUT(" Adding the multicast addresses:\n");
+ DEBUGOUT7(" MC Addr #%d =%.2X %.2X %.2X %.2X %.2X %.2X\n", i,
+ mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad)],
+ mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 1],
+ mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 2],
+ mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 3],
+ mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 4],
+ mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 5]);
+
+ hash_value = e1000_hash_mc_addr(shared,
+ mc_addr_list +
+ (i * (ETH_LENGTH_OF_ADDRESS + pad)));
+
+ DEBUGOUT1(" Hash value = 0x%03X\n", hash_value);
+
+ /* Place this multicast address in the RAR if there is room, *
+ * else put it in the MTA
+ */
+ if(rar_used_count < E1000_RAR_ENTRIES) {
+ e1000_rar_set(shared,
+ mc_addr_list + (i * (ETH_LENGTH_OF_ADDRESS + pad)),
+ rar_used_count);
+ rar_used_count++;
+ } else {
+ e1000_mta_set(shared, hash_value);
+ }
+ }
+
+ DEBUGOUT("MC Update Complete\n");
+ return;
+}
+
+/******************************************************************************
+ * Hashes an address to determine its location in the multicast table
+ *
+ * shared - Struct containing variables accessed by shared code
+ * mc_addr - the multicast address to hash
+ *****************************************************************************/
+uint32_t
+e1000_hash_mc_addr(struct e1000_shared_adapter *shared,
+ uint8_t *mc_addr)
+{
+ uint32_t hash_value = 0;
+
+ /* The portion of the address that is used for the hash table is
+ * determined by the mc_filter_type setting.
+ */
+ switch (shared->mc_filter_type) {
+ /* [0] [1] [2] [3] [4] [5]
+ * 01 AA 00 12 34 56
+ * LSB MSB - According to H/W docs */
+ case 0:
+ /* [47:36] i.e. 0x563 for above example address */
+ hash_value = ((mc_addr[4] >> 4) | (((uint16_t) mc_addr[5]) << 4));
+ break;
+ case 1: /* [46:35] i.e. 0xAC6 for above example address */
+ hash_value = ((mc_addr[4] >> 3) | (((uint16_t) mc_addr[5]) << 5));
+ break;
+ case 2: /* [45:34] i.e. 0x5D8 for above example address */
+ hash_value = ((mc_addr[4] >> 2) | (((uint16_t) mc_addr[5]) << 6));
+ break;
+ case 3: /* [43:32] i.e. 0x634 for above example address */
+ hash_value = ((mc_addr[4]) | (((uint16_t) mc_addr[5]) << 8));
+ break;
+ }
+
+ hash_value &= 0xFFF;
+ return (hash_value);
+}
+
+/******************************************************************************
+ * Sets the bit in the multicast table corresponding to the hash value.
+ *
+ * shared - Struct containing variables accessed by shared code
+ * hash_value - Multicast address hash value
+ *****************************************************************************/
+void
+e1000_mta_set(struct e1000_shared_adapter *shared,
+ uint32_t hash_value)
+{
+ uint32_t hash_bit, hash_reg;
+ uint32_t mta_reg;
+ uint32_t temp;
+
+ /* The MTA is a register array of 128 32-bit registers.
+ * It is treated like an array of 4096 bits. We want to set
+ * bit BitArray[hash_value]. So we figure out what register
+ * the bit is in, read it, OR in the new bit, then write
+ * back the new value. The register is determined by the
+ * upper 7 bits of the hash value and the bit within that
+ * register are determined by the lower 5 bits of the value.
+ */
+ hash_reg = (hash_value >> 5) & 0x7F;
+ hash_bit = hash_value & 0x1F;
+
+ mta_reg = E1000_READ_REG_ARRAY(shared, MTA, hash_reg);
+
+ mta_reg |= (1 << hash_bit);
+
+ /* If we are on an 82544 and we are trying to write an odd offset
+ * in the MTA, save off the previous entry before writing and
+ * restore the old value after writing.
+ */
+ if((shared->mac_type == e1000_82544) && ((hash_reg & 0x1) == 1)) {
+ temp = E1000_READ_REG_ARRAY(shared, MTA, (hash_reg - 1));
+ E1000_WRITE_REG_ARRAY(shared, MTA, hash_reg, mta_reg);
+ E1000_WRITE_REG_ARRAY(shared, MTA, (hash_reg - 1), temp);
+ } else {
+ E1000_WRITE_REG_ARRAY(shared, MTA, hash_reg, mta_reg);
+ }
+ return;
+}
+
+/******************************************************************************
+ * Puts an ethernet address into a receive address register.
+ *
+ * shared - Struct containing variables accessed by shared code
+ * addr - Address to put into receive address register
+ * index - Receive address register to write
+ *****************************************************************************/
+void
+e1000_rar_set(struct e1000_shared_adapter *shared,
+ uint8_t *addr,
+ uint32_t index)
+{
+ uint32_t rar_low, rar_high;
+
+ /* HW expects these in little endian so we reverse the byte order
+ * from network order (big endian) to little endian
+ */
+ rar_low = ((uint32_t) addr[0] |
+ ((uint32_t) addr[1] << 8) |
+ ((uint32_t) addr[2] << 16) | ((uint32_t) addr[3] << 24));
+
+ rar_high = ((uint32_t) addr[4] | ((uint32_t) addr[5] << 8) | E1000_RAH_AV);
+
+ E1000_WRITE_REG_ARRAY(shared, RA, (index << 1), rar_low);
+ E1000_WRITE_REG_ARRAY(shared, RA, ((index << 1) + 1), rar_high);
+ return;
+}
+
+/******************************************************************************
+ * Writes a value to the specified offset in the VLAN filter table.
+ *
+ * shared - Struct containing variables accessed by shared code
+ * offset - Offset in VLAN filer table to write
+ * value - Value to write into VLAN filter table
+ *****************************************************************************/
+void
+e1000_write_vfta(struct e1000_shared_adapter *shared,
+ uint32_t offset,
+ uint32_t value)
+{
+ uint32_t temp;
+
+ if((shared->mac_type == e1000_82544) && ((offset & 0x1) == 1)) {
+ temp = E1000_READ_REG_ARRAY(shared, VFTA, (offset - 1));
+ E1000_WRITE_REG_ARRAY(shared, VFTA, offset, value);
+ E1000_WRITE_REG_ARRAY(shared, VFTA, (offset - 1), temp);
+ } else {
+ E1000_WRITE_REG_ARRAY(shared, VFTA, offset, value);
+ }
+ return;
+}
+
+/******************************************************************************
+ * Clears the VLAN filer table
+ *
+ * shared - Struct containing variables accessed by shared code
+ *****************************************************************************/
+void
+e1000_clear_vfta(struct e1000_shared_adapter *shared)
+{
+ uint32_t offset;
+
+ for(offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++)
+ E1000_WRITE_REG_ARRAY(shared, VFTA, offset, 0);
+ return;
+}
+
+/******************************************************************************
+ * Configures flow control and link settings.
+ *
+ * shared - Struct containing variables accessed by shared code
+ *
+ * Determines which flow control settings to use. Calls the apropriate media-
+ * specific link configuration function. Configures the flow control settings.
+ * Assuming the adapter has a valid link partner, a valid link should be
+ * established. Assumes the hardware has previously been reset and the
+ * transmitter and receiver are not enabled.
+ *****************************************************************************/
+boolean_t
+e1000_setup_fc_and_link(struct e1000_shared_adapter *shared)
+{
+ uint32_t ctrl_reg;
+ uint32_t eecd_reg;
+ uint32_t ctrl_ext_reg;
+ boolean_t status = TRUE;
+
+ DEBUGFUNC("e1000_setup_fc_and_link");
+
+ /* Read the SWDPIO bits and the ILOS bit out of word 0x0A in the
+ * EEPROM. Store these bits in a variable that we will later write
+ * to the Device Control Register (CTRL).
+ */
+ eecd_reg = e1000_read_eeprom(shared, EEPROM_INIT_CONTROL1_REG);
+
+ ctrl_reg =
+ (((eecd_reg & EEPROM_WORD0A_SWDPIO) << SWDPIO_SHIFT) |
+ ((eecd_reg & EEPROM_WORD0A_ILOS) << ILOS_SHIFT));
+
+ /* Set the PCI priority bit correctly in the CTRL register. This
+ * determines if the adapter gives priority to receives, or if it
+ * gives equal priority to transmits and receives.
+ */
+ if(shared->dma_fairness)
+ ctrl_reg |= E1000_CTRL_PRIOR;
+
+ /* Read and store word 0x0F of the EEPROM. This word contains bits
+ * that determine the hardware's default PAUSE (flow control) mode,
+ * a bit that determines whether the HW defaults to enabling or
+ * disabling auto-negotiation, and the direction of the
+ * SW defined pins. If there is no SW over-ride of the flow
+ * control setting, then the variable shared->fc will
+ * be initialized based on a value in the EEPROM.
+ */
+ eecd_reg = e1000_read_eeprom(shared, EEPROM_INIT_CONTROL2_REG);
+
+ if(shared->fc > e1000_fc_full) {
+ if((eecd_reg & EEPROM_WORD0F_PAUSE_MASK) == 0)
+ shared->fc = e1000_fc_none;
+ else if((eecd_reg & EEPROM_WORD0F_PAUSE_MASK) == EEPROM_WORD0F_ASM_DIR)
+ shared->fc = e1000_fc_tx_pause;
+ else
+ shared->fc = e1000_fc_full;
+ }
+
+ /* We want to save off the original Flow Control configuration just
+ * in case we get disconnected and then reconnected into a different
+ * hub or switch with different Flow Control capabilities.
+ */
+ shared->original_fc = shared->fc;
+
+ if(shared->mac_type == e1000_82542_rev2_0)
+ shared->fc &= (~e1000_fc_tx_pause);
+
+ if((shared->mac_type < e1000_82543) && (shared->report_tx_early == 1))
+ shared->fc &= (~e1000_fc_rx_pause);
+
+ DEBUGOUT1("After fix-ups FlowControl is now = %x\n", shared->fc);
+
+ /* Take the 4 bits from EEPROM word 0x0F that determine the initial
+ * polarity value for the SW controlled pins, and setup the
+ * Extended Device Control reg with that info.
+ * This is needed because one of the SW controlled pins is used for
+ * signal detection. So this should be done before e1000_setup_pcs_link()
+ * or e1000_phy_setup() is called.
+ */
+ if(shared->mac_type == e1000_82543) {
+ ctrl_ext_reg = ((eecd_reg & EEPROM_WORD0F_SWPDIO_EXT)
+ << SWDPIO__EXT_SHIFT);
+ E1000_WRITE_REG(shared, CTRL_EXT, ctrl_ext_reg);
+ }
+
+ /* Call the necessary subroutine to configure the link. */
+ if(shared->media_type == e1000_media_type_fiber)
+ status = e1000_setup_pcs_link(shared, ctrl_reg);
+ else
+ status = e1000_phy_setup(shared, ctrl_reg);
+
+ /* Initialize the flow control address, type, and PAUSE timer
+ * registers to their default values. This is done even if flow
+ * control is disabled, because it does not hurt anything to
+ * initialize these registers.
+ */
+ DEBUGOUT("Initializing the Flow Control address, type and timer regs\n");
+
+ E1000_WRITE_REG(shared, FCAL, FLOW_CONTROL_ADDRESS_LOW);
+ E1000_WRITE_REG(shared, FCAH, FLOW_CONTROL_ADDRESS_HIGH);
+ E1000_WRITE_REG(shared, FCT, FLOW_CONTROL_TYPE);
+ E1000_WRITE_REG(shared, FCTTV, shared->fc_pause_time);
+
+ /* Set the flow control receive threshold registers. Normally,
+ * these registers will be set to a default threshold that may be
+ * adjusted later by the driver's runtime code. However, if the
+ * ability to transmit pause frames in not enabled, then these
+ * registers will be set to 0.
+ */
+ if(!(shared->fc & e1000_fc_tx_pause)) {
+ E1000_WRITE_REG(shared, FCRTL, 0);
+ E1000_WRITE_REG(shared, FCRTH, 0);
+ } else {
+ /* We need to set up the Receive Threshold high and low water marks
+ * as well as (optionally) enabling the transmission of XON frames.
+ */
+ if(shared->fc_send_xon) {
+ E1000_WRITE_REG(shared, FCRTL,
+ (shared->fc_low_water | E1000_FCRTL_XONE));
+ E1000_WRITE_REG(shared, FCRTH, shared->fc_high_water);
+ } else {
+ E1000_WRITE_REG(shared, FCRTL, shared->fc_low_water);
+ E1000_WRITE_REG(shared, FCRTH, shared->fc_high_water);
+ }
+ }
+ return (status);
+}
+
+/******************************************************************************
+ * Sets up link for a fiber based adapter
+ *
+ * shared - Struct containing variables accessed by shared code
+ * ctrl_reg - Current value of the device control register
+ *
+ * Manipulates Physical Coding Sublayer functions in order to configure
+ * link. Assumes the hardware has been previously reset and the transmitter
+ * and receiver are not enabled.
+ *****************************************************************************/
+boolean_t
+e1000_setup_pcs_link(struct e1000_shared_adapter *shared,
+ uint32_t ctrl_reg)
+{
+ uint32_t status_reg;
+ uint32_t tctl_reg;
+ uint32_t txcw_reg = 0;
+ uint32_t i;
+
+ DEBUGFUNC("e1000_setup_pcs_link");
+
+ /* Setup the collsion distance. Since this is configuring the
+ * TBI it is assumed that we are in Full Duplex.
+ */
+ tctl_reg = E1000_READ_REG(shared, TCTL);
+ i = E1000_FDX_COLLISION_DISTANCE;
+ i <<= E1000_COLD_SHIFT;
+ tctl_reg |= i;
+ E1000_WRITE_REG(shared, TCTL, tctl_reg);
+
+ /* Check for a software override of the flow control settings, and
+ * setup the device accordingly. If auto-negotiation is enabled,
+ * then software will have to set the "PAUSE" bits to the correct
+ * value in the Tranmsit Config Word Register (TXCW) and re-start
+ * auto-negotiation. However, if auto-negotiation is disabled,
+ * then software will have to manually configure the two flow
+ * control enable bits in the CTRL register.
+ *
+ * The possible values of the "fc" parameter are:
+ * 0: Flow control is completely disabled
+ * 1: Rx flow control is enabled (we can receive pause frames
+ * but not send pause frames).
+ * 2: Tx flow control is enabled (we can send pause frames
+ * but we do not support receiving pause frames).
+ * 3: Both Rx and TX flow control (symmetric) are enabled.
+ * other: No software override. The flow control configuration
+ * in the EEPROM is used.
+ */
+ switch (shared->fc) {
+ case e1000_fc_none: /* 0 */
+ /* Flow control (RX & TX) is completely disabled by a
+ * software over-ride.
+ */
+ txcw_reg = (E1000_TXCW_ANE | E1000_TXCW_FD);
+ break;
+ case e1000_fc_rx_pause: /* 1 */
+ /* RX Flow control is enabled, and TX Flow control is
+ * disabled, by a software over-ride.
+ */
+ /* Since there really isn't a way to advertise that we are
+ * capable of RX Pause ONLY, we will advertise that we
+ * support both symmetric and asymmetric RX PAUSE. Later
+ * we will disable the adapter's ability to send PAUSE
+ * frames.
+ */
+ txcw_reg = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
+ break;
+ case e1000_fc_tx_pause: /* 2 */
+ /* TX Flow control is enabled, and RX Flow control is
+ * disabled, by a software over-ride.
+ */
+ txcw_reg = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
+ break;
+ case e1000_fc_full: /* 3 */
+ /* Flow control (both RX and TX) is enabled by a software
+ * over-ride.
+ */
+ txcw_reg = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
+ break;
+ default:
+ /* We should never get here. The value should be 0-3. */
+ DEBUGOUT("Flow control param set incorrectly\n");
+ ASSERT(0);
+ break;
+ }
+
+ /* Since auto-negotiation is enabled, take the link out of reset.
+ * (the link will be in reset, because we previously reset the
+ * chip). This will restart auto-negotiation. If auto-neogtiation
+ * is successful then the link-up status bit will be set and the
+ * flow control enable bits (RFCE and TFCE) will be set according
+ * to their negotiated value.
+ */
+ DEBUGOUT("Auto-negotiation enabled\n");
+
+ E1000_WRITE_REG(shared, TXCW, txcw_reg);
+ E1000_WRITE_REG(shared, CTRL, ctrl_reg);
+
+ shared->txcw_reg = txcw_reg;
+ msec_delay(1);
+
+ /* If we have a signal then poll for a "Link-Up" indication in the
+ * Device Status Register. Time-out if a link isn't seen in 500
+ * milliseconds seconds (Auto-negotiation should complete in less
+ * than 500 milliseconds even if the other end is doing it in SW).
+ */
+ if(!(E1000_READ_REG(shared, CTRL) & E1000_CTRL_SWDPIN1)) {
+
+ DEBUGOUT("Looking for Link\n");
+ for(i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
+ msec_delay(10);
+ status_reg = E1000_READ_REG(shared, STATUS);
+ if(status_reg & E1000_STATUS_LU)
+ break;
+ }
+
+ if(i == (LINK_UP_TIMEOUT / 10)) {
+ /* AutoNeg failed to achieve a link, so we'll call the
+ * "CheckForLink" routine. This routine will force the link
+ * up if we have "signal-detect". This will allow us to
+ * communicate with non-autonegotiating link partners.
+ */
+ DEBUGOUT("Never got a valid link from auto-neg!!!\n");
+
+ shared->autoneg_failed = 1;
+ e1000_check_for_link(shared);
+ shared->autoneg_failed = 0;
+ } else {
+ shared->autoneg_failed = 0;
+ DEBUGOUT("Valid Link Found\n");
+ }
+ } else {
+ DEBUGOUT("No Signal Detected\n");
+ }
+
+ return (TRUE);
+}
+
+/******************************************************************************
+ * Configures flow control settings after link is established
+ *
+ * shared - Struct containing variables accessed by shared code
+ *
+ * Should be called immediately after a valid link has been established.
+ * Forces MAC flow control settings if link was forced. When in MII/GMII mode
+ * and autonegotiation is enabled, the MAC flow control settings will be set
+ * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
+ * and RFCE bits will be automaticaly set to the negotiated flow control mode.
+ *****************************************************************************/
+void
+e1000_config_fc_after_link_up(struct e1000_shared_adapter *shared)
+{
+ uint16_t mii_status_reg;
+ uint16_t mii_nway_adv_reg;
+ uint16_t mii_nway_lp_ability_reg;
+ uint16_t speed;
+ uint16_t duplex;
+
+ DEBUGFUNC("e1000_config_fc_after_link_up");
+
+ /* Check for the case where we have fiber media and auto-neg failed
+ * so we had to force link. In this case, we need to force the
+ * configuration of the MAC to match the "fc" parameter.
+ */
+ if(((shared->media_type == e1000_media_type_fiber)
+ && (shared->autoneg_failed))
+ || ((shared->media_type == e1000_media_type_copper)
+ && (!shared->autoneg))) {
+ e1000_force_mac_fc(shared);
+ }
+
+ /* Check for the case where we have copper media and auto-neg is
+ * enabled. In this case, we need to check and see if Auto-Neg
+ * has completed, and if so, how the PHY and link partner has
+ * flow control configured.
+ */
+ if((shared->media_type == e1000_media_type_copper) && shared->autoneg) {
+ /* Read the MII Status Register and check to see if AutoNeg
+ * has completed. We read this twice because this reg has
+ * some "sticky" (latched) bits.
+ */
+ mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+ mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+
+ if(mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
+ /* The AutoNeg process has completed, so we now need to
+ * read both the Auto Negotiation Advertisement Register
+ * (Address 4) and the Auto_Negotiation Base Page Ability
+ * Register (Address 5) to determine how flow control was
+ * negotiated.
+ */
+ mii_nway_adv_reg = e1000_read_phy_reg(shared,
+ PHY_AUTONEG_ADV);
+ mii_nway_lp_ability_reg = e1000_read_phy_reg(shared,
+ PHY_LP_ABILITY);
+
+ /* Two bits in the Auto Negotiation Advertisement Register
+ * (Address 4) and two bits in the Auto Negotiation Base
+ * Page Ability Register (Address 5) determine flow control
+ * for both the PHY and the link partner. The following
+ * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
+ * 1999, describes these PAUSE resolution bits and how flow
+ * control is determined based upon these settings.
+ * NOTE: DC = Don't Care
+ *
+ * LOCAL DEVICE | LINK PARTNER
+ * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
+ *-------|---------|-------|---------|--------------------
+ * 0 | 0 | DC | DC | e1000_fc_none
+ * 0 | 1 | 0 | DC | e1000_fc_none
+ * 0 | 1 | 1 | 0 | e1000_fc_none
+ * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
+ * 1 | 0 | 0 | DC | e1000_fc_none
+ * 1 | DC | 1 | DC | e1000_fc_full
+ * 1 | 1 | 0 | 0 | e1000_fc_none
+ * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
+ *
+ */
+ /* Are both PAUSE bits set to 1? If so, this implies
+ * Symmetric Flow Control is enabled at both ends. The
+ * ASM_DIR bits are irrelevant per the spec.
+ *
+ * For Symmetric Flow Control:
+ *
+ * LOCAL DEVICE | LINK PARTNER
+ * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+ *-------|---------|-------|---------|--------------------
+ * 1 | DC | 1 | DC | e1000_fc_full
+ *
+ */
+ if((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+ (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
+ /* Now we need to check if the user selected RX ONLY
+ * of pause frames. In this case, we had to advertise
+ * FULL flow control because we could not advertise RX
+ * ONLY. Hence, we must now check to see if we need to
+ * turn OFF the TRANSMISSION of PAUSE frames.
+ */
+ if(shared->original_fc == e1000_fc_full) {
+ shared->fc = e1000_fc_full;
+ DEBUGOUT("Flow Control = FULL.\r\n");
+ } else {
+ shared->fc = e1000_fc_rx_pause;
+ DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
+ }
+ }
+ /* For receiving PAUSE frames ONLY.
+ *
+ * LOCAL DEVICE | LINK PARTNER
+ * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+ *-------|---------|-------|---------|--------------------
+ * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
+ *
+ */
+ else if(!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+ (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
+ (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
+ (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
+ shared->fc = e1000_fc_tx_pause;
+ DEBUGOUT("Flow Control = TX PAUSE frames only.\r\n");
+ }
+ /* For transmitting PAUSE frames ONLY.
+ *
+ * LOCAL DEVICE | LINK PARTNER
+ * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+ *-------|---------|-------|---------|--------------------
+ * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
+ *
+ */
+ else if((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+ (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
+ !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
+ (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
+ shared->fc = e1000_fc_rx_pause;
+ DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
+ }
+ /* Per the IEEE spec, at this point flow control should be
+ * disabled. However, we want to consider that we could
+ * be connected to a legacy switch that doesn't advertise
+ * desired flow control, but can be forced on the link
+ * partner. So if we advertised no flow control, that is
+ * what we will resolve to. If we advertised some kind of
+ * receive capability (Rx Pause Only or Full Flow Control)
+ * and the link partner advertised none, we will configure
+ * ourselves to enable Rx Flow Control only. We can do
+ * this safely for two reasons: If the link partner really
+ * didn't want flow control enabled, and we enable Rx, no
+ * harm done since we won't be receiving any PAUSE frames
+ * anyway. If the intent on the link partner was to have
+ * flow control enabled, then by us enabling RX only, we
+ * can at least receive pause frames and process them.
+ * This is a good idea because in most cases, since we are
+ * predominantly a server NIC, more times than not we will
+ * be asked to delay transmission of packets than asking
+ * our link partner to pause transmission of frames.
+ */
+ else if(shared->original_fc == e1000_fc_none ||
+ shared->original_fc == e1000_fc_tx_pause) {
+ shared->fc = e1000_fc_none;
+ DEBUGOUT("Flow Control = NONE.\r\n");
+ } else {
+ shared->fc = e1000_fc_rx_pause;
+ DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
+ }
+
+ /* Now we need to do one last check... If we auto-
+ * negotiated to HALF DUPLEX, flow control should not be
+ * enabled per IEEE 802.3 spec.
+ */
+ e1000_get_speed_and_duplex(shared, &speed, &duplex);
+
+ if(duplex == HALF_DUPLEX)
+ shared->fc = e1000_fc_none;
+
+ /* Now we call a subroutine to actually force the MAC
+ * controller to use the correct flow control settings.
+ */
+ e1000_force_mac_fc(shared);
+ } else {
+ DEBUGOUT("Copper PHY and Auto Neg has not completed.\r\n");
+ }
+ }
+ return;
+}
+
+/******************************************************************************
+ * Checks to see if the link status of the hardware has changed.
+ *
+ * shared - Struct containing variables accessed by shared code
+ *
+ * Called by any function that needs to check the link status of the adapter.
+ *****************************************************************************/
+void
+e1000_check_for_link(struct e1000_shared_adapter *shared)
+{
+ uint32_t rxcw_reg;
+ uint32_t ctrl_reg;
+ uint32_t status_reg;
+ uint32_t rctl_reg;
+ uint16_t phy_data;
+ uint16_t lp_capability;
+
+ DEBUGFUNC("e1000_check_for_link");
+
+ ctrl_reg = E1000_READ_REG(shared, CTRL);
+ status_reg = E1000_READ_REG(shared, STATUS);
+ rxcw_reg = E1000_READ_REG(shared, RXCW);
+
+ /* If we have a copper PHY then we only want to go out to the PHY
+ * registers to see if Auto-Neg has completed and/or if our link
+ * status has changed. The get_link_status flag will be set if we
+ * receive a Link Status Change interrupt or we have Rx Sequence
+ * Errors.
+ */
+ if(shared->media_type == e1000_media_type_copper
+ && shared->get_link_status) {
+ /* First we want to see if the MII Status Register reports
+ * link. If so, then we want to get the current speed/duplex
+ * of the PHY.
+ * Read the register twice since the link bit is sticky.
+ */
+ phy_data = e1000_read_phy_reg(shared, PHY_STATUS);
+ phy_data = e1000_read_phy_reg(shared, PHY_STATUS);
+
+ if(phy_data & MII_SR_LINK_STATUS) {
+ shared->get_link_status = FALSE;
+ } else {
+ DEBUGOUT("**** CFL - No link detected. ****\r\n");
+ return;
+ }
+
+ /* If we are forcing speed/duplex, then we simply return since
+ * we have already determined whether we have link or not.
+ */
+ if(!shared->autoneg) {
+ return;
+ }
+
+ switch (shared->phy_id) {
+ case M88E1000_12_PHY_ID:
+ case M88E1000_14_PHY_ID:
+ case M88E1000_I_PHY_ID:
+ /* We have a M88E1000 PHY and Auto-Neg is enabled. If we
+ * have Si on board that is 82544 or newer, Auto
+ * Speed Detection takes care of MAC speed/duplex
+ * configuration. So we only need to configure Collision
+ * Distance in the MAC. Otherwise, we need to force
+ * speed/duplex on the MAC to the current PHY speed/duplex
+ * settings.
+ */
+ if(shared->mac_type >= e1000_82544) {
+ DEBUGOUT("CFL - Auto-Neg complete.");
+ DEBUGOUT("Configuring Collision Distance.");
+ e1000_config_collision_dist(shared);
+ } else {
+ /* Read the Phy Specific Status register to get the
+ * resolved speed/duplex settings. Then call
+ * e1000_config_mac_to_phy which will retrieve
+ * PHY register information and configure the MAC to
+ * equal the negotiated speed/duplex.
+ */
+ phy_data = e1000_read_phy_reg(shared,
+ M88E1000_PHY_SPEC_STATUS);
+
+ DEBUGOUT1("CFL - Auto-Neg complete. phy_data = %x\r\n",
+ phy_data);
+ e1000_config_mac_to_phy(shared, phy_data);
+ }
+
+ /* Configure Flow Control now that Auto-Neg has completed.
+ * We need to first restore the users desired Flow
+ * Control setting since we may have had to re-autoneg
+ * with a different link partner.
+ */
+ e1000_config_fc_after_link_up(shared);
+ break;
+
+ default:
+ DEBUGOUT("CFL - Invalid PHY detected.\r\n");
+
+ } /* end switch statement */
+
+ /* At this point we know that we are on copper, link is up,
+ * and we are auto-neg'd. These are pre-conditions for checking
+ * the link parter capabilities register. We use the link partner
+ * capabilities to determine if TBI Compatibility needs to be turned on
+ * or turned off. If the link partner advertises any speed in addition
+ * to Gigabit, then we assume that they are GMII-based and TBI
+ * compatibility is not needed.
+ * If no other speeds are advertised, then we assume the link partner
+ * is TBI-based and we turn on TBI Compatibility.
+ */
+ if(shared->tbi_compatibility_en) {
+ lp_capability = e1000_read_phy_reg(shared, PHY_LP_ABILITY);
+ if(lp_capability & (NWAY_LPAR_10T_HD_CAPS |
+ NWAY_LPAR_10T_FD_CAPS |
+ NWAY_LPAR_100TX_HD_CAPS |
+ NWAY_LPAR_100TX_FD_CAPS |
+ NWAY_LPAR_100T4_CAPS)) {
+ /* If our link partner advertises below Gig, then they do not
+ * need the special Tbi Compatibility mode.
+ */
+ if(shared->tbi_compatibility_on) {
+ /* If we previously were in the mode, turn it off, now. */
+ rctl_reg = E1000_READ_REG(shared, RCTL);
+ rctl_reg &= ~E1000_RCTL_SBP;
+ E1000_WRITE_REG(shared, RCTL, rctl_reg);
+ shared->tbi_compatibility_on = FALSE;
+ }
+ } else {
+ /* If the mode is was previously off, turn it on.
+ * For compatibility with a suspected Tbi link partners,
+ * we will store bad packets.
+ * (Certain frames have an additional byte on the end and will
+ * look like CRC errors to to the hardware).
+ */
+ if(!shared->tbi_compatibility_on) {
+ shared->tbi_compatibility_on = TRUE;
+ rctl_reg = E1000_READ_REG(shared, RCTL);
+ rctl_reg |= E1000_RCTL_SBP;
+ E1000_WRITE_REG(shared, RCTL, rctl_reg);
+ }
+ }
+ }
+ } /* end if e1000_media_type_copper statement */
+ /* If we don't have link (auto-negotiation failed or link partner
+ * cannot auto-negotiate) and the cable is plugged in since we don't
+ * have Loss-Of-Signal (we HAVE a signal) and our link partner is
+ * not trying to AutoNeg with us (we are receiving idles/data
+ * then we need to force our link to connect to a non
+ * auto-negotiating link partner. We also need to give
+ * auto-negotiation time to complete in case the cable was just
+ * plugged in. The autoneg_failed flag does this.
+ */
+ else if((shared->media_type == e1000_media_type_fiber) && /* Fiber PHY */
+ (!(status_reg & E1000_STATUS_LU)) && /* no link and */
+ (!(ctrl_reg & E1000_CTRL_SWDPIN1)) && /* we have signal */
+ (!(rxcw_reg & E1000_RXCW_C))) { /* and rxing idle/data */
+ if(shared->autoneg_failed == 0) { /* given AutoNeg time */
+ shared->autoneg_failed = 1;
+ return;
+ }
+
+ DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\r\n");
+
+ /* Disable auto-negotiation in the TXCW register */
+ E1000_WRITE_REG(shared, TXCW, (shared->txcw_reg & ~E1000_TXCW_ANE));
+
+ /* Force link-up and also force full-duplex. */
+ ctrl_reg = E1000_READ_REG(shared, CTRL);
+ ctrl_reg |= (E1000_CTRL_SLU | E1000_CTRL_FD);
+ E1000_WRITE_REG(shared, CTRL, ctrl_reg);
+
+ /* Configure Flow Control after forcing link up. */
+ e1000_config_fc_after_link_up(shared);
+
+ } else if((shared->media_type == e1000_media_type_fiber) && /* Fiber */
+ (ctrl_reg & E1000_CTRL_SLU) && /* we have forced link */
+ (rxcw_reg & E1000_RXCW_C)) { /* and Rxing /C/ ordered sets */
+ /* If we are forcing link and we are receiving /C/ ordered sets,
+ * then re-enable auto-negotiation in the RXCW register and
+ * disable forced link in the Device Control register in an attempt
+ * to AutoNeg with our link partner.
+ */
+ DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\r\n");
+
+ /* Enable auto-negotiation in the TXCW register and stop
+ * forcing link.
+ */
+ E1000_WRITE_REG(shared, TXCW, shared->txcw_reg);
+
+ E1000_WRITE_REG(shared, CTRL, (ctrl_reg & ~E1000_CTRL_SLU));
+ }
+
+ return;
+}
+
+/******************************************************************************
+ * Clears all hardware statistics counters.
+ *
+ * shared - Struct containing variables accessed by shared code
+ *****************************************************************************/
+void
+e1000_clear_hw_cntrs(struct e1000_shared_adapter *shared)
+{
+ volatile uint32_t temp_reg;
+
+ DEBUGFUNC("e1000_clear_hw_cntrs");
+
+ /* if we are stopped or resetting exit gracefully */
+ if(shared->adapter_stopped) {
+ DEBUGOUT("Exiting because the adapter is stopped!!!\n");
+ return;
+ }
+
+ temp_reg = E1000_READ_REG(shared, CRCERRS);
+ temp_reg = E1000_READ_REG(shared, SYMERRS);
+ temp_reg = E1000_READ_REG(shared, MPC);
+ temp_reg = E1000_READ_REG(shared, SCC);
+ temp_reg = E1000_READ_REG(shared, ECOL);
+ temp_reg = E1000_READ_REG(shared, MCC);
+ temp_reg = E1000_READ_REG(shared, LATECOL);
+ temp_reg = E1000_READ_REG(shared, COLC);
+ temp_reg = E1000_READ_REG(shared, DC);
+ temp_reg = E1000_READ_REG(shared, SEC);
+ temp_reg = E1000_READ_REG(shared, RLEC);
+ temp_reg = E1000_READ_REG(shared, XONRXC);
+ temp_reg = E1000_READ_REG(shared, XONTXC);
+ temp_reg = E1000_READ_REG(shared, XOFFRXC);
+ temp_reg = E1000_READ_REG(shared, XOFFTXC);
+ temp_reg = E1000_READ_REG(shared, FCRUC);
+ temp_reg = E1000_READ_REG(shared, PRC64);
+ temp_reg = E1000_READ_REG(shared, PRC127);
+ temp_reg = E1000_READ_REG(shared, PRC255);
+ temp_reg = E1000_READ_REG(shared, PRC511);
+ temp_reg = E1000_READ_REG(shared, PRC1023);
+ temp_reg = E1000_READ_REG(shared, PRC1522);
+ temp_reg = E1000_READ_REG(shared, GPRC);
+ temp_reg = E1000_READ_REG(shared, BPRC);
+ temp_reg = E1000_READ_REG(shared, MPRC);
+ temp_reg = E1000_READ_REG(shared, GPTC);
+ temp_reg = E1000_READ_REG(shared, GORCL);
+ temp_reg = E1000_READ_REG(shared, GORCH);
+ temp_reg = E1000_READ_REG(shared, GOTCL);
+ temp_reg = E1000_READ_REG(shared, GOTCH);
+ temp_reg = E1000_READ_REG(shared, RNBC);
+ temp_reg = E1000_READ_REG(shared, RUC);
+ temp_reg = E1000_READ_REG(shared, RFC);
+ temp_reg = E1000_READ_REG(shared, ROC);
+ temp_reg = E1000_READ_REG(shared, RJC);
+ temp_reg = E1000_READ_REG(shared, TORL);
+ temp_reg = E1000_READ_REG(shared, TORH);
+ temp_reg = E1000_READ_REG(shared, TOTL);
+ temp_reg = E1000_READ_REG(shared, TOTH);
+ temp_reg = E1000_READ_REG(shared, TPR);
+ temp_reg = E1000_READ_REG(shared, TPT);
+ temp_reg = E1000_READ_REG(shared, PTC64);
+ temp_reg = E1000_READ_REG(shared, PTC127);
+ temp_reg = E1000_READ_REG(shared, PTC255);
+ temp_reg = E1000_READ_REG(shared, PTC511);
+ temp_reg = E1000_READ_REG(shared, PTC1023);
+ temp_reg = E1000_READ_REG(shared, PTC1522);
+ temp_reg = E1000_READ_REG(shared, MPTC);
+ temp_reg = E1000_READ_REG(shared, BPTC);
+
+ if(shared->mac_type < e1000_82543)
+ return;
+
+ temp_reg = E1000_READ_REG(shared, ALGNERRC);
+ temp_reg = E1000_READ_REG(shared, RXERRC);
+ temp_reg = E1000_READ_REG(shared, TNCRS);
+ temp_reg = E1000_READ_REG(shared, CEXTERR);
+ temp_reg = E1000_READ_REG(shared, TSCTC);
+ temp_reg = E1000_READ_REG(shared, TSCTFC);
+ return;
+}
+
+/******************************************************************************
+ * Detects the current speed and duplex settings of the hardware.
+ *
+ * shared - Struct containing variables accessed by shared code
+ * speed - Speed of the connection
+ * duplex - Duplex setting of the connection
+ *****************************************************************************/
+void
+e1000_get_speed_and_duplex(struct e1000_shared_adapter *shared,
+ uint16_t *speed,
+ uint16_t *duplex)
+{
+ uint32_t status_reg;
+#if DBG
+ uint16_t phy_data;
+#endif
+
+ DEBUGFUNC("e1000_get_speed_and_duplex");
+
+ /* If the adapter is stopped we don't have a speed or duplex */
+ if(shared->adapter_stopped) {
+ *speed = 0;
+ *duplex = 0;
+ return;
+ }
+
+ if(shared->mac_type >= e1000_82543) {
+ status_reg = E1000_READ_REG(shared, STATUS);
+ if(status_reg & E1000_STATUS_SPEED_1000) {
+ *speed = SPEED_1000;
+ DEBUGOUT("1000 Mbs, ");
+ } else if(status_reg & E1000_STATUS_SPEED_100) {
+ *speed = SPEED_100;
+ DEBUGOUT("100 Mbs, ");
+ } else {
+ *speed = SPEED_10;
+ DEBUGOUT("10 Mbs, ");
+ }
+
+ if(status_reg & E1000_STATUS_FD) {
+ *duplex = FULL_DUPLEX;
+ DEBUGOUT("Full Duplex\r\n");
+ } else {
+ *duplex = HALF_DUPLEX;
+ DEBUGOUT(" Half Duplex\r\n");
+ }
+ } else {
+ DEBUGOUT("1000 Mbs, Full Duplex\r\n");
+ *speed = SPEED_1000;
+ *duplex = FULL_DUPLEX;
+ }
+
+#if DBG
+ if(shared->phy_id == M88E1000_12_PHY_ID ||
+ shared->phy_id == M88E1000_14_PHY_ID ||
+ shared->phy_id == M88E1000_I_PHY_ID) {
+ /* read the phy specific status register */
+ phy_data = e1000_read_phy_reg(shared, M88E1000_PHY_SPEC_STATUS);
+ DEBUGOUT1("M88E1000 Phy Specific Status Reg contents = %x\n", phy_data);
+ phy_data = e1000_read_phy_reg(shared, PHY_STATUS);
+ DEBUGOUT1("Phy MII Status Reg contents = %x\n", phy_data);
+ DEBUGOUT1("Device Status Reg contents = %x\n",
+ E1000_READ_REG(shared, STATUS));
+ }
+#endif
+ return;
+}
+
+/******************************************************************************
+ * Reads a 16 bit word from the EEPROM.
+ *
+ * shared - Struct containing variables accessed by shared code
+ * offset - offset of 16 bit word in the EEPROM to read
+ *****************************************************************************/
+uint16_t
+e1000_read_eeprom(struct e1000_shared_adapter *shared,
+ uint16_t offset)
+{
+ uint16_t data;
+
+ /* Prepare the EEPROM for reading */
+ e1000_setup_eeprom(shared);
+
+ /* Send the READ command (opcode + addr) */
+ e1000_shift_out_bits(shared, EEPROM_READ_OPCODE, 3);
+ e1000_shift_out_bits(shared, offset, 6);
+
+ /* Read the data */
+ data = e1000_shift_in_bits(shared);
+
+ /* End this read operation */
+ e1000_standby_eeprom(shared);
+
+ return (data);
+}
+
+/******************************************************************************
+ * Verifies that the EEPROM has a valid checksum
+ *
+ * shared - Struct containing variables accessed by shared code
+ *
+ * Reads the first 64 16 bit words of the EEPROM and sums the values read.
+ * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
+ * valid.
+ *****************************************************************************/
+boolean_t
+e1000_validate_eeprom_checksum(struct e1000_shared_adapter *shared)
+{
+ uint16_t checksum = 0;
+ uint16_t i;
+
+ for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
+ checksum += e1000_read_eeprom(shared, i);
+
+ if(checksum == (uint16_t) EEPROM_SUM)
+ return (TRUE);
+ else
+ return (FALSE);
+}
+/******************************************************************************
+ * Reads the adapter's part number from the EEPROM
+ *
+ * shared - Struct containing variables accessed by shared code
+ * part_num - Adapter's part number
+ *****************************************************************************/
+boolean_t
+e1000_read_part_num(struct e1000_shared_adapter *shared,
+ uint32_t *part_num)
+{
+ uint16_t eeprom_word;
+
+ DEBUGFUNC("e1000_read_part_num");
+
+ /* Don't read the EEPROM if we are stopped */
+ if(shared->adapter_stopped) {
+ *part_num = 0;
+ return (FALSE);
+ }
+
+ /* Get word 0 from EEPROM */
+ eeprom_word = e1000_read_eeprom(shared, (uint16_t) (EEPROM_PBA_BYTE_1));
+
+ DEBUGOUT("Read first part number word\n");
+
+ /* Save word 0 in upper half is PartNumber */
+ *part_num = (uint32_t) eeprom_word;
+ *part_num = *part_num << 16;
+
+ /* Get word 1 from EEPROM */
+ eeprom_word =
+ e1000_read_eeprom(shared, (uint16_t) (EEPROM_PBA_BYTE_1 + 1));
+
+ DEBUGOUT("Read second part number word\n");
+
+ /* Save word 1 in lower half of PartNumber */
+ *part_num |= eeprom_word;
+
+ /* read a valid part number */
+ return (TRUE);
+}
+
+void
+e1000_read_mac_addr(struct e1000_shared_adapter * shared)
+{
+ uint16_t temp, x;
+
+ for(x = 0; x < NODE_ADDRESS_SIZE; x += 2) {
+ temp = e1000_read_eeprom(shared, (uint16_t)
+ (EEPROM_NODE_ADDRESS_BYTE_0 + (x/2)));
+ shared->perm_mac_addr[x] = (uint8_t) (temp & 0x00FF);
+ shared->perm_mac_addr[x+1] = (uint8_t) (temp >> 8);
+ }
+
+ for(x = 0; x < NODE_ADDRESS_SIZE; x++)
+ shared->mac_addr[x] = shared->perm_mac_addr[x];
+}
+
+/******************************************************************************
+ * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
+ *
+ * shared - Struct containing variables accessed by shared code
+ * frame_len - The length of the frame in question
+ * mac_addr - The Ethernet destination address of the frame in question
+ *****************************************************************************/
+uint32_t
+e1000_tbi_adjust_stats(struct e1000_shared_adapter *shared,
+ struct e1000_shared_stats *stats,
+ uint32_t frame_len,
+ uint8_t *mac_addr)
+{
+ uint64_t carry_bit;
+
+ /* First adjust the frame length. */
+ frame_len--;
+ /* We need to adjust the statistics counters, since the hardware
+ * counters overcount this packet as a CRC error and undercount
+ * the packet as a good packet
+ */
+ /* This packet should not be counted as a CRC error. */
+ stats->crcerrs--;
+ /* This packet does count as a Good Packet Received. */
+ stats->gprc++;
+
+ /* Adjust the Good Octets received counters */
+ carry_bit = 0x80000000 & stats->gorcl;
+ stats->gorcl += frame_len;
+ /* If the high bit of Gorcl (the low 32 bits of the Good Octets
+ * Received Count) was one before the addition,
+ * AND it is zero after, then we lost the carry out,
+ * need to add one to Gorch (Good Octets Received Count High).
+ * This could be simplified if all environments supported
+ * 64-bit integers.
+ */
+ if(carry_bit && ((stats->gorcl & 0x80000000) == 0))
+ stats->gorch++;
+ /* Is this a broadcast or multicast? Check broadcast first,
+ * since the test for a multicast frame will test positive on
+ * a broadcast frame.
+ */
+ if((mac_addr[0] == (uint8_t) 0xff) && (mac_addr[1] == (uint8_t) 0xff))
+ /* Broadcast packet */
+ stats->bprc++;
+ else if(*mac_addr & 0x01)
+ /* Multicast packet */
+ stats->mprc++;
+
+ if(frame_len == shared->max_frame_size) {
+ /* In this case, the hardware has overcounted the number of
+ * oversize frames.
+ */
+ if(stats->roc > 0)
+ stats->roc--;
+ }
+
+ /* Adjust the bin counters when the extra byte put the frame in the
+ * wrong bin. Remember that the frame_len was adjusted above.
+ */
+ if(frame_len == 64) {
+ stats->prc64++;
+ stats->prc127--;
+ } else if(frame_len == 127) {
+ stats->prc127++;
+ stats->prc255--;
+ } else if(frame_len == 255) {
+ stats->prc255++;
+ stats->prc511--;
+ } else if(frame_len == 511) {
+ stats->prc511++;
+ stats->prc1023--;
+ } else if(frame_len == 1023) {
+ stats->prc1023++;
+ stats->prc1522--;
+ } else if(frame_len == 1522) {
+ stats->prc1522++;
+ }
+ return frame_len;
+}
+
+/******************************************************************************
+ * Gets the current PCI bus type, speed, and width of the hardware
+ *
+ * shared - Struct containing variables accessed by shared code
+ *****************************************************************************/
+void
+e1000_get_bus_info(struct e1000_shared_adapter *shared)
+{
+ uint32_t status_reg;
+
+ if(shared->mac_type < e1000_82543) {
+ shared->bus_type = e1000_bus_type_unknown;
+ shared->bus_speed = e1000_bus_speed_unknown;
+ shared->bus_width = e1000_bus_width_unknown;
+ return;
+ }
+
+ status_reg = E1000_READ_REG(shared, STATUS);
+
+ shared->bus_type = (status_reg & E1000_STATUS_PCIX_MODE) ?
+ e1000_bus_type_pcix : e1000_bus_type_pci;
+
+ if(shared->bus_type == e1000_bus_type_pci) {
+ shared->bus_speed = (status_reg & E1000_STATUS_PCI66) ?
+ e1000_bus_speed_66 : e1000_bus_speed_33;
+ } else {
+ switch (status_reg & E1000_STATUS_PCIX_SPEED) {
+ case E1000_STATUS_PCIX_SPEED_66:
+ shared->bus_speed = e1000_bus_speed_66;
+ break;
+ case E1000_STATUS_PCIX_SPEED_100:
+ shared->bus_speed = e1000_bus_speed_100;
+ break;
+ case E1000_STATUS_PCIX_SPEED_133:
+ shared->bus_speed = e1000_bus_speed_133;
+ break;
+ default:
+ shared->bus_speed = e1000_bus_speed_reserved;
+ break;
+ }
+ }
+
+ shared->bus_width = (status_reg & E1000_STATUS_BUS64) ?
+ e1000_bus_width_64 : e1000_bus_width_32;
+
+ return;
+}
diff --git a/drivers/net/e1000/e1000_mac.h b/drivers/net/e1000/e1000_mac.h
new file mode 100644
index 000000000000..928c277ac28d
--- /dev/null
+++ b/drivers/net/e1000/e1000_mac.h
@@ -0,0 +1,1383 @@
+/*******************************************************************************
+
+ This software program is available to you under a choice of one of two
+ licenses. You may choose to be licensed under either the GNU General Public
+ License (GPL) Version 2, June 1991, available at
+ http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
+ text of which follows:
+
+ Recipient has requested a license and Intel Corporation ("Intel") is willing
+ to grant a license for the software entitled Linux Base Driver for the
+ Intel(R) PRO/1000 Family of Adapters (e1000) (the "Software") being provided
+ by Intel Corporation. The following definitions apply to this license:
+
+ "Licensed Patents" means patent claims licensable by Intel Corporation which
+ are necessarily infringed by the use of sale of the Software alone or when
+ combined with the operating system referred to below.
+
+ "Recipient" means the party to whom Intel delivers this Software.
+
+ "Licensee" means Recipient and those third parties that receive a license to
+ any operating system available under the GNU Public License version 2.0 or
+ later.
+
+ Copyright (c) 1999 - 2002 Intel Corporation.
+ All rights reserved.
+
+ The license is provided to Recipient and Recipient's Licensees under the
+ following terms.
+
+ Redistribution and use in source and binary forms of the Software, with or
+ without modification, are permitted provided that the following conditions
+ are met:
+
+ Redistributions of source code of the Software may retain the above
+ copyright notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form of the Software may reproduce the above
+ copyright notice, this list of conditions and the following disclaimer in
+ the documentation and/or materials provided with the distribution.
+
+ Neither the name of Intel Corporation nor the names of its contributors
+ shall be used to endorse or promote products derived from this Software
+ without specific prior written permission.
+
+ Intel hereby grants Recipient and Licensees a non-exclusive, worldwide,
+ royalty-free patent license under Licensed Patents to make, use, sell, offer
+ to sell, import and otherwise transfer the Software, if any, in source code
+ and object code form. This license shall include changes to the Software
+ that are error corrections or other minor changes to the Software that do
+ not add functionality or features when the Software is incorporated in any
+ version of an operating system that has been distributed under the GNU
+ General Public License 2.0 or later. This patent license shall apply to the
+ combination of the Software and any operating system licensed under the GNU
+ Public License version 2.0 or later if, at the time Intel provides the
+ Software to Recipient, such addition of the Software to the then publicly
+ available versions of such operating systems available under the GNU Public
+ License version 2.0 or later (whether in gold, beta or alpha form) causes
+ such combination to be covered by the Licensed Patents. The patent license
+ shall not apply to any other combinations which include the Software. NO
+ hardware per se is licensed hereunder.
+
+ 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 MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR IT CONTRIBUTORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ ANY LOSS OF USE; DATA, OR PROFITS; OR BUSINESS INTERUPTION) 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.
+
+*******************************************************************************/
+
+/* e1000_mac.h
+ * Structures, enums, and macros for the MAC
+ */
+
+#ifndef _E1000_MAC_H_
+#define _E1000_MAC_H_
+
+#include "e1000_osdep.h"
+
+/* Forward declarations of structures used by the shared code */
+struct e1000_shared_adapter;
+struct e1000_shared_stats;
+
+/* Enumerated types specific to the e1000 hardware */
+/* Media Access Controlers */
+typedef enum {
+ e1000_82542_rev2_0 = 0,
+ e1000_82542_rev2_1,
+ e1000_82543,
+ e1000_82544,
+ e1000_num_macs
+} e1000_mac_type;
+
+/* Media Types */
+typedef enum {
+ e1000_media_type_copper = 0,
+ e1000_media_type_fiber = 1,
+ e1000_num_media_types
+} e1000_media_type;
+
+typedef enum {
+ e1000_10_half = 0,
+ e1000_10_full = 1,
+ e1000_100_half = 2,
+ e1000_100_full = 3
+} e1000_speed_duplex_type;
+
+/* Flow Control Settings */
+typedef enum {
+ e1000_fc_none = 0,
+ e1000_fc_rx_pause = 1,
+ e1000_fc_tx_pause = 2,
+ e1000_fc_full = 3,
+ e1000_fc_default = 0xFF
+} e1000_fc_type;
+
+/* PCI bus types */
+typedef enum {
+ e1000_bus_type_unknown = 0,
+ e1000_bus_type_pci,
+ e1000_bus_type_pcix
+} e1000_bus_type;
+
+/* PCI bus speeds */
+typedef enum {
+ e1000_bus_speed_unknown = 0,
+ e1000_bus_speed_33,
+ e1000_bus_speed_66,
+ e1000_bus_speed_100,
+ e1000_bus_speed_133,
+ e1000_bus_speed_reserved
+} e1000_bus_speed;
+
+/* PCI bus widths */
+typedef enum {
+ e1000_bus_width_unknown = 0,
+ e1000_bus_width_32,
+ e1000_bus_width_64
+} e1000_bus_width;
+
+
+
+/* Function prototypes */
+/* Setup */
+void e1000_adapter_stop(struct e1000_shared_adapter *shared);
+boolean_t e1000_init_hw(struct e1000_shared_adapter *shared);
+void e1000_init_rx_addrs(struct e1000_shared_adapter *shared);
+
+/* Filters (multicast, vlan, receive) */
+void e1000_mc_addr_list_update(struct e1000_shared_adapter *shared, uint8_t * mc_addr_list, uint32_t mc_addr_count, uint32_t pad);
+uint32_t e1000_hash_mc_addr(struct e1000_shared_adapter *shared, uint8_t * mc_addr);
+void e1000_mta_set(struct e1000_shared_adapter *shared, uint32_t hash_value);
+void e1000_rar_set(struct e1000_shared_adapter *shared, uint8_t * mc_addr, uint32_t rar_index);
+void e1000_write_vfta(struct e1000_shared_adapter *shared, uint32_t offset, uint32_t value);
+void e1000_clear_vfta(struct e1000_shared_adapter *shared);
+
+/* Link layer setup functions */
+boolean_t e1000_setup_fc_and_link(struct e1000_shared_adapter *shared);
+boolean_t e1000_setup_pcs_link(struct e1000_shared_adapter *shared, uint32_t dev_ctrl_reg);
+void e1000_config_fc_after_link_up(struct e1000_shared_adapter *shared);
+void e1000_check_for_link(struct e1000_shared_adapter *shared);
+void e1000_get_speed_and_duplex(struct e1000_shared_adapter *shared, uint16_t * speed, uint16_t * duplex);
+
+/* EEPROM Functions */
+uint16_t e1000_read_eeprom(struct e1000_shared_adapter *shared, uint16_t reg);
+boolean_t e1000_validate_eeprom_checksum(struct e1000_shared_adapter *shared);
+
+/* Everything else */
+void e1000_clear_hw_cntrs(struct e1000_shared_adapter *shared);
+boolean_t e1000_read_part_num(struct e1000_shared_adapter *shared, uint32_t * part_num);
+void e1000_read_mac_addr(struct e1000_shared_adapter * shared);
+void e1000_get_bus_info(struct e1000_shared_adapter *shared);
+uint32_t e1000_tbi_adjust_stats(struct e1000_shared_adapter *shared, struct e1000_shared_stats *stats, uint32_t frame_len, uint8_t * mac_addr);
+void e1000_write_pci_cfg(struct e1000_shared_adapter *shared, uint32_t reg, uint16_t * value);
+
+/* PCI Device IDs */
+#define E1000_DEV_ID_82542 0x1000
+#define E1000_DEV_ID_82543GC_FIBER 0x1001
+#define E1000_DEV_ID_82543GC_COPPER 0x1004
+#define E1000_DEV_ID_82544EI_COPPER 0x1008
+#define E1000_DEV_ID_82544EI_FIBER 0x1009
+#define E1000_DEV_ID_82544GC_COPPER 0x100C
+#define E1000_DEV_ID_82544GC_LOM 0x100D
+#define NUM_DEV_IDS 7
+
+#define NODE_ADDRESS_SIZE 6
+#define ETH_LENGTH_OF_ADDRESS 6
+
+/* MAC decode size is 128K - This is the size of BAR0 */
+#define MAC_DECODE_SIZE (128 * 1024)
+
+#define E1000_82542_2_0_REV_ID 2
+#define E1000_82542_2_1_REV_ID 3
+
+#define SPEED_10 10
+#define SPEED_100 100
+#define SPEED_1000 1000
+#define HALF_DUPLEX 1
+#define FULL_DUPLEX 2
+
+/* The sizes (in bytes) of a ethernet packet */
+#define ENET_HEADER_SIZE 14
+#define MAXIMUM_ETHERNET_PACKET_SIZE 1514 /* Without FCS */
+#define MINIMUM_ETHERNET_PACKET_SIZE 60 /* Without FCS */
+#define CRC_LENGTH 4
+#define MAX_JUMBO_FRAME_SIZE 0x3F00
+
+
+/* 802.1q VLAN Packet Sizes */
+#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMAed) */
+
+/* Ethertype field values */
+#define ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.3ac packet */
+#define ETHERNET_IP_TYPE 0x0800 /* IP packets */
+#define ETHERNET_ARP_TYPE 0x0806 /* Address Resolution Protocol (ARP) */
+
+/* Packet Header defines */
+#define IP_PROTOCOL_TCP 6
+#define IP_PROTOCOL_UDP 0x11
+
+/* This defines the bits that are set in the Interrupt Mask
+ * Set/Read Register. Each bit is documented below:
+ * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
+ * o RXSEQ = Receive Sequence Error
+ */
+#define POLL_IMS_ENABLE_MASK ( \
+ E1000_IMS_RXDMT0 | \
+ E1000_IMS_RXSEQ)
+
+/* This defines the bits that are set in the Interrupt Mask
+ * Set/Read Register. Each bit is documented below:
+ * o RXT0 = Receiver Timer Interrupt (ring 0)
+ * o TXDW = Transmit Descriptor Written Back
+ * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
+ * o RXSEQ = Receive Sequence Error
+ * o LSC = Link Status Change
+ */
+#define IMS_ENABLE_MASK ( \
+ E1000_IMS_RXT0 | \
+ E1000_IMS_TXDW | \
+ E1000_IMS_RXDMT0 | \
+ E1000_IMS_RXSEQ | \
+ E1000_IMS_LSC)
+
+/* The number of high/low register pairs in the RAR. The RAR (Receive Address
+ * Registers) holds the directed and multicast addresses that we monitor. We
+ * reserve one of these spots for our directed address, allowing us room for
+ * E1000_RAR_ENTRIES - 1 multicast addresses.
+ */
+#define E1000_RAR_ENTRIES 16
+
+#define MIN_NUMBER_OF_DESCRIPTORS 8
+#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
+
+/* Receive Descriptor */
+struct e1000_rx_desc {
+ uint64_t buffer_addr; /* Address of the descriptor's data buffer */
+ uint16_t length; /* Length of data DMAed into data buffer */
+ uint16_t csum; /* Packet checksum */
+ uint8_t status; /* Descriptor status */
+ uint8_t errors; /* Descriptor Errors */
+ uint16_t special;
+};
+
+/* Receive Decriptor bit definitions */
+#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
+#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
+#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
+#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
+#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
+#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
+#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */
+#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
+#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
+#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
+#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */
+#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */
+#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */
+#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
+#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
+#define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */
+#define E1000_RXD_SPC_PRI_SHIFT 0x000D /* Priority is in upper 3 of 16 */
+#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */
+#define E1000_RXD_SPC_CFI_SHIFT 0x000C /* CFI is bit 12 */
+
+/* mask to determine if packets should be dropped due to frame errors */
+#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
+ E1000_RXD_ERR_CE | \
+ E1000_RXD_ERR_SE | \
+ E1000_RXD_ERR_SEQ | \
+ E1000_RXD_ERR_CXE | \
+ E1000_RXD_ERR_RXE)
+
+/* Transmit Descriptor */
+struct e1000_tx_desc {
+ uint64_t buffer_addr; /* Address of the descriptor's data buffer */
+ union {
+ uint32_t data;
+ struct {
+ uint16_t length; /* Data buffer length */
+ uint8_t cso; /* Checksum offset */
+ uint8_t cmd; /* Descriptor control */
+ } flags;
+ } lower;
+ union {
+ uint32_t data;
+ struct {
+ uint8_t status; /* Descriptor status */
+ uint8_t css; /* Checksum start */
+ uint16_t special;
+ } fields;
+ } upper;
+};
+
+/* Transmit Descriptor bit definitions */
+#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */
+#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */
+#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
+#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
+#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */
+#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
+#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */
+#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */
+#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */
+#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */
+#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
+#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */
+#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
+#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */
+#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */
+#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */
+#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */
+#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */
+#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */
+#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
+
+/* Offload Context Descriptor */
+struct e1000_context_desc {
+ union {
+ uint32_t ip_config;
+ struct {
+ uint8_t ipcss; /* IP checksum start */
+ uint8_t ipcso; /* IP checksum offset */
+ uint16_t ipcse; /* IP checksum end */
+ } ip_fields;
+ } lower_setup;
+ union {
+ uint32_t tcp_config;
+ struct {
+ uint8_t tucss; /* TCP checksum start */
+ uint8_t tucso; /* TCP checksum offset */
+ uint16_t tucse; /* TCP checksum end */
+ } tcp_fields;
+ } upper_setup;
+ uint32_t cmd_and_length; /* */
+ union {
+ uint32_t data;
+ struct {
+ uint8_t status; /* Descriptor status */
+ uint8_t hdr_len; /* Header length */
+ uint16_t mss; /* Maximum segment size */
+ } fields;
+ } tcp_seg_setup;
+};
+
+/* Offload data descriptor */
+struct e1000_data_desc {
+ uint64_t buffer_addr; /* Address of the descriptor's buffer address */
+ union {
+ uint32_t data;
+ struct {
+ uint16_t length; /* Data buffer length */
+ uint8_t typ_len_ext; /* */
+ uint8_t cmd; /* */
+ } flags;
+ } lower;
+ union {
+ uint32_t data;
+ struct {
+ uint8_t status; /* Descriptor status */
+ uint8_t popts; /* Packet Options */
+ uint16_t special; /* */
+ } fields;
+ } upper;
+};
+
+/* Filters */
+#define E1000_NUM_UNICAST 16 /* Unicast filter entries */
+#define E1000_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */
+#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
+
+
+/* Receive Address Register */
+struct e1000_rar {
+ volatile uint32_t low; /* receive address low */
+ volatile uint32_t high; /* receive address high */
+};
+
+/* The number of entries in the Multicast Table Array (MTA). */
+#define E1000_NUM_MTA_REGISTERS 128
+
+/* IPv4 Address Table Entry */
+struct e1000_ipv4_at_entry {
+ volatile uint32_t ipv4_addr; /* IP Address (RW) */
+ volatile uint32_t reserved;
+};
+
+/* Four wakeup IP addresses are supported */
+#define E1000_WAKEUP_IP_ADDRESS_COUNT_MAX 4
+#define E1000_IP4AT_SIZE E1000_WAKEUP_IP_ADDRESS_COUNT_MAX
+#define E1000_IP6AT_SIZE 1
+
+/* IPv6 Address Table Entry */
+struct e1000_ipv6_at_entry {
+ volatile uint8_t ipv6_addr[16];
+};
+
+/* Flexible Filter Length Table Entry */
+struct e1000_fflt_entry {
+ volatile uint32_t length; /* Flexible Filter Length (RW) */
+ volatile uint32_t reserved;
+};
+
+/* Flexible Filter Mask Table Entry */
+struct e1000_ffmt_entry {
+ volatile uint32_t mask; /* Flexible Filter Mask (RW) */
+ volatile uint32_t reserved;
+};
+
+/* Flexible Filter Value Table Entry */
+struct e1000_ffvt_entry {
+ volatile uint32_t value; /* Flexible Filter Value (RW) */
+ volatile uint32_t reserved;
+};
+
+/* Four Flexible Filters are supported */
+#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
+
+/* Each Flexible Filter is at most 128 (0x80) bytes in length */
+#define E1000_FLEXIBLE_FILTER_SIZE_MAX 128
+
+#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX
+#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
+#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
+
+/* Register Set. (82543, 82544)
+ *
+ * Registers are defined to be 32 bits and should be accessed as 32 bit values.
+ * These registers are physically located on the NIC, but are mapped into the
+ * host memory address space.
+ *
+ * RW - register is both readable and writable
+ * RO - register is read only
+ * WO - register is write only
+ * R/clr - register is read only and is cleared when read
+ * A - register array
+ */
+#define E1000_CTRL 0x00000 /* Device Control - RW */
+#define E1000_STATUS 0x00008 /* Device Status - RO */
+#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
+#define E1000_EERD 0x00014 /* EEPROM Read - RW */
+#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
+#define E1000_MDIC 0x00020 /* MDI Control - RW */
+#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
+#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
+#define E1000_FCT 0x00030 /* Flow Control Type - RW */
+#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
+#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
+#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
+#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
+#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
+#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
+#define E1000_RCTL 0x00100 /* RX Control - RW */
+#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
+#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
+#define E1000_RXCW 0x00180 /* RX Configuration Word - RO */
+#define E1000_TCTL 0x00400 /* TX Control - RW */
+#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
+#define E1000_TBT 0x00448 /* TX Burst Timer - RW */
+#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
+#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
+#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
+#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
+#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */
+#define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */
+#define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */
+#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */
+#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */
+#define E1000_RDTR 0x02820 /* RX Delay Timer - RW */
+#define E1000_RXDCTL 0x02828 /* RX Descriptor Control - RW */
+#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */
+#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */
+#define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */
+#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
+#define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */
+#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
+#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */
+#define E1000_TDT 0x03818 /* TX Descripotr Tail - RW */
+#define E1000_TIDV 0x03820 /* TX Interrupt Delay Value - RW */
+#define E1000_TXDCTL 0x03828 /* TX Descriptor Control - RW */
+#define E1000_TADV 0x0382C /* TX Interrupt Absolute Delay Val - RW */
+#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
+#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
+#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
+#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
+#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
+#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
+#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
+#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
+#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
+#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
+#define E1000_COLC 0x04028 /* Collision Count - R/clr */
+#define E1000_DC 0x04030 /* Defer Count - R/clr */
+#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */
+#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
+#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
+#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
+#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */
+#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */
+#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */
+#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */
+#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/clr */
+#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */
+#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */
+#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */
+#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */
+#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */
+#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */
+#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */
+#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */
+#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */
+#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */
+#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */
+#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */
+#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */
+#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */
+#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */
+#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */
+#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */
+#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */
+#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */
+#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */
+#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
+#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */
+#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */
+#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */
+#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */
+#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */
+#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */
+#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */
+#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */
+#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */
+#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */
+#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */
+#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */
+#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */
+#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */
+#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
+#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
+#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */
+#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
+#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
+#define E1000_RA 0x05400 /* Receive Address - RW Array */
+#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
+#define E1000_WUC 0x05800 /* Wakeup Control - RW */
+#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
+#define E1000_WUS 0x05810 /* Wakeup Status - RO */
+#define E1000_MANC 0x05820 /* Management Control - RW */
+#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
+#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */
+#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */
+#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
+#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */
+#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */
+#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
+#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
+
+/* Register Set (82542)
+ *
+ * Some of the 82542 registers are located at different offsets than they are
+ * in more current versions of the 8254x. Despite the difference in location,
+ * the registers function in the same manner.
+ */
+#define E1000_82542_CTRL E1000_CTRL
+#define E1000_82542_STATUS E1000_STATUS
+#define E1000_82542_EECD E1000_EECD
+#define E1000_82542_EERD E1000_EERD
+#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
+#define E1000_82542_MDIC E1000_MDIC
+#define E1000_82542_FCAL E1000_FCAL
+#define E1000_82542_FCAH E1000_FCAH
+#define E1000_82542_FCT E1000_FCT
+#define E1000_82542_VET E1000_VET
+#define E1000_82542_RA 0x00040
+#define E1000_82542_ICR E1000_ICR
+#define E1000_82542_ITR E1000_ITR
+#define E1000_82542_ICS E1000_ICS
+#define E1000_82542_IMS E1000_IMS
+#define E1000_82542_IMC E1000_IMC
+#define E1000_82542_RCTL E1000_RCTL
+#define E1000_82542_RDTR 0x00108
+#define E1000_82542_RDBAL 0x00110
+#define E1000_82542_RDBAH 0x00114
+#define E1000_82542_RDLEN 0x00118
+#define E1000_82542_RDH 0x00120
+#define E1000_82542_RDT 0x00128
+#define E1000_82542_FCRTH 0x00160
+#define E1000_82542_FCRTL 0x00168
+#define E1000_82542_FCTTV E1000_FCTTV
+#define E1000_82542_TXCW E1000_TXCW
+#define E1000_82542_RXCW E1000_RXCW
+#define E1000_82542_MTA 0x00200
+#define E1000_82542_TCTL E1000_TCTL
+#define E1000_82542_TIPG E1000_TIPG
+#define E1000_82542_TDBAL 0x00420
+#define E1000_82542_TDBAH 0x00424
+#define E1000_82542_TDLEN 0x00428
+#define E1000_82542_TDH 0x00430
+#define E1000_82542_TDT 0x00438
+#define E1000_82542_TIDV 0x00440
+#define E1000_82542_TBT E1000_TBT
+#define E1000_82542_VFTA 0x00600
+#define E1000_82542_LEDCTL E1000_LEDCTL
+#define E1000_82542_PBA E1000_PBA
+#define E1000_82542_RXDCTL E1000_RXDCTL
+#define E1000_82542_RADV E1000_RADV
+#define E1000_82542_RSRPD E1000_RSRPD
+#define E1000_82542_TXDMAC E1000_TXDMAC
+#define E1000_82542_TXDCTL E1000_TXDCTL
+#define E1000_82542_TADV E1000_TADV
+#define E1000_82542_TSPMT E1000_TSPMT
+#define E1000_82542_CRCERRS E1000_CRCERRS
+#define E1000_82542_ALGNERRC E1000_ALGNERRC
+#define E1000_82542_SYMERRS E1000_SYMERRS
+#define E1000_82542_RXERRC E1000_RXERRC
+#define E1000_82542_MPC E1000_MPC
+#define E1000_82542_SCC E1000_SCC
+#define E1000_82542_ECOL E1000_ECOL
+#define E1000_82542_MCC E1000_MCC
+#define E1000_82542_LATECOL E1000_LATECOL
+#define E1000_82542_COLC E1000_COLC
+#define E1000_82542_DC E1000_DC
+#define E1000_82542_TNCRS E1000_TNCRS
+#define E1000_82542_SEC E1000_SEC
+#define E1000_82542_CEXTERR E1000_CEXTERR
+#define E1000_82542_RLEC E1000_RLEC
+#define E1000_82542_XONRXC E1000_XONRXC
+#define E1000_82542_XONTXC E1000_XONTXC
+#define E1000_82542_XOFFRXC E1000_XOFFRXC
+#define E1000_82542_XOFFTXC E1000_XOFFTXC
+#define E1000_82542_FCRUC E1000_FCRUC
+#define E1000_82542_PRC64 E1000_PRC64
+#define E1000_82542_PRC127 E1000_PRC127
+#define E1000_82542_PRC255 E1000_PRC255
+#define E1000_82542_PRC511 E1000_PRC511
+#define E1000_82542_PRC1023 E1000_PRC1023
+#define E1000_82542_PRC1522 E1000_PRC1522
+#define E1000_82542_GPRC E1000_GPRC
+#define E1000_82542_BPRC E1000_BPRC
+#define E1000_82542_MPRC E1000_MPRC
+#define E1000_82542_GPTC E1000_GPTC
+#define E1000_82542_GORCL E1000_GORCL
+#define E1000_82542_GORCH E1000_GORCH
+#define E1000_82542_GOTCL E1000_GOTCL
+#define E1000_82542_GOTCH E1000_GOTCH
+#define E1000_82542_RNBC E1000_RNBC
+#define E1000_82542_RUC E1000_RUC
+#define E1000_82542_RFC E1000_RFC
+#define E1000_82542_ROC E1000_ROC
+#define E1000_82542_RJC E1000_RJC
+#define E1000_82542_MGTPRC E1000_MGTPRC
+#define E1000_82542_MGTPDC E1000_MGTPDC
+#define E1000_82542_MGTPTC E1000_MGTPTC
+#define E1000_82542_TORL E1000_TORL
+#define E1000_82542_TORH E1000_TORH
+#define E1000_82542_TOTL E1000_TOTL
+#define E1000_82542_TOTH E1000_TOTH
+#define E1000_82542_TPR E1000_TPR
+#define E1000_82542_TPT E1000_TPT
+#define E1000_82542_PTC64 E1000_PTC64
+#define E1000_82542_PTC127 E1000_PTC127
+#define E1000_82542_PTC255 E1000_PTC255
+#define E1000_82542_PTC511 E1000_PTC511
+#define E1000_82542_PTC1023 E1000_PTC1023
+#define E1000_82542_PTC1522 E1000_PTC1522
+#define E1000_82542_MPTC E1000_MPTC
+#define E1000_82542_BPTC E1000_BPTC
+#define E1000_82542_TSCTC E1000_TSCTC
+#define E1000_82542_TSCTFC E1000_TSCTFC
+#define E1000_82542_RXCSUM E1000_RXCSUM
+#define E1000_82542_WUC E1000_WUC
+#define E1000_82542_WUFC E1000_WUFC
+#define E1000_82542_WUS E1000_WUS
+#define E1000_82542_MANC E1000_MANC
+#define E1000_82542_IPAV E1000_IPAV
+#define E1000_82542_IP4AT E1000_IP4AT
+#define E1000_82542_IP6AT E1000_IP6AT
+#define E1000_82542_WUPL E1000_WUPL
+#define E1000_82542_WUPM E1000_WUPM
+#define E1000_82542_FFLT E1000_FFLT
+#define E1000_82542_FFMT E1000_FFMT
+#define E1000_82542_FFVT E1000_FFVT
+
+/* Statistics counters collected by the MAC */
+struct e1000_shared_stats {
+ uint64_t crcerrs;
+ uint64_t algnerrc;
+ uint64_t symerrs;
+ uint64_t rxerrc;
+ uint64_t mpc;
+ uint64_t scc;
+ uint64_t ecol;
+ uint64_t mcc;
+ uint64_t latecol;
+ uint64_t colc;
+ uint64_t dc;
+ uint64_t tncrs;
+ uint64_t sec;
+ uint64_t cexterr;
+ uint64_t rlec;
+ uint64_t xonrxc;
+ uint64_t xontxc;
+ uint64_t xoffrxc;
+ uint64_t xofftxc;
+ uint64_t fcruc;
+ uint64_t prc64;
+ uint64_t prc127;
+ uint64_t prc255;
+ uint64_t prc511;
+ uint64_t prc1023;
+ uint64_t prc1522;
+ uint64_t gprc;
+ uint64_t bprc;
+ uint64_t mprc;
+ uint64_t gptc;
+ uint64_t gorcl;
+ uint64_t gorch;
+ uint64_t gotcl;
+ uint64_t gotch;
+ uint64_t rnbc;
+ uint64_t ruc;
+ uint64_t rfc;
+ uint64_t roc;
+ uint64_t rjc;
+ uint64_t mgprc;
+ uint64_t mgpdc;
+ uint64_t mgptc;
+ uint64_t torl;
+ uint64_t torh;
+ uint64_t totl;
+ uint64_t toth;
+ uint64_t tpr;
+ uint64_t tpt;
+ uint64_t ptc64;
+ uint64_t ptc127;
+ uint64_t ptc255;
+ uint64_t ptc511;
+ uint64_t ptc1023;
+ uint64_t ptc1522;
+ uint64_t mptc;
+ uint64_t bptc;
+ uint64_t tsctc;
+ uint64_t tsctfc;
+};
+
+/* Structure containing variables used by the shared code (e1000_mac.c and
+ * e1000_phy.c)
+ */
+struct e1000_shared_adapter {
+ uint8_t *hw_addr;
+ e1000_mac_type mac_type;
+ e1000_media_type media_type;
+ void *back;
+ e1000_fc_type fc;
+ e1000_bus_speed bus_speed;
+ e1000_bus_width bus_width;
+ e1000_bus_type bus_type;
+ uint32_t phy_id;
+ uint32_t phy_addr;
+ uint32_t original_fc;
+ uint32_t txcw_reg;
+ uint32_t autoneg_failed;
+ uint32_t max_frame_size;
+ uint32_t min_frame_size;
+ uint32_t mc_filter_type;
+ uint32_t num_mc_addrs;
+ uint16_t autoneg_advertised;
+ uint16_t pci_cmd_word;
+ uint16_t fc_high_water;
+ uint16_t fc_low_water;
+ uint16_t fc_pause_time;
+ uint16_t device_id;
+ uint16_t vendor_id;
+ uint16_t subsystem_id;
+ uint16_t subsystem_vendor_id;
+ uint8_t revision_id;
+ boolean_t disable_polarity_correction;
+ boolean_t get_link_status;
+ boolean_t tbi_compatibility_en;
+ boolean_t tbi_compatibility_on;
+ boolean_t adapter_stopped;
+ boolean_t fc_send_xon;
+ boolean_t report_tx_early;
+ uint8_t autoneg;
+ uint8_t mdix;
+ uint8_t forced_speed_duplex;
+ uint8_t wait_autoneg_complete;
+ uint8_t dma_fairness;
+ uint8_t mac_addr[NODE_ADDRESS_SIZE];
+ uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
+};
+
+
+#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */
+#define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */
+
+/* Register Bit Masks */
+/* Device Control */
+#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
+#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */
+#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */
+#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
+#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */
+#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */
+#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */
+#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */
+#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */
+#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */
+#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */
+#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */
+#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */
+#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */
+#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
+#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
+#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
+#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
+#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
+#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */
+#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */
+#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */
+#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */
+#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */
+#define E1000_CTRL_RST 0x04000000 /* Global reset */
+#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */
+#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */
+#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */
+#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */
+#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */
+
+/* Device Status */
+#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
+#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
+#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */
+#define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */
+#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */
+#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */
+#define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */
+#define E1000_STATUS_SPEED_MASK 0x000000C0
+#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */
+#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
+#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
+#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */
+#define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */
+#define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */
+#define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */
+#define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */
+#define E1000_STATUS_PCIX_SPEED 0x0000C000 /* PCI-X bus speed */
+
+/* Constants used to intrepret the masked PCI-X bus speed. */
+#define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */
+#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed 66-100 MHz */
+#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /* PCI-X bus speed 100-133 MHz */
+
+/* EEPROM/Flash Control */
+#define E1000_EECD_SK 0x00000001 /* EEPROM Clock */
+#define E1000_EECD_CS 0x00000002 /* EEPROM Chip Select */
+#define E1000_EECD_DI 0x00000004 /* EEPROM Data In */
+#define E1000_EECD_DO 0x00000008 /* EEPROM Data Out */
+#define E1000_EECD_FWE_MASK 0x00000030
+#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */
+#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */
+#define E1000_EECD_FWE_SHIFT 4
+#define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
+#define E1000_EECD_REQ 0x00000040 /* EEPROM Access Request */
+#define E1000_EECD_GNT 0x00000080 /* EEPROM Access Grant */
+#define E1000_EECD_PRES 0x00000100 /* EEPROM Present */
+
+/* EEPROM Read */
+#define E1000_EERD_START 0x00000001 /* Start Read */
+#define E1000_EERD_DONE 0x00000010 /* Read Done */
+#define E1000_EERD_ADDR_SHIFT 8
+#define E1000_EERD_ADDR_MASK 0x0000FF00 /* Read Address */
+#define E1000_EERD_DATA_SHIFT 16
+#define E1000_EERD_DATA_MASK 0xFFFF0000 /* Read Data */
+
+/* Extended Device Control */
+#define E1000_CTRL_EXT_GPI0_EN 0x00000001 /* Maps SDP4 to GPI0 */
+#define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */
+#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN
+#define E1000_CTRL_EXT_GPI2_EN 0x00000004 /* Maps SDP6 to GPI2 */
+#define E1000_CTRL_EXT_GPI3_EN 0x00000008 /* Maps SDP7 to GPI3 */
+#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Defineable Pin 4 */
+#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Defineable Pin 5 */
+#define E1000_CTRL_EXT_PHY_INT E1000_CTRL_EXT_SDP5_DATA
+#define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Defineable Pin 6 */
+#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
+#define E1000_CTRL_EXT_SDP4_DIR 0x00000100 /* Direction of SDP4 0=in 1=out */
+#define E1000_CTRL_EXT_SDP5_DIR 0x00000200 /* Direction of SDP5 0=in 1=out */
+#define E1000_CTRL_EXT_SDP6_DIR 0x00000400 /* Direction of SDP6 0=in 1=out */
+#define E1000_CTRL_EXT_SDP7_DIR 0x00000800 /* Direction of SDP7 0=in 1=out */
+#define E1000_CTRL_EXT_ASDCHK 0x00001000 /* Initiate an ASD sequence */
+#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
+#define E1000_CTRL_EXT_IPS 0x00004000 /* Invert Power State */
+#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
+#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
+#define E1000_CTRL_EXT_LINK_MODE_TBI 0x00C00000
+#define E1000_CTRL_EXT_WR_WMARK_MASK 0x03000000
+#define E1000_CTRL_EXT_WR_WMARK_256 0x00000000
+#define E1000_CTRL_EXT_WR_WMARK_320 0x01000000
+#define E1000_CTRL_EXT_WR_WMARK_384 0x02000000
+#define E1000_CTRL_EXT_WR_WMARK_448 0x03000000
+
+/* MDI Control */
+#define E1000_MDIC_DATA_MASK 0x0000FFFF
+#define E1000_MDIC_REG_MASK 0x001F0000
+#define E1000_MDIC_REG_SHIFT 16
+#define E1000_MDIC_PHY_MASK 0x03E00000
+#define E1000_MDIC_PHY_SHIFT 21
+#define E1000_MDIC_OP_WRITE 0x04000000
+#define E1000_MDIC_OP_READ 0x08000000
+#define E1000_MDIC_READY 0x10000000
+#define E1000_MDIC_INT_EN 0x20000000
+#define E1000_MDIC_ERROR 0x40000000
+
+/* LED Control */
+#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
+#define E1000_LEDCTL_LED0_MODE_SHIFT 0
+#define E1000_LEDCTL_LED0_IVRT 0x00000040
+#define E1000_LEDCTL_LED0_BLINK 0x00000080
+#define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00
+#define E1000_LEDCTL_LED1_MODE_SHIFT 8
+#define E1000_LEDCTL_LED1_IVRT 0x00004000
+#define E1000_LEDCTL_LED1_BLINK 0x00008000
+#define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000
+#define E1000_LEDCTL_LED2_MODE_SHIFT 16
+#define E1000_LEDCTL_LED2_IVRT 0x00400000
+#define E1000_LEDCTL_LED2_BLINK 0x00800000
+#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000
+#define E1000_LEDCTL_LED3_MODE_SHIFT 24
+#define E1000_LEDCTL_LED3_IVRT 0x40000000
+#define E1000_LEDCTL_LED3_BLINK 0x80000000
+
+#define E1000_LEDCTL_MODE_LINK_10_1000 0x0
+#define E1000_LEDCTL_MODE_LINK_100_1000 0x1
+#define E1000_LEDCTL_MODE_LINK_UP 0x2
+#define E1000_LEDCTL_MODE_ACTIVITY 0x3
+#define E1000_LEDCTL_MODE_LINK_ACTIVITY 0x4
+#define E1000_LEDCTL_MODE_LINK_10 0x5
+#define E1000_LEDCTL_MODE_LINK_100 0x6
+#define E1000_LEDCTL_MODE_LINK_1000 0x7
+#define E1000_LEDCTL_MODE_PCIX_MODE 0x8
+#define E1000_LEDCTL_MODE_FULL_DUPLEX 0x9
+#define E1000_LEDCTL_MODE_COLLISION 0xA
+#define E1000_LEDCTL_MODE_BUS_SPEED 0xB
+#define E1000_LEDCTL_MODE_BUS_SIZE 0xC
+#define E1000_LEDCTL_MODE_PAUSED 0xD
+#define E1000_LEDCTL_MODE_LED_ON 0xE
+#define E1000_LEDCTL_MODE_LED_OFF 0xF
+
+/* Receive Address */
+#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
+
+/* Interrupt Cause Read */
+#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
+#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
+#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
+#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */
+#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
+#define E1000_ICR_RXO 0x00000040 /* rx overrun */
+#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
+#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
+#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */
+#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
+#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */
+#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */
+#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
+#define E1000_ICR_TXD_LOW 0x00008000
+#define E1000_ICR_SRPD 0x00010000
+
+/* Interrupt Cause Set */
+#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
+#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
+#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
+#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
+#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
+#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */
+#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
+#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */
+#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
+#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
+#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
+#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
+#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
+#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
+#define E1000_ICS_SRPD E1000_ICR_SRPD
+
+/* Interrupt Mask Set */
+#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
+#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
+#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
+#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
+#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
+#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */
+#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
+#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */
+#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
+#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
+#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
+#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
+#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
+#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
+#define E1000_IMS_SRPD E1000_ICR_SRPD
+
+/* Interrupt Mask Clear */
+#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */
+#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
+#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */
+#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
+#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
+#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */
+#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */
+#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */
+#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
+#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
+#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
+#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
+#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
+#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
+#define E1000_IMC_SRPD E1000_ICR_SRPD
+
+/* Receive Control */
+#define E1000_RCTL_RST 0x00000001 /* Software reset */
+#define E1000_RCTL_EN 0x00000002 /* enable */
+#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
+#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
+#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
+#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
+#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
+#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
+#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */
+#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
+#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
+#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */
+#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */
+#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
+#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */
+#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */
+#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */
+#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
+#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */
+#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
+#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */
+#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */
+#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */
+#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
+#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */
+#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */
+#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */
+#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
+#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
+#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */
+#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */
+#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
+#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
+
+/* Receive Descriptor */
+#define E1000_RDT_DELAY 0x0000ffff /* Delay timer (1=1024us) */
+#define E1000_RDT_FPDB 0x80000000 /* Flush descriptor block */
+#define E1000_RDLEN_LEN 0x0007ff80 /* descriptor length */
+#define E1000_RDH_RDH 0x0000ffff /* receive descriptor head */
+#define E1000_RDT_RDT 0x0000ffff /* receive descriptor tail */
+
+/* Flow Control */
+#define E1000_FCRTH_RTH 0x0000FFF8 /* Mask Bits[15:3] for RTH */
+#define E1000_FCRTH_XFCE 0x80000000 /* External Flow Control Enable */
+#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */
+#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
+
+/* Receive Descriptor Control */
+#define E1000_RXDCTL_PTHRESH 0x0000003F /* RXDCTL Prefetch Threshold */
+#define E1000_RXDCTL_HTHRESH 0x00003F00 /* RXDCTL Host Threshold */
+#define E1000_RXDCTL_WTHRESH 0x003F0000 /* RXDCTL Writeback Threshold */
+#define E1000_RXDCTL_GRAN 0x01000000 /* RXDCTL Granularity */
+
+/* Transmit Descriptor Control */
+#define E1000_TXDCTL_PTHRESH 0x000000FF /* TXDCTL Prefetch Threshold */
+#define E1000_TXDCTL_HTHRESH 0x0000FF00 /* TXDCTL Host Threshold */
+#define E1000_TXDCTL_WTHRESH 0x00FF0000 /* TXDCTL Writeback Threshold */
+#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */
+#define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */
+
+/* Transmit Configuration Word */
+#define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */
+#define E1000_TXCW_HD 0x00000040 /* TXCW half duplex */
+#define E1000_TXCW_PAUSE 0x00000080 /* TXCW sym pause request */
+#define E1000_TXCW_ASM_DIR 0x00000100 /* TXCW astm pause direction */
+#define E1000_TXCW_PAUSE_MASK 0x00000180 /* TXCW pause request mask */
+#define E1000_TXCW_RF 0x00003000 /* TXCW remote fault */
+#define E1000_TXCW_NP 0x00008000 /* TXCW next page */
+#define E1000_TXCW_CW 0x0000ffff /* TxConfigWord mask */
+#define E1000_TXCW_TXC 0x40000000 /* Transmit Config control */
+#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */
+
+/* Receive Configuration Word */
+#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */
+#define E1000_RXCW_NC 0x04000000 /* Receive config no carrier */
+#define E1000_RXCW_IV 0x08000000 /* Receive config invalid */
+#define E1000_RXCW_CC 0x10000000 /* Receive config change */
+#define E1000_RXCW_C 0x20000000 /* Receive config */
+#define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */
+#define E1000_RXCW_ANC 0x80000000 /* Auto-neg complete */
+
+/* Transmit Control */
+#define E1000_TCTL_RST 0x00000001 /* software reset */
+#define E1000_TCTL_EN 0x00000002 /* enable tx */
+#define E1000_TCTL_BCE 0x00000004 /* busy check enable */
+#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
+#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
+#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
+#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */
+#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */
+#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
+#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */
+
+/* Receive Checksum Control */
+#define E1000_RXCSUM_PCSS_MASK 0x000000FF /* Packet Checksum Start */
+#define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */
+#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */
+#define E1000_RXCSUM_IPV6OFL 0x00000400 /* IPv6 checksum offload */
+
+/* Definitions for power management and wakeup registers */
+/* Wake Up Control */
+#define E1000_WUC_APME 0x00000001 /* APM Enable */
+#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */
+#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */
+#define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */
+
+/* Wake Up Filter Control */
+#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
+#define E1000_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
+#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
+#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */
+#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
+#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
+#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
+#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
+#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
+#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
+#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
+#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
+#define E1000_WUFC_ALL_FILTERS 0x000F00FF /* Mask for all wakeup filters */
+#define E1000_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
+#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
+
+/* Wake Up Status */
+#define E1000_WUS_LNKC 0x00000001 /* Link Status Changed */
+#define E1000_WUS_MAG 0x00000002 /* Magic Packet Received */
+#define E1000_WUS_EX 0x00000004 /* Directed Exact Received */
+#define E1000_WUS_MC 0x00000008 /* Directed Multicast Received */
+#define E1000_WUS_BC 0x00000010 /* Broadcast Received */
+#define E1000_WUS_ARP 0x00000020 /* ARP Request Packet Received */
+#define E1000_WUS_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Received */
+#define E1000_WUS_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Received */
+#define E1000_WUS_FLX0 0x00010000 /* Flexible Filter 0 Match */
+#define E1000_WUS_FLX1 0x00020000 /* Flexible Filter 1 Match */
+#define E1000_WUS_FLX2 0x00040000 /* Flexible Filter 2 Match */
+#define E1000_WUS_FLX3 0x00080000 /* Flexible Filter 3 Match */
+#define E1000_WUS_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
+
+/* Management Control */
+#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
+#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
+#define E1000_MANC_R_ON_FORCE 0x00000004 /* Reset on Force TCO - RO */
+#define E1000_MANC_RMCP_EN 0x00000100 /* Enable RCMP 026Fh Filtering */
+#define E1000_MANC_0298_EN 0x00000200 /* Enable RCMP 0298h Filtering */
+#define E1000_MANC_IPV4_EN 0x00000400 /* Enable IPv4 */
+#define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */
+#define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */
+#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
+#define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery
+ * Filtering */
+#define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */
+#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
+#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
+#define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */
+#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */
+#define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */
+#define E1000_MANC_SMB_DATA_IN 0x08000000 /* SMBus Data In */
+#define E1000_MANC_SMB_DATA_OUT 0x10000000 /* SMBus Data Out */
+#define E1000_MANC_SMB_CLK_OUT 0x20000000 /* SMBus Clock Out */
+
+#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */
+#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */
+
+/* Wake Up Packet Length */
+#define E1000_WUPL_LENGTH_MASK 0x0FFF /* Only the lower 12 bits are valid */
+
+#define E1000_MDALIGN 4096
+
+/* EEPROM Commands */
+#define EEPROM_READ_OPCODE 0x6 /* EERPOM read opcode */
+#define EEPROM_WRITE_OPCODE 0x5 /* EERPOM write opcode */
+#define EEPROM_ERASE_OPCODE 0x7 /* EERPOM erase opcode */
+#define EEPROM_EWEN_OPCODE 0x13 /* EERPOM erase/write enable */
+#define EEPROM_EWDS_OPCODE 0x10 /* EERPOM erast/write disable */
+
+/* EEPROM Word Offsets */
+#define EEPROM_INIT_CONTROL1_REG 0x000A
+#define EEPROM_INIT_CONTROL2_REG 0x000F
+#define EEPROM_FLASH_VERSION 0x0032
+#define EEPROM_CHECKSUM_REG 0x003F
+
+/* Mask bits for fields in Word 0x0a of the EEPROM */
+#define EEPROM_WORD0A_ILOS 0x0010
+#define EEPROM_WORD0A_SWDPIO 0x01E0
+#define EEPROM_WORD0A_LRST 0x0200
+#define EEPROM_WORD0A_FD 0x0400
+#define EEPROM_WORD0A_66MHZ 0x0800
+
+/* Mask bits for fields in Word 0x0f of the EEPROM */
+#define EEPROM_WORD0F_PAUSE_MASK 0x3000
+#define EEPROM_WORD0F_PAUSE 0x1000
+#define EEPROM_WORD0F_ASM_DIR 0x2000
+#define EEPROM_WORD0F_ANE 0x0800
+#define EEPROM_WORD0F_SWPDIO_EXT 0x00F0
+
+/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
+#define EEPROM_SUM 0xBABA
+
+/* EEPROM Map defines (WORD OFFSETS)*/
+#define EEPROM_NODE_ADDRESS_BYTE_0 0
+#define EEPROM_PBA_BYTE_1 8
+
+/* EEPROM Map Sizes (Byte Counts) */
+#define PBA_SIZE 4
+
+/* Collision related configuration parameters */
+#define E1000_COLLISION_THRESHOLD 16
+#define E1000_CT_SHIFT 4
+#define E1000_FDX_COLLISION_DISTANCE 64
+#define E1000_HDX_COLLISION_DISTANCE 64
+#define E1000_GB_HDX_COLLISION_DISTANCE 512
+#define E1000_COLD_SHIFT 12
+
+/* The number of Transmit and Receive Descriptors must be a multiple of 8 */
+#define REQ_TX_DESCRIPTOR_MULTIPLE 8
+#define REQ_RX_DESCRIPTOR_MULTIPLE 8
+
+/* Default values for the transmit IPG register */
+#define DEFAULT_82542_TIPG_IPGT 10
+#define DEFAULT_82543_TIPG_IPGT_FIBER 9
+#define DEFAULT_82543_TIPG_IPGT_COPPER 8
+
+#define E1000_TIPG_IPGT_MASK 0x000003FF
+#define E1000_TIPG_IPGR1_MASK 0x000FFC00
+#define E1000_TIPG_IPGR2_MASK 0x3FF00000
+
+#define DEFAULT_82542_TIPG_IPGR1 2
+#define DEFAULT_82543_TIPG_IPGR1 8
+#define E1000_TIPG_IPGR1_SHIFT 10
+
+#define DEFAULT_82542_TIPG_IPGR2 10
+#define DEFAULT_82543_TIPG_IPGR2 6
+#define E1000_TIPG_IPGR2_SHIFT 20
+
+#define E1000_TXDMAC_DPP 0x00000001
+
+/* PBA constants */
+#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
+#define E1000_PBA_24K 0x0018
+#define E1000_PBA_40K 0x0028
+#define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */
+
+/* Flow Control Constants */
+#define FLOW_CONTROL_ADDRESS_LOW 0x00C28001
+#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
+#define FLOW_CONTROL_TYPE 0x8808
+
+/* The historical defaults for the flow control values are given below. */
+#define FC_DEFAULT_HI_THRESH (0x8000) /* 32KB */
+#define FC_DEFAULT_LO_THRESH (0x4000) /* 16KB */
+#define FC_DEFAULT_TX_TIMER (0x100) /* ~130 us */
+
+
+/* The number of bits that we need to shift right to move the "pause"
+ * bits from the EEPROM (bits 13:12) to the "pause" (bits 8:7) field
+ * in the TXCW register
+ */
+#define PAUSE_SHIFT 5
+
+/* The number of bits that we need to shift left to move the "SWDPIO"
+ * bits from the EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field
+ * in the CTRL register
+ */
+#define SWDPIO_SHIFT 17
+
+/* The number of bits that we need to shift left to move the "SWDPIO_EXT"
+ * bits from the EEPROM word F (bits 7:4) to the bits 11:8 of The
+ * Extended CTRL register.
+ * in the CTRL register
+ */
+#define SWDPIO__EXT_SHIFT 4
+
+/* The number of bits that we need to shift left to move the "ILOS"
+ * bit from the EEPROM (bit 4) to the "ILOS" (bit 7) field
+ * in the CTRL register
+ */
+#define ILOS_SHIFT 3
+
+
+#define RECEIVE_BUFFER_ALIGN_SIZE (256)
+
+/* The number of milliseconds we wait for auto-negotiation to complete */
+#define LINK_UP_TIMEOUT 500
+
+#define E1000_TX_BUFFER_SIZE ((uint32_t)1514)
+
+/* The carrier extension symbol, as received by the NIC. */
+#define CARRIER_EXTENSION 0x0F
+
+/* TBI_ACCEPT macro definition:
+ *
+ * If Tbi Compatibility mode is turned-on, then we should accept frames with
+ * receive errors if and only if:
+ * 1) errors is equal to the CRC error bit.
+ * 2) The last byte is a Carrier extension (0x0F).
+ * 3) The frame length (as reported by Hardware) is greater than 64 (60
+ * if a VLAN tag was stripped from the frame.
+ * 4) " " " " " " " <= max_frame_size+1.
+ *
+ * This macro requires:
+ * adapter = a pointer to struct e1000_shared_adapter
+ * special = the 16 bit special field of the RX descriptor with EOP set
+ * error = the 8 bit error field of the RX descriptor with EOP set
+ * length = the sum of all the length fields of the RX descriptors that
+ * make up the current frame
+ * last_byte = the last byte of the frame DMAed by the hardware
+ * max_frame_length = the maximum frame length we want to accept.
+ * min_frame_length = the minimum frame length we want to accept.
+ *
+ * This macro is a conditional that should be used in the interrupt
+ * handler's Rx processing routine when RxErrors have been detected.
+ *
+ * Typical use:
+ * ...
+ * if (TBI_ACCEPT) {
+ * accept_frame = TRUE;
+ * e1000_tbi_adjust_stats(adapter, MacAddress);
+ * frame_length--;
+ * } else {
+ * accept_frame = FALSE;
+ * }
+ * ...
+ */
+
+#define TBI_ACCEPT(adapter, special, errors, length, last_byte) \
+ ((adapter)->tbi_compatibility_on && \
+ (((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
+ ((last_byte) == CARRIER_EXTENSION) && \
+ ((length) <= ((adapter)->max_frame_size + 1)) && \
+ ((length) > ((special == 0x0000) ? \
+ ((adapter)->min_frame_size) : \
+ ((adapter)->min_frame_size - VLAN_TAG_SIZE))))
+
+
+#endif /* _E1000_MAC_H_ */
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
new file mode 100644
index 000000000000..94e8aaef5fc7
--- /dev/null
+++ b/drivers/net/e1000/e1000_main.c
@@ -0,0 +1,2036 @@
+/*******************************************************************************
+
+ This software program is available to you under a choice of one of two
+ licenses. You may choose to be licensed under either the GNU General Public
+ License (GPL) Version 2, June 1991, available at
+ http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
+ text of which follows:
+
+ Recipient has requested a license and Intel Corporation ("Intel") is willing
+ to grant a license for the software entitled Linux Base Driver for the
+ Intel(R) PRO/1000 Family of Adapters (e1000) (the "Software") being provided
+ by Intel Corporation. The following definitions apply to this license:
+
+ "Licensed Patents" means patent claims licensable by Intel Corporation which
+ are necessarily infringed by the use of sale of the Software alone or when
+ combined with the operating system referred to below.
+
+ "Recipient" means the party to whom Intel delivers this Software.
+
+ "Licensee" means Recipient and those third parties that receive a license to
+ any operating system available under the GNU Public License version 2.0 or
+ later.
+
+ Copyright (c) 1999 - 2002 Intel Corporation.
+ All rights reserved.
+
+ The license is provided to Recipient and Recipient's Licensees under the
+ following terms.
+
+ Redistribution and use in source and binary forms of the Software, with or
+ without modification, are permitted provided that the following conditions
+ are met:
+
+ Redistributions of source code of the Software may retain the above
+ copyright notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form of the Software may reproduce the above
+ copyright notice, this list of conditions and the following disclaimer in
+ the documentation and/or materials provided with the distribution.
+
+ Neither the name of Intel Corporation nor the names of its contributors
+ shall be used to endorse or promote products derived from this Software
+ without specific prior written permission.
+
+ Intel hereby grants Recipient and Licensees a non-exclusive, worldwide,
+ royalty-free patent license under Licensed Patents to make, use, sell, offer
+ to sell, import and otherwise transfer the Software, if any, in source code
+ and object code form. This license shall include changes to the Software
+ that are error corrections or other minor changes to the Software that do
+ not add functionality or features when the Software is incorporated in any
+ version of an operating system that has been distributed under the GNU
+ General Public License 2.0 or later. This patent license shall apply to the
+ combination of the Software and any operating system licensed under the GNU
+ Public License version 2.0 or later if, at the time Intel provides the
+ Software to Recipient, such addition of the Software to the then publicly
+ available versions of such operating systems available under the GNU Public
+ License version 2.0 or later (whether in gold, beta or alpha form) causes
+ such combination to be covered by the Licensed Patents. The patent license
+ shall not apply to any other combinations which include the Software. NO
+ hardware per se is licensed hereunder.
+
+ 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 MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR IT CONTRIBUTORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ ANY LOSS OF USE; DATA, OR PROFITS; OR BUSINESS INTERUPTION) 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.
+
+*******************************************************************************/
+
+#define __E1000_MAIN__
+#include "e1000.h"
+
+char e1000_driver_name[] = "e1000";
+
+char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
+
+char e1000_driver_version[] = "4.2.4-k1";
+
+char e1000_copyright[] = "Copyright (c) 1999-2002 Intel Corporation.";
+
+/* e1000_pci_tbl - PCI Device ID Table
+ *
+ * Private driver_data field (last one) stores an index into e1000_strings
+ * Wildcard entries (PCI_ANY_ID) should come last
+ * Last entry must be all 0s
+ *
+ * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
+ * Class, Class Mask, String Index }
+ */
+static struct pci_device_id e1000_pci_tbl[] __devinitdata = {
+ /* Intel(R) PRO/1000 Network Connection */
+ {0x8086, 0x1000, 0x8086, 0x1000, 0, 0, 0},
+ {0x8086, 0x1001, 0x8086, 0x1003, 0, 0, 0},
+ {0x8086, 0x1004, 0x8086, 0x1004, 0, 0, 0},
+ {0x8086, 0x1008, 0x8086, 0x1107, 0, 0, 0},
+ {0x8086, 0x1009, 0x8086, 0x1109, 0, 0, 0},
+ {0x8086, 0x100C, 0x8086, 0x1112, 0, 0, 0},
+ /* Compaq Gigabit Ethernet Server Adapter */
+ {0x8086, 0x1000, 0x0E11, PCI_ANY_ID, 0, 0, 1},
+ {0x8086, 0x1001, 0x0E11, PCI_ANY_ID, 0, 0, 1},
+ {0x8086, 0x1004, 0x0E11, PCI_ANY_ID, 0, 0, 1},
+ /* IBM Mobile, Desktop & Server Adapters */
+ {0x8086, 0x1000, 0x1014, PCI_ANY_ID, 0, 0, 2},
+ {0x8086, 0x1001, 0x1014, PCI_ANY_ID, 0, 0, 2},
+ {0x8086, 0x1004, 0x1014, PCI_ANY_ID, 0, 0, 2},
+ /* Generic */
+ {0x8086, 0x1000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x100C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x100D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ /* required last entry */
+ {0,}
+};
+
+MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
+
+static char *e1000_strings[] = {
+ "Intel(R) PRO/1000 Network Connection",
+ "Compaq Gigabit Ethernet Server Adapter",
+ "IBM Mobile, Desktop & Server Adapters"
+};
+
+/* Local Function Prototypes */
+
+int e1000_up(struct e1000_adapter *adapter);
+void e1000_down(struct e1000_adapter *adapter);
+static int e1000_init_module(void);
+static void e1000_exit_module(void);
+static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+static void e1000_remove(struct pci_dev *pdev);
+static void e1000_sw_init(struct e1000_adapter *adapter);
+static int e1000_open(struct net_device *netdev);
+static int e1000_close(struct net_device *netdev);
+static int e1000_setup_tx_resources(struct e1000_adapter *adapter);
+static int e1000_setup_rx_resources(struct e1000_adapter *adapter);
+static void e1000_configure_tx(struct e1000_adapter *adapter);
+static void e1000_configure_rx(struct e1000_adapter *adapter);
+static void e1000_setup_rctl(struct e1000_adapter *adapter);
+static void e1000_clean_tx_ring(struct e1000_adapter *adapter);
+static void e1000_clean_rx_ring(struct e1000_adapter *adapter);
+static void e1000_free_tx_resources(struct e1000_adapter *adapter);
+static void e1000_free_rx_resources(struct e1000_adapter *adapter);
+static void e1000_set_multi(struct net_device *netdev);
+static void e1000_update_phy_info(unsigned long data);
+static void e1000_watchdog(unsigned long data);
+static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
+static void e1000_tx_timeout(struct net_device *dev);
+static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
+static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
+static int e1000_set_mac(struct net_device *netdev, void *p);
+static void e1000_update_stats(struct e1000_adapter *adapter);
+static inline void e1000_irq_disable(struct e1000_adapter *adapter);
+static inline void e1000_irq_enable(struct e1000_adapter *adapter);
+static void e1000_intr(int irq, void *data, struct pt_regs *regs);
+static void e1000_clean_tx_irq(struct e1000_adapter *adapter);
+static void e1000_clean_rx_irq(struct e1000_adapter *adapter);
+static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter);
+static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
+static void e1000_reset(struct e1000_adapter *adapter);
+static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
+static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
+static inline void e1000_rx_checksum(struct e1000_adapter *adapter,
+ struct e1000_rx_desc *rx_desc,
+ struct sk_buff *skb);
+void e1000_enable_WOL(struct e1000_adapter *adapter);
+
+/* Exported from other modules */
+
+extern void e1000_check_options(struct e1000_adapter *adapter);
+extern void e1000_proc_dev_setup(struct e1000_adapter *adapter);
+extern void e1000_proc_dev_free(struct e1000_adapter *adapter);
+extern int e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr);
+
+static struct pci_driver e1000_driver = {
+ name: e1000_driver_name,
+ id_table: e1000_pci_tbl,
+ probe: e1000_probe,
+ remove: e1000_remove,
+ /* Power Managment Hooks */
+ suspend: NULL,
+ resume: NULL
+};
+
+MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
+MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
+MODULE_LICENSE("Dual BSD/GPL");
+
+#ifdef EXPORT_SYMTAB
+EXPORT_SYMBOL(e1000_init_module);
+EXPORT_SYMBOL(e1000_exit_module);
+EXPORT_SYMBOL(e1000_probe);
+EXPORT_SYMBOL(e1000_remove);
+EXPORT_SYMBOL(e1000_open);
+EXPORT_SYMBOL(e1000_close);
+EXPORT_SYMBOL(e1000_xmit_frame);
+EXPORT_SYMBOL(e1000_intr);
+EXPORT_SYMBOL(e1000_set_multi);
+EXPORT_SYMBOL(e1000_change_mtu);
+EXPORT_SYMBOL(e1000_set_mac);
+EXPORT_SYMBOL(e1000_get_stats);
+EXPORT_SYMBOL(e1000_watchdog);
+EXPORT_SYMBOL(e1000_ioctl);
+#endif
+
+/**
+ * e1000_init_module - Driver Registration Routine
+ *
+ * e1000_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ **/
+
+static int __init
+e1000_init_module(void)
+{
+ printk(KERN_INFO "%s - version %s\n",
+ e1000_driver_string, e1000_driver_version);
+
+ printk(KERN_INFO "%s\n", e1000_copyright);
+
+ return pci_module_init(&e1000_driver);
+}
+
+module_init(e1000_init_module);
+
+/**
+ * e1000_exit_module - Driver Exit Cleanup Routine
+ *
+ * e1000_exit_module is called just before the driver is removed
+ * from memory.
+ **/
+
+static void __exit
+e1000_exit_module(void)
+{
+ pci_unregister_driver(&e1000_driver);
+
+ return;
+}
+
+module_exit(e1000_exit_module);
+
+
+int
+e1000_up(struct e1000_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ if(request_irq(netdev->irq, &e1000_intr, SA_SHIRQ,
+ netdev->name, netdev))
+ return -1;
+
+ /* hardware has been reset, we need to reload some things */
+
+ e1000_set_multi(netdev);
+
+ e1000_configure_tx(adapter);
+ e1000_setup_rctl(adapter);
+ e1000_configure_rx(adapter);
+ e1000_alloc_rx_buffers(adapter);
+
+ e1000_clear_hw_cntrs(&adapter->shared);
+
+ mod_timer(&adapter->watchdog_timer, jiffies);
+ e1000_irq_enable(adapter);
+
+ return 0;
+}
+
+void
+e1000_down(struct e1000_adapter *adapter)
+{
+ struct e1000_shared_adapter *shared = &adapter->shared;
+ struct net_device *netdev = adapter->netdev;
+
+ e1000_irq_disable(adapter);
+ free_irq(netdev->irq, netdev);
+ del_timer_sync(&adapter->watchdog_timer);
+ del_timer_sync(&adapter->phy_info_timer);
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+
+ /* disable the transmit and receive units */
+
+ E1000_WRITE_REG(shared, RCTL, 0);
+ E1000_WRITE_REG(shared, TCTL, E1000_TCTL_PSP);
+
+ /* delay to allow PCI transactions to complete */
+
+ msec_delay(10);
+
+ e1000_clean_tx_ring(adapter);
+ e1000_clean_rx_ring(adapter);
+
+ e1000_reset(adapter);
+}
+
+static void
+e1000_reset(struct e1000_adapter *adapter)
+{
+ struct e1000_shared_adapter *shared = &adapter->shared;
+ uint32_t ctrl_ext;
+
+ /* Repartition Pba for greater than 9k mtu
+ * To take effect CTRL.RST is required.
+ */
+
+ if(adapter->rx_buffer_len > E1000_RXBUFFER_8192)
+ E1000_WRITE_REG(shared, PBA, E1000_JUMBO_PBA);
+ else
+ E1000_WRITE_REG(shared, PBA, E1000_DEFAULT_PBA);
+
+ /* 82542 2.0 needs MWI disabled while issuing a reset */
+
+ if(shared->mac_type == e1000_82542_rev2_0)
+ e1000_enter_82542_rst(adapter);
+
+ /* global reset */
+
+ E1000_WRITE_REG(shared, CTRL, E1000_CTRL_RST);
+ msec_delay(10);
+
+ /* EEPROM reload */
+
+ ctrl_ext = E1000_READ_REG(shared, CTRL_EXT);
+ ctrl_ext |= E1000_CTRL_EXT_EE_RST;
+ E1000_WRITE_REG(shared, CTRL_EXT, ctrl_ext);
+ msec_delay(5);
+
+ if(shared->mac_type == e1000_82542_rev2_0)
+ e1000_leave_82542_rst(adapter);
+
+ shared->tbi_compatibility_on = FALSE;
+ shared->fc = shared->original_fc;
+
+ e1000_init_hw(shared);
+
+ e1000_enable_WOL(adapter);
+
+ return;
+}
+
+/**
+ * e1000_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in e1000_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * e1000_probe initializes an adapter identified by a pci_dev structure.
+ * The OS initialization, configuring of the adapter private structure,
+ * and a hardware reset occur.
+ **/
+
+static int __devinit
+e1000_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct net_device *netdev;
+ struct e1000_adapter *adapter;
+ static int cards_found = 0;
+ unsigned long mmio_start;
+ int mmio_len;
+ int i;
+
+ if((i = pci_enable_device(pdev)))
+ return i;
+
+ if((i = pci_set_dma_mask(pdev, E1000_DMA_MASK)))
+ return i;
+
+ if((i = pci_request_regions(pdev, e1000_driver_name)))
+ return i;
+
+ pci_set_master(pdev);
+
+ netdev = alloc_etherdev(sizeof(struct e1000_adapter));
+ if(!netdev)
+ goto err_alloc_etherdev;
+
+ SET_MODULE_OWNER(netdev);
+
+ pci_set_drvdata(pdev, netdev);
+ adapter = netdev->priv;
+ adapter->netdev = netdev;
+ adapter->pdev = pdev;
+ adapter->shared.back = adapter;
+
+ mmio_start = pci_resource_start(pdev, BAR_0);
+ mmio_len = pci_resource_len(pdev, BAR_0);
+
+ adapter->shared.hw_addr = ioremap(mmio_start, mmio_len);
+ if(!adapter->shared.hw_addr)
+ goto err_ioremap;
+
+ netdev->open = &e1000_open;
+ netdev->stop = &e1000_close;
+ netdev->hard_start_xmit = &e1000_xmit_frame;
+ netdev->get_stats = &e1000_get_stats;
+ netdev->set_multicast_list = &e1000_set_multi;
+ netdev->set_mac_address = &e1000_set_mac;
+ netdev->change_mtu = &e1000_change_mtu;
+ netdev->do_ioctl = &e1000_ioctl;
+ netdev->tx_timeout = &e1000_tx_timeout;
+ netdev->watchdog_timeo = HZ;
+
+ netdev->irq = pdev->irq;
+ netdev->base_addr = mmio_start;
+
+ adapter->bd_number = cards_found;
+ adapter->id_string = e1000_strings[ent->driver_data];
+
+ /* setup the private structure */
+
+ e1000_sw_init(adapter);
+
+ if(adapter->shared.mac_type >= e1000_82543) {
+ netdev->features = NETIF_F_SG |
+ NETIF_F_IP_CSUM |
+ NETIF_F_HIGHDMA;
+ } else {
+ netdev->features = NETIF_F_SG | NETIF_F_HIGHDMA;
+ }
+
+ /* make sure the EEPROM is good */
+
+ if(!e1000_validate_eeprom_checksum(&adapter->shared))
+ goto err_eeprom;
+
+ /* copy the MAC address out of the EEPROM */
+
+ e1000_read_mac_addr(&adapter->shared);
+ memcpy(netdev->dev_addr, adapter->shared.mac_addr, netdev->addr_len);
+
+ if(!is_valid_ether_addr(netdev->dev_addr))
+ goto err_eeprom;
+
+ e1000_read_part_num(&adapter->shared, &(adapter->part_num));
+ e1000_get_bus_info(&adapter->shared);
+
+ init_timer(&adapter->watchdog_timer);
+ adapter->watchdog_timer.function = &e1000_watchdog;
+ adapter->watchdog_timer.data = (unsigned long) adapter;
+
+ init_timer(&adapter->phy_info_timer);
+ adapter->phy_info_timer.function = &e1000_update_phy_info;
+ adapter->phy_info_timer.data = (unsigned long) adapter;
+
+ register_netdev(netdev);
+
+ /* we're going to reset, so assume we have no link for now */
+
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+
+ printk(KERN_INFO "%s: %s\n", netdev->name, adapter->id_string);
+ e1000_check_options(adapter);
+ e1000_proc_dev_setup(adapter);
+
+ /* reset the hardware with the new settings */
+
+ e1000_reset(adapter);
+
+ cards_found++;
+ return 0;
+
+err_eeprom:
+ iounmap(adapter->shared.hw_addr);
+err_ioremap:
+ pci_release_regions(pdev);
+ kfree(netdev);
+err_alloc_etherdev:
+ return -ENOMEM;
+}
+
+/**
+ * e1000_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * e1000_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device. The could be caused by a
+ * Hot-Plug event, or because the driver is going to be removed from
+ * memory.
+ *
+ * This routine is also called to clean up from a failure in
+ * e1000_probe. The Adapter struct and netdev will always exist,
+ * all other pointers must be checked for NULL before freeing.
+ **/
+
+static void __devexit
+e1000_remove(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct e1000_adapter *adapter = netdev->priv;
+
+ unregister_netdev(netdev);
+
+ e1000_phy_hw_reset(&adapter->shared);
+
+ e1000_proc_dev_free(adapter);
+
+ iounmap(adapter->shared.hw_addr);
+ pci_release_regions(pdev);
+
+ kfree(netdev);
+ return;
+}
+
+/**
+ * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * e1000_sw_init initializes the Adapter private data structure.
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ **/
+
+static void __devinit
+e1000_sw_init(struct e1000_adapter *adapter)
+{
+ struct e1000_shared_adapter *shared = &adapter->shared;
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+
+ /* PCI config space info */
+
+ uint16_t *vendor = &shared->vendor_id;
+ uint16_t *device = &shared->device_id;
+ uint16_t *subvendor = &shared->subsystem_vendor_id;
+ uint16_t *subsystem = &shared->subsystem_id;
+ uint8_t *revision = &shared->revision_id;
+
+ pci_read_config_word(pdev, PCI_VENDOR_ID, vendor);
+ pci_read_config_word(pdev, PCI_DEVICE_ID, device);
+ pci_read_config_byte(pdev, PCI_REVISION_ID, revision);
+ pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, subvendor);
+ pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, subsystem);
+
+ pci_read_config_word(pdev, PCI_COMMAND, &shared->pci_cmd_word);
+
+ adapter->rx_buffer_len = E1000_RXBUFFER_2048;
+ shared->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + CRC_LENGTH;
+ shared->min_frame_size = MINIMUM_ETHERNET_PACKET_SIZE + CRC_LENGTH;
+
+ /* identify the MAC */
+
+ switch (*device) {
+ case E1000_DEV_ID_82542:
+ switch (*revision) {
+ case E1000_82542_2_0_REV_ID:
+ shared->mac_type = e1000_82542_rev2_0;
+ break;
+ case E1000_82542_2_1_REV_ID:
+ shared->mac_type = e1000_82542_rev2_1;
+ break;
+ default:
+ shared->mac_type = e1000_82542_rev2_0;
+ E1000_ERR("Could not identify 82542 revision\n");
+ }
+ break;
+ case E1000_DEV_ID_82543GC_FIBER:
+ case E1000_DEV_ID_82543GC_COPPER:
+ shared->mac_type = e1000_82543;
+ break;
+ case E1000_DEV_ID_82544EI_COPPER:
+ case E1000_DEV_ID_82544EI_FIBER:
+ case E1000_DEV_ID_82544GC_COPPER:
+ case E1000_DEV_ID_82544GC_LOM:
+ shared->mac_type = e1000_82544;
+ break;
+ default:
+ /* should never have loaded on this device */
+ BUG();
+ }
+
+ /* flow control settings */
+
+ shared->fc_high_water = FC_DEFAULT_HI_THRESH;
+ shared->fc_low_water = FC_DEFAULT_LO_THRESH;
+ shared->fc_pause_time = FC_DEFAULT_TX_TIMER;
+ shared->fc_send_xon = 1;
+
+ /* Media type - copper or fiber */
+
+ if(shared->mac_type >= e1000_82543) {
+ uint32_t status = E1000_READ_REG(shared, STATUS);
+
+ if(status & E1000_STATUS_TBIMODE)
+ shared->media_type = e1000_media_type_fiber;
+ else
+ shared->media_type = e1000_media_type_copper;
+ } else {
+ shared->media_type = e1000_media_type_fiber;
+ }
+
+ if(shared->mac_type < e1000_82543)
+ shared->report_tx_early = 0;
+ else
+ shared->report_tx_early = 1;
+
+ shared->wait_autoneg_complete = FALSE;
+ shared->tbi_compatibility_en = TRUE;
+
+ atomic_set(&adapter->irq_sem, 1);
+ spin_lock_init(&adapter->stats_lock);
+}
+
+/**
+ * e1000_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * The open entry point is called when a network interface is made
+ * active by the system (IFF_UP). At this point all resources needed
+ * for transmit and receive operations are allocated, the interrupt
+ * handler is registered with the OS, the watchdog timer is started,
+ * and the stack is notified that the interface is ready.
+ **/
+
+static int
+e1000_open(struct net_device *netdev)
+{
+ struct e1000_adapter *adapter = netdev->priv;
+
+ /* allocate transmit descriptors */
+
+ if(e1000_setup_tx_resources(adapter))
+ goto err_setup_tx;
+
+ /* allocate receive descriptors */
+
+ if(e1000_setup_rx_resources(adapter))
+ goto err_setup_rx;
+
+ if(e1000_up(adapter))
+ goto err_up;
+
+ return 0;
+
+err_up:
+ e1000_free_rx_resources(adapter);
+err_setup_rx:
+ e1000_free_tx_resources(adapter);
+err_setup_tx:
+ e1000_reset(adapter);
+
+ return -EBUSY;
+}
+
+/**
+ * e1000_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * The close entry point is called when an interface is de-activated
+ * by the OS. The hardware is still under the drivers control, but
+ * needs to be disabled. A global MAC reset is issued to stop the
+ * hardware, and all transmit and receive resources are freed.
+ **/
+
+static int
+e1000_close(struct net_device *netdev)
+{
+ struct e1000_adapter *adapter = netdev->priv;
+
+ e1000_down(adapter);
+
+ e1000_free_tx_resources(adapter);
+ e1000_free_rx_resources(adapter);
+
+ return 0;
+}
+
+/**
+ * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ *
+ * e1000_setup_tx_resources allocates all software transmit resources
+ * and enabled the Tx unit of the MAC.
+ **/
+
+static int
+e1000_setup_tx_resources(struct e1000_adapter *adapter)
+{
+ struct e1000_desc_ring *txdr = &adapter->tx_ring;
+ struct pci_dev *pdev = adapter->pdev;
+ int size;
+
+ size = sizeof(struct e1000_buffer) * txdr->count;
+ txdr->buffer_info = kmalloc(size, GFP_KERNEL);
+ if(!txdr->buffer_info) {
+ return -ENOMEM;
+ }
+ memset(txdr->buffer_info, 0, size);
+
+ /* round up to nearest 4K */
+
+ txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
+ E1000_ROUNDUP(txdr->size, 4096);
+
+ txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
+ if(!txdr->desc) {
+ kfree(txdr->buffer_info);
+ return -ENOMEM;
+ }
+ memset(txdr->desc, 0, txdr->size);
+
+ atomic_set(&txdr->unused, txdr->count);
+ txdr->next_to_use = 0;
+ txdr->next_to_clean = 0;
+
+ return 0;
+}
+
+/**
+ * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx unit of the MAC after a reset.
+ **/
+
+static void
+e1000_configure_tx(struct e1000_adapter *adapter)
+{
+ uint64_t tdba = adapter->tx_ring.dma;
+ uint32_t tdlen = adapter->tx_ring.count * sizeof(struct e1000_tx_desc);
+ uint32_t tctl, tipg;
+
+ E1000_WRITE_REG(&adapter->shared, TDBAL, (tdba & 0x00000000FFFFFFFF));
+ E1000_WRITE_REG(&adapter->shared, TDBAH, (tdba >> 32));
+
+ E1000_WRITE_REG(&adapter->shared, TDLEN, tdlen);
+
+ /* Setup the HW Tx Head and Tail descriptor pointers */
+
+ E1000_WRITE_REG(&adapter->shared, TDH, 0);
+ E1000_WRITE_REG(&adapter->shared, TDT, 0);
+
+ /* Set the default values for the Tx Inter Packet Gap timer */
+
+ switch (adapter->shared.mac_type) {
+ case e1000_82542_rev2_0:
+ case e1000_82542_rev2_1:
+ tipg = DEFAULT_82542_TIPG_IPGT;
+ tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
+ tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+ break;
+ default:
+ if(adapter->shared.media_type == e1000_media_type_fiber)
+ tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
+ else
+ tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
+ tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
+ tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+ }
+ E1000_WRITE_REG(&adapter->shared, TIPG, tipg);
+
+ /* Set the Tx Interrupt Delay register */
+
+ E1000_WRITE_REG(&adapter->shared, TIDV, adapter->tx_int_delay);
+
+ /* Program the Transmit Control Register */
+
+ tctl = E1000_TCTL_PSP | E1000_TCTL_EN |
+ (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
+
+ if(adapter->link_duplex == FULL_DUPLEX) {
+ tctl |= E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT;
+ } else {
+ tctl |= E1000_HDX_COLLISION_DISTANCE << E1000_COLD_SHIFT;
+ }
+
+ E1000_WRITE_REG(&adapter->shared, TCTL, tctl);
+
+#ifdef CONFIG_PPC
+ if(adapter->shared.mac_type >= e1000_82543) {
+ E1000_WRITE_REG(&adapter->shared, TXDCTL, 0x00020000);
+ }
+#endif
+
+ /* Setup Transmit Descriptor Settings for this adapter */
+ adapter->txd_cmd = E1000_TXD_CMD_IFCS;
+
+ if(adapter->tx_int_delay > 0)
+ adapter->txd_cmd |= E1000_TXD_CMD_IDE;
+ if(adapter->shared.report_tx_early == 1)
+ adapter->txd_cmd |= E1000_TXD_CMD_RS;
+ else
+ adapter->txd_cmd |= E1000_TXD_CMD_RPS;
+
+ return;
+}
+
+/**
+ * e1000_setup_rx_resources - allocate Rx resources (Descriptors, receive SKBs)
+ * @adapter: board private structure
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * e1000_setup_rx_resources allocates all software receive resources
+ * and network buffers, and enables the Rx unit of the MAC.
+ **/
+
+static int
+e1000_setup_rx_resources(struct e1000_adapter *adapter)
+{
+ struct e1000_desc_ring *rxdr = &adapter->rx_ring;
+ struct pci_dev *pdev = adapter->pdev;
+ int size;
+
+ size = sizeof(struct e1000_buffer) * rxdr->count;
+ rxdr->buffer_info = kmalloc(size, GFP_KERNEL);
+ if(!rxdr->buffer_info) {
+ return -ENOMEM;
+ }
+ memset(rxdr->buffer_info, 0, size);
+
+ /* Round up to nearest 4K */
+
+ rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc);
+ E1000_ROUNDUP(rxdr->size, 4096);
+
+ rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
+
+ if(!rxdr->desc) {
+ kfree(rxdr->buffer_info);
+ return -ENOMEM;
+ }
+ memset(rxdr->desc, 0, rxdr->size);
+
+ rxdr->next_to_clean = 0;
+ rxdr->unused_count = rxdr->count;
+ rxdr->next_to_use = 0;
+
+ return 0;
+}
+
+/**
+ * e1000_setup_rctl - configure the receive control register
+ * @adapter: Board private structure
+ **/
+
+static void
+e1000_setup_rctl(struct e1000_adapter *adapter)
+{
+ uint32_t rctl;
+
+ /* Setup the Receive Control Register */
+ rctl = E1000_RCTL_EN | E1000_RCTL_BAM |
+ E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
+ (adapter->shared.mc_filter_type << E1000_RCTL_MO_SHIFT);
+
+ if(adapter->shared.tbi_compatibility_on == 1)
+ rctl |= E1000_RCTL_SBP;
+
+ switch (adapter->rx_buffer_len) {
+ case E1000_RXBUFFER_2048:
+ default:
+ rctl |= E1000_RCTL_SZ_2048;
+ break;
+ case E1000_RXBUFFER_4096:
+ rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
+ break;
+ case E1000_RXBUFFER_8192:
+ rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
+ break;
+ case E1000_RXBUFFER_16384:
+ rctl |= E1000_RCTL_SZ_16384 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
+ break;
+ }
+
+ E1000_WRITE_REG(&adapter->shared, RCTL, rctl);
+}
+
+/**
+ * e1000_configure_rx - Configure 8254x Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Rx unit of the MAC after a reset.
+ **/
+
+static void
+e1000_configure_rx(struct e1000_adapter *adapter)
+{
+ uint64_t rdba = adapter->rx_ring.dma;
+ uint32_t rdlen = adapter->rx_ring.count * sizeof(struct e1000_rx_desc);
+ uint32_t rctl;
+ uint32_t rxcsum;
+
+ /* make sure receives are disabled while setting up the descriptors */
+
+ rctl = E1000_READ_REG(&adapter->shared, RCTL);
+ E1000_WRITE_REG(&adapter->shared, RCTL, rctl & ~E1000_RCTL_EN);
+
+ /* set the Receive Delay Timer Register */
+
+ E1000_WRITE_REG(&adapter->shared, RDTR,
+ adapter->rx_int_delay | E1000_RDT_FPDB);
+
+ /* Setup the Base and Length of the Rx Descriptor Ring */
+
+ E1000_WRITE_REG(&adapter->shared, RDBAL, (rdba & 0x00000000FFFFFFFF));
+ E1000_WRITE_REG(&adapter->shared, RDBAH, (rdba >> 32));
+
+ E1000_WRITE_REG(&adapter->shared, RDLEN, rdlen);
+
+ /* Setup the HW Rx Head and Tail Descriptor Pointers */
+ E1000_WRITE_REG(&adapter->shared, RDH, 0);
+ E1000_WRITE_REG(&adapter->shared, RDT, 0);
+
+ /* Enable 82543 Receive Checksum Offload for TCP and UDP */
+ if((adapter->shared.mac_type >= e1000_82543) &&
+ (adapter->rx_csum == TRUE)) {
+ rxcsum = E1000_READ_REG(&adapter->shared, RXCSUM);
+ rxcsum |= E1000_RXCSUM_TUOFL;
+ E1000_WRITE_REG(&adapter->shared, RXCSUM, rxcsum);
+ }
+
+#ifdef CONFIG_PPC
+ if(adapter->shared.mac_type >= e1000_82543) {
+ E1000_WRITE_REG(&adapter->shared, RXDCTL, 0x00020000);
+ }
+#endif
+
+ /* Enable Receives */
+
+ E1000_WRITE_REG(&adapter->shared, RCTL, rctl);
+
+ return;
+}
+
+/**
+ * e1000_free_tx_resources - Free Tx Resources
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ **/
+
+static void
+e1000_free_tx_resources(struct e1000_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ e1000_clean_tx_ring(adapter);
+
+ kfree(adapter->tx_ring.buffer_info);
+ adapter->tx_ring.buffer_info = NULL;
+
+ pci_free_consistent(pdev, adapter->tx_ring.size,
+ adapter->tx_ring.desc, adapter->tx_ring.dma);
+
+ adapter->tx_ring.desc = NULL;
+
+ return;
+}
+
+/**
+ * e1000_clean_tx_ring - Free Tx Buffers
+ * @adapter: board private structure
+ **/
+
+static void
+e1000_clean_tx_ring(struct e1000_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ unsigned long size;
+ int i;
+
+ /* Free all the Tx ring sk_buffs */
+
+ for(i = 0; i < adapter->tx_ring.count; i++) {
+ if(adapter->tx_ring.buffer_info[i].skb) {
+
+ pci_unmap_page(pdev,
+ adapter->tx_ring.buffer_info[i].dma,
+ adapter->tx_ring.buffer_info[i].length,
+ PCI_DMA_TODEVICE);
+
+ dev_kfree_skb(adapter->tx_ring.buffer_info[i].skb);
+
+ adapter->tx_ring.buffer_info[i].skb = NULL;
+ }
+ }
+
+ size = sizeof(struct e1000_buffer) * adapter->tx_ring.count;
+ memset(adapter->tx_ring.buffer_info, 0, size);
+
+ /* Zero out the descriptor ring */
+
+ memset(adapter->tx_ring.desc, 0, adapter->tx_ring.size);
+
+ atomic_set(&adapter->tx_ring.unused, adapter->tx_ring.count);
+ adapter->tx_ring.next_to_use = 0;
+ adapter->tx_ring.next_to_clean = 0;
+
+ E1000_WRITE_REG(&adapter->shared, TDH, 0);
+ E1000_WRITE_REG(&adapter->shared, TDT, 0);
+
+ return;
+}
+
+/**
+ * e1000_free_rx_resources - Free Rx Resources
+ * @adapter: board private structure
+ *
+ * Free all receive software resources
+ **/
+
+static void
+e1000_free_rx_resources(struct e1000_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ e1000_clean_rx_ring(adapter);
+
+ kfree(adapter->rx_ring.buffer_info);
+ adapter->rx_ring.buffer_info = NULL;
+
+ pci_free_consistent(pdev, adapter->rx_ring.size,
+ adapter->rx_ring.desc, adapter->rx_ring.dma);
+
+ adapter->rx_ring.desc = NULL;
+
+ return;
+}
+
+/**
+ * e1000_clean_rx_ring - Free Rx Buffers
+ * @adapter: board private structure
+ **/
+
+static void
+e1000_clean_rx_ring(struct e1000_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ unsigned long size;
+ int i;
+
+ /* Free all the Rx ring sk_buffs */
+
+ for(i = 0; i < adapter->rx_ring.count; i++) {
+ if(adapter->rx_ring.buffer_info[i].skb) {
+
+ pci_unmap_single(pdev,
+ adapter->rx_ring.buffer_info[i].dma,
+ adapter->rx_ring.buffer_info[i].length,
+ PCI_DMA_FROMDEVICE);
+
+ dev_kfree_skb(adapter->rx_ring.buffer_info[i].skb);
+
+ adapter->rx_ring.buffer_info[i].skb = NULL;
+ }
+ }
+
+ size = sizeof(struct e1000_buffer) * adapter->rx_ring.count;
+ memset(adapter->rx_ring.buffer_info, 0, size);
+
+ /* Zero out the descriptor ring */
+
+ memset(adapter->rx_ring.desc, 0, adapter->rx_ring.size);
+
+ adapter->rx_ring.unused_count = adapter->rx_ring.count;
+ adapter->rx_ring.next_to_clean = 0;
+ adapter->rx_ring.next_to_use = 0;
+
+ E1000_WRITE_REG(&adapter->shared, RDH, 0);
+ E1000_WRITE_REG(&adapter->shared, RDT, 0);
+
+ return;
+}
+
+/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
+ * and memory write and invalidate disabled for certain operations
+ */
+static void
+e1000_enter_82542_rst(struct e1000_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ struct net_device *netdev = adapter->netdev;
+ uint16_t pci_command_word = adapter->shared.pci_cmd_word;
+ uint32_t rctl;
+
+ if(pci_command_word & PCI_COMMAND_INVALIDATE) {
+ pci_command_word &= ~PCI_COMMAND_INVALIDATE;
+ pci_write_config_word(pdev, PCI_COMMAND, pci_command_word);
+ }
+
+ rctl = E1000_READ_REG(&adapter->shared, RCTL);
+ rctl |= E1000_RCTL_RST;
+ E1000_WRITE_REG(&adapter->shared, RCTL, rctl);
+ msec_delay(5);
+
+ if(netif_running(netdev))
+ e1000_clean_rx_ring(adapter);
+ return;
+}
+
+static void
+e1000_leave_82542_rst(struct e1000_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ struct net_device *netdev = adapter->netdev;
+ uint16_t pci_command_word = adapter->shared.pci_cmd_word;
+ uint32_t rctl;
+
+ rctl = E1000_READ_REG(&adapter->shared, RCTL);
+ rctl &= ~E1000_RCTL_RST;
+ E1000_WRITE_REG(&adapter->shared, RCTL, rctl);
+ msec_delay(5);
+
+ if(pci_command_word & PCI_COMMAND_INVALIDATE)
+ pci_write_config_word(pdev, PCI_COMMAND, pci_command_word);
+
+ if(netif_running(netdev)) {
+ e1000_configure_rx(adapter);
+ e1000_alloc_rx_buffers(adapter);
+ }
+ return;
+}
+
+/**
+ * e1000_set_mac - Change the Ethernet Address of the NIC
+ * @netdev: network interface device structure
+ * @p: pointer to an address structure
+ *
+ * Returns 0 on success, negative on failure
+ **/
+
+static int
+e1000_set_mac(struct net_device *netdev, void *p)
+{
+ struct e1000_adapter *adapter = netdev->priv;
+ struct sockaddr *addr = p;
+
+ /* 82542 2.0 needs to be in reset to write receive address registers */
+
+ if(adapter->shared.mac_type == e1000_82542_rev2_0)
+ e1000_enter_82542_rst(adapter);
+
+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+ memcpy(adapter->shared.mac_addr, addr->sa_data, netdev->addr_len);
+
+ e1000_rar_set(&adapter->shared, adapter->shared.mac_addr, 0);
+
+ if(adapter->shared.mac_type == e1000_82542_rev2_0)
+ e1000_leave_82542_rst(adapter);
+
+ return 0;
+}
+
+/**
+ * e1000_set_multi - Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+ * The set_multi entry point is called whenever the multicast address
+ * list or the network interface flags are updated. This routine is
+ * resposible for configuring the hardware for proper multicast,
+ * promiscuous mode, and all-multi behavior.
+ **/
+
+static void
+e1000_set_multi(struct net_device *netdev)
+{
+ struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_shared_adapter *shared = &adapter->shared;
+ struct dev_mc_list *mc_ptr;
+ uint32_t rctl;
+ uint32_t hash_value;
+ int i;
+
+ /* Check for Promiscuous and All Multicast modes */
+
+ rctl = E1000_READ_REG(shared, RCTL);
+
+ if(netdev->flags & IFF_PROMISC) {
+ rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
+ } else if(netdev->flags & IFF_ALLMULTI) {
+ rctl |= E1000_RCTL_MPE;
+ rctl &= ~E1000_RCTL_UPE;
+ } else {
+ rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
+ }
+
+ E1000_WRITE_REG(shared, RCTL, rctl);
+
+ /* 82542 2.0 needs to be in reset to write receive address registers */
+
+ if(shared->mac_type == e1000_82542_rev2_0)
+ e1000_enter_82542_rst(adapter);
+
+ /* load the first 15 multicast address into the exact filters 1-15
+ * RAR 0 is used for the station MAC adddress
+ * if there are not 15 addresses, go ahead and clear the filters
+ */
+ mc_ptr = netdev->mc_list;
+
+ for(i = 1; i < E1000_RAR_ENTRIES; i++) {
+ if(mc_ptr) {
+ e1000_rar_set(shared, mc_ptr->dmi_addr, i);
+ mc_ptr = mc_ptr->next;
+ } else {
+ E1000_WRITE_REG_ARRAY(shared, RA, i << 1, 0);
+ E1000_WRITE_REG_ARRAY(shared, RA, (i << 1) + 1, 0);
+ }
+ }
+
+ /* clear the old settings from the multicast hash table */
+
+ for(i = 0; i < E1000_NUM_MTA_REGISTERS; i++)
+ E1000_WRITE_REG_ARRAY(shared, MTA, i, 0);
+
+ /* load any remaining addresses into the hash table */
+
+ for(; mc_ptr; mc_ptr = mc_ptr->next) {
+ hash_value = e1000_hash_mc_addr(shared, mc_ptr->dmi_addr);
+ e1000_mta_set(shared, hash_value);
+ }
+
+ if(shared->mac_type == e1000_82542_rev2_0)
+ e1000_leave_82542_rst(adapter);
+ return;
+}
+
+
+/* need to wait a few seconds after link up to get diagnostic information from the phy */
+
+static void
+e1000_update_phy_info(unsigned long data)
+{
+ struct e1000_adapter *adapter = (struct e1000_adapter *) data;
+ e1000_phy_get_info(&adapter->shared, &adapter->phy_info);
+ return;
+}
+
+/**
+ * e1000_watchdog - Timer Call-back
+ * @data: pointer to netdev cast into an unsigned long
+ **/
+
+static void
+e1000_watchdog(unsigned long data)
+{
+ struct e1000_adapter *adapter = (struct e1000_adapter *) data;
+ struct net_device *netdev = adapter->netdev;
+
+ e1000_check_for_link(&adapter->shared);
+
+ if(E1000_READ_REG(&adapter->shared, STATUS) & E1000_STATUS_LU) {
+ if(!netif_carrier_ok(netdev)) {
+ e1000_get_speed_and_duplex(&adapter->shared,
+ &adapter->link_speed,
+ &adapter->link_duplex);
+
+ printk(KERN_INFO
+ "e1000: %s NIC Link is Up %d Mbps %s\n",
+ netdev->name, adapter->link_speed,
+ adapter->link_duplex == FULL_DUPLEX ?
+ "Full Duplex" : "Half Duplex");
+
+ netif_carrier_on(netdev);
+ adapter->trans_finish = jiffies;
+ netif_wake_queue(netdev);
+ mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
+ }
+ } else {
+ if(netif_carrier_ok(netdev)) {
+ adapter->link_speed = 0;
+ adapter->link_duplex = 0;
+ printk(KERN_INFO
+ "e1000: %s NIC Link is Down\n",
+ netdev->name);
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+ }
+ }
+
+ e1000_update_stats(adapter);
+
+ /* Reset the timer */
+ mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
+
+ return;
+}
+
+/**
+ * e1000_xmit_frame - Transmit entry point
+ * @skb: buffer with frame data to transmit
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, 1 on error
+ *
+ * e1000_xmit_frame is called by the stack to initiate a transmit.
+ * The out of resource condition is checked after each successful Tx
+ * so that the stack can be notified, preventing the driver from
+ * ever needing to drop a frame. The atomic operations on
+ * tx_ring.unused are used to syncronize with the transmit
+ * interrupt processing code without the need for a spinlock.
+ **/
+
+#define TXD_USE_COUNT(x) (((x) >> 12) + ((x) & 0x0fff ? 1 : 0))
+
+#define SETUP_TXD_PAGE(L, P, O) do { \
+ tx_ring->buffer_info[i].length = (L); \
+ tx_ring->buffer_info[i].dma = \
+ pci_map_page(pdev, (P), (O), (L), PCI_DMA_TODEVICE); \
+ tx_desc->buffer_addr = cpu_to_le64(tx_ring->buffer_info[i].dma); \
+ tx_desc->lower.data = cpu_to_le32(txd_lower | (L)); \
+ tx_desc->upper.data = cpu_to_le32(txd_upper); \
+} while (0)
+
+#define SETUP_TXD_PTR(L, P) \
+ SETUP_TXD_PAGE((L), virt_to_page(P), (unsigned long)(P) & ~PAGE_MASK)
+
+#define QUEUE_TXD() do { i = (i + 1) % tx_ring->count; \
+ atomic_dec(&tx_ring->unused); } while (0)
+
+
+static int
+e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct e1000_adapter *adapter = netdev->priv;
+ struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+ struct pci_dev *pdev = adapter->pdev;
+ struct e1000_tx_desc *tx_desc;
+ int f, len, offset, txd_needed;
+ skb_frag_t *frag;
+
+ int i = tx_ring->next_to_use;
+ uint32_t txd_upper = 0;
+ uint32_t txd_lower = adapter->txd_cmd;
+
+
+ /* If controller appears hung, force transmit timeout */
+
+ if (time_after(netdev->trans_start, adapter->trans_finish + HZ) &&
+ /* If transmitting XOFFs, we're not really hung */
+ !(E1000_READ_REG(&adapter->shared, STATUS) & E1000_STATUS_TXOFF)) {
+ adapter->trans_finish = jiffies;
+ netif_stop_queue(netdev);
+ return 1;
+ }
+
+ txd_needed = TXD_USE_COUNT(skb->len - skb->data_len);
+
+ for(f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
+ frag = &skb_shinfo(skb)->frags[f];
+ txd_needed += TXD_USE_COUNT(frag->size);
+ }
+
+ if(skb->ip_summed == CHECKSUM_HW)
+ txd_needed += 1;
+
+ /* make sure there are enough Tx descriptors available in the ring */
+
+ if(atomic_read(&tx_ring->unused) <= (txd_needed + 1)) {
+ adapter->net_stats.tx_dropped++;
+ netif_stop_queue(netdev);
+ return 1;
+ }
+
+ if(skb->ip_summed == CHECKSUM_HW) {
+ struct e1000_context_desc *context_desc;
+ uint8_t css = skb->h.raw - skb->data;
+ uint8_t cso = (skb->h.raw + skb->csum) - skb->data;
+
+ context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
+
+ context_desc->upper_setup.tcp_fields.tucss = css;
+ context_desc->upper_setup.tcp_fields.tucso = cso;
+ context_desc->upper_setup.tcp_fields.tucse = 0;
+ context_desc->tcp_seg_setup.data = 0;
+ context_desc->cmd_and_length =
+ cpu_to_le32(txd_lower | E1000_TXD_CMD_DEXT);
+
+ QUEUE_TXD();
+
+ txd_upper |= E1000_TXD_POPTS_TXSM << 8;
+ txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
+ }
+
+ tx_desc = E1000_TX_DESC(*tx_ring, i);
+ len = skb->len - skb->data_len;
+ offset = 0;
+
+ while(len > 4096) {
+ SETUP_TXD_PTR(4096, skb->data + offset);
+ QUEUE_TXD();
+
+ tx_desc = E1000_TX_DESC(*tx_ring, i);
+ len -= 4096;
+ offset += 4096;
+ }
+
+ SETUP_TXD_PTR(len, skb->data + offset);
+
+ for(f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
+ frag = &skb_shinfo(skb)->frags[f];
+
+ QUEUE_TXD();
+
+ tx_desc = E1000_TX_DESC(*tx_ring, i);
+ len = frag->size;
+ offset = 0;
+
+ while(len > 4096) {
+ SETUP_TXD_PAGE(4096, frag->page,
+ frag->page_offset + offset);
+ QUEUE_TXD();
+
+ tx_desc = E1000_TX_DESC(*tx_ring, i);
+ len -= 4096;
+ offset += 4096;
+ }
+ SETUP_TXD_PAGE(len, frag->page, frag->page_offset + offset);
+ }
+
+ /* EOP and SKB pointer go with the last fragment */
+
+ tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP);
+ tx_ring->buffer_info[i].skb = skb;
+
+ QUEUE_TXD();
+
+ tx_ring->next_to_use = i;
+
+ /* Move the HW Tx Tail Pointer */
+
+ E1000_WRITE_REG(&adapter->shared, TDT, i);
+
+ netdev->trans_start = jiffies;
+
+ return 0;
+}
+
+#undef TXD_USE_COUNT
+#undef SETUP_TXD
+#undef QUEUE_TXD
+
+/**
+ * e1000_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ **/
+
+static void
+e1000_tx_timeout(struct net_device *netdev)
+{
+ struct e1000_adapter *adapter = netdev->priv;
+
+ e1000_down(adapter);
+ e1000_up(adapter);
+}
+
+/**
+ * e1000_get_stats - Get System Network Statistics
+ * @netdev: network interface device structure
+ *
+ * Returns the address of the device statistics structure.
+ * The statistics are actually updated from the timer callback.
+ **/
+
+static struct net_device_stats *
+e1000_get_stats(struct net_device *netdev)
+{
+ struct e1000_adapter *adapter = netdev->priv;
+
+ return &adapter->net_stats;
+}
+
+/**
+ * e1000_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ **/
+
+static int
+e1000_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ struct e1000_adapter *adapter = netdev->priv;
+ int old_mtu = adapter->rx_buffer_len;
+ int max_frame = new_mtu + ENET_HEADER_SIZE + CRC_LENGTH;
+
+ if((max_frame < MINIMUM_ETHERNET_PACKET_SIZE + CRC_LENGTH) ||
+ (max_frame > MAX_JUMBO_FRAME_SIZE + CRC_LENGTH)) {
+ E1000_ERR("Invalid MTU setting\n");
+ return -EINVAL;
+ }
+
+ if(max_frame <= MAXIMUM_ETHERNET_PACKET_SIZE + CRC_LENGTH) {
+ adapter->rx_buffer_len = E1000_RXBUFFER_2048;
+
+ } else if(adapter->shared.mac_type < e1000_82543) {
+ E1000_ERR("Jumbo Frames not supported on 82542\n");
+ return -EINVAL;
+
+ } else if(max_frame <= E1000_RXBUFFER_2048) {
+ adapter->rx_buffer_len = E1000_RXBUFFER_2048;
+
+ } else if(max_frame <= E1000_RXBUFFER_4096) {
+ adapter->rx_buffer_len = E1000_RXBUFFER_4096;
+
+ } else if(max_frame <= E1000_RXBUFFER_8192) {
+ adapter->rx_buffer_len = E1000_RXBUFFER_8192;
+
+ } else {
+ adapter->rx_buffer_len = E1000_RXBUFFER_16384;
+ }
+
+ if(old_mtu != adapter->rx_buffer_len && netif_running(netdev)) {
+
+ e1000_down(adapter);
+ e1000_clean_rx_ring(adapter);
+ e1000_clean_tx_ring(adapter);
+ e1000_up(adapter);
+ }
+
+ netdev->mtu = new_mtu;
+ adapter->shared.max_frame_size = max_frame;
+
+ return 0;
+}
+
+/**
+ * e1000_update_stats - Update the board statistics counters
+ * @adapter: board private structure
+ **/
+
+static void
+e1000_update_stats(struct e1000_adapter *adapter)
+{
+ struct e1000_shared_adapter *shared = &adapter->shared;
+ unsigned long flags;
+
+#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
+
+ spin_lock_irqsave(&adapter->stats_lock, flags);
+
+ /* these counters are modified from e1000_adjust_tbi_stats,
+ * called from the interrupt context, so they must only
+ * be written while holding adapter->stats_lock
+ */
+
+ adapter->stats.crcerrs += E1000_READ_REG(shared, CRCERRS);
+ adapter->stats.gprc += E1000_READ_REG(shared, GPRC);
+ adapter->stats.gorcl += E1000_READ_REG(shared, GORCL);
+ adapter->stats.gorch += E1000_READ_REG(shared, GORCH);
+ adapter->stats.bprc += E1000_READ_REG(shared, BPRC);
+ adapter->stats.mprc += E1000_READ_REG(shared, MPRC);
+ adapter->stats.roc += E1000_READ_REG(shared, ROC);
+ adapter->stats.prc64 += E1000_READ_REG(shared, PRC64);
+ adapter->stats.prc127 += E1000_READ_REG(shared, PRC127);
+ adapter->stats.prc255 += E1000_READ_REG(shared, PRC255);
+ adapter->stats.prc511 += E1000_READ_REG(shared, PRC511);
+ adapter->stats.prc1023 += E1000_READ_REG(shared, PRC1023);
+ adapter->stats.prc1522 += E1000_READ_REG(shared, PRC1522);
+
+ spin_unlock_irqrestore(&adapter->stats_lock, flags);
+
+ /* the rest of the counters are only modified here */
+
+ adapter->stats.symerrs += E1000_READ_REG(shared, SYMERRS);
+ adapter->stats.mpc += E1000_READ_REG(shared, MPC);
+ adapter->stats.scc += E1000_READ_REG(shared, SCC);
+ adapter->stats.ecol += E1000_READ_REG(shared, ECOL);
+ adapter->stats.mcc += E1000_READ_REG(shared, MCC);
+ adapter->stats.latecol += E1000_READ_REG(shared, LATECOL);
+ adapter->stats.colc += E1000_READ_REG(shared, COLC);
+ adapter->stats.dc += E1000_READ_REG(shared, DC);
+ adapter->stats.sec += E1000_READ_REG(shared, SEC);
+ adapter->stats.rlec += E1000_READ_REG(shared, RLEC);
+ adapter->stats.xonrxc += E1000_READ_REG(shared, XONRXC);
+ adapter->stats.xontxc += E1000_READ_REG(shared, XONTXC);
+ adapter->stats.xoffrxc += E1000_READ_REG(shared, XOFFRXC);
+ adapter->stats.xofftxc += E1000_READ_REG(shared, XOFFTXC);
+ adapter->stats.fcruc += E1000_READ_REG(shared, FCRUC);
+ adapter->stats.gptc += E1000_READ_REG(shared, GPTC);
+ adapter->stats.gotcl += E1000_READ_REG(shared, GOTCL);
+ adapter->stats.gotch += E1000_READ_REG(shared, GOTCH);
+ adapter->stats.rnbc += E1000_READ_REG(shared, RNBC);
+ adapter->stats.ruc += E1000_READ_REG(shared, RUC);
+ adapter->stats.rfc += E1000_READ_REG(shared, RFC);
+ adapter->stats.rjc += E1000_READ_REG(shared, RJC);
+ adapter->stats.torl += E1000_READ_REG(shared, TORL);
+ adapter->stats.torh += E1000_READ_REG(shared, TORH);
+ adapter->stats.totl += E1000_READ_REG(shared, TOTL);
+ adapter->stats.toth += E1000_READ_REG(shared, TOTH);
+ adapter->stats.tpr += E1000_READ_REG(shared, TPR);
+ adapter->stats.tpt += E1000_READ_REG(shared, TPT);
+ adapter->stats.ptc64 += E1000_READ_REG(shared, PTC64);
+ adapter->stats.ptc127 += E1000_READ_REG(shared, PTC127);
+ adapter->stats.ptc255 += E1000_READ_REG(shared, PTC255);
+ adapter->stats.ptc511 += E1000_READ_REG(shared, PTC511);
+ adapter->stats.ptc1023 += E1000_READ_REG(shared, PTC1023);
+ adapter->stats.ptc1522 += E1000_READ_REG(shared, PTC1522);
+ adapter->stats.mptc += E1000_READ_REG(shared, MPTC);
+ adapter->stats.bptc += E1000_READ_REG(shared, BPTC);
+
+ if(adapter->shared.mac_type >= e1000_82543) {
+ adapter->stats.algnerrc += E1000_READ_REG(shared, ALGNERRC);
+ adapter->stats.rxerrc += E1000_READ_REG(shared, RXERRC);
+ adapter->stats.tncrs += E1000_READ_REG(shared, TNCRS);
+ adapter->stats.cexterr += E1000_READ_REG(shared, CEXTERR);
+ adapter->stats.tsctc += E1000_READ_REG(shared, TSCTC);
+ adapter->stats.tsctfc += E1000_READ_REG(shared, TSCTFC);
+ }
+
+ /* Fill out the OS statistics structure */
+
+ adapter->net_stats.rx_packets = adapter->stats.gprc;
+ adapter->net_stats.tx_packets = adapter->stats.gptc;
+ adapter->net_stats.rx_bytes = adapter->stats.gorcl;
+ adapter->net_stats.tx_bytes = adapter->stats.gotcl;
+ adapter->net_stats.multicast = adapter->stats.mprc;
+ adapter->net_stats.collisions = adapter->stats.colc;
+
+ /* Rx Errors */
+
+ adapter->net_stats.rx_errors = adapter->stats.rxerrc +
+ adapter->stats.crcerrs + adapter->stats.algnerrc +
+ adapter->stats.rlec + adapter->stats.rnbc +
+ adapter->stats.mpc + adapter->stats.cexterr;
+ adapter->net_stats.rx_dropped = adapter->stats.rnbc;
+ adapter->net_stats.rx_length_errors = adapter->stats.rlec;
+ adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
+ adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
+ adapter->net_stats.rx_fifo_errors = adapter->stats.mpc;
+ adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
+
+ /* Tx Errors */
+
+ adapter->net_stats.tx_errors = adapter->stats.ecol +
+ adapter->stats.latecol;
+ adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
+ adapter->net_stats.tx_window_errors = adapter->stats.latecol;
+
+ /* Tx Dropped needs to be maintained elsewhere */
+
+ if(adapter->shared.media_type == e1000_media_type_copper) {
+ adapter->phy_stats.idle_errors +=
+ (e1000_read_phy_reg(shared, PHY_1000T_STATUS)
+ & PHY_IDLE_ERROR_COUNT_MASK);
+ adapter->phy_stats.receive_errors +=
+ e1000_read_phy_reg(shared, M88E1000_RX_ERR_CNTR);
+ }
+ return;
+}
+
+/**
+ * e1000_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ **/
+
+static inline void
+e1000_irq_disable(struct e1000_adapter *adapter)
+{
+ atomic_inc(&adapter->irq_sem);
+ E1000_WRITE_REG(&adapter->shared, IMC, ~0);
+ synchronize_irq();
+ return;
+}
+
+/**
+ * e1000_irq_enable - Enable default interrupt generation settings
+ * @adapter: board private structure
+ **/
+
+static inline void
+e1000_irq_enable(struct e1000_adapter *adapter)
+{
+ if(atomic_dec_and_test(&adapter->irq_sem))
+ E1000_WRITE_REG(&adapter->shared, IMS, IMS_ENABLE_MASK);
+ return;
+}
+
+/**
+ * e1000_intr - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ * @pt_regs: CPU registers structure
+ **/
+
+static void
+e1000_intr(int irq, void *data, struct pt_regs *regs)
+{
+ struct net_device *netdev = data;
+ struct e1000_adapter *adapter = netdev->priv;
+ uint32_t icr;
+ int i = E1000_MAX_INTR;
+
+ while(i && (icr = E1000_READ_REG(&adapter->shared, ICR))) {
+
+ if(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+ /* run the watchdog ASAP */
+ adapter->shared.get_link_status = 1;
+ mod_timer(&adapter->watchdog_timer, jiffies);
+ }
+
+ e1000_clean_rx_irq(adapter);
+ e1000_clean_tx_irq(adapter);
+ i--;
+ }
+
+ return;
+}
+
+/**
+ * e1000_clean_tx_irq - Reclaim resources after transmit completes
+ * @adapter: board private structure
+ **/
+
+static void
+e1000_clean_tx_irq(struct e1000_adapter *adapter)
+{
+ struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ struct e1000_tx_desc *tx_desc;
+ int i;
+
+ i = tx_ring->next_to_clean;
+ tx_desc = E1000_TX_DESC(*tx_ring, i);
+
+ while(tx_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
+
+ if(tx_ring->buffer_info[i].dma) {
+
+ pci_unmap_page(pdev,
+ tx_ring->buffer_info[i].dma,
+ tx_ring->buffer_info[i].length,
+ PCI_DMA_TODEVICE);
+
+ tx_ring->buffer_info[i].dma = 0;
+ }
+
+ if(tx_ring->buffer_info[i].skb) {
+
+ dev_kfree_skb_irq(tx_ring->buffer_info[i].skb);
+
+ tx_ring->buffer_info[i].skb = NULL;
+ }
+
+ memset(tx_desc, 0, sizeof(struct e1000_tx_desc));
+ mb();
+
+ atomic_inc(&tx_ring->unused);
+ i = (i + 1) % tx_ring->count;
+ tx_desc = E1000_TX_DESC(*tx_ring, i);
+
+ adapter->trans_finish = jiffies;
+ }
+
+ tx_ring->next_to_clean = i;
+
+ if(netif_queue_stopped(netdev) && netif_carrier_ok(netdev) &&
+ (atomic_read(&tx_ring->unused) > E1000_TX_QUEUE_WAKE)) {
+
+ netif_wake_queue(netdev);
+ }
+ return;
+}
+
+/**
+ * e1000_clean_rx_irq - Send received data up the network stack,
+ * @adapter: board private structure
+ **/
+
+static void
+e1000_clean_rx_irq(struct e1000_adapter *adapter)
+{
+ struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ struct e1000_rx_desc *rx_desc;
+ struct sk_buff *skb;
+ unsigned long flags;
+ uint32_t length;
+ uint8_t last_byte;
+ int i;
+
+ i = rx_ring->next_to_clean;
+ rx_desc = E1000_RX_DESC(*rx_ring, i);
+
+ while(rx_desc->status & E1000_RXD_STAT_DD) {
+
+ pci_unmap_single(pdev,
+ rx_ring->buffer_info[i].dma,
+ rx_ring->buffer_info[i].length,
+ PCI_DMA_FROMDEVICE);
+
+ skb = rx_ring->buffer_info[i].skb;
+ length = le16_to_cpu(rx_desc->length);
+
+ if(!(rx_desc->status & E1000_RXD_STAT_EOP)) {
+
+ /* All receives must fit into a single buffer */
+
+ E1000_DBG("Receive packet consumed multiple buffers\n");
+
+ dev_kfree_skb_irq(skb);
+ memset(rx_desc, 0, 16);
+ mb();
+ rx_ring->buffer_info[i].skb = NULL;
+
+ rx_ring->unused_count++;
+
+ i = (i + 1) % rx_ring->count;
+
+ rx_desc = E1000_RX_DESC(*rx_ring, i);
+ continue;
+ }
+
+ if(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
+
+ last_byte = *(skb->data + length - 1);
+
+ if(TBI_ACCEPT(&adapter->shared, rx_desc->special,
+ rx_desc->errors, length, last_byte)) {
+
+ spin_lock_irqsave(&adapter->stats_lock, flags);
+
+ e1000_tbi_adjust_stats(&adapter->shared,
+ &adapter->stats,
+ length, skb->data);
+
+ spin_unlock_irqrestore(&adapter->stats_lock,
+ flags);
+ length--;
+ } else {
+
+ dev_kfree_skb_irq(skb);
+ memset(rx_desc, 0, 16);
+ mb();
+ rx_ring->buffer_info[i].skb = NULL;
+
+ rx_ring->unused_count++;
+ i = (i + 1) % rx_ring->count;
+
+ rx_desc = E1000_RX_DESC(*rx_ring, i);
+ continue;
+ }
+ }
+
+ /* Good Receive */
+ skb_put(skb, length - CRC_LENGTH);
+
+ /* Receive Checksum Offload */
+ e1000_rx_checksum(adapter, rx_desc, skb);
+
+ skb->protocol = eth_type_trans(skb, netdev);
+ netif_rx(skb);
+
+ memset(rx_desc, 0, sizeof(struct e1000_rx_desc));
+ mb();
+ rx_ring->buffer_info[i].skb = NULL;
+
+ rx_ring->unused_count++;
+
+ i = (i + 1) % rx_ring->count;
+
+ rx_desc = E1000_RX_DESC(*rx_ring, i);
+ }
+
+ rx_ring->next_to_clean = i;
+
+ e1000_alloc_rx_buffers(adapter);
+
+ return;
+}
+
+/**
+ * e1000_alloc_rx_buffers - Replace used receive buffers
+ * @data: address of board private structure
+ **/
+
+static void
+e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
+{
+ struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ struct e1000_rx_desc *rx_desc;
+ struct sk_buff *skb;
+ int reserve_len;
+ int i;
+
+ if(!netif_running(netdev))
+ return;
+
+ reserve_len = 2;
+
+ i = rx_ring->next_to_use;
+
+ while(!rx_ring->buffer_info[i].skb) {
+ rx_desc = E1000_RX_DESC(*rx_ring, i);
+
+ skb = alloc_skb(adapter->rx_buffer_len + reserve_len,
+ GFP_ATOMIC);
+
+ if(!skb) {
+ /* Better luck next round */
+ break;
+ }
+
+ /* Make buffer alignment 2 beyond a 16 byte boundary
+ * this will result in a 16 byte aligned IP header after
+ * the 14 byte MAC header is removed
+ */
+ skb_reserve(skb, reserve_len);
+
+ skb->dev = netdev;
+
+ rx_ring->buffer_info[i].skb = skb;
+ rx_ring->buffer_info[i].length = adapter->rx_buffer_len;
+ rx_ring->buffer_info[i].dma =
+ pci_map_single(pdev,
+ skb->data,
+ adapter->rx_buffer_len,
+ PCI_DMA_FROMDEVICE);
+
+ rx_desc->buffer_addr = cpu_to_le64(rx_ring->buffer_info[i].dma);
+
+ /* move tail */
+ E1000_WRITE_REG(&adapter->shared, RDT, i);
+
+ atomic_dec(&rx_ring->unused);
+
+ i = (i + 1) % rx_ring->count;
+ }
+
+ rx_ring->next_to_use = i;
+ return;
+}
+
+/**
+ * e1000_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ **/
+
+static int
+e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+ switch (cmd) {
+ case SIOCETHTOOL:
+ return e1000_ethtool_ioctl(netdev, ifr);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+/**
+ * e1000_rx_checksum - Receive Checksum Offload for 82543
+ * @adapter: board private structure
+ * @rx_desc: receive descriptor
+ * @sk_buff: socket buffer with received data
+ **/
+
+static inline void
+e1000_rx_checksum(struct e1000_adapter *adapter,
+ struct e1000_rx_desc *rx_desc,
+ struct sk_buff *skb)
+{
+ /* 82543 or newer only */
+ if((adapter->shared.mac_type < e1000_82543) ||
+ /* Ignore Checksum bit is set */
+ (rx_desc->status & E1000_RXD_STAT_IXSM) ||
+ /* TCP Checksum has not been calculated */
+ (!(rx_desc->status & E1000_RXD_STAT_TCPCS))) {
+ skb->ip_summed = CHECKSUM_NONE;
+ return;
+ }
+
+ /* At this point we know the hardware did the TCP checksum */
+ /* now look at the TCP checksum error bit */
+ if(rx_desc->errors & E1000_RXD_ERR_TCPE) {
+ /* let the stack verify checksum errors */
+ skb->ip_summed = CHECKSUM_NONE;
+ adapter->hw_csum_err++;
+ } else {
+ /* TCP checksum is good */
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ adapter->hw_csum_good++;
+ }
+ return;
+}
+
+
+/**
+ * e1000_enable_WOL - Wake On Lan Support (Magic Pkt)
+ * @adapter: Adapter structure
+ **/
+
+void
+e1000_enable_WOL(struct e1000_adapter *adapter)
+{
+ uint32_t wuc;
+
+ if(adapter->shared.mac_type < e1000_82544)
+ return;
+
+ if(adapter->wol) {
+ wuc = E1000_WUC_APME | E1000_WUC_PME_EN |
+ E1000_WUC_PME_STATUS | E1000_WUC_APMPME;
+
+ E1000_WRITE_REG(&adapter->shared, WUC, wuc);
+
+ E1000_WRITE_REG(&adapter->shared, WUFC, adapter->wol);
+ }
+
+ return;
+}
+
+void
+e1000_write_pci_cfg(struct e1000_shared_adapter *shared,
+ uint32_t reg, uint16_t *value)
+{
+ struct e1000_adapter *adapter = shared->back;
+
+ pci_write_config_word(adapter->pdev, reg, *value);
+ return;
+}
+
+/* e1000_main.c */
diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h
new file mode 100644
index 000000000000..a7a1be20bc7c
--- /dev/null
+++ b/drivers/net/e1000/e1000_osdep.h
@@ -0,0 +1,142 @@
+/*******************************************************************************
+
+ This software program is available to you under a choice of one of two
+ licenses. You may choose to be licensed under either the GNU General Public
+ License (GPL) Version 2, June 1991, available at
+ http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
+ text of which follows:
+
+ Recipient has requested a license and Intel Corporation ("Intel") is willing
+ to grant a license for the software entitled Linux Base Driver for the
+ Intel(R) PRO/1000 Family of Adapters (e1000) (the "Software") being provided
+ by Intel Corporation. The following definitions apply to this license:
+
+ "Licensed Patents" means patent claims licensable by Intel Corporation which
+ are necessarily infringed by the use of sale of the Software alone or when
+ combined with the operating system referred to below.
+
+ "Recipient" means the party to whom Intel delivers this Software.
+
+ "Licensee" means Recipient and those third parties that receive a license to
+ any operating system available under the GNU Public License version 2.0 or
+ later.
+
+ Copyright (c) 1999 - 2002 Intel Corporation.
+ All rights reserved.
+
+ The license is provided to Recipient and Recipient's Licensees under the
+ following terms.
+
+ Redistribution and use in source and binary forms of the Software, with or
+ without modification, are permitted provided that the following conditions
+ are met:
+
+ Redistributions of source code of the Software may retain the above
+ copyright notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form of the Software may reproduce the above
+ copyright notice, this list of conditions and the following disclaimer in
+ the documentation and/or materials provided with the distribution.
+
+ Neither the name of Intel Corporation nor the names of its contributors
+ shall be used to endorse or promote products derived from this Software
+ without specific prior written permission.
+
+ Intel hereby grants Recipient and Licensees a non-exclusive, worldwide,
+ royalty-free patent license under Licensed Patents to make, use, sell, offer
+ to sell, import and otherwise transfer the Software, if any, in source code
+ and object code form. This license shall include changes to the Software
+ that are error corrections or other minor changes to the Software that do
+ not add functionality or features when the Software is incorporated in any
+ version of an operating system that has been distributed under the GNU
+ General Public License 2.0 or later. This patent license shall apply to the
+ combination of the Software and any operating system licensed under the GNU
+ Public License version 2.0 or later if, at the time Intel provides the
+ Software to Recipient, such addition of the Software to the then publicly
+ available versions of such operating systems available under the GNU Public
+ License version 2.0 or later (whether in gold, beta or alpha form) causes
+ such combination to be covered by the Licensed Patents. The patent license
+ shall not apply to any other combinations which include the Software. NO
+ hardware per se is licensed hereunder.
+
+ 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 MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR IT CONTRIBUTORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ ANY LOSS OF USE; DATA, OR PROFITS; OR BUSINESS INTERUPTION) 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.
+
+*******************************************************************************/
+
+
+/* glue for the OS independant part of e1000
+ * includes register access macros
+ */
+
+#ifndef _E1000_OSDEP_H_
+#define _E1000_OSDEP_H_
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <linux/interrupt.h>
+
+#define usec_delay(x) udelay(x)
+#define msec_delay(x) do { if(in_interrupt()) { \
+ mdelay(x); \
+ } else { \
+ set_current_state(TASK_UNINTERRUPTIBLE); \
+ schedule_timeout((x * HZ)/1000); \
+ } } while(0)
+
+#define PCI_COMMAND_REGISTER PCI_COMMAND
+#define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE
+
+typedef enum {
+ FALSE = 0,
+ TRUE = 1
+} boolean_t;
+
+#define ASSERT(x) if(!(x)) BUG()
+#define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B)
+
+#if DBG
+#define DEBUGOUT(S) printk(KERN_DEBUG S "\n")
+#define DEBUGOUT1(S, A...) printk(KERN_DEBUG S "\n", A)
+#else
+#define DEBUGOUT(S)
+#define DEBUGOUT1(S, A...)
+#endif
+
+#define DEBUGFUNC(F) DEBUGOUT(F)
+#define DEBUGOUT2 DEBUGOUT1
+#define DEBUGOUT3 DEBUGOUT2
+#define DEBUGOUT7 DEBUGOUT3
+
+
+#define E1000_WRITE_REG(a, reg, value) ( \
+ ((a)->mac_type >= e1000_82543) ? \
+ (writel((value), ((a)->hw_addr + E1000_##reg))) : \
+ (writel((value), ((a)->hw_addr + E1000_82542_##reg))))
+
+#define E1000_READ_REG(a, reg) ( \
+ ((a)->mac_type >= e1000_82543) ? \
+ readl((a)->hw_addr + E1000_##reg) : \
+ readl((a)->hw_addr + E1000_82542_##reg))
+
+#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) ( \
+ ((a)->mac_type >= e1000_82543) ? \
+ writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2))) : \
+ writel((value), ((a)->hw_addr + E1000_82542_##reg + ((offset) << 2))))
+
+#define E1000_READ_REG_ARRAY(a, reg, offset) ( \
+ ((a)->mac_type >= e1000_82543) ? \
+ readl((a)->hw_addr + E1000_##reg + ((offset) << 2)) : \
+ readl((a)->hw_addr + E1000_82542_##reg + ((offset) << 2)))
+
+#endif /* _E1000_OSDEP_H_ */
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
new file mode 100644
index 000000000000..b93595df24f2
--- /dev/null
+++ b/drivers/net/e1000/e1000_param.c
@@ -0,0 +1,709 @@
+/*******************************************************************************
+
+ This software program is available to you under a choice of one of two
+ licenses. You may choose to be licensed under either the GNU General Public
+ License (GPL) Version 2, June 1991, available at
+ http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
+ text of which follows:
+
+ Recipient has requested a license and Intel Corporation ("Intel") is willing
+ to grant a license for the software entitled Linux Base Driver for the
+ Intel(R) PRO/1000 Family of Adapters (e1000) (the "Software") being provided
+ by Intel Corporation. The following definitions apply to this license:
+
+ "Licensed Patents" means patent claims licensable by Intel Corporation which
+ are necessarily infringed by the use of sale of the Software alone or when
+ combined with the operating system referred to below.
+
+ "Recipient" means the party to whom Intel delivers this Software.
+
+ "Licensee" means Recipient and those third parties that receive a license to
+ any operating system available under the GNU Public License version 2.0 or
+ later.
+
+ Copyright (c) 1999 - 2002 Intel Corporation.
+ All rights reserved.
+
+ The license is provided to Recipient and Recipient's Licensees under the
+ following terms.
+
+ Redistribution and use in source and binary forms of the Software, with or
+ without modification, are permitted provided that the following conditions
+ are met:
+
+ Redistributions of source code of the Software may retain the above
+ copyright notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form of the Software may reproduce the above
+ copyright notice, this list of conditions and the following disclaimer in
+ the documentation and/or materials provided with the distribution.
+
+ Neither the name of Intel Corporation nor the names of its contributors
+ shall be used to endorse or promote products derived from this Software
+ without specific prior written permission.
+
+ Intel hereby grants Recipient and Licensees a non-exclusive, worldwide,
+ royalty-free patent license under Licensed Patents to make, use, sell, offer
+ to sell, import and otherwise transfer the Software, if any, in source code
+ and object code form. This license shall include changes to the Software
+ that are error corrections or other minor changes to the Software that do
+ not add functionality or features when the Software is incorporated in any
+ version of an operating system that has been distributed under the GNU
+ General Public License 2.0 or later. This patent license shall apply to the
+ combination of the Software and any operating system licensed under the GNU
+ Public License version 2.0 or later if, at the time Intel provides the
+ Software to Recipient, such addition of the Software to the then publicly
+ available versions of such operating systems available under the GNU Public
+ License version 2.0 or later (whether in gold, beta or alpha form) causes
+ such combination to be covered by the Licensed Patents. The patent license
+ shall not apply to any other combinations which include the Software. NO
+ hardware per se is licensed hereunder.
+
+ 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 MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR IT CONTRIBUTORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ ANY LOSS OF USE; DATA, OR PROFITS; OR BUSINESS INTERUPTION) 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 "e1000.h"
+
+/* This is the only thing that needs to be changed to adjust the
+ * maximum number of ports that the driver can manage.
+ */
+
+#define E1000_MAX_NIC 32
+
+#define OPTION_UNSET -1
+#define OPTION_DISABLED 0
+#define OPTION_ENABLED 1
+
+/* Module Parameters are always initialized to -1, so that the driver
+ * can tell the difference between no user specified value or the
+ * user asking for the default value.
+ * The true default values are loaded in when e1000_check_options is called.
+ *
+ * This is a GCC extension to ANSI C.
+ * See the item "Labeled Elements in Initializers" in the section
+ * "Extensions to the C Language Family" of the GCC documentation.
+ */
+
+#define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET }
+
+/* All parameters are treated the same, as an integer array of values.
+ * This macro just reduces the need to repeat the same declaration code
+ * over and over (plus this helps to avoid typo bugs).
+ */
+
+#define E1000_PARAM(X, S) \
+static const int __devinitdata X[E1000_MAX_NIC + 1] = E1000_PARAM_INIT; \
+MODULE_PARM(X, "1-" __MODULE_STRING(E1000_MAX_NIC) "i"); \
+MODULE_PARM_DESC(X, S);
+
+/* Transmit Descriptor Count
+ *
+ * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers
+ * Valid Range: 80-4096 for 82544
+ *
+ * Default Value: 256
+ */
+
+E1000_PARAM(TxDescriptors, "Number of transmit descriptors");
+
+/* Receive Descriptor Count
+ *
+ * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers
+ * Valid Range: 80-4096 for 82544
+ *
+ * Default Value: 80
+ */
+
+E1000_PARAM(RxDescriptors, "Number of receive descriptors");
+
+/* User Specified Speed Override
+ *
+ * Valid Range: 0, 10, 100, 1000
+ * - 0 - auto-negotiate at all supported speeds
+ * - 10 - only link at 10 Mbps
+ * - 100 - only link at 100 Mbps
+ * - 1000 - only link at 1000 Mbps
+ *
+ * Default Value: 0
+ */
+
+E1000_PARAM(Speed, "Speed setting");
+
+/* User Specified Duplex Override
+ *
+ * Valid Range: 0-2
+ * - 0 - auto-negotiate for duplex
+ * - 1 - only link at half duplex
+ * - 2 - only link at full duplex
+ *
+ * Default Value: 0
+ */
+
+E1000_PARAM(Duplex, "Duplex setting");
+
+/* Auto-negotiation Advertisement Override
+ *
+ * Valid Range: 0x00-0x0F, 0x20-0x2F
+ *
+ * The AutoNeg value is a bit mask describing which speed and duplex
+ * combinations should be advertised during auto-negotiation.
+ * The supported speed and duplex modes are listed below
+ *
+ * Bit 7 6 5 4 3 2 1 0
+ * Speed (Mbps) N/A N/A 1000 N/A 100 100 10 10
+ * Duplex Full Full Half Full Half
+ *
+ * Default Value: 0x2F
+ */
+
+E1000_PARAM(AutoNeg, "Advertised auto-negotiation setting");
+
+/* User Specified Flow Control Override
+ *
+ * Valid Range: 0-3
+ * - 0 - No Flow Control
+ * - 1 - Rx only, respond to PAUSE frames but do not generate them
+ * - 2 - Tx only, generate PAUSE frames but ignore them on receive
+ * - 3 - Full Flow Control Support
+ *
+ * Default Value: Read flow control settings from the EEPROM
+ */
+
+E1000_PARAM(FlowControl, "Flow Control setting");
+
+/* XsumRX - Receive Checksum Offload Enable/Disable
+ *
+ * Valid Range: 0, 1
+ * - 0 - disables all checksum offload
+ * - 1 - enables receive IP/TCP/UDP checksum offload
+ * on 82543 based NICs
+ *
+ * Default Value: 1
+ */
+
+E1000_PARAM(XsumRX, "Disable or enable Receive Checksum offload");
+
+/* Transmit Interrupt Delay in units of 1.024 microseconds
+ *
+ * Valid Range: 0-65535
+ *
+ * Default Value: 64
+ */
+
+E1000_PARAM(TxIntDelay, "Transmit Interrupt Delay");
+
+/* Receive Interrupt Delay in units of 1.024 microseconds
+ *
+ * Valid Range: 0-65535
+ *
+ * Default Value: 64
+ */
+
+E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
+
+/* MDI-X Support Enable/Disable - Applies only to Copper PHY
+ *
+ * Valid Range: 0, 3
+ * - 0 - Auto in all modes
+ * - 1 - MDI
+ * - 2 - MDI-X
+ * - 3 - Auto in 1000 Base-T mode (MDI in 10 Base-T and 100 Base-T)
+ *
+ * Default Value: 0 (Auto)
+ */
+
+E1000_PARAM(MdiX, "Set MDI/MDI-X Mode");
+
+/* Automatic Correction of Reversed Cable Polarity Enable/Disable
+ * This setting applies only to Copper PHY
+ *
+ * Valid Range: 0, 1
+ * - 0 - Disabled
+ * - 1 - Enabled
+ *
+ * Default Value: 1 (Enabled)
+ */
+
+E1000_PARAM(DisablePolarityCorrection,
+ "Disable or enable Automatic Correction for Reversed Cable Polarity");
+
+
+#define AUTONEG_ADV_DEFAULT 0x2F
+#define AUTONEG_ADV_MASK 0x2F
+#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
+
+#define DEFAULT_TXD 256
+#define MAX_TXD 256
+#define MIN_TXD 80
+#define MAX_82544_TXD 4096
+
+#define DEFAULT_RXD 80
+#define MAX_RXD 256
+#define MIN_RXD 80
+#define MAX_82544_RXD 4096
+
+#define DEFAULT_TIDV 64
+#define MAX_TIDV 0xFFFF
+#define MIN_TIDV 0
+
+#define DEFAULT_RIDV 64
+#define MAX_RIDV 0xFFFF
+#define MIN_RIDV 0
+
+#define DEFAULT_MDIX 0
+#define MAX_MDIX 3
+#define MIN_MDIX 0
+
+
+struct e1000_option {
+ enum { enable_option, range_option, list_option } type;
+ char *name;
+ char *err;
+ int def;
+ union {
+ struct { /* range_option info */
+ int min;
+ int max;
+ } r;
+ struct { /* list_option info */
+ int nr;
+ struct e1000_opt_list { int i; char *str; } *p;
+ } l;
+ } arg;
+};
+
+
+static int __devinit
+e1000_validate_option(int *value, struct e1000_option *opt)
+{
+ if(*value == OPTION_UNSET) {
+ *value = opt->def;
+ return 0;
+ }
+
+ switch (opt->type) {
+ case enable_option:
+ switch (*value) {
+ case OPTION_ENABLED:
+ printk(KERN_INFO "%s Enabled\n", opt->name);
+ return 0;
+ case OPTION_DISABLED:
+ printk(KERN_INFO "%s Disabled\n", opt->name);
+ return 0;
+ }
+ break;
+ case range_option:
+ if(*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+ printk(KERN_INFO "%s set to %i\n", opt->name, *value);
+ return 0;
+ }
+ break;
+ case list_option: {
+ int i;
+ struct e1000_opt_list *ent;
+
+ for(i = 0; i < opt->arg.l.nr; i++) {
+ ent = &opt->arg.l.p[i];
+ if(*value == ent->i) {
+ if(ent->str[0] != '\0')
+ printk(KERN_INFO "%s\n", ent->str);
+ return 0;
+ }
+ }
+ }
+ break;
+ default:
+ BUG();
+ }
+
+ printk(KERN_INFO "Invalid %s specified (%i) %s\n",
+ opt->name, *value, opt->err);
+ *value = opt->def;
+ return -1;
+}
+
+#define LIST_LEN(l) (sizeof(l) / sizeof(l[0]))
+
+static void e1000_check_fiber_options(struct e1000_adapter *adapter);
+static void e1000_check_copper_options(struct e1000_adapter *adapter);
+
+/**
+ * e1000_check_options - Range Checking for Command Line Parameters
+ * @adapter: board private structure
+ *
+ * This routine checks all command line paramters for valid user
+ * input. If an invalid value is given, or if no user specified
+ * value exists, a default value is used. The final value is stored
+ * in a variable in the adapter structure.
+ **/
+
+void __devinit
+e1000_check_options(struct e1000_adapter *adapter)
+{
+ int bd = adapter->bd_number;
+ if(bd >= E1000_MAX_NIC) {
+ printk(KERN_NOTICE
+ "Warning: no configuration for board #%i\n", bd);
+ printk(KERN_NOTICE "Using defaults for all values\n");
+ bd = E1000_MAX_NIC;
+ }
+
+ { /* Transmit Descriptor Count */
+ struct e1000_option opt = {
+ type: range_option,
+ name: "Transmit Descriptors",
+ err: "using default of " __MODULE_STRING(DEFAULT_TXD),
+ def: DEFAULT_TXD,
+ arg: { r: { min: MIN_TXD }}
+ };
+ struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+ e1000_mac_type mac_type = adapter->shared.mac_type;
+ opt.arg.r.max = mac_type < e1000_82544 ? MAX_TXD : MAX_82544_TXD;
+
+ tx_ring->count = TxDescriptors[bd];
+ e1000_validate_option(&tx_ring->count, &opt);
+ E1000_ROUNDUP(tx_ring->count, REQ_TX_DESCRIPTOR_MULTIPLE);
+ }
+ { /* Receive Descriptor Count */
+ struct e1000_option opt = {
+ type: range_option,
+ name: "Receive Descriptors",
+ err: "using default of " __MODULE_STRING(DEFAULT_RXD),
+ def: DEFAULT_RXD,
+ arg: { r: { min: MIN_RXD }}
+ };
+ struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+ e1000_mac_type mac_type = adapter->shared.mac_type;
+ opt.arg.r.max = mac_type < e1000_82544 ? MAX_RXD : MAX_82544_RXD;
+
+ rx_ring->count = RxDescriptors[bd];
+ e1000_validate_option(&rx_ring->count, &opt);
+ E1000_ROUNDUP(rx_ring->count, REQ_RX_DESCRIPTOR_MULTIPLE);
+ }
+ { /* Checksum Offload Enable/Disable */
+ struct e1000_option opt = {
+ type: enable_option,
+ name: "Checksum Offload",
+ err: "defaulting to Enabled",
+ def: OPTION_ENABLED
+ };
+
+ int rx_csum = XsumRX[bd];
+ e1000_validate_option(&rx_csum, &opt);
+ adapter->rx_csum = rx_csum;
+ }
+ { /* Flow Control */
+
+ struct e1000_opt_list fc_list[] =
+ {{ e1000_fc_none, "Flow Control Disabled" },
+ { e1000_fc_rx_pause,"Flow Control Receive Only" },
+ { e1000_fc_tx_pause,"Flow Control Transmit Only" },
+ { e1000_fc_full, "Flow Control Enabled" },
+ { e1000_fc_default, "Flow Control Hardware Default" }};
+
+ struct e1000_option opt = {
+ type: list_option,
+ name: "Flow Control",
+ err: "reading default settings from EEPROM",
+ def: e1000_fc_default,
+ arg: { l: { nr: LIST_LEN(fc_list), p: fc_list }}
+ };
+
+ int fc = FlowControl[bd];
+ e1000_validate_option(&fc, &opt);
+ adapter->shared.fc = adapter->shared.original_fc = fc;
+ }
+ { /* Transmit Interrupt Delay */
+ struct e1000_option opt = {
+ type: range_option,
+ name: "Transmit Interrupt Delay",
+ err: "using default of " __MODULE_STRING(DEFAULT_TIDV),
+ def: DEFAULT_TIDV,
+ arg: { r: { min: MIN_TIDV, max: MAX_TIDV }}
+ };
+
+ adapter->tx_int_delay = TxIntDelay[bd];
+ e1000_validate_option(&adapter->tx_int_delay, &opt);
+ }
+ { /* Receive Interrupt Delay */
+ struct e1000_option opt = {
+ type: range_option,
+ name: "Receive Interrupt Delay",
+ err: "using default of " __MODULE_STRING(DEFAULT_RIDV),
+ def: DEFAULT_RIDV,
+ arg: { r: { min: MIN_RIDV, max: MAX_RIDV }}
+ };
+
+ adapter->rx_int_delay = RxIntDelay[bd];
+ e1000_validate_option(&adapter->rx_int_delay, &opt);
+ }
+
+ switch(adapter->shared.media_type) {
+ case e1000_media_type_fiber:
+ e1000_check_fiber_options(adapter);
+ break;
+ case e1000_media_type_copper:
+ e1000_check_copper_options(adapter);
+ break;
+ default:
+ BUG();
+ }
+}
+
+/**
+ * e1000_check_fiber_options - Range Checking for Link Options, Fiber Version
+ * @adapter: board private structure
+ *
+ * Handles speed and duplex options on fiber adapters
+ **/
+
+static void __devinit
+e1000_check_fiber_options(struct e1000_adapter *adapter)
+{
+ int bd = adapter->bd_number;
+ bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd;
+
+ if((Speed[bd] != OPTION_UNSET)) {
+ printk(KERN_INFO "Speed not valid for fiber adapters, "
+ "parameter ignored\n");
+ }
+ if((Duplex[bd] != OPTION_UNSET)) {
+ printk(KERN_INFO "Duplex not valid for fiber adapters, "
+ "parameter ignored\n");
+ }
+ if((AutoNeg[bd] != OPTION_UNSET)) {
+ printk(KERN_INFO "AutoNeg not valid for fiber adapters, "
+ "parameter ignored\n");
+ }
+}
+
+/**
+ * e1000_check_copper_options - Range Checking for Link Options, Copper Version
+ * @adapter: board private structure
+ *
+ * Handles speed and duplex options on copper adapters
+ **/
+
+static void __devinit
+e1000_check_copper_options(struct e1000_adapter *adapter)
+{
+ int speed, dplx;
+ int bd = adapter->bd_number;
+ bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd;
+
+ { /* Speed */
+ struct e1000_opt_list speed_list[] = {{ 0, "" },
+ { SPEED_10, "" },
+ { SPEED_100, "" },
+ { SPEED_1000, "" }};
+ struct e1000_option opt = {
+ type: list_option,
+ name: "Speed",
+ err: "parameter ignored",
+ def: 0,
+ arg: { l: { nr: LIST_LEN(speed_list), p: speed_list }}
+ };
+
+ speed = Speed[bd];
+ e1000_validate_option(&speed, &opt);
+ }
+ { /* Duplex */
+ struct e1000_opt_list dplx_list[] = {{ 0, "" },
+ { HALF_DUPLEX, "" },
+ { FULL_DUPLEX, "" }};
+ struct e1000_option opt = {
+ type: list_option,
+ name: "Duplex",
+ err: "parameter ignored",
+ def: 0,
+ arg: { l: { nr: LIST_LEN(dplx_list), p: dplx_list }}
+ };
+
+ dplx = Duplex[bd];
+ e1000_validate_option(&dplx, &opt);
+ }
+
+ if(AutoNeg[bd] != OPTION_UNSET && (speed != 0 || dplx != 0)) {
+ printk(KERN_INFO
+ "AutoNeg specified along with Speed or Duplex, "
+ "parameter ignored\n");
+ adapter->shared.autoneg_advertised = AUTONEG_ADV_DEFAULT;
+ } else { /* Autoneg */
+ struct e1000_opt_list an_list[] =
+ #define AA "Autoneg advertising "
+ {{ 0x01, AA "10/HD" },
+ { 0x02, AA "10/FD" },
+ { 0x03, AA "10/FD, 10/HD" },
+ { 0x04, AA "100/HD" },
+ { 0x05, AA "100/HD, 10/HD" },
+ { 0x06, AA "100/HD, 10/FD" },
+ { 0x07, AA "100/HD, 10/FD, 10/HD" },
+ { 0x08, AA "100/FD" },
+ { 0x09, AA "100/FD, 10/HD" },
+ { 0x0a, AA "100/FD, 10/FD" },
+ { 0x0b, AA "100/FD, 10/FD, 10/HD" },
+ { 0x0c, AA "100/FD, 100/HD" },
+ { 0x0d, AA "100/FD, 100/HD, 10/HD" },
+ { 0x0e, AA "100/FD, 100/HD, 10/FD" },
+ { 0x0f, AA "100/FD, 100/HD, 10/FD, 10/HD" },
+ { 0x20, AA "1000/FD" },
+ { 0x21, AA "1000/FD, 10/HD" },
+ { 0x22, AA "1000/FD, 10/FD" },
+ { 0x23, AA "1000/FD, 10/FD, 10/HD" },
+ { 0x24, AA "1000/FD, 100/HD" },
+ { 0x25, AA "1000/FD, 100/HD, 10/HD" },
+ { 0x26, AA "1000/FD, 100/HD, 10/FD" },
+ { 0x27, AA "1000/FD, 100/HD, 10/FD, 10/HD" },
+ { 0x28, AA "1000/FD, 100/FD" },
+ { 0x29, AA "1000/FD, 100/FD, 10/HD" },
+ { 0x2a, AA "1000/FD, 100/FD, 10/FD" },
+ { 0x2b, AA "1000/FD, 100/FD, 10/FD, 10/HD" },
+ { 0x2c, AA "1000/FD, 100/FD, 100/HD" },
+ { 0x2d, AA "1000/FD, 100/FD, 100/HD, 10/HD" },
+ { 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" },
+ { 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" }};
+
+ struct e1000_option opt = {
+ type: list_option,
+ name: "Autoneg",
+ err: "parameter ignored",
+ def: AUTONEG_ADV_DEFAULT,
+ arg: { l: { nr: LIST_LEN(an_list), p: an_list }}
+ };
+
+ int an = AutoNeg[bd];
+ e1000_validate_option(&an, &opt);
+ adapter->shared.autoneg_advertised = an;
+ }
+
+ switch (speed + dplx) {
+ case 0:
+ adapter->shared.autoneg = 1;
+ if(Speed[bd] != OPTION_UNSET || Duplex[bd] != OPTION_UNSET)
+ printk(KERN_INFO
+ "Speed and duplex autonegotiation enabled\n");
+ break;
+ case HALF_DUPLEX:
+ printk(KERN_INFO "Half Duplex specified without Speed\n");
+ printk(KERN_INFO "Using Autonegotiation at Half Duplex only\n");
+ adapter->shared.autoneg = 1;
+ adapter->shared.autoneg_advertised = ADVERTISE_10_HALF |
+ ADVERTISE_100_HALF;
+ break;
+ case FULL_DUPLEX:
+ printk(KERN_INFO "Full Duplex specified without Speed\n");
+ printk(KERN_INFO "Using Autonegotiation at Full Duplex only\n");
+ adapter->shared.autoneg = 1;
+ adapter->shared.autoneg_advertised = ADVERTISE_10_FULL |
+ ADVERTISE_100_FULL |
+ ADVERTISE_1000_FULL;
+ break;
+ case SPEED_10:
+ printk(KERN_INFO "10 Mbps Speed specified without Duplex\n");
+ printk(KERN_INFO "Using Autonegotiation at 10 Mbps only\n");
+ adapter->shared.autoneg = 1;
+ adapter->shared.autoneg_advertised = ADVERTISE_10_HALF |
+ ADVERTISE_10_FULL;
+ break;
+ case SPEED_10 + HALF_DUPLEX:
+ printk(KERN_INFO "Forcing to 10 Mbps Half Duplex\n");
+ adapter->shared.autoneg = 0;
+ adapter->shared.forced_speed_duplex = e1000_10_half;
+ adapter->shared.autoneg_advertised = 0;
+ break;
+ case SPEED_10 + FULL_DUPLEX:
+ printk(KERN_INFO "Forcing to 10 Mbps Full Duplex\n");
+ adapter->shared.autoneg = 0;
+ adapter->shared.forced_speed_duplex = e1000_10_full;
+ adapter->shared.autoneg_advertised = 0;
+ break;
+ case SPEED_100:
+ printk(KERN_INFO "100 Mbps Speed specified without Duplex\n");
+ printk(KERN_INFO "Using Autonegotiation at 100 Mbps only\n");
+ adapter->shared.autoneg = 1;
+ adapter->shared.autoneg_advertised = ADVERTISE_100_HALF |
+ ADVERTISE_100_FULL;
+ break;
+ case SPEED_100 + HALF_DUPLEX:
+ printk(KERN_INFO "Forcing to 100 Mbps Half Duplex\n");
+ adapter->shared.autoneg = 0;
+ adapter->shared.forced_speed_duplex = e1000_100_half;
+ adapter->shared.autoneg_advertised = 0;
+ break;
+ case SPEED_100 + FULL_DUPLEX:
+ printk(KERN_INFO "Forcing to 100 Mbps Full Duplex\n");
+ adapter->shared.autoneg = 0;
+ adapter->shared.forced_speed_duplex = e1000_100_full;
+ adapter->shared.autoneg_advertised = 0;
+ break;
+ case SPEED_1000:
+ printk(KERN_INFO "1000 Mbps Speed specified without Duplex\n");
+ printk(KERN_INFO
+ "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
+ adapter->shared.autoneg = 1;
+ adapter->shared.autoneg_advertised = ADVERTISE_1000_FULL;
+ break;
+ case SPEED_1000 + HALF_DUPLEX:
+ printk(KERN_INFO "Half Duplex is not supported at 1000 Mbps\n");
+ printk(KERN_INFO
+ "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
+ adapter->shared.autoneg = 1;
+ adapter->shared.autoneg_advertised = ADVERTISE_1000_FULL;
+ break;
+ case SPEED_1000 + FULL_DUPLEX:
+ printk(KERN_INFO
+ "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
+ adapter->shared.autoneg = 1;
+ adapter->shared.autoneg_advertised = ADVERTISE_1000_FULL;
+ break;
+ default:
+ BUG();
+ }
+
+ /* a few other copper only options */
+
+ { /* MDI/MDI-X */
+ struct e1000_option opt = {
+ type: range_option,
+ name: "MDI/MDI-X",
+ err: "using default of " __MODULE_STRING(DEFAULT_MDIX),
+ def: DEFAULT_MDIX,
+ arg: { r: { min: MIN_MDIX, max: MAX_MDIX }}
+ };
+
+ int mdix = MdiX[bd];
+ e1000_validate_option(&mdix, &opt);
+ adapter->shared.mdix = mdix;
+ }
+ { /* Automatic Correction for Reverse Cable Polarity */
+ /* option is actually to disable polarity correction,
+ * so setting to OPTION_ENABLED turns the hardware feature off */
+ struct e1000_option opt = {
+ type: enable_option,
+ name: "Disable Polarity Correction",
+ err: "defaulting to Disabled",
+ def: OPTION_DISABLED,
+ };
+
+ int dpc = DisablePolarityCorrection[bd];
+ e1000_validate_option(&dpc, &opt);
+ adapter->shared.disable_polarity_correction = dpc;
+ }
+
+ /* Speed, AutoNeg and MDI/MDI-X must all play nice */
+ if (!e1000_validate_mdi_setting(&(adapter->shared))) {
+ printk(KERN_INFO "Speed, AutoNeg and MDI-X specifications are "
+ "incompatible. Setting MDI-X to a compatible value.\n");
+ }
+}
+
diff --git a/drivers/net/e1000/e1000_phy.c b/drivers/net/e1000/e1000_phy.c
new file mode 100644
index 000000000000..a1e61ccfa84a
--- /dev/null
+++ b/drivers/net/e1000/e1000_phy.c
@@ -0,0 +1,1485 @@
+/*******************************************************************************
+
+ This software program is available to you under a choice of one of two
+ licenses. You may choose to be licensed under either the GNU General Public
+ License (GPL) Version 2, June 1991, available at
+ http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
+ text of which follows:
+
+ Recipient has requested a license and Intel Corporation ("Intel") is willing
+ to grant a license for the software entitled Linux Base Driver for the
+ Intel(R) PRO/1000 Family of Adapters (e1000) (the "Software") being provided
+ by Intel Corporation. The following definitions apply to this license:
+
+ "Licensed Patents" means patent claims licensable by Intel Corporation which
+ are necessarily infringed by the use of sale of the Software alone or when
+ combined with the operating system referred to below.
+
+ "Recipient" means the party to whom Intel delivers this Software.
+
+ "Licensee" means Recipient and those third parties that receive a license to
+ any operating system available under the GNU Public License version 2.0 or
+ later.
+
+ Copyright (c) 1999 - 2002 Intel Corporation.
+ All rights reserved.
+
+ The license is provided to Recipient and Recipient's Licensees under the
+ following terms.
+
+ Redistribution and use in source and binary forms of the Software, with or
+ without modification, are permitted provided that the following conditions
+ are met:
+
+ Redistributions of source code of the Software may retain the above
+ copyright notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form of the Software may reproduce the above
+ copyright notice, this list of conditions and the following disclaimer in
+ the documentation and/or materials provided with the distribution.
+
+ Neither the name of Intel Corporation nor the names of its contributors
+ shall be used to endorse or promote products derived from this Software
+ without specific prior written permission.
+
+ Intel hereby grants Recipient and Licensees a non-exclusive, worldwide,
+ royalty-free patent license under Licensed Patents to make, use, sell, offer
+ to sell, import and otherwise transfer the Software, if any, in source code
+ and object code form. This license shall include changes to the Software
+ that are error corrections or other minor changes to the Software that do
+ not add functionality or features when the Software is incorporated in any
+ version of an operating system that has been distributed under the GNU
+ General Public License 2.0 or later. This patent license shall apply to the
+ combination of the Software and any operating system licensed under the GNU
+ Public License version 2.0 or later if, at the time Intel provides the
+ Software to Recipient, such addition of the Software to the then publicly
+ available versions of such operating systems available under the GNU Public
+ License version 2.0 or later (whether in gold, beta or alpha form) causes
+ such combination to be covered by the Licensed Patents. The patent license
+ shall not apply to any other combinations which include the Software. NO
+ hardware per se is licensed hereunder.
+
+ 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 MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR IT CONTRIBUTORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ ANY LOSS OF USE; DATA, OR PROFITS; OR BUSINESS INTERUPTION) 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.
+
+*******************************************************************************/
+
+/* e1000_phy.c
+ * Shared functions for accessing and configuring the PHY
+ */
+
+#include "e1000_mac.h"
+#include "e1000_phy.h"
+
+/******************************************************************************
+* Raises the Management Data Clock
+*
+* shared - Struct containing variables accessed by shared code
+* ctrl_reg - Device control register's current value
+******************************************************************************/
+static void
+e1000_raise_mdc(struct e1000_shared_adapter *shared,
+ uint32_t *ctrl_reg)
+{
+ /* Raise the clock input to the Management Data Clock (by setting
+ * the MDC bit), and then delay 2 microseconds.
+ */
+ E1000_WRITE_REG(shared, CTRL, (*ctrl_reg | E1000_CTRL_MDC));
+ usec_delay(2);
+ return;
+}
+
+/******************************************************************************
+* Lowers the Management Data Clock
+*
+* shared - Struct containing variables accessed by shared code
+* ctrl_reg - Device control register's current value
+******************************************************************************/
+static void
+e1000_lower_mdc(struct e1000_shared_adapter *shared,
+ uint32_t *ctrl_reg)
+{
+ /* Lower the clock input to the Management Data Clock (by clearing
+ * the MDC bit), and then delay 2 microseconds.
+ */
+ E1000_WRITE_REG(shared, CTRL, (*ctrl_reg & ~E1000_CTRL_MDC));
+ usec_delay(2);
+ return;
+}
+
+/******************************************************************************
+* Shifts data bits out to the PHY
+*
+* shared - Struct containing variables accessed by shared code
+* data - Data to send out to the PHY
+* count - Number of bits to shift out
+*
+* Bits are shifted out in MSB to LSB order.
+******************************************************************************/
+static void
+e1000_phy_shift_out(struct e1000_shared_adapter *shared,
+ uint32_t data,
+ uint16_t count)
+{
+ uint32_t ctrl_reg;
+ uint32_t mask;
+
+ ASSERT(count <= 32);
+
+ /* We need to shift "count" number of bits out to the PHY. So, the
+ * value in the "Data" parameter will be shifted out to the PHY
+ * one bit at a time. In order to do this, "Data" must be broken
+ * down into bits, which is what the "while" logic does below.
+ */
+ mask = 0x01;
+ mask <<= (count - 1);
+
+ ctrl_reg = E1000_READ_REG(shared, CTRL);
+
+ /* Set MDIO_DIR (SWDPIO1) and MDC_DIR (SWDPIO2) direction bits to
+ * be used as output pins.
+ */
+ ctrl_reg |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
+
+ while(mask) {
+ /* A "1" is shifted out to the PHY by setting the MDIO bit to
+ * "1" and then raising and lowering the Management Data Clock
+ * (MDC). A "0" is shifted out to the PHY by setting the MDIO
+ * bit to "0" and then raising and lowering the clock.
+ */
+ if(data & mask)
+ ctrl_reg |= E1000_CTRL_MDIO;
+ else
+ ctrl_reg &= ~E1000_CTRL_MDIO;
+
+ E1000_WRITE_REG(shared, CTRL, ctrl_reg);
+
+ usec_delay(2);
+
+ e1000_raise_mdc(shared, &ctrl_reg);
+ e1000_lower_mdc(shared, &ctrl_reg);
+
+ mask = mask >> 1;
+ }
+
+ /* Clear the data bit just before leaving this routine. */
+ ctrl_reg &= ~E1000_CTRL_MDIO;
+ return;
+}
+
+/******************************************************************************
+* Shifts data bits in from the PHY
+*
+* shared - Struct containing variables accessed by shared code
+*
+* Bits are shifted in in MSB to LSB order.
+******************************************************************************/
+static uint16_t
+e1000_phy_shift_in(struct e1000_shared_adapter *shared)
+{
+ uint32_t ctrl_reg;
+ uint16_t data = 0;
+ uint8_t i;
+
+ /* In order to read a register from the PHY, we need to shift in a
+ * total of 18 bits from the PHY. The first two bit (TurnAround)
+ * times are used to avoid contention on the MDIO pin when a read
+ * operation is performed. These two bits are ignored by us and
+ * thrown away. Bits are "shifted in" by raising the clock input
+ * to the Management Data Clock (setting the MDC bit), and then
+ * reading the value of the MDIO bit.
+ */
+ ctrl_reg = E1000_READ_REG(shared, CTRL);
+
+ /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as
+ * input.
+ */
+ ctrl_reg &= ~E1000_CTRL_MDIO_DIR;
+ ctrl_reg &= ~E1000_CTRL_MDIO;
+
+ E1000_WRITE_REG(shared, CTRL, ctrl_reg);
+
+ /* Raise and Lower the clock before reading in the data. This
+ * accounts for the TurnAround bits. The first clock occurred
+ * when we clocked out the last bit of the Register Address.
+ */
+ e1000_raise_mdc(shared, &ctrl_reg);
+ e1000_lower_mdc(shared, &ctrl_reg);
+
+ for(data = 0, i = 0; i < 16; i++) {
+ data = data << 1;
+ e1000_raise_mdc(shared, &ctrl_reg);
+
+ ctrl_reg = E1000_READ_REG(shared, CTRL);
+
+ /* Check to see if we shifted in a "1". */
+ if(ctrl_reg & E1000_CTRL_MDIO)
+ data |= 1;
+
+ e1000_lower_mdc(shared, &ctrl_reg);
+ }
+
+ e1000_raise_mdc(shared, &ctrl_reg);
+ e1000_lower_mdc(shared, &ctrl_reg);
+
+ /* Clear the MDIO bit just before leaving this routine. */
+ ctrl_reg &= ~E1000_CTRL_MDIO;
+
+ return (data);
+}
+
+/******************************************************************************
+* Force PHY speed and duplex settings to shared->forced_speed_duplex
+*
+* shared - Struct containing variables accessed by shared code
+******************************************************************************/
+static void
+e1000_phy_force_speed_duplex(struct e1000_shared_adapter *shared)
+{
+ uint32_t tctl_reg;
+ uint32_t ctrl_reg;
+ uint32_t shift;
+ uint16_t mii_ctrl_reg;
+ uint16_t mii_status_reg;
+ uint16_t phy_data;
+ uint16_t i;
+
+ DEBUGFUNC("e1000_phy_force_speed_duplex");
+
+ /* Turn off Flow control if we are forcing speed and duplex. */
+ shared->fc = e1000_fc_none;
+
+ DEBUGOUT1("shared->fc = %d\n", shared->fc);
+
+ /* Read the Device Control Register. */
+ ctrl_reg = E1000_READ_REG(shared, CTRL);
+
+ /* Set the bits to Force Speed and Duplex in the Device Ctrl Reg. */
+ ctrl_reg |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
+ ctrl_reg &= ~(DEVICE_SPEED_MASK);
+
+ /* Clear the Auto Speed Detect Enable bit. */
+ ctrl_reg &= ~E1000_CTRL_ASDE;
+
+ /* Read the MII Control Register. */
+ mii_ctrl_reg = e1000_read_phy_reg(shared, PHY_CTRL);
+
+ /* We need to disable autoneg in order to force link and duplex. */
+
+ mii_ctrl_reg &= ~MII_CR_AUTO_NEG_EN;
+
+ /* Are we forcing Full or Half Duplex? */
+ if(shared->forced_speed_duplex == e1000_100_full ||
+ shared->forced_speed_duplex == e1000_10_full) {
+
+ /* We want to force full duplex so we SET the full duplex bits
+ * in the Device and MII Control Registers.
+ */
+ ctrl_reg |= E1000_CTRL_FD;
+ mii_ctrl_reg |= MII_CR_FULL_DUPLEX;
+
+ DEBUGOUT("Full Duplex\n");
+ } else {
+
+ /* We want to force half duplex so we CLEAR the full duplex
+ * bits in the Device and MII Control Registers.
+ */
+ ctrl_reg &= ~E1000_CTRL_FD;
+ mii_ctrl_reg &= ~MII_CR_FULL_DUPLEX; /* Do this implies HALF */
+
+ DEBUGOUT("Half Duplex\n");
+ }
+
+ /* Are we forcing 100Mbps??? */
+ if(shared->forced_speed_duplex == e1000_100_full ||
+ shared->forced_speed_duplex == e1000_100_half) {
+
+ /* Set the 100Mb bit and turn off the 1000Mb and 10Mb bits. */
+ ctrl_reg |= E1000_CTRL_SPD_100;
+ mii_ctrl_reg |= MII_CR_SPEED_100;
+ mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
+
+ DEBUGOUT("Forcing 100mb ");
+ } else { /* Force 10MB Full or Half */
+
+ /* Set the 10Mb bit and turn off the 1000Mb and 100Mb bits. */
+ ctrl_reg &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
+ mii_ctrl_reg |= MII_CR_SPEED_10;
+ mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
+
+ DEBUGOUT("Forcing 10mb ");
+ }
+
+ /* Now we need to configure the Collision Distance. We need to read
+ * the Transmit Control Register to do this.
+ * Note: This must be done for both Half or Full Duplex.
+ */
+ tctl_reg = E1000_READ_REG(shared, TCTL);
+ DEBUGOUT1("tctl_reg = %x\n", tctl_reg);
+
+ if(!(mii_ctrl_reg & MII_CR_FULL_DUPLEX)) {
+
+ /* We are in Half Duplex mode so we need to set up our collision
+ * distance for 10/100.
+ */
+ tctl_reg &= ~E1000_TCTL_COLD;
+ shift = E1000_HDX_COLLISION_DISTANCE;
+ shift <<= E1000_COLD_SHIFT;
+ tctl_reg |= shift;
+ } else {
+ /* We are in Full Duplex mode. We have the same collision
+ * distance regardless of speed.
+ */
+ tctl_reg &= ~E1000_TCTL_COLD;
+ shift = E1000_FDX_COLLISION_DISTANCE;
+ shift <<= E1000_COLD_SHIFT;
+ tctl_reg |= shift;
+ }
+
+ /* Write the configured values back to the Transmit Control Reg. */
+ E1000_WRITE_REG(shared, TCTL, tctl_reg);
+
+ /* Write the configured values back to the Device Control Reg. */
+ E1000_WRITE_REG(shared, CTRL, ctrl_reg);
+
+ /* Write the MII Control Register with the new PHY configuration. */
+ phy_data = e1000_read_phy_reg(shared, M88E1000_PHY_SPEC_CTRL);
+
+ /* Clear Auto-Crossover to force MDI manually.
+ * M88E1000 requires MDI forced whenever speed/duplex is forced
+ */
+ phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+
+ e1000_write_phy_reg(shared, M88E1000_PHY_SPEC_CTRL, phy_data);
+
+ DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data);
+
+ /* Need to reset the PHY or these bits will get ignored. */
+ mii_ctrl_reg |= MII_CR_RESET;
+
+ e1000_write_phy_reg(shared, PHY_CTRL, mii_ctrl_reg);
+
+ /* The wait_autoneg_complete flag may be a little misleading here.
+ * Since we are forcing speed and duplex, Auto-Neg is not enabled.
+ * But we do want to delay for a period while forcing only so we
+ * don't generate false No Link messages. So we will wait here
+ * only if the user has set wait_autoneg_complete to 1, which is
+ * the default.
+ */
+ if(shared->wait_autoneg_complete) {
+ /* We will wait for autoneg to complete. */
+ DEBUGOUT("Waiting for forced speed/duplex link.\n");
+ mii_status_reg = 0;
+
+ /* We will wait for autoneg to complete or 4.5 seconds to expire. */
+ for(i = PHY_FORCE_TIME; i > 0; i--) {
+ /* Read the MII Status Register and wait for Auto-Neg
+ * Complete bit to be set.
+ */
+ mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+ mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+
+ if(mii_status_reg & MII_SR_LINK_STATUS)
+ break;
+
+ msec_delay(100);
+ } /* end for loop */
+
+ if(i == 0) { /* We didn't get link */
+
+ /* Reset the DSP and wait again for link. */
+ e1000_phy_reset_dsp(shared);
+ }
+
+ /* This loop will early-out if the link condition has been met. */
+ for(i = PHY_FORCE_TIME; i > 0; i--) {
+ if(mii_status_reg & MII_SR_LINK_STATUS)
+ break;
+
+ msec_delay(100);
+ /* Read the MII Status Register and wait for Auto-Neg
+ * Complete bit to be set.
+ */
+ mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+ mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+
+ } /* end for loop */
+ } /* end if wait_autoneg_complete */
+ /*
+ * Because we reset the PHY above, we need to re-force TX_CLK in the
+ * Extended PHY Specific Control Register to 25MHz clock. This
+ * value defaults back to a 2.5MHz clock when the PHY is reset.
+ */
+ phy_data = e1000_read_phy_reg(shared, M88E1000_EXT_PHY_SPEC_CTRL);
+
+ phy_data |= M88E1000_EPSCR_TX_CLK_25;
+
+ e1000_write_phy_reg(shared, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
+
+ /* In addition, because of the s/w reset above, we need to enable
+ * CRS on TX. This must be set for both full and half duplex
+ * operation.
+ */
+ phy_data = e1000_read_phy_reg(shared, M88E1000_PHY_SPEC_CTRL);
+
+ phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+
+ e1000_write_phy_reg(shared, M88E1000_PHY_SPEC_CTRL, phy_data);
+ DEBUGOUT1("M88E1000 Phy Specific Ctrl Reg = %4x\r\n", phy_data);
+
+ return;
+}
+
+/*****************************************************************************
+* Reads the value from a PHY register
+*
+* shared - Struct containing variables accessed by shared code
+* reg_addr - address of the PHY register to read
+******************************************************************************/
+uint16_t
+e1000_read_phy_reg(struct e1000_shared_adapter *shared,
+ uint32_t reg_addr)
+{
+ uint32_t i;
+ uint32_t data = 0;
+ uint32_t command = 0;
+
+ ASSERT(reg_addr <= MAX_PHY_REG_ADDRESS);
+
+ if(shared->mac_type > e1000_82543) {
+ /* Set up Op-code, Phy Address, and
+ * register address in the MDI Control register. The MAC will
+ * take care of interfacing with the PHY to retrieve the
+ * desired data.
+ */
+ command = ((reg_addr << E1000_MDIC_REG_SHIFT) |
+ (shared->phy_addr << E1000_MDIC_PHY_SHIFT) |
+ (E1000_MDIC_OP_READ));
+
+ E1000_WRITE_REG(shared, MDIC, command);
+
+ /* Check every 10 usec to see if the read completed. The read
+ * may take as long as 64 usecs (we'll wait 100 usecs max)
+ * from the CPU Write to the Ready bit assertion.
+ */
+ for(i = 0; i < 64; i++) {
+ usec_delay(10);
+
+ data = E1000_READ_REG(shared, MDIC);
+
+ if(data & E1000_MDIC_READY)
+ break;
+ }
+ } else {
+ /* We must first send a preamble through the MDIO pin to signal the
+ * beginning of an MII instruction. This is done by sending 32
+ * consecutive "1" bits.
+ */
+ e1000_phy_shift_out(shared, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
+
+ /* Now combine the next few fields that are required for a read
+ * operation. We use this method instead of calling the
+ * e1000_phy_shift_out routine five different times. The format of
+ * a MII read instruction consists of a shift out of 14 bits and is
+ * defined as follows:
+ * <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
+ * followed by a shift in of 18 bits. This first two bits shifted
+ * in are TurnAround bits used to avoid contention on the MDIO pin
+ * when a READ operation is performed. These two bits are thrown
+ * away followed by a shift in of 16 bits which contains the
+ * desired data.
+ */
+ command = ((reg_addr) |
+ (shared->phy_addr << 5) |
+ (PHY_OP_READ << 10) | (PHY_SOF << 12));
+
+ e1000_phy_shift_out(shared, command, 14);
+
+ /* Now that we've shifted out the read command to the MII, we need
+ * to "shift in" the 16-bit value (18 total bits) of the requested
+ * PHY register address.
+ */
+ data = (uint32_t) e1000_phy_shift_in(shared);
+ }
+
+ ASSERT(!(data & E1000_MDIC_ERROR));
+
+ return ((uint16_t) data);
+}
+
+/******************************************************************************
+* Writes a value to a PHY register
+*
+* shared - Struct containing variables accessed by shared code
+* reg_addr - address of the PHY register to write
+* data - data to write to the PHY
+******************************************************************************/
+void
+e1000_write_phy_reg(struct e1000_shared_adapter *shared,
+ uint32_t reg_addr,
+ uint16_t data)
+{
+ uint32_t i;
+ uint32_t command = 0;
+ uint32_t mdic_reg;
+
+ ASSERT(reg_addr <= MAX_PHY_REG_ADDRESS);
+
+ if(shared->mac_type > e1000_82543) {
+ /* Set up Op-code, Phy Address, register
+ * address, and data intended for the PHY register in the MDI
+ * Control register. The MAC will take care of interfacing
+ * with the PHY to send the desired data.
+ */
+ command = (((uint32_t) data) |
+ (reg_addr << E1000_MDIC_REG_SHIFT) |
+ (shared->phy_addr << E1000_MDIC_PHY_SHIFT) |
+ (E1000_MDIC_OP_WRITE));
+
+ E1000_WRITE_REG(shared, MDIC, command);
+
+ /* Check every 10 usec to see if the read completed. The read
+ * may take as long as 64 usecs (we'll wait 100 usecs max)
+ * from the CPU Write to the Ready bit assertion.
+ */
+ for(i = 0; i < 10; i++) {
+ usec_delay(10);
+
+ mdic_reg = E1000_READ_REG(shared, MDIC);
+
+ if(mdic_reg & E1000_MDIC_READY)
+ break;
+ }
+ } else {
+ /* We'll need to use the SW defined pins to shift the write command
+ * out to the PHY. We first send a preamble to the PHY to signal the
+ * beginning of the MII instruction. This is done by sending 32
+ * consecutive "1" bits.
+ */
+ e1000_phy_shift_out(shared, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
+
+ /* Now combine the remaining required fields that will indicate
+ * a write operation. We use this method instead of calling the
+ * e1000_phy_shift_out routine for each field in the command. The
+ * format of a MII write instruction is as follows:
+ * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
+ */
+ command = ((PHY_TURNAROUND) |
+ (reg_addr << 2) |
+ (shared->phy_addr << 7) |
+ (PHY_OP_WRITE << 12) | (PHY_SOF << 14));
+ command <<= 16;
+ command |= ((uint32_t) data);
+
+ e1000_phy_shift_out(shared, command, 32);
+ }
+ return;
+}
+
+/******************************************************************************
+* Returns the PHY to the power-on reset state
+*
+* shared - Struct containing variables accessed by shared code
+******************************************************************************/
+void
+e1000_phy_hw_reset(struct e1000_shared_adapter *shared)
+{
+ uint32_t ctrl_reg;
+ uint32_t ctrl_ext_reg;
+
+ DEBUGFUNC("e1000_phy_hw_reset");
+
+ DEBUGOUT("Resetting Phy...\n");
+
+ if(shared->mac_type > e1000_82543) {
+ /* Read the device control register and assert the
+ * E1000_CTRL_PHY_RST bit. Hold for 20ms and then take it out
+ * of reset.
+ */
+ ctrl_reg = E1000_READ_REG(shared, CTRL);
+
+ ctrl_reg |= E1000_CTRL_PHY_RST;
+
+ E1000_WRITE_REG(shared, CTRL, ctrl_reg);
+
+ msec_delay(20);
+
+ ctrl_reg &= ~E1000_CTRL_PHY_RST;
+
+ E1000_WRITE_REG(shared, CTRL, ctrl_reg);
+
+ msec_delay(20);
+ } else {
+ /* Read the Extended Device Control Register, assert the
+ * PHY_RESET_DIR bit. Then clock it out to the PHY.
+ */
+ ctrl_ext_reg = E1000_READ_REG(shared, CTRL_EXT);
+
+ ctrl_ext_reg |= E1000_CTRL_PHY_RESET_DIR4;
+
+ E1000_WRITE_REG(shared, CTRL_EXT, ctrl_ext_reg);
+
+ msec_delay(20);
+
+ /* Set the reset bit in the device control register and clock
+ * it out to the PHY.
+ */
+ ctrl_ext_reg = E1000_READ_REG(shared, CTRL_EXT);
+
+ ctrl_ext_reg &= ~E1000_CTRL_PHY_RESET4;
+
+ E1000_WRITE_REG(shared, CTRL_EXT, ctrl_ext_reg);
+
+ msec_delay(20);
+
+ ctrl_ext_reg = E1000_READ_REG(shared, CTRL_EXT);
+
+ ctrl_ext_reg |= E1000_CTRL_PHY_RESET4;
+
+ E1000_WRITE_REG(shared, CTRL_EXT, ctrl_ext_reg);
+
+ msec_delay(20);
+ }
+ return;
+}
+
+/******************************************************************************
+* Resets the PHY
+*
+* shared - Struct containing variables accessed by shared code
+*
+* Sets bit 15 of the MII Control regiser
+******************************************************************************/
+boolean_t
+e1000_phy_reset(struct e1000_shared_adapter *shared)
+{
+ uint16_t reg_data;
+ uint16_t i;
+
+ DEBUGFUNC("e1000_phy_reset");
+
+ /* Read the MII control register, set the reset bit and write the
+ * value back by clocking it out to the PHY.
+ */
+ reg_data = e1000_read_phy_reg(shared, PHY_CTRL);
+
+ reg_data |= MII_CR_RESET;
+
+ e1000_write_phy_reg(shared, PHY_CTRL, reg_data);
+
+ /* Wait for bit 15 of the MII Control Register to be cleared
+ * indicating the PHY has been reset.
+ */
+ i = 0;
+ while((reg_data & MII_CR_RESET) && i++ < 500) {
+ reg_data = e1000_read_phy_reg(shared, PHY_CTRL);
+ usec_delay(1);
+ }
+
+ if(i >= 500) {
+ DEBUGOUT("Timeout waiting for PHY to reset.\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/******************************************************************************
+* Detects which PHY is present and the speed and duplex
+*
+* shared - Struct containing variables accessed by shared code
+* ctrl_reg - current value of the device control register
+******************************************************************************/
+boolean_t
+e1000_phy_setup(struct e1000_shared_adapter *shared,
+ uint32_t ctrl_reg)
+{
+ uint16_t mii_ctrl_reg;
+ uint16_t mii_status_reg;
+ uint16_t phy_specific_ctrl_reg;
+ uint16_t mii_autoneg_adv_reg;
+ uint16_t mii_1000t_ctrl_reg;
+ uint16_t i;
+ uint16_t data;
+ uint16_t autoneg_hw_setting;
+ uint16_t autoneg_fc_setting;
+ boolean_t restart_autoneg = FALSE;
+ boolean_t force_autoneg_restart = FALSE;
+
+ DEBUGFUNC("e1000_phy_setup");
+
+ /* We want to enable the Auto-Speed Detection bit in the Device
+ * Control Register. When set to 1, the MAC automatically detects
+ * the resolved speed of the link and self-configures appropriately.
+ * The Set Link Up bit must also be set for this behavior work
+ * properly.
+ */
+ /* Nothing but 82543 and newer */
+ ASSERT(shared->mac_type >= e1000_82543);
+
+ /* With 82543, we need to force speed/duplex
+ * on the MAC equal to what the PHY speed/duplex configuration is.
+ * In addition, on 82543, we need to perform a hardware reset
+ * on the PHY to take it out of reset.
+ */
+ if(shared->mac_type >= e1000_82544) {
+ ctrl_reg |= E1000_CTRL_SLU;
+ E1000_WRITE_REG(shared, CTRL, ctrl_reg);
+ } else {
+ ctrl_reg |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
+ E1000_WRITE_REG(shared, CTRL, ctrl_reg);
+
+ if(shared->mac_type == e1000_82543)
+ e1000_phy_hw_reset(shared);
+ }
+
+ if(!e1000_detect_gig_phy(shared)) {
+ /* No PHY detected, return FALSE */
+ DEBUGOUT("PhySetup failure, did not detect valid phy.\n");
+ return (FALSE);
+ }
+
+ DEBUGOUT1("Phy ID = %x \n", shared->phy_id);
+
+ /* Read the MII Control Register. */
+ mii_ctrl_reg = e1000_read_phy_reg(shared, PHY_CTRL);
+
+ DEBUGOUT1("MII Ctrl Reg contents = %x\n", mii_ctrl_reg);
+
+ /* Check to see if the Auto Neg Enable bit is set in the MII Control
+ * Register. If not, we could be in a situation where a driver was
+ * loaded previously and was forcing speed and duplex. Then the
+ * driver was unloaded but a e1000_phy_hw_reset was not performed, so
+ * link was still being forced and link was still achieved. Then
+ * the driver was reloaded with the intention to auto-negotiate, but
+ * since link is already established we end up not restarting
+ * auto-neg. So if the auto-neg bit is not enabled and the driver
+ * is being loaded with the desire to auto-neg, we set this flag to
+ * to ensure the restart of the auto-neg engine later in the logic.
+ */
+ if(!(mii_ctrl_reg & MII_CR_AUTO_NEG_EN))
+ force_autoneg_restart = TRUE;
+
+ /* Clear the isolate bit for normal operation and write it back to
+ * the MII Control Reg. Although the spec says this doesn't need
+ * to be done when the PHY address is not equal to zero, we do it
+ * anyway just to be safe.
+ */
+ mii_ctrl_reg &= ~(MII_CR_ISOLATE);
+
+ e1000_write_phy_reg(shared, PHY_CTRL, mii_ctrl_reg);
+
+ data = e1000_read_phy_reg(shared, M88E1000_PHY_SPEC_CTRL);
+
+ /* Enable CRS on TX. This must be set for half-duplex operation. */
+ data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+
+ DEBUGOUT1("M88E1000 PSCR: %x \n", data);
+
+ e1000_write_phy_reg(shared, M88E1000_PHY_SPEC_CTRL, data);
+
+ data = e1000_read_phy_reg(shared, M88E1000_EXT_PHY_SPEC_CTRL);
+
+ /* Force TX_CLK in the Extended PHY Specific Control Register
+ * to 25MHz clock.
+ */
+ data |= M88E1000_EPSCR_TX_CLK_25;
+
+ e1000_write_phy_reg(shared, M88E1000_EXT_PHY_SPEC_CTRL, data);
+
+ /* Certain PHYs will set the default of MII register 4 differently.
+ * We need to check this against our fc value. If it is
+ * different, we need to setup up register 4 correctly and restart
+ * autonegotiation.
+ */
+ /* Read the MII Auto-Neg Advertisement Register (Address 4). */
+ mii_autoneg_adv_reg = e1000_read_phy_reg(shared, PHY_AUTONEG_ADV);
+
+ /* Shift right to put 10T-Half bit in bit 0
+ * Isolate the four bits for 100/10 Full/Half.
+ */
+ autoneg_hw_setting = (mii_autoneg_adv_reg >> 5) & 0xF;
+
+ /* Get the 1000T settings. */
+ mii_1000t_ctrl_reg = e1000_read_phy_reg(shared, PHY_1000T_CTRL);
+
+ /* Isolate and OR in the 1000T settings. */
+ autoneg_hw_setting |= ((mii_1000t_ctrl_reg & 0x0300) >> 4);
+
+ /* mask all bits in the MII Auto-Neg Advertisement Register
+ * except for ASM_DIR and PAUSE and shift. This value
+ * will be used later to see if we need to restart Auto-Negotiation.
+ */
+ autoneg_fc_setting = ((mii_autoneg_adv_reg & 0x0C00) >> 10);
+
+ /* Perform some bounds checking on the shared->autoneg_advertised
+ * parameter. If this variable is zero, then set it to the default.
+ */
+ shared->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
+
+ /* If autoneg_advertised is zero, we assume it was not defaulted
+ * by the calling code so we set to advertise full capability.
+ */
+ if(shared->autoneg_advertised == 0)
+ shared->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+
+ /* We could be in the situation where Auto-Neg has already completed
+ * and the user has not indicated any overrides. In this case we
+ * simply need to call e1000_get_speed_and_duplex to obtain the Auto-
+ * Negotiated speed and duplex, then return.
+ */
+ if(!force_autoneg_restart && shared->autoneg &&
+ (shared->autoneg_advertised == autoneg_hw_setting) &&
+ (shared->fc == autoneg_fc_setting)) {
+
+ DEBUGOUT("No overrides - Reading MII Status Reg..\n");
+
+ /* Read the MII Status Register. We read this twice because
+ * certain bits are "sticky" and need to be read twice.
+ */
+ mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+ mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+
+ DEBUGOUT1("MII Status Reg contents = %x\n", mii_status_reg);
+
+ /* Do we have link now? (if so, auto-neg has completed) */
+ if(mii_status_reg & MII_SR_LINK_STATUS) {
+ data = e1000_read_phy_reg(shared, M88E1000_PHY_SPEC_STATUS);
+ DEBUGOUT1("M88E1000 Phy Specific Status Reg contents = %x\n", data);
+
+ /* We have link, so we need to finish the config process:
+ * 1) Set up the MAC to the current PHY speed/duplex
+ * if we are on 82543. If we
+ * are on newer silicon, we only need to configure
+ * collision distance in the Transmit Control Register.
+ * 2) Set up flow control on the MAC to that established
+ * with the link partner.
+ */
+ if(shared->mac_type >= e1000_82544)
+ e1000_config_collision_dist(shared);
+ else
+ e1000_config_mac_to_phy(shared, data);
+
+ e1000_config_fc_after_link_up(shared);
+
+ return (TRUE);
+ }
+ }
+
+ /* Options:
+ * MDI/MDI-X = 0 (default)
+ * 0 - Auto for all speeds
+ * 1 - MDI mode
+ * 2 - MDI-X mode
+ * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
+ */
+ phy_specific_ctrl_reg = e1000_read_phy_reg(shared, M88E1000_PHY_SPEC_CTRL);
+
+ phy_specific_ctrl_reg &= ~M88E1000_PSCR_AUTO_X_MODE;
+
+ switch (shared->mdix) {
+ case 1:
+ phy_specific_ctrl_reg |= M88E1000_PSCR_MDI_MANUAL_MODE;
+ break;
+ case 2:
+ phy_specific_ctrl_reg |= M88E1000_PSCR_MDIX_MANUAL_MODE;
+ break;
+ case 3:
+ phy_specific_ctrl_reg |= M88E1000_PSCR_AUTO_X_1000T;
+ break;
+ case 0:
+ default:
+ phy_specific_ctrl_reg |= M88E1000_PSCR_AUTO_X_MODE;
+ break;
+ }
+
+ e1000_write_phy_reg(shared, M88E1000_PHY_SPEC_CTRL, phy_specific_ctrl_reg);
+
+ /* Options:
+ * disable_polarity_correction = 0 (default)
+ * Automatic Correction for Reversed Cable Polarity
+ * 0 - Disabled
+ * 1 - Enabled
+ */
+ phy_specific_ctrl_reg = e1000_read_phy_reg(shared, M88E1000_PHY_SPEC_CTRL);
+
+ phy_specific_ctrl_reg &= ~M88E1000_PSCR_POLARITY_REVERSAL;
+
+ if(shared->disable_polarity_correction == 1)
+ phy_specific_ctrl_reg |= M88E1000_PSCR_POLARITY_REVERSAL;
+
+ e1000_write_phy_reg(shared, M88E1000_PHY_SPEC_CTRL, phy_specific_ctrl_reg);
+
+ /* Options:
+ * autoneg = 1 (default)
+ * PHY will advertise value(s) parsed from
+ * autoneg_advertised and fc
+ * autoneg = 0
+ * PHY will be set to 10H, 10F, 100H, or 100F
+ * depending on value parsed from forced_speed_duplex.
+ */
+
+ /* Is autoneg enabled? This is enabled by default or by software override.
+ * If so, call e1000_phy_setup_autoneg routine to parse the
+ * autoneg_advertised and fc options. If autoneg is NOT enabled, then the
+ * user should have provided a speed/duplex override. If so, then call
+ * e1000_phy_force_speed_duplex to parse and set this up. Otherwise,
+ * we are in an error situation and need to bail.
+ */
+ if(shared->autoneg) {
+ DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
+ restart_autoneg = e1000_phy_setup_autoneg(shared);
+ } else {
+ DEBUGOUT("Forcing speed and duplex\n");
+ e1000_phy_force_speed_duplex(shared);
+ }
+
+ /* Based on information parsed above, check the flag to indicate
+ * whether we need to restart Auto-Neg.
+ */
+ if(restart_autoneg) {
+ DEBUGOUT("Restarting Auto-Neg\n");
+
+ /* Read the MII Control Register. */
+ mii_ctrl_reg = e1000_read_phy_reg(shared, PHY_CTRL);
+
+ /* Restart auto-negotiation by setting the Auto Neg Enable bit and
+ * the Auto Neg Restart bit.
+ */
+ mii_ctrl_reg |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
+
+ e1000_write_phy_reg(shared, PHY_CTRL, mii_ctrl_reg);
+
+ /* Does the user want to wait for Auto-Neg to complete here, or
+ * check at a later time (for example, callback routine).
+ */
+ if(shared->wait_autoneg_complete)
+ e1000_wait_autoneg(shared);
+ } /* end if restart_autoneg */
+
+ /* Read the MII Status Register. */
+ mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+ mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+
+ DEBUGOUT1("Checking for link status - MII Status Reg contents = %x\n",
+ mii_status_reg);
+
+ /* Check link status. Wait up to 100 microseconds for link to
+ * become valid.
+ */
+ for(i = 0; i < 10; i++) {
+ if(mii_status_reg & MII_SR_LINK_STATUS)
+ break;
+ usec_delay(10);
+ DEBUGOUT(". ");
+
+ mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+ mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+ }
+
+ if(mii_status_reg & MII_SR_LINK_STATUS) {
+ /* Yes, so configure MAC to PHY settings as well as flow control
+ * registers.
+ */
+ data = e1000_read_phy_reg(shared, M88E1000_PHY_SPEC_STATUS);
+
+ DEBUGOUT1("M88E1000 Phy Specific Status Reg contents = %x\n", data);
+
+ /* We have link, so we need to finish the config process:
+ * 1) Set up the MAC to the current PHY speed/duplex
+ * if we are on 82543. If we
+ * are on newer silicon, we only need to configure
+ * collision distance in the Transmit Control Register.
+ * 2) Set up flow control on the MAC to that established with
+ * the link partner.
+ */
+ if(shared->mac_type >= e1000_82544)
+ e1000_config_collision_dist(shared);
+ else
+ e1000_config_mac_to_phy(shared, data);
+
+ e1000_config_fc_after_link_up(shared);
+
+ DEBUGOUT("Valid link established!!!\n");
+ } else {
+ DEBUGOUT("Unable to establish link!!!\n");
+ }
+
+ return (TRUE);
+}
+
+/******************************************************************************
+* Configures PHY autoneg and flow control advertisement settings
+*
+* shared - Struct containing variables accessed by shared code
+******************************************************************************/
+boolean_t
+e1000_phy_setup_autoneg(struct e1000_shared_adapter *shared)
+{
+ uint16_t mii_autoneg_adv_reg;
+ uint16_t mii_1000t_ctrl_reg;
+
+ DEBUGFUNC("e1000_phy_setup_autoneg");
+
+ /* Read the MII Auto-Neg Advertisement Register (Address 4). */
+ mii_autoneg_adv_reg = e1000_read_phy_reg(shared, PHY_AUTONEG_ADV);
+
+ /* Read the MII 1000Base-T Control Register (Address 9). */
+ mii_1000t_ctrl_reg = e1000_read_phy_reg(shared, PHY_1000T_CTRL);
+
+ /* Need to parse both autoneg_advertised and fc and set up
+ * the appropriate PHY registers. First we will parse for
+ * autoneg_advertised software override. Since we can advertise
+ * a plethora of combinations, we need to check each bit
+ * individually.
+ */
+
+ /* First we clear all the 10/100 mb speed bits in the Auto-Neg
+ * Advertisement Register (Address 4) and the 1000 mb speed bits in
+ * the 1000Base-T Control Register (Address 9).
+ */
+ mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
+ mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
+
+ DEBUGOUT1("autoneg_advertised %x\n", shared->autoneg_advertised);
+
+ /* Do we want to advertise 10 Mb Half Duplex? */
+ if(shared->autoneg_advertised & ADVERTISE_10_HALF) {
+ DEBUGOUT("Advertise 10mb Half duplex\n");
+ mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
+ }
+
+ /* Do we want to advertise 10 Mb Full Duplex? */
+ if(shared->autoneg_advertised & ADVERTISE_10_FULL) {
+ DEBUGOUT("Advertise 10mb Full duplex\n");
+ mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
+ }
+
+ /* Do we want to advertise 100 Mb Half Duplex? */
+ if(shared->autoneg_advertised & ADVERTISE_100_HALF) {
+ DEBUGOUT("Advertise 100mb Half duplex\n");
+ mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
+ }
+
+ /* Do we want to advertise 100 Mb Full Duplex? */
+ if(shared->autoneg_advertised & ADVERTISE_100_FULL) {
+ DEBUGOUT("Advertise 100mb Full duplex\n");
+ mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
+ }
+
+ /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
+ if(shared->autoneg_advertised & ADVERTISE_1000_HALF) {
+ DEBUGOUT("Advertise 1000mb Half duplex requested, request denied!\n");
+ }
+
+ /* Do we want to advertise 1000 Mb Full Duplex? */
+ if(shared->autoneg_advertised & ADVERTISE_1000_FULL) {
+ DEBUGOUT("Advertise 1000mb Full duplex\n");
+ mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
+ }
+
+ /* Check for a software override of the flow control settings, and
+ * setup the PHY advertisement registers accordingly. If
+ * auto-negotiation is enabled, then software will have to set the
+ * "PAUSE" bits to the correct value in the Auto-Negotiation
+ * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation.
+ *
+ * The possible values of the "fc" parameter are:
+ * 0: Flow control is completely disabled
+ * 1: Rx flow control is enabled (we can receive pause frames
+ * but not send pause frames).
+ * 2: Tx flow control is enabled (we can send pause frames
+ * but we do not support receiving pause frames).
+ * 3: Both Rx and TX flow control (symmetric) are enabled.
+ * other: No software override. The flow control configuration
+ * in the EEPROM is used.
+ */
+ switch (shared->fc) {
+ case e1000_fc_none: /* 0 */
+ /* Flow control (RX & TX) is completely disabled by a
+ * software over-ride.
+ */
+ mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+ break;
+ case e1000_fc_rx_pause: /* 1 */
+ /* RX Flow control is enabled, and TX Flow control is
+ * disabled, by a software over-ride.
+ */
+
+ /* Since there really isn't a way to advertise that we are
+ * capable of RX Pause ONLY, we will advertise that we
+ * support both symmetric and asymmetric RX PAUSE. Later
+ * (in e1000_config_fc_after_link_up) we will disable the
+ *shared's ability to send PAUSE frames.
+ */
+ mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+ break;
+ case e1000_fc_tx_pause: /* 2 */
+ /* TX Flow control is enabled, and RX Flow control is
+ * disabled, by a software over-ride.
+ */
+ mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
+ mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
+ break;
+ case e1000_fc_full: /* 3 */
+ /* Flow control (both RX and TX) is enabled by a software
+ * over-ride.
+ */
+ mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+ break;
+ default:
+ /* We should never get here. The value should be 0-3. */
+ DEBUGOUT("Flow control param set incorrectly\n");
+ ASSERT(0);
+ break;
+ }
+
+ /* Write the MII Auto-Neg Advertisement Register (Address 4). */
+ e1000_write_phy_reg(shared, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
+
+ DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
+
+ /* Write the MII 1000Base-T Control Register (Address 9). */
+ e1000_write_phy_reg(shared, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
+ return (TRUE);
+}
+
+/******************************************************************************
+* Sets MAC speed and duplex settings to reflect the those in the PHY
+*
+* shared - Struct containing variables accessed by shared code
+* mii_reg - data to write to the MII control register
+*
+* The contents of the PHY register containing the needed information need to
+* be passed in.
+******************************************************************************/
+void
+e1000_config_mac_to_phy(struct e1000_shared_adapter *shared,
+ uint16_t mii_reg)
+{
+ uint32_t ctrl_reg;
+ uint32_t tctl_reg;
+ uint32_t shift;
+
+ DEBUGFUNC("e1000_config_mac_to_phy");
+
+ /* We need to read the Transmit Control register to configure the
+ * collision distance.
+ * Note: This must be done for both Half or Full Duplex.
+ */
+ tctl_reg = E1000_READ_REG(shared, TCTL);
+ DEBUGOUT1("tctl_reg = %x\n", tctl_reg);
+
+ /* Read the Device Control Register and set the bits to Force Speed
+ * and Duplex.
+ */
+ ctrl_reg = E1000_READ_REG(shared, CTRL);
+
+ ctrl_reg |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
+ ctrl_reg &= ~(DEVICE_SPEED_MASK);
+
+ DEBUGOUT1("MII Register Data = %x\r\n", mii_reg);
+
+ /* Clear the ILOS bit. */
+ ctrl_reg &= ~E1000_CTRL_ILOS;
+
+ /* Set up duplex in the Device Control and Transmit Control
+ * registers depending on negotiated values.
+ */
+ if(mii_reg & M88E1000_PSSR_DPLX) {
+ ctrl_reg |= E1000_CTRL_FD;
+
+ /* We are in Full Duplex mode. We have the same collision
+ * distance regardless of speed.
+ */
+ tctl_reg &= ~E1000_TCTL_COLD;
+ shift = E1000_FDX_COLLISION_DISTANCE;
+ shift <<= E1000_COLD_SHIFT;
+ tctl_reg |= shift;
+ } else {
+ ctrl_reg &= ~E1000_CTRL_FD;
+
+ /* We are in Half Duplex mode. Our Half Duplex collision
+ * distance is different for Gigabit than for 10/100 so we will
+ * set accordingly.
+ */
+ if((mii_reg & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
+ /* 1000Mbs HDX */
+ tctl_reg &= ~E1000_TCTL_COLD;
+ shift = E1000_GB_HDX_COLLISION_DISTANCE;
+ shift <<= E1000_COLD_SHIFT;
+ tctl_reg |= shift;
+ tctl_reg |= E1000_TCTL_PBE; /* Enable Packet Bursting */
+ } else {
+ /* 10/100Mbs HDX */
+ tctl_reg &= ~E1000_TCTL_COLD;
+ shift = E1000_HDX_COLLISION_DISTANCE;
+ shift <<= E1000_COLD_SHIFT;
+ tctl_reg |= shift;
+ }
+ }
+
+ /* Set up speed in the Device Control register depending on
+ * negotiated values.
+ */
+ if((mii_reg & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
+ ctrl_reg |= E1000_CTRL_SPD_1000;
+ else if((mii_reg & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
+ ctrl_reg |= E1000_CTRL_SPD_100;
+ else
+ ctrl_reg &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
+
+ /* Write the configured values back to the Transmit Control Reg. */
+ E1000_WRITE_REG(shared, TCTL, tctl_reg);
+
+ /* Write the configured values back to the Device Control Reg. */
+ E1000_WRITE_REG(shared, CTRL, ctrl_reg);
+
+ return;
+}
+
+/******************************************************************************
+* Sets the collision distance in the Transmit Control register
+*
+* shared - Struct containing variables accessed by shared code
+*
+* Link should have been established previously. Reads the speed and duplex
+* information from the Device Status register.
+******************************************************************************/
+void
+e1000_config_collision_dist(struct e1000_shared_adapter *shared)
+{
+ uint32_t tctl_reg;
+ uint16_t speed;
+ uint16_t duplex;
+ uint32_t shift;
+
+ DEBUGFUNC("e1000_config_collision_dist");
+
+ /* Get our current speed and duplex from the Device Status Register. */
+ e1000_get_speed_and_duplex(shared, &speed, &duplex);
+
+ /* We need to configure the Collision Distance for both Full or
+ * Half Duplex.
+ */
+ tctl_reg = E1000_READ_REG(shared, TCTL);
+ DEBUGOUT1("tctl_reg = %x\n", tctl_reg);
+
+ /* mask the Collision Distance bits in the Transmit Control Reg. */
+ tctl_reg &= ~E1000_TCTL_COLD;
+
+ if(duplex == FULL_DUPLEX) {
+ /* We are in Full Duplex mode. Therefore, the collision distance
+ * is the same regardless of speed.
+ */
+ shift = E1000_FDX_COLLISION_DISTANCE;
+ shift <<= E1000_COLD_SHIFT;
+ tctl_reg |= shift;
+ } else {
+ /* We are in Half Duplex mode. Half Duplex collision distance is
+ * different for Gigabit vs. 10/100, so we will set accordingly.
+ */
+ if(speed == SPEED_1000) { /* 1000Mbs HDX */
+ shift = E1000_GB_HDX_COLLISION_DISTANCE;
+ shift <<= E1000_COLD_SHIFT;
+ tctl_reg |= shift;
+ tctl_reg |= E1000_TCTL_PBE; /* Enable Packet Bursting */
+ } else { /* 10/100Mbs HDX */
+ shift = E1000_HDX_COLLISION_DISTANCE;
+ shift <<= E1000_COLD_SHIFT;
+ tctl_reg |= shift;
+ }
+ }
+
+ /* Write the configured values back to the Transmit Control Reg. */
+ E1000_WRITE_REG(shared, TCTL, tctl_reg);
+
+ return;
+}
+
+/******************************************************************************
+* Probes the expected PHY address for known PHY IDs
+*
+* shared - Struct containing variables accessed by shared code
+******************************************************************************/
+boolean_t
+e1000_detect_gig_phy(struct e1000_shared_adapter *shared)
+{
+ uint32_t phy_id_high;
+ uint16_t phy_id_low;
+
+ DEBUGFUNC("e1000_detect_gig_phy");
+
+ /* Read the PHY ID Registers to identify which PHY is onboard. */
+ shared->phy_addr = 1;
+
+ phy_id_high = e1000_read_phy_reg(shared, PHY_ID1);
+
+ usec_delay(2);
+
+ phy_id_low = e1000_read_phy_reg(shared, PHY_ID2);
+
+ shared->phy_id = (phy_id_low | (phy_id_high << 16)) & PHY_REVISION_MASK;
+
+ if(shared->phy_id == M88E1000_12_PHY_ID ||
+ shared->phy_id == M88E1000_14_PHY_ID ||
+ shared->phy_id == M88E1000_I_PHY_ID) {
+
+ DEBUGOUT2("phy_id 0x%x detected at address 0x%x\n",
+ shared->phy_id, shared->phy_addr);
+ return (TRUE);
+ } else {
+ DEBUGOUT("Could not auto-detect Phy!\n");
+ return (FALSE);
+ }
+}
+
+/******************************************************************************
+* Resets the PHY's DSP
+*
+* shared - Struct containing variables accessed by shared code
+******************************************************************************/
+void
+e1000_phy_reset_dsp(struct e1000_shared_adapter *shared)
+{
+ e1000_write_phy_reg(shared, 29, 0x1d);
+ e1000_write_phy_reg(shared, 30, 0xc1);
+ e1000_write_phy_reg(shared, 30, 0x00);
+ return;
+}
+
+/******************************************************************************
+* Blocks until autoneg completes or times out (~4.5 seconds)
+*
+* shared - Struct containing variables accessed by shared code
+******************************************************************************/
+boolean_t
+e1000_wait_autoneg(struct e1000_shared_adapter *shared)
+{
+ uint16_t i;
+ uint16_t mii_status_reg;
+ boolean_t autoneg_complete = FALSE;
+
+ DEBUGFUNC("e1000_wait_autoneg");
+
+ /* We will wait for autoneg to complete. */
+ DEBUGOUT("Waiting for Auto-Neg to complete.\n");
+ mii_status_reg = 0;
+
+ /* We will wait for autoneg to complete or 4.5 seconds to expire. */
+
+ for(i = PHY_AUTO_NEG_TIME; i > 0; i--) {
+ /* Read the MII Status Register and wait for Auto-Neg
+ * Complete bit to be set.
+ */
+ mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+ mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+
+ if(mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
+ autoneg_complete = TRUE;
+ break;
+ }
+
+ msec_delay(100);
+ }
+
+ return (autoneg_complete);
+}
+
+/******************************************************************************
+* Get PHY information from various PHY registers
+*
+* shared - Struct containing variables accessed by shared code
+* phy_status_info - PHY information structure
+******************************************************************************/
+boolean_t
+e1000_phy_get_info(struct e1000_shared_adapter *shared,
+ struct e1000_phy_info *phy_status_info)
+{
+ uint16_t phy_mii_status_reg;
+ uint16_t phy_specific_ctrl_reg;
+ uint16_t phy_specific_status_reg;
+ uint16_t phy_specific_ext_ctrl_reg;
+ uint16_t phy_1000t_stat_reg;
+
+ phy_status_info->cable_length = e1000_cable_length_undefined;
+ phy_status_info->extended_10bt_distance =
+ e1000_10bt_ext_dist_enable_undefined;
+ phy_status_info->cable_polarity = e1000_rev_polarity_undefined;
+ phy_status_info->polarity_correction = e1000_polarity_reversal_undefined;
+ phy_status_info->link_reset = e1000_down_no_idle_undefined;
+ phy_status_info->mdix_mode = e1000_auto_x_mode_undefined;
+ phy_status_info->local_rx = e1000_1000t_rx_status_undefined;
+ phy_status_info->remote_rx = e1000_1000t_rx_status_undefined;
+
+ /* PHY info only valid for copper media. */
+ if(shared == NULL || shared->media_type != e1000_media_type_copper)
+ return FALSE;
+
+ /* PHY info only valid for LINK UP. Read MII status reg
+ * back-to-back to get link status.
+ */
+ phy_mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+ phy_mii_status_reg = e1000_read_phy_reg(shared, PHY_STATUS);
+ if((phy_mii_status_reg & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS)
+ return FALSE;
+
+ /* Read various PHY registers to get the PHY info. */
+ phy_specific_ctrl_reg = e1000_read_phy_reg(shared, M88E1000_PHY_SPEC_CTRL);
+ phy_specific_status_reg =
+ e1000_read_phy_reg(shared, M88E1000_PHY_SPEC_STATUS);
+ phy_specific_ext_ctrl_reg =
+ e1000_read_phy_reg(shared, M88E1000_EXT_PHY_SPEC_CTRL);
+ phy_1000t_stat_reg = e1000_read_phy_reg(shared, PHY_1000T_STATUS);
+
+ phy_status_info->cable_length =
+ ((phy_specific_status_reg & M88E1000_PSSR_CABLE_LENGTH) >>
+ M88E1000_PSSR_CABLE_LENGTH_SHIFT);
+
+ phy_status_info->extended_10bt_distance =
+ (phy_specific_ctrl_reg & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
+ M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT;
+
+ phy_status_info->cable_polarity =
+ (phy_specific_status_reg & M88E1000_PSSR_REV_POLARITY) >>
+ M88E1000_PSSR_REV_POLARITY_SHIFT;
+
+ phy_status_info->polarity_correction =
+ (phy_specific_ctrl_reg & M88E1000_PSCR_POLARITY_REVERSAL) >>
+ M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
+
+ phy_status_info->link_reset =
+ (phy_specific_ext_ctrl_reg & M88E1000_EPSCR_DOWN_NO_IDLE) >>
+ M88E1000_EPSCR_DOWN_NO_IDLE_SHIFT;
+
+ phy_status_info->mdix_mode =
+ (phy_specific_status_reg & M88E1000_PSSR_MDIX) >>
+ M88E1000_PSSR_MDIX_SHIFT;
+
+ phy_status_info->local_rx =
+ (phy_1000t_stat_reg & SR_1000T_LOCAL_RX_STATUS) >>
+ SR_1000T_LOCAL_RX_STATUS_SHIFT;
+
+ phy_status_info->remote_rx =
+ (phy_1000t_stat_reg & SR_1000T_REMOTE_RX_STATUS) >>
+ SR_1000T_REMOTE_RX_STATUS_SHIFT;
+
+ return TRUE;
+}
+
+boolean_t
+e1000_validate_mdi_setting(struct e1000_shared_adapter *shared)
+{
+ if(!shared->autoneg && (shared->mdix == 0 || shared->mdix == 3)) {
+ shared->mdix = 1;
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/drivers/net/e1000/e1000_phy.h b/drivers/net/e1000/e1000_phy.h
new file mode 100644
index 000000000000..2232583cec04
--- /dev/null
+++ b/drivers/net/e1000/e1000_phy.h
@@ -0,0 +1,422 @@
+/*******************************************************************************
+
+ This software program is available to you under a choice of one of two
+ licenses. You may choose to be licensed under either the GNU General Public
+ License (GPL) Version 2, June 1991, available at
+ http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
+ text of which follows:
+
+ Recipient has requested a license and Intel Corporation ("Intel") is willing
+ to grant a license for the software entitled Linux Base Driver for the
+ Intel(R) PRO/1000 Family of Adapters (e1000) (the "Software") being provided
+ by Intel Corporation. The following definitions apply to this license:
+
+ "Licensed Patents" means patent claims licensable by Intel Corporation which
+ are necessarily infringed by the use of sale of the Software alone or when
+ combined with the operating system referred to below.
+
+ "Recipient" means the party to whom Intel delivers this Software.
+
+ "Licensee" means Recipient and those third parties that receive a license to
+ any operating system available under the GNU Public License version 2.0 or
+ later.
+
+ Copyright (c) 1999 - 2002 Intel Corporation.
+ All rights reserved.
+
+ The license is provided to Recipient and Recipient's Licensees under the
+ following terms.
+
+ Redistribution and use in source and binary forms of the Software, with or
+ without modification, are permitted provided that the following conditions
+ are met:
+
+ Redistributions of source code of the Software may retain the above
+ copyright notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form of the Software may reproduce the above
+ copyright notice, this list of conditions and the following disclaimer in
+ the documentation and/or materials provided with the distribution.
+
+ Neither the name of Intel Corporation nor the names of its contributors
+ shall be used to endorse or promote products derived from this Software
+ without specific prior written permission.
+
+ Intel hereby grants Recipient and Licensees a non-exclusive, worldwide,
+ royalty-free patent license under Licensed Patents to make, use, sell, offer
+ to sell, import and otherwise transfer the Software, if any, in source code
+ and object code form. This license shall include changes to the Software
+ that are error corrections or other minor changes to the Software that do
+ not add functionality or features when the Software is incorporated in any
+ version of an operating system that has been distributed under the GNU
+ General Public License 2.0 or later. This patent license shall apply to the
+ combination of the Software and any operating system licensed under the GNU
+ Public License version 2.0 or later if, at the time Intel provides the
+ Software to Recipient, such addition of the Software to the then publicly
+ available versions of such operating systems available under the GNU Public
+ License version 2.0 or later (whether in gold, beta or alpha form) causes
+ such combination to be covered by the Licensed Patents. The patent license
+ shall not apply to any other combinations which include the Software. NO
+ hardware per se is licensed hereunder.
+
+ 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 MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR IT CONTRIBUTORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ ANY LOSS OF USE; DATA, OR PROFITS; OR BUSINESS INTERUPTION) 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.
+
+*******************************************************************************/
+
+/* e1000_phy.h
+ * Structures, enums, and macros for the PHY
+ */
+
+#ifndef _E1000_PHY_H_
+#define _E1000_PHY_H_
+
+#include "e1000_osdep.h"
+
+/* PHY status info structure and supporting enums */
+typedef enum {
+ e1000_cable_length_50 = 0,
+ e1000_cable_length_50_80,
+ e1000_cable_length_80_110,
+ e1000_cable_length_110_140,
+ e1000_cable_length_140,
+ e1000_cable_length_undefined = 0xFF
+} e1000_cable_length;
+
+typedef enum {
+ e1000_10bt_ext_dist_enable_normal = 0,
+ e1000_10bt_ext_dist_enable_lower,
+ e1000_10bt_ext_dist_enable_undefined = 0xFF
+} e1000_10bt_ext_dist_enable;
+
+typedef enum {
+ e1000_rev_polarity_normal = 0,
+ e1000_rev_polarity_reversed,
+ e1000_rev_polarity_undefined = 0xFF
+} e1000_rev_polarity;
+
+typedef enum {
+ e1000_polarity_reversal_enabled = 0,
+ e1000_polarity_reversal_disabled,
+ e1000_polarity_reversal_undefined = 0xFF
+} e1000_polarity_reversal;
+
+typedef enum {
+ e1000_down_no_idle_no_detect = 0,
+ e1000_down_no_idle_detect,
+ e1000_down_no_idle_undefined = 0xFF
+} e1000_down_no_idle;
+
+typedef enum {
+ e1000_auto_x_mode_manual_mdi = 0,
+ e1000_auto_x_mode_manual_mdix,
+ e1000_auto_x_mode_auto1,
+ e1000_auto_x_mode_auto2,
+ e1000_auto_x_mode_undefined = 0xFF
+} e1000_auto_x_mode;
+
+typedef enum {
+ e1000_1000t_rx_status_not_ok = 0,
+ e1000_1000t_rx_status_ok,
+ e1000_1000t_rx_status_undefined = 0xFF
+} e1000_1000t_rx_status;
+
+struct e1000_phy_info {
+ e1000_cable_length cable_length;
+ e1000_10bt_ext_dist_enable extended_10bt_distance;
+ e1000_rev_polarity cable_polarity;
+ e1000_polarity_reversal polarity_correction;
+ e1000_down_no_idle link_reset;
+ e1000_auto_x_mode mdix_mode;
+ e1000_1000t_rx_status local_rx;
+ e1000_1000t_rx_status remote_rx;
+};
+
+struct e1000_phy_stats {
+ uint32_t idle_errors;
+ uint32_t receive_errors;
+};
+
+/* Function Prototypes */
+uint16_t e1000_read_phy_reg(struct e1000_shared_adapter *shared, uint32_t reg_addr);
+void e1000_write_phy_reg(struct e1000_shared_adapter *shared, uint32_t reg_addr, uint16_t data);
+void e1000_phy_hw_reset(struct e1000_shared_adapter *shared);
+boolean_t e1000_phy_reset(struct e1000_shared_adapter *shared);
+boolean_t e1000_phy_setup(struct e1000_shared_adapter *shared, uint32_t ctrl_reg);
+boolean_t e1000_phy_setup_autoneg(struct e1000_shared_adapter *shared);
+void e1000_config_mac_to_phy(struct e1000_shared_adapter *shared, uint16_t mii_reg);
+void e1000_config_collision_dist(struct e1000_shared_adapter *shared);
+boolean_t e1000_detect_gig_phy(struct e1000_shared_adapter *shared);
+void e1000_phy_reset_dsp(struct e1000_shared_adapter *shared);
+boolean_t e1000_wait_autoneg(struct e1000_shared_adapter *shared);
+boolean_t e1000_phy_get_info(struct e1000_shared_adapter *shared, struct e1000_phy_info *phy_status_info);
+boolean_t e1000_validate_mdi_setting(struct e1000_shared_adapter *shared);
+
+/* Bit definitions for the Management Data IO (MDIO) and Management Data
+ * Clock (MDC) pins in the Device Control Register.
+ */
+#define E1000_CTRL_PHY_RESET_DIR E1000_CTRL_SWDPIO0
+#define E1000_CTRL_PHY_RESET E1000_CTRL_SWDPIN0
+#define E1000_CTRL_MDIO_DIR E1000_CTRL_SWDPIO2
+#define E1000_CTRL_MDIO E1000_CTRL_SWDPIN2
+#define E1000_CTRL_MDC_DIR E1000_CTRL_SWDPIO3
+#define E1000_CTRL_MDC E1000_CTRL_SWDPIN3
+#define E1000_CTRL_PHY_RESET_DIR4 E1000_CTRL_EXT_SDP4_DIR
+#define E1000_CTRL_PHY_RESET4 E1000_CTRL_EXT_SDP4_DATA
+
+/* PHY 1000 MII Register/Bit Definitions */
+/* PHY Registers defined by IEEE */
+#define PHY_CTRL 0x00 /* Control Register */
+#define PHY_STATUS 0x01 /* Status Regiser */
+#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */
+#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */
+#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
+#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */
+#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */
+#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */
+#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */
+#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */
+#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
+#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */
+
+/* M88E1000 Specific Registers */
+#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
+#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */
+#define M88E1000_INT_ENABLE 0x12 /* Interrupt Enable Register */
+#define M88E1000_INT_STATUS 0x13 /* Interrupt Status Register */
+#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */
+#define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */
+
+#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
+
+/* PHY Control Register */
+#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
+#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
+#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
+#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */
+#define MII_CR_POWER_DOWN 0x0800 /* Power down */
+#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
+#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
+#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
+
+/* PHY Status Register */
+#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
+#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
+#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
+#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
+#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
+#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
+#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
+#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
+#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
+#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
+#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
+#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
+#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
+#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
+#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
+
+/* Autoneg Advertisement Register */
+#define NWAY_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */
+#define NWAY_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */
+#define NWAY_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */
+#define NWAY_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */
+#define NWAY_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */
+#define NWAY_AR_100T4_CAPS 0x0200 /* 100T4 Capable */
+#define NWAY_AR_PAUSE 0x0400 /* Pause operation desired */
+#define NWAY_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */
+#define NWAY_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */
+#define NWAY_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */
+
+/* Link Partner Ability Register (Base Page) */
+#define NWAY_LPAR_SELECTOR_FIELD 0x0000 /* LP protocol selector field */
+#define NWAY_LPAR_10T_HD_CAPS 0x0020 /* LP is 10T Half Duplex Capable */
+#define NWAY_LPAR_10T_FD_CAPS 0x0040 /* LP is 10T Full Duplex Capable */
+#define NWAY_LPAR_100TX_HD_CAPS 0x0080 /* LP is 100TX Half Duplex Capable */
+#define NWAY_LPAR_100TX_FD_CAPS 0x0100 /* LP is 100TX Full Duplex Capable */
+#define NWAY_LPAR_100T4_CAPS 0x0200 /* LP is 100T4 Capable */
+#define NWAY_LPAR_PAUSE 0x0400 /* LP Pause operation desired */
+#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asymmetric Pause Direction bit */
+#define NWAY_LPAR_REMOTE_FAULT 0x2000 /* LP has detected Remote Fault */
+#define NWAY_LPAR_ACKNOWLEDGE 0x4000 /* LP has rx'd link code word */
+#define NWAY_LPAR_NEXT_PAGE 0x8000 /* Next Page ability supported */
+
+/* Autoneg Expansion Register */
+#define NWAY_ER_LP_NWAY_CAPS 0x0001 /* LP has Auto Neg Capability */
+#define NWAY_ER_PAGE_RXD 0x0002 /* LP is 10T Half Duplex Capable */
+#define NWAY_ER_NEXT_PAGE_CAPS 0x0004 /* LP is 10T Full Duplex Capable */
+#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 /* LP is 100TX Half Duplex Capable */
+#define NWAY_ER_PAR_DETECT_FAULT 0x0100 /* LP is 100TX Full Duplex Capable */
+
+/* Next Page TX Register */
+#define NPTX_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */
+#define NPTX_TOGGLE 0x0800 /* Toggles between exchanges
+ * of different NP
+ */
+#define NPTX_ACKNOWLDGE2 0x1000 /* 1 = will comply with msg
+ * 0 = cannot comply with msg
+ */
+#define NPTX_MSG_PAGE 0x2000 /* formatted(1)/unformatted(0) pg */
+#define NPTX_NEXT_PAGE 0x8000 /* 1 = addition NP will follow
+ * 0 = sending last NP
+ */
+
+/* Link Partner Next Page Register */
+#define LP_RNPR_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */
+#define LP_RNPR_TOGGLE 0x0800 /* Toggles between exchanges
+ * of different NP
+ */
+#define LP_RNPR_ACKNOWLDGE2 0x1000 /* 1 = will comply with msg
+ * 0 = cannot comply with msg
+ */
+#define LP_RNPR_MSG_PAGE 0x2000 /* formatted(1)/unformatted(0) pg */
+#define LP_RNPR_ACKNOWLDGE 0x4000 /* 1 = ACK / 0 = NO ACK */
+#define LP_RNPR_NEXT_PAGE 0x8000 /* 1 = addition NP will follow
+ * 0 = sending last NP
+ */
+
+/* 1000BASE-T Control Register */
+#define CR_1000T_ASYM_PAUSE 0x0080 /* Advertise asymmetric pause bit */
+#define CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */
+#define CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */
+#define CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port */
+ /* 0=DTE device */
+#define CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */
+ /* 0=Configure PHY as Slave */
+#define CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */
+ /* 0=Automatic Master/Slave config */
+#define CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
+#define CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */
+#define CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */
+#define CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */
+#define CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */
+
+/* 1000BASE-T Status Register */
+#define SR_1000T_IDLE_ERROR_CNT 0x00FF /* Num idle errors since last read */
+#define SR_1000T_ASYM_PAUSE_DIR 0x0100 /* LP asymmetric pause direction bit */
+#define SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */
+#define SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */
+#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
+#define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */
+#define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */
+#define SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */
+#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12
+#define SR_1000T_LOCAL_RX_STATUS_SHIFT 13
+
+/* Extended Status Register */
+#define IEEE_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */
+#define IEEE_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */
+#define IEEE_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */
+#define IEEE_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */
+
+#define PHY_TX_POLARITY_MASK 0x0100 /* register 10h bit 8 (polarity bit) */
+#define PHY_TX_NORMAL_POLARITY 0 /* register 10h bit 8 (normal polarity) */
+
+#define AUTO_POLARITY_DISABLE 0x0010 /* register 11h bit 4 */
+ /* (0=enable, 1=disable) */
+
+/* M88E1000 PHY Specific Control Register */
+#define M88E1000_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */
+#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
+#define M88E1000_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */
+#define M88E1000_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low,
+ * 0=CLK125 toggling
+ */
+#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */
+ /* Manual MDI configuration */
+#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */
+#define M88E1000_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover,
+ * 100BASE-TX/10BASE-T:
+ * MDI Mode
+ */
+#define M88E1000_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled
+ * all speeds.
+ */
+#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE 0x0080
+ /* 1=Enable Extended 10BASE-T distance
+ * (Lower 10BASE-T RX Threshold)
+ * 0=Normal 10BASE-T RX Threshold */
+#define M88E1000_PSCR_MII_5BIT_ENABLE 0x0100
+ /* 1=5-Bit interface in 100BASE-TX
+ * 0=MII interface in 100BASE-TX */
+#define M88E1000_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */
+#define M88E1000_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */
+#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */
+
+#define M88E1000_PSCR_POLARITY_REVERSAL_SHIFT 1
+#define M88E1000_PSCR_AUTO_X_MODE_SHIFT 5
+#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
+
+/* M88E1000 PHY Specific Status Register */
+#define M88E1000_PSSR_JABBER 0x0001 /* 1=Jabber */
+#define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */
+#define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */
+#define M88E1000_PSSR_CABLE_LENGTH 0x0380 /* 0=<50M;1=50-80M;2=80-110M;
+ * 3=110-140M;4=>140M */
+#define M88E1000_PSSR_LINK 0x0400 /* 1=Link up, 0=Link down */
+#define M88E1000_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */
+#define M88E1000_PSSR_PAGE_RCVD 0x1000 /* 1=Page received */
+#define M88E1000_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */
+#define M88E1000_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
+#define M88E1000_PSSR_10MBS 0x0000 /* 00=10Mbs */
+#define M88E1000_PSSR_100MBS 0x4000 /* 01=100Mbs */
+#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
+
+#define M88E1000_PSSR_REV_POLARITY_SHIFT 1
+#define M88E1000_PSSR_MDIX_SHIFT 6
+#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
+
+/* M88E1000 Extended PHY Specific Control Register */
+#define M88E1000_EPSCR_FIBER_LOOPBACK 0x4000 /* 1=Fiber loopback */
+#define M88E1000_EPSCR_DOWN_NO_IDLE 0x8000 /* 1=Lost lock detect enabled.
+ * Will assert lost lock and bring
+ * link down if idle not seen
+ * within 1ms in 1000BASE-T
+ */
+#define M88E1000_EPSCR_TX_CLK_2_5 0x0060 /* 2.5 MHz TX_CLK */
+#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
+#define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */
+
+#define M88E1000_EPSCR_DOWN_NO_IDLE_SHIFT 15
+
+/* Bit definitions for valid PHY IDs. */
+#define M88E1000_12_PHY_ID 0x01410C50
+#define M88E1000_14_PHY_ID 0x01410C40
+#define M88E1000_I_PHY_ID 0x01410C30
+
+/* Miscellaneous PHY bit definitions. */
+#define PHY_PREAMBLE 0xFFFFFFFF
+#define PHY_SOF 0x01
+#define PHY_OP_READ 0x02
+#define PHY_OP_WRITE 0x01
+#define PHY_TURNAROUND 0x02
+#define PHY_PREAMBLE_SIZE 32
+#define MII_CR_SPEED_1000 0x0040
+#define MII_CR_SPEED_100 0x2000
+#define MII_CR_SPEED_10 0x0000
+#define E1000_PHY_ADDRESS 0x01
+#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */
+#define PHY_FORCE_TIME 20 /* 2.0 Seconds */
+#define PHY_REVISION_MASK 0xFFFFFFF0
+#define DEVICE_SPEED_MASK 0x00000300 /* Device Ctrl Reg Speed Mask */
+#define REG4_SPEED_MASK 0x01E0
+#define REG9_SPEED_MASK 0x0300
+#define ADVERTISE_10_HALF 0x0001
+#define ADVERTISE_10_FULL 0x0002
+#define ADVERTISE_100_HALF 0x0004
+#define ADVERTISE_100_FULL 0x0008
+#define ADVERTISE_1000_HALF 0x0010
+#define ADVERTISE_1000_FULL 0x0020
+#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F /* Everything but 1000-Half */
+
+#endif /* _E1000_PHY_H_ */
diff --git a/drivers/net/e1000/e1000_proc.c b/drivers/net/e1000/e1000_proc.c
new file mode 100644
index 000000000000..f497f0de1b6a
--- /dev/null
+++ b/drivers/net/e1000/e1000_proc.c
@@ -0,0 +1,760 @@
+/*******************************************************************************
+
+ This software program is available to you under a choice of one of two
+ licenses. You may choose to be licensed under either the GNU General Public
+ License (GPL) Version 2, June 1991, available at
+ http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
+ text of which follows:
+
+ Recipient has requested a license and Intel Corporation ("Intel") is willing
+ to grant a license for the software entitled Linux Base Driver for the
+ Intel(R) PRO/1000 Family of Adapters (e1000) (the "Software") being provided
+ by Intel Corporation. The following definitions apply to this license:
+
+ "Licensed Patents" means patent claims licensable by Intel Corporation which
+ are necessarily infringed by the use of sale of the Software alone or when
+ combined with the operating system referred to below.
+
+ "Recipient" means the party to whom Intel delivers this Software.
+
+ "Licensee" means Recipient and those third parties that receive a license to
+ any operating system available under the GNU Public License version 2.0 or
+ later.
+
+ Copyright (c) 1999 - 2002 Intel Corporation.
+ All rights reserved.
+
+ The license is provided to Recipient and Recipient's Licensees under the
+ following terms.
+
+ Redistribution and use in source and binary forms of the Software, with or
+ without modification, are permitted provided that the following conditions
+ are met:
+
+ Redistributions of source code of the Software may retain the above
+ copyright notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form of the Software may reproduce the above
+ copyright notice, this list of conditions and the following disclaimer in
+ the documentation and/or materials provided with the distribution.
+
+ Neither the name of Intel Corporation nor the names of its contributors
+ shall be used to endorse or promote products derived from this Software
+ without specific prior written permission.
+
+ Intel hereby grants Recipient and Licensees a non-exclusive, worldwide,
+ royalty-free patent license under Licensed Patents to make, use, sell, offer
+ to sell, import and otherwise transfer the Software, if any, in source code
+ and object code form. This license shall include changes to the Software
+ that are error corrections or other minor changes to the Software that do
+ not add functionality or features when the Software is incorporated in any
+ version of an operating system that has been distributed under the GNU
+ General Public License 2.0 or later. This patent license shall apply to the
+ combination of the Software and any operating system licensed under the GNU
+ Public License version 2.0 or later if, at the time Intel provides the
+ Software to Recipient, such addition of the Software to the then publicly
+ available versions of such operating systems available under the GNU Public
+ License version 2.0 or later (whether in gold, beta or alpha form) causes
+ such combination to be covered by the Licensed Patents. The patent license
+ shall not apply to any other combinations which include the Software. NO
+ hardware per se is licensed hereunder.
+
+ 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 MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR IT CONTRIBUTORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ ANY LOSS OF USE; DATA, OR PROFITS; OR BUSINESS INTERUPTION) 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.
+
+*******************************************************************************/
+
+/*
+ * Proc fs support.
+ *
+ * Read-only files created by driver (if CONFIG_PROC_FS):
+ *
+ * /proc/net/PRO_LAN_Adapters/<ethx>.info
+ * /proc/net/PRO_LAN_Adapters/<ethx>/<attribute>
+ *
+ * where <ethx> is the system device name, i.e eth0.
+ * <attribute> is the driver attribute name.
+ *
+ * There is one file for each driver attribute, where the contents
+ * of the file is the attribute value. The ethx.info file contains
+ * a list of all driver attributes in one file.
+ *
+ */
+
+#include "e1000.h"
+
+#ifdef CONFIG_PROC_FS
+
+#include <linux/proc_fs.h>
+
+#define ADAPTERS_PROC_DIR "PRO_LAN_Adapters"
+#define TAG_MAX_LENGTH 36
+
+extern char e1000_driver_name[];
+extern char e1000_driver_version[];
+
+/*
+ * The list of driver proc attributes is stored in a proc_list link
+ * list. The list is build with proc_list_setup and is used to
+ * build the proc fs nodes. The private data for each node is the
+ * corresponding link in the link list.
+ */
+
+struct proc_list {
+ struct list_head list; /* link list */
+ char tag[TAG_MAX_LENGTH]; /* attribute name */
+ void *data; /* attribute data */
+ size_t len; /* sizeof data */
+ char *(*func)(void *, size_t, char *); /* format data func */
+};
+
+static int
+e1000_proc_read(char *page, char **start, off_t off, int count, int *eof)
+{
+ int len = strlen(page);
+
+ page[len++] = '\n';
+
+ if(len <= off + count)
+ *eof = 1;
+ *start = page + off;
+ len -= off;
+ if(len > count)
+ len = count;
+ if(len < 0)
+ len = 0;
+
+ return len;
+}
+
+static int
+e1000_proc_info_read(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ struct list_head *proc_list_head = data, *curr;
+ struct proc_list *elem;
+ char *p = page;
+ char buf[64];
+
+ list_for_each(curr, proc_list_head) {
+ elem = list_entry(curr, struct proc_list, list);
+
+ if(strlen(elem->tag) == 0)
+ p += sprintf(p, "\n");
+ else
+ p += sprintf(p, "%-32s %s\n", elem->tag,
+ elem->func(elem->data, elem->len, buf));
+ }
+
+ *p = '\0';
+
+ return e1000_proc_read(page, start, off, count, eof);
+}
+
+static int
+e1000_proc_single_read(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ struct proc_list *elem = data;
+
+ sprintf(page, "%s", elem->func(elem->data, elem->len, page));
+
+ return e1000_proc_read(page, start, off, count, eof);
+}
+
+static void __devexit
+e1000_proc_dirs_free(char *name, struct list_head *proc_list_head)
+{
+ struct proc_dir_entry *intel_proc_dir, *proc_dir;
+ char info_name[strlen(name) + strlen(".info")];
+
+ for(intel_proc_dir = proc_net->subdir; intel_proc_dir;
+ intel_proc_dir = intel_proc_dir->next) {
+ if((intel_proc_dir->namelen == strlen(ADAPTERS_PROC_DIR)) &&
+ (memcmp(intel_proc_dir->name,
+ ADAPTERS_PROC_DIR, strlen(ADAPTERS_PROC_DIR)) == 0))
+ break;
+ }
+
+ if(!intel_proc_dir)
+ return;
+
+ for(proc_dir = intel_proc_dir->subdir; proc_dir;
+ proc_dir = proc_dir->next) {
+ if ((proc_dir->namelen == strlen(name)) &&
+ !memcmp(proc_dir->name, name, strlen(name)))
+ break;
+ }
+
+ if(proc_dir) {
+ struct list_head *curr;
+ struct proc_list *elem;
+
+ list_for_each(curr, proc_list_head) {
+ elem = list_entry(curr, struct proc_list, list);
+ remove_proc_entry(elem->tag, proc_dir);
+ }
+
+ strcpy(info_name, name);
+ strcat(info_name, ".info");
+
+ remove_proc_entry(info_name, intel_proc_dir);
+ remove_proc_entry(name, intel_proc_dir);
+ }
+
+ /* If the intel dir is empty, remove it */
+
+ for(proc_dir = intel_proc_dir->subdir; proc_dir;
+ proc_dir = proc_dir->next) {
+
+ /* ignore . and .. */
+
+ if(*(proc_dir->name) == '.')
+ continue;
+ break;
+ }
+
+ if(!proc_dir)
+ remove_proc_entry(ADAPTERS_PROC_DIR, proc_net);
+
+ return;
+}
+
+
+static int __devinit
+e1000_proc_singles_create(struct proc_dir_entry *parent,
+ struct list_head *proc_list_head)
+{
+ struct list_head *curr;
+ struct proc_list *elem;
+
+ list_for_each(curr, proc_list_head) {
+ struct proc_dir_entry *proc_entry;
+
+ elem = list_entry(curr, struct proc_list, list);
+
+ if(strlen(elem->tag) == 0)
+ continue;
+
+ if(!(proc_entry =
+ create_proc_entry(elem->tag, S_IFREG, parent)))
+ return 0;
+
+ proc_entry->read_proc = e1000_proc_single_read;
+ proc_entry->data = elem;
+ SET_MODULE_OWNER(proc_entry);
+ }
+
+ return 1;
+}
+
+static int __devinit
+e1000_proc_dirs_create(char *name, struct list_head *proc_list_head)
+{
+ struct proc_dir_entry *intel_proc_dir, *proc_dir, *info_entry;
+ char info_name[strlen(name) + strlen(".info")];
+
+ for(intel_proc_dir = proc_net->subdir; intel_proc_dir;
+ intel_proc_dir = intel_proc_dir->next) {
+ if((intel_proc_dir->namelen == strlen(ADAPTERS_PROC_DIR)) &&
+ (memcmp(intel_proc_dir->name,
+ ADAPTERS_PROC_DIR, strlen(ADAPTERS_PROC_DIR)) == 0))
+ break;
+ }
+
+ if(!intel_proc_dir)
+ if(!(intel_proc_dir =
+ create_proc_entry(ADAPTERS_PROC_DIR,
+ S_IFDIR, proc_net)))
+ return 0;
+
+ if(!(proc_dir =
+ create_proc_entry(name, S_IFDIR, intel_proc_dir)))
+ return 0;
+ SET_MODULE_OWNER(proc_dir);
+
+ if(!e1000_proc_singles_create(proc_dir, proc_list_head))
+ return 0;
+
+ strcpy(info_name, name);
+ strcat(info_name, ".info");
+
+ if(!(info_entry =
+ create_proc_entry(info_name, S_IFREG, intel_proc_dir)))
+ return 0;
+ SET_MODULE_OWNER(info_entry);
+
+ info_entry->read_proc = e1000_proc_info_read;
+ info_entry->data = proc_list_head;
+
+ return 1;
+}
+
+static void __devinit
+e1000_proc_list_add(struct list_head *proc_list_head, char *tag,
+ void *data, size_t len,
+ char *(*func)(void *, size_t, char *))
+{
+ struct proc_list *new = (struct proc_list *)
+ kmalloc(sizeof(struct proc_list), GFP_KERNEL);
+
+ if(!new)
+ return;
+
+ strncpy(new->tag, tag, TAG_MAX_LENGTH);
+ new->data = data;
+ new->len = len;
+ new->func = func;
+
+ list_add_tail(&new->list, proc_list_head);
+
+ return;
+}
+
+static void __devexit
+e1000_proc_list_free(struct list_head *proc_list_head)
+{
+ struct proc_list *elem;
+
+ while(!list_empty(proc_list_head)) {
+ elem = list_entry(proc_list_head->next, struct proc_list, list);
+ list_del(&elem->list);
+ kfree(elem);
+ }
+
+ return;
+}
+
+/*
+ * General purpose formating functions
+ */
+
+static char *
+e1000_proc_str(void *data, size_t len, char *buf)
+{
+ sprintf(buf, "%s", (char *)data);
+ return buf;
+}
+
+static char *
+e1000_proc_hex(void *data, size_t len, char *buf)
+{
+ switch(len) {
+ case sizeof(uint8_t):
+ sprintf(buf, "0x%02x", *(uint8_t *)data);
+ break;
+ case sizeof(uint16_t):
+ sprintf(buf, "0x%04x", *(uint16_t *)data);
+ break;
+ case sizeof(uint32_t):
+ sprintf(buf, "0x%08x", *(uint32_t *)data);
+ break;
+ case sizeof(uint64_t):
+ sprintf(buf, "0x%08Lx", (unsigned long long)*(uint64_t *)data);
+ break;
+ }
+ return buf;
+}
+
+static char *
+e1000_proc_unsigned(void *data, size_t len, char *buf)
+{
+ switch(len) {
+ case sizeof(uint8_t):
+ sprintf(buf, "%u", *(uint8_t *)data);
+ break;
+ case sizeof(uint16_t):
+ sprintf(buf, "%u", *(uint16_t *)data);
+ break;
+ case sizeof(uint32_t):
+ sprintf(buf, "%u", *(uint32_t *)data);
+ break;
+ case sizeof(uint64_t):
+ sprintf(buf, "%Lu", (unsigned long long)*(uint64_t *)data);
+ break;
+ }
+ return buf;
+}
+
+/*
+ * Specific formating functions
+ */
+
+static char *
+e1000_proc_part_number(void *data, size_t len, char *buf)
+{
+ sprintf(buf, "%06x-%03x", *(uint32_t *)data >> 8,
+ *(uint32_t *)data & 0x000000FF);
+ return buf;
+}
+
+static char *
+e1000_proc_slot(void *data, size_t len, char *buf)
+{
+ struct e1000_adapter *adapter = data;
+ sprintf(buf, "%u", PCI_SLOT(adapter->pdev->devfn));
+ return buf;
+}
+
+static char *
+e1000_proc_bus_type(void *data, size_t len, char *buf)
+{
+ e1000_bus_type bus_type = *(e1000_bus_type *)data;
+ sprintf(buf,
+ bus_type == e1000_bus_type_pci ? "PCI" :
+ bus_type == e1000_bus_type_pcix ? "PCI-X" :
+ "UNKNOWN");
+ return buf;
+}
+
+static char *
+e1000_proc_bus_speed(void *data, size_t len, char *buf)
+{
+ e1000_bus_speed bus_speed = *(e1000_bus_speed *)data;
+ sprintf(buf,
+ bus_speed == e1000_bus_speed_33 ? "33MHz" :
+ bus_speed == e1000_bus_speed_66 ? "66MHz" :
+ bus_speed == e1000_bus_speed_100 ? "100MHz" :
+ bus_speed == e1000_bus_speed_133 ? "133MHz" :
+ "UNKNOWN");
+ return buf;
+}
+
+static char *
+e1000_proc_bus_width(void *data, size_t len, char *buf)
+{
+ e1000_bus_width bus_width = *(e1000_bus_width *)data;
+ sprintf(buf,
+ bus_width == e1000_bus_width_32 ? "32-bit" :
+ bus_width == e1000_bus_width_64 ? "64-bit" :
+ "UNKNOWN");
+ return buf;
+}
+
+static char *
+e1000_proc_hwaddr(void *data, size_t len, char *buf)
+{
+ unsigned char *hwaddr = data;
+ sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
+ hwaddr[0], hwaddr[1], hwaddr[2],
+ hwaddr[3], hwaddr[4], hwaddr[5]);
+ return buf;
+}
+
+static char *
+e1000_proc_link(void *data, size_t len, char *buf)
+{
+ struct e1000_adapter *adapter = data;
+ sprintf(buf, netif_running(adapter->netdev) ?
+ netif_carrier_ok(adapter->netdev) ?
+ "up" : "down" : "N/A");
+ return buf;
+}
+
+static char *
+e1000_proc_link_speed(void *data, size_t len, char *buf)
+{
+ uint16_t link_speed = *(uint16_t *)data;
+ sprintf(buf, link_speed ? "%u" : "N/A", link_speed);
+ return buf;
+}
+
+static char *
+e1000_proc_link_duplex(void *data, size_t len, char *buf)
+{
+ uint16_t link_duplex = *(uint16_t *)data;
+ sprintf(buf,
+ link_duplex == FULL_DUPLEX ? "Full" :
+ link_duplex == HALF_DUPLEX ? "Half" :
+ "N/A");
+ return buf;
+}
+
+static char *
+e1000_proc_state(void *data, size_t len, char *buf)
+{
+ struct e1000_adapter *adapter = data;
+ sprintf(buf, adapter->netdev->flags & IFF_UP ? "up" : "down");
+ return buf;
+}
+
+static char *
+e1000_proc_media_type(void *data, size_t len, char *buf)
+{
+ struct e1000_adapter *adapter = data;
+ sprintf(buf,
+ adapter->shared.media_type == e1000_media_type_copper ?
+ "Copper" : "Fiber");
+ return buf;
+}
+
+static char *
+e1000_proc_cable_length(void *data, size_t len, char *buf)
+{
+ struct e1000_adapter *adapter = data;
+ e1000_cable_length cable_length = adapter->phy_info.cable_length;
+ sprintf(buf, "%s%s",
+ cable_length == e1000_cable_length_50 ? "0-50" :
+ cable_length == e1000_cable_length_50_80 ? "50-80" :
+ cable_length == e1000_cable_length_80_110 ? "80-110" :
+ cable_length == e1000_cable_length_110_140 ? "110-140" :
+ cable_length == e1000_cable_length_140 ? "> 140" :
+ "Unknown",
+ cable_length != e1000_cable_length_undefined ?
+ " Meters (+/- 20 Meters)" : "");
+ return buf;
+}
+
+static char *
+e1000_proc_extended(void *data, size_t len, char *buf)
+{
+ struct e1000_adapter *adapter = data;
+ e1000_10bt_ext_dist_enable dist_enable =
+ adapter->phy_info.extended_10bt_distance;
+ sprintf(buf,
+ dist_enable == e1000_10bt_ext_dist_enable_normal ? "Disabled" :
+ dist_enable == e1000_10bt_ext_dist_enable_lower ? "Enabled" :
+ "Unknown");
+ return buf;
+}
+
+static char *
+e1000_proc_cable_polarity(void *data, size_t len, char *buf)
+{
+ struct e1000_adapter *adapter = data;
+ e1000_rev_polarity polarity = adapter->phy_info.cable_polarity;
+ sprintf(buf,
+ polarity == e1000_rev_polarity_normal ? "Normal" :
+ polarity == e1000_rev_polarity_reversed ? "Reversed" :
+ "Unknown");
+ return buf;
+}
+
+static char *
+e1000_proc_polarity_correction(void *data, size_t len, char *buf)
+{
+ struct e1000_adapter *adapter = data;
+ e1000_polarity_reversal correction =
+ adapter->phy_info.polarity_correction;
+ sprintf(buf,
+ correction == e1000_polarity_reversal_enabled ? "Disabled" :
+ correction == e1000_polarity_reversal_disabled ? "Enabled" :
+ "Undefined");
+ return buf;
+}
+
+static char *
+e1000_proc_link_reset_enabled(void *data, size_t len, char *buf)
+{
+ struct e1000_adapter *adapter = data;
+ e1000_down_no_idle link_reset = adapter->phy_info.link_reset;
+ sprintf(buf,
+ link_reset == e1000_down_no_idle_no_detect ? "Disabled" :
+ link_reset == e1000_down_no_idle_detect ? "Enabled" :
+ "Unknown");
+ return buf;
+}
+
+static char *
+e1000_proc_mdi_x_enabled(void *data, size_t len, char *buf)
+{
+ struct e1000_adapter *adapter = data;
+ e1000_auto_x_mode mdix_mode = adapter->phy_info.mdix_mode;
+ sprintf(buf, mdix_mode == 0 ? "MDI" : "MDI-X");
+ return buf;
+}
+
+static char *
+e1000_proc_rx_status(void *data, size_t len, char *buf)
+{
+ e1000_1000t_rx_status rx_status = *(e1000_1000t_rx_status *)data;
+ sprintf(buf,
+ rx_status == e1000_1000t_rx_status_not_ok ? "NOT_OK" :
+ rx_status == e1000_1000t_rx_status_ok ? "OK" :
+ "Unknown");
+ return buf;
+}
+
+/*
+ * e1000_proc_list_setup - build link list of proc praramters
+ * @adapter: board private structure
+ *
+ * Order matters - ethx.info entries are ordered in the order links
+ * are added to list.
+ */
+
+#define LIST_ADD_F(T,D,F) \
+ e1000_proc_list_add(proc_list_head, (T), (D), sizeof(*(D)), (F))
+#define LIST_ADD_BLANK() LIST_ADD_F("", NULL, NULL)
+#define LIST_ADD_S(T,D) LIST_ADD_F((T), (D), e1000_proc_str)
+#define LIST_ADD_H(T,D) LIST_ADD_F((T), (D), e1000_proc_hex)
+#define LIST_ADD_U(T,D) LIST_ADD_F((T), (D), e1000_proc_unsigned)
+
+static void __devinit
+e1000_proc_list_setup(struct e1000_adapter *adapter)
+{
+ struct e1000_shared_adapter *shared = &adapter->shared;
+ struct list_head *proc_list_head = &adapter->proc_list_head;
+
+ INIT_LIST_HEAD(proc_list_head);
+
+ LIST_ADD_S("Description", adapter->id_string);
+ LIST_ADD_F("Part_Number", &adapter->part_num, e1000_proc_part_number);
+ LIST_ADD_S("Driver_Name", e1000_driver_name);
+ LIST_ADD_S("Driver_Version", e1000_driver_version);
+ LIST_ADD_H("PCI_Vendor", &shared->vendor_id);
+ LIST_ADD_H("PCI_Device_ID", &shared->device_id);
+ LIST_ADD_H("PCI_Subsystem_Vendor", &shared->subsystem_vendor_id);
+ LIST_ADD_H("PCI_Subsystem_ID", &shared->subsystem_id);
+ LIST_ADD_H("PCI_Revision_ID", &shared->revision_id);
+ LIST_ADD_U("PCI_Bus", &adapter->pdev->bus->number);
+ LIST_ADD_F("PCI_Slot", adapter, e1000_proc_slot);
+
+ if(adapter->shared.mac_type >= e1000_82543) {
+ LIST_ADD_F("PCI_Bus_Type",
+ &shared->bus_type, e1000_proc_bus_type);
+ LIST_ADD_F("PCI_Bus_Speed",
+ &shared->bus_speed, e1000_proc_bus_speed);
+ LIST_ADD_F("PCI_Bus_Width",
+ &shared->bus_width, e1000_proc_bus_width);
+ }
+
+ LIST_ADD_U("IRQ", &adapter->pdev->irq);
+ LIST_ADD_S("System_Device_Name", adapter->netdev->name);
+ LIST_ADD_F("Current_HWaddr",
+ adapter->netdev->dev_addr, e1000_proc_hwaddr);
+ LIST_ADD_F("Permanent_HWaddr",
+ adapter->shared.perm_mac_addr, e1000_proc_hwaddr);
+
+ LIST_ADD_BLANK();
+
+ LIST_ADD_F("Link", adapter, e1000_proc_link);
+ LIST_ADD_F("Speed", &adapter->link_speed, e1000_proc_link_speed);
+ LIST_ADD_F("Duplex", &adapter->link_duplex, e1000_proc_link_duplex);
+ LIST_ADD_F("State", adapter, e1000_proc_state);
+
+ LIST_ADD_BLANK();
+
+ /* Standard net device stats */
+ LIST_ADD_U("Rx_Packets", &adapter->net_stats.rx_packets);
+ LIST_ADD_U("Tx_Packets", &adapter->net_stats.tx_packets);
+ LIST_ADD_U("Rx_Bytes", &adapter->net_stats.rx_bytes);
+ LIST_ADD_U("Tx_Bytes", &adapter->net_stats.tx_bytes);
+ LIST_ADD_U("Rx_Errors", &adapter->net_stats.rx_errors);
+ LIST_ADD_U("Tx_Errors", &adapter->net_stats.tx_errors);
+ LIST_ADD_U("Rx_Dropped", &adapter->net_stats.rx_dropped);
+ LIST_ADD_U("Tx_Dropped", &adapter->net_stats.tx_dropped);
+
+ LIST_ADD_U("Multicast", &adapter->net_stats.multicast);
+ LIST_ADD_U("Collisions", &adapter->net_stats.collisions);
+
+ LIST_ADD_U("Rx_Length_Errors", &adapter->net_stats.rx_length_errors);
+ LIST_ADD_U("Rx_Over_Errors", &adapter->net_stats.rx_over_errors);
+ LIST_ADD_U("Rx_CRC_Errors", &adapter->net_stats.rx_crc_errors);
+ LIST_ADD_U("Rx_Frame_Errors", &adapter->net_stats.rx_frame_errors);
+ LIST_ADD_U("Rx_FIFO_Errors", &adapter->net_stats.rx_fifo_errors);
+ LIST_ADD_U("Rx_Missed_Errors", &adapter->net_stats.rx_missed_errors);
+
+ LIST_ADD_U("Tx_Aborted_Errors", &adapter->net_stats.tx_aborted_errors);
+ LIST_ADD_U("Tx_Carrier_Errors", &adapter->net_stats.tx_carrier_errors);
+ LIST_ADD_U("Tx_FIFO_Errors", &adapter->net_stats.tx_fifo_errors);
+ LIST_ADD_U("Tx_Heartbeat_Errors",
+ &adapter->net_stats.tx_heartbeat_errors);
+ LIST_ADD_U("Tx_Window_Errors", &adapter->net_stats.tx_window_errors);
+
+ /* 8254x-specific stats */
+ LIST_ADD_U("Tx_Abort_Late_Coll", &adapter->stats.latecol);
+ LIST_ADD_U("Tx_Deferred_Ok", &adapter->stats.dc);
+ LIST_ADD_U("Tx_Single_Coll_Ok", &adapter->stats.scc);
+ LIST_ADD_U("Tx_Multi_Coll_Ok", &adapter->stats.mcc);
+ LIST_ADD_U("Rx_Long_Length_Errors", &adapter->stats.roc);
+ LIST_ADD_U("Rx_Short_Length_Errors", &adapter->stats.ruc);
+
+ /* The 82542 does not have an alignment error count register */
+ if(adapter->shared.mac_type >= e1000_82543)
+ LIST_ADD_U("Rx_Align_Errors", &adapter->stats.algnerrc);
+
+ LIST_ADD_U("Rx_Flow_Control_XON", &adapter->stats.xonrxc);
+ LIST_ADD_U("Rx_Flow_Control_XOFF", &adapter->stats.xoffrxc);
+ LIST_ADD_U("Tx_Flow_Control_XON", &adapter->stats.xontxc);
+ LIST_ADD_U("Tx_Flow_Control_XOFF", &adapter->stats.xofftxc);
+ LIST_ADD_U("Rx_CSum_Offload_Good", &adapter->hw_csum_good);
+ LIST_ADD_U("Rx_CSum_Offload_Errors", &adapter->hw_csum_err);
+
+ LIST_ADD_BLANK();
+
+ /* Cable diags */
+ LIST_ADD_F("PHY_Media_Type", adapter, e1000_proc_media_type);
+ if(adapter->shared.media_type == e1000_media_type_copper) {
+ LIST_ADD_F("PHY_Cable_Length",
+ adapter, e1000_proc_cable_length);
+ LIST_ADD_F("PHY_Extended_10Base_T_Distance",
+ adapter, e1000_proc_extended);
+ LIST_ADD_F("PHY_Cable_Polarity",
+ adapter, e1000_proc_cable_polarity);
+ LIST_ADD_F("PHY_Disable_Polarity_Correction",
+ adapter, e1000_proc_polarity_correction);
+ LIST_ADD_U("PHY_Idle_Errors",
+ &adapter->phy_stats.idle_errors);
+ LIST_ADD_F("PHY_Link_Reset_Enabled",
+ adapter, e1000_proc_link_reset_enabled);
+ LIST_ADD_U("PHY_Receive_Errors",
+ &adapter->phy_stats.receive_errors);
+ LIST_ADD_F("PHY_MDI_X_Enabled",
+ adapter, e1000_proc_mdi_x_enabled);
+ LIST_ADD_F("PHY_Local_Receiver_Status",
+ &adapter->phy_info.local_rx,
+ e1000_proc_rx_status);
+ LIST_ADD_F("PHY_Remote_Receiver_Status",
+ &adapter->phy_info.remote_rx,
+ e1000_proc_rx_status);
+ }
+
+ return;
+}
+
+/*
+ * e1000_proc_dev_setup - create proc fs nodes and link list
+ * @adapter: board private structure
+ */
+
+void __devinit
+e1000_proc_dev_setup(struct e1000_adapter *adapter)
+{
+ e1000_proc_list_setup(adapter);
+
+ e1000_proc_dirs_create(adapter->netdev->name,&adapter->proc_list_head);
+
+ return;
+}
+
+/*
+ * e1000_proc_dev_free - free proc fs nodes and link list
+ * @adapter: board private structure
+ */
+
+void __devexit
+e1000_proc_dev_free(struct e1000_adapter *adapter)
+{
+ e1000_proc_dirs_free(adapter->netdev->name, &adapter->proc_list_head);
+
+ e1000_proc_list_free(&adapter->proc_list_head);
+
+ return;
+}
+
+#else /* CONFIG_PROC_FS */
+
+void __devinit e1000_proc_dev_setup(struct e1000_adapter *adapter) {}
+void __devexit e1000_proc_dev_free(struct e1000_adapter *adapter) {}
+
+#endif /* CONFIG_PROC_FS */
+
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
new file mode 100644
index 000000000000..b31c78151763
--- /dev/null
+++ b/drivers/net/tokenring/3c359.c
@@ -0,0 +1,1816 @@
+/*
+ * 3c359.c (c) 2000 Mike Phillips (mikep@linuxtr.net) All Rights Reserved
+ *
+ * Linux driver for 3Com 3c359 Tokenlink Velocity XL PCI NIC
+ *
+ * Base Driver Olympic:
+ * Written 1999 Peter De Schrijver & Mike Phillips
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * 7/17/00 - Clean up, version number 0.9.0. Ready to release to the world.
+ *
+ * 2/16/01 - Port up to kernel 2.4.2 ready for submission into the kernel.
+ * 3/05/01 - Last clean up stuff before submission.
+ * 2/15/01 - Finally, update to new pci api.
+ *
+ * To Do:
+ */
+
+/*
+ * Technical Card Details
+ *
+ * All access to data is done with 16/8 bit transfers. The transfer
+ * method really sucks. You can only read or write one location at a time.
+ *
+ * Also, the microcode for the card must be uploaded if the card does not have
+ * the flashrom on board. This is a 28K bloat in the driver when compiled
+ * as a module.
+ *
+ * Rx is very simple, status into a ring of descriptors, dma data transfer,
+ * interrupts to tell us when a packet is received.
+ *
+ * Tx is a little more interesting. Similar scenario, descriptor and dma data
+ * transfers, but we don't have to interrupt the card to tell it another packet
+ * is ready for transmission, we are just doing simple memory writes, not io or mmio
+ * writes. The card can be set up to simply poll on the next
+ * descriptor pointer and when this value is non-zero will automatically download
+ * the next packet. The card then interrupts us when the packet is done.
+ *
+ */
+
+#define XL_DEBUG 0
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/timer.h>
+#include <linux/in.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/proc_fs.h>
+#include <linux/ptrace.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/trdevice.h>
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <net/checksum.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include "3c359.h"
+
+static char version[] __devinitdata =
+"3c359.c v1.2.0 2/17/01 - Mike Phillips (mikep@linuxtr.net)" ;
+
+MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ;
+MODULE_DESCRIPTION("3Com 3C359 Velocity XL Token Ring Adapter Driver \n") ;
+
+/* Module paramters */
+
+/* Ring Speed 0,4,16
+ * 0 = Autosense
+ * 4,16 = Selected speed only, no autosense
+ * This allows the card to be the first on the ring
+ * and become the active monitor.
+ *
+ * WARNING: Some hubs will allow you to insert
+ * at the wrong speed.
+ *
+ * The adapter will _not_ fail to open if there are no
+ * active monitors on the ring, it will simply open up in
+ * its last known ringspeed if no ringspeed is specified.
+ */
+
+static int ringspeed[XL_MAX_ADAPTERS] = {0,} ;
+
+MODULE_PARM(ringspeed, "1-" __MODULE_STRING(XL_MAX_ADAPTERS) "i");
+MODULE_PARM_DESC(ringspeed,"3c359: Ringspeed selection - 4,16 or 0") ;
+
+/* Packet buffer size */
+
+static int pkt_buf_sz[XL_MAX_ADAPTERS] = {0,} ;
+
+MODULE_PARM(pkt_buf_sz, "1-" __MODULE_STRING(XL_MAX_ADAPTERS) "i") ;
+MODULE_PARM_DESC(pkt_buf_sz,"3c359: Initial buffer size") ;
+/* Message Level */
+
+static int message_level[XL_MAX_ADAPTERS] = {0,} ;
+
+MODULE_PARM(message_level, "1-" __MODULE_STRING(XL_MAX_ADAPTERS) "i") ;
+MODULE_PARM_DESC(message_level, "3c359: Level of reported messages \n") ;
+/*
+ * This is a real nasty way of doing this, but otherwise you
+ * will be stuck with 1555 lines of hex #'s in the code.
+ */
+
+#include "3c359_microcode.h"
+
+static struct pci_device_id xl_pci_tbl[] __devinitdata =
+{
+ {PCI_VENDOR_ID_3COM,PCI_DEVICE_ID_3COM_3C359, PCI_ANY_ID, PCI_ANY_ID, },
+ { } /* terminate list */
+};
+MODULE_DEVICE_TABLE(pci,xl_pci_tbl) ;
+
+static int xl_init(struct net_device *dev);
+static int xl_open(struct net_device *dev);
+static int xl_open_hw(struct net_device *dev) ;
+static int xl_hw_reset(struct net_device *dev);
+static int xl_xmit(struct sk_buff *skb, struct net_device *dev);
+static void xl_dn_comp(struct net_device *dev);
+static int xl_close(struct net_device *dev);
+static void xl_set_rx_mode(struct net_device *dev);
+static void xl_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static struct net_device_stats * xl_get_stats(struct net_device *dev);
+static int xl_set_mac_address(struct net_device *dev, void *addr) ;
+static void xl_arb_cmd(struct net_device *dev);
+static void xl_asb_cmd(struct net_device *dev) ;
+static void xl_srb_cmd(struct net_device *dev, int srb_cmd) ;
+static void xl_wait_misr_flags(struct net_device *dev) ;
+static int xl_change_mtu(struct net_device *dev, int mtu);
+static void xl_srb_bh(struct net_device *dev) ;
+static void xl_asb_bh(struct net_device *dev) ;
+static void xl_reset(struct net_device *dev) ;
+static void xl_freemem(struct net_device *dev) ;
+
+
+/* EEProm Access Functions */
+static u16 xl_ee_read(struct net_device *dev, int ee_addr) ;
+static void xl_ee_write(struct net_device *dev, int ee_addr, u16 ee_value) ;
+
+/* Debugging functions */
+#if XL_DEBUG
+static void print_tx_state(struct net_device *dev) ;
+static void print_rx_state(struct net_device *dev) ;
+
+static void print_tx_state(struct net_device *dev)
+{
+
+ struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
+ struct xl_tx_desc *txd ;
+ u8 *xl_mmio = xl_priv->xl_mmio ;
+ int i ;
+
+ printk("tx_ring_head: %d, tx_ring_tail: %d, free_ent: %d \n",xl_priv->tx_ring_head,
+ xl_priv->tx_ring_tail, xl_priv->free_ring_entries) ;
+ printk("Ring , Address , FSH , DnNextPtr, Buffer, Buffer_Len \n");
+ for (i = 0; i < 16; i++) {
+ txd = &(xl_priv->xl_tx_ring[i]) ;
+ printk("%d, %08lx, %08x, %08x, %08x, %08x \n", i, virt_to_bus(txd),
+ txd->framestartheader, txd->dnnextptr, txd->buffer, txd->buffer_length ) ;
+ }
+
+ printk("DNLISTPTR = %04x \n", readl(xl_mmio + MMIO_DNLISTPTR) );
+
+ printk("DmaCtl = %04x \n", readl(xl_mmio + MMIO_DMA_CTRL) );
+ printk("Queue status = %0x \n",netif_running(dev) ) ;
+}
+
+static void print_rx_state(struct net_device *dev)
+{
+
+ struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
+ struct xl_rx_desc *rxd ;
+ u8 *xl_mmio = xl_priv->xl_mmio ;
+ int i ;
+
+ printk("rx_ring_tail: %d \n", xl_priv->rx_ring_tail) ;
+ printk("Ring , Address , FrameState , UPNextPtr, FragAddr, Frag_Len \n");
+ for (i = 0; i < 16; i++) {
+ /* rxd = (struct xl_rx_desc *)xl_priv->rx_ring_dma_addr + (i * sizeof(struct xl_rx_desc)) ; */
+ rxd = &(xl_priv->xl_rx_ring[i]) ;
+ printk("%d, %08lx, %08x, %08x, %08x, %08x \n", i, virt_to_bus(rxd),
+ rxd->framestatus, rxd->upnextptr, rxd->upfragaddr, rxd->upfraglen ) ;
+ }
+
+ printk("UPLISTPTR = %04x \n", readl(xl_mmio + MMIO_UPLISTPTR) );
+
+ printk("DmaCtl = %04x \n", readl(xl_mmio + MMIO_DMA_CTRL) );
+ printk("Queue status = %0x \n",netif_running(dev) ) ;
+}
+#endif
+
+/*
+ * Read values from the on-board EEProm. This looks very strange
+ * but you have to wait for the EEProm to get/set the value before
+ * passing/getting the next value from the nic. As with all requests
+ * on this nic it has to be done in two stages, a) tell the nic which
+ * memory address you want to access and b) pass/get the value from the nic.
+ * With the EEProm, you have to wait before and inbetween access a) and b).
+ * As this is only read at initialization time and the wait period is very
+ * small we shouldn't have to worry about scheduling issues.
+ */
+
+static u16 xl_ee_read(struct net_device *dev, int ee_addr)
+{
+ struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
+ u8 *xl_mmio = xl_priv->xl_mmio ;
+
+ /* Wait for EEProm to not be busy */
+ writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ;
+
+ /* Tell EEProm what we want to do and where */
+ writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writew(EEREAD + ee_addr, xl_mmio + MMIO_MACDATA) ;
+
+ /* Wait for EEProm to not be busy */
+ writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ;
+
+ /* Tell EEProm what we want to do and where */
+ writel(IO_WORD_WRITE | EECONTROL , xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writew(EEREAD + ee_addr, xl_mmio + MMIO_MACDATA) ;
+
+ /* Finally read the value from the EEProm */
+ writel(IO_WORD_READ | EEDATA , xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ return readw(xl_mmio + MMIO_MACDATA) ;
+}
+
+/*
+ * Write values to the onboard eeprom. As with eeprom read you need to
+ * set which location to write, wait, value to write, wait, with the
+ * added twist of having to enable eeprom writes as well.
+ */
+
+static void xl_ee_write(struct net_device *dev, int ee_addr, u16 ee_value)
+{
+ struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
+ u8 *xl_mmio = xl_priv->xl_mmio ;
+
+ /* Wait for EEProm to not be busy */
+ writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ;
+
+ /* Enable write/erase */
+ writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writew(EE_ENABLE_WRITE, xl_mmio + MMIO_MACDATA) ;
+
+ /* Wait for EEProm to not be busy */
+ writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ;
+
+ /* Put the value we want to write into EEDATA */
+ writel(IO_WORD_WRITE | EEDATA, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writew(ee_value, xl_mmio + MMIO_MACDATA) ;
+
+ /* Tell EEProm to write eevalue into ee_addr */
+ writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writew(EEWRITE + ee_addr, xl_mmio + MMIO_MACDATA) ;
+
+ /* Wait for EEProm to not be busy, to ensure write gets done */
+ writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ;
+
+ return ;
+}
+
+int __devinit xl_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ struct net_device *dev ;
+ struct xl_private *xl_priv ;
+ static int card_no = -1 ;
+ int i ;
+
+ card_no++ ;
+
+ if (pci_enable_device(pdev)) {
+ return -ENODEV ;
+ }
+
+ pci_set_master(pdev);
+
+ if ((i = pci_request_regions(pdev,"3c359"))) {
+ return i ;
+ } ;
+
+ /*
+ * Allowing init_trdev to allocate the dev->priv structure will align xl_private
+ * on a 32 bytes boundary which we need for the rx/tx descriptors
+ */
+
+ dev = alloc_trdev(sizeof(struct xl_private)) ;
+ if (!dev) {
+ pci_release_regions(pdev) ;
+ return -ENOMEM ;
+ }
+ xl_priv = dev->priv ;
+
+#if XL_DEBUG
+ printk("pci_device: %p, dev:%p, dev->priv: %p, ba[0]: %10x, ba[1]:%10x\n",
+ pdev, dev, dev->priv, (unsigned int)pdev->resource[0].start, (unsigned int)pdev->resource[1].start) ;
+#endif
+
+ dev->irq=pdev->irq;
+ dev->base_addr=pci_resource_start(pdev,0) ;
+ dev->init=NULL ; /* Must be null with new api, otherwise get called twice */
+ xl_priv->xl_card_name = (char *)pdev->name ;
+ xl_priv->xl_mmio=ioremap(pci_resource_start(pdev,1), XL_IO_SPACE);
+ xl_priv->pdev = pdev ;
+
+ if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) )
+ xl_priv->pkt_buf_sz = PKT_BUF_SZ ;
+ else
+ xl_priv->pkt_buf_sz = pkt_buf_sz[card_no] ;
+
+ dev->mtu = xl_priv->pkt_buf_sz - TR_HLEN ;
+ xl_priv->xl_ring_speed = ringspeed[card_no] ;
+ xl_priv->xl_message_level = message_level[card_no] ;
+ xl_priv->xl_functional_addr[0] = xl_priv->xl_functional_addr[1] = xl_priv->xl_functional_addr[2] = xl_priv->xl_functional_addr[3] = 0 ;
+ xl_priv->xl_copy_all_options = 0 ;
+
+ if((i = xl_init(dev))) {
+ iounmap(xl_priv->xl_mmio) ;
+ kfree(dev) ;
+ pci_release_regions(pdev) ;
+ return i ;
+ }
+
+ dev->open=&xl_open;
+ dev->hard_start_xmit=&xl_xmit;
+ dev->change_mtu=&xl_change_mtu;
+ dev->stop=&xl_close;
+ dev->do_ioctl=NULL;
+ dev->set_multicast_list=&xl_set_rx_mode;
+ dev->get_stats=&xl_get_stats ;
+ dev->set_mac_address=&xl_set_mac_address ;
+ SET_MODULE_OWNER(dev);
+
+ pci_set_drvdata(pdev,dev) ;
+ if ((i = register_netdev(dev))) {
+ printk(KERN_ERR "3C359, register netdev failed\n") ;
+ pci_set_drvdata(pdev,NULL) ;
+ iounmap(xl_priv->xl_mmio) ;
+ kfree(dev) ;
+ pci_release_regions(pdev) ;
+ return i ;
+ }
+
+ printk(KERN_INFO "3C359: %s registered as: %s\n",xl_priv->xl_card_name,dev->name) ;
+
+ return 0;
+}
+
+
+static int __init xl_init(struct net_device *dev)
+{
+ struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
+
+ printk(KERN_INFO "%s \n", version);
+ printk(KERN_INFO "%s: I/O at %hx, MMIO at %p, using irq %d\n",
+ xl_priv->xl_card_name, (unsigned int)dev->base_addr ,xl_priv->xl_mmio, dev->irq);
+
+ spin_lock_init(&xl_priv->xl_lock) ;
+
+ return xl_hw_reset(dev) ;
+
+}
+
+
+/*
+ * Hardware reset. This needs to be a separate entity as we need to reset the card
+ * when we change the EEProm settings.
+ */
+
+static int xl_hw_reset(struct net_device *dev)
+{
+ struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
+ u8 *xl_mmio = xl_priv->xl_mmio ;
+ unsigned long t ;
+ u16 i ;
+ u16 result_16 ;
+ u8 result_8 ;
+ u16 start ;
+ int j ;
+
+ /*
+ * Reset the card. If the card has got the microcode on board, we have
+ * missed the initialization interrupt, so we must always do this.
+ */
+
+ writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ;
+
+ /*
+ * Must wait for cmdInProgress bit (12) to clear before continuing with
+ * card configuration.
+ */
+
+ t=jiffies;
+ while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) {
+ schedule();
+ if(jiffies-t > 40*HZ) {
+ printk(KERN_ERR "%s: 3COM 3C359 Velocity XL card not responding to global reset.\n", dev->name);
+ return -ENODEV;
+ }
+ }
+
+ /*
+ * Enable pmbar by setting bit in CPAttention
+ */
+
+ writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ result_8 = readb(xl_mmio + MMIO_MACDATA) ;
+ result_8 = result_8 | CPA_PMBARVIS ;
+ writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(result_8, xl_mmio + MMIO_MACDATA) ;
+
+ /*
+ * Read cpHold bit in pmbar, if cleared we have got Flashrom on board.
+ * If not, we need to upload the microcode to the card
+ */
+
+ writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD);
+
+#if XL_DEBUG
+ printk(KERN_INFO "Read from PMBAR = %04x \n", readw(xl_mmio + MMIO_MACDATA)) ;
+#endif
+
+ if ( readw( (xl_mmio + MMIO_MACDATA)) & PMB_CPHOLD ) {
+
+ /* Set PmBar, privateMemoryBase bits (8:2) to 0 */
+
+ writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD);
+ result_16 = readw(xl_mmio + MMIO_MACDATA) ;
+ result_16 = result_16 & ~((0x7F) << 2) ;
+ writel( (IO_WORD_WRITE | PMBAR), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writew(result_16,xl_mmio + MMIO_MACDATA) ;
+
+ /* Set CPAttention, memWrEn bit */
+
+ writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ result_8 = readb(xl_mmio + MMIO_MACDATA) ;
+ result_8 = result_8 | CPA_MEMWREN ;
+ writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(result_8, xl_mmio + MMIO_MACDATA) ;
+
+ /*
+ * Now to write the microcode into the shared ram
+ * The microcode must finish at position 0xFFFF, so we must subtract
+ * to get the start position for the code
+ */
+
+ start = (0xFFFF - (mc_size) + 1 ) ; /* Looks strange but ensures compiler only uses 16 bit unsigned int for this */
+
+ printk(KERN_INFO "3C359: Uploading Microcode: ");
+
+ for (i = start,j=0; (j < mc_size && i <= 0xffff) ; i++,j++) {
+ writel(MEM_BYTE_WRITE | 0XD0000 | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(microcode[j],xl_mmio + MMIO_MACDATA) ;
+ if (j % 1024 == 0)
+ printk(".");
+ }
+ printk("\n") ;
+
+ for (i=0;i < 16; i++) {
+ writel( (MEM_BYTE_WRITE | 0xDFFF0) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(microcode[mc_size - 16 + i], xl_mmio + MMIO_MACDATA) ;
+ }
+
+ /*
+ * Have to write the start address of the upload to FFF4, but
+ * the address must be >> 4. You do not want to know how long
+ * it took me to discover this.
+ */
+
+ writel(MEM_WORD_WRITE | 0xDFFF4, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writew(start >> 4, xl_mmio + MMIO_MACDATA);
+
+ /* Clear the CPAttention, memWrEn Bit */
+
+ writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ result_8 = readb(xl_mmio + MMIO_MACDATA) ;
+ result_8 = result_8 & ~CPA_MEMWREN ;
+ writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(result_8, xl_mmio + MMIO_MACDATA) ;
+
+ /* Clear the cpHold bit in pmbar */
+
+ writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD);
+ result_16 = readw(xl_mmio + MMIO_MACDATA) ;
+ result_16 = result_16 & ~PMB_CPHOLD ;
+ writel( (IO_WORD_WRITE | PMBAR), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writew(result_16,xl_mmio + MMIO_MACDATA) ;
+
+
+ } /* If microcode upload required */
+
+ /*
+ * The card should now go though a self test procedure and get itself ready
+ * to be opened, we must wait for an srb response with the initialization
+ * information.
+ */
+
+#if XL_DEBUG
+ printk(KERN_INFO "%s: Microcode uploaded, must wait for the self test to complete\n", dev->name);
+#endif
+
+ writew(SETINDENABLE | 0xFFF, xl_mmio + MMIO_COMMAND) ;
+
+ t=jiffies;
+ while ( !(readw(xl_mmio + MMIO_INTSTATUS_AUTO) & INTSTAT_SRB) ) {
+ schedule();
+ if(jiffies-t > 15*HZ) {
+ printk(KERN_ERR "3COM 3C359 Velocity XL card not responding.\n");
+ return -ENODEV;
+ }
+ }
+
+ /*
+ * Write the RxBufArea with D000, RxEarlyThresh, TxStartThresh,
+ * DnPriReqThresh, read the tech docs if you want to know what
+ * values they need to be.
+ */
+
+ writel(MMIO_WORD_WRITE | RXBUFAREA, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writew(0xD000, xl_mmio + MMIO_MACDATA) ;
+
+ writel(MMIO_WORD_WRITE | RXEARLYTHRESH, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writew(0X0020, xl_mmio + MMIO_MACDATA) ;
+
+ writew( SETTXSTARTTHRESH | 0x40 , xl_mmio + MMIO_COMMAND) ;
+
+ writeb(0x04, xl_mmio + MMIO_DNBURSTTHRESH) ;
+ writeb(0x04, xl_mmio + DNPRIREQTHRESH) ;
+
+ /*
+ * Read WRBR to provide the location of the srb block, have to use byte reads not word reads.
+ * Tech docs have this wrong !!!!
+ */
+
+ writel(MMIO_BYTE_READ | WRBR, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ xl_priv->srb = readb(xl_mmio + MMIO_MACDATA) << 8 ;
+ writel( (MMIO_BYTE_READ | WRBR) + 1, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ xl_priv->srb = xl_priv->srb | readb(xl_mmio + MMIO_MACDATA) ;
+
+#if XL_DEBUG
+ writel(IO_WORD_READ | SWITCHSETTINGS, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ if ( readw(xl_mmio + MMIO_MACDATA) & 2) {
+ printk(KERN_INFO "Default ring speed 4 mbps \n") ;
+ } else {
+ printk(KERN_INFO "Default ring speed 16 mbps \n") ;
+ }
+ printk(KERN_INFO "%s: xl_priv->srb = %04x\n",xl_priv->xl_card_name, xl_priv->srb);
+#endif
+
+ return 0;
+}
+
+static int xl_open(struct net_device *dev)
+{
+ struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+ u8 * xl_mmio = xl_priv->xl_mmio ;
+ u8 i ;
+ u16 hwaddr[3] ; /* Should be u8[6] but we get word return values */
+ int open_err ;
+
+ u16 switchsettings, switchsettings_eeprom ;
+
+ if(request_irq(dev->irq, &xl_interrupt, SA_SHIRQ , "3c359", dev)) {
+ return -EAGAIN;
+ }
+
+ /*
+ * Read the information from the EEPROM that we need. I know we
+ * should use ntohs, but the word gets stored reversed in the 16
+ * bit field anyway and it all works its self out when we memcpy
+ * it into dev->dev_addr.
+ */
+
+ hwaddr[0] = xl_ee_read(dev,0x10) ;
+ hwaddr[1] = xl_ee_read(dev,0x11) ;
+ hwaddr[2] = xl_ee_read(dev,0x12) ;
+
+ /* Ring speed */
+
+ switchsettings_eeprom = xl_ee_read(dev,0x08) ;
+ switchsettings = switchsettings_eeprom ;
+
+ if (xl_priv->xl_ring_speed != 0) {
+ if (xl_priv->xl_ring_speed == 4)
+ switchsettings = switchsettings | 0x02 ;
+ else
+ switchsettings = switchsettings & ~0x02 ;
+ }
+
+ /* Only write EEProm if there has been a change */
+ if (switchsettings != switchsettings_eeprom) {
+ xl_ee_write(dev,0x08,switchsettings) ;
+ /* Hardware reset after changing EEProm */
+ xl_hw_reset(dev) ;
+ }
+
+ memcpy(dev->dev_addr,hwaddr,dev->addr_len) ;
+
+ open_err = xl_open_hw(dev) ;
+
+ /*
+ * This really needs to be cleaned up with better error reporting.
+ */
+
+ if (open_err != 0) { /* Something went wrong with the open command */
+ if (open_err & 0x07) { /* Wrong speed, retry at different speed */
+ printk(KERN_WARNING "%s: Open Error, retrying at different ringspeed \n", dev->name) ;
+ switchsettings = switchsettings ^ 2 ;
+ xl_ee_write(dev,0x08,switchsettings) ;
+ xl_hw_reset(dev) ;
+ open_err = xl_open_hw(dev) ;
+ if (open_err != 0) {
+ printk(KERN_WARNING "%s: Open error returned a second time, we're bombing out now\n", dev->name);
+ free_irq(dev->irq,dev) ;
+ return -ENODEV ;
+ }
+ } else {
+ printk(KERN_WARNING "%s: Open Error = %04x\n", dev->name, open_err) ;
+ free_irq(dev->irq,dev) ;
+ return -ENODEV ;
+ }
+ }
+
+ /*
+ * Now to set up the Rx and Tx buffer structures
+ */
+ /* These MUST be on 8 byte boundaries */
+ xl_priv->xl_tx_ring = kmalloc((sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE) + 7, GFP_DMA | GFP_KERNEL) ;
+ xl_priv->xl_rx_ring = kmalloc((sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE) +7, GFP_DMA | GFP_KERNEL) ;
+ memset(xl_priv->xl_tx_ring,0,sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE) ;
+ memset(xl_priv->xl_rx_ring,0,sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE) ;
+
+ /* Setup Rx Ring */
+ for (i=0 ; i < XL_RX_RING_SIZE ; i++) {
+ struct sk_buff *skb ;
+
+ skb = dev_alloc_skb(xl_priv->pkt_buf_sz) ;
+ if (skb==NULL)
+ break ;
+
+ skb->dev = dev ;
+ xl_priv->xl_rx_ring[i].upfragaddr = pci_map_single(xl_priv->pdev, skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE) ;
+ xl_priv->xl_rx_ring[i].upfraglen = xl_priv->pkt_buf_sz | RXUPLASTFRAG;
+ xl_priv->rx_ring_skb[i] = skb ;
+ }
+
+ if (i==0) {
+ printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled \n",dev->name) ;
+ free_irq(dev->irq,dev) ;
+ return -EIO ;
+ }
+
+ xl_priv->rx_ring_no = i ;
+ xl_priv->rx_ring_tail = 0 ;
+ xl_priv->rx_ring_dma_addr = pci_map_single(xl_priv->pdev,xl_priv->xl_rx_ring, sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, PCI_DMA_TODEVICE) ;
+ for (i=0;i<(xl_priv->rx_ring_no-1);i++) {
+ xl_priv->xl_rx_ring[i].upnextptr = xl_priv->rx_ring_dma_addr + (sizeof (struct xl_rx_desc) * (i+1)) ;
+ }
+ xl_priv->xl_rx_ring[i].upnextptr = 0 ;
+
+ writel(xl_priv->rx_ring_dma_addr, xl_mmio + MMIO_UPLISTPTR) ;
+
+ /* Setup Tx Ring */
+
+ xl_priv->tx_ring_dma_addr = pci_map_single(xl_priv->pdev,xl_priv->xl_tx_ring, sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE,PCI_DMA_TODEVICE) ;
+
+ xl_priv->tx_ring_head = 1 ;
+ xl_priv->tx_ring_tail = 255 ; /* Special marker for first packet */
+ xl_priv->free_ring_entries = XL_TX_RING_SIZE ;
+
+ /*
+ * Setup the first dummy DPD entry for polling to start working.
+ */
+
+ xl_priv->xl_tx_ring[0].framestartheader = TXDPDEMPTY ;
+ xl_priv->xl_tx_ring[0].buffer = 0 ;
+ xl_priv->xl_tx_ring[0].buffer_length = 0 ;
+ xl_priv->xl_tx_ring[0].dnnextptr = 0 ;
+
+ writel(xl_priv->tx_ring_dma_addr, xl_mmio + MMIO_DNLISTPTR) ;
+ writel(DNUNSTALL, xl_mmio + MMIO_COMMAND) ;
+ writel(UPUNSTALL, xl_mmio + MMIO_COMMAND) ;
+ writel(DNENABLE, xl_mmio + MMIO_COMMAND) ;
+ writeb(0x40, xl_mmio + MMIO_DNPOLL) ;
+
+ /*
+ * Enable interrupts on the card
+ */
+
+ writel(SETINTENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ;
+ writel(SETINDENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ;
+
+ netif_start_queue(dev) ;
+ return 0;
+
+}
+
+static int xl_open_hw(struct net_device *dev)
+{
+ struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+ u8 * xl_mmio = xl_priv->xl_mmio ;
+ u16 vsoff ;
+ char ver_str[33];
+ int open_err ;
+ int i ;
+ unsigned long t ;
+
+ /*
+ * Okay, let's build up the Open.NIC srb command
+ *
+ */
+
+ writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(OPEN_NIC, xl_mmio + MMIO_MACDATA) ;
+
+ /*
+ * Use this as a test byte, if it comes back with the same value, the command didn't work
+ */
+
+ writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb)+ 2, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(0xff,xl_mmio + MMIO_MACDATA) ;
+
+ /* Open options */
+ writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + 8, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(0x00, xl_mmio + MMIO_MACDATA) ;
+ writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + 9, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(0x00, xl_mmio + MMIO_MACDATA) ;
+
+ /*
+ * Node address, be careful here, the docs say you can just put zeros here and it will use
+ * the hardware address, it doesn't, you must include the node address in the open command.
+ */
+
+ if (xl_priv->xl_laa[0]) { /* If using a LAA address */
+ for (i=10;i<16;i++) {
+ writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(xl_priv->xl_laa[i],xl_mmio + MMIO_MACDATA) ;
+ }
+ memcpy(dev->dev_addr,xl_priv->xl_laa,dev->addr_len) ;
+ } else { /* Regular hardware address */
+ for (i=10;i<16;i++) {
+ writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(dev->dev_addr[i-10], xl_mmio + MMIO_MACDATA) ;
+ }
+ }
+
+ /* Default everything else to 0 */
+ for (i = 16; i < 34; i++) {
+ writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(0x00,xl_mmio + MMIO_MACDATA) ;
+ }
+
+ /*
+ * Set the csrb bit in the MISR register
+ */
+
+ xl_wait_misr_flags(dev) ;
+ writel(MEM_BYTE_WRITE | MF_CSRB, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(0xFF, xl_mmio + MMIO_MACDATA) ;
+ writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(MISR_CSRB , xl_mmio + MMIO_MACDATA) ;
+
+ /*
+ * Now wait for the command to run
+ */
+
+ t=jiffies;
+ while (! (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_SRB)) {
+ schedule();
+ if(jiffies-t > 40*HZ) {
+ printk(KERN_ERR "3COM 3C359 Velocity XL card not responding.\n");
+ break ;
+ }
+ }
+
+ /*
+ * Let's interpret the open response
+ */
+
+ writel( (MEM_BYTE_READ | 0xD0000 | xl_priv->srb)+2, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ if (readb(xl_mmio + MMIO_MACDATA)!=0) {
+ open_err = readb(xl_mmio + MMIO_MACDATA) << 8 ;
+ writel( (MEM_BYTE_READ | 0xD0000 | xl_priv->srb) + 7, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ open_err |= readb(xl_mmio + MMIO_MACDATA) ;
+ return open_err ;
+ } else {
+ writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 8, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ xl_priv->asb = ntohs(readw(xl_mmio + MMIO_MACDATA)) ;
+ printk(KERN_INFO "%s: Adapter Opened Details: ",dev->name) ;
+ printk("ASB: %04x",xl_priv->asb ) ;
+ writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 10, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ printk(", SRB: %04x",ntohs(readw(xl_mmio + MMIO_MACDATA)) ) ;
+
+ writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 12, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ xl_priv->arb = ntohs(readw(xl_mmio + MMIO_MACDATA)) ;
+ printk(", ARB: %04x \n",xl_priv->arb ) ;
+ writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 14, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ vsoff = ntohs(readw(xl_mmio + MMIO_MACDATA)) ;
+
+ /*
+ * Interesting, sending the individual characters directly to printk was causing klogd to use
+ * use 100% of processor time, so we build up the string and print that instead.
+ */
+
+ for (i=0;i<0x20;i++) {
+ writel( (MEM_BYTE_READ | 0xD0000 | vsoff) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ ver_str[i] = readb(xl_mmio + MMIO_MACDATA) ;
+ }
+ ver_str[i] = '\0' ;
+ printk(KERN_INFO "%s: Microcode version String: %s \n",dev->name,ver_str);
+ }
+
+ /*
+ * Issue the AckInterrupt
+ */
+ writew(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
+
+ return 0 ;
+}
+
+/*
+ * There are two ways of implementing rx on the 359 NIC, either
+ * interrupt driven or polling. We are going to uses interrupts,
+ * it is the easier way of doing things.
+ *
+ * The Rx works with a ring of Rx descriptors. At initialise time the ring
+ * entries point to the next entry except for the last entry in the ring
+ * which points to 0. The card is programmed with the location of the first
+ * available descriptor and keeps reading the next_ptr until next_ptr is set
+ * to 0. Hopefully with a ring size of 16 the card will never get to read a next_ptr
+ * of 0. As the Rx interrupt is received we copy the frame up to the protocol layers
+ * and then point the end of the ring to our current position and point our current
+ * position to 0, therefore making the current position the last position on the ring.
+ * The last position on the ring therefore loops continually loops around the rx ring.
+ *
+ * rx_ring_tail is the position on the ring to process next. (Think of a snake, the head
+ * expands as the card adds new packets and we go around eating the tail processing the
+ * packets.)
+ *
+ * Undoubtably it could be streamlined and improved upon, but at the moment it works
+ * and the fast path through the routine is fine.
+ *
+ * adv_rx_ring could be inlined to increase performance, but its called a *lot* of times
+ * in xl_rx so would increase the size of the function significantly.
+ */
+
+static void adv_rx_ring(struct net_device *dev) /* Advance rx_ring, cut down on bloat in xl_rx */
+{
+ struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+ int prev_ring_loc ;
+
+ prev_ring_loc = (xl_priv->rx_ring_tail + XL_RX_RING_SIZE - 1) & (XL_RX_RING_SIZE - 1);
+ xl_priv->xl_rx_ring[prev_ring_loc].upnextptr = xl_priv->rx_ring_dma_addr + (sizeof (struct xl_rx_desc) * xl_priv->rx_ring_tail) ;
+ xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus = 0 ;
+ xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upnextptr = 0 ;
+ xl_priv->rx_ring_tail++ ;
+ xl_priv->rx_ring_tail &= (XL_RX_RING_SIZE-1) ;
+
+ return ;
+}
+
+static void xl_rx(struct net_device *dev)
+{
+ struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+ u8 * xl_mmio = xl_priv->xl_mmio ;
+ struct sk_buff *skb, *skb2 ;
+ int frame_length = 0, copy_len = 0 ;
+ int temp_ring_loc ;
+
+ /*
+ * Receive the next frame, loop around the ring until all frames
+ * have been received.
+ */
+
+ while (xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus & (RXUPDCOMPLETE | RXUPDFULL) ) { /* Descriptor to process */
+
+ if (xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus & RXUPDFULL ) { /* UpdFull, Multiple Descriptors used for the frame */
+
+ /*
+ * This is a pain, you need to go through all the descriptors until the last one
+ * for this frame to find the framelength
+ */
+
+ temp_ring_loc = xl_priv->rx_ring_tail ;
+
+ while (xl_priv->xl_rx_ring[temp_ring_loc].framestatus & RXUPDFULL ) {
+ temp_ring_loc++ ;
+ temp_ring_loc &= (XL_RX_RING_SIZE-1) ;
+ }
+
+ frame_length = xl_priv->xl_rx_ring[temp_ring_loc].framestatus & 0x7FFF ;
+
+ skb = dev_alloc_skb(frame_length) ;
+
+ if (skb==NULL) { /* No memory for frame, still need to roll forward the rx ring */
+ printk(KERN_WARNING "%s: dev_alloc_skb failed - multi buffer !\n", dev->name) ;
+ while (xl_priv->rx_ring_tail != temp_ring_loc)
+ adv_rx_ring(dev) ;
+
+ adv_rx_ring(dev) ; /* One more time just for luck :) */
+ xl_priv->xl_stats.rx_dropped++ ;
+
+ writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ;
+ return ;
+ }
+
+ skb->dev = dev ;
+
+ while (xl_priv->rx_ring_tail != temp_ring_loc) {
+ copy_len = xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen & 0x7FFF ;
+ frame_length -= copy_len ;
+ pci_dma_sync_single(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
+ memcpy(skb_put(skb,copy_len), xl_priv->rx_ring_skb[xl_priv->rx_ring_tail]->data, copy_len) ;
+ adv_rx_ring(dev) ;
+ }
+
+ /* Now we have found the last fragment */
+ pci_dma_sync_single(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
+ memcpy(skb_put(skb,copy_len), xl_priv->rx_ring_skb[xl_priv->rx_ring_tail]->data, frame_length) ;
+/* memcpy(skb_put(skb,frame_length), bus_to_virt(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr), frame_length) ; */
+ adv_rx_ring(dev) ;
+ skb->protocol = tr_type_trans(skb,dev) ;
+ netif_rx(skb) ;
+
+ } else { /* Single Descriptor Used, simply swap buffers over, fast path */
+
+ frame_length = xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus & 0x7FFF ;
+
+ skb = dev_alloc_skb(xl_priv->pkt_buf_sz) ;
+
+ if (skb==NULL) { /* Still need to fix the rx ring */
+ printk(KERN_WARNING "%s: dev_alloc_skb failed in rx, single buffer \n",dev->name) ;
+ adv_rx_ring(dev) ;
+ xl_priv->xl_stats.rx_dropped++ ;
+ writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ;
+ return ;
+ }
+
+ skb->dev = dev ;
+
+ skb2 = xl_priv->rx_ring_skb[xl_priv->rx_ring_tail] ;
+ pci_unmap_single(xl_priv->pdev, xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr, xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
+ skb_put(skb2, frame_length) ;
+ skb2->protocol = tr_type_trans(skb2,dev) ;
+
+ xl_priv->rx_ring_skb[xl_priv->rx_ring_tail] = skb ;
+ xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr = pci_map_single(xl_priv->pdev,skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE) ;
+ xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen = xl_priv->pkt_buf_sz | RXUPLASTFRAG ;
+ adv_rx_ring(dev) ;
+ xl_priv->xl_stats.rx_packets++ ;
+ xl_priv->xl_stats.rx_bytes += frame_length ;
+
+ netif_rx(skb2) ;
+ } /* if multiple buffers */
+ dev->last_rx = jiffies ;
+ } /* while packet to do */
+
+ /* Clear the updComplete interrupt */
+ writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ;
+ return ;
+}
+
+/*
+ * This is ruthless, it doesn't care what state the card is in it will
+ * completely reset the adapter.
+ */
+
+static void xl_reset(struct net_device *dev)
+{
+ struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+ u8 * xl_mmio = xl_priv->xl_mmio ;
+ unsigned long t;
+
+ writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ;
+
+ /*
+ * Must wait for cmdInProgress bit (12) to clear before continuing with
+ * card configuration.
+ */
+
+ t=jiffies;
+ while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) {
+ if(jiffies-t > 40*HZ) {
+ printk(KERN_ERR "3COM 3C359 Velocity XL card not responding.\n");
+ break ;
+ }
+ }
+
+}
+
+static void xl_freemem(struct net_device *dev)
+{
+ struct xl_private *xl_priv=(struct xl_private *)dev->priv ;
+ int i ;
+
+ for (i=0;i<XL_RX_RING_SIZE;i++) {
+ dev_kfree_skb_irq(xl_priv->rx_ring_skb[xl_priv->rx_ring_tail]) ;
+ pci_unmap_single(xl_priv->pdev,xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE) ;
+ xl_priv->rx_ring_tail++ ;
+ xl_priv->rx_ring_tail &= XL_RX_RING_SIZE-1;
+ }
+
+ /* unmap ring */
+ pci_unmap_single(xl_priv->pdev,xl_priv->rx_ring_dma_addr, sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, PCI_DMA_FROMDEVICE) ;
+
+ pci_unmap_single(xl_priv->pdev,xl_priv->tx_ring_dma_addr, sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE, PCI_DMA_TODEVICE) ;
+
+ kfree(xl_priv->xl_rx_ring) ;
+ kfree(xl_priv->xl_tx_ring) ;
+
+ return ;
+}
+
+static void xl_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct xl_private *xl_priv =(struct xl_private *)dev->priv;
+ u8 * xl_mmio = xl_priv->xl_mmio ;
+ u16 intstatus, macstatus ;
+
+ if (!dev) {
+ printk(KERN_WARNING "Device structure dead, aaahhhh !\n") ;
+ return ;
+ }
+
+ intstatus = readw(xl_mmio + MMIO_INTSTATUS) ;
+
+ if (!(intstatus & 1)) /* We didn't generate the interrupt */
+ return ;
+
+ spin_lock(&xl_priv->xl_lock) ;
+
+ /*
+ * Process the interrupt
+ */
+ /*
+ * Something fishy going on here, we shouldn't get 0001 ints, not fatal though.
+ */
+ if (intstatus == 0x0001) {
+ writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
+ printk(KERN_INFO "%s: 00001 int received \n",dev->name) ;
+ } else {
+ if (intstatus & (HOSTERRINT | SRBRINT | ARBCINT | UPCOMPINT | DNCOMPINT | HARDERRINT | (1<<8) | TXUNDERRUN | ASBFINT)) {
+
+ /*
+ * Host Error.
+ * It may be possible to recover from this, but usually it means something
+ * is seriously fubar, so we just close the adapter.
+ */
+
+ if (intstatus & HOSTERRINT) {
+ printk(KERN_WARNING "%s: Host Error, performing global reset, intstatus = %04x \n",dev->name,intstatus) ;
+ writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ;
+ printk(KERN_WARNING "%s: Resetting hardware: \n", dev->name);
+ netif_stop_queue(dev) ;
+ xl_freemem(dev) ;
+ free_irq(dev->irq,dev);
+ xl_reset(dev) ;
+ writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
+ spin_unlock(&xl_priv->xl_lock) ;
+ return ;
+ } /* Host Error */
+
+ if (intstatus & SRBRINT ) { /* Srbc interrupt */
+ writel(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
+ if (xl_priv->srb_queued)
+ xl_srb_bh(dev) ;
+ } /* SRBR Interrupt */
+
+ if (intstatus & TXUNDERRUN) { /* Issue DnReset command */
+ writel(DNRESET, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { /* Wait for command to run */
+ /* !!! FIX-ME !!!!
+ Must put a timeout check here ! */
+ /* Empty Loop */
+ }
+ printk(KERN_WARNING "%s: TX Underrun received \n",dev->name) ;
+ writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
+ } /* TxUnderRun */
+
+ if (intstatus & ARBCINT ) { /* Arbc interrupt */
+ xl_arb_cmd(dev) ;
+ } /* Arbc */
+
+ if (intstatus & ASBFINT) {
+ if (xl_priv->asb_queued == 1) {
+ xl_asb_cmd(dev) ;
+ } else if (xl_priv->asb_queued == 2) {
+ xl_asb_bh(dev) ;
+ } else {
+ writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ;
+ }
+ } /* Asbf */
+
+ if (intstatus & UPCOMPINT ) /* UpComplete */
+ xl_rx(dev) ;
+
+ if (intstatus & DNCOMPINT ) /* DnComplete */
+ xl_dn_comp(dev) ;
+
+ if (intstatus & HARDERRINT ) { /* Hardware error */
+ writel(MMIO_WORD_READ | MACSTATUS, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ macstatus = readw(xl_mmio + MMIO_MACDATA) ;
+ printk(KERN_WARNING "%s: MacStatusError, details: ", dev->name);
+ if (macstatus & (1<<14))
+ printk(KERN_WARNING "tchk error: Unrecoverable error \n") ;
+ if (macstatus & (1<<3))
+ printk(KERN_WARNING "eint error: Internal watchdog timer expired \n") ;
+ if (macstatus & (1<<2))
+ printk(KERN_WARNING "aint error: Host tried to perform illegal operation \n") ;
+ printk(KERN_WARNING "Instatus = %02x, macstatus = %02x\n",intstatus,macstatus) ;
+ printk(KERN_WARNING "%s: Resetting hardware: \n", dev->name);
+ netif_stop_queue(dev) ;
+ xl_freemem(dev) ;
+ free_irq(dev->irq,dev);
+ unregister_trdev(dev) ;
+ kfree(dev) ;
+ xl_reset(dev) ;
+ writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
+ spin_unlock(&xl_priv->xl_lock) ;
+ return ;
+ }
+ } else {
+ printk(KERN_WARNING "%s: Received Unknown interrupt : %04x \n", dev->name, intstatus) ;
+ writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
+ }
+ }
+
+ /* Turn interrupts back on */
+
+ writel( SETINDENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ;
+ writel( SETINTENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ;
+
+ spin_unlock(&xl_priv->xl_lock) ;
+}
+
+/*
+ * Tx - Polling configuration
+ */
+
+static int xl_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+ struct xl_tx_desc *txd ;
+ int tx_head, tx_tail, tx_prev ;
+ unsigned long flags ;
+
+ spin_lock_irqsave(&xl_priv->xl_lock,flags) ;
+
+ netif_stop_queue(dev) ;
+
+ if (xl_priv->free_ring_entries > 1 ) {
+ /*
+ * Set up the descriptor for the packet
+ */
+ tx_head = xl_priv->tx_ring_head ;
+ tx_tail = xl_priv->tx_ring_tail ;
+
+ txd = &(xl_priv->xl_tx_ring[tx_head]) ;
+ txd->dnnextptr = 0 ;
+ txd->framestartheader = skb->len | TXDNINDICATE ;
+ txd->buffer = pci_map_single(xl_priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE) ;
+ txd->buffer_length = skb->len | TXDNFRAGLAST ;
+ xl_priv->tx_ring_skb[tx_head] = skb ;
+ xl_priv->xl_stats.tx_packets++ ;
+ xl_priv->xl_stats.tx_bytes += skb->len ;
+
+ /*
+ * Set the nextptr of the previous descriptor equal to this descriptor, add XL_TX_RING_SIZE -1
+ * to ensure no negative numbers in unsigned locations.
+ */
+
+ tx_prev = (xl_priv->tx_ring_head + XL_TX_RING_SIZE - 1) & (XL_TX_RING_SIZE - 1) ;
+
+ xl_priv->tx_ring_head++ ;
+ xl_priv->tx_ring_head &= (XL_TX_RING_SIZE - 1) ;
+ xl_priv->free_ring_entries-- ;
+
+ xl_priv->xl_tx_ring[tx_prev].dnnextptr = xl_priv->tx_ring_dma_addr + (sizeof (struct xl_tx_desc) * tx_head) ;
+
+ /* Sneaky, by doing a read on DnListPtr we can force the card to poll on the DnNextPtr */
+ /* readl(xl_mmio + MMIO_DNLISTPTR) ; */
+
+ netif_wake_queue(dev) ;
+
+ spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ;
+
+ return 0;
+ } else {
+ spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ;
+ return 1;
+ }
+
+}
+
+/*
+ * The NIC has told us that a packet has been downloaded onto the card, we must
+ * find out which packet it has done, clear the skb and information for the packet
+ * then advance around the ring for all tranmitted packets
+ */
+
+static void xl_dn_comp(struct net_device *dev)
+{
+ struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+ u8 * xl_mmio = xl_priv->xl_mmio ;
+ struct xl_tx_desc *txd ;
+
+
+ if (xl_priv->tx_ring_tail == 255) {/* First time */
+ xl_priv->xl_tx_ring[0].framestartheader = 0 ;
+ xl_priv->xl_tx_ring[0].dnnextptr = 0 ;
+ xl_priv->tx_ring_tail = 1 ;
+ }
+
+ while (xl_priv->xl_tx_ring[xl_priv->tx_ring_tail].framestartheader & TXDNCOMPLETE ) {
+ txd = &(xl_priv->xl_tx_ring[xl_priv->tx_ring_tail]) ;
+ pci_unmap_single(xl_priv->pdev,txd->buffer, xl_priv->tx_ring_skb[xl_priv->tx_ring_tail]->len, PCI_DMA_TODEVICE) ;
+ txd->framestartheader = 0 ;
+ txd->buffer = 0xdeadbeef ;
+ txd->buffer_length = 0 ;
+ dev_kfree_skb_irq(xl_priv->tx_ring_skb[xl_priv->tx_ring_tail]) ;
+ xl_priv->tx_ring_tail++ ;
+ xl_priv->tx_ring_tail &= (XL_TX_RING_SIZE - 1) ;
+ xl_priv->free_ring_entries++ ;
+ }
+
+ netif_wake_queue(dev) ;
+
+ writel(ACK_INTERRUPT | DNCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ;
+}
+
+/*
+ * Close the adapter properly.
+ * This srb reply cannot be handled from interrupt context as we have
+ * to free the interrupt from the driver.
+ */
+
+static int xl_close(struct net_device *dev)
+{
+ struct xl_private *xl_priv = (struct xl_private *) dev->priv ;
+ u8 * xl_mmio = xl_priv->xl_mmio ;
+ unsigned long t ;
+
+ netif_stop_queue(dev) ;
+
+ /*
+ * Close the adapter, need to stall the rx and tx queues.
+ */
+
+ writew(DNSTALL, xl_mmio + MMIO_COMMAND) ;
+ t=jiffies;
+ while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) {
+ schedule();
+ if(jiffies-t > 10*HZ) {
+ printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNSTALL not responding.\n", dev->name);
+ break ;
+ }
+ }
+ writew(DNDISABLE, xl_mmio + MMIO_COMMAND) ;
+ t=jiffies;
+ while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) {
+ schedule();
+ if(jiffies-t > 10*HZ) {
+ printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNDISABLE not responding.\n", dev->name);
+ break ;
+ }
+ }
+ writew(UPSTALL, xl_mmio + MMIO_COMMAND) ;
+ t=jiffies;
+ while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) {
+ schedule();
+ if(jiffies-t > 10*HZ) {
+ printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-UPSTALL not responding.\n", dev->name);
+ break ;
+ }
+ }
+
+ /* Turn off interrupts, we will still get the indication though
+ * so we can trap it
+ */
+
+ writel(SETINTENABLE, xl_mmio + MMIO_COMMAND) ;
+
+ xl_srb_cmd(dev,CLOSE_NIC) ;
+
+ t=jiffies;
+ while (!(readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_SRB)) {
+ schedule();
+ if(jiffies-t > 10*HZ) {
+ printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-CLOSENIC not responding.\n", dev->name);
+ break ;
+ }
+ }
+ /* Read the srb response from the adapter */
+
+ writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD);
+ if (readb(xl_mmio + MMIO_MACDATA) != CLOSE_NIC) {
+ printk(KERN_INFO "%s: CLOSE_NIC did not get a CLOSE_NIC response \n",dev->name) ;
+ } else {
+ writel((MEM_BYTE_READ | 0xd0000 | xl_priv->srb) +2, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ if (readb(xl_mmio + MMIO_MACDATA)==0) {
+ printk(KERN_INFO "%s: Adapter has been closed \n",dev->name) ;
+ writew(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
+
+ xl_freemem(dev) ;
+ free_irq(dev->irq,dev) ;
+ } else {
+ printk(KERN_INFO "%s: Close nic command returned error code %02x\n",dev->name, readb(xl_mmio + MMIO_MACDATA)) ;
+ }
+ }
+
+ /* Reset the upload and download logic */
+
+ writew(UPRESET, xl_mmio + MMIO_COMMAND) ;
+ t=jiffies;
+ while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) {
+ schedule();
+ if(jiffies-t > 10*HZ) {
+ printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-UPRESET not responding.\n", dev->name);
+ break ;
+ }
+ }
+ writew(DNRESET, xl_mmio + MMIO_COMMAND) ;
+ t=jiffies;
+ while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) {
+ schedule();
+ if(jiffies-t > 10*HZ) {
+ printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNRESET not responding.\n", dev->name);
+ break ;
+ }
+ }
+ xl_hw_reset(dev) ;
+ return 0 ;
+}
+
+static void xl_set_rx_mode(struct net_device *dev)
+{
+ struct xl_private *xl_priv = (struct xl_private *) dev->priv ;
+ struct dev_mc_list *dmi ;
+ unsigned char dev_mc_address[4] ;
+ u16 options ;
+ int i ;
+
+ if (dev->flags & IFF_PROMISC)
+ options = 0x0004 ;
+ else
+ options = 0x0000 ;
+
+ if (options ^ xl_priv->xl_copy_all_options) { /* Changed, must send command */
+ xl_priv->xl_copy_all_options = options ;
+ xl_srb_cmd(dev, SET_RECEIVE_MODE) ;
+ return ;
+ }
+
+ dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ;
+
+ for (i=0,dmi=dev->mc_list;i < dev->mc_count; i++,dmi = dmi->next) {
+ dev_mc_address[0] |= dmi->dmi_addr[2] ;
+ dev_mc_address[1] |= dmi->dmi_addr[3] ;
+ dev_mc_address[2] |= dmi->dmi_addr[4] ;
+ dev_mc_address[3] |= dmi->dmi_addr[5] ;
+ }
+
+ if (memcmp(xl_priv->xl_functional_addr,dev_mc_address,4) != 0) { /* Options have changed, run the command */
+ memcpy(xl_priv->xl_functional_addr, dev_mc_address,4) ;
+ xl_srb_cmd(dev, SET_FUNC_ADDRESS) ;
+ }
+ return ;
+}
+
+
+/*
+ * We issued an srb command and now we must read
+ * the response from the completed command.
+ */
+
+static void xl_srb_bh(struct net_device *dev)
+{
+ struct xl_private *xl_priv = (struct xl_private *) dev->priv ;
+ u8 * xl_mmio = xl_priv->xl_mmio ;
+ u8 srb_cmd, ret_code ;
+ int i ;
+
+ writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ srb_cmd = readb(xl_mmio + MMIO_MACDATA) ;
+ writel((MEM_BYTE_READ | 0xd0000 | xl_priv->srb) +2, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ ret_code = readb(xl_mmio + MMIO_MACDATA) ;
+
+ /* Ret_code is standard across all commands */
+
+ switch (ret_code) {
+ case 1:
+ printk(KERN_INFO "%s: Command: %d - Invalid Command code\n",dev->name,srb_cmd) ;
+ break ;
+ case 4:
+ printk(KERN_INFO "%s: Command: %d - Adapter is closed, must be open for this command \n",dev->name,srb_cmd) ;
+ break ;
+
+ case 6:
+ printk(KERN_INFO "%s: Command: %d - Options Invalid for command \n",dev->name,srb_cmd) ;
+ break ;
+
+ case 0: /* Successful command execution */
+ switch (srb_cmd) {
+ case READ_LOG: /* Returns 14 bytes of data from the NIC */
+ if(xl_priv->xl_message_level)
+ printk(KERN_INFO "%s: READ.LOG 14 bytes of data ",dev->name) ;
+ /*
+ * We still have to read the log even if message_level = 0 and we don't want
+ * to see it
+ */
+ for (i=0;i<14;i++) {
+ writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ if(xl_priv->xl_message_level)
+ printk("%02x:",readb(xl_mmio + MMIO_MACDATA)) ;
+ }
+ printk("\n") ;
+ break ;
+ case SET_FUNC_ADDRESS:
+ if(xl_priv->xl_message_level)
+ printk(KERN_INFO "%s: Functional Address Set \n",dev->name) ;
+ break ;
+ case CLOSE_NIC:
+ if(xl_priv->xl_message_level)
+ printk(KERN_INFO "%s: Received CLOSE_NIC interrupt in interrupt handler \n",dev->name) ;
+ break ;
+ case SET_MULTICAST_MODE:
+ if(xl_priv->xl_message_level)
+ printk(KERN_INFO "%s: Multicast options successfully changed\n",dev->name) ;
+ break ;
+ case SET_RECEIVE_MODE:
+ if(xl_priv->xl_message_level) {
+ if (xl_priv->xl_copy_all_options == 0x0004)
+ printk(KERN_INFO "%s: Entering promiscuous mode \n", dev->name) ;
+ else
+ printk(KERN_INFO "%s: Entering normal receive mode \n",dev->name) ;
+ }
+ break ;
+
+ } /* switch */
+ break ;
+ } /* switch */
+ return ;
+}
+
+static struct net_device_stats * xl_get_stats(struct net_device *dev)
+{
+ struct xl_private *xl_priv = (struct xl_private *) dev->priv ;
+ return (struct net_device_stats *) &xl_priv->xl_stats;
+}
+
+static int xl_set_mac_address (struct net_device *dev, void *addr)
+{
+ struct sockaddr *saddr = addr ;
+ struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
+
+ if (netif_running(dev)) {
+ printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name) ;
+ return -EIO ;
+ }
+
+ memcpy(xl_priv->xl_laa, saddr->sa_data,dev->addr_len) ;
+
+ if (xl_priv->xl_message_level) {
+ printk(KERN_INFO "%s: MAC/LAA Set to = %x.%x.%x.%x.%x.%x\n",dev->name, xl_priv->xl_laa[0],
+ xl_priv->xl_laa[1], xl_priv->xl_laa[2],
+ xl_priv->xl_laa[3], xl_priv->xl_laa[4],
+ xl_priv->xl_laa[5]);
+ }
+
+ return 0 ;
+}
+
+static void xl_arb_cmd(struct net_device *dev)
+{
+ struct xl_private *xl_priv = (struct xl_private *) dev->priv;
+ u8 * xl_mmio = xl_priv->xl_mmio ;
+ u8 arb_cmd ;
+ u16 lan_status, lan_status_diff ;
+
+ writel( ( MEM_BYTE_READ | 0xD0000 | xl_priv->arb), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ arb_cmd = readb(xl_mmio + MMIO_MACDATA) ;
+
+ if (arb_cmd == RING_STATUS_CHANGE) { /* Ring.Status.Change */
+ writel( ( (MEM_WORD_READ | 0xD0000 | xl_priv->arb) + 6), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+
+ printk(KERN_INFO "%s: Ring Status Change: New Status = %04x\n", dev->name, ntohs(readw(xl_mmio + MMIO_MACDATA) )) ;
+
+ lan_status = ntohs(readw(xl_mmio + MMIO_MACDATA));
+
+ /* Acknowledge interrupt, this tells nic we are done with the arb */
+ writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
+
+ lan_status_diff = xl_priv->xl_lan_status ^ lan_status ;
+
+ if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR) ) {
+ if (lan_status_diff & LSC_LWF)
+ printk(KERN_WARNING "%s: Short circuit detected on the lobe\n",dev->name);
+ if (lan_status_diff & LSC_ARW)
+ printk(KERN_WARNING "%s: Auto removal error\n",dev->name);
+ if (lan_status_diff & LSC_FPE)
+ printk(KERN_WARNING "%s: FDX Protocol Error\n",dev->name);
+ if (lan_status_diff & LSC_RR)
+ printk(KERN_WARNING "%s: Force remove MAC frame received\n",dev->name);
+
+ /* Adapter has been closed by the hardware */
+
+ netif_stop_queue(dev);
+ xl_freemem(dev) ;
+ free_irq(dev->irq,dev);
+
+ printk(KERN_WARNING "%s: Adapter has been closed \n", dev->name) ;
+ } /* If serious error */
+
+ if (xl_priv->xl_message_level) {
+ if (lan_status_diff & LSC_SIG_LOSS)
+ printk(KERN_WARNING "%s: No receive signal detected \n", dev->name) ;
+ if (lan_status_diff & LSC_HARD_ERR)
+ printk(KERN_INFO "%s: Beaconing \n",dev->name);
+ if (lan_status_diff & LSC_SOFT_ERR)
+ printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame \n",dev->name);
+ if (lan_status_diff & LSC_TRAN_BCN)
+ printk(KERN_INFO "%s: We are tranmitting the beacon, aaah\n",dev->name);
+ if (lan_status_diff & LSC_SS)
+ printk(KERN_INFO "%s: Single Station on the ring \n", dev->name);
+ if (lan_status_diff & LSC_RING_REC)
+ printk(KERN_INFO "%s: Ring recovery ongoing\n",dev->name);
+ if (lan_status_diff & LSC_FDX_MODE)
+ printk(KERN_INFO "%s: Operating in FDX mode\n",dev->name);
+ }
+
+ if (lan_status_diff & LSC_CO) {
+ if (xl_priv->xl_message_level)
+ printk(KERN_INFO "%s: Counter Overflow \n", dev->name);
+ /* Issue READ.LOG command */
+ xl_srb_cmd(dev, READ_LOG) ;
+ }
+
+ /* There is no command in the tech docs to issue the read_sr_counters */
+ if (lan_status_diff & LSC_SR_CO) {
+ if (xl_priv->xl_message_level)
+ printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name);
+ }
+
+ xl_priv->xl_lan_status = lan_status ;
+
+ } /* Lan.change.status */
+ else if ( arb_cmd == RECEIVE_DATA) { /* Received.Data */
+#if XL_DEBUG
+ printk(KERN_INFO "Received.Data \n") ;
+#endif
+ writel( ((MEM_WORD_READ | 0xD0000 | xl_priv->arb) + 6), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ xl_priv->mac_buffer = ntohs(readw(xl_mmio + MMIO_MACDATA)) ;
+
+ /* Now we are going to be really basic here and not do anything
+ * with the data at all. The tech docs do not give me enough
+ * information to calculate the buffers properly so we're
+ * just going to tell the nic that we've dealt with the frame
+ * anyway.
+ */
+
+ dev->last_rx = jiffies ;
+ /* Acknowledge interrupt, this tells nic we are done with the arb */
+ writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
+
+ /* Is the ASB free ? */
+
+ xl_priv->asb_queued = 0 ;
+ writel( ((MEM_BYTE_READ | 0xD0000 | xl_priv->asb) + 2), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ if (readb(xl_mmio + MMIO_MACDATA) != 0xff) {
+ xl_priv->asb_queued = 1 ;
+
+ xl_wait_misr_flags(dev) ;
+
+ writel(MEM_BYTE_WRITE | MF_ASBFR, xl_mmio + MMIO_MAC_ACCESS_CMD);
+ writeb(0xff, xl_mmio + MMIO_MACDATA) ;
+ writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(MISR_ASBFR, xl_mmio + MMIO_MACDATA) ;
+ return ;
+ /* Drop out and wait for the bottom half to be run */
+ }
+
+ xl_asb_cmd(dev) ;
+
+ } else {
+ printk(KERN_WARNING "%s: Received unknown arb (xl_priv) command: %02x \n",dev->name,arb_cmd) ;
+ }
+
+ /* Acknowledge the arb interrupt */
+
+ writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ;
+
+ return ;
+}
+
+
+/*
+ * There is only one asb command, but we can get called from different
+ * places.
+ */
+
+static void xl_asb_cmd(struct net_device *dev)
+{
+ struct xl_private *xl_priv = (struct xl_private *) dev->priv ;
+ u8 * xl_mmio = xl_priv->xl_mmio ;
+
+ if (xl_priv->asb_queued == 1)
+ writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ;
+
+ writel(MEM_BYTE_WRITE | 0xd0000 | xl_priv->asb, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(0x81, xl_mmio + MMIO_MACDATA) ;
+
+ writel(MEM_WORD_WRITE | 0xd0000 | xl_priv->asb | 6, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writew(ntohs(xl_priv->mac_buffer), xl_mmio + MMIO_MACDATA) ;
+
+ xl_wait_misr_flags(dev) ;
+
+ writel(MEM_BYTE_WRITE | MF_RASB, xl_mmio + MMIO_MAC_ACCESS_CMD);
+ writeb(0xff, xl_mmio + MMIO_MACDATA) ;
+
+ writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(MISR_RASB, xl_mmio + MMIO_MACDATA) ;
+
+ xl_priv->asb_queued = 2 ;
+
+ return ;
+}
+
+/*
+ * This will only get called if there was an error
+ * from the asb cmd.
+ */
+static void xl_asb_bh(struct net_device *dev)
+{
+ struct xl_private *xl_priv = (struct xl_private *) dev->priv ;
+ u8 * xl_mmio = xl_priv->xl_mmio ;
+ u8 ret_code ;
+
+ writel(MMIO_BYTE_READ | 0xd0000 | xl_priv->asb | 2, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ ret_code = readb(xl_mmio + MMIO_MACDATA) ;
+ switch (ret_code) {
+ case 0x01:
+ printk(KERN_INFO "%s: ASB Command, unrecognized command code \n",dev->name) ;
+ break ;
+ case 0x26:
+ printk(KERN_INFO "%s: ASB Command, unexpected receive buffer \n", dev->name) ;
+ break ;
+ case 0x40:
+ printk(KERN_INFO "%s: ASB Command, Invalid Station ID \n", dev->name) ;
+ break ;
+ }
+ xl_priv->asb_queued = 0 ;
+ writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ;
+ return ;
+}
+
+/*
+ * Issue srb commands to the nic
+ */
+
+static void xl_srb_cmd(struct net_device *dev, int srb_cmd)
+{
+ struct xl_private *xl_priv = (struct xl_private *) dev->priv ;
+ u8 * xl_mmio = xl_priv->xl_mmio ;
+
+ switch (srb_cmd) {
+ case READ_LOG:
+ writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(READ_LOG, xl_mmio + MMIO_MACDATA) ;
+ break;
+
+ case CLOSE_NIC:
+ writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(CLOSE_NIC, xl_mmio + MMIO_MACDATA) ;
+ break ;
+
+ case SET_RECEIVE_MODE:
+ writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(SET_RECEIVE_MODE, xl_mmio + MMIO_MACDATA) ;
+ writel(MEM_WORD_WRITE | 0xD0000 | xl_priv->srb | 4, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writew(xl_priv->xl_copy_all_options, xl_mmio + MMIO_MACDATA) ;
+ break ;
+
+ case SET_FUNC_ADDRESS:
+ writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(SET_FUNC_ADDRESS, xl_mmio + MMIO_MACDATA) ;
+ writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 6 , xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(xl_priv->xl_functional_addr[0], xl_mmio + MMIO_MACDATA) ;
+ writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 7 , xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(xl_priv->xl_functional_addr[1], xl_mmio + MMIO_MACDATA) ;
+ writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 8 , xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(xl_priv->xl_functional_addr[2], xl_mmio + MMIO_MACDATA) ;
+ writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 9 , xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(xl_priv->xl_functional_addr[3], xl_mmio + MMIO_MACDATA) ;
+ break ;
+ } /* switch */
+
+
+ xl_wait_misr_flags(dev) ;
+
+ /* Write 0xff to the CSRB flag */
+ writel(MEM_BYTE_WRITE | MF_CSRB , xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(0xFF, xl_mmio + MMIO_MACDATA) ;
+ /* Set csrb bit in MISR register to process command */
+ writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(MISR_CSRB, xl_mmio + MMIO_MACDATA) ;
+ xl_priv->srb_queued = 1 ;
+
+ return ;
+}
+
+/*
+ * This is nasty, to use the MISR command you have to wait for 6 memory locations
+ * to be zero. This is the way the driver does on other OS'es so we should be ok with
+ * the empty loop.
+ */
+
+static void xl_wait_misr_flags(struct net_device *dev)
+{
+ struct xl_private *xl_priv = (struct xl_private *) dev->priv ;
+ u8 * xl_mmio = xl_priv->xl_mmio ;
+
+ int i ;
+
+ writel(MMIO_BYTE_READ | MISR_RW, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ if (readb(xl_mmio + MMIO_MACDATA) != 0) { /* Misr not clear */
+ for (i=0; i<6; i++) {
+ writel(MEM_BYTE_READ | 0xDFFE0 | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ while (readb(xl_mmio + MMIO_MACDATA) != 0 ) {} ; /* Empty Loop */
+ }
+ }
+
+ writel(MMIO_BYTE_WRITE | MISR_AND, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
+ writeb(0x80, xl_mmio + MMIO_MACDATA) ;
+
+ return ;
+}
+
+/*
+ * Change mtu size, this should work the same as olympic
+ */
+
+static int xl_change_mtu(struct net_device *dev, int mtu)
+{
+ struct xl_private *xl_priv = (struct xl_private *) dev->priv;
+ u16 max_mtu ;
+
+ if (xl_priv->xl_ring_speed == 4)
+ max_mtu = 4500 ;
+ else
+ max_mtu = 18000 ;
+
+ if (mtu > max_mtu)
+ return -EINVAL ;
+ if (mtu < 100)
+ return -EINVAL ;
+
+ dev->mtu = mtu ;
+ xl_priv->pkt_buf_sz = mtu + TR_HLEN ;
+
+ return 0 ;
+}
+
+static void __devexit xl_remove_one (struct pci_dev *pdev)
+{
+ struct net_device *dev = pdev->driver_data;
+ struct xl_private *xl_priv=(struct xl_private *)dev->priv;
+
+ unregister_trdev(dev);
+ iounmap(xl_priv->xl_mmio) ;
+ pci_release_regions(pdev) ;
+ pci_set_drvdata(pdev,NULL) ;
+ kfree(dev);
+ return ;
+}
+
+static struct pci_driver xl_3c359_driver = {
+ name: "3c359",
+ id_table: xl_pci_tbl,
+ probe: xl_probe,
+ remove: __devexit_p(xl_remove_one),
+};
+
+static int __init xl_pci_init (void)
+{
+ return pci_module_init (&xl_3c359_driver);
+}
+
+
+static void __exit xl_pci_cleanup (void)
+{
+ pci_unregister_driver (&xl_3c359_driver);
+}
+
+module_init(xl_pci_init);
+module_exit(xl_pci_cleanup);
+
+MODULE_LICENSE("GPL") ;
diff --git a/drivers/net/tokenring/3c359.h b/drivers/net/tokenring/3c359.h
new file mode 100644
index 000000000000..eb3cea9f2255
--- /dev/null
+++ b/drivers/net/tokenring/3c359.h
@@ -0,0 +1,290 @@
+/*
+ * 3c359.h (c) 2000 Mike Phillips (mikep@linuxtr.net) All Rights Reserved
+ *
+ * Linux driver for 3Com 3C359 Token Link PCI XL cards.
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License Version 2 or (at your option)
+ * any later verion, incorporated herein by reference.
+ */
+
+/* Memory Access Commands */
+#define IO_BYTE_READ 0x28 << 24
+#define IO_BYTE_WRITE 0x18 << 24
+#define IO_WORD_READ 0x20 << 24
+#define IO_WORD_WRITE 0x10 << 24
+#define MMIO_BYTE_READ 0x88 << 24
+#define MMIO_BYTE_WRITE 0x48 << 24
+#define MMIO_WORD_READ 0x80 << 24
+#define MMIO_WORD_WRITE 0x40 << 24
+#define MEM_BYTE_READ 0x8C << 24
+#define MEM_BYTE_WRITE 0x4C << 24
+#define MEM_WORD_READ 0x84 << 24
+#define MEM_WORD_WRITE 0x44 << 24
+
+#define PMBAR 0x1C80
+#define PMB_CPHOLD (1<<10)
+
+#define CPATTENTION 0x180D
+#define CPA_PMBARVIS (1<<7)
+#define CPA_MEMWREN (1<<6)
+
+#define SWITCHSETTINGS 0x1C88
+#define EECONTROL 0x1C8A
+#define EEDATA 0x1C8C
+#define EEREAD 0x0080
+#define EEWRITE 0x0040
+#define EEERASE 0x0060
+#define EE_ENABLE_WRITE 0x0030
+#define EEBUSY (1<<15)
+
+#define WRBR 0xCDE02
+#define WWOR 0xCDE04
+#define WWCR 0xCDE06
+#define MACSTATUS 0xCDE08
+#define MISR_RW 0xCDE0B
+#define MISR_AND 0xCDE2B
+#define MISR_SET 0xCDE4B
+#define RXBUFAREA 0xCDE10
+#define RXEARLYTHRESH 0xCDE12
+#define TXSTARTTHRESH 0x58
+#define DNPRIREQTHRESH 0x2C
+
+#define MISR_CSRB (1<<5)
+#define MISR_RASB (1<<4)
+#define MISR_SRBFR (1<<3)
+#define MISR_ASBFR (1<<2)
+#define MISR_ARBF (1<<1)
+
+/* MISR Flags memory locations */
+#define MF_SSBF 0xDFFE0
+#define MF_ARBF 0xDFFE1
+#define MF_ASBFR 0xDFFE2
+#define MF_SRBFR 0xDFFE3
+#define MF_RASB 0xDFFE4
+#define MF_CSRB 0xDFFE5
+
+#define MMIO_MACDATA 0x10
+#define MMIO_MAC_ACCESS_CMD 0x14
+#define MMIO_TIMER 0x1A
+#define MMIO_DMA_CTRL 0x20
+#define MMIO_DNLISTPTR 0x24
+#define MMIO_HASHFILTER 0x28
+#define MMIO_CONFIG 0x29
+#define MMIO_DNPRIREQTHRESH 0x2C
+#define MMIO_DNPOLL 0x2D
+#define MMIO_UPPKTSTATUS 0x30
+#define MMIO_FREETIMER 0x34
+#define MMIO_COUNTDOWN 0x36
+#define MMIO_UPLISTPTR 0x38
+#define MMIO_UPPOLL 0x3C
+#define MMIO_UPBURSTTHRESH 0x40
+#define MMIO_DNBURSTTHRESH 0x41
+#define MMIO_INTSTATUS_AUTO 0x56
+#define MMIO_TXSTARTTHRESH 0x58
+#define MMIO_INTERRUPTENABLE 0x5A
+#define MMIO_INDICATIONENABLE 0x5C
+#define MMIO_COMMAND 0x5E /* These two are meant to be the same */
+#define MMIO_INTSTATUS 0x5E /* Makes the code more readable this way */
+#define INTSTAT_CMD_IN_PROGRESS (1<<12)
+#define INTSTAT_SRB (1<<14)
+#define INTSTAT_INTLATCH (1<<0)
+
+/* Indication / Interrupt Mask
+ * Annoyingly the bits to be set in the indication and interrupt enable
+ * do not match with the actual bits received in the interrupt, although
+ * they are in the same order.
+ * The mapping for the indication / interrupt are:
+ * Bit Indication / Interrupt
+ * 0 HostError
+ * 1 txcomplete
+ * 2 updneeded
+ * 3 rxcomplete
+ * 4 intrequested
+ * 5 macerror
+ * 6 dncomplete
+ * 7 upcomplete
+ * 8 txunderrun
+ * 9 asbf
+ * 10 srbr
+ * 11 arbc
+ *
+ * The only ones we don't want to receive are txcomplete and rxcomplete
+ * we use dncomplete and upcomplete instead.
+ */
+
+#define INT_MASK 0xFF5
+
+/* Note the subtle difference here, IND and INT */
+
+#define SETINDENABLE (8<<12)
+#define SETINTENABLE (7<<12)
+#define SRBBIT (1<<10)
+#define ASBBIT (1<<9)
+#define ARBBIT (1<<11)
+
+#define SRB 0xDFE90
+#define ASB 0xDFED0
+#define ARB 0xD0000
+#define SCRATCH 0xDFEF0
+
+#define INT_REQUEST 0x6000 /* (6 << 12) */
+#define ACK_INTERRUPT 0x6800 /* (13 <<11) */
+#define GLOBAL_RESET 0x00
+#define DNDISABLE 0x5000
+#define DNENABLE 0x4800
+#define DNSTALL 0x3002
+#define DNRESET 0x5800
+#define DNUNSTALL 0x3003
+#define UPRESET 0x2800
+#define UPSTALL 0x3000
+#define UPUNSTALL 0x3001
+#define SETCONFIG 0x4000
+#define SETTXSTARTTHRESH 0x9800
+
+/* Received Interrupts */
+#define ASBFINT (1<<13)
+#define SRBRINT (1<<14)
+#define ARBCINT (1<<15)
+#define TXUNDERRUN (1<<11)
+
+#define UPCOMPINT (1<<10)
+#define DNCOMPINT (1<<9)
+#define HARDERRINT (1<<7)
+#define RXCOMPLETE (1<<4)
+#define TXCOMPINT (1<<2)
+#define HOSTERRINT (1<<1)
+
+/* Receive descriptor bits */
+#define RXOVERRUN (1<<19)
+#define RXFC (1<<21)
+#define RXAR (1<<22)
+#define RXUPDCOMPLETE (1<<23)
+#define RXUPDFULL (1<<24)
+#define RXUPLASTFRAG (1<<31)
+
+/* Transmit descriptor bits */
+#define TXDNCOMPLETE (1<<16)
+#define TXTXINDICATE (1<<27)
+#define TXDPDEMPTY (1<<29)
+#define TXDNINDICATE (1<<31)
+#define TXDNFRAGLAST (1<<31)
+
+/* Interrupts to Acknowledge */
+#define LATCH_ACK 1
+#define TXCOMPACK (1<<1)
+#define INTREQACK (1<<2)
+#define DNCOMPACK (1<<3)
+#define UPCOMPACK (1<<4)
+#define ASBFACK (1<<5)
+#define SRBRACK (1<<6)
+#define ARBCACK (1<<7)
+
+#define XL_IO_SPACE 128
+#define SRB_COMMAND_SIZE 50
+
+/* Adapter Commands */
+#define REQUEST_INT 0x00
+#define MODIFY_OPEN_PARMS 0x01
+#define RESTORE_OPEN_PARMS 0x02
+#define OPEN_NIC 0x03
+#define CLOSE_NIC 0x04
+#define SET_SLEEP_MODE 0x05
+#define SET_GROUP_ADDRESS 0x06
+#define SET_FUNC_ADDRESS 0x07
+#define READ_LOG 0x08
+#define SET_MULTICAST_MODE 0x0C
+#define CHANGE_WAKEUP_PATTERN 0x0D
+#define GET_STATISTICS 0x13
+#define SET_RECEIVE_MODE 0x1F
+
+/* ARB Commands */
+#define RECEIVE_DATA 0x81
+#define RING_STATUS_CHANGE 0x84
+
+/* ASB Commands */
+#define ASB_RECEIVE_DATE 0x81
+
+/* Defines for LAN STATUS CHANGE reports */
+#define LSC_SIG_LOSS 0x8000
+#define LSC_HARD_ERR 0x4000
+#define LSC_SOFT_ERR 0x2000
+#define LSC_TRAN_BCN 0x1000
+#define LSC_LWF 0x0800
+#define LSC_ARW 0x0400
+#define LSC_FPE 0x0200
+#define LSC_RR 0x0100
+#define LSC_CO 0x0080
+#define LSC_SS 0x0040
+#define LSC_RING_REC 0x0020
+#define LSC_SR_CO 0x0010
+#define LSC_FDX_MODE 0x0004
+
+#define XL_MAX_ADAPTERS 8 /* 0x08 __MODULE_STRING can't hand 0xnn */
+
+/* 3c359 defaults for buffers */
+
+#define XL_RX_RING_SIZE 16 /* must be a power of 2 */
+#define XL_TX_RING_SIZE 16 /* must be a power of 2 */
+
+#define PKT_BUF_SZ 4096 /* Default packet size */
+
+/* 3c359 data structures */
+
+struct xl_tx_desc {
+ u32 dnnextptr ;
+ u32 framestartheader ;
+ u32 buffer ;
+ u32 buffer_length ;
+};
+
+struct xl_rx_desc {
+ u32 upnextptr ;
+ u32 framestatus ;
+ u32 upfragaddr ;
+ u32 upfraglen ;
+};
+
+struct xl_private {
+
+
+ /* These two structures must be aligned on 8 byte boundaries */
+
+ /* struct xl_rx_desc xl_rx_ring[XL_RX_RING_SIZE]; */
+ /* struct xl_tx_desc xl_tx_ring[XL_TX_RING_SIZE]; */
+ struct xl_rx_desc *xl_rx_ring ;
+ struct xl_tx_desc *xl_tx_ring ;
+ struct sk_buff *tx_ring_skb[XL_TX_RING_SIZE], *rx_ring_skb[XL_RX_RING_SIZE];
+ int tx_ring_head, tx_ring_tail ;
+ int rx_ring_tail, rx_ring_no ;
+ int free_ring_entries ;
+
+ u16 srb;
+ u16 arb;
+ u16 asb;
+
+ u8 *xl_mmio;
+ char *xl_card_name;
+ struct pci_dev *pdev ;
+
+ spinlock_t xl_lock ;
+
+ volatile int srb_queued;
+ struct wait_queue *srb_wait;
+ volatile int asb_queued;
+
+ struct net_device_stats xl_stats ;
+
+ u16 mac_buffer ;
+ u16 xl_lan_status ;
+ u8 xl_ring_speed ;
+ u16 pkt_buf_sz ;
+ u8 xl_message_level;
+ u16 xl_copy_all_options ;
+ unsigned char xl_functional_addr[4] ;
+ u16 xl_addr_table_addr, xl_parms_addr ;
+ u8 xl_laa[6] ;
+ u32 rx_ring_dma_addr ;
+ u32 tx_ring_dma_addr ;
+};
+
diff --git a/drivers/net/tokenring/3c359_microcode.h b/drivers/net/tokenring/3c359_microcode.h
new file mode 100644
index 000000000000..476d33f79770
--- /dev/null
+++ b/drivers/net/tokenring/3c359_microcode.h
@@ -0,0 +1,1585 @@
+
+/*
+ * The firmware this driver downloads into the tokenring card is a
+ * separate program and is not GPL'd source code, even though the Linux
+ * side driver and the routine that loads this data into the card are.
+ *
+ * This firmware is licensed to you strictly for use in conjunction
+ * with the use of 3Com 3C359 TokenRing adapters. There is no
+ * waranty expressed or implied about its fitness for any purpose.
+ */
+
+/* 3c359_microcode.mac: 3Com 3C359 Tokenring microcode.
+ *
+ * Notes:
+ * - Loaded from xl_init upon adapter initialization.
+ *
+ * Available from 3Com as part of their standard 3C359 driver.
+ *
+ * mc_size *must* must match the microcode being used, each version is a
+ * different length.
+ */
+
+
+#if defined(CONFIG_3C359) || defined(CONFIG_3C359_MODULE)
+
+static int mc_size = 24880 ;
+
+u8 microcode[] = {
+ 0xfe,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x33,0x2f,0x30,0x32,0x2f,0x39,0x39,0x20,0x31
+,0x37,0x3a,0x31,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46
+,0x00,0x00,0x07,0xff,0x02,0x00,0xfe,0x9f,0x06,0x00,0x00,0x7c,0x48,0x00,0x00,0x70
+,0x82,0x00,0xff,0xff,0x86,0x00,0xff,0xff,0x88,0x00,0xff,0xff,0x9a,0x00,0xff,0xff
+,0xff,0xff,0x11,0x00,0xc0,0x00,0xff,0xff,0xff,0xff,0x11,0x22,0x33,0x44,0x55,0x66
+,0x33,0x43,0x4f,0x4d,0x20,0x42,0x41,0x42,0x45,0x11,0x40,0xc0,0x00,0xff,0xff,0xff
+,0xff,0x11,0x22,0x33,0x44,0x55,0x66,0x53,0x74,0x61,0x72,0x74,0x20,0x6f,0x66,0x20
+,0x4c,0x4c,0x43,0x20,0x66,0x72,0x61,0x6d,0x65,0x2e,0x20,0x20,0x54,0x6f,0x74,0x61
+,0x6c,0x20,0x64,0x61,0x74,0x61,0x20,0x73,0x69,0x7a,0x65,0x20,0x69,0x73,0x20,0x78
+,0x78,0x78,0x20,0x20,0x20,0x42,0x41,0x42,0x45,0xe8,0xd2,0x01,0x83,0x3e,0xf7,0x34
+,0x00,0x75,0x21,0xe8,0x41,0x00,0x83,0x3e,0xf7,0x34,0x00,0x75,0x17,0xe8,0x82,0x00
+,0x83,0x3e,0xf7,0x34,0x00,0x75,0x0d,0xe8,0xbf,0x00,0x83,0x3e,0xf7,0x34,0x00,0x75
+,0x03,0xe8,0x41,0x02,0xc3,0x1e,0xb8,0x00,0xf0,0x8e,0xd8,0x33,0xf6,0xb9,0x00,0x80
+,0x33,0xdb,0xad,0x03,0xd8,0xe2,0xfb,0x1f,0xb8,0x00,0x00,0x83,0xfb,0x00,0x74,0x03
+,0xb8,0x22,0x00,0xa3,0xf7,0x34,0xc3,0xfa,0xba,0x56,0x00,0xb0,0xff,0xee,0x33,0xc0
+,0x8e,0xc0,0x33,0xf6,0xb9,0xff,0x7f,0x83,0x3e,0xff,0x34,0x00,0x74,0x08,0x8d,0x3e
+,0x30,0x61,0xd1,0xef,0x2b,0xcf,0x26,0x8b,0x1c,0x26,0xc7,0x04,0xff,0xff,0x26,0x83
+,0x3c,0xff,0x75,0x17,0x26,0xc7,0x04,0x00,0x00,0x26,0x83,0x3c,0x00,0x75,0x0c,0x26
+,0x89,0x1c,0x46,0x46,0xe2,0xe0,0xb8,0x00,0x00,0xeb,0x03,0xb8,0x24,0x00,0xa3,0xf7
+,0x34,0xc3,0xfa,0xb4,0xd7,0x9e,0x73,0x3a,0x75,0x38,0x79,0x36,0x7b,0x34,0x9f,0xb1
+,0x05,0xd2,0xec,0x73,0x2d,0xb0,0x40,0xd0,0xe0,0x71,0x27,0x79,0x25,0xd0,0xe0,0x73
+,0x21,0x7b,0x1f,0x32,0xc0,0x75,0x1b,0x32,0xe4,0x9e,0x72,0x16,0x74,0x14,0x78,0x12
+,0x7a,0x10,0x9f,0xd2,0xec,0x72,0x0b,0xd0,0xe4,0x70,0x07,0x75,0x05,0xb8,0x00,0x00
+,0xeb,0x03,0xb8,0x26,0x00,0xa3,0xf7,0x34,0xc3,0xfa,0xba,0x5a,0x00,0x33,0xc0,0xef
+,0xef,0xef,0xef,0xb0,0x00,0xe6,0x56,0xb0,0x00,0xe6,0x54,0xba,0x52,0x00,0xb8,0x01
+,0x01,0xef,0xe8,0xca,0x00,0x3c,0x01,0x75,0x7f,0xe8,0x83,0x00,0xba,0x52,0x00,0xb8
+,0x02,0x02,0xef,0xe8,0xb9,0x00,0x3c,0x02,0x75,0x6e,0xe8,0x7a,0x00,0xba,0x52,0x00
+,0xb8,0x04,0x04,0xef,0xe8,0xa8,0x00,0x3c,0x04,0x75,0x5d,0xe8,0x71,0x00,0xba,0x52
+,0x00,0xb8,0x08,0x08,0xef,0xe8,0x97,0x00,0x3c,0x08,0x75,0x4c,0xe8,0x68,0x00,0xba
+,0x52,0x00,0xb8,0x10,0x10,0xef,0xe8,0x86,0x00,0x3c,0x10,0x75,0x3b,0xe8,0x5f,0x00
+,0xba,0x52,0x00,0xb8,0x20,0x20,0xef,0xe8,0x75,0x00,0x3c,0x20,0x75,0x2a,0xe8,0x56
+,0x00,0xba,0x52,0x00,0xb8,0x40,0x40,0xef,0xe8,0x64,0x00,0x3c,0x40,0x75,0x19,0xe8
+,0x4d,0x00,0xba,0x52,0x00,0xb8,0x80,0x80,0xef,0xe8,0x53,0x00,0x3c,0x80,0x75,0x08
+,0xe8,0x44,0x00,0xb8,0x00,0x00,0xeb,0x03,0xb8,0x28,0x00,0xa3,0xf7,0x34,0xc3,0xba
+,0x5a,0x00,0xb8,0x00,0x80,0xef,0xc3,0xba,0x5a,0x00,0xb8,0x01,0x80,0xef,0xc3,0xba
+,0x5a,0x00,0xb8,0x02,0x80,0xef,0xc3,0xba,0x5a,0x00,0xb8,0x03,0x80,0xef,0xc3,0xba
+,0x5a,0x00,0xb8,0x04,0x80,0xef,0xc3,0xba,0x5a,0x00,0xb8,0x05,0x80,0xef,0xc3,0xba
+,0x5a,0x00,0xb8,0x06,0x80,0xef,0xc3,0xba,0x5a,0x00,0xb8,0x07,0x80,0xef,0xc3,0xb9
+,0xff,0xff,0xe4,0x58,0xe4,0x54,0x3c,0x00,0x75,0x03,0x49,0x75,0xf7,0xc3,0xfa,0x32
+,0xc0,0xe6,0x56,0xe4,0x56,0x3c,0x00,0x74,0x03,0xe9,0x82,0x00,0xb0,0xff,0xe6,0x56
+,0xe4,0x56,0x3c,0xff,0x75,0x78,0xba,0x52,0x00,0xb8,0xff,0xff,0xef,0xed,0x3c,0xff
+,0x75,0x6c,0xb8,0x00,0xff,0xef,0xed,0x3c,0x00,0x75,0x63,0xb0,0xff,0xe6,0x54,0xe4
+,0x54,0x3c,0xff,0x75,0x59,0x32,0xc0,0xe6,0x54,0xe4,0x54,0x3c,0x00,0x75,0x4f,0xb0
+,0x0f,0xe6,0x50,0xe4,0x50,0x24,0x0f,0x3c,0x0f,0x75,0x43,0xb0,0x00,0xe6,0x50,0xe4
+,0x50,0x24,0x0f,0x3c,0x00,0x75,0x37,0x8c,0xc8,0x8e,0xc0,0xbe,0x70,0x00,0x26,0x8b
+,0x14,0x26,0x8b,0x5c,0x02,0xb8,0x00,0x00,0xef,0xed,0x23,0xc3,0x3d,0x00,0x00,0x75
+,0x1d,0xb8,0xff,0xff,0x23,0xc3,0xef,0x8b,0xc8,0xed,0x23,0xc3,0x3b,0xc1,0x75,0x0e
+,0x83,0xc6,0x04,0x26,0x83,0x3c,0xff,0x75,0xd5,0xb8,0x00,0x00,0xeb,0x03,0xb8,0x2a
+,0x00,0xa3,0xf7,0x34,0xc3,0xfa,0x33,0xc0,0xbf,0x00,0x20,0xb9,0x17,0x00,0xf3,0xab
+,0xbf,0x00,0x30,0xb9,0x17,0x00,0xf3,0xab,0xbf,0x00,0x22,0xb9,0x40,0x00,0xf3,0xab
+,0xbf,0x00,0x32,0xb9,0x40,0x00,0xf3,0xab,0xfc,0x1e,0x8c,0xc8,0x8e,0xd8,0x33,0xc0
+,0x8e,0xc0,0xbe,0x92,0x00,0xbf,0x00,0x20,0xb9,0x17,0x00,0xf3,0xa4,0xbe,0xa9,0x00
+,0xbf,0x00,0x22,0xb9,0x40,0x00,0xf3,0xa4,0x1f,0xc7,0x06,0xfb,0x34,0x64,0x00,0xba
+,0x08,0x00,0xb8,0x0f,0x00,0xef,0xe8,0x82,0x01,0xe8,0x9b,0x01,0x72,0x0d,0xc7,0x06
+,0xf7,0x34,0x2c,0x00,0xc7,0x06,0xf9,0x34,0x04,0x00,0xc3,0xba,0x0a,0x00,0x33,0xc0
+,0xef,0xe8,0x98,0x01,0xe8,0xb5,0x01,0xb8,0x17,0x00,0xba,0x9c,0x00,0xef,0xb8,0x00
+,0x10,0xba,0x9a,0x00,0xef,0xb8,0x17,0x00,0xa9,0x01,0x00,0x74,0x01,0x40,0xba,0x8c
+,0x00,0xef,0xb8,0x00,0x18,0xba,0x86,0x00,0xef,0xb8,0x0c,0x00,0xba,0x82,0x00,0xef
+,0xba,0x02,0x00,0xed,0x25,0xf9,0xff,0x0d,0x02,0x00,0xef,0xba,0x06,0x00,0x33,0xc0
+,0xef,0xba,0x04,0x00,0xb8,0x60,0x00,0xef,0xba,0x00,0x00,0xb8,0x18,0x00,0xef,0xba
+,0x80,0x00,0xb9,0xff,0xff,0xed,0xa9,0x01,0x00,0x75,0x04,0xe2,0xf8,0xeb,0x3e,0xba
+,0x0a,0x00,0xed,0xa9,0x00,0x40,0x74,0x35,0xa9,0x00,0x20,0x74,0x30,0x33,0xc0,0xef
+,0x51,0xb9,0xc8,0x00,0xe2,0xfe,0x59,0x1e,0x06,0x1f,0x26,0x8b,0x0e,0x02,0x30,0x83
+,0xf9,0x17,0x75,0x18,0x49,0x49,0xbe,0x02,0x20,0xbf,0x06,0x30,0xf3,0xa6,0x1f,0x23
+,0xc9,0x75,0x0a,0xff,0x0e,0xfb,0x34,0x74,0x12,0xe9,0x4d,0xff,0x1f,0xb8,0x2c,0x00
+,0xbb,0x00,0x00,0xa3,0xf7,0x34,0x89,0x1e,0xf9,0x34,0xc3,0xc7,0x06,0xfb,0x34,0x64
+,0x00,0xe8,0xd3,0x00,0x72,0x0d,0xc7,0x06,0xf7,0x34,0x2c,0x00,0xc7,0x06,0xf9,0x34
+,0x04,0x00,0xc3,0xe8,0xd6,0x00,0xe8,0xf3,0x00,0xb8,0x03,0x00,0xba,0x82,0x00,0xef
+,0xb8,0x40,0x80,0xba,0x98,0x00,0xef,0xb8,0x00,0x11,0xba,0x96,0x00,0xef,0xb8,0x40
+,0x00,0xa9,0x01,0x00,0x74,0x01,0x40,0xba,0x92,0x00,0xef,0xb8,0x00,0x19,0xba,0x8e
+,0x00,0xef,0xba,0x02,0x00,0xed,0x25,0xf9,0xff,0x0d,0x06,0x00,0xef,0xba,0x06,0x00
+,0x33,0xc0,0xef,0xba,0x00,0x00,0xb8,0x18,0x00,0xef,0xba,0x80,0x00,0xb9,0xff,0xff
+,0xed,0xa9,0x20,0x00,0x75,0x04,0xe2,0xf8,0xeb,0x43,0xba,0x0a,0x00,0xed,0xa9,0x00
+,0x40,0x74,0x3a,0xa9,0x00,0x20,0x74,0x35,0x33,0xc0,0xef,0x51,0xb9,0xc8,0x00,0xe2
+,0xfe,0x59,0x1e,0x06,0x1f,0x26,0x8b,0x0e,0x02,0x32,0x83,0xf9,0x40,0x75,0x1d,0x49
+,0x49,0xbe,0x02,0x22,0xbf,0x06,0x32,0xf3,0xa6,0x1f,0x23,0xc9,0x75,0x0f,0xff,0x0e
+,0xfb,0x34,0x74,0x03,0xe9,0x5a,0xff,0xb8,0x00,0x00,0xeb,0x0b,0x1f,0xb8,0x2c,0x00
+,0xbb,0x02,0x00,0x89,0x1e,0xf9,0x34,0xa3,0xf7,0x34,0xc3,0xba,0x02,0x00,0xb8,0x00
+,0x9c,0xef,0xba,0x00,0x00,0xb8,0x00,0x84,0xef,0x33,0xc0,0xef,0xba,0x0a,0x00,0xef
+,0xba,0x0e,0x00,0x33,0xc0,0xef,0xc3,0xba,0x0a,0x00,0xb9,0xff,0xff,0xed,0x25,0x00
+,0x60,0x3d,0x00,0x60,0x74,0x04,0xe2,0xf5,0xf8,0xc3,0xf9,0xc3,0xb0,0x00,0xe6,0x56
+,0xb8,0x00,0xff,0xba,0x52,0x00,0xef,0xb9,0xff,0xff,0xba,0x58,0x00,0xed,0x25,0xef
+,0x00,0x74,0x08,0xba,0x5a,0x00,0x33,0xc0,0xef,0xe2,0xef,0xc3,0xba,0x80,0x00,0xed
+,0xba,0x84,0x00,0xef,0xba,0x80,0x00,0xed,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0xc6,0x06,0xec,0x34,0x15,0x33,0xc0,0x8e,0xd8,0x8e,0xc0,0x1e,0x8c,0xc8,0xbe,0x40
+,0x54,0xbf,0x60,0xfe,0x8e,0xd8,0xb9,0x10,0x00,0xf3,0xa4,0x1f,0xc7,0x06,0x80,0x36
+,0x10,0x35,0xc7,0x06,0x8c,0x36,0x30,0x35,0x8d,0x06,0x38,0x35,0xa3,0x30,0x35,0xa3
+,0x32,0x35,0x05,0x33,0x01,0xa3,0x34,0x35,0xc7,0x06,0x36,0x35,0x50,0x01,0xc7,0x06
+,0x84,0x36,0x80,0xfe,0xc7,0x06,0x88,0x36,0xc0,0xfe,0xc6,0x06,0xc2,0xfe,0xff,0xc6
+,0x06,0x93,0x36,0x80,0xc6,0x06,0x92,0x36,0x00,0xc6,0x06,0x80,0xfe,0x80,0xc7,0x06
+,0x82,0xfe,0x54,0x50,0xc7,0x06,0x84,0xfe,0x2b,0x4d,0xe5,0xce,0xa9,0x02,0x00,0x75
+,0x08,0xc6,0x06,0x81,0xfe,0x23,0xe9,0x05,0x00,0xc6,0x06,0x81,0xfe,0x22,0xa1,0xf7
+,0x34,0xa3,0x86,0xfe,0xb8,0x48,0x34,0x86,0xe0,0xa3,0x88,0xfe,0x8d,0x06,0x4e,0x34
+,0x86,0xe0,0xa3,0x8a,0xfe,0xb8,0x58,0x34,0x86,0xe0,0xa3,0x8c,0xfe,0xb8,0x9c,0x34
+,0x86,0xe0,0xa3,0x8e,0xfe,0x8d,0x06,0x20,0x03,0x86,0xe0,0xa3,0x90,0xfe,0x33,0xc0
+,0xba,0x72,0x00,0xef,0x33,0xc0,0xba,0x74,0x00,0xef,0xba,0x76,0x00,0xef,0xb8,0x80
+,0xfe,0x86,0xe0,0xba,0x72,0x00,0xef,0xe8,0xbf,0x07,0xba,0x0c,0x01,0xb8,0x40,0x40
+,0xef,0xed,0xba,0x6a,0x00,0xb8,0x03,0x00,0xc1,0xe0,0x08,0x0d,0x03,0x00,0xef,0xb9
+,0x0a,0x00,0xe8,0x94,0x00,0xba,0x6a,0x00,0xb8,0x03,0x00,0xc1,0xe0,0x08,0xef,0xa1
+,0x32,0x34,0xa3,0xa2,0x33,0xc7,0x06,0xa6,0x33,0x04,0x00,0x8d,0x06,0xa0,0x33,0xc1
+,0xe8,0x04,0xcd,0x39,0xc7,0x06,0x90,0x36,0xff,0xff,0xe9,0xe3,0x00,0x63,0x0d,0x66
+,0x0d,0x66,0x0d,0x8a,0x0d,0xe6,0x0e,0x75,0x12,0x2e,0x0f,0x03,0x0f,0x50,0x0f,0x60
+,0x0d,0x60,0x0d,0x60,0x0d,0xed,0x0f,0xe9,0x12,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60
+,0x0d,0x60,0x0d,0x22,0x10,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0xfe,0x10,0x60
+,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0xaf,0x0f,0x32,0x10,0x37
+,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60
+,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60
+,0x0d,0x64,0x0e,0x00,0x0f,0x95,0x09,0x60,0x0a,0x49,0xbb,0xff,0xff,0xba,0x6a,0x00
+,0xed,0xa9,0x00,0x20,0x74,0x38,0x80,0x3e,0x80,0xfe,0x12,0x75,0x31,0xe8,0x4a,0x00
+,0xa1,0x32,0x34,0xa3,0xa2,0x33,0xc7,0x06,0xa6,0x33,0x04,0x00,0x8d,0x06,0xa0,0x33
+,0xc1,0xe8,0x04,0xcd,0x39,0xe8,0x22,0x00,0xc7,0x06,0xf3,0x34,0x46,0x00,0xc7,0x06
+,0xf5,0x34,0xff,0xff,0xc7,0x06,0x90,0x36,0xff,0xff,0x58,0xe9,0x32,0x00,0x4b,0x83
+,0xfb,0x00,0x75,0xb9,0x83,0xf9,0x00,0x75,0xb0,0xc3,0x52,0xba,0x6a,0x00,0xb8,0x03
+,0x00,0xc1,0xe0,0x08,0x0d,0x03,0x00,0xef,0x5a,0xc3,0x52,0xba,0x6a,0x00,0xb8,0x03
+,0x00,0xc1,0xe0,0x08,0xef,0x5a,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x68,0x80,0x07,0xa1,0x90,0x36,0xcd,0x35,0x8b,0x36,0x24,0x02,0x2e,0xff,0xa4,0x35
+,0x0a,0xfa,0x8a,0x26,0x94,0x36,0x88,0x26,0xe8,0x34,0xc6,0x06,0x94,0x36,0x00,0xfb
+,0x22,0xe4,0x75,0x01,0xc3,0xf6,0xc4,0x20,0x74,0x7d,0xf6,0xc4,0x08,0x74,0x05,0x80
+,0x0e,0x92,0x36,0x04,0x80,0x26,0xe8,0x34,0xd7,0xc4,0x1e,0x84,0x36,0x26,0x8b,0x37
+,0x81,0xe6,0xff,0x00,0x83,0xfe,0x20,0x76,0x05,0xb0,0x01,0xe9,0x28,0x00,0x53,0x06
+,0xd1,0xe6,0x2e,0xff,0x94,0x9d,0x06,0x07,0x5b,0x26,0x88,0x47,0x02,0x3c,0xff,0x74
+,0x07,0x3c,0xfe,0x75,0x11,0xe9,0x3b,0x00,0xf6,0x06,0x92,0x36,0x08,0x75,0x34,0xf6
+,0x06,0x92,0x36,0x04,0x74,0x2d,0x80,0x26,0x92,0x36,0xf3,0x80,0x3e,0x95,0x36,0x00
+,0x75,0x21,0x26,0x80,0x3f,0x05,0x75,0x13,0xc6,0x06,0x95,0x36,0x00,0x26,0x80,0x7f
+,0x06,0x00,0x74,0x07,0x26,0x8b,0x47,0x04,0xa2,0x95,0x36,0xba,0x0c,0x01,0xb8,0x40
+,0x40,0xef,0xed,0x8a,0x26,0xe8,0x34,0xf6,0xc4,0x10,0x75,0x03,0xe9,0x5b,0x00,0xf6
+,0xc4,0x04,0x74,0x05,0x80,0x0e,0x92,0x36,0x01,0x80,0x26,0xe8,0x34,0xeb,0xc4,0x3e
+,0x88,0x36,0x26,0x8b,0x35,0x83,0xe6,0x7f,0x83,0xfe,0x12,0x72,0x08,0x26,0xc6,0x45
+,0x02,0x01,0xe9,0x24,0x00,0x83,0xc6,0x20,0xd1,0xe6,0x2e,0xff,0x94,0x9d,0x06,0xc4
+,0x3e,0x88,0x36,0x26,0x88,0x45,0x02,0x3c,0xff,0x75,0x0e,0xf6,0x06,0x92,0x36,0x01
+,0x74,0x14,0xf6,0x06,0x92,0x36,0x02,0x75,0x0d,0x80,0x26,0x92,0x36,0xfc,0xba,0x0c
+,0x01,0xb8,0x20,0x20,0xef,0xed,0x8a,0x26,0xe8,0x34,0xf6,0xc4,0x08,0x74,0x22,0x80
+,0x26,0xe8,0x34,0xf7,0x80,0x0e,0x92,0x36,0x04,0xf6,0x06,0x92,0x36,0x08,0x74,0x11
+,0x80,0x26,0x92,0x36,0xf3,0xba,0x0c,0x01,0xb8,0x40,0x40,0xef,0xed,0x8a,0x26,0xe8
+,0x34,0xf6,0xc4,0x04,0x74,0x22,0x80,0x26,0xe8,0x34,0xfb,0x80,0x0e,0x92,0x36,0x01
+,0xf6,0x06,0x92,0x36,0x02,0x75,0x11,0x80,0x26,0x92,0x36,0xfe,0xba,0x0c,0x01,0xb8
+,0x20,0x20,0xef,0xed,0x8a,0x26,0xe8,0x34,0xf6,0xc4,0x01,0x74,0x67,0x80,0x26,0xe8
+,0x34,0xfe,0x80,0x3e,0xe8,0xff,0x00,0x74,0x39,0x80,0x3e,0xe8,0xff,0x04,0x74,0x32
+,0x80,0x3e,0xe8,0xff,0x01,0x75,0x21,0xe5,0x80,0xa9,0x00,0x07,0x74,0x0a,0xba,0x9e
+,0x00,0xb8,0x00,0x02,0xef,0xe9,0xef,0xff,0xc6,0x06,0xe8,0xff,0x03,0xba,0x0c,0x01
+,0xb8,0x08,0x08,0xef,0xed,0xe9,0x28,0x00,0x80,0x3e,0xe8,0xff,0x03,0x74,0x06,0xe9
+,0x1e,0x00,0xe9,0x00,0x00,0xba,0x10,0x01,0xb8,0x02,0x02,0xef,0xed,0xe5,0x00,0x0d
+,0x18,0x00,0xe7,0x00,0xe5,0x82,0x0d,0x02,0x00,0xe7,0x82,0xc6,0x06,0xe8,0xff,0x04
+,0x8a,0x26,0xe8,0x34,0xf6,0xc4,0x02,0x74,0x0d,0x80,0x26,0xe8,0x34,0xfd,0x80,0x26
+,0x92,0x36,0xbf,0xe8,0x4f,0x0b,0xfa,0xa0,0xe8,0x34,0x08,0x06,0x94,0x36,0xc6,0x06
+,0xe8,0x34,0x00,0xfb,0xc3,0xe8,0xe7,0x0f,0xc4,0x1e,0x84,0x36,0x2e,0xff,0x16,0x01
+,0x07,0x26,0x88,0x47,0x02,0xe9,0x7e,0xfe,0xe8,0x2d,0x10,0xc4,0x1e,0x84,0x36,0x2e
+,0xff,0x16,0x03,0x07,0x26,0x88,0x47,0x02,0xe9,0x6b,0xfe,0x8e,0x06,0x26,0x02,0x2e
+,0xff,0x16,0x07,0x07,0xc3,0xc3,0x83,0x3e,0xf5,0x34,0x00,0x74,0x0f,0xff,0x0e,0xf3
+,0x34,0x75,0x09,0xe8,0xc4,0xfd,0xc7,0x06,0xf5,0x34,0x00,0x00,0xf6,0x06,0x93,0x36
+,0x20,0x74,0x30,0xa1,0xc2,0x34,0x3b,0x06,0xe9,0x34,0xa3,0xe9,0x34,0x74,0x24,0x80
+,0x3e,0x95,0x36,0x00,0x75,0x1d,0xf7,0x06,0xe6,0x34,0x20,0x00,0x74,0x12,0xa9,0x20
+,0x00,0x74,0x0d,0x83,0x26,0xc2,0x34,0xdf,0x83,0x26,0xe9,0x34,0xdf,0xe9,0x03,0x00
+,0xe8,0xdd,0x09,0xba,0x06,0x01,0xed,0x8b,0xd0,0x81,0xe2,0x00,0xc0,0xc1,0xea,0x0e
+,0x03,0x16,0x74,0x34,0xc1,0xe0,0x02,0x11,0x06,0x72,0x34,0x73,0x04,0xff,0x06,0x74
+,0x34,0xba,0x02,0x01,0xed,0x8b,0xd0,0x81,0xe2,0x00,0xc0,0xc1,0xea,0x0e,0x03,0x16
+,0x70,0x34,0xc1,0xe0,0x02,0x11,0x06,0x6e,0x34,0x73,0x04,0xff,0x06,0x70,0x34,0xc7
+,0x06,0xa6,0x33,0x04,0x00,0xc7,0x06,0xaa,0x33,0x00,0x00,0x8d,0x06,0xa0,0x33,0xc1
+,0xe8,0x04,0xcd,0x39,0xc3,0x95,0x09,0x95,0x09,0x65,0x09,0x78,0x09,0x95,0x09,0x95
+,0x09,0x91,0x07,0x95,0x09,0x96,0x09,0x8b,0x09,0x95,0x09,0x95,0x09,0x95,0x09,0x95
+,0x09,0x95,0x09,0x95,0x09,0x8b,0xc0,0x8b,0xc0,0x8b,0xc0,0x8b,0xc0,0x8b,0xc0,0x90
+,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xe9,0xcc,0x00,0x8c,0xc0,0x40,0x8e,0xc0,0x26
+,0x8b,0x0e,0x06,0x00,0x86,0xe9,0x26,0x89,0x0e,0x06,0x00,0x8c,0xc2,0xc1,0xe2,0x04
+,0xbe,0x0e,0x00,0x26,0xa1,0x04,0x00,0xd0,0xe0,0x24,0xc0,0x8a,0xe0,0xc0,0xec,0x04
+,0x0a,0xc4,0x26,0xa2,0x05,0x00,0x26,0xa1,0x08,0x00,0xa9,0x00,0xc0,0x74,0x03,0xe9
+,0x9e,0x00,0x26,0xf6,0x06,0x10,0x00,0x80,0x75,0x03,0xe9,0x0a,0x00,0x26,0xa0,0x16
+,0x00,0x24,0x1f,0x32,0xe4,0x03,0xf0,0x80,0x3e,0xec,0x34,0x06,0x72,0x5c,0x80,0x3e
+,0x95,0x36,0x00,0x75,0x66,0x8b,0xfa,0x33,0xdb,0x8e,0xc3,0x26,0x89,0x1d,0x26,0x88
+,0x5d,0x04,0x51,0x50,0xc4,0x1e,0x8c,0x36,0xb9,0x0f,0x00,0x33,0xc0,0xe8,0x21,0x09
+,0x58,0x59,0x0b,0xdb,0x74,0x34,0xfe,0x0e,0xe6,0x3a,0x26,0xc6,0x07,0x81,0x26,0xc6
+,0x47,0x01,0x00,0x26,0xc6,0x47,0x02,0xff,0x26,0xc7,0x47,0x04,0x00,0x00,0x26,0x89
+,0x4f,0x0a,0x86,0xf2,0x26,0x89,0x57,0x06,0x26,0x89,0x77,0x08,0x26,0xc6,0x47,0x09
+,0x00,0x26,0xc6,0x47,0x0c,0x02,0xe8,0x8c,0x09,0xc3,0xff,0x06,0xec,0x33,0x8c,0xc0
+,0x48,0x8e,0xc0,0xfa,0xe8,0x97,0x10,0xfb,0xe9,0xeb,0xff,0x8c,0xc0,0x48,0x8e,0xc0
+,0xfa,0xe8,0x8a,0x10,0xfb,0xc3,0x8c,0xc0,0x8e,0xc0,0xfa,0xe8,0x80,0x10,0xfb,0xc3
+,0x80,0x3e,0x95,0x36,0x00,0x75,0x03,0xe9,0xc2,0x00,0xbf,0x08,0x00,0x26,0xf6,0x06
+,0x10,0x00,0x80,0x75,0x05,0x03,0xfe,0xe9,0x0c,0x00,0x26,0xa0,0x16,0x00,0x24,0x1f
+,0x32,0xe4,0x03,0xf0,0x03,0xfe,0xa0,0x95,0x36,0x3c,0x00,0x75,0x03,0xe9,0x9c,0x00
+,0x3c,0x01,0x74,0x0b,0x3c,0x02,0x74,0x14,0x3c,0x03,0x74,0x1d,0xe9,0x8d,0x00,0xc6
+,0x06,0x96,0x36,0x01,0xe8,0x3c,0x01,0x72,0x27,0xe9,0x80,0x00,0xc6,0x06,0x96,0x36
+,0x02,0xe8,0x83,0x00,0x72,0x1a,0xe9,0x73,0x00,0xc6,0x06,0x96,0x36,0x01,0xe8,0x22
+,0x01,0x72,0x0d,0xc6,0x06,0x96,0x36,0x02,0xe8,0x6c,0x00,0x72,0x03,0xe9,0x5c,0x00
+,0x53,0x06,0x50,0xc4,0x1e,0x8c,0x36,0xb9,0x0b,0x00,0x33,0xc0,0xe8,0x42,0x08,0x58
+,0x26,0xc6,0x07,0x82,0x26,0xc6,0x47,0x02,0xff,0x8d,0x06,0xe0,0xfe,0x86,0xc4,0x26
+,0x89,0x47,0x06,0xa0,0x96,0x36,0x26,0x88,0x47,0x08,0xe8,0xc8,0x08,0x07,0x5b,0x83
+,0x26,0xad,0x36,0xfe,0xa1,0xad,0x36,0xe7,0x04,0xba,0x10,0x01,0xb8,0x80,0x80,0xef
+,0xed,0xba,0x10,0x01,0xb8,0x02,0x02,0xef,0xed,0x52,0xba,0xe0,0x00,0xb8,0x41,0x10
+,0xef,0x5a,0xb8,0x9c,0x03,0xcd,0x39,0xc6,0x06,0x95,0x36,0x00,0x8c,0xc0,0x48,0x8e
+,0xc0,0xfa,0xe8,0xa9,0x0f,0xfb,0xc3,0x1e,0x06,0x1f,0x06,0x33,0xc0,0x8e,0xc0,0x8b
+,0xf0,0x8d,0x3e,0x20,0xf3,0x51,0xb1,0x0a,0x26,0x83,0x7d,0x0c,0x01,0x75,0x2a,0x57
+,0x26,0x83,0x7d,0x0e,0x00,0x74,0x06,0xe8,0x2f,0x00,0xe9,0x03,0x00,0xe8,0x66,0x07
+,0x5f,0x73,0x16,0x33,0xc0,0x8e,0xd8,0x26,0x8b,0x4d,0x12,0x8d,0x75,0x20,0x8d,0x3e
+,0xe0,0xfe,0xf3,0xa4,0x59,0x07,0x1f,0xf9,0xc3,0xfe,0xc9,0x74,0x07,0x81,0xc7,0x20
+,0x01,0xe9,0xc4,0xff,0x59,0x07,0x1f,0xf8,0xc3,0x51,0x50,0x53,0x56,0x52,0x57,0x33
+,0xdb,0x26,0x8a,0x5d,0x0e,0x26,0x8b,0x4d,0x12,0x8d,0x7d,0x20,0x5a,0x87,0xd7,0x26
+,0x8a,0x45,0x14,0x87,0xd7,0x42,0x32,0xff,0x80,0xff,0x08,0x75,0x08,0xfe,0xcb,0x22
+,0xdb,0x75,0xea,0x33,0xdb,0x23,0xdb,0x74,0x06,0xfe,0xc7,0xd0,0xc8,0x73,0x0c,0x50
+,0x26,0x8a,0x05,0x38,0x04,0x58,0x74,0x03,0xe9,0x0a,0x00,0x49,0x46,0x47,0x23,0xc9
+,0x74,0x0a,0xe9,0xd3,0xff,0x5a,0x5e,0x5b,0x58,0x59,0xf8,0xc3,0x5a,0x5e,0x5b,0x58
+,0x59,0xf9,0xc3,0x1e,0x06,0x1f,0x06,0x33,0xc0,0x8e,0xc0,0x86,0xcd,0x2b,0xce,0x8b
+,0xf7,0x8b,0xc1,0x33,0xc9,0x80,0x3c,0xff,0x74,0x16,0x80,0xf9,0x06,0x73,0x09,0x32
+,0xc9,0x46,0x48,0x74,0x2e,0xe9,0xed,0xff,0x3d,0x60,0x00,0x73,0x0c,0xe9,0x23,0x00
+,0xfe,0xc1,0x46,0x48,0x74,0x1d,0xe9,0xdc,0xff,0xb8,0x10,0x00,0x8d,0x3e,0x18,0x34
+,0x32,0xed,0xb1,0x06,0xf3,0xa6,0x74,0x03,0xe9,0x08,0x00,0x48,0x23,0xc0,0x74,0x07
+,0xe9,0xe9,0xff,0x07,0x1f,0xf8,0xc3,0x8d,0x36,0x18,0x34,0x33,0xc0,0x8e,0xd8,0x8d
+,0x3e,0xe0,0xfe,0xb8,0x10,0x00,0xb9,0x06,0x00,0x56,0xf3,0xa4,0x5e,0x48,0x3d,0x00
+,0x00,0x75,0xf3,0x07,0x1f,0xf9,0xc3,0xff,0x06,0xe4,0x33,0xc6,0x06,0xeb,0x34,0x00
+,0x26,0x8b,0x45,0x06,0x86,0xe0,0xc1,0xe8,0x04,0x48,0x06,0x8e,0xc0,0xfe,0x06,0xe6
+,0x3a,0xfa,0xe8,0x69,0x0e,0xfb,0x07,0xb0,0xff,0xc3,0x00,0x00,0x00,0x00,0x00,0x00
+,0xb0,0x01,0xc3,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3
+,0x8b,0x0e,0x97,0x36,0x81,0xe1,0x80,0x30,0x26,0x8b,0x47,0x04,0x25,0x7f,0xcf,0x0b
+,0xc1,0xa3,0x97,0x36,0xa3,0xe6,0x34,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x74
+,0x03,0xb0,0x03,0xc3,0x26,0x8b,0x47,0x08,0xa3,0x97,0x36,0xa3,0xe6,0x34,0x26,0x8a
+,0x47,0x20,0xa2,0xfd,0x34,0x3c,0x01,0x75,0x06,0xc7,0x06,0xa1,0x36,0x00,0x00,0x26
+,0x8a,0x47,0x21,0xa2,0xfe,0x34,0x26,0x8b,0x47,0x0a,0xa3,0x18,0x34,0xa3,0x58,0x34
+,0x26,0x8b,0x47,0x0c,0xa3,0x1a,0x34,0xa3,0x5a,0x34,0x26,0x8b,0x47,0x0e,0xa3,0x1c
+,0x34,0xa3,0x5c,0x34,0xc6,0x06,0x2a,0x34,0xc0,0x26,0x8b,0x47,0x14,0x25,0x7f,0xff
+,0x09,0x06,0x2c,0x34,0x26,0x8b,0x47,0x16,0x25,0xff,0xfe,0x25,0xff,0xfc,0x09,0x06
+,0x2e,0x34,0xc6,0x06,0x00,0x34,0xc0,0x26,0x8b,0x47,0x10,0xa3,0x02,0x34,0x26,0x8b
+,0x47,0x12,0xa3,0x04,0x34,0x06,0x53,0xe8,0x84,0x0a,0x5b,0x07,0x3d,0x00,0x00,0x75
+,0x07,0x80,0x0e,0x92,0x36,0x08,0xb0,0xfe,0xc3,0xb9,0x00,0x01,0xa1,0xac,0x33,0x33
+,0xd2,0xf7,0xf9,0xa3,0xae,0x33,0x91,0x49,0x33,0xd2,0xf7,0xe9,0x05,0x00,0x3b,0xa3
+,0x46,0x34,0xbf,0x00,0x3b,0x89,0x3e,0x44,0x34,0xba,0x68,0x00,0xb8,0xe0,0xe0,0xef
+,0xa1,0xae,0x33,0xe7,0x62,0xa1,0xae,0x33,0xba,0x08,0x01,0xef,0xa1,0x44,0x34,0xe7
+,0x64,0xa1,0x44,0x34,0xba,0x0a,0x01,0xef,0xb8,0x00,0x01,0x2d,0x04,0x00,0x0d,0x00
+,0x10,0xe7,0x92,0xc3,0x3d,0x00,0x00,0x74,0x0a,0x26,0x89,0x47,0x07,0xe8,0x83,0x3a
+,0xb0,0x07,0xc3,0xa1,0xae,0x33,0x26,0x89,0x47,0x2b,0xa1,0x44,0x34,0x26,0x89,0x47
+,0x2d,0xa1,0x46,0x34,0x26,0x89,0x47,0x2f,0x80,0x0e,0x93,0x36,0x20,0xa1,0x88,0x36
+,0x86,0xe0,0x26,0x89,0x47,0x08,0xa1,0x84,0x36,0x86,0xe0,0x26,0x89,0x47,0x0a,0xa1
+,0x80,0x36,0x86,0xe0,0x26,0x89,0x47,0x0c,0xb8,0x60,0xfe,0x86,0xe0,0x26,0x89,0x47
+,0x0e,0xa0,0xa1,0x36,0x26,0x88,0x47,0x10,0x8b,0x36,0x88,0x36,0x26,0xc6,0x44,0x02
+,0xff,0xe5,0x9e,0xa9,0x00,0x08,0x74,0x0c,0xba,0x84,0x00,0xed,0x0d,0x08,0x00,0xef
+,0xba,0x8e,0x00,0xef,0xe5,0x02,0x25,0xf9,0xff,0xe7,0x02,0xba,0x10,0x01,0xb8,0x02
+,0x02,0xef,0xed,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x01,0xc3
+,0x80,0x26,0x93,0x36,0x9f,0xe8,0x8d,0x0a,0x80,0x0e,0x92,0x36,0x08,0xb0,0xfe,0xc3
+,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0xc6,0x06,0x2a
+,0x34,0xc0,0x26,0x8b,0x47,0x06,0x25,0x7f,0xff,0xa3,0x2c,0x34,0x26,0x8b,0x47,0x08
+,0x25,0xff,0xfe,0x25,0xff,0xfc,0xa3,0x2e,0x34,0xcd,0x52,0xb0,0x00,0xc3,0xf6,0x06
+,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0xc6,0x06,0x00,0x34,0xc0,0x26,0x8b,0x47
+,0x06,0xa3,0x02,0x34,0x26,0x8b,0x47,0x08,0xa3,0x04,0x34,0xcd,0x52,0xb0,0x00,0xc3
+,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0x57,0x8d,0x7f,0x06,0x51,0xb9
+,0x07,0x00,0x33,0xc0,0xf3,0xab,0x59,0x8d,0x7f,0x06,0xa1,0x7a,0x34,0x03,0x06,0x39
+,0x37,0x26,0x88,0x05,0xa1,0x95,0x37,0x26,0x88,0x45,0x02,0xa1,0x80,0x34,0x03,0x06
+,0x76,0x34,0x26,0x88,0x45,0x07,0xa1,0xc6,0x34,0x26,0x88,0x45,0x09,0xa1,0xd8,0x33
+,0x26,0x88,0x45,0x0a,0x33,0xc0,0xa3,0x7a,0x34,0xa3,0x39,0x37,0xa3,0x95,0x37,0xa3
+,0x80,0x34,0xa3,0x76,0x34,0xa3,0xc6,0x34,0xa3,0xd8,0x33,0x5f,0xb0,0x00,0xc3,0xf6
+,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0x26,0x8b,0x4f,0x04,0x83,0xf9,0x06
+,0x74,0x12,0x83,0xf9,0x04,0x74,0x0d,0x83,0xf9,0x00,0x74,0x08,0x83,0xf9,0x02,0x74
+,0x03,0xb0,0x01,0xc3,0x89,0x0e,0xe8,0x3a,0x83,0x26,0xab,0x36,0xf9,0x09,0x0e,0xab
+,0x36,0xe5,0x02,0x25,0xf9,0xff,0x0b,0xc1,0xe7,0x02,0xb0,0x00,0xc3,0xf6,0x06,0x93
+,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0x26,0x8b,0x4f,0x04,0x80,0xf9,0xff,0x74,0x08
+,0x80,0xf9,0x00,0x74,0x10,0xb0,0x01,0xc3,0x83,0x0e,0xad,0x36,0x02,0xa1,0xad,0x36
+,0xe7,0x04,0xe9,0x0a,0x00,0x83,0x26,0xad,0x36,0xfd,0xa1,0xad,0x36,0xe7,0x04,0xb0
+,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0xe8,0xd5,0x04,0xb0
+,0x00,0xc3,0xf6,0x06,0x93,0x36,0x80,0x75,0x03,0xb0,0x01,0xc3,0x26,0x83,0x7f,0x06
+,0x05,0x75,0x03,0xe9,0x9d,0x00,0x26,0x8b,0x57,0x04,0x26,0x8b,0x47,0x08,0x26,0x81
+,0x7f,0x06,0x00,0x80,0x75,0x08,0xed,0x26,0x89,0x47,0x0a,0xe9,0x9d,0x00,0x26,0x83
+,0x7f,0x06,0x01,0x75,0x04,0xef,0xe9,0x92,0x00,0x26,0x81,0x7f,0x06,0x01,0x80,0x75
+,0x09,0xef,0xed,0x26,0x89,0x47,0x0a,0xe9,0x81,0x00,0x26,0x83,0x7f,0x06,0x02,0x75
+,0x07,0x26,0x21,0x47,0x04,0xe9,0x73,0x00,0x26,0x81,0x7f,0x06,0x02,0x80,0x75,0x0c
+,0x26,0x21,0x47,0x04,0xed,0x26,0x89,0x47,0x0a,0xe9,0x5f,0x00,0x26,0x83,0x7f,0x06
+,0x03,0x75,0x07,0x26,0x09,0x47,0x04,0xe9,0x51,0x00,0x26,0x81,0x7f,0x06,0x03,0x80
+,0x75,0x0c,0x26,0x09,0x47,0x04,0xed,0x26,0x89,0x47,0x0a,0xe9,0x3d,0x00,0x26,0x83
+,0x7f,0x06,0x04,0x75,0x07,0x26,0x31,0x47,0x04,0xe9,0x2f,0x00,0x26,0x81,0x7f,0x06
+,0x04,0x80,0x75,0x0c,0x26,0x31,0x47,0x04,0xed,0x26,0x89,0x47,0x0a,0xe9,0x1b,0x00
+,0xb0,0x01,0xc3,0xfa,0x53,0x26,0x8b,0x4f,0x08,0x0b,0xc9,0x74,0x0c,0x8d,0x1e,0xe0
+,0xfe,0xe8,0x52,0xff,0x83,0xc3,0x08,0xe2,0xf8,0x5b,0xfb,0xb0,0x00,0xc3,0xf6,0x06
+,0x93,0x36,0x80,0x75,0x0a,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x01,0xc3,0x8d
+,0x3e,0xe0,0xfe,0xe5,0x00,0x26,0x89,0x05,0xe5,0x02,0x26,0x89,0x45,0x02,0xa1,0xad
+,0x36,0x26,0x89,0x45,0x04,0xe5,0x06,0x26,0x89,0x45,0x06,0xe5,0x08,0x26,0x89,0x45
+,0x08,0xe5,0x0a,0x26,0x89,0x45,0x0a,0xe5,0x0e,0x26,0x89,0x45,0x0c,0xe5,0x48,0x26
+,0x89,0x45,0x0e,0xe5,0x4a,0x26,0x89,0x45,0x10,0xe5,0x4c,0x26,0x89,0x45,0x12,0xa1
+,0xb7,0x36,0x26,0x89,0x45,0x14,0xe5,0x50,0x26,0x89,0x45,0x16,0xe5,0x52,0x26,0x89
+,0x45,0x18,0xe5,0x54,0x26,0x89,0x45,0x1a,0xe5,0x56,0x26,0x89,0x45,0x1c,0xe5,0x58
+,0x26,0x89,0x45,0x1e,0xe5,0x62,0x26,0x89,0x45,0x20,0xe5,0x64,0x26,0x89,0x45,0x22
+,0xe5,0x66,0x26,0x89,0x45,0x24,0xe5,0x68,0x26,0x89,0x45,0x26,0xe5,0x6a,0x26,0x89
+,0x45,0x28,0xe5,0x6c,0x26,0x89,0x45,0x2a,0xe5,0x70,0x26,0x89,0x45,0x2c,0xe5,0x72
+,0x26,0x89,0x45,0x2e,0xe5,0x74,0x26,0x89,0x45,0x30,0xe5,0x76,0x26,0x89,0x45,0x32
+,0xe5,0x7c,0x26,0x89,0x45,0x34,0xe5,0x7e,0x26,0x89,0x45,0x36,0xe5,0x80,0x26,0x89
+,0x45,0x38,0xe5,0x82,0x26,0x89,0x45,0x3a,0xe5,0x86,0x26,0x89,0x45,0x3c,0xe5,0x88
+,0x26,0x89,0x45,0x3e,0xe5,0x9a,0x26,0x89,0x45,0x40,0xe5,0x9e,0x26,0x89,0x45,0x42
+,0xe5,0xcc,0x26,0x89,0x45,0x44,0xe5,0xce,0x26,0x89,0x45,0x46,0xe5,0xd0,0x26,0x89
+,0x45,0x48,0xe5,0xd2,0x26,0x89,0x45,0x4a,0xba,0x00,0x01,0xed,0x11,0x06,0x66,0x34
+,0x73,0x04,0xff,0x06,0x68,0x34,0x26,0x89,0x45,0x4c,0xba,0x02,0x01,0xed,0xc1,0xe0
+,0x02,0x11,0x06,0x6e,0x34,0x73,0x04,0xff,0x06,0x70,0x34,0x26,0x89,0x45,0x4e,0xba
+,0x04,0x01,0xed,0x11,0x06,0x6a,0x34,0x73,0x04,0xff,0x06,0x6c,0x34,0x26,0x89,0x45
+,0x50,0xba,0x06,0x01,0xed,0xc1,0xe0,0x02,0x11,0x06,0x72,0x34,0x73,0x04,0xff,0x06
+,0x74,0x34,0x26,0x89,0x45,0x52,0xba,0x08,0x01,0xed,0x26,0x89,0x45,0x54,0xba,0x0a
+,0x01,0xed,0x26,0x89,0x45,0x56,0xba,0x0c,0x01,0xed,0x26,0x89,0x45,0x58,0xba,0x0e
+,0x01,0xed,0x01,0x06,0x7a,0x34,0x26,0x89,0x45,0x5e,0xba,0x10,0x01,0xed,0x26,0x89
+,0x45,0x5c,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x80,0x74,0x07,0xf6,0x06,0x93,0x36
+,0x20,0x75,0x03,0xb0,0x01,0xc3,0x26,0x80,0x7f,0x06,0x00,0x75,0x30,0x80,0x3e,0x95
+,0x36,0x00,0x74,0x52,0xc6,0x06,0x95,0x36,0x00,0x83,0x26,0xad,0x36,0xfe,0xa1,0xad
+,0x36,0xe7,0x04,0xba,0x10,0x01,0xb8,0x80,0x80,0xef,0xed,0xba,0x10,0x01,0xb8,0x02
+,0x02,0xef,0xed,0xba,0xe0,0x00,0xb8,0x00,0x10,0xef,0xb0,0x00,0xc3,0x26,0x8b,0x47
+,0x04,0x3d,0x00,0x00,0x74,0x20,0x3d,0x03,0x00,0x77,0x1b,0xba,0x10,0x01,0xb8,0x02
+,0x00,0xef,0xba,0xe0,0x00,0xb8,0x01,0x10,0xef,0x83,0x0e,0xad,0x36,0x01,0xa1,0xad
+,0x36,0xe7,0x04,0xb0,0x00,0xc3,0xb0,0x06,0xc3,0xf6,0x06,0x93,0x36,0x80,0x75,0x03
+,0xb0,0x01,0xc3,0x26,0x83,0x7f,0x04,0x01,0x74,0x0a,0x26,0x83,0x7f,0x04,0x02,0x74
+,0x19,0xb0,0x06,0xc3,0x26,0x83,0x7f,0x06,0x0c,0x77,0xf6,0x26,0x83,0x7f,0x0a,0x60
+,0x77,0xef,0xe8,0x10,0x00,0x72,0x0b,0xb0,0x46,0xc3,0xe8,0x4e,0x00,0x72,0x03,0xb0
+,0x46,0xc3,0xb0,0x00,0xc3,0x51,0xb1,0x0a,0x8b,0x3e,0x20,0xf3,0x26,0x83,0x7d,0x0c
+,0x02,0x75,0x03,0xe9,0x0e,0x00,0xfe,0xc9,0x74,0x07,0x81,0xc7,0x20,0x01,0xe9,0xeb
+,0xff,0x59,0xf8,0xc3,0x57,0x8d,0x7d,0x0e,0x8d,0x77,0x06,0xb9,0x12,0x00,0xf3,0xa4
+,0x8d,0x7d,0x20,0x8d,0x36,0xe0,0xfe,0x26,0x8b,0x4d,0x12,0xf3,0xa4,0xff,0x06,0x01
+,0x35,0x5f,0x26,0xc7,0x45,0x0c,0x01,0x00,0x59,0xf9,0xc3,0x51,0xb1,0x0a,0x8d,0x3e
+,0x20,0xf3,0x8d,0x36,0xe0,0xfe,0x26,0x83,0x7d,0x0c,0x01,0x75,0x1b,0x57,0xe8,0x25
+,0x00,0x5f,0x73,0x14,0x33,0xc0,0xb9,0x20,0x01,0xf3,0xaa,0x26,0xc7,0x45,0x0c,0x02
+,0x00,0xff,0x0e,0x01,0x35,0x59,0xf9,0xc3,0xfe,0xc9,0x74,0x07,0x81,0xc7,0x20,0x01
+,0xe9,0xd3,0xff,0x59,0xf8,0xc3,0x51,0x26,0x8b,0x4d,0x12,0x8d,0x7d,0x20,0xf3,0xa6
+,0x74,0x03,0x59,0xf8,0xc3,0x59,0xf9,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x80,0x3e,0xec,0x34,0x06,0x72,0x33,0xff,0x06,0xf0,0x33,0x50,0xc4,0x1e,0x8c,0x36
+,0xb9,0x0f,0x00,0x33,0xc0,0xe8,0x29,0x00,0x58,0x81,0x26,0xc2,0x34,0xdf,0x7f,0x81
+,0x26,0xe9,0x34,0xdf,0x7f,0x0b,0xdb,0x74,0x11,0x26,0xc6,0x07,0x84,0x26,0xc6,0x47
+,0x02,0xff,0x26,0x89,0x47,0x06,0xe8,0xac,0x00,0xc3,0xff,0x06,0xea,0x33,0xe9,0xf5
+,0xff,0x57,0x26,0x8b,0x3f,0x03,0xf9,0x26,0x3b,0x7f,0x02,0x74,0x16,0x26,0x3b,0x7f
+,0x04,0x7c,0x2a,0x3d,0x00,0x00,0x75,0x13,0x8d,0x7f,0x08,0x03,0xf9,0x26,0x3b,0x7f
+,0x02,0x7c,0x14,0xff,0x06,0xde,0x33,0x33,0xdb,0x5f,0xc3,0x26,0x8b,0x7f,0x02,0x26
+,0x89,0x3f,0x03,0xf9,0xe9,0x06,0x00,0x26,0x89,0x3f,0x26,0x29,0x0f,0x26,0xc7,0x05
+,0xff,0xff,0x26,0x87,0x3f,0x26,0x89,0x0d,0x8d,0x5d,0x02,0x50,0x8b,0xfb,0x83,0xe9
+,0x02,0x33,0xc0,0xf3,0xaa,0x58,0xfe,0x0e,0xec,0x34,0x5f,0xc3,0x8b,0x7c,0x02,0x3b
+,0x3c,0x74,0x2f,0x83,0x3d,0xff,0x75,0x0b,0x8d,0x7c,0x08,0x89,0x7c,0x02,0x83,0x3d
+,0xff,0x74,0x1e,0x8a,0x45,0x02,0x3c,0x81,0x75,0x0c,0x80,0x3e,0xeb,0x34,0x00,0x74
+,0x05,0x33,0xc0,0xe9,0x0b,0x00,0x8b,0x0d,0x01,0x4c,0x02,0x8d,0x75,0x02,0x83,0xe9
+,0x02,0xc3,0x80,0x3e,0xec,0x34,0x06,0x72,0x05,0x33,0xc0,0xe9,0xf3,0xff,0xff,0x06
+,0xee,0x33,0xe9,0xbe,0xff,0xf6,0x06,0x92,0x36,0x40,0x74,0x01,0xc3,0x57,0x56,0x51
+,0x52,0x8b,0x36,0x8c,0x36,0xe8,0xa4,0xff,0x75,0x03,0xe9,0x1a,0x00,0xe9,0x1c,0x00
+,0xfe,0x06,0xec,0x34,0xc4,0x3e,0x80,0x36,0xf3,0xa4,0x80,0x0e,0x92,0x36,0x40,0xba
+,0x0c,0x01,0xb8,0x80,0x80,0xef,0xed,0x5a,0x59,0x5e,0x5f,0xc3,0xff,0x06,0xe0,0x33
+,0x80,0x3c,0x81,0x75,0x0c,0xff,0x06,0xe2,0x33,0xc6,0x06,0xeb,0x34,0x01,0xe9,0xcf
+,0xff,0x80,0x3c,0x84,0x75,0x07,0xff,0x06,0xe6,0x33,0xe9,0xc3,0xff,0xff,0x06,0xe8
+,0x33,0xe9,0xbc,0xff,0x8d,0x3e,0xe0,0xfe,0xa1,0x72,0x34,0xc7,0x06,0x72,0x34,0x00
+,0x00,0x89,0x05,0xa1,0x74,0x34,0xc7,0x06,0x74,0x34,0x00,0x00,0x89,0x45,0x02,0xba
+,0x04,0x01,0xed,0x89,0x45,0x04,0xc7,0x45,0x06,0x00,0x00,0xa1,0x6e,0x34,0xc7,0x06
+,0x6e,0x34,0x00,0x00,0x89,0x45,0x08,0xa1,0x70,0x34,0xc7,0x06,0x70,0x34,0x00,0x00
+,0x89,0x45,0x0a,0xba,0x00,0x01,0xed,0x89,0x45,0x0c,0xc7,0x45,0x0e,0x00,0x00,0x32
+,0xe4,0xba,0x0e,0x01,0xec,0x89,0x45,0x10,0xa1,0x7e,0x34,0xc7,0x06,0x7e,0x34,0x00
+,0x00,0x89,0x45,0x12,0xa1,0x8c,0x34,0xc7,0x06,0x8c,0x34,0x00,0x00,0x89,0x45,0x14
+,0xa1,0x8a,0x34,0xc7,0x06,0x8a,0x34,0x00,0x00,0x89,0x45,0x16,0xa1,0x7c,0x34,0xc7
+,0x06,0x7c,0x34,0x00,0x00,0x89,0x45,0x18,0xa1,0x88,0x34,0xc7,0x06,0x88,0x34,0x00
+,0x00,0x89,0x45,0x1a,0xa1,0xca,0x33,0xc7,0x06,0xca,0x33,0x00,0x00,0x89,0x45,0x1c
+,0xa1,0x78,0x34,0xc7,0x06,0x78,0x34,0x00,0x00,0x89,0x45,0x1e,0xa1,0xc6,0x34,0xc7
+,0x06,0xc6,0x34,0x00,0x00,0x89,0x45,0x20,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0xfa,0x33,0xc0,0x8e,0xd8,0x8e,0xc0,0xb8,0xa0,0x01,0xc1,0xe8,0x04,0x8e,0xd0,0x8d
+,0x26,0x80,0x00,0xe8,0x00,0x01,0xe8,0x10,0xeb,0x8b,0x1e,0xf7,0x34,0x8b,0x16,0xf9
+,0x34,0x8b,0x36,0xff,0x34,0x33,0xc0,0xb9,0xef,0xff,0x8d,0x3e,0x14,0x00,0x2b,0xcf
+,0x2b,0xce,0xd1,0xe9,0xf3,0xab,0x89,0x1e,0xf7,0x34,0x89,0x16,0xf9,0x34,0x83,0xfe
+,0x00,0x74,0x0c,0xb9,0xef,0xff,0xbf,0x80,0xfe,0x2b,0xcf,0xd1,0xe9,0xf3,0xab,0xb9
+,0xff,0xff,0x81,0xe9,0x00,0x3b,0x83,0xfe,0x00,0x74,0x03,0xe9,0x1b,0x00,0x51,0x1e
+,0xb8,0x00,0xe0,0x8e,0xd8,0x33,0xf6,0x8d,0x3e,0x00,0xd8,0xb9,0x00,0x0c,0xf3,0xa5
+,0x1f,0x59,0xbe,0xff,0xff,0x81,0xee,0x00,0xd8,0x2b,0xce,0x81,0xe1,0x00,0xff,0x89
+,0x0e,0xac,0x33,0x8d,0x06,0x20,0x02,0xc1,0xe8,0x04,0xa3,0x32,0x34,0x8e,0xd0,0x36
+,0xc7,0x06,0x1e,0x00,0x80,0x18,0x36,0xc7,0x06,0x22,0x00,0xff,0x7f,0x36,0xc7,0x06
+,0x0a,0x00,0xff,0xff,0x36,0xc7,0x06,0x1c,0x00,0x80,0x00,0x8d,0x06,0xa0,0x02,0xc1
+,0xe8,0x04,0xa3,0x30,0x34,0x8e,0xd0,0x36,0xc7,0x06,0x1e,0x00,0x50,0x28,0x36,0xc7
+,0x06,0x0a,0x00,0xff,0xff,0x36,0xc7,0x06,0x1c,0x00,0x80,0x00,0xb8,0xa0,0x01,0xc1
+,0xe8,0x04,0xa3,0x34,0x34,0xa3,0xf2,0x33,0x8e,0xd0,0x8d,0x26,0x80,0x00,0xb8,0x00
+,0x90,0xe7,0x02,0x8d,0x3e,0x70,0x01,0x8b,0xc7,0xc1,0xe8,0x04,0xb9,0x03,0x00,0x89
+,0x45,0x0e,0x89,0x45,0x02,0xc7,0x05,0xff,0xff,0x83,0xc7,0x10,0x05,0x01,0x00,0xe2
+,0xee,0xe8,0x5b,0x01,0xe5,0xce,0xa3,0xb5,0x36,0xe8,0x21,0x00,0xe8,0x45,0x01,0xa1
+,0x32,0x34,0x8c,0xcb,0xcd,0x37,0x0e,0x58,0xa9,0x00,0xf0,0x74,0x07,0x33,0xf6,0x89
+,0x36,0xff,0x34,0xc3,0x8d,0x36,0x30,0x61,0x89,0x36,0xff,0x34,0xc3,0x33,0xc0,0x8b
+,0xd0,0x8b,0xf2,0xb9,0x68,0x00,0x2e,0x80,0xbc,0xac,0x17,0x80,0x75,0x01,0xef,0x83
+,0xc2,0x02,0x46,0xe2,0xf1,0xb8,0x02,0x00,0xe7,0x50,0xb9,0x5a,0x00,0x33,0xff,0xc7
+,0x05,0x65,0x18,0x8c,0x4d,0x02,0x83,0xc7,0x04,0xe2,0xf4,0x33,0xc0,0x8e,0xc0,0x8c
+,0xc8,0x8e,0xd8,0x8d,0x3e,0x80,0x00,0x8d,0x36,0x9c,0x17,0xb9,0x08,0x00,0xe8,0x37
+,0x00,0x8d,0x36,0x20,0x21,0x8d,0x3e,0xc0,0x00,0xb9,0x0d,0x00,0xe8,0x29,0x00,0x8d
+,0x3e,0x40,0x01,0xb9,0x0a,0x00,0xe8,0x1f,0x00,0xe8,0x4b,0x0e,0x33,0xc0,0x8e,0xd8
+,0xc7,0x06,0x4e,0x37,0x6f,0x17,0xe7,0x48,0xe7,0x4c,0xb8,0x40,0x9c,0xe7,0x4a,0xe5
+,0x48,0x90,0xb8,0x00,0x70,0xe7,0x48,0xc3,0xa5,0x83,0xc7,0x02,0xe2,0xfa,0xc3,0xe5
+,0x4c,0xc3,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe5,0x58,0xd1
+,0xe0,0x73,0x11,0x8b,0xf0,0xd1,0xe6,0x33,0xc0,0x8e,0xd8,0x8b,0xb4,0x80,0x00,0x83
+,0xc6,0x0b,0xff,0xe6,0x1f,0x07,0x5a,0x5f,0x5e,0x59,0x58,0xcf,0x58,0x1c,0xe4,0x1c
+,0x6c,0x1c,0x8e,0x1a,0xc0,0x1f,0x40,0x1a,0x44,0x1c,0x65,0x18,0x80,0x80,0x80,0xff
+,0x80,0x03,0x02,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+,0x80,0x03,0x03,0x43,0x80,0x80,0x02,0x80,0x42,0x03,0x02,0xff,0x03,0x01,0x03,0x01
+,0x01,0x03,0x02,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x03,0x01,0x03
+,0x03,0xff,0x01,0x01,0xff,0x01,0xff,0x01,0x01,0x03,0x03,0x03,0xff,0xff,0xff,0xff
+,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+,0xff,0xff,0xff,0x02,0xb8,0x0f,0x00,0xe7,0x84,0xb8,0x0f,0xf8,0xe7,0x82,0xc3,0xb9
+,0x08,0x00,0x89,0x0e,0xe6,0x3a,0x8d,0x06,0x20,0x03,0x8b,0xd0,0xc1,0xe8,0x04,0xa3
+,0x90,0x01,0x8b,0xc2,0x8b,0xd8,0xc1,0xe8,0x04,0x8e,0xc0,0x05,0x61,0x00,0x26,0xa3
+,0x00,0x00,0xa1,0x30,0x34,0x26,0xa3,0x02,0x00,0x83,0xc3,0x14,0xd1,0xeb,0x26,0x89
+,0x1e,0x08,0x00,0x81,0xc2,0x10,0x06,0xe2,0xd9,0x26,0xc7,0x06,0x00,0x00,0xff,0xff
+,0x8c,0x06,0x92,0x01,0xc3,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8
+,0xe7,0x5a,0xff,0x06,0xbe,0x33,0xba,0xd2,0x00,0xed,0xcf,0x00,0x00,0x00,0x00,0x00
+,0x8c,0xcb,0xa1,0x30,0x34,0xcd,0x37,0xe9,0x06,0xed,0xb8,0x32,0x00,0xc3,0xe8,0x8c
+,0x01,0xfe,0x06,0xe2,0x34,0xe8,0x21,0x01,0x75,0xf0,0xe8,0x53,0x0e,0x81,0x0e,0xaf
+,0x36,0x00,0xc0,0xc7,0x06,0xad,0x36,0x60,0x00,0xf7,0x06,0xe6,0x34,0x80,0x00,0x75
+,0x1a,0xf7,0x06,0xe6,0x34,0x00,0x08,0x74,0x09,0xc7,0x06,0xab,0x36,0x0b,0x00,0xe9
+,0x0f,0x00,0xc7,0x06,0xab,0x36,0x03,0x00,0xe9,0x06,0x00,0xc7,0x06,0xab,0x36,0x11
+,0x9c,0xc7,0x06,0xa9,0x36,0x18,0x00,0xf7,0x06,0xe6,0x34,0x80,0x00,0x75,0x0d,0xf7
+,0x06,0xb5,0x36,0x02,0x00,0x74,0x05,0x83,0x0e,0xa9,0x36,0x20,0xa1,0xa9,0x36,0xe7
+,0x00,0xa1,0xab,0x36,0xe7,0x02,0xf7,0x06,0xe6,0x34,0x80,0x00,0x74,0x2e,0xe8,0xf2
+,0x2f,0x33,0xc0,0x0d,0x41,0x00,0xe7,0x56,0xa1,0xb1,0x36,0x0d,0x00,0x10,0xe7,0x08
+,0xa1,0xb3,0x36,0xe7,0x0a,0xa1,0xaf,0x36,0xe7,0x06,0xb8,0x40,0x00,0xe7,0x4e,0x33
+,0xc0,0xe7,0x0e,0xc7,0x06,0x26,0x02,0x00,0x00,0xe9,0x23,0x00,0xc7,0x06,0x4e,0x37
+,0x3f,0x20,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x80,0x74,0x07,0x26
+,0x81,0x0e,0x08,0x00,0x00,0x80,0xc6,0x06,0xe0,0x34,0x01,0xb8,0x00,0x00,0xc3,0xfe
+,0x06,0xe1,0x34,0xc6,0x06,0xe0,0x34,0x00,0xa1,0x26,0x02,0x0b,0xc0,0x74,0x01,0xc3
+,0xe8,0x04,0x00,0xb8,0x00,0x00,0xc3,0xa1,0xa9,0x36,0xe7,0x00,0x8b,0x1e,0xab,0x36
+,0x83,0xe3,0x06,0xe5,0x02,0x25,0xf9,0xff,0x0b,0xc3,0x0d,0x10,0x00,0xe7,0x02,0xa1
+,0xad,0x36,0xe7,0x04,0xc3,0xb8,0x0a,0x00,0xe7,0x84,0xfe,0x06,0xe5,0x34,0xc6,0x06
+,0xe3,0x34,0x01,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x40,0x74,0x07
+,0x26,0x81,0x0e,0x08,0x00,0x00,0x40,0xc3,0xc7,0x06,0x4e,0x37,0x6f,0x17,0xfe,0x06
+,0xe4,0x34,0xc6,0x06,0xe3,0x34,0x00,0xc3,0xc3,0xf6,0x06,0x18,0x34,0x80,0x75,0x0d
+,0xa1,0x18,0x34,0x0b,0x06,0x1a,0x34,0x0b,0x06,0x1c,0x34,0x75,0x01,0xc3,0xa1,0x2e
+,0x34,0x25,0xff,0xfe,0x8b,0x16,0xe7,0x36,0x81,0xe2,0x00,0x01,0x0b,0xc2,0xa3,0x2e
+,0x34,0x8d,0x16,0x10,0x00,0xbf,0x00,0x00,0xb9,0x08,0x00,0x8b,0x85,0x00,0x34,0xef
+,0x83,0xc2,0x10,0x8b,0x85,0x02,0x34,0xef,0x83,0xc2,0x10,0x8b,0x85,0x04,0x34,0xef
+,0x83,0xc2,0xe2,0x83,0xc7,0x06,0x49,0x75,0xe2,0xb8,0x00,0x00,0x8e,0xc0,0xbe,0x00
+,0x34,0xbf,0xb9,0x36,0xb9,0x18,0x00,0xf3,0xa5,0xb8,0x00,0x00,0xc3,0x33,0xc0,0x8e
+,0xc0,0x8d,0x3e,0xb0,0x33,0xb9,0x08,0x00,0xf3,0xab,0x8d,0x3e,0x3e,0x34,0xb9,0x03
+,0x00,0xf3,0xab,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xba
+,0x33,0xe5,0x56,0x0d,0x20,0x00,0xe7,0x56,0xba,0x7a,0x00,0xed,0x08,0x26,0x94,0x36
+,0x33,0xc0,0xb1,0x08,0x32,0xed,0x06,0x8e,0xc0,0x8d,0x3e,0xe0,0xff,0xf3,0xaa,0x8e
+,0x06,0x32,0x34,0x26,0x81,0x0e,0x08,0x00,0x00,0x02,0x07,0xe5,0x56,0x25,0xdf,0xff
+,0xe7,0x56,0xe9,0xf8,0xfc,0x00,0xbd,0x1b,0x10,0x1b,0xd9,0x1a,0xf3,0x1a,0x50,0x51
+,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xb6,0x33,0x53
+,0x06,0x51,0xe5,0x80,0xa3,0xb4,0x33,0x8b,0xd8,0x8b,0xc8,0x25,0x10,0x00,0xa3,0xed
+,0x34,0x0b,0xc0,0x74,0x14,0xff,0x06,0x80,0x34,0x80,0x3e,0xfe,0x34,0x00,0x74,0x03
+,0xe9,0x06,0x00,0xb8,0x80,0x00,0xe8,0x9d,0x04,0x83,0xe3,0x03,0xd1,0xe3,0x2e,0xff
+,0x97,0x86,0x1a,0x59,0x07,0x5b,0xe9,0xa4,0xfc,0xba,0x20,0x00,0x8e,0x06,0x3c,0x34
+,0x83,0x3e,0x3c,0x34,0x00,0x75,0x03,0xe9,0xf0,0x00,0xc7,0x06,0x3c,0x34,0x00,0x00
+,0xe9,0x2a,0x00,0xba,0x10,0x00,0x8e,0x06,0x3a,0x34,0x83,0x3e,0x3a,0x34,0x00,0x75
+,0x03,0xe9,0xd5,0xff,0xc7,0x06,0x3a,0x34,0x00,0x00,0xe8,0x10,0x00,0xe9,0xc9,0xff
+,0xba,0x10,0x00,0x8e,0x06,0x3a,0x34,0xc7,0x06,0x3a,0x34,0x00,0x00,0x26,0xa1,0x14
+,0x00,0x26,0xa3,0x0c,0x00,0x26,0xa1,0x16,0x00,0x26,0xa3,0x0e,0x00,0x26,0xc6,0x06
+,0x0a,0x00,0x00,0xc1,0xea,0x02,0x23,0xd1,0x74,0x1c,0xba,0x20,0x00,0x26,0xc7,0x06
+,0x0e,0x00,0xea,0x05,0x26,0x0b,0x16,0x0c,0x00,0x26,0x89,0x16,0x0c,0x00,0xff,0x06
+,0x86,0x34,0xff,0x06,0xdc,0x33,0x26,0xa1,0x0c,0x00,0xa9,0x00,0x37,0x74,0x16,0x26
+,0xc6,0x06,0x0a,0x00,0x02,0xa9,0x00,0x30,0x74,0x04,0xff,0x06,0x7a,0x34,0xff,0x06
+,0xda,0x33,0xe9,0x49,0x00,0xc0,0xec,0x07,0x83,0x16,0x8a,0x34,0x00,0x24,0x07,0x3c
+,0x07,0x75,0x04,0xff,0x06,0x8c,0x34,0xff,0x06,0x7e,0x34,0xa1,0x30,0x34,0x8c,0xc3
+,0x8e,0xc0,0x8e,0xdb,0x26,0x83,0x0e,0x08,0x00,0x40,0x8c,0xd8,0x26,0x87,0x06,0x16
+,0x00,0x26,0x83,0x3e,0x14,0x00,0xff,0x74,0x0a,0x8e,0xc0,0x26,0x8c,0x1e,0x00,0x00
+,0xe9,0x05,0x00,0x26,0x8c,0x1e,0x14,0x00,0x33,0xc0,0x8e,0xd8,0xc3,0xc3,0x8c,0xc0
+,0x87,0x06,0x92,0x01,0x3d,0xff,0xff,0x74,0x0d,0x8e,0xd8,0x8c,0x06,0x00,0x00,0x33
+,0xc0,0x8e,0xd8,0xe9,0x04,0x00,0x8c,0x06,0x90,0x01,0xe8,0x01,0x00,0xc3,0x06,0x83
+,0x3e,0x90,0x01,0xff,0x74,0x29,0x83,0x3e,0x3a,0x34,0x00,0x75,0x11,0xba,0x86,0x00
+,0xe8,0x1e,0x00,0x8c,0x06,0x3a,0x34,0x83,0x3e,0x90,0x01,0xff,0x74,0x11,0x83,0x3e
+,0x3c,0x34,0x00,0x75,0x0a,0xba,0x88,0x00,0xe8,0x06,0x00,0x8c,0x06,0x3c,0x34,0x07
+,0xc3,0xa1,0x90,0x01,0x8e,0xc0,0x26,0xa1,0x08,0x00,0xef,0x26,0xa1,0x00,0x00,0x26
+,0xc7,0x06,0x00,0x00,0xff,0xff,0xa3,0x90,0x01,0x3d,0xff,0xff,0x75,0x03,0xa3,0x92
+,0x01,0x83,0x3e,0xed,0x34,0x00,0x74,0x0b,0xb8,0x10,0x00,0xe7,0x84,0xc7,0x06,0xed
+,0x34,0x00,0x00,0xc3,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7
+,0x5a,0xff,0x06,0xbc,0x33,0xe9,0x25,0xfb,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33
+,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xb0,0x33,0xe9,0x11,0xfb,0x50,0x51,0x56,0x57
+,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xb4,0x33,0x06,0xff,0x06
+,0x76,0x34,0x80,0x3e,0xfe,0x34,0x00,0x74,0x04,0x07,0xe9,0xf0,0xfa,0xb8,0x80,0x00
+,0xe8,0xd3,0x02,0x07,0xe9,0xe6,0xfa,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0xc6,0x1d,0x08,0x1d,0x91,0x1e,0x5d,0x1e,0x73,0x1e,0x89,0x1e,0x91,0x1e,0xa8,0x1d
+,0x91,0x1e,0x91,0x1e,0xaf,0x1e,0xaf,0x1e,0x15,0x1d,0x15,0x1d,0x91,0x1e,0x99,0x1f
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00
+,0x00,0x01,0x00,0x10,0x00,0x01,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00
+,0x07,0xe9,0x99,0xfa,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7
+,0x5a,0xff,0x06,0xb2,0x33,0x06,0x68,0xf6,0x1c,0xe5,0x06,0xa3,0xb2,0x33,0x8b,0xf0
+,0x83,0xe6,0x1e,0x2e,0xff,0xa4,0xa0,0x1c,0xe5,0x0c,0xa9,0x80,0x00,0x74,0x06,0xe8
+,0xa4,0x01,0xe5,0x06,0xc3,0x53,0xe5,0x0c,0x8b,0xd8,0xa9,0x01,0x00,0x74,0x14,0x83
+,0x3e,0xe0,0x3a,0x00,0x74,0x0d,0x8e,0x06,0x38,0x34,0xe8,0xbf,0x06,0xc7,0x06,0xe0
+,0x3a,0x00,0x00,0xe5,0x00,0x0d,0x18,0x00,0xe7,0x00,0xe5,0x02,0x0d,0x11,0x00,0xe7
+,0x02,0x8b,0xc3,0x5b,0xa9,0x01,0x00,0x74,0x01,0xc3,0x8b,0xd0,0xb8,0x00,0x08,0xe7
+,0x84,0x8b,0xc2,0x8e,0x06,0x38,0x34,0x26,0xa3,0x0c,0x00,0x8b,0xd0,0xc1,0xe0,0x03
+,0x83,0x16,0x88,0x34,0x00,0xff,0x06,0x7c,0x34,0x26,0x83,0x3e,0x06,0x00,0x0a,0x75
+,0x21,0x8b,0xc2,0x25,0x40,0x18,0x3d,0x40,0x00,0x74,0x0c,0x3d,0x00,0x10,0x75,0x12
+,0x26,0xfe,0x0e,0x0a,0x00,0x74,0x0b,0xf7,0x06,0xef,0x34,0x20,0x00,0x75,0x03,0xe9
+,0x5a,0x06,0x8c,0xc0,0x26,0x8e,0x06,0x02,0x00,0x26,0x83,0x0e,0x08,0x00,0x20,0x26
+,0xa3,0x12,0x00,0x26,0xa3,0x10,0x00,0xc3,0xff,0x06,0xc4,0x33,0xe5,0x0c,0xa9,0x01
+,0x00,0x75,0x01,0xc3,0xa9,0xf0,0x07,0x74,0x01,0xc3,0xff,0x06,0xd4,0x33,0xe5,0x00
+,0x0d,0x18,0x00,0xe7,0x00,0xc3,0xff,0x06,0xca,0x33,0x80,0x3e,0xa0,0x36,0x08,0x75
+,0x14,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x08,0x74,0x07,0x26,0x81
+,0x0e,0x08,0x00,0x00,0x08,0xe5,0x82,0x25,0xfd,0xff,0xe7,0x82,0xe5,0x0c,0x50,0xe5
+,0x80,0x25,0x00,0x07,0xa3,0xe4,0x3a,0xe5,0x8c,0x25,0x00,0x80,0xa3,0xe2,0x3a,0x58
+,0xa9,0x02,0x00,0x75,0x25,0x83,0x3e,0xe2,0x3a,0x00,0x75,0x1e,0x83,0x3e,0xe4,0x3a
+,0x00,0x75,0x17,0xe5,0x08,0x0d,0x00,0x04,0x25,0xff,0x04,0xe7,0x08,0xe8,0x6a,0x01
+,0xe5,0x82,0x0d,0x02,0x00,0xe7,0x82,0xe9,0x21,0x00,0xe8,0x1a,0x06,0x80,0x3e,0xe8
+,0xff,0x00,0x74,0x0a,0x80,0x3e,0xe8,0xff,0x04,0x74,0x03,0xe9,0x0d,0x00,0xc6,0x06
+,0xe8,0xff,0x01,0xba,0x0c,0x01,0xb8,0x08,0x08,0xef,0xed,0x80,0x3e,0x9f,0x36,0x06
+,0x75,0x05,0x83,0x0e,0x99,0x36,0x40,0xb8,0x00,0x01,0xe9,0x09,0x01,0xff,0x06,0xcc
+,0x33,0x81,0x26,0xaf,0x36,0xff,0xf7,0xa1,0xaf,0x36,0xe7,0x06,0xff,0x06,0xc6,0x34
+,0xe9,0x1e,0x00,0xff,0x06,0xce,0x33,0xff,0x06,0x95,0x37,0x81,0x26,0xaf,0x36,0xff
+,0xef,0xa1,0xaf,0x36,0xe7,0x06,0xe9,0x08,0x00,0xff,0x06,0xd0,0x33,0xff,0x06,0x7a
+,0x34,0xff,0x06,0xd2,0x33,0xd1,0xe6,0x8e,0x06,0x30,0x34,0x2e,0x8b,0x84,0xc0,0x1c
+,0x26,0x09,0x06,0x08,0x00,0x2e,0x8b,0x84,0xc2,0x1c,0x09,0x06,0x66,0x37,0xc3,0xe5
+,0x0c,0xa9,0x80,0x00,0x74,0x56,0x50,0xe8,0xf0,0x00,0x58,0xa9,0x00,0x01,0x75,0x07
+,0xff,0x06,0xc6,0x33,0xe9,0x08,0x00,0xff,0x06,0x78,0x34,0xff,0x06,0xc8,0x33,0xe5
+,0x82,0x25,0xfd,0xff,0xe7,0x82,0xe8,0x6e,0x05,0xba,0x10,0x01,0xed,0x80,0x3e,0xe8
+,0xff,0x00,0x74,0x0a,0x80,0x3e,0xe8,0xff,0x04,0x74,0x03,0xe9,0x1d,0x00,0xc6,0x06
+,0xe8,0xff,0x01,0xba,0x0c,0x01,0xb8,0x08,0x08,0xef,0xed,0xe9,0x0d,0x00,0xc6,0x06
+,0xe8,0xff,0x03,0xba,0x0c,0x01,0xb8,0x08,0x08,0xef,0xed,0xc3,0xa9,0x01,0x00,0x74
+,0x1c,0xe8,0x2c,0x00,0x83,0x3e,0xe0,0x3a,0x00,0x74,0x0f,0x06,0x8e,0x06,0x38,0x34
+,0xe8,0xc9,0x04,0xc7,0x06,0xe0,0x3a,0x00,0x00,0x07,0xe9,0x5d,0x00,0x8b,0xd0,0x8e
+,0x06,0x38,0x34,0x26,0xa3,0x0c,0x00,0xe8,0x06,0x00,0x68,0x69,0x1d,0xe9,0x4a,0x00
+,0xa9,0x00,0x04,0x74,0x0a,0xb8,0x00,0x04,0xff,0x06,0xd8,0x33,0xe9,0x17,0x00,0xa9
+,0x00,0x01,0x74,0x0a,0xff,0x06,0x39,0x37,0xb8,0x00,0x01,0xe9,0x08,0x00,0xa9,0x10
+,0x00,0xb8,0x10,0x00,0x74,0x1d,0x09,0x06,0x66,0x37,0x8c,0xc0,0x8e,0x06,0x30,0x34
+,0x26,0xf7,0x06,0x0a,0x00,0x00,0x01,0x74,0x07,0x26,0x81,0x0e,0x08,0x00,0x00,0x01
+,0x8e,0xc0,0xc3,0xff,0x06,0xc2,0x33,0xe9,0xf8,0xff,0xe5,0x00,0x0d,0x18,0x00,0xe7
+,0x00,0xe5,0x02,0x0d,0x11,0x00,0xe7,0x02,0xc3,0x58,0xe9,0x43,0xfd,0xe5,0x08,0x0d
+,0x00,0x04,0x25,0xff,0x04,0xe7,0x08,0xe9,0xe0,0xff,0xe5,0x0e,0xa9,0x00,0x08,0x75
+,0x01,0xc3,0xe9,0xf5,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xb8
+,0x33,0xe5,0x48,0x06,0x53,0x57,0xff,0x16,0x4e,0x37,0x5f,0x5b,0x83,0x3e,0x80,0x01
+,0xff,0x74,0x58,0x8e,0x06,0x80,0x01,0x26,0xff,0x0e,0x08,0x00,0x75,0x4d,0x26,0xa1
+,0x00,0x00,0xa3,0x80,0x01,0x26,0xc7,0x06,0x00,0x00,0xff,0xff,0x8c,0xc0,0x26,0x8e
+,0x06,0x02,0x00,0x26,0x81,0x0e,0x08,0x00,0x80,0x00,0x8b,0xd0,0x26,0x87,0x06,0x1a
+,0x00,0x26,0x83,0x3e,0x18,0x00,0xff,0x74,0x0a,0x8e,0xc0,0x26,0x89,0x16,0x00,0x00
+,0xe9,0x05,0x00,0x26,0x89,0x16,0x18,0x00,0x83,0x3e,0x80,0x01,0xff,0x74,0x0c,0x8e
+,0x06,0x80,0x01,0x26,0x83,0x3e,0x08,0x00,0x00,0x74,0xb3,0x07,0xe9,0x3e,0xf7,0xe5
+,0x4c,0x90,0xe5,0x02,0xa9,0x00,0x20,0x74,0x0d,0x25,0xff,0xdf,0x0d,0x01,0x00,0xe7
+,0x02,0x0d,0x00,0x20,0xe7,0x02,0xe5,0x0a,0x8b,0xd8,0xa3,0xf4,0x33,0x25,0xc3,0x57
+,0x0d,0x00,0x10,0xe7,0x0a,0xf7,0x06,0x9b,0x36,0x00,0x80,0x74,0x37,0xf7,0xc3,0x00
+,0x80,0x74,0x06,0xf7,0xc3,0x00,0x08,0x74,0x5d,0x81,0x26,0xc2,0x34,0x7f,0xff,0xc7
+,0x06,0x35,0x37,0x05,0x00,0xb8,0x80,0x03,0xcd,0x39,0x81,0x26,0x9b,0x36,0xff,0x7f
+,0xc7,0x06,0x0f,0x37,0x04,0x00,0xf7,0x06,0x9b,0x36,0x40,0x00,0x75,0x06,0xc7,0x06
+,0x0f,0x37,0x03,0x00,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x2a,0xf7,0xc3,0x00,0x08
+,0x74,0x24,0x80,0x3e,0x9d,0x36,0x06,0x7c,0x1d,0xff,0x06,0x94,0x34,0x83,0x0e,0x66
+,0x37,0x20,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x01,0x74,0x07,0x26
+,0x81,0x0e,0x08,0x00,0x00,0x01,0xf7,0xc3,0x00,0x20,0x75,0x3b,0xf7,0x06,0x9a,0x37
+,0x80,0x00,0x74,0x0b,0xff,0x06,0x89,0x37,0x33,0xc0,0xe7,0x0e,0xe9,0x04,0x00,0xff
+,0x06,0x3b,0x37,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x1c,0x80,0x26,0x9e,0x36,0xff
+,0x75,0x15,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x08,0x74,0x07,0x26
+,0x81,0x0e,0x08,0x00,0x00,0x08,0xc3,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x02,0x23,0x02,0x23,0x02,0x23,0x02,0x23,0x03,0x23,0xdd,0x22,0x02,0x23,0xfd,0x21
+,0x02,0x23,0xa4,0x24,0xf3,0x24,0x02,0x23,0x8d,0x22,0x7a,0x23,0x02,0x23,0x97,0x24
+,0x1b,0x24,0x75,0x24,0x02,0x23,0x02,0x23,0x8e,0x25,0xfb,0x8e,0x06,0x7e,0x01,0xfb
+,0x26,0x83,0x3e,0x00,0x00,0xff,0x74,0xf2,0x26,0x8e,0x06,0x00,0x00,0xfa,0x26,0x8b
+,0x1e,0x08,0x00,0x26,0x23,0x1e,0x0a,0x00,0x74,0xe5,0x8c,0xc0,0x8e,0xd0,0x26,0x8b
+,0x26,0x02,0x00,0x8c,0x16,0xf2,0x33,0x22,0xff,0x75,0x6a,0x26,0xa1,0x1c,0x00,0x8a
+,0xe3,0x8a,0xdc,0x22,0xd8,0x75,0x0d,0xd0,0xe8,0x24,0xf8,0x0a,0xc0,0x75,0xf2,0xb0
+,0x80,0xe9,0xed,0xff,0xd0,0xe8,0x24,0xf8,0x0a,0xc0,0x75,0x02,0xb0,0x80,0x32,0xe4
+,0x26,0xa3,0x1c,0x00,0xf7,0xc3,0x08,0x00,0x75,0x47,0x2e,0x8a,0x9f,0xc5,0x25,0x2e
+,0x8b,0xbf,0xc5,0x26,0x80,0xc3,0x10,0x26,0x8e,0x1d,0x26,0x8c,0x1e,0x06,0x00,0x8b
+,0x16,0x00,0x00,0xc7,0x06,0x00,0x00,0xff,0xff,0x26,0x89,0x15,0x83,0xfa,0xff,0x75
+,0x0a,0x2e,0x8b,0x97,0xcd,0x26,0x26,0x21,0x16,0x08,0x00,0x33,0xc0,0x8e,0xd8,0x26
+,0x89,0x1e,0x04,0x00,0xc3,0x8a,0xdf,0xb7,0x00,0x2e,0x8a,0x9f,0xc5,0x25,0xe9,0xe0
+,0xff,0x26,0x83,0x26,0x08,0x00,0xf7,0x83,0xc3,0x10,0xe9,0xde,0xff,0x60,0x06,0x1e
+,0x68,0x87,0x25,0x6a,0x00,0x1f,0x8e,0x06,0xf2,0x33,0x8b,0x0e,0x34,0x34,0x39,0x0e
+,0xf2,0x33,0x74,0x0e,0x26,0x81,0x0e,0x0a,0x00,0x00,0x02,0x26,0x81,0x0e,0x08,0x00
+,0x00,0x02,0x26,0x89,0x26,0x02,0x00,0xa3,0xf2,0x33,0x8e,0xd0,0x8d,0x26,0x80,0x00
+,0x36,0x89,0x26,0x02,0x00,0x36,0x89,0x1e,0x20,0x00,0x36,0xc7,0x06,0x08,0x00,0x00
+,0x00,0xb9,0x04,0x00,0xbe,0x00,0x00,0x2e,0x8b,0xbc,0xc5,0x26,0x36,0xc7,0x05,0xff
+,0xff,0x36,0xc7,0x45,0x02,0xff,0xff,0x83,0xc6,0x02,0xe2,0xeb,0x8e,0x06,0x7e,0x01
+,0x36,0x8b,0x0e,0x22,0x00,0x8c,0xc0,0x26,0x83,0x3e,0x00,0x00,0xff,0x26,0x8e,0x06
+,0x00,0x00,0x74,0x07,0x26,0x3b,0x0e,0x22,0x00,0x7d,0xea,0x36,0x8c,0x06,0x00,0x00
+,0x8e,0xc0,0x26,0x8c,0x16,0x00,0x00,0xfb,0x36,0xff,0x2e,0x1e,0x00,0x06,0x1e,0x68
+,0x8b,0x25,0x6a,0x00,0x1f,0x26,0x09,0x36,0x08,0x00,0xf7,0xc6,0x00,0xff,0x74,0x01
+,0xc3,0x56,0x52,0x2e,0x8b,0xb4,0xc5,0x25,0x81,0xe6,0xff,0x00,0x2e,0x8b,0xb4,0xc5
+,0x26,0x8c,0xc2,0x8e,0xc0,0x26,0xc7,0x06,0x00,0x00,0xff,0xff,0x8e,0xc2,0x26,0x83
+,0x3c,0xff,0x74,0x0f,0x8b,0xd0,0x26,0x87,0x54,0x02,0x8e,0xc2,0x26,0xa3,0x00,0x00
+,0xe9,0x07,0x00,0x26,0x89,0x44,0x02,0x26,0x89,0x04,0x5a,0x5e,0xc3,0x06,0x1e,0x68
+,0x8b,0x25,0x6a,0x00,0x1f,0x8e,0x06,0xf2,0x33,0x26,0xa3,0x0a,0x00,0x26,0x89,0x26
+,0x02,0x00,0xa1,0x34,0x34,0x8e,0xd0,0x8d,0x26,0x80,0x00,0x8c,0x16,0xf2,0x33,0xe9
+,0x4d,0xfe,0xcf,0x50,0x1e,0x52,0x53,0x33,0xc0,0x8e,0xd8,0x26,0x83,0x3e,0x04,0x00
+,0xff,0x26,0xc7,0x06,0x04,0x00,0x00,0x00,0x74,0x03,0xe9,0x1a,0x00,0x83,0x3e,0xe6
+,0x3a,0x02,0x76,0x13,0xff,0x06,0xd6,0x33,0x8c,0xc0,0x8e,0x06,0x32,0x34,0xbe,0x40
+,0x00,0x68,0x3a,0x23,0xe9,0x5e,0xff,0xe8,0x84,0xf8,0x5b,0x5a,0x1f,0x58,0xcf,0xe8
+,0xe1,0x00,0x26,0xc6,0x06,0x18,0x00,0x10,0x26,0x8a,0x1e,0x29,0x00,0x88,0x1e,0x1b
+,0x37,0x26,0xc7,0x06,0x0c,0x00,0xff,0x7f,0x26,0xa1,0x0e,0x00,0xe7,0x9c,0x26,0xa1
+,0x08,0x00,0xe7,0x9a,0xe5,0x00,0x80,0xfb,0x08,0x74,0x09,0x0d,0x18,0xac,0xe7,0x00
+,0x07,0x1f,0x58,0xcf,0x0d,0x18,0x00,0xe9,0xf4,0xff,0x50,0x1e,0x06,0x33,0xc0,0x8e
+,0xd8,0x83,0x3e,0xa1,0x36,0x00,0x75,0xb7,0x26,0x8b,0x36,0x06,0x00,0x2e,0xff,0x94
+,0xdc,0x23,0x07,0x1f,0x58,0xcf,0xe8,0x8a,0x00,0xe5,0x00,0x0d,0x18,0x00,0xe7,0x00
+,0xe8,0x49,0x00,0xc3,0x53,0xf7,0x06,0xef,0x34,0x20,0x00,0x75,0x2d,0xe5,0x8c,0x25
+,0x00,0x70,0x8b,0xd8,0xe5,0x8c,0x25,0x00,0x70,0x3b,0xc3,0x74,0x05,0x8b,0xd8,0xe9
+,0xf2,0xff,0x3d,0x00,0x30,0x75,0x10,0xe5,0x02,0x25,0xef,0xff,0xe7,0x02,0xc7,0x06
+,0xe0,0x3a,0xff,0xff,0xe9,0x03,0x00,0xe8,0x12,0x00,0x5b,0xc3,0xa3,0x23,0x96,0x23
+,0xa4,0x23,0xa4,0x23,0x96,0x23,0xa4,0x23,0x96,0x23,0x96,0x23,0x26,0xa0,0x29,0x00
+,0xa2,0x1b,0x37,0x26,0xc7,0x06,0x0c,0x00,0xff,0x7f,0x26,0xa1,0x0e,0x00,0xe7,0x9c
+,0x26,0xa1,0x08,0x00,0xe7,0x9a,0xe5,0x00,0x25,0xff,0x53,0x26,0x8b,0x36,0x06,0x00
+,0x83,0xe6,0x0e,0x2e,0x0b,0x84,0xad,0x25,0xe7,0x00,0xc3,0x06,0x1e,0x68,0x8b,0x25
+,0x6a,0x00,0x1f,0x83,0x0e,0xef,0x34,0x20,0x83,0x0e,0x9b,0x36,0x08,0xe5,0x00,0x25
+,0xef,0xff,0x0d,0x08,0x00,0xe7,0x00,0xe5,0x00,0xa9,0x10,0x00,0x75,0x01,0xc3,0xe5
+,0x00,0xa9,0x10,0x00,0x75,0xf9,0xc3,0x50,0x53,0x51,0x56,0x06,0x1e,0x33,0xc0,0x8e
+,0xd8,0xb8,0x05,0x00,0xe7,0x84,0xe5,0x08,0x0d,0x00,0x04,0x25,0xff,0x04,0xe7,0x08
+,0xe5,0x00,0x0d,0x18,0x00,0xe7,0x00,0xe5,0x02,0x0d,0x11,0x00,0xe7,0x02,0x1f,0x07
+,0x5e,0x59,0x5b,0x58,0xc3,0x50,0x1e,0x33,0xc0,0x8e,0xd8,0xc7,0x06,0xef,0x34,0x00
+,0x00,0x83,0x26,0x9b,0x36,0xf7,0xe5,0x00,0x0d,0x18,0x00,0xe7,0x00,0xe5,0x02,0x0d
+,0x11,0x00,0xe7,0x02,0x1f,0x58,0xcf,0x60,0x06,0x1e,0x68,0x87,0x25,0x6a,0x00,0x1f
+,0xe8,0x16,0xf5,0xc3,0x06,0x1e,0x68,0x8b,0x25,0x6a,0x00,0x1f,0x8e,0xc0,0x26,0x83
+,0x3e,0x0a,0x00,0x00,0x74,0x03,0xe8,0x43,0x00,0x26,0xc7,0x06,0x0a,0x00,0xff,0xff
+,0x26,0x8b,0x16,0x06,0x00,0x8e,0x1e,0x8e,0x01,0x8c,0xd8,0x8b,0xca,0x83,0x3e,0x00
+,0x00,0xff,0x8e,0x1e,0x00,0x00,0x74,0x0a,0x2b,0x16,0x08,0x00,0x73,0xeb,0x29,0x0e
+,0x08,0x00,0x26,0x89,0x0e,0x08,0x00,0x26,0x8c,0x1e,0x00,0x00,0x8e,0xd8,0x8c,0x06
+,0x00,0x00,0xc3,0x60,0x06,0x1e,0x68,0x87,0x25,0x6a,0x00,0x1f,0x8e,0xc0,0x8b,0xc8
+,0x8e,0x1e,0x8e,0x01,0x26,0xc7,0x06,0x0a,0x00,0x00,0x00,0x8c,0xd8,0x83,0x3e,0x00
+,0x00,0xff,0x74,0x25,0x3b,0x0e,0x00,0x00,0x8e,0x1e,0x00,0x00,0x75,0xed,0x8e,0xd8
+,0x26,0xa1,0x00,0x00,0xa3,0x00,0x00,0x3d,0xff,0xff,0x74,0x56,0x8e,0xd8,0x26,0xa1
+,0x08,0x00,0x01,0x06,0x08,0x00,0xe9,0x49,0x00,0x26,0x8e,0x1e,0x02,0x00,0xbe,0x18
+,0x00,0x83,0x3c,0xff,0x74,0x3c,0x39,0x0c,0x74,0x19,0x8e,0x1c,0xbe,0x00,0x00,0x83
+,0x3e,0x00,0x00,0xff,0x74,0x2c,0x39,0x0e,0x00,0x00,0x74,0x07,0x8e,0x1e,0x00,0x00
+,0xe9,0xec,0xff,0x26,0xa1,0x00,0x00,0x89,0x04,0x33,0xc9,0x8e,0xd9,0x3d,0xff,0xff
+,0x75,0x10,0x83,0xfe,0x18,0x75,0x0b,0x26,0x8e,0x1e,0x02,0x00,0x81,0x26,0x08,0x00
+,0x7f,0xff,0x33,0xc0,0x8e,0xd8,0xc3,0x1f,0x07,0x61,0xcf,0x1f,0x07,0xcf,0x60,0x06
+,0x1e,0x68,0x87,0x25,0x6a,0x00,0x1f,0xe5,0x06,0x25,0x1e,0x00,0x3d,0x1e,0x00,0x75
+,0xf6,0xb9,0x08,0x00,0xe5,0x58,0xe7,0x5a,0x23,0xc0,0xe0,0xf8,0xc3,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x00,0x00,0x00,0xa8,0x00,0x8c,0x02,0x04,0x00
+,0x00,0x08,0x10,0x20,0x00,0xff,0x0e,0x0c,0x0c,0x0a,0x0a,0x0a,0x0a,0x08,0x08,0x08
+,0x08,0x08,0x08,0x08,0x08,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06
+,0x06,0x06,0x06,0x06,0x06,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
+,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
+,0x04,0x04,0x04,0x04,0x04,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02
+,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02
+,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02
+,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02
+,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x14,0x00,0x10,0x00,0x0c,0x00,0xff,0x7f,0xff
+,0xbf,0xff,0xdf,0xff,0xef,0xff,0xf7,0xff,0xfb,0xff,0xfd,0xff,0xfe,0x7f,0xff,0xbf
+,0xff,0xdf,0xff,0xef,0xff,0xf7,0xff,0xfb,0xff,0xfd,0xff,0xfe,0xff,0x00,0x00,0x00
+,0x80,0x3e,0xe2,0x34,0x01,0x76,0x03,0xe9,0xa5,0x00,0xb8,0x00,0x00,0xe7,0x4e,0xb9
+,0x28,0x00,0xe2,0xfe,0xc6,0x06,0x45,0x37,0x02,0xbf,0x3f,0x28,0x2e,0x8b,0x45,0x08
+,0xe7,0x4e,0xb9,0x28,0x00,0xe2,0xfe,0x2e,0x8b,0x1d,0xc7,0x06,0xb3,0x36,0x40,0x11
+,0xc7,0x06,0xb1,0x36,0x27,0x00,0xc7,0x06,0x46,0x37,0x02,0x00,0xc7,0x06,0x48,0x37
+,0x64,0x00,0xf7,0x06,0xb5,0x36,0x02,0x00,0x75,0x1c,0x2e,0x0b,0x5d,0x02,0x81,0x26
+,0xb3,0x36,0xff,0xfe,0xc7,0x06,0xb1,0x36,0x9c,0x00,0xc7,0x06,0x46,0x37,0x08,0x00
+,0xc7,0x06,0x48,0x37,0x90,0x01,0x89,0x1e,0xb7,0x36,0x89,0x1e,0xfe,0x33,0xbe,0x20
+,0x00,0x8b,0xc3,0xe7,0x4e,0xb9,0x28,0x00,0xe2,0xfe,0x2e,0x8b,0x45,0x04,0xe7,0x4e
+,0xb9,0x28,0x00,0xe2,0xfe,0xe5,0x4e,0x8b,0xcb,0x2e,0x23,0x45,0x06,0x2e,0x23,0x4d
+,0x06,0x3a,0xc1,0x74,0x36,0x4e,0x75,0xd9,0x80,0x3e,0x45,0x37,0x00,0x74,0x0b,0xc6
+,0x06,0x45,0x37,0x00,0xbf,0x2f,0x28,0xe9,0x72,0xff,0xc6,0x06,0x45,0x37,0x01,0xf7
+,0x06,0xb5,0x36,0x02,0x00,0x74,0x14,0xe5,0xce,0x25,0xfd,0xff,0xe7,0xce,0xe8,0x43
+,0x00,0xe5,0xce,0x0d,0x02,0x00,0xe7,0xce,0xe8,0x39,0x00,0x80,0x3e,0xe2,0x34,0x01
+,0x76,0x01,0xc3,0xb8,0xea,0x05,0xe7,0x8c,0xfa,0xe8,0x12,0xf4,0xfb,0x8d,0x06,0xd0
+,0x39,0x8b,0xd8,0xc1,0xe8,0x04,0xa3,0x38,0x34,0x8e,0xc0,0xa1,0x30,0x34,0x26,0xa3
+,0x02,0x00,0x26,0xc7,0x06,0x00,0x00,0xff,0xff,0x83,0xc3,0x18,0xd1,0xeb,0x26,0x89
+,0x1e,0x08,0x00,0xc3,0xe5,0x02,0x0d,0x00,0x40,0xe7,0x02,0xe5,0x00,0x0d,0x04,0x00
+,0xe7,0x00,0xb8,0x00,0x00,0xe7,0x0a,0xe5,0x0a,0xa9,0x00,0x80,0x75,0x14,0xe5,0x08
+,0x0d,0x00,0x10,0xe7,0x08,0xe5,0x0a,0x0d,0x00,0x08,0xb9,0x05,0x00,0xe7,0x0a,0xe2
+,0xfc,0xc3,0xe5,0x08,0x0d,0x00,0x10,0xb9,0x05,0x00,0xe7,0x08,0xe2,0xfc,0xc3,0x04
+,0x0c,0x20,0x00,0x01,0x0c,0x7e,0xff,0x00,0x0c,0x02,0x00,0x10,0x00,0x40,0x00,0x0c
+,0xc6,0x01,0x00,0x00,0xc0,0xf7,0xff,0x00,0xc0,0x02,0x00,0x10,0x00,0x40,0x00,0x00
+,0x33,0xc0,0x8e,0xd8,0x8d,0x3e,0x72,0x49,0x8d,0x36,0xb0,0x37,0xb9,0x14,0x00,0x8b
+,0x1e,0x30,0x34,0x89,0x5c,0x02,0x2e,0x8b,0x45,0x02,0x89,0x44,0x06,0x2e,0x8b,0x05
+,0x89,0x44,0x04,0x83,0xc7,0x04,0x83,0xc6,0x10,0xe2,0xe8,0xc6,0x06,0x9e,0x36,0x0e
+,0xe8,0xfd,0x26,0x68,0x83,0x28,0xa1,0xaa,0x02,0xcd,0x35,0x83,0x3e,0xa1,0x36,0x00
+,0x74,0x03,0xe9,0x3b,0x27,0x33,0xff,0x8e,0x06,0xa6,0x02,0x8b,0x36,0xa4,0x02,0x2e
+,0xff,0xa4,0x2e,0x30,0x83,0x0e,0x99,0x36,0x04,0xc7,0x06,0x37,0x37,0x01,0x00,0xc6
+,0x06,0xca,0x34,0x01,0xe9,0x7d,0x19,0x80,0x3e,0xa0,0x36,0x08,0x74,0xe6,0x80,0x26
+,0x9e,0x36,0xff,0x75,0x1a,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x12,0xf7,0x06,0x9b
+,0x36,0x03,0x00,0x75,0x0a,0x83,0x0e,0x66,0x37,0x10,0xc6,0x06,0xa0,0x36,0x08,0xe9
+,0xfb,0x01,0x80,0x3e,0x9e,0x36,0x02,0x75,0xce,0xc6,0x06,0xa0,0x36,0x06,0xe9,0xec
+,0x01,0xc3,0xe9,0xe8,0x01,0x26,0xc7,0x06,0x0a,0x00,0x00,0x00,0x26,0xff,0x26,0x04
+,0x00,0xa1,0xd1,0x36,0x26,0x39,0x06,0x1a,0x00,0x75,0x22,0xa1,0xd3,0x36,0x26,0x39
+,0x06,0x1c,0x00,0x75,0x18,0xa1,0xd5,0x36,0x26,0x39,0x06,0x1e,0x00,0x75,0x0e,0x26
+,0xf7,0x06,0x0c,0x00,0x40,0x00,0x74,0x05,0x83,0x0e,0x66,0x37,0x40,0x81,0x0e,0xaf
+,0x36,0x00,0x10,0xa1,0xaf,0x36,0xe7,0x06,0x80,0x3e,0x9d,0x36,0x02,0x75,0x06,0xcd
+,0x34,0xe9,0xa2,0x1a,0xc3,0xf7,0x06,0x9b,0x36,0x10,0x00,0x75,0x54,0x26,0xf6,0x06
+,0x0a,0x00,0xff,0x75,0x4c,0x26,0xa0,0x19,0x00,0x24,0xc0,0x3c,0x40,0x75,0x11,0x80
+,0x3e,0x95,0x36,0x00,0x74,0x3b,0x26,0xc7,0x06,0x04,0x00,0xff,0xff,0xe9,0x31,0x00
+,0xe8,0xf1,0x04,0xf7,0x06,0x9b,0x36,0x03,0x00,0x74,0x2f,0x8b,0xd8,0xb8,0x7d,0x03
+,0xcd,0x3a,0x8b,0xc3,0xc6,0x06,0xa0,0x36,0x06,0xf7,0x06,0x9b,0x36,0x02,0x00,0x75
+,0x05,0xc6,0x06,0xa0,0x36,0x04,0x81,0x0e,0x9b,0x36,0x80,0x00,0x83,0x26,0x9b,0x36
+,0xfc,0xe9,0x23,0x01,0xe8,0x87,0x1d,0xe9,0x33,0x01,0x50,0x26,0xa1,0x0c,0x00,0x25
+,0x07,0x00,0x3d,0x07,0x00,0x75,0x03,0xe9,0x84,0x00,0x3d,0x05,0x00,0x75,0x03,0xe9
+,0x7c,0x00,0x83,0x3e,0xe8,0x3a,0x04,0x74,0x75,0x83,0x3e,0xe8,0x3a,0x02,0x74,0x6e
+,0xf7,0x06,0xe6,0x34,0x18,0x80,0x75,0x03,0xe9,0x6a,0x00,0xf7,0x06,0xe6,0x34,0x00
+,0x80,0x74,0x35,0x26,0x80,0x3e,0x29,0x00,0x02,0x75,0x2d,0x51,0x56,0x57,0x8d,0x36
+,0x3e,0x34,0x8d,0x3e,0x20,0x00,0xb9,0x06,0x00,0xf3,0xa6,0x5f,0x5e,0x59,0x74,0x45
+,0x26,0xa1,0x20,0x00,0xa3,0x3e,0x34,0x26,0xa1,0x22,0x00,0xa3,0x40,0x34,0x26,0xa1
+,0x24,0x00,0xa3,0x42,0x34,0xe9,0x26,0x00,0xf7,0x06,0xe6,0x34,0x08,0x00,0x74,0x0b
+,0x26,0x80,0x3e,0x19,0x00,0x00,0x74,0x03,0xe9,0x13,0x00,0xf7,0x06,0xe6,0x34,0x10
+,0x00,0x74,0x12,0x26,0xa0,0x28,0x00,0xc0,0xe8,0x04,0x22,0xc0,0x74,0x07,0x26,0xc7
+,0x06,0x04,0x00,0xff,0xff,0x58,0x23,0xc0,0x74,0x03,0xe9,0x57,0xff,0x81,0x26,0x9b
+,0x36,0xff,0xfe,0x83,0xfe,0x06,0x7f,0x24,0x26,0xa1,0x20,0x00,0x3b,0x06,0xd1,0x36
+,0x75,0x1a,0x26,0xa1,0x22,0x00,0x3b,0x06,0xd3,0x36,0x75,0x10,0x26,0xa1,0x24,0x00
+,0x3b,0x06,0xd5,0x36,0x75,0x06,0x81,0x0e,0x9b,0x36,0x00,0x01,0x26,0xa1,0x20,0x00
+,0x25,0x7f,0xff,0xa3,0xb8,0x34,0x26,0xa1,0x22,0x00,0xa3,0xba,0x34,0x26,0xa1,0x24
+,0x00,0xa3,0xbc,0x34,0x8b,0xc6,0x86,0xc4,0xa3,0xc0,0x34,0xd1,0xe6,0x80,0xfc,0x09
+,0x74,0x03,0xe8,0xaa,0x1c,0x8b,0xc6,0x2e,0xff,0xa4,0x30,0x49,0x26,0xa1,0x0c,0x00
+,0x3d,0xff,0x7f,0x74,0x0f,0x26,0xff,0x26,0x04,0x00,0x8e,0x06,0x38,0x34,0xe8,0x36
+,0x06,0xcd,0x50,0xc3,0xe9,0x16,0x00,0xcd,0x34,0xe9,0x11,0x00,0xcd,0x34,0x89,0x36
+,0x3d,0x37,0xa1,0x9d,0x36,0xa3,0x3f,0x37,0xc6,0x06,0xa0,0x36,0x0c,0xe8,0x8e,0x00
+,0xa1,0x9f,0x36,0x22,0xe4,0x75,0x32,0xf7,0x06,0x4c,0x37,0x01,0x00,0x75,0x2a,0xf6
+,0x06,0x9d,0x36,0x80,0x74,0x07,0x88,0x26,0x9e,0x36,0xe9,0x31,0x00,0x3a,0x06,0x9d
+,0x36,0xa3,0x9d,0x36,0x74,0x28,0x8b,0xf0,0x2e,0xff,0xa4,0x0d,0x2b,0x44,0x29,0xee
+,0x42,0x19,0x44,0xcd,0x44,0x2f,0x45,0x5a,0x45,0x3a,0x26,0x9e,0x36,0x75,0x01,0xc3
+,0x32,0xc0,0x86,0xc4,0x8b,0xf0,0xa2,0x9e,0x36,0x2e,0xff,0xa4,0x20,0x49,0x8b,0x2e
+,0x99,0x36,0x23,0xed,0x75,0x01,0xc3,0xbf,0x01,0x00,0xbe,0x00,0x00,0x85,0xfd,0x75
+,0x1a,0x46,0xd1,0xe7,0xe9,0xf6,0xff,0x2a,0x00,0x29,0x00,0x28,0x00,0x27,0x00,0x25
+,0x00,0x05,0x00,0x07,0x00,0x26,0x00,0x06,0x00,0x20,0x00,0xf7,0xd7,0x21,0x3e,0x99
+,0x36,0xd1,0xe6,0x2e,0x8b,0xb4,0x47,0x2b,0xe9,0x4f,0xff,0xe9,0x56,0xff,0x80,0x26
+,0x9e,0x36,0xff,0x75,0x17,0xf7,0x06,0x4c,0x37,0x01,0x00,0x75,0x0f,0xf6,0x06,0x9d
+,0x36,0x80,0x74,0x08,0xf7,0x06,0x66,0x37,0xff,0xff,0x75,0x07,0xc7,0x06,0x66,0x37
+,0x00,0x00,0xc3,0xf7,0x06,0x41,0x37,0x01,0x00,0x75,0x0b,0xb8,0x7f,0x03,0xcd,0x39
+,0xc7,0x06,0x41,0x37,0x01,0x00,0x33,0xf6,0xb8,0x00,0x40,0x85,0x06,0x66,0x37,0x74
+,0x21,0x80,0xbc,0x54,0x37,0xff,0x74,0x04,0xfe,0x84,0x54,0x37,0x80,0xbc,0x96,0x34
+,0xff,0x74,0x04,0xfe,0x84,0x96,0x34,0x31,0x06,0x66,0x37,0x83,0x3e,0x66,0x37,0x00
+,0x74,0x05,0x46,0xd1,0xe8,0x73,0xd4,0xc3,0xa1,0xf4,0x33,0xa9,0x00,0x88,0x74,0x0b
+,0xa9,0x00,0x10,0x75,0x09,0x8b,0x1e,0x43,0x37,0xff,0xe3,0xe9,0xd7,0x00,0xc7,0x06
+,0x35,0x37,0x05,0x00,0xc7,0x06,0x43,0x37,0x1e,0x2c,0xf7,0x06,0xf4,0x33,0x00,0x08
+,0x74,0x06,0xc7,0x06,0x43,0x37,0x10,0x2c,0xb8,0x80,0x03,0xcd,0x39,0xe9,0xcd,0xfe
+,0xa9,0x00,0x08,0x74,0xd9,0xff,0x0e,0x35,0x37,0x75,0xed,0xe9,0x66,0x00,0xa9,0x00
+,0x08,0x75,0xcb,0xff,0x0e,0x35,0x37,0x75,0xdf,0x81,0x0e,0xc2,0x34,0xc0,0x00,0xf6
+,0x06,0x9d,0x36,0x80,0x74,0x48,0x81,0x0e,0x9b,0x36,0x00,0x80,0xf7,0x06,0x9b,0x36
+,0x01,0x00,0x74,0x1e,0xb8,0x7d,0x03,0xcd,0x3a,0x81,0x0e,0x9b,0x36,0x80,0x00,0x83
+,0x26,0x9b,0x36,0xfe,0xc7,0x06,0x0f,0x37,0x02,0x00,0xc6,0x06,0xa0,0x36,0x04,0xe9
+,0x7b,0xfe,0x80,0x3e,0xa0,0x36,0x04,0x75,0x07,0x83,0x3e,0x0f,0x37,0x01,0x75,0x05
+,0xc6,0x06,0xa0,0x36,0x06,0xc7,0x06,0x0f,0x37,0x02,0x00,0xe9,0x5f,0xfe,0xbe,0x02
+,0x00,0xe9,0x4a,0xfe,0x80,0x26,0x9e,0x36,0xff,0x75,0x3a,0xf6,0x06,0x9d,0x36,0x80
+,0x74,0x2d,0xf7,0x06,0x9b,0x36,0x00,0x20,0x75,0x2b,0xc6,0x06,0xa0,0x36,0x06,0xff
+,0x06,0x94,0x34,0x83,0x0e,0x66,0x37,0x20,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a
+,0x00,0x00,0x01,0x74,0x07,0x26,0x81,0x0e,0x08,0x00,0x00,0x01,0xe9,0x06,0x00,0xbe
+,0x04,0x00,0xe9,0x09,0xfe,0x81,0x0e,0xaf,0x36,0x00,0x08,0xa1,0xaf,0x36,0xe7,0x06
+,0xe5,0x0a,0xa9,0x00,0x80,0x74,0x0e,0x81,0x26,0xaf,0x36,0xff,0xf7,0xa1,0xaf,0x36
+,0xe7,0x06,0xe9,0x09,0xff,0xe9,0xf5,0xfd,0xc7,0x06,0x41,0x37,0x00,0x00,0x83,0x0e
+,0x99,0x36,0x02,0xe9,0xe7,0xfd,0x80,0x26,0x9e,0x36,0xff,0x75,0x1d,0xf7,0x06,0x9b
+,0x36,0x00,0x40,0x75,0x05,0x83,0x0e,0x99,0x36,0x08,0x83,0x0e,0x99,0x36,0x20,0x81
+,0x26,0x9b,0x36,0xff,0xbf,0xb8,0x85,0x03,0xcd,0x39,0xe9,0xc0,0xfd,0x80,0x3e,0x9e
+,0x36,0x06,0x74,0x07,0x80,0x3e,0x9e,0x36,0x0a,0x75,0x34,0xf6,0x06,0x9d,0x36,0x80
+,0x75,0x06,0xbe,0x07,0x00,0xe9,0x96,0xfd,0xc6,0x06,0xa0,0x36,0x04,0x83,0x3e,0x0f
+,0x37,0x02,0x74,0x1b,0xc7,0x06,0x0f,0x37,0x04,0x00,0x80,0x3e,0x9e,0x36,0x06,0x75
+,0x0e,0xf7,0x06,0x9b,0x36,0x40,0x00,0x75,0x06,0xc7,0x06,0x0f,0x37,0x03,0x00,0xe9
+,0x7b,0xfd,0x80,0x3e,0x9d,0x36,0x04,0x75,0x12,0x81,0x0e,0xc2,0x34,0x00,0x40,0xff
+,0x06,0x92,0x34,0xc6,0x06,0xa0,0x36,0x06,0xe9,0x62,0xfd,0xbe,0x05,0x00,0xe9,0x4d
+,0xfd,0xf6,0x06,0x9d,0x36,0x80,0x75,0x19,0x83,0x0e,0xc2,0x34,0x04,0xbe,0x06,0x00
+,0xe9,0x3b,0xfd,0x80,0x26,0x9e,0x36,0xff,0x75,0xc5,0xff,0x06,0x31,0x37,0xe9,0x00
+,0x00,0x83,0x26,0xc2,0x34,0xbf,0xc6,0x06,0xa0,0x36,0x06,0xe9,0x2f,0xfd,0xe5,0x0a
+,0x50,0x25,0xc3,0xbf,0xe7,0x0a,0x58,0x80,0x26,0x9e,0x36,0xff,0x75,0x0d,0xa9,0x00
+,0x40,0x75,0x08,0xc6,0x06,0xa0,0x36,0x06,0xe9,0x12,0xfd,0xb8,0x83,0x03,0xcd,0x39
+,0xc3,0xb8,0x7c,0x03,0xcd,0x39,0xf7,0x06,0xf4,0x33,0x00,0x10,0x75,0x09,0xc7,0x06
+,0x33,0x37,0x02,0x00,0xe9,0xf6,0xfc,0xff,0x0e,0x33,0x37,0x74,0x03,0xe9,0xed,0xfc
+,0xff,0x06,0x8e,0x34,0xe8,0xf7,0x19,0x83,0x0e,0xc2,0x34,0x08,0xbe,0x03,0x00,0xe9
+,0xcc,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x04,0x05
+,0x04,0x04,0x04,0x00,0x03,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x04,0x00,0x08,0x08,0x05,0x08,0x08,0x08,0x00,0x03,0x00,0x03,0x03,0x00,0x00
+,0x02,0x04,0x04,0x04,0x04,0x00,0x00,0x08,0x00,0x00,0x0a,0x14,0x00,0x00,0x1a,0x00
+,0x1c,0x00,0x1e,0x20,0x00,0x00,0x04,0x41,0x06,0x0b,0x08,0xc2,0xff,0xe7,0x04,0x03
+,0x06,0x04,0x04,0x05,0x04,0x06,0x04,0x87,0x04,0x03,0x06,0x04,0x04,0x85,0x4e,0xa2
+,0x04,0xcf,0x04,0xcd,0xc7,0x06,0xa2,0x37,0x00,0x00,0xc7,0x06,0xa6,0x37,0x00,0x00
+,0x26,0xa1,0x20,0x00,0x25,0x7f,0xff,0xa3,0xf5,0x36,0x26,0xa1,0x22,0x00,0xa3,0xf7
+,0x36,0x26,0xa1,0x24,0x00,0xa3,0xf9,0x36,0xe8,0x3b,0x19,0x8b,0xf0,0x26,0x8b,0x0e
+,0x0e,0x00,0x2b,0xc8,0x83,0xe9,0x0e,0xb8,0x01,0x80,0x83,0xf9,0x04,0x7c,0x51,0x26
+,0x8a,0x54,0x28,0x88,0x16,0x1c,0x37,0x40,0x26,0x8b,0x6c,0x26,0x86,0xcd,0x3b,0xcd
+,0x86,0xcd,0x89,0x0e,0xa4,0x37,0x75,0x38,0x40,0x32,0xff,0x26,0x8a,0x5c,0x29,0x80
+,0xfb,0x15,0x77,0x25,0x80,0xfb,0x0a,0x74,0x20,0x80,0xfb,0x01,0x74,0x1b,0xb8,0x04
+,0x80,0x2e,0x3a,0x97,0x02,0x2e,0x74,0x07,0x2e,0x3a,0x97,0x18,0x2e,0x75,0x11,0x33
+,0xc0,0x80,0xfb,0x09,0x75,0x4f,0x8b,0xf3,0xc3,0x26,0xc7,0x06,0x04,0x00,0xff,0xff
+,0x50,0x52,0xa1,0xa4,0x37,0x86,0xc4,0x26,0x3b,0x06,0x26,0x00,0x7c,0x32,0x26,0x81
+,0x3e,0x26,0x00,0x00,0x04,0x7e,0x29,0x8d,0x74,0x2a,0x26,0x8b,0x14,0x22,0xd2,0x74
+,0x1f,0x80,0xe6,0xbf,0x80,0xfe,0x09,0x75,0x17,0xc7,0x06,0xa2,0x37,0x01,0x00,0x80
+,0xfa,0x04,0x75,0x0c,0x26,0x8b,0x44,0x02,0xa3,0x03,0x37,0x86,0xc4,0xa3,0xd0,0x34
+,0x5a,0x58,0xe9,0xb1,0xff,0xbd,0x72,0x37,0x2e,0x8a,0x87,0x2e,0x2e,0x22,0xc0,0x74
+,0x16,0x05,0x44,0x2e,0x8b,0xf8,0x2e,0x8b,0x05,0x3e,0x89,0x46,0x00,0x83,0xc5,0x02
+,0x83,0xc7,0x02,0x22,0xe4,0x7d,0xef,0x8d,0x74,0x2a,0x83,0xe9,0x04,0x75,0x03,0xe9
+,0xa1,0x00,0x26,0x8b,0x14,0x22,0xd2,0x75,0x03,0xe9,0x7c,0x00,0xc7,0x06,0xa6,0x37
+,0x01,0x00,0xbf,0x72,0x37,0x8b,0x05,0x83,0xc7,0x02,0x80,0xe6,0xbf,0x80,0xe4,0x3f
+,0x80,0xfe,0x09,0x75,0x22,0x80,0xfa,0x04,0x75,0x5e,0xc7,0x06,0xa2,0x37,0x01,0x00
+,0x26,0x8b,0x44,0x02,0xa3,0x03,0x37,0x86,0xc4,0xa3,0xd0,0x34,0x86,0xc4,0xc7,0x06
+,0xa6,0x37,0x00,0x00,0xe9,0x47,0x00,0x3b,0xfd,0x7e,0x15,0x26,0x8b,0x04,0xa8,0x40
+,0x74,0x06,0xb8,0x07,0x80,0xe9,0x38,0xff,0x32,0xc0,0x26,0x8b,0x04,0xe9,0x2e,0x00
+,0x3a,0xf4,0x75,0xb1,0xc7,0x45,0xfe,0x00,0x00,0x80,0xfe,0x22,0x75,0x0d,0x3a,0xd0
+,0x77,0x16,0xc7,0x06,0xa6,0x37,0x00,0x00,0xe9,0x13,0x00,0x3a,0xd0,0x75,0x09,0xc7
+,0x06,0xa6,0x37,0x00,0x00,0xe9,0x06,0x00,0xb8,0x05,0x80,0xe9,0x02,0xff,0x32,0xf6
+,0x03,0xf2,0x2b,0xca,0xb8,0x05,0x80,0x23,0xc9,0x76,0x03,0xe9,0x64,0xff,0x74,0x03
+,0xe9,0xed,0xfe,0x33,0xc0,0xbf,0x72,0x37,0x8b,0x15,0x47,0x47,0x3b,0xfd,0x7f,0x1b
+,0xf6,0xc6,0x80,0x74,0x16,0xf7,0x06,0xa6,0x37,0x01,0x00,0x74,0x06,0xb8,0x08,0x80
+,0xe9,0xc3,0xfe,0xf6,0xc6,0x40,0x74,0xe0,0xb8,0x07,0x80,0xe9,0xb8,0xfe,0x7d,0x42
+,0xa3,0x45,0x44,0x29,0x44,0x29,0xb7,0x28,0xe2,0x28,0xee,0x2b,0xf2,0x28,0xf5,0x28
+,0x01,0x29,0xac,0x2a,0x44,0x29,0x44,0x29,0x44,0x29,0x44,0x29,0x44,0x29,0x00,0x00
+,0x73,0x36,0x00,0x00,0x03,0x36,0xc5,0x35,0x83,0x35,0x45,0x35,0x07,0x35,0xd2,0x34
+,0x45,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0xa6,0x38,0x00,0x00,0xe0,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0xf2,0x33,0x00,0x00,0xa6,0x33,0x60,0x33,0xfd,0x32,0xbc,0x32,0x77,0x32,0x3c,0x32
+,0xfb,0x31,0x6a,0x31,0x0a,0x31,0xe0,0xe0,0x10,0x10,0x10,0xe0,0xe0,0xe0,0xe0,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0
+,0xe0,0x33,0xff,0x26,0xf6,0x06,0x1a,0x00,0x80,0x74,0x1b,0x26,0x80,0x26,0x1a,0x00
+,0x7f,0x26,0x8b,0x3e,0x26,0x00,0x83,0xe7,0x1f,0x74,0x0b,0x26,0x80,0x0e,0x20,0x00
+,0x80,0x26,0x01,0x3e,0x0e,0x00,0xc3,0x60,0x2e,0x8b,0x84,0xa6,0x30,0x26,0xa3,0x18
+,0x00,0xd1,0xe6,0x2e,0xff,0x94,0x50,0x30,0x61,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4
+,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x16,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26
+,0xc6,0x06,0x19,0x00,0x00,0xe8,0xbf,0x05,0xe8,0x98,0x05,0x26,0xc7,0x06,0x26,0x00
+,0x00,0x08,0x26,0xc6,0x06,0x28,0x00,0x40,0x26,0xc6,0x06,0x29,0x00,0x2a,0xbf,0x2a
+,0x00,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x2a,0xa1,0x93,0x37,0x33,0xdb,0xa9
+,0x40,0x00,0x75,0x02,0xb3,0x01,0xa9,0x00,0x10,0x74,0x02,0xb7,0x88,0xa9,0x00,0x08
+,0x74,0x03,0x80,0xcf,0x44,0x26,0x89,0x5d,0x02,0xc3,0x83,0x0e,0xc2,0x34,0x20,0x26
+,0xc7,0x06,0x04,0x00,0x6b,0x2b,0x26,0xc7,0x06,0x0e,0x00,0x30,0x00,0x26,0xc7,0x06
+,0x06,0x00,0x0a,0x00,0x26,0xc7,0x06,0x0a,0x00,0x04,0x00,0x26,0xc6,0x06,0x19,0x00
+,0x00,0xe8,0x69,0x05,0xe8,0x2c,0x05,0x26,0xc7,0x06,0x26,0x00,0x00,0x22,0x26,0xc6
+,0x06,0x28,0x00,0x60,0x26,0xc6,0x06,0x29,0x00,0x29,0xbf,0x2a,0x00,0x26,0xc6,0x05
+,0x08,0x26,0xc6,0x45,0x01,0x2d,0x8d,0x7d,0x02,0xbe,0x54,0x37,0xb9,0x03,0x00,0xf3
+,0xa5,0x26,0xc6,0x05,0x08,0x26,0xc6,0x45,0x01,0x2e,0x8d,0x7d,0x02,0xbe,0x5a,0x37
+,0xb9,0x03,0x00,0xf3,0xa5,0xe8,0xd4,0x05,0xe8,0x64,0x05,0xb9,0x06,0x00,0xbe,0x54
+,0x37,0x8d,0x2e,0x2c,0x00,0x26,0x8b,0x46,0x00,0x29,0x04,0x83,0xc6,0x02,0x83,0xc5
+,0x02,0x83,0xf9,0x04,0x75,0x02,0x45,0x45,0xe2,0xeb,0xc3,0x26,0xc7,0x06,0x04,0x00
+,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x24,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00
+,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0xe4,0x04,0xe8,0xa7,0x04,0x26,0xc7,0x06,0x26
+,0x00,0x00,0x16,0x26,0xc6,0x06,0x28,0x00,0x60,0x26,0xc6,0x06,0x29,0x00,0x28,0xbf
+,0x2a,0x00,0xe8,0x5b,0x06,0xe8,0x74,0x05,0xe8,0x04,0x05,0xc3,0x26,0xc7,0x06,0x04
+,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x1a,0x00,0x26,0xc7,0x06,0x06,0x00,0x06
+,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0xa3,0x04,0xe8,0x66,0x04,0x26,0xc7,0x06
+,0x26,0x00,0x00,0x0c,0x26,0xc6,0x06,0x28,0x00,0x60,0x26,0xc6,0x06,0x29,0x00,0x27
+,0xbf,0x2a,0x00,0xe8,0x21,0x05,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7
+,0x06,0x0e,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x0a,0x00,0x26,0xc7,0x06,0x0a
+,0x00,0x04,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x4b,0x04,0xe8,0x24,0x04,0x26
+,0xc7,0x06,0x26,0x00,0x00,0x12,0x26,0xc6,0x06,0x28,0x00,0x40,0x26,0xc6,0x06,0x29
+,0x00,0x26,0xbf,0x2a,0x00,0xe8,0xf4,0x04,0xe8,0x84,0x04,0xc3,0x26,0xc7,0x06,0x04
+,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x34,0x00,0x26,0xc7,0x06,0x06,0x00,0x06
+,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x0d,0x04,0xe8,0xe6,0x03,0x26,0xc7,0x06
+,0x26,0x00,0x00,0x26,0x26,0xc6,0x06,0x28,0x00,0x40,0x26,0xc6,0x06,0x29,0x00,0x25
+,0xbf,0x2a,0x00,0xe8,0xb6,0x04,0xe8,0x46,0x04,0xe8,0xfa,0x04,0xc3,0x26,0xc7,0x06
+,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x38,0x00,0xa1,0xa2,0x37,0x50,0x0b
+,0xc0,0x75,0x07,0x26,0xc7,0x06,0x0e,0x00,0x34,0x00,0x26,0xc7,0x06,0x06,0x00,0x06
+,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x99,0x03,0xe8,0xa4,0xfd,0x26,0xc7,0x45
+,0x26,0x00,0x2a,0x58,0x0b,0xc0,0x75,0x06,0x26,0xc7,0x45,0x26,0x00,0x26,0xa1,0x1c
+,0x37,0xc1,0xe0,0x04,0x26,0x88,0x45,0x28,0x26,0xc6,0x45,0x29,0x24,0x83,0xc7,0x2a
+,0xe8,0x29,0x04,0xe8,0xa0,0x04,0xe8,0x22,0x05,0xe8,0xf8,0x03,0xe8,0x09,0x04,0xc3
+,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x32,0x00,0x26,0xc7
+,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x45,0x03,0xe8,0x50
+,0xfd,0x26,0xc7,0x45,0x26,0x00,0x24,0xa1,0x1c,0x37,0xc1,0xe0,0x04,0x26,0x88,0x45
+,0x28,0x26,0xc6,0x45,0x29,0x23,0x83,0xc7,0x2a,0xe8,0xe0,0x03,0xe8,0x6c,0x04,0xe8
+,0x8a,0x04,0xe8,0x9c,0x04,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06
+,0x0e,0x00,0x34,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00
+,0x00,0xe8,0xff,0x02,0xe8,0x0a,0xfd,0x26,0xc7,0x45,0x26,0x00,0x26,0xa1,0x1c,0x37
+,0xc1,0xe0,0x04,0x26,0x88,0x45,0x28,0x26,0xc6,0x45,0x29,0x22,0x83,0xc7,0x2a,0xe8
+,0x9a,0x03,0xe8,0xc7,0x03,0xe8,0x57,0x03,0xe8,0xf8,0x03,0xe8,0x78,0x04,0xe8,0x8a
+,0x04,0xc3,0x26,0xc7,0x06,0x04,0x00,0x74,0x45,0x26,0xc7,0x06,0x0e,0x00,0x3e,0x00
+,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc7,0x06,0x0a,0x00,0x04,0x00,0x26,0xc6
+,0x06,0x19,0x00,0x00,0xe8,0xfc,0x02,0xe8,0xa9,0x02,0x83,0x3e,0x8d,0x37,0x03,0x75
+,0x01,0x90,0x26,0xc7,0x06,0x26,0x00,0x00,0x30,0x26,0xc6,0x06,0x28,0x00,0x50,0x26
+,0xc6,0x06,0x29,0x00,0x20,0xbf,0x2a,0x00,0xe8,0xd0,0x03,0xe8,0x01,0x03,0xe8,0xb5
+,0x03,0xe8,0x9f,0x03,0xc3,0x26,0xc7,0x06,0x04,0x00,0x61,0x43,0xb9,0xf0,0x00,0x83
+,0xe9,0x02,0x26,0x89,0x0e,0x0e,0x00,0x26,0xc7,0x06,0x06,0x00,0x02,0x00,0x26,0xc6
+,0x06,0x19,0x00,0x00,0x26,0xc7,0x06,0x1a,0x00,0x00,0x00,0x26,0xc7,0x06,0x1c,0x00
+,0x00,0x00,0x26,0xc7,0x06,0x1e,0x00,0x00,0x00,0xe8,0x47,0x02,0x83,0xe9,0x0e,0x86
+,0xcd,0x26,0x89,0x0e,0x26,0x00,0x86,0xcd,0x26,0xc6,0x06,0x28,0x00,0x00,0x26,0xc6
+,0x06,0x29,0x00,0x08,0xbf,0x2a,0x00,0x83,0xe9,0x04,0x26,0x89,0x0d,0x26,0xc6,0x45
+,0x01,0x26,0x8d,0x7d,0x02,0x83,0xe9,0x02,0xbb,0x01,0x00,0xb8,0x30,0x30,0x4b,0x75
+,0x17,0xbb,0x0a,0x00,0x8a,0xc4,0x26,0x88,0x05,0xb0,0x31,0x80,0xc4,0x01,0x80,0xfc
+,0x3a,0x75,0x0a,0xb4,0x61,0xe9,0x05,0x00,0x26,0x88,0x05,0x04,0x01,0x47,0x49,0x75
+,0xdd,0xc3,0x26,0xc7,0x06,0x04,0x00,0x04,0x45,0x26,0xc7,0x06,0x0e,0x00,0x12,0x00
+,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00,0x01,0xe8,0xe5,0x01
+,0xe8,0xd0,0x01,0x26,0xc7,0x06,0x26,0x00,0x00,0x04,0x26,0xc6,0x06,0x28,0x00,0x00
+,0x26,0xc6,0x06,0x29,0x00,0x07,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7
+,0x06,0x0e,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19
+,0x00,0x06,0xe8,0x04,0x02,0xe8,0x9b,0x01,0x26,0xc7,0x06,0x26,0x00,0x00,0x12,0x26
+,0xc6,0x06,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x06,0xbf,0x2a,0x00,0xe8,0x6b
+,0x02,0xe8,0xfb,0x01,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e
+,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00,0x05
+,0xe8,0xc6,0x01,0xe8,0x5d,0x01,0x26,0xc7,0x06,0x26,0x00,0x00,0x12,0x26,0xc6,0x06
+,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x05,0xbf,0x2a,0x00,0xe8,0x2d,0x02,0xe8
+,0xbd,0x01,0xc3,0xff,0x06,0x82,0x34,0x26,0xc7,0x06,0x04,0x00,0x3d,0x41,0x26,0xc7
+,0x06,0x0e,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x0e,0x00,0x26,0xc6,0x06,0x19
+,0x00,0x04,0xe8,0x84,0x01,0xe8,0x1b,0x01,0x26,0xc7,0x06,0x26,0x00,0x00,0x12,0x26
+,0xc6,0x06,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x04,0xbf,0x2a,0x00,0xe8,0xeb
+,0x01,0xe8,0x7b,0x01,0xc3,0x26,0xc7,0x06,0x04,0x00,0x67,0x42,0x26,0xc7,0x06,0x0e
+,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x08,0x00,0x26,0xc6,0x06,0x19,0x00,0x03
+,0xe8,0x46,0x01,0xe8,0xdd,0x00,0x26,0xc7,0x06,0x26,0x00,0x00,0x12,0x26,0xc6,0x06
+,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x03,0xbf,0x2a,0x00,0xe8,0xad,0x01,0xe8
+,0x3d,0x01,0xc3,0xff,0x06,0x84,0x34,0x26,0xc7,0x06,0x04,0x00,0x67,0x42,0x26,0xc7
+,0x06,0x0e,0x00,0x24,0x00,0x26,0xc7,0x06,0x06,0x00,0x08,0x00,0x26,0xc6,0x06,0x19
+,0x00,0x02,0xe8,0x04,0x01,0xe8,0x9b,0x00,0x26,0xc7,0x06,0x26,0x00,0x00,0x16,0x26
+,0xc6,0x06,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x02,0xbf,0x2a,0x00,0x26,0xc6
+,0x05,0x04,0x26,0xc6,0x45,0x01,0x01,0xa1,0x0f,0x37,0x86,0xe0,0xf6,0x06,0x6f,0x37
+,0x01,0x75,0x0f,0x39,0x06,0xcc,0x34,0x74,0x09,0x8b,0xd8,0xb8,0x89,0x03,0xcd,0x39
+,0x8b,0xc3,0xa3,0xcc,0x34,0x26,0x89,0x45,0x02,0x8d,0x7d,0x04,0xe8,0x3d,0x01,0xe8
+,0xcd,0x00,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x1c
+,0x00,0xa1,0xa2,0x37,0x50,0x0b,0xc0,0x75,0x07,0x26,0xc7,0x06,0x0e,0x00,0x18,0x00
+,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x23,0x00
+,0xe8,0x2e,0xfa,0x26,0xc7,0x45,0x26,0x00,0x0e,0x58,0x0b,0xc0,0x75,0x06,0x26,0xc7
+,0x45,0x26,0x00,0x0a,0x26,0xc6,0x45,0x29,0x00,0x83,0xc7,0x2a,0xe8,0xbd,0x00,0xe8
+,0xff,0x00,0xc3,0x56,0x57,0x51,0xb9,0x03,0x00,0xbe,0xd1,0x36,0xbf,0x20,0x00,0xf3
+,0xa5,0x59,0x5f,0x5e,0xc3,0x56,0x57,0x51,0xb9,0x03,0x00,0xbe,0xd1,0x36,0xbf,0x1a
+,0x00,0xf3,0xa5,0x59,0x5f,0x5e,0xc3,0x26,0xc7,0x06,0x1a,0x00,0xc0,0x00,0x26,0xc7
+,0x06,0x1c,0x00,0x00,0x00,0x26,0xc7,0x06,0x1e,0x00,0x00,0x10,0xc3,0x26,0xc7,0x06
+,0x1a,0x00,0xc0,0x00,0x26,0xc7,0x06,0x1c,0x00,0x00,0x00,0x26,0xc7,0x06,0x1e,0x00
+,0x00,0x08,0xc3,0x26,0xc7,0x06,0x1a,0x00,0xc0,0x00,0x26,0xc7,0x06,0x1c,0x00,0x00
+,0x00,0x26,0xc7,0x06,0x1e,0x00,0x00,0x02,0xc3,0x26,0xc7,0x06,0x1a,0x00,0xc0,0x00
+,0x26,0xc7,0x06,0x1c,0x00,0xff,0xff,0x26,0xc7,0x06,0x1e,0x00,0xff,0xff,0xc3,0x26
+,0xc6,0x05,0x08,0x26,0xc6,0x45,0x01,0x02,0x8d,0x7d,0x02,0xbe,0x05,0x37,0xb9,0x03
+,0x00,0xf3,0xa5,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x06,0xa1,0x0d,0x37
+,0x26,0x89,0x45,0x02,0x8d,0x7d,0x04,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01
+,0x07,0xa1,0x0b,0x37,0x26,0x89,0x45,0x02,0x83,0xc7,0x04,0xc3,0xa1,0xa2,0x37,0x0b
+,0xc0,0x74,0x13,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x09,0xa1,0x03,0x37,0x26
+,0x89,0x45,0x02,0x83,0xc7,0x04,0xc3,0x26,0xc6,0x05,0x08,0x26,0xc6,0x45,0x01,0x02
+,0x8d,0x7d,0x02,0xbe,0x05,0x37,0xb9,0x03,0x00,0xf3,0xa5,0xc3,0x26,0xc6,0x05,0x06
+,0x26,0xc6,0x45,0x01,0x0b,0x8d,0x7d,0x02,0xbe,0xef,0x36,0xb9,0x02,0x00,0xf3,0xa5
+,0xc3,0x26,0xc6,0x05,0x06,0x26,0xc6,0x45,0x01,0x20,0xa1,0x68,0x37,0x26,0x89,0x45
+,0x02,0xa1,0x6a,0x37,0x26,0x88,0x65,0x05,0xc1,0xe0,0x04,0x26,0x88,0x45,0x04,0x83
+,0xc7,0x06,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x21,0x26,0xc7,0x45,0x02
+,0x00,0x00,0x83,0xc7,0x04,0xc3,0x26,0xc6,0x05,0x14,0x26,0xc6,0x45,0x01,0x22,0x8d
+,0x7d,0x02,0xbe,0x1f,0x37,0xb9,0x09,0x00,0xf3,0xa5,0xc3,0x26,0xc6,0x05,0x0c,0x26
+,0xc6,0x45,0x01,0x23,0x8d,0x7d,0x02,0x1e,0x0e,0x1f,0x8d,0x36,0x40,0x54,0xb9,0x03
+,0x00,0xf3,0xa5,0x33,0xc0,0xb9,0x02,0x00,0xf3,0xab,0x1f,0xc3,0x26,0xc6,0x05,0x08
+,0x26,0xc6,0x45,0x01,0x28,0x8d,0x7d,0x02,0xbe,0xd1,0x36,0xb9,0x03,0x00,0xf3,0xa5
+,0xc3,0x26,0xc6,0x05,0x08,0x26,0xc6,0x45,0x01,0x29,0xa1,0xc2,0x34,0x86,0xe0,0x26
+,0x89,0x45,0x02,0xa1,0x9b,0x36,0x26,0x89,0x45,0x04,0x26,0x88,0x45,0x06,0x26,0x88
+,0x45,0x07,0x8d,0x7d,0x08,0xc3,0x26,0xc6,0x05,0x06,0x26,0xc6,0x45,0x01,0x2b,0x8d
+,0x7d,0x02,0xbe,0xbb,0x36,0xb9,0x02,0x00,0xf3,0xa5,0xc3,0x26,0xc6,0x05,0x06,0x26
+,0xc6,0x45,0x01,0x2c,0x8d,0x7d,0x02,0xbe,0xe5,0x36,0xb9,0x02,0x00,0xf3,0xa5,0xc3
+,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x30,0xa1,0x37,0x37,0x86,0xe0,0x26,0x89
+,0x45,0x02,0x8d,0x7d,0x04,0xc3,0x26,0xc7,0x06,0x0e,0x00,0x1e,0x00,0x26,0xc7,0x06
+,0x06,0x00,0x02,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x6c,0xfe,0xe8,0x03,0xfe
+,0x26,0xc7,0x06,0x26,0x00,0x00,0x10,0x26,0xc6,0x06,0x28,0x00,0x30,0x26,0xc6,0x06
+,0x29,0x00,0x11,0xbf,0x2a,0x00,0xe8,0x35,0x00,0xe8,0x45,0x00,0xe8,0x55,0x00,0xc3
+,0x26,0xc7,0x06,0x0e,0x00,0x12,0x00,0x26,0xc7,0x06,0x06,0x00,0x02,0x00,0x26,0xc6
+,0x06,0x19,0x00,0x00,0xe8,0x32,0xfe,0xe8,0xc9,0xfd,0x26,0xc7,0x06,0x26,0x00,0x00
+,0x04,0x26,0xc6,0x06,0x28,0x00,0x30,0x26,0xc6,0x06,0x29,0x00,0x13,0xc3,0x26,0xc6
+,0x05,0x04,0x26,0xc6,0x45,0x01,0x0c,0x26,0xc7,0x45,0x02,0x00,0x01,0x83,0xc7,0x04
+,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x0e,0x26,0xc7,0x45,0x02,0x00,0x02
+,0x83,0xc7,0x04,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x21,0x26,0xc7,0x45
+,0x02,0x00,0x00,0x83,0xc7,0x04,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0xb3,0x39,0xc9,0x39,0x83,0x3a,0xb3,0x39,0xb3,0x39,0xb3,0x39,0x1c,0x3a,0x1c,0x3a
+,0xa3,0xb6,0x34,0xa1,0xe9,0x36,0xa3,0x11,0x37,0xa3,0xd2,0x34,0xa1,0xeb,0x36,0xa3
+,0x13,0x37,0xa3,0xd4,0x34,0xa1,0xed,0x36,0xa3,0x15,0x37,0xa3,0xd6,0x34,0xa1,0x01
+,0x37,0xa3,0xce,0x34,0xa1,0xf7,0x36,0xa3,0x17,0x37,0xa3,0xdc,0x34,0xa1,0xf9,0x36
+,0xa3,0x19,0x37,0xa3,0xde,0x34,0xf7,0x06,0x9b,0x36,0x02,0x00,0x75,0x0c,0x33,0xc0
+,0xa0,0x9e,0x36,0x8b,0xf0,0x2e,0xff,0xa4,0x50,0x39,0xe9,0x0f,0x01,0xbe,0x07,0x00
+,0xe9,0x19,0xf1,0xf6,0x06,0x9d,0x36,0x80,0x74,0xf3,0xc6,0x06,0xa0,0x36,0x02,0xc6
+,0x06,0x6e,0x37,0x08,0xc6,0x06,0x70,0x37,0x02,0xb8,0x88,0x03,0xcd,0x39,0xf6,0x06
+,0x6f,0x37,0x01,0x75,0x4a,0xa1,0xd1,0x36,0x3a,0x06,0xe9,0x36,0x75,0x41,0x3a,0x26
+,0xea,0x36,0x75,0x3b,0xa1,0xd3,0x36,0x3a,0x06,0xeb,0x36,0x75,0x32,0x3a,0x26,0xec
+,0x36,0x75,0x2c,0xa1,0xd5,0x36,0x3a,0x06,0xed,0x36,0x75,0x23,0x3a,0x26,0xee,0x36
+,0x75,0x1d,0xc6,0x06,0x70,0x37,0x02,0xfe,0x0e,0x6e,0x37,0x75,0x0f,0xb8,0x88,0x03
+,0xcd,0x3a,0x83,0x0e,0x9b,0x36,0x12,0xc6,0x06,0xa0,0x36,0x0c,0xe9,0xa8,0xf0,0xa1
+,0x05,0x37,0x26,0x3b,0x06,0x20,0x00,0x75,0x40,0xa1,0x07,0x37,0x26,0x3b,0x06,0x22
+,0x00,0x75,0x36,0xa1,0x09,0x37,0x26,0x3b,0x06,0x24,0x00,0x75,0x2c,0xa0,0x9e,0x36
+,0x3c,0x02,0x75,0x08,0x26,0xf6,0x06,0x18,0x00,0x08,0x75,0x47,0xc6,0x06,0x6e,0x37
+,0x08,0xfe,0x0e,0x70,0x37,0x75,0x1c,0xc6,0x06,0x70,0x37,0x02,0xe5,0x02,0x0d,0x01
+,0x04,0x25,0xef,0xff,0xe7,0x02,0xe9,0x5e,0xf0,0xc6,0x06,0x70,0x37,0x02,0xc6,0x06
+,0x6e,0x37,0x08,0xe5,0x02,0x25,0xff,0xfb,0x0d,0x01,0x00,0x25,0xef,0xff,0xe7,0x02
+,0xe9,0x44,0xf0,0xf7,0x06,0x9b,0x36,0x00,0x01,0x74,0x25,0x26,0xf6,0x06,0x18,0x00
+,0x08,0x75,0xed,0x81,0x26,0x9b,0x36,0x7f,0xff,0xb8,0x89,0x03,0xcd,0x3a,0xb8,0x84
+,0x03,0xcd,0x3a,0xc6,0x06,0xa0,0x36,0x06,0x83,0x26,0xc2,0x34,0xaf,0xe9,0x17,0xf0
+,0xa1,0x01,0x37,0x3a,0x26,0x0f,0x37,0x7f,0xc7,0xe9,0xf7,0xfe,0x83,0x26,0x9b,0x36
+,0xec,0xe8,0x2a,0x0d,0x81,0x0e,0x9b,0x36,0x80,0x00,0xbb,0xff,0x7f,0xcd,0x53,0xc6
+,0x06,0xa0,0x36,0x02,0xe9,0xf0,0xef,0x83,0x0e,0x9b,0x36,0x11,0xc6,0x06,0xa0,0x36
+,0x0c,0xe9,0xf9,0xef,0x44,0x3b,0x2c,0x3b,0xc7,0x2a,0x6b,0x3b,0x44,0x3b,0xc7,0x2a
+,0xc7,0x2a,0xc7,0x2a,0xa3,0xb6,0x34,0x81,0x0e,0xc2,0x34,0x00,0x20,0xf7,0x06,0x41
+,0x37,0x01,0x00,0x74,0x1b,0x8c,0xc3,0xc7,0x06,0x41,0x37,0x00,0x00,0xb8,0x7f,0x03
+,0xcd,0x3a,0x33,0xc0,0x8e,0xc0,0xbf,0x54,0x37,0xb9,0x06,0x00,0xf3,0xab,0x8e,0xc3
+,0x33,0xc0,0xa0,0x9e,0x36,0x8b,0xf0,0x2e,0xff,0xa4,0xe4,0x3a,0xf7,0x06,0x9b,0x36
+,0x00,0x01,0x75,0x21,0x83,0x26,0xc2,0x34,0xbf,0xa1,0xa9,0x36,0xe7,0x00,0xa1,0x9b
+,0x36,0xe9,0x09,0x00,0xa1,0x9b,0x36,0x81,0x26,0x9b,0x36,0xff,0xdf,0xa9,0x00,0x20
+,0x75,0x06,0xe9,0x6e,0x00,0xe9,0x6f,0xef,0x83,0x0e,0x99,0x36,0x04,0xc7,0x06,0x37
+,0x37,0x01,0x00,0xc6,0x06,0xca,0x34,0x01,0xe9,0x58,0x00,0x83,0x0e,0x9b,0x36,0x40
+,0xe8,0x58,0x00,0xa1,0x05,0x37,0x3b,0x06,0xe9,0x36,0x75,0x37,0xa1,0x07,0x37,0x3b
+,0x06,0xeb,0x36,0x75,0x2e,0xa1,0x09,0x37,0x3b,0x06,0xed,0x36,0x75,0x25,0xfe,0x0e
+,0x71,0x37,0x75,0x1c,0xb8,0x87,0x03,0xcd,0x3a,0x83,0x0e,0x99,0x36,0x10,0xa1,0x50
+,0x37,0xc7,0x06,0x50,0x37,0x00,0x00,0x09,0x06,0x99,0x36,0xc6,0x06,0xa0,0x36,0x08
+,0xe9,0x14,0xef,0x83,0x0e,0x99,0x36,0x04,0xc7,0x06,0x37,0x37,0x03,0x00,0xc6,0x06
+,0xca,0x34,0x03,0xc6,0x06,0xa0,0x36,0x0a,0xe9,0xfc,0xee,0xa1,0xd1,0x36,0x26,0x3b
+,0x06,0x20,0x00,0x75,0x15,0xa1,0xd3,0x36,0x26,0x3b,0x06,0x22,0x00,0x75,0x12,0xa1
+,0xd5,0x36,0x26,0x3b,0x06,0x24,0x00,0x75,0x0f,0xc3,0x8d,0x36,0x20,0x00,0xe9,0x0b
+,0x00,0x8d,0x36,0x22,0x00,0xe9,0x04,0x00,0x8d,0x36,0x24,0x00,0x83,0xc4,0x02,0xf7
+,0x06,0xe6,0x34,0x01,0x00,0x74,0x15,0x26,0x3a,0x04,0x77,0x08,0x72,0x0e,0x26,0x3a
+,0x64,0x01,0x72,0x08,0xc6,0x06,0xa0,0x36,0x06,0xe9,0xab,0xee,0xe8,0x7c,0x0a,0x8c
+,0xc0,0x3d,0xff,0xff,0x74,0x1b,0x26,0xc6,0x06,0x18,0x00,0x10,0x26,0xc7,0x06,0x04
+,0x00,0x49,0x3c,0x26,0xc7,0x06,0x06,0x00,0x0c,0x00,0xcd,0x50,0xb9,0x4e,0x00,0xe2
+,0xfe,0xc6,0x06,0xa0,0x36,0x0a,0xe9,0x94,0xee,0xe9,0x7b,0xee,0x8f,0x3c,0x06,0x3d
+,0x06,0x3d,0x06,0x3d,0xd2,0x3c,0xea,0x3c,0x06,0x3d,0x06,0x3d,0xa3,0xb6,0x34,0x81
+,0x26,0xc2,0x34,0xaf,0xdf,0xc7,0x06,0x4c,0x37,0x00,0x00,0xb8,0x8a,0x03,0xcd,0x3a
+,0x80,0x3e,0x9d,0x36,0x04,0x75,0x0c,0x80,0x3e,0x9e,0x36,0x06,0x74,0x05,0xc6,0x06
+,0x9f,0x36,0x06,0x33,0xc0,0xa0,0x9e,0x36,0x8b,0xf0,0x2e,0xff,0xa4,0x4c,0x3c,0xf7
+,0x06,0x9b,0x36,0x00,0x20,0x75,0x0e,0x81,0x26,0x9b,0x36,0xff,0xbf,0xb8,0x8b,0x03
+,0xcd,0x3a,0xe9,0x54,0x00,0xf7,0x06,0x9b,0x36,0x00,0x01,0x74,0x03,0xe9,0x17,0xee
+,0xc7,0x06,0x37,0x37,0x02,0x00,0xc6,0x06,0xca,0x34,0x02,0x83,0x0e,0x99,0x36,0x04
+,0x83,0x0e,0x50,0x37,0x04,0xf6,0x06,0x9d,0x36,0x80,0x75,0x2a,0xe8,0x1f,0x0b,0xe9
+,0x27,0x00,0xf7,0x06,0x9b,0x36,0x00,0x01,0x75,0xd3,0xc7,0x06,0x37,0x37,0x02,0x00
+,0xc6,0x06,0xca,0x34,0x02,0x83,0x0e,0x99,0x36,0x04,0xc6,0x06,0xa0,0x36,0x00,0xf6
+,0x06,0x9d,0x36,0x80,0x74,0x03,0xe8,0xde,0x0a,0x81,0x26,0x9b,0x36,0x7c,0xff,0xbb
+,0xff,0xff,0xcd,0x53,0xcd,0x54,0xe9,0xbe,0xed,0xa3,0xb6,0x34,0xe8,0xad,0x01,0xb8
+,0x86,0x03,0xcd,0x39,0xc7,0x06,0x4c,0x37,0x00,0x00,0x81,0x26,0xc2,0x34,0xaf,0xdf
+,0xf6,0x06,0x9d,0x36,0x80,0x74,0x34,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x56,0xf7
+,0x06,0x9b,0x36,0x00,0x01,0x74,0x27,0xe8,0x35,0x01,0x72,0x1c,0xbe,0x00,0x40,0x85
+,0x36,0xc2,0x34,0x75,0x08,0x09,0x36,0xc2,0x34,0xff,0x06,0x92,0x34,0xe8,0x8b,0x01
+,0x73,0x06,0x81,0x0e,0x99,0x36,0x80,0x00,0xe9,0x6c,0xed,0xe9,0xb5,0x00,0xc7,0x06
+,0x37,0x37,0x02,0x00,0xc6,0x06,0xca,0x34,0x02,0x83,0x0e,0x99,0x36,0x04,0x83,0x0e
+,0x50,0x37,0x04,0x80,0x3e,0x9e,0x36,0x08,0x74,0x03,0xe8,0x5a,0x0a,0xe8,0xef,0x00
+,0x72,0xd6,0xe9,0xc8,0xff,0x80,0x3e,0x9e,0x36,0x0a,0x75,0x12,0xc6,0x06,0xa0,0x36
+,0x00,0xf7,0x06,0x9b,0x36,0x08,0x00,0x74,0x02,0xcd,0x54,0xe8,0x39,0x0a,0x81,0x26
+,0x9b,0x36,0xff,0xbf,0xe8,0xc8,0x00,0x72,0xaf,0xb8,0x8b,0x03,0xcd,0x39,0xe9,0x9c
+,0xff,0xf6,0x06,0x9e,0x36,0xff,0x75,0x58,0xa3,0xb6,0x34,0xe8,0xfe,0x00,0x81,0x26
+,0xc2,0x34,0xff,0xbf,0xf6,0x06,0x9d,0x36,0x80,0x74,0x48,0xf7,0x06,0x9b,0x36,0x00
+,0x20,0x74,0x22,0xf7,0x06,0x9b,0x36,0x00,0x40,0x75,0x08,0xe8,0x91,0x00,0x72,0x30
+,0xe9,0x22,0x00,0x26,0xa1,0x0c,0x00,0xa9,0x60,0x00,0x75,0x24,0x81,0x0e,0x66,0x37
+,0x00,0x08,0xe9,0xd2,0xec,0xc7,0x06,0x4c,0x37,0x00,0x00,0xe8,0x71,0x00,0x72,0x10
+,0xb8,0x8b,0x03,0xcd,0x39,0xe8,0xd3,0x00,0x73,0x06,0x81,0x0e,0x99,0x36,0x80,0x00
+,0xe9,0xb4,0xec,0x80,0x3e,0x9d,0x36,0x04,0x75,0x0c,0x80,0x3e,0x9e,0x36,0x06,0x74
+,0x46,0xc6,0x06,0x9f,0x36,0x06,0xf7,0x06,0x9b,0x36,0x00,0x01,0x74,0x0c,0x80,0x3e
+,0x9d,0x36,0x08,0x75,0x05,0xc6,0x06,0x9f,0x36,0x0a,0xe8,0x32,0x00,0x72,0xd1,0xe8
+,0x99,0x00,0x80,0x3e,0x9d,0x36,0x08,0x75,0x13,0x81,0x0e,0x99,0x36,0x80,0x00,0xf7
+,0x06,0x9b,0x36,0x00,0x20,0x75,0x08,0xb8,0x8b,0x03,0xcd,0x39,0xe9,0x68,0xec,0xc6
+,0x06,0x9f,0x36,0x0a,0xe9,0x60,0xec,0xb8,0x86,0x03,0xcd,0x3a,0xe9,0x58,0xec,0x26
+,0xa1,0x0c,0x00,0xa9,0x60,0x00,0x74,0x08,0x81,0x26,0xc2,0x34,0xff,0xbf,0xf9,0xc3
+,0xf7,0x06,0x9b,0x36,0x00,0x40,0x74,0x13,0x81,0x0e,0x66,0x37,0x00,0x08,0xe8,0x4a
+,0x00,0x73,0x06,0x81,0x0e,0x99,0x36,0x80,0x00,0xf9,0xc3,0x81,0x0e,0x9b,0x36,0x00
+,0x40,0x80,0x26,0x6f,0x37,0xfe,0x81,0x26,0x9b,0x36,0x7f,0xff,0xc6,0x06,0xa0,0x36
+,0x00,0xf8,0xc3,0x81,0x0e,0x99,0x36,0x00,0x01,0xe9,0x21,0xec,0x26,0xa1,0x20,0x00
+,0xa3,0xfb,0x36,0xa3,0xaa,0x34,0x26,0xa1,0x22,0x00,0xa3,0xfd,0x36,0xa3,0xac,0x34
+,0x26,0xa1,0x24,0x00,0xa3,0xff,0x36,0xa3,0xae,0x34,0xc3,0xa1,0x05,0x37,0x26,0x3b
+,0x06,0x20,0x00,0x75,0x19,0xa1,0x07,0x37,0x26,0x3b,0x06,0x22,0x00,0x75,0x0f,0xa1
+,0x09,0x37,0x26,0x3b,0x06,0x24,0x00,0x75,0x05,0xe8,0x02,0x00,0xf8,0xc3,0x51,0x1e
+,0x06,0x8b,0xc7,0x8d,0x36,0x20,0x00,0xbf,0x05,0x37,0xb9,0x03,0x00,0x1e,0x06,0x1f
+,0x07,0xf3,0xa5,0x8b,0xf8,0x8d,0x36,0x20,0x00,0xbf,0xa0,0x34,0xb9,0x03,0x00,0xf3
+,0xa5,0x07,0x1f,0x59,0x8b,0xf8,0xa1,0x07,0x37,0xa3,0xa6,0x34,0xa1,0x09,0x37,0xa3
+,0xa8,0x34,0xf9,0xc3,0xc6,0x06,0xb6,0x34,0x01,0xe9,0x8b,0xeb,0xe8,0x87,0x08,0x8b
+,0xf0,0x05,0x12,0x00,0x26,0x29,0x06,0x0e,0x00,0x26,0x8b,0x44,0x2a,0x26,0x3a,0x06
+,0x0e,0x00,0x75,0x5b,0x26,0x83,0x2e,0x0e,0x00,0x02,0x80,0xfc,0x27,0x75,0x50,0x26
+,0x8b,0x44,0x2c,0xa9,0xff,0xff,0x75,0x47,0x8b,0xfe,0x33,0xc0,0x26,0xf6,0x45,0x3c
+,0x80,0x74,0x06,0x26,0x8a,0x45,0x3a,0x24,0x1f,0x03,0xf8,0x26,0x80,0x7d,0x45,0x09
+,0x75,0x2d,0x8c,0xc2,0x8e,0x06,0x38,0x34,0x8e,0xda,0x8b,0x0e,0x0e,0x00,0x26,0x89
+,0x0e,0x0e,0x00,0x8d,0x74,0x2c,0xbf,0x18,0x00,0xf3,0xa4,0x33,0xc0,0x8e,0xd8,0x26
+,0xc7,0x06,0x04,0x00,0xb5,0x3f,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0xcd,0x50,0xb8
+,0x06,0x80,0xe9,0xef,0xe9,0x26,0xa1,0x0c,0x00,0xa3,0x93,0x37,0x83,0x0e,0x99,0x36
+,0x01,0xe9,0x00,0xeb,0x26,0x80,0x3e,0x1c,0x00,0xff,0x75,0x2f,0x26,0x80,0x3e,0x1e
+,0x00,0xff,0x75,0x27,0x26,0xf7,0x06,0x0c,0x00,0x40,0x00,0x75,0x1b,0xa1,0xd1,0x36
+,0x26,0xa3,0x1a,0x00,0xa1,0xd3,0x36,0x26,0xa3,0x1c,0x00,0xa1,0xd5,0x36,0x26,0xa3
+,0x1e,0x00,0xb8,0x0a,0x80,0xe8,0x36,0x07,0xe9,0xe2,0xea,0xff,0x06,0x90,0x34,0xbe
+,0x0a,0x00,0xc6,0x06,0xb6,0x34,0x01,0xf6,0x06,0x9d,0x36,0x80,0x75,0x05,0x83,0x0e
+,0xc2,0x34,0x01,0xe9,0xb6,0xea,0x80,0x3e,0x9d,0x36,0x0a,0x75,0x0f,0x26,0xa1,0x0c
+,0x00,0x25,0x07,0x00,0x3d,0x04,0x00,0x75,0x03,0xe8,0x79,0x00,0xa1,0xf3,0x36,0x86
+,0xe0,0xe7,0x1e,0xa3,0xe3,0x36,0x81,0x26,0x0b,0x37,0x00,0x03,0x81,0x26,0x0d,0x37
+,0x7b,0x7f,0x83,0x0e,0x0d,0x37,0x48,0xe8,0x1e,0x00,0x26,0xa1,0x0c,0x00,0x25,0x07
+,0x00,0x3d,0x04,0x00,0x74,0x09,0x26,0xf7,0x06,0x0c,0x00,0x20,0x00,0x75,0x06,0xb8
+,0x01,0x00,0xe9,0x3f,0xe9,0xe9,0x5f,0xea,0xc7,0x06,0x41,0x37,0x00,0x00,0xb8,0x7f
+,0x03,0xcd,0x3a,0xa1,0x1d,0x37,0xa3,0xc4,0x34,0x86,0xe0,0x68,0x7f,0x03,0x1f,0xa3
+,0x06,0x00,0x33,0xc0,0x8e,0xd8,0xa1,0x0b,0x37,0xa3,0xb2,0x34,0xa1,0x0d,0x37,0xa3
+,0xb4,0x34,0xa1,0xf3,0x36,0xa3,0xc8,0x34,0xa1,0xef,0x36,0xa3,0x9c,0x34,0xa1,0xf1
+,0x36,0xa3,0x9e,0x34,0xc3,0x80,0x0e,0x9d,0x36,0x80,0xbe,0x00,0x00,0xe8,0xb4,0x07
+,0xb8,0x7b,0x03,0xcd,0x3a,0xb8,0x7c,0x03,0xcd,0x39,0xc7,0x06,0x33,0x37,0x02,0x00
+,0xa1,0xe5,0x36,0xe7,0x2e,0xa1,0xe7,0x36,0xe7,0x3e,0xb8,0x82,0x03,0xcd,0x3a,0xf7
+,0x06,0x9b,0x36,0x00,0x20,0x75,0x03,0xe8,0xfd,0x06,0xa1,0xd3,0x36,0xa3,0xef,0x36
+,0xa3,0x9c,0x34,0xa1,0xd5,0x36,0xa3,0xf1,0x36,0xa3,0x9e,0x34,0xc3,0xf6,0x06,0x9d
+,0x36,0x80,0x74,0x31,0xbe,0x22,0x00,0xe9,0x17,0x00,0xf6,0x06,0x9d,0x36,0x80,0x74
+,0x24,0xbe,0x23,0x00,0xe9,0x0a,0x00,0xf6,0x06,0x9d,0x36,0x80,0x74,0x17,0xbe,0x24
+,0x00,0x56,0xe8,0xa8,0x05,0x8c,0xc0,0x3d,0xff,0xff,0x5e,0x74,0x05,0xe8,0xd7,0xef
+,0xcd,0x50,0xe9,0x1f,0xe8,0xe9,0x9f,0xe9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0xb8,0x84,0x03,0xcd,0x3a,0xb8,0x8a,0x03,0xcd,0x39,0xe9,0xf7,0x00,0x80,0x3e,0xa0
+,0x36,0x08,0x75,0x2e,0xa9,0xd0,0x07,0x75,0x2c,0xa1,0xb1,0x36,0x0d,0x00,0x04,0xe7
+,0x08,0xe5,0x00,0x25,0xff,0x73,0xe7,0x00,0xb8,0x8a,0x03,0xcd,0x3a,0xe8,0xc3,0x06
+,0x33,0xc0,0xe7,0x0e,0xe5,0x0a,0x25,0xc3,0x17,0xe7,0x0a,0xcd,0x54,0xc6,0x06,0xa0
+,0x36,0x00,0xe9,0x68,0xe9,0xbe,0x04,0x00,0xe9,0x3f,0xe9,0x83,0x26,0x9b,0x36,0xbf
+,0xc6,0x06,0x71,0x37,0x03,0xb8,0x86,0x03,0xcd,0x3a,0xb8,0x88,0x03,0xcd,0x3a,0xb8
+,0x83,0x03,0xcd,0x3a,0xb8,0x87,0x03,0xcd,0x39,0x81,0x0e,0xc2,0x34,0x00,0x20,0xe9
+,0x92,0x00,0xe8,0x49,0x06,0xb8,0x87,0x03,0xcd,0x39,0xbb,0xff,0x7f,0xcd,0x53,0xb8
+,0x84,0x03,0xcd,0x3a,0xb8,0x88,0x03,0xcd,0x3a,0xb8,0x8b,0x03,0xcd,0x3a,0xb8,0x83
+,0x03,0xcd,0x3a,0xb8,0x86,0x03,0xcd,0x3a,0xb8,0x85,0x03,0xcd,0x3a,0xc3,0xe5,0x00
+,0x25,0xff,0x53,0xe7,0x00,0x83,0x0e,0xc2,0x34,0x40,0x83,0x26,0xc2,0x34,0xef,0xe8
+,0x0c,0x06,0xbb,0xff,0x7f,0xcd,0x53,0xb8,0x8a,0x03,0xcd,0x3a,0xb8,0x85,0x03,0xcd
+,0x3a,0xb8,0x86,0x03,0xcd,0x3a,0xb8,0x83,0x03,0xcd,0x3a,0xb8,0x87,0x03,0xcd,0x3a
+,0xb8,0x8b,0x03,0xcd,0x3a,0xb8,0x84,0x03,0xcd,0x3a,0xb8,0x89,0x03,0xcd,0x3a,0xc3
+,0x83,0x0e,0xc2,0x34,0x50,0xe8,0x18,0x04,0xe8,0xd3,0x05,0xf6,0x06,0x6f,0x37,0x01
+,0x75,0x12,0xb8,0x89,0x03,0xcd,0x39,0x83,0x3e,0x0f,0x37,0x00,0x75,0x06,0xc7,0x06
+,0x0f,0x37,0x04,0x00,0xa1,0x9d,0x36,0x80,0xfc,0x08,0x74,0x05,0xb8,0x84,0x03,0xcd
+,0x39,0xe5,0x02,0x0d,0x01,0x08,0x25,0xef,0xff,0xe7,0x02,0xa1,0x9d,0x36,0x86,0xe0
+,0x32,0xe4,0x8b,0xf0,0xd1,0xee,0x33,0xc0,0x0d,0x20,0x00,0x09,0x06,0xad,0x36,0xa1
+,0xad,0x36,0xe7,0x04,0xe9,0x53,0xe8,0xe9,0x5a,0xe8,0x33,0xc0,0xa0,0x1b,0x37,0xd1
+,0xe0,0x3a,0x06,0xa0,0x36,0x75,0x03,0xe9,0xba,0xff,0xe9,0x60,0xe8,0xc7,0x06,0x41
+,0x37,0x00,0x00,0xe8,0xc1,0xe1,0xe8,0x6a,0x06,0x33,0xc0,0x0d,0x41,0x00,0xe7,0x56
+,0xa1,0xb1,0x36,0x0d,0x00,0x10,0xe7,0x08,0xe5,0x02,0x25,0xf9,0xff,0x0d,0x03,0x00
+,0xe7,0x02,0xa1,0xb3,0x36,0xe7,0x0a,0xa1,0xaf,0x36,0xe7,0x06,0xa1,0xad,0x36,0xe7
+,0x04,0xe8,0x7c,0x03,0xe8,0x9f,0x03,0xc7,0x06,0x1d,0x37,0x00,0xc8,0xc7,0x06,0x0b
+,0x37,0x00,0x03,0xc7,0x06,0x0d,0x37,0x7b,0x7f,0x33,0xc0,0xa3,0x99,0x36,0xa3,0x9b
+,0x36,0xa3,0x9d,0x36,0xa3,0x9f,0x36,0xa3,0x4c,0x37,0xa3,0xf3,0x36,0xa3,0xef,0x36
+,0xa3,0xf1,0x36,0xe8,0x82,0xfd,0xc6,0x06,0x9f,0x36,0x02,0xe9,0xef,0xe7,0xe5,0x02
+,0x0d,0x01,0x88,0x25,0xef,0xff,0x0d,0x00,0x40,0x0d,0x00,0x04,0xe7,0x02,0xe8,0xf2
+,0x05,0xe5,0x0a,0x0d,0x40,0x00,0xe7,0x0a,0x33,0xc0,0xa3,0x81,0x37,0xa3,0x85,0x37
+,0xa3,0x83,0x37,0xa3,0x87,0x37,0xa3,0x89,0x37,0xe5,0x00,0x0d,0x00,0x84,0xe7,0x00
+,0xb8,0x8c,0x03,0xcd,0x39,0xb8,0x80,0x00,0xcd,0x35,0xc7,0x06,0xaa,0x02,0xff,0xff
+,0xe5,0x00,0x25,0xff,0x7b,0xe7,0x00,0x81,0x0e,0x9a,0x37,0x80,0x00,0xb8,0x7e,0x03
+,0xcd,0x39,0x33,0xc0,0xe7,0x0e,0xbe,0x08,0x00,0x8e,0x06,0x38,0x34,0xe8,0xa7,0xed
+,0x83,0x26,0xef,0x34,0xdf,0xff,0x06,0x81,0x37,0xcd,0x50,0x83,0x0e,0xef,0x34,0x20
+,0xc3,0xf7,0x06,0x9a,0x37,0x80,0x00,0x74,0x3d,0xa9,0xd0,0x07,0x74,0x10,0xa9,0x00
+,0x04,0x74,0x12,0x33,0xc0,0xe7,0x0e,0xff,0x06,0x87,0x37,0xe9,0xd2,0xff,0xff,0x06
+,0x85,0x37,0xe9,0xcb,0xff,0xff,0x06,0x83,0x37,0xe9,0xc4,0xff,0x83,0x26,0x9a,0x37
+,0x7f,0xa1,0x89,0x37,0x03,0x06,0x87,0x37,0x3d,0x05,0x00,0x7f,0x01,0xc3,0xbb,0xff
+,0x7f,0xcd,0x53,0xe9,0x00,0x00,0xe5,0x02,0x25,0xff,0xfb,0x25,0xef,0xff,0x0d,0x01
+,0x00,0xe7,0x02,0xa1,0x83,0x37,0x3b,0x06,0x46,0x37,0x7f,0x2a,0xa1,0x85,0x37,0x3b
+,0x06,0x48,0x37,0x7c,0x21,0xa1,0x89,0x37,0x03,0x06,0x87,0x37,0x3d,0x05,0x00,0x7f
+,0x15,0xc6,0x06,0x9f,0x36,0x04,0xe5,0x02,0x25,0xff,0xf7,0x0d,0x01,0x00,0x25,0xef
+,0xff,0xe7,0x02,0xe9,0xf7,0xe6,0xbe,0x01,0x00,0xf7,0x06,0x9b,0x36,0x03,0x00,0x74
+,0x0a,0x83,0x26,0x9b,0x36,0xfc,0x83,0x0e,0xc2,0x34,0x04,0xe9,0xd0,0xe6,0xb8,0x7b
+,0x03,0xcd,0x39,0xe5,0x02,0x0d,0x01,0x60,0x25,0xef,0xff,0xe7,0x02,0xc7,0x06,0xf1
+,0x34,0x20,0x03,0xb8,0x8e,0x03,0xcd,0x39,0xc3,0x81,0x26,0xc2,0x34,0x7f,0xff,0x80
+,0x0e,0x6f,0x37,0x01,0xf7,0x06,0x9b,0x36,0x03,0x00,0x74,0xd2,0xb8,0x7b,0x03,0xcd
+,0x3a,0xb8,0x7d,0x03,0xcd,0x39,0x83,0x26,0x9b,0x36,0xef,0x33,0xc0,0xb0,0x8a,0xa2
+,0x9f,0x36,0xa2,0x9d,0x36,0xc7,0x06,0x4c,0x37,0x01,0x00,0xc7,0x06,0x0f,0x37,0x04
+,0x00,0xf7,0x06,0x9b,0x36,0x40,0x00,0x75,0x06,0xc7,0x06,0x0f,0x37,0x03,0x00,0xb8
+,0x8d,0x03,0xcd,0x39,0xe8,0x00,0xd5,0xe5,0x02,0x0d,0x01,0x40,0x25,0xef,0xff,0x8b
+,0xd8,0xb8,0x7c,0x03,0xcd,0x39,0xc7,0x06,0x33,0x37,0x02,0x00,0x8b,0xc3,0x0d,0x00
+,0x20,0x25,0xf9,0xff,0x0b,0x06,0xe8,0x3a,0xe7,0x02,0xc3,0xff,0x0e,0xf1,0x34,0x75
+,0x01,0xc3,0xe5,0x4e,0xa9,0x01,0x00,0x75,0x12,0xe5,0x00,0xa9,0x00,0x04,0x75,0x05
+,0x0d,0x00,0x04,0xe7,0x00,0xb8,0x8e,0x03,0xcd,0x39,0xc3,0xe5,0x00,0xa9,0x00,0x04
+,0x74,0xf3,0x25,0xff,0xfb,0xe7,0x00,0xe9,0xeb,0xff,0xc6,0x06,0xa0,0x36,0x04,0x83
+,0x26,0x9b,0x36,0xfc,0x81,0x0e,0x9b,0x36,0x80,0x00,0xe9,0x10,0xe6,0xb8,0x8e,0x03
+,0xcd,0x3a,0xcd,0x54,0x81,0x0e,0xaf,0x36,0x00,0x18,0xa1,0xaf,0x36,0xe7,0x06,0xb8
+,0x7b,0x03,0xcd,0x39,0xa1,0xd3,0x36,0xa3,0x8f,0x37,0xa1,0xd5,0x36,0xa3,0x91,0x37
+,0xc7,0x06,0x8b,0x37,0x02,0x00,0xc7,0x06,0x8d,0x37,0x02,0x00,0x83,0x0e,0x99,0x36
+,0x40,0xe9,0xd9,0xe5,0x80,0x3e,0x9f,0x36,0x06,0x75,0x15,0xa9,0xd0,0x07,0x75,0xec
+,0x25,0x00,0x18,0x75,0x0e,0xff,0x0e,0x8b,0x37,0x75,0xe1,0xc6,0x06,0x9f,0x36,0x08
+,0xe9,0xba,0xe5,0xff,0x0e,0x8d,0x37,0x75,0xd3,0xbe,0x08,0x00,0xe9,0x9f,0xe5,0xb8
+,0x7b,0x03,0xcd,0x39,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x08,0xc6,0x06,0x9f,0x36
+,0x0a,0xe9,0x0d,0x00,0xf7,0x06,0x9b,0x36,0x00,0x40,0x74,0x0b,0xb8,0x8b,0x03,0xcd
+,0x39,0x81,0x0e,0x99,0x36,0x80,0x00,0xe9,0x83,0xe5,0xb8,0x7b,0x03,0xcd,0x39,0xc7
+,0x06,0x8b,0x37,0x04,0x00,0xc7,0x06,0x8d,0x37,0x04,0x00,0x81,0x0e,0x99,0x36,0x00
+,0x02,0xe9,0x69,0xe5,0xf6,0x06,0x9d,0x36,0x80,0x75,0x1b,0xa9,0xd0,0x07,0x75,0xeb
+,0xa9,0x00,0x18,0x75,0x0c,0xff,0x0e,0x8d,0x37,0x75,0xe0,0xe8,0x17,0xfb,0xe9,0x4c
+,0xe5,0xb8,0x82,0x03,0xcd,0x39,0xc3,0xff,0x0e,0x8b,0x37,0x75,0xce,0xbe,0x09,0x00
+,0xe9,0x2b,0xe5,0xc7,0x06,0x3d,0x37,0x00,0x00,0xc7,0x06,0x9b,0x36,0x00,0x00,0xe8
+,0x3c,0x02,0x81,0x26,0xaf,0x36,0xff,0xe7,0xa1,0xaf,0x36,0xe7,0x06,0x81,0x26,0x9b
+,0x36,0xff,0x7f,0xe5,0x02,0x0d,0x01,0x00,0x25,0xef,0xff,0x25,0xff,0xdf,0xe7,0x02
+,0xbb,0xff,0x7f,0xcd,0x53,0x33,0xc0,0xa3,0x9d,0x36,0xa3,0x9f,0x36,0xe8,0x50,0x00
+,0xe8,0x73,0x00,0xb8,0x81,0x03,0xcd,0x39,0xc3,0xf7,0x06,0x9b,0x36,0x03,0x00,0x74
+,0x0d,0xc6,0x06,0x9f,0x36,0x02,0xc6,0x06,0xa0,0x36,0x00,0xe9,0xdf,0xe4,0x83,0x0e
+,0x9b,0x36,0x10,0xc7,0x06,0x99,0x36,0x00,0x00,0xe8,0xe7,0x02,0xe5,0x56,0x0d,0x02
+,0x00,0xe7,0x56,0xc7,0x06,0xa8,0x02,0x00,0x00,0x8b,0x36,0x3d,0x37,0xe8,0x44,0x02
+,0xc6,0x06,0xa0,0x36,0x0e,0xe9,0xb5,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x06,0xb8,0x8a,0x03,0xcd,0x3a,0xb8,0x85,0x03,0xcd,0x3a,0xb8,0x86,0x03,0xcd,0x3a
+,0xb8,0x83,0x03,0xcd,0x3a,0xb8,0x87,0x03,0xcd,0x3a,0xb8,0x8b,0x03,0xcd,0x3a,0xb8
+,0x88,0x03,0xcd,0x3a,0x07,0xc3,0x06,0xb8,0x88,0x03,0xcd,0x3a,0xb8,0x7b,0x03,0xcd
+,0x3a,0xb8,0x82,0x03,0xcd,0x3a,0xb8,0x7f,0x03,0xcd,0x3a,0xb8,0x7c,0x03,0xcd,0x3a
+,0xb8,0x7e,0x03,0xcd,0x3a,0xb8,0x80,0x03,0xcd,0x3a,0xb8,0x81,0x03,0xcd,0x3a,0xb8
+,0x84,0x03,0xcd,0x3a,0xb8,0x89,0x03,0xcd,0x3a,0xb8,0x7d,0x03,0xcd,0x3a,0xb8,0x8d
+,0x03,0xcd,0x3a,0xc7,0x06,0x41,0x37,0x00,0x00,0x07,0xc3,0x06,0x8e,0x06,0x38,0x34
+,0x1f,0x8b,0x0e,0x0e,0x00,0x26,0x89,0x0e,0x0e,0x00,0xbe,0x18,0x00,0xbf,0x18,0x00
+,0xf3,0xa4,0x06,0x1e,0x07,0xcd,0x34,0x07,0x33,0xc0,0x8e,0xd8,0xc3,0x26,0xf6,0x06
+,0x20,0x00,0x80,0x74,0x44,0x33,0xc0,0x26,0xa0,0x26,0x00,0x24,0x1f,0x8b,0xf0,0x26
+,0x8b,0x5c,0x28,0x89,0x1e,0x6a,0x37,0x06,0x8e,0x06,0x38,0x34,0x1f,0xc0,0xe3,0x04
+,0x26,0x88,0x5c,0x28,0x8b,0xc6,0xb9,0x06,0x00,0xbe,0x20,0x00,0xbf,0x1a,0x00,0xf3
+,0xa4,0x8b,0xc8,0x83,0xc7,0x06,0xf3,0xa4,0x26,0x81,0x26,0x26,0x00,0x1f,0x80,0x26
+,0x81,0x36,0x26,0x00,0x00,0x80,0xe9,0xa9,0xff,0x26,0x8b,0x1e,0x28,0x00,0x89,0x1e
+,0x6a,0x37,0x06,0x8e,0x06,0x38,0x34,0x1f,0xc0,0xe3,0x04,0x26,0x88,0x1e,0x28,0x00
+,0xb9,0x06,0x00,0xbe,0x20,0x00,0xbf,0x1a,0x00,0xf3,0xa4,0xe9,0x84,0xff,0x86,0xc4
+,0xa3,0x68,0x37,0xe8,0x87,0xff,0xf7,0x06,0x6a,0x37,0x0f,0x00,0x74,0x10,0x80,0x3e
+,0x9e,0x36,0x00,0x75,0x09,0xbe,0x00,0x00,0xe8,0xac,0xe9,0xcd,0x50,0xc3,0xc3,0x50
+,0x56,0x06,0x33,0xc0,0x26,0xf6,0x06,0x20,0x00,0x80,0x74,0x06,0x26,0xa0,0x26,0x00
+,0x24,0x1f,0x8b,0xf0,0x26,0x8b,0x5c,0x26,0x86,0xfb,0x83,0xeb,0x04,0x74,0x4f,0x83
+,0xc6,0x2a,0x8c,0xc0,0x8e,0xd8,0xb9,0x07,0x00,0x33,0xc0,0x8e,0xc0,0xbf,0x72,0x37
+,0xf3,0xab,0x33,0xc9,0x8a,0x0c,0x80,0xf9,0x00,0x75,0x03,0xe9,0x30,0x00,0x3b,0xd9
+,0x73,0x03,0xe9,0x29,0x00,0x2b,0xd9,0x8a,0x44,0x01,0x25,0x3f,0x00,0x74,0x19,0x3d
+,0x0b,0x00,0x7d,0x14,0xd1,0xe0,0x8b,0xf8,0x2e,0x8b,0xbd,0x5c,0x49,0x8d,0x74,0x02
+,0x83,0xe9,0x02,0xf3,0xa4,0xe9,0x02,0x00,0x03,0xf1,0x23,0xdb,0x75,0xc4,0x33,0xc0
+,0x8e,0xd8,0x07,0x5e,0x58,0xc3,0x33,0xc0,0x26,0xf6,0x06,0x20,0x00,0x80,0x74,0x06
+,0x26,0xa0,0x26,0x00,0x24,0x1f,0xc3,0xe5,0x0a,0x25,0xc3,0xbf,0xe7,0x0a,0xb8,0x86
+,0x03,0xcd,0x39,0xb8,0x83,0x03,0xcd,0x39,0x81,0x26,0x9b,0x36,0x7c,0xdf,0xb8,0x85
+,0x03,0xcd,0x3a,0xe5,0x02,0x25,0xff,0xf3,0x0d,0x01,0x00,0x25,0xef,0xff,0xe7,0x02
+,0xe5,0x00,0x25,0xff,0x53,0xe7,0x00,0xa1,0xe7,0x36,0x25,0xff,0xfe,0xa3,0xe7,0x36
+,0xe7,0x3e,0x83,0x26,0x99,0x36,0xcf,0x81,0x0e,0xaf,0x36,0x00,0x10,0xa1,0xaf,0x36
+,0xe7,0x06,0xc3,0xe5,0x02,0x0d,0x01,0x0c,0x25,0xef,0xff,0xe7,0x02,0xa1,0xe7,0x36
+,0x0d,0x00,0x01,0xe7,0x3e,0xa3,0xe7,0x36,0x81,0x0e,0x9b,0x36,0x00,0x20,0x83,0x0e
+,0x99,0x36,0x20,0x81,0x26,0x9b,0x36,0x7c,0xbf,0x81,0x0e,0xaf,0x36,0x00,0x10,0xa1
+,0xaf,0x36,0xe7,0x06,0xb8,0x86,0x03,0xcd,0x39,0xb8,0x85,0x03,0xcd,0x39,0xb8,0x83
+,0x03,0xcd,0x3a,0xc3,0x0b,0xf6,0x75,0x49,0x06,0x8e,0x06,0x32,0x34,0x80,0x3e,0xe0
+,0x34,0x01,0x75,0x1b,0x26,0x89,0x36,0x06,0x00,0x8e,0x06,0x32,0x34,0x26,0xf7,0x06
+,0x0a,0x00,0x00,0x20,0x74,0x07,0x26,0x81,0x0e,0x08,0x00,0x00,0x20,0x07,0xc3,0x80
+,0x3e,0xe3,0x34,0x01,0x75,0x19,0x26,0x89,0x36,0x06,0x00,0x8e,0x06,0x32,0x34,0x26
+,0xf7,0x06,0x0a,0x00,0x00,0x10,0x74,0x07,0x26,0x81,0x0e,0x08,0x00,0x00,0x10,0x07
+,0xc3,0xe9,0xb4,0xff,0x50,0x51,0x57,0x33,0xc0,0xb9,0x06,0x00,0x8e,0xc0,0xbf,0xd1
+,0x36,0xf3,0xae,0x5f,0x74,0x0c,0x26,0xf6,0x06,0x00,0x00,0xc0,0x75,0x04,0xf8,0x59
+,0x58,0xc3,0xf9,0xe9,0xf9,0xff,0x8b,0x05,0x0b,0x45,0x02,0x0b,0x45,0x04,0xc3,0x52
+,0x50,0xe5,0x06,0x25,0x1e,0x00,0x3d,0x1e,0x00,0x75,0xf6,0xb8,0x01,0x80,0xe7,0x5a
+,0x58,0x5a,0xc3,0xe8,0xe9,0xff,0x50,0xe5,0x02,0x25,0xff,0x7f,0x0d,0x01,0x00,0x25
+,0xef,0xff,0xe7,0x02,0x0d,0x00,0x80,0xe7,0x02,0xa1,0xad,0x36,0xe7,0x04,0xa1,0xaf
+,0x36,0xe7,0x06,0x58,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x2e,0x2b,0xce,0x41,0x10,0x42,0x7b,0x41,0x30,0x41,0xa2,0x41,0xaf,0x45,0x44,0x29
+,0xc7,0x2a,0xc7,0x2a,0x60,0x39,0xf4,0x3a,0x5c,0x3c,0x09,0x3d,0xb1,0x3d,0x34,0x3f
+,0xc7,0x2a,0x3c,0x3f,0xc7,0x2a,0xc4,0x3f,0x16,0x40,0x16,0x40,0xed,0x40,0xfa,0x40
+,0x07,0x41,0xc7,0x2a,0xc7,0x2a,0xc7,0x2a,0xc7,0x2a,0xd6,0x52,0x00,0x00,0x01,0x37
+,0xe9,0x36,0xf3,0x36,0xef,0x36,0x1d,0x37,0x0d,0x37,0x0b,0x37,0x9c,0x37,0x03,0x37
+,0xfb,0x36,0x62,0x2d,0x40,0x06,0xd1,0x2d,0xf4,0x01,0xba,0x44,0x40,0x06,0x8c,0x43
+,0x64,0x00,0xe8,0x2c,0xc8,0x00,0xd8,0x2b,0x05,0x00,0xe9,0x45,0x50,0x00,0x97,0x45
+,0xfa,0x00,0xae,0x2d,0x04,0x01,0x6a,0x42,0x02,0x00,0xf6,0x2c,0xbc,0x02,0x93,0x2d
+,0xdc,0x05,0x1d,0x2d,0x64,0x00,0xa1,0x2d,0x14,0x00,0xd7,0x3a,0x08,0x07,0x81,0x2d
+,0x64,0x00,0xb3,0x3e,0x02,0x00,0x30,0x43,0x64,0x00,0xc5,0x2c,0xf4,0x01,0x8b,0x44
+,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x80,0x3e,0xfd,0x34,0x02,0x74,0x0c,0xe8,0x20,0x05,0xc7,0x06,0xa1,0x36,0x00,0x00
+,0xe9,0x9a,0xf8,0xff,0x06,0xc0,0x33,0xe8,0x10,0x05,0x8b,0x36,0x3d,0x37,0xe8,0x73
+,0xfe,0xc3,0xcd,0x34,0xe9,0xe8,0x05,0xc7,0x06,0xa3,0x36,0x00,0x00,0xc7,0x06,0x41
+,0x37,0x00,0x00,0xe8,0xed,0xfe,0x33,0xc0,0x0d,0x41,0x00,0xe7,0x56,0xa1,0xb1,0x36
+,0x0d,0x00,0x10,0xe7,0x08,0xa1,0xb3,0x36,0xe7,0x0a,0xa1,0xaf,0x36,0xe7,0x06,0xa1
+,0xad,0x36,0xe7,0x04,0xe8,0x2b,0x09,0xc7,0x06,0x1d,0x37,0x00,0xc8,0xc7,0x06,0x0b
+,0x37,0x00,0x03,0xc7,0x06,0x0d,0x37,0x7b,0x7f,0x33,0xc0,0xa3,0x9b,0x36,0xa3,0x9d
+,0x36,0xc7,0x06,0x4c,0x37,0x01,0x00,0xc6,0x06,0x9e,0x36,0xff,0xc7,0x06,0x05,0x37
+,0x00,0x00,0xc7,0x06,0x07,0x37,0x00,0x00,0xc7,0x06,0x09,0x37,0x00,0x00,0xa3,0xf3
+,0x36,0xa3,0xef,0x36,0xa3,0xf1,0x36,0xe8,0xfe,0xf5,0xe5,0x02,0x25,0xf9,0xff,0x0d
+,0x03,0x00,0x0d,0x00,0x88,0x25,0xef,0xff,0x0d,0x00,0x40,0x0d,0x00,0x04,0xe7,0x02
+,0xb8,0x8f,0x03,0xcd,0x39,0xb8,0x80,0x00,0xcd,0x35,0xc7,0x06,0xaa,0x02,0xff,0xff
+,0xa1,0xa9,0x36,0xa3,0xa7,0x36,0x0d,0x00,0xa4,0x0d,0x00,0x08,0xe7,0x00,0xa3,0xa9
+,0x36,0xc7,0x06,0xa3,0x36,0x01,0x00,0xc7,0x06,0xa5,0x36,0x0c,0x00,0x83,0x3e,0xa5
+,0x36,0x00,0x75,0x09,0xc7,0x06,0x3d,0x37,0x05,0x00,0xe9,0x13,0xff,0xff,0x0e,0xa5
+,0x36,0xbe,0x11,0x00,0xe8,0x22,0x05,0xb8,0x90,0x03,0xcd,0x39,0xc3,0x83,0x3e,0xa3
+,0x36,0x01,0x74,0xd9,0xc3,0xb8,0x90,0x03,0xcd,0x3a,0x26,0xa0,0x2b,0x00,0x26,0x8b
+,0x1e,0x2c,0x00,0xcd,0x34,0x83,0x3e,0xa3,0x36,0x01,0x74,0x03,0xe9,0xf0,0x04,0x3c
+,0x0f,0x75,0x1e,0x81,0xfb,0x00,0x02,0x75,0x18,0x26,0xa1,0x20,0x00,0xa3,0x05,0x37
+,0x26,0xa1,0x22,0x00,0xa3,0x07,0x37,0x26,0xa1,0x24,0x00,0xa3,0x09,0x37,0xe9,0x09
+,0x00,0xc7,0x06,0x3d,0x37,0x01,0x00,0xe9,0xb6,0xfe,0xc7,0x06,0xa3,0x36,0x02,0x00
+,0xc6,0x06,0x9e,0x36,0xff,0xe8,0xcb,0xfd,0xe8,0x1c,0xd9,0x33,0xc0,0xa3,0x85,0x37
+,0xa3,0x83,0x37,0xa3,0x87,0x37,0xa3,0x89,0x37,0xb8,0x91,0x03,0xcd,0x39,0xb8,0x80
+,0x00,0xcd,0x35,0xc7,0x06,0xaa,0x02,0xff,0xff,0xe5,0x00,0x25,0xff,0x53,0xe7,0x00
+,0x81,0x0e,0x9a,0x37,0x80,0x00,0xb8,0x92,0x03,0xcd,0x39,0x33,0xc0,0xe7,0x0e,0xbe
+,0x08,0x00,0x8e,0x06,0x38,0x34,0xe8,0x8e,0xe5,0x26,0xc7,0x06,0x04,0x00,0x7d,0x4b
+,0x83,0x26,0xef,0x34,0xdf,0xcd,0x50,0x83,0x0e,0xef,0x34,0x20,0xc3,0xf7,0x06,0x9a
+,0x37,0x80,0x00,0x74,0x32,0xa9,0xd0,0x07,0x74,0x0c,0xa9,0x00,0x04,0x74,0x0e,0x33
+,0xc0,0xe7,0x0e,0xe9,0xda,0xff,0xff,0x06,0x85,0x37,0xe9,0xd3,0xff,0xff,0x06,0x83
+,0x37,0xe9,0xcc,0xff,0xc7,0x06,0x3d,0x37,0x01,0x00,0xe9,0x36,0xfe,0x83,0x26,0x9a
+,0x37,0x7f,0xbb,0xff,0x7f,0xcd,0x53,0xe5,0x00,0x0d,0x00,0xac,0xe7,0x00,0xe5,0x02
+,0x25,0xff,0xfb,0x25,0xef,0xff,0x25,0xff,0xf7,0x0d,0x01,0x00,0xe7,0x02,0xa1,0x83
+,0x37,0x3b,0x06,0x46,0x37,0x7f,0xcd,0xa1,0x85,0x37,0x3b,0x06,0x48,0x37,0x7c,0xc4
+,0xc7,0x06,0xa3,0x36,0x03,0x00,0xbe,0x13,0x00,0xe8,0xfd,0x03,0xb8,0x93,0x03,0xcd
+,0x39,0xb8,0x94,0x03,0xcd,0x39,0xb8,0x96,0x03,0xcd,0x39,0xb8,0x95,0x03,0xcd,0x39
+,0xbe,0x06,0x00,0xe8,0xe3,0x03,0xe9,0xd6,0x03,0x83,0x3e,0xa3,0x36,0x03,0x74,0x01
+,0xc3,0xbe,0x13,0x00,0xe8,0xd2,0x03,0xb8,0x94,0x03,0xcd,0x39,0xc3,0xb8,0x94,0x03
+,0xcd,0x3a,0x26,0xa0,0x2b,0x00,0x26,0x8b,0x1e,0x2c,0x00,0xcd,0x34,0x83,0x3e,0xa3
+,0x36,0x03,0x74,0x03,0xe9,0xa8,0x03,0x3c,0x0d,0x75,0x3e,0x83,0xfb,0x00,0x75,0x39
+,0xe5,0x02,0x0d,0x00,0x20,0xe7,0x02,0xb8,0x93,0x03,0xcd,0x3a,0xc7,0x06,0xa3,0x36
+,0x04,0x00,0xbe,0x00,0x00,0xe8,0x0c,0xfc,0xc6,0x06,0x9d,0x36,0x80,0xc6,0x06,0x9e
+,0x36,0x00,0xc7,0x06,0x33,0x37,0x02,0x00,0xb8,0x9a,0x03,0xcd,0x39,0xe8,0xfc,0x00
+,0xc7,0x06,0x4c,0x37,0x00,0x00,0xe9,0x66,0x03,0xc7,0x06,0x3d,0x37,0x08,0x00,0xe9
+,0x61,0xfd,0x83,0x3e,0xa3,0x36,0x03,0x75,0x09,0xc7,0x06,0x3d,0x37,0x05,0x00,0xe9
+,0x51,0xfd,0xe9,0x4a,0x03,0x83,0x3e,0xa3,0x36,0x04,0x74,0x12,0x83,0x3e,0xa3,0x36
+,0x05,0x74,0x0b,0xcd,0x34,0xc7,0x06,0x3d,0x37,0x07,0x00,0xe9,0x35,0xfd,0xc7,0x06
+,0xa3,0x36,0x06,0x00,0xc6,0x06,0x9e,0x36,0xff,0xb8,0x9a,0x03,0xcd,0x3a,0xb8,0x99
+,0x03,0xcd,0x3a,0xb8,0x96,0x03,0xcd,0x3a,0xb8,0x97,0x03,0xcd,0x39,0xb8,0x98,0x03
+,0xcd,0x39,0xb8,0x9b,0x03,0xcd,0x39,0xe9,0x18,0xfd,0xcd,0x34,0x83,0x3e,0xa3,0x36
+,0x04,0x77,0x18,0x83,0x3e,0xa3,0x36,0x03,0x75,0x08,0xf7,0x06,0x9b,0x36,0x00,0x01
+,0x75,0x09,0xc7,0x06,0x3d,0x37,0x01,0x00,0xe9,0xe8,0xfc,0xe9,0xe1,0x02,0xcd,0x34
+,0x83,0x3e,0xa3,0x36,0x02,0x77,0x09,0xc7,0x06,0x3d,0x37,0x01,0x00,0xe9,0xd3,0xfc
+,0x83,0x3e,0xa3,0x36,0x04,0x77,0x05,0xb8,0x96,0x03,0xcd,0x39,0xe9,0xc0,0x02,0x83
+,0x3e,0xa3,0x36,0x03,0x75,0x10,0x26,0xa1,0x0c,0x00,0x25,0x07,0x00,0x50,0x3d,0x04
+,0x00,0x75,0x03,0xe8,0x36,0x00,0xa1,0xf3,0x36,0x86,0xe0,0xe7,0x1e,0xa3,0xe3,0x36
+,0x81,0x26,0x0b,0x37,0x00,0x03,0x81,0x26,0x0d,0x37,0x7b,0x7f,0x83,0x0e,0x0d,0x37
+,0x48,0xe8,0x14,0xf3,0x58,0x3d,0x04,0x00,0x74,0x09,0x26,0xf7,0x06,0x0c,0x00,0x20
+,0x00,0x75,0x06,0xb8,0x01,0x00,0xe9,0x7a,0x02,0xe9,0x86,0xfc,0xa1,0xe5,0x36,0xe7
+,0x2e,0xa1,0xe7,0x36,0xe7,0x3e,0xa1,0xd3,0x36,0xa3,0x9c,0x34,0xa1,0xd5,0x36,0xa3
+,0x9e,0x34,0xc3,0x26,0x80,0x3e,0x1c,0x00,0xff,0x75,0x2f,0x26,0x80,0x3e,0x1e,0x00
+,0xff,0x75,0x27,0x26,0xf7,0x06,0x0c,0x00,0x40,0x00,0x75,0x1b,0xa1,0xd1,0x36,0x26
+,0xa3,0x1a,0x00,0xa1,0xd3,0x36,0x26,0xa3,0x1c,0x00,0xa1,0xd5,0x36,0x26,0xa3,0x1e
+,0x00,0xb8,0x0a,0x80,0xe9,0x2c,0x02,0xe9,0x38,0xfc,0xff,0x06,0x90,0x34,0xbe,0x0a
+,0x00,0xc6,0x06,0xb6,0x34,0x01,0xf6,0x06,0x9d,0x36,0x80,0x75,0x05,0x83,0x0e,0xc2
+,0x34,0x01,0xcd,0x34,0xe9,0x0c,0xfc,0x83,0x3e,0xa3,0x36,0x03,0x75,0x09,0xc7,0x06
+,0x3d,0x37,0x05,0x00,0xe9,0xfc,0xfb,0xe5,0x02,0x0d,0x03,0x00,0x0d,0x00,0x88,0x0d
+,0x00,0x40,0x0d,0x00,0x04,0xe7,0x02,0xc7,0x06,0xa3,0x36,0x05,0x00,0xc6,0x06,0x9e
+,0x36,0xff,0xbe,0x02,0x00,0xe8,0xe1,0x01,0xb8,0x89,0x03,0xcd,0x3a,0xb8,0x9a,0x03
+,0xcd,0x3a,0xb8,0x99,0x03,0xcd,0x39,0xb8,0x97,0x03,0xcd,0x39,0xb8,0x98,0x03,0xcd
+,0x39,0xe9,0xbb,0x01,0x83,0x3e,0xa3,0x36,0x03,0x74,0x0a,0x83,0x3e,0xa3,0x36,0x04
+,0x74,0x03,0xe9,0xaa,0x01,0xbe,0x06,0x00,0xe8,0xae,0x01,0xb8,0x95,0x03,0xcd,0x39
+,0xe9,0x9c,0x01,0x83,0x3e,0xa3,0x36,0x05,0x74,0x03,0xe9,0x92,0x01,0xbe,0x02,0x00
+,0xe8,0x96,0x01,0xb8,0x99,0x03,0xcd,0x39,0xe9,0x84,0x01,0xc7,0x06,0x0f,0x37,0x05
+,0x00,0xe9,0x7b,0x01,0xe5,0x02,0x25,0xff,0xdf,0xe7,0x02,0xc7,0x06,0xa3,0x36,0x07
+,0x00,0xc7,0x06,0x0f,0x37,0x05,0x00,0xe9,0x65,0x01,0xe8,0xd5,0x04,0xc6,0x06,0x9d
+,0x36,0x00,0xc7,0x06,0x9b,0x36,0x00,0x00,0xc7,0x06,0x0f,0x37,0x05,0x00,0xc7,0x06
+,0xa8,0x02,0x00,0x00,0xc7,0x06,0x4c,0x37,0x01,0x00,0xe5,0x02,0x25,0xf9,0xff,0x0d
+,0x03,0x00,0x0d,0x00,0x88,0x25,0xef,0xff,0x0d,0x00,0x40,0x0d,0x00,0x04,0xe7,0x02
+,0xe9,0x67,0xfc,0xb8,0x9a,0x03,0xcd,0x39,0xf7,0x06,0xf4,0x33,0x00,0x10,0x75,0x09
+,0xc7,0x06,0x33,0x37,0x02,0x00,0xe9,0x16,0x01,0xff,0x0e,0x33,0x37,0x74,0x03,0xe9
+,0x0d,0x01,0xff,0x06,0x8e,0x34,0x83,0x0e,0xc2,0x34,0x08,0xc7,0x06,0x3d,0x37,0x03
+,0x00,0xe9,0xff,0xfa,0xc3,0x52,0x50,0xba,0xe0,0x00,0xb8,0x00,0x10,0xef,0x58,0x5a
+,0xc3,0xc7,0x06,0x3d,0x37,0x00,0x00,0xe9,0xe9,0xfa,0xfa,0xe8,0x54,0x04,0xb8,0x80
+,0x03,0x8e,0xc0,0x26,0xc7,0x06,0x04,0x00,0xd8,0x2b,0xb8,0x7f,0x03,0x8e,0xc0,0x26
+,0xc7,0x06,0x04,0x00,0xe8,0x2c,0x33,0xc0,0x8e,0xc0,0xa1,0xa7,0x36,0xa3,0xa9,0x36
+,0xa1,0xa9,0x36,0xe7,0x00,0xa1,0xab,0x36,0xe7,0x02,0xc7,0x06,0x05,0x37,0x00,0x00
+,0xc7,0x06,0x07,0x37,0x00,0x00,0xc7,0x06,0x09,0x37,0x00,0x00,0xc6,0x06,0x9d,0x36
+,0x00,0xc6,0x06,0x9e,0x36,0xff,0xc7,0x06,0x9b,0x36,0x00,0x00,0xc7,0x06,0xa3,0x36
+,0x00,0x00,0xc7,0x06,0x0f,0x37,0x00,0x00,0xc7,0x06,0xa8,0x02,0x00,0x00,0xc7,0x06
+,0x4c,0x37,0x01,0x00,0x81,0x26,0xaf,0x36,0xff,0xe7,0xa1,0xaf,0x36,0xe7,0x06,0xbb
+,0xff,0x7f,0xcd,0x53,0xe8,0x7c,0xf9,0xe5,0x56,0x0d,0x02,0x00,0xe7,0x56,0xfb,0xc3
+,0x8d,0x3e,0xc0,0x53,0x8d,0x36,0xf0,0x38,0xb9,0x0e,0x00,0x8b,0x1e,0x30,0x34,0x89
+,0x5c,0x02,0x2e,0x8b,0x45,0x02,0x89,0x44,0x06,0x2e,0x8b,0x05,0x89,0x44,0x04,0x83
+,0xc7,0x04,0x83,0xc6,0x10,0xe2,0xe8,0xb8,0x80,0x03,0x8e,0xc0,0x26,0xc7,0x06,0x04
+,0x00,0xe2,0x51,0xb8,0x7f,0x03,0x8e,0xc0,0x26,0xc7,0x06,0x04,0x00,0xb2,0x52,0x33
+,0xc0,0x8e,0xc0,0xc7,0x06,0xa1,0x36,0x01,0x00,0xc7,0x06,0x0f,0x37,0x05,0x00,0xc3
+,0x33,0xff,0x8e,0x06,0xa6,0x02,0x8b,0x36,0xa4,0x02,0x2e,0xff,0xa4,0xa0,0x53,0xe8
+,0x8c,0xdb,0xc3,0xe8,0x48,0xf7,0xe9,0xf6,0xff,0x8e,0x06,0x38,0x34,0xe8,0x07,0xe1
+,0x26,0xc7,0x06,0x04,0x00,0xdf,0x4f,0xcd,0x50,0xc3,0x26,0xc7,0x06,0x0a,0x00,0x00
+,0x00,0x26,0xff,0x26,0x04,0x00,0xcd,0x34,0xe9,0xd4,0xff,0xa1,0xd1,0x36,0x26,0x39
+,0x06,0x1a,0x00,0x75,0x22,0xa1,0xd3,0x36,0x26,0x39,0x06,0x1c,0x00,0x75,0x18,0xa1
+,0xd5,0x36,0x26,0x39,0x06,0x1e,0x00,0x75,0x0e,0x26,0xf7,0x06,0x0c,0x00,0x40,0x00
+,0x74,0x05,0x83,0x0e,0x66,0x37,0x40,0x81,0x0e,0xaf,0x36,0x00,0x10,0xa1,0xaf,0x36
+,0xe7,0x06,0x83,0x3e,0xa3,0x36,0x02,0x75,0x05,0xcd,0x34,0xe9,0x56,0xfb,0x83,0x3e
+,0xa3,0x36,0x00,0x74,0xb1,0x83,0x3e,0xa3,0x36,0x05,0x77,0xaa,0x26,0xf6,0x06,0x0a
+,0x00,0xff,0x75,0xa2,0xe8,0xfd,0xdd,0x50,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xe9
+,0x8c,0x00,0x26,0xa1,0x0c,0x00,0x25,0x07,0x00,0x3d,0x07,0x00,0x75,0x03,0xe9,0x76
+,0x00,0x3d,0x05,0x00,0x75,0x03,0xe9,0x6e,0x00,0xf7,0x06,0xe6,0x34,0x18,0x80,0x75
+,0x03,0xe9,0x6a,0x00,0xf7,0x06,0xe6,0x34,0x00,0x80,0x74,0x35,0x26,0x80,0x3e,0x29
+,0x00,0x02,0x75,0x2d,0x51,0x56,0x57,0x8d,0x36,0x3e,0x34,0x8d,0x3e,0x20,0x00,0xb9
+,0x06,0x00,0xf3,0xa6,0x5f,0x5e,0x59,0x75,0x45,0x26,0xa1,0x20,0x00,0xa3,0x3e,0x34
+,0x26,0xa1,0x22,0x00,0xa3,0x40,0x34,0x26,0xa1,0x24,0x00,0xa3,0x42,0x34,0xe9,0x26
+,0x00,0xf7,0x06,0xe6,0x34,0x08,0x00,0x74,0x0b,0x26,0x80,0x3e,0x19,0x00,0x00,0x74
+,0x03,0xe9,0x13,0x00,0xf7,0x06,0xe6,0x34,0x10,0x00,0x74,0x12,0x26,0xa0,0x28,0x00
+,0xc0,0xe8,0x04,0x22,0xc0,0x74,0x07,0x26,0xc7,0x06,0x04,0x00,0xff,0xff,0x58,0x23
+,0xc0,0x74,0x03,0xe9,0xdd,0xfe,0x81,0x26,0x9b,0x36,0xff,0xfe,0x26,0xa1,0x20,0x00
+,0x3b,0x06,0xd1,0x36,0x75,0x1a,0x26,0xa1,0x22,0x00,0x3b,0x06,0xd3,0x36,0x75,0x10
+,0x26,0xa1,0x24,0x00,0x3b,0x06,0xd5,0x36,0x75,0x06,0x81,0x0e,0x9b,0x36,0x00,0x01
+,0x26,0xa1,0x20,0x00,0x25,0x7f,0xff,0xa3,0xb8,0x34,0x26,0xa1,0x22,0x00,0xa3,0xba
+,0x34,0x26,0xa1,0x24,0x00,0xa3,0xbc,0x34,0x8b,0xc6,0x86,0xc4,0xa3,0xc0,0x34,0xd1
+,0xe6,0x80,0xfc,0x09,0x74,0x03,0xe8,0xf6,0xf5,0xa1,0x05,0x37,0x0b,0x06,0x07,0x37
+,0x0b,0x06,0x09,0x37,0x74,0x3e,0x26,0xa1,0x20,0x00,0x3b,0x06,0x05,0x37,0x75,0x17
+,0x26,0xa1,0x22,0x00,0x3b,0x06,0x07,0x37,0x75,0x0d,0x26,0xa1,0x24,0x00,0x3b,0x06
+,0x09,0x37,0x75,0x03,0xe9,0x1d,0x00,0x26,0xa0,0x28,0x00,0x24,0x0f,0x3c,0x03,0x74
+,0x1b,0x3c,0x00,0x75,0x0f,0x83,0x3e,0xa3,0x36,0x04,0x74,0x10,0xf7,0x06,0x9b,0x36
+,0x00,0x01,0x74,0x08,0x2e,0xff,0x94,0xf8,0x53,0xe9,0x33,0xfe,0xcd,0x34,0xc7,0x06
+,0x3d,0x37,0x01,0x00,0xe9,0x2c,0xf8,0x83,0x3e,0xa3,0x36,0x05,0x74,0x10,0x83,0x3e
+,0xa3,0x36,0x01,0x7e,0x09,0x83,0xee,0x16,0x2e,0xff,0x94,0x24,0x54,0xc3,0xcd,0x34
+,0xc3,0x26,0xa1,0x0c,0x00,0x3d,0xff,0x7f,0x74,0x05,0x26,0xff,0x26,0x04,0x00,0xe9
+,0xfd,0xfd,0xa1,0xf4,0x33,0xa9,0x00,0x88,0x74,0x0b,0xa9,0x00,0x10,0x75,0x09,0x8b
+,0x1e,0x43,0x37,0xff,0xe3,0xe9,0x97,0x00,0xc7,0x06,0x35,0x37,0x05,0x00,0xc7,0x06
+,0x43,0x37,0x28,0x52,0xf7,0x06,0xf4,0x33,0x00,0x08,0x74,0x06,0xc7,0x06,0x43,0x37
+,0x1a,0x52,0xb8,0x80,0x03,0xcd,0x39,0xe9,0xc5,0xfd,0xa9,0x00,0x08,0x74,0xd9,0xff
+,0x0e,0x35,0x37,0x75,0xed,0xe9,0x30,0x00,0xa9,0x00,0x08,0x75,0xcb,0xff,0x0e,0x35
+,0x37,0x75,0xdf,0x81,0x0e,0xc2,0x34,0xc0,0x00,0xf6,0x06,0x9d,0x36,0x80,0x74,0x0f
+,0x81,0x0e,0x9b,0x36,0x00,0x80,0xc7,0x06,0x0f,0x37,0x02,0x00,0xe9,0x90,0xfd,0xc7
+,0x06,0x3d,0x37,0x02,0x00,0xe9,0x8b,0xf7,0x80,0x26,0x9e,0x36,0xff,0x75,0x30,0xf6
+,0x06,0x9d,0x36,0x80,0x74,0x20,0xff,0x06,0x94,0x34,0x83,0x0e,0x66,0x37,0x20,0x8e
+,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x01,0x74,0x07,0x26,0x81,0x0e,0x08
+,0x00,0x00,0x01,0xe9,0x09,0x00,0xc7,0x06,0x3d,0x37,0x04,0x00,0xe9,0x54,0xf7,0x81
+,0x0e,0xaf,0x36,0x00,0x08,0xa1,0xaf,0x36,0xe7,0x06,0xe5,0x0a,0xa9,0x00,0x80,0x74
+,0x0e,0x81,0x26,0xaf,0x36,0xff,0xf7,0xa1,0xaf,0x36,0xe7,0x06,0xe9,0x49,0xff,0xe9
+,0x2d,0xfd,0xc7,0x06,0x41,0x37,0x00,0x00,0xbe,0x29,0x00,0xe8,0x2b,0xfd,0xe9,0x1e
+,0xfd,0xcd,0x34,0x83,0x3e,0xa3,0x36,0x04,0x77,0x09,0xc7,0x06,0x3d,0x37,0x01,0x00
+,0xe9,0x10,0xf7,0xe9,0x09,0xfd,0xcd,0x34,0xc3,0xc7,0x06,0x9b,0x36,0x00,0x00,0xe8
+,0x0c,0xf5,0x81,0x26,0xaf,0x36,0xff,0xe7,0xa1,0xaf,0x36,0xe7,0x06,0x81,0x26,0x9b
+,0x36,0xff,0x7f,0xe5,0x02,0x0d,0x01,0x00,0x25,0xef,0xff,0x25,0xff,0xdf,0xe7,0x02
+,0xbb,0xff,0x7f,0xcd,0x53,0x33,0xc0,0xa3,0x9d,0x36,0xa3,0x9f,0x36,0xe8,0x20,0xf3
+,0xe8,0x43,0xf3,0x83,0x0e,0x9b,0x36,0x10,0xc7,0x06,0x99,0x36,0x00,0x00,0xe8,0xd2
+,0xf5,0xe5,0x56,0x0d,0x02,0x00,0xe7,0x56,0xc7,0x06,0xa8,0x02,0x00,0x00,0xbe,0x00
+,0x00,0xe8,0x30,0xf5,0xc6,0x06,0xa0,0x36,0x0e,0xb8,0x9c,0x03,0xcd,0x39,0xb8,0x80
+,0x00,0xcd,0x35,0xc7,0x06,0xaa,0x02,0xff,0xff,0xc7,0x06,0xa1,0x36,0x01,0x00,0xe9
+,0xa5,0xf6,0x06,0xb8,0x8f,0x03,0xcd,0x3a,0xb8,0x90,0x03,0xcd,0x3a,0xb8,0x91,0x03
+,0xcd,0x3a,0xb8,0x92,0x03,0xcd,0x3a,0xb8,0x93,0x03,0xcd,0x3a,0xb8,0x94,0x03,0xcd
+,0x3a,0xb8,0x95,0x03,0xcd,0x3a,0xb8,0x96,0x03,0xcd,0x3a,0xb8,0x97,0x03,0xcd,0x3a
+,0xb8,0x98,0x03,0xcd,0x3a,0xb8,0x99,0x03,0xcd,0x3a,0xb8,0x9a,0x03,0xcd,0x3a,0xb8
+,0x9b,0x03,0xcd,0x3a,0xb8,0x7f,0x03,0xcd,0x3a,0xb8,0x80,0x03,0xcd,0x3a,0x07,0xc3
+,0xf7,0x49,0xf1,0x4e,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f,0xf8,0x51,0xdf,0x4f
+,0xfa,0x4f,0x0b,0x50,0xd1,0x51,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f
+,0xe4,0x4e,0x06,0x00,0xcd,0x4a,0x04,0x00,0xe4,0x4e,0x19,0x00,0xad,0x4b,0xfa,0x00
+,0x82,0x4c,0x08,0x07,0x09,0x4c,0x14,0x00,0x24,0x4e,0x64,0x00,0xd7,0x4d,0xf4,0x01
+,0x64,0x4e,0xbc,0x02,0x7a,0x4e,0xe8,0x03,0x43,0x4e,0x02,0x00,0xb3,0x4e,0xf4,0x01
+,0x5b,0x4e,0xf4,0x01,0xe5,0x4e,0x14,0x00,0x06,0x50,0x06,0x50,0x95,0x4c,0xc1,0x52
+,0xc1,0x52,0xfe,0x4c,0xda,0x4c,0x06,0x50,0x06,0x50,0x06,0x50,0x06,0x50,0xb7,0x51
+,0xb7,0x51,0xb7,0x51,0xb7,0x51,0xb7,0x51,0xb7,0x51,0x06,0x50,0xd5,0x4a,0x06,0x50
+,0x1d,0x4c,0x06,0x50,0x83,0x4d,0x1f,0x4d,0x1f,0x4d,0xed,0x40,0xfa,0x40,0x07,0x41
+,0x37,0x37,0x2e,0x37,0x37,0x20,0x20,0x79,0x79,0x2f,0x79,0x79,0x2f,0x79,0x79,0x20
+,0x30,0x31,0x2e,0x39,0x30,0x20,0x20,0x30,0x32,0x2f,0x31,0x37,0x2f,0x39,0x39,0x20
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+,0x90,0xea,0xc0,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x06
+} ;
+#endif
diff --git a/drivers/net/tokenring/Config.help b/drivers/net/tokenring/Config.help
index aadf56c0d15b..7c760925220f 100644
--- a/drivers/net/tokenring/Config.help
+++ b/drivers/net/tokenring/Config.help
@@ -129,3 +129,21 @@ CONFIG_SMCTR
The module will be called smctr.o. If you want to compile it
as a module, say M here and read <file:Documentation/modules.txt>.
+3COM 3C359 Token Link Velocity XL PCI adapter support
+CONFIG_3C359
+ This is support for the 3Com PCI Velocity XL cards, specifically
+ the 3Com 3C359, please note this is not for the 3C339 cards, you
+ should use the tms380 driver instead.
+
+ If you have such an adapter, say Y and read the Token-Ring
+ mini-HOWTO, available from <http://www.linuxdoc.org/docs.html#howto>.
+
+ This driver is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want).
+ The module will will be called 3c359.o. If you want to compile it
+ as a module, say M here and read Documentation/modules.txt.
+
+ Also read the file <file:Documentation/networking/3c359.txt> or check the
+ Linux Token Ring Project site for the latest information at
+ <http://www.linuxtr.net>
+
diff --git a/drivers/net/tokenring/Config.in b/drivers/net/tokenring/Config.in
index e087359bcb2f..f996a3dd9542 100644
--- a/drivers/net/tokenring/Config.in
+++ b/drivers/net/tokenring/Config.in
@@ -18,6 +18,7 @@ if [ "$CONFIG_TR" != "n" ]; then
fi
dep_tristate ' IBM Olympic chipset PCI adapter support' CONFIG_IBMOL $CONFIG_TR $CONFIG_PCI
dep_tristate ' IBM Lanstreamer chipset PCI adapter support' CONFIG_IBMLS $CONFIG_TR $CONFIG_PCI
+ dep_tristate ' 3Com 3C359 Token Link Velocity XL adapter support' CONFIG_3C359 $CONFIG_TR $CONFIG_PCI
tristate ' Generic TMS380 Token Ring ISA/PCI adapter support' CONFIG_TMS380TR
if [ "$CONFIG_TMS380TR" != "n" ]; then
dep_tristate ' Generic TMS380 PCI support' CONFIG_TMSPCI $CONFIG_PCI
diff --git a/drivers/net/tokenring/Makefile b/drivers/net/tokenring/Makefile
index 4a8c344e7e35..8c1c1ff5eb38 100644
--- a/drivers/net/tokenring/Makefile
+++ b/drivers/net/tokenring/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_MADGEMC) += madgemc.o
obj-$(CONFIG_TMSPCI) += tmspci.o
obj-$(CONFIG_TMSISA) += tmsisa.o
obj-$(CONFIG_SMCTR) += smctr.o
+obj-$(CONFIG_3C359) += 3c359.o
O_TARGET := tr.o
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index a9000039c999..9d62e00518d6 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -321,6 +321,7 @@ enum via_rhine_chips {
VT86C100A = 0,
VT6102,
VT3043,
+ VT6105,
};
struct via_rhine_chip_info {
@@ -349,7 +350,7 @@ static struct via_rhine_chip_info via_rhine_chip_info[] __devinitdata =
{ "VIA VT6102 Rhine-II", RHINE_IOTYPE, 256,
CanHaveMII | HasWOL },
{ "VIA VT3043 Rhine", RHINE_IOTYPE, 128,
- CanHaveMII | ReqTxAlign }
+ CanHaveMII | ReqTxAlign },
{ "VIA VT6105 Rhine-III", RHINE_IOTYPE, 256,
CanHaveMII | HasWOL },
};
diff --git a/drivers/usb/ov511.c b/drivers/usb/ov511.c
index fe947754f2f3..0957c2b8246b 100644
--- a/drivers/usb/ov511.c
+++ b/drivers/usb/ov511.c
@@ -380,10 +380,9 @@ static unsigned char uvQuanTable518[] = OV518_UVQUANTABLE;
static inline unsigned long
kvirt_to_pa(unsigned long adr)
{
- unsigned long va, kva, ret;
+ unsigned long kva, ret;
- va = VMALLOC_VMADDR(adr);
- kva = page_address(vmalloc_to_page(va));
+ kva = page_address(vmalloc_to_page((void *)adr));
ret = __pa(kva);
return ret;
}
diff --git a/drivers/usb/pwc-if.c b/drivers/usb/pwc-if.c
index a256758bafce..6a9698784e0d 100644
--- a/drivers/usb/pwc-if.c
+++ b/drivers/usb/pwc-if.c
@@ -184,10 +184,9 @@ static struct video_device pwc_template = {
*/
static inline unsigned long kvirt_to_pa(unsigned long adr)
{
- unsigned long va, kva, ret;
+ unsigned long kva, ret;
- va = VMALLOC_VMADDR(adr);
- kva = page_address(vmalloc_to_page(va));
+ kva = page_address(vmalloc_to_page((void *)adr));
ret = __pa(kva);
return ret;
}
diff --git a/drivers/usb/se401.c b/drivers/usb/se401.c
index c421e05c280c..755858e6f219 100644
--- a/drivers/usb/se401.c
+++ b/drivers/usb/se401.c
@@ -89,10 +89,9 @@ static struct usb_driver se401_driver;
*/
static inline unsigned long kvirt_to_pa(unsigned long adr)
{
- unsigned long va, kva, ret;
+ unsigned long kva, ret;
- va = VMALLOC_VMADDR(adr);
- kva = page_address(vmalloc_to_page(va));
+ kva = page_address(vmalloc_to_page((void *)adr));
ret = __pa(kva);
return ret;
}
diff --git a/drivers/usb/usbvideo.c b/drivers/usb/usbvideo.c
index 50571ce0335e..e2dd62a84c1f 100644
--- a/drivers/usb/usbvideo.c
+++ b/drivers/usb/usbvideo.c
@@ -68,10 +68,9 @@ static int usbvideo_default_procfs_write_proc(
*/
unsigned long usbvideo_kvirt_to_pa(unsigned long adr)
{
- unsigned long va, kva, ret;
+ unsigned long kva, ret;
- va = VMALLOC_VMADDR(adr);
- kva = page_address(vmalloc_to_page(va));
+ kva = page_address(vmalloc_to_page((void *)adr));
ret = __pa(kva);
MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
return ret;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 580b32a99f93..6599c710fd37 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -585,7 +585,7 @@ static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * m
extern struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr);
-extern struct page * vmalloc_to_page(unsigned long adr);
+extern struct page * vmalloc_to_page(void *addr);
#endif /* __KERNEL__ */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 1def04889c3b..03d3d6eea25a 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -772,6 +772,7 @@
#define PCI_VENDOR_ID_3COM 0x10b7
#define PCI_DEVICE_ID_3COM_3C985 0x0001
#define PCI_DEVICE_ID_3COM_3C339 0x3390
+#define PCI_DEVICE_ID_3COM_3C359 0x3590
#define PCI_DEVICE_ID_3COM_3C590 0x5900
#define PCI_DEVICE_ID_3COM_3C595TX 0x5950
#define PCI_DEVICE_ID_3COM_3C595T4 0x5951
diff --git a/mm/memory.c b/mm/memory.c
index 976fd785cb6f..a7ecc422dd1a 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1480,8 +1480,9 @@ int make_pages_present(unsigned long addr, unsigned long end)
/*
* Map a vmalloc()-space virtual address to the physical page.
*/
-struct page * vmalloc_to_page(unsigned long addr)
+struct page * vmalloc_to_page(void * vmalloc_addr)
{
+ unsigned long addr = (unsigned long) vmalloc_addr;
struct page *page = NULL;
pgd_t *pgd = pgd_offset_k(addr);
pmd_t *pmd;