Whamcloud - gitweb
update driver for sk98 Ethernet controller to enabale more nodes in CNBuild.
authorhuanghua <huanghua>
Fri, 8 Dec 2006 03:37:27 +0000 (03:37 +0000)
committerhuanghua <huanghua>
Fri, 8 Dec 2006 03:37:27 +0000 (03:37 +0000)
If we do not use this kind of sk98, no need to apply this patch.

lustre/kernel_patches/patches/linux-2.6.9-network_driver-for-sk98.patch [new file with mode: 0644]
lustre/kernel_patches/series/2.6-rhel4.series

diff --git a/lustre/kernel_patches/patches/linux-2.6.9-network_driver-for-sk98.patch b/lustre/kernel_patches/patches/linux-2.6.9-network_driver-for-sk98.patch
new file mode 100644 (file)
index 0000000..64439f9
--- /dev/null
@@ -0,0 +1,39833 @@
+diff -ruN linux-2.6.9.old/Documentation/networking/sk98lin.txt linux-2.6.9.new/Documentation/networking/sk98lin.txt
+--- linux-2.6.9.old/Documentation/networking/sk98lin.txt       2004-10-19 05:54:38.000000000 +0800
++++ linux-2.6.9.new/Documentation/networking/sk98lin.txt       2006-12-07 14:35:03.000000000 +0800
+@@ -1,38 +1,56 @@
+-(C)Copyright 1999-2004 Marvell(R).
+-All rights reserved
+-===========================================================================
++(C)Copyright 1999-2005 Marvell(R).
++All rights reserved.
++================================================================================
+-sk98lin.txt created 13-Feb-2004
++sk98lin.txt created 20-Jun-2005
+-Readme File for sk98lin v6.23
+-Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX
++Readme File for sk98lin v8.23.1.3
++Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter driver for LINUX
+ This file contains
+  1  Overview
+- 2  Required Files
+- 3  Installation
+-    3.1  Driver Installation
+-    3.2  Inclusion of adapter at system start
+- 4  Driver Parameters
+-    4.1  Per-Port Parameters
+-    4.2  Adapter Parameters
+- 5  Large Frame Support
+- 6  VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
+- 7  Troubleshooting
++ 2  Supported Functions
++ 3  Required Files
++ 4  Installation
++    4.1  Driver Installation
++    4.2  Inclusion of adapter at system start
++ 5  Driver Parameters
++    5.1  Per-Port Parameters
++    5.2  Adapter Parameters
++ 6  Ethtool Support
++ 7  Large Frame Support
++ 8  VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
++ 9  Wake on Lan support
++10  Troubleshooting
+-===========================================================================
++================================================================================
+ 1  Overview
+ ===========
+-The sk98lin driver supports the Marvell Yukon and SysKonnect 
+-SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux. It has 
+-been tested with Linux on Intel/x86 machines.
++The sk98lin driver supports the Marvell Yukon, Yukon EC/FE, Yukon 2
++and SysKonnect SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux.
++It has been tested with Linux on Intel/x86, x86_64 and IA64 machines.
+ ***
++2  Supported Functions
++======================
++
++The following functions are supported by the driver:
+-2  Required Files
++   NOTE 1: The hardware support depends on the used card
++ 
++   - RX/TX HW Checksum
++   - Hardware interrupt moderation (static/dynamic)
++   - Transmit poll
++   - Zerocopy/Scatter-Gather
++   - Ethtool support
++   - Wake on Lan (Magic Packet only) (From suspend and APM only)
++   - DualNet
++ 
++
++3  Required Files
+ =================
+ The linux kernel source.
+@@ -40,16 +58,14 @@
+ ***
+-3  Installation
++4  Installation
+ ===============
+ It is recommended to download the latest version of the driver from the 
+-SysKonnect web site www.syskonnect.com. If you have downloaded the latest
+-driver, the Linux kernel has to be patched before the driver can be 
+-installed. For details on how to patch a Linux kernel, refer to the 
+-patch.txt file.
++SysKonnect web site www.syskonnect.com. For details on Installation 
++Instructions for sk98lin Driver, please refer to the README.txt file.
+-3.1  Driver Installation
++4.1  Driver Installation
+ ------------------------
+ The following steps describe the actions that are required to install
+@@ -110,13 +126,13 @@
+    
+    NOTE 1: If you have more than one Marvell Yukon or SysKonnect SK-98xx 
+            adapter installed, the adapters will be listed as 'eth0', 
+-                   'eth1', 'eth2', etc.
+-                   For each adapter, repeat steps 3 and 4 below.
++           'eth1', 'eth2', etc.
++           For each adapter, repeat steps 3 and 4 below.
+    NOTE 2: If you have other Ethernet adapters installed, your Marvell
+            Yukon or SysKonnect SK-98xx adapter will be mapped to the 
+-                   next available number, e.g. 'eth1'. The mapping is executed 
+-                   automatically.
++           next available number, e.g. 'eth1'. The mapping is executed 
++           automatically.
+            The module installation message (displayed either in a system
+            log file or on the console) prints a line for each adapter 
+            found containing the corresponding 'ethX'.
+@@ -153,7 +169,7 @@
+ 1. Execute the command "ifconfig eth0 down".
+ 2. Execute the command "rmmod sk98lin".
+-3.2  Inclusion of adapter at system start
++4.2  Inclusion of adapter at system start
+ -----------------------------------------
+ Since a large number of different Linux distributions are 
+@@ -165,7 +181,8 @@
+ ***
+-4  Driver Parameters
++
++5  Driver Parameters
+ ====================
+ Parameters can be set at the command line after the module has been 
+@@ -174,7 +191,7 @@
+ to the driver module.
+ If you use the kernel module loader, you can set driver parameters
+-in the file /etc/modprobe.conf (or /etc/modules.conf in 2.4 or earlier).
++in the file /etc/modules.conf (or old name: /etc/conf.modules).
+ To set the driver parameters in this file, proceed as follows:
+ 1. Insert a line of the form :
+@@ -208,7 +225,7 @@
+       more adapters, adjust this and recompile.
+-4.1  Per-Port Parameters
++5.1  Per-Port Parameters
+ ------------------------
+ These settings are available for each port on the adapter.
+@@ -282,7 +299,7 @@
+ with this parameter.
+-4.2  Adapter Parameters
++5.2  Adapter Parameters
+ -----------------------
+ Connection Type (SK-98xx V2.0 copper adapters only)
+@@ -379,7 +396,6 @@
+ is tremendous. On the other hand, selecting a very short moderation time might
+ compensate the use of any moderation being applied.
+-
+ Preferred Port
+ --------------
+ Parameter:    PrefPort
+@@ -394,7 +410,7 @@
+ ------------------------------------------------
+ Parameter:    RlmtMode
+ Values:       CheckLinkState,CheckLocalPort, CheckSeg, DualNet
+-Default:      CheckLinkState
++Default:      CheckLinkState (DualNet on dual port adapters)
+ RLMT monitors the status of the port. If the link of the active port 
+ fails, RLMT switches immediately to the standby link. The virtual link is 
+@@ -429,10 +445,94 @@
+       where a network path between the ports on one adapter exists. 
+       Moreover, they are not designed to work where adapters are connected
+       back-to-back.
++
++LowLatency 
++----------
++Parameter:    LowLatency
++Values:       On, Off
++Default:      Off
++
++This is used to reduce the packet latency time of the adapter. Setting the 
++LowLatency parameter to 'On' forces the adapter to pass any received packet
++immediately to upper network layers and to send out any transmit packet as
++fast as possible.
++
++NOTE 1: The system load increases if LowLatency is set to 'On' and a lot
++        of data packets are transmitted and received.
++
++NOTE 2: This parameter is only used on adapters which are based on 
++        PCI Express compatible chipsets.
+ ***
+-5  Large Frame Support
++6  Ethtool Support
++==================
++
++The sk98lin driver provides built-in ethtool support. The ethtool 
++can be used to display or modify interface specific configurations.
++
++Ethtool commands are invoked using a single parameter which reflects
++the requested ethtool command plus an optional number of parameters 
++which belong to the desired command.
++
++It is not the intention of this section to explain the ethtool command
++line tool and all its options. For further information refer to the 
++manpage of the ethtool.  This sections describes only the sk98lin 
++driver supported ethtool commands.
++
++Pause Parameters
++----------------
++Query command:  -a
++Set command:    -A [autoneg on|off] [rx on|off] [tx on|off]
++Sample:         ethtool -A eth0 rx off tx off
++
++Coalescing Parameters
++---------------------
++Query command:  -c
++Set command:    -C [sample-interval I]
++                   [rx-usecs N] [tx-usecs N]
++                   [rx-usecs-low N] [tx-usecs-low N]
++                   [rx-usecs-high N] [tx-usecs-high N]
++Parameter:      I = Length of sample interval, in seconds
++                    (supported values range from 1...10)
++                N = Length of coalescing interval, in microseconds
++                    (supported values range from 25...33,333)
++Sample:         ethtool -C eth2 rx-usecs 500 tx-usecs 500
++
++NOTE: The sk98lin driver does not support different settings
++      for the rx and tx interrupt coalescing parameters.
++
++Driver Information
++------------------
++Query command:  -i
++Sample:         ethtool -i eth1
++
++Checksumming Parameters
++-----------------------
++Query command:  -k
++Set command:    -K [rx on|off] [tx on|off] [sg on|off]
++Sample:         ethtool -K eth0 sg off
++
++Locate NIC Command
++------------------
++Query command:  -p [N]
++Parameter:      N = Amount of time to perform locate NIC command, in seconds
++Sample:         ethtool -p 10 eth1
++
++Driver-specific Statistics
++--------------------------
++Query command:  -S
++Sample:         ethtool -S eth0
++
++Setting Parameters
++------------------
++Set command:    -s [speed 10|100|1000] [duplex half|full] 
++                   [autoneg on|off] [wol gd]
++Sample:         ethtool -s eth2 wol d
++***
++
++
++7  Large Frame Support
+ ======================
+ The driver supports large frames (also called jumbo frames). Using large 
+@@ -444,10 +544,10 @@
+       ifconfig eth0 mtu 9000
+ This will only work if you have two adapters connected back-to-back
+ or if you use a switch that supports large frames. When using a switch, 
+-it should be configured to allow large frames and auto-negotiation should  
+-be set to OFF. The setting must be configured on all adapters that can be 
+-reached by the large frames. If one adapter is not set to receive large 
+-frames, it will simply drop them.
++it should be configured to allow large frames. The setting must be 
++configured on all adapters that can be reached by the large frames. 
++If one adapter is not set to receive large frames, it will simply drop 
++them.
+ You can switch back to the standard ethernet frame size by executing the 
+ following command:
+@@ -459,7 +559,7 @@
+ ***
+-6  VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
++8  VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
+ ==================================================================
+ The Marvell Yukon/SysKonnect Linux drivers are able to support VLAN and 
+@@ -477,8 +577,21 @@
+       cause problems when unloading the driver.
+-7  Troubleshooting
+-==================
++9  Wake on Lan support
++======================
++
++The sk98lin driver supports wake up from suspend mode with MagicPacket
++on APM systems. Wake on Lan support is enabled by default. To disable it 
++please use the ethtool.
++
++NOTE 1: APM support has to be enabled in BIOS and in the kernel.
++
++NOTE 2: Refer to the kernel documentation for additional requirements 
++        regarding APM support.
++
++
++10  Troubleshooting
++===================
+ If any problems occur during the installation process, check the 
+ following list:
+diff -ruN linux-2.6.9.old/drivers/net/Kconfig linux-2.6.9.new/drivers/net/Kconfig
+--- linux-2.6.9.old/drivers/net/Kconfig        2006-12-07 14:37:37.000000000 +0800
++++ linux-2.6.9.new/drivers/net/Kconfig        2006-12-07 14:45:12.000000000 +0800
+@@ -2071,6 +2071,7 @@
+         To compile this driver as a module, choose M here: the module
+         will be called sky2.  This is recommended.
++
+ config SK98LIN
+       tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
+       depends on PCI
+@@ -2080,6 +2081,22 @@
+         by this driver:
+           - 3Com 3C940 Gigabit LOM Ethernet Adapter
+           - 3Com 3C941 Gigabit LOM Ethernet Adapter
++          - 88E8021 Marvell 1000 Mbit PCI-X, single Port Copper 
++          - 88E8021 Marvell 1000 Mbit PCI-X, single Port Fiber LX 
++          - 88E8021 Marvell 1000 Mbit PCI-X, single Port Fiber SX 
++          - 88E8022 Marvell 1000 Mbit PCI-X, dual Port Copper 
++          - 88E8022 Marvell 1000 Mbit PCI-X, dual Port Copper (Gateway) 
++          - 88E8022 Marvell 1000 Mbit PCI-X, dual Port Fiber LX 
++          - 88E8022 Marvell 1000 Mbit PCI-X, dual Port Fiber SX 
++          - 88E8061 Marvell 1000 Mbit PCI-E, single Port Copper 
++          - 88E8061 Marvell 1000 Mbit PCI-E, single Port Fiber LX 
++          - 88E8061 Marvell 1000 Mbit PCI-E, single Port Fiber SX 
++          - 88E8062 Marvell 1000 Mbit PCI-E, dual Port Copper 
++          - 88E8062 Marvell 1000 Mbit PCI-E, dual Port Copper (Gateway) 
++          - 88E8062 Marvell 1000 Mbit PCI-E, dual Port Fiber LX 
++          - 88E8062 Marvell 1000 Mbit PCI-E, dual Port Fiber SX 
++          - Abocom EFE3K - 10/100 Ethernet Expresscard
++          - Abocom EGE5K - Giga Ethernet Expresscard
+           - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter
+           - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter
+           - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter
+@@ -2090,31 +2107,79 @@
+           - Allied Telesyn AT-2971T Gigabit Ethernet Adapter
+           - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45
+           - DGE-530T Gigabit Ethernet Adapter
++          - DGE-560T Gigabit Ethernet Adapter
+           - EG1032 v2 Instant Gigabit Network Adapter
+           - EG1064 v2 Instant Gigabit Network Adapter
+-          - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
+-          - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron)
+-          - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
+-          - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
+-          - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox)
+-          - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn)
+-          - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
+-          - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
+-          - Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel)
++          - Marvell 88E8001 Gigabit Ethernet Controller (Abit)
++          - Marvell 88E8001 Gigabit Ethernet Controller (Albatron)
++          - Marvell 88E8001 Gigabit Ethernet Controller (Asus)
++          - Marvell 88E8001 Gigabit Ethernet Controller (Chaintech)
++          - Marvell 88E8001 Gigabit Ethernet Controller (ECS)
++          - Marvell 88E8001 Gigabit Ethernet Controller (Epox)
++          - Marvell 88E8001 Gigabit Ethernet Controller (Foxconn)
++          - Marvell 88E8001 Gigabit Ethernet Controller (Gigabyte)
++          - Marvell 88E8001 Gigabit Ethernet Controller (Iwill)
++          - Marvell 88E8035 Fast Ethernet Controller (LGE)
++          - Marvell 88E8035 Fast Ethernet Controller (Toshiba)
++          - Marvell 88E8036 Fast Ethernet Controller (Arima)
++          - Marvell 88E8036 Fast Ethernet Controller (Compal)
++          - Marvell 88E8036 Fast Ethernet Controller (Inventec)
++          - Marvell 88E8036 Fast Ethernet Controller (LGE)
++          - Marvell 88E8036 Fast Ethernet Controller (Mitac)
++          - Marvell 88E8036 Fast Ethernet Controller (Panasonic)
++          - Marvell 88E8036 Fast Ethernet Controller (Quanta)
++          - Marvell 88E8036 Fast Ethernet Controller (Toshiba)
++          - Marvell 88E8036 Fast Ethernet Controller (Wistron)
++          - Marvell 88E8050 Gigabit Ethernet Controller (Gateway)
++          - Marvell 88E8050 Gigabit Ethernet Controller (Intel)
++          - Marvell 88E8052 Gigabit Ethernet Controller (ASRock)
++          - Marvell 88E8052 Gigabit Ethernet Controller (Aopen)
++          - Marvell 88E8052 Gigabit Ethernet Controller (Asus)
++          - Marvell 88E8052 Gigabit Ethernet Controller (Gateway)
++          - Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte)
++          - Marvell 88E8052 Gigabit Ethernet Controller (MSI)
++          - Marvell 88E8052 Gigabit Ethernet Controller (Wistron)
++          - Marvell 88E8053 Gigabit Ethernet Controller (ASRock)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Albatron)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Aopen)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Arima)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Asus)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Chaintech)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Clevo)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Compal)
++          - Marvell 88E8053 Gigabit Ethernet Controller (DFI)
++          - Marvell 88E8053 Gigabit Ethernet Controller (ECS)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Epox)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Inventec)
++          - Marvell 88E8053 Gigabit Ethernet Controller (LGE)
++          - Marvell 88E8053 Gigabit Ethernet Controller (MSI)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Mitac)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Panasonic)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Quanta)
++          - Marvell 88E8053 Gigabit Ethernet Controller (SOYO)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Toshiba)
++          - Marvell 88E8053 Gigabit Ethernet Controller (Trigem)
++          - Marvell RDK-8001 
+           - Marvell RDK-8001 Adapter
+           - Marvell RDK-8002 Adapter
++          - Marvell RDK-8003 
+           - Marvell RDK-8003 Adapter
+           - Marvell RDK-8004 Adapter
+           - Marvell RDK-8006 Adapter
+           - Marvell RDK-8007 Adapter
+           - Marvell RDK-8008 Adapter
+           - Marvell RDK-8009 Adapter
+-          - Marvell RDK-8010 Adapter
++          - Marvell RDK-8010 
+           - Marvell RDK-8011 Adapter
+           - Marvell RDK-8012 Adapter
+-          - Marvell RDK-8052 Adapter
+-          - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
+-          - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
++          - Marvell RDK-8035 
++          - Marvell RDK-8036 
++          - Marvell RDK-8052 
++          - Marvell RDK-8053 
++          - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (32 bit)
++          - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (64 bit)
+           - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
+           - SK-9521 10/100/1000Base-T Adapter
+           - SK-9521 V2.0 10/100/1000Base-T Adapter
+@@ -2134,6 +2199,14 @@
+           - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
+           - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
+           - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
++          - SK-9S21 Server Adapter 
++          - SK-9S22 Server Adapter 
++          - SK-9S24 Server Adapter 
++          - SK-9S34 Server Adapter 
++          - SK-9S81 Server Adapter 
++          - SK-9S82 Server Adapter 
++          - SK-9S91 Server Adapter 
++          - SK-9S92 Server Adapter 
+           - SMC EZ Card 1000 (SMC9452TXV.2)
+         
+         The adapters support Jumbo Frames.
+@@ -2147,8 +2220,9 @@
+         
+         If you want to compile this driver as a module ( = code which can be
+         inserted in and removed from the running kernel whenever you want),
+-        say M here and read Documentation/kbuild/modules.txt. The module will
+-        be called sk98lin. This is recommended.
++        say M here and read Documentation/modules.txt. This is recommended.
++        The module will be called sk98lin. This is recommended.
++
+ config VIA_VELOCITY
+       tristate "VIA Velocity support"
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/lm80.h linux-2.6.9.new/drivers/net/sk98lin/h/lm80.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/lm80.h       2004-10-19 05:55:06.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/lm80.h       2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      lm80.h  
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.6 $
+- * Date:      $Date: 2003/05/13 17:26:52 $
++ * Version:   $Revision: 2.1 $
++ * Date:      $Date: 2003/10/27 14:16:08 $
+  * Purpose:   Contains all defines for the LM80 Chip
+  *            (National Semiconductor).
+  *
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skaddr.h linux-2.6.9.new/drivers/net/sk98lin/h/skaddr.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skaddr.h     2004-10-19 05:54:30.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skaddr.h     2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skaddr.h
+  * Project:   Gigabit Ethernet Adapters, ADDR-Modul
+- * Version:   $Revision: 1.29 $
+- * Date:      $Date: 2003/05/13 16:57:24 $
++ * Version:   $Revision: 2.1 $
++ * Date:      $Date: 2003/10/27 14:16:07 $
+  * Purpose:   Header file for Address Management (MC, UC, Prom).
+  *
+  ******************************************************************************/
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skcsum.h linux-2.6.9.new/drivers/net/sk98lin/h/skcsum.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skcsum.h     2004-10-19 05:53:10.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skcsum.h     2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skcsum.h
+  * Project:   GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
+- * Version:   $Revision: 1.10 $
+- * Date:      $Date: 2003/08/20 13:59:57 $
++ * Version:   $Revision: 2.2 $
++ * Date:      $Date: 2003/12/29 15:37:26 $
+  * Purpose:   Store/verify Internet checksum in send/receive packets.
+  *
+  ******************************************************************************/
+@@ -157,9 +157,7 @@
+ typedef struct s_Csum {
+       /* Enabled receive SK_PROTO_XXX bit flags. */
+       unsigned ReceiveFlags[SK_MAX_NETS];
+-#ifdef TX_CSUM
+       unsigned TransmitFlags[SK_MAX_NETS];
+-#endif /* TX_CSUM */
+       /* The protocol statistics structure; one per supported protocol. */
+       SKCS_PROTO_STATS ProtoStats[SK_MAX_NETS][SKCS_NUM_PROTOCOLS];
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skdebug.h linux-2.6.9.new/drivers/net/sk98lin/h/skdebug.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skdebug.h    2004-10-19 05:54:26.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skdebug.h    2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skdebug.h
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.14 $
+- * Date:      $Date: 2003/05/13 17:26:00 $
++ * Version:   $Revision: 2.3 $
++ * Date:      $Date: 2005/01/25 16:44:28 $
+  * Purpose:   SK specific DEBUG support
+  *
+  ******************************************************************************/
+@@ -11,13 +11,12 @@
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2005 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+  *    the Free Software Foundation; either version 2 of the License, or
+  *    (at your option) any later version.
+- *
+  *    The information in this file is provided "AS IS" without warranty.
+  *
+  ******************************************************************************/
+@@ -28,9 +27,9 @@
+ #ifdef        DEBUG
+ #ifndef SK_DBG_MSG
+ #define SK_DBG_MSG(pAC,comp,cat,arg) \
+-              if ( ((comp) & SK_DBG_CHKMOD(pAC)) &&   \
+-                    ((cat) & SK_DBG_CHKCAT(pAC)) ) {  \
+-                      SK_DBG_PRINTF arg ;             \
++              if ( ((comp) & SK_DBG_CHKMOD(pAC)) &&   \
++                    ((cat) & SK_DBG_CHKCAT(pAC)) ) {  \
++                      SK_DBG_PRINTF arg;              \
+               }
+ #endif
+ #else
+@@ -58,6 +57,13 @@
+ #define SK_DBGMOD_ADDR        0x00000080L     /* ADDR module */
+ #define SK_DBGMOD_PECP        0x00000100L     /* PECP module */
+ #define SK_DBGMOD_POWM        0x00000200L     /* Power Management module */
++#ifdef SK_ASF
++#define SK_DBGMOD_ASF 0x00000400L     /* ASF module */
++#endif
++#ifdef SK_LBFO
++#define SK_DBGMOD_LACP        0x00000800L     /* link aggregation control protocol */
++#define SK_DBGMOD_FD  0x00001000L     /* frame distributor (link aggregation) */
++#endif /* SK_LBFO */
+ /* Debug events */
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skdrv1st.h linux-2.6.9.new/drivers/net/sk98lin/h/skdrv1st.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skdrv1st.h   2004-10-19 05:53:06.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skdrv1st.h   2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skdrv1st.h
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.4 $
+- * Date:      $Date: 2003/11/12 14:28:14 $
++ * Version:   $Revision: 1.5.2.5 $
++ * Date:      $Date: 2005/04/11 09:00:53 $
+  * Purpose:   First header file for driver and all other modules
+  *
+  ******************************************************************************/
+@@ -11,7 +11,7 @@
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect GmbH.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2005 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+@@ -22,20 +22,6 @@
+  *
+  ******************************************************************************/
+-/******************************************************************************
+- *
+- * Description:
+- *
+- * This is the first include file of the driver, which includes all
+- * neccessary system header files and some of the GEnesis header files.
+- * It also defines some basic items.
+- *
+- * Include File Hierarchy:
+- *
+- *    see skge.c
+- *
+- ******************************************************************************/
+-
+ #ifndef __INC_SKDRV1ST_H
+ #define __INC_SKDRV1ST_H
+@@ -58,6 +44,9 @@
+ #define SK_ADDR_EQUAL(a1,a2)          (!memcmp(a1,a2,6))
++#define SK_STRNCMP(s1,s2,len)         strncmp(s1,s2,len)
++#define SK_STRCPY(dest,src)           strcpy(dest,src)
++
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+@@ -78,11 +67,7 @@
+ #include <net/checksum.h>
+ #define SK_CS_CALCULATE_CHECKSUM
+-#ifndef CONFIG_X86_64
+-#define SkCsCalculateChecksum(p,l)    ((~ip_compute_csum(p, l)) & 0xffff)
+-#else
+-#define SkCsCalculateChecksum(p,l)    ((~ip_fast_csum(p, l)) & 0xffff)
+-#endif
++#define SkCsCalculateChecksum(p,l)    (~csum_fold(csum_partial(p, l, 0)))
+ #include      "h/sktypes.h"
+ #include      "h/skerror.h"
+@@ -90,6 +75,10 @@
+ #include      "h/lm80.h"
+ #include      "h/xmac_ii.h"
++#ifndef SK_BMU_RX_WM_PEX
++#define SK_BMU_RX_WM_PEX 0x80
++#endif
++
+ #ifdef __LITTLE_ENDIAN
+ #define SK_LITTLE_ENDIAN
+ #else
+@@ -188,3 +177,8 @@
+ #endif
++/*******************************************************************************
++ *
++ * End of file
++ *
++ ******************************************************************************/
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skdrv2nd.h linux-2.6.9.new/drivers/net/sk98lin/h/skdrv2nd.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skdrv2nd.h   2004-10-19 05:55:29.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skdrv2nd.h   2006-12-07 14:35:03.000000000 +0800
+@@ -1,17 +1,17 @@
+ /******************************************************************************
+  *
+- * Name:      skdrv2nd.h
+- * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.10 $
+- * Date:      $Date: 2003/12/11 16:04:45 $
+- * Purpose:   Second header file for driver and all other modules
++ * Name:        skdrv2nd.h
++ * Project:     GEnesis, PCI Gigabit Ethernet Adapter
++ * Version:     $Revision: 1.29.2.20 $
++ * Date:        $Date: 2005/06/17 14:09:50 $
++ * Purpose:     Second header file for driver and all other modules
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect GmbH.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2005 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+@@ -42,10 +42,11 @@
+ #include "h/skqueue.h"
+ #include "h/skgehwt.h"
+ #include "h/sktimer.h"
+-#include "h/ski2c.h"
++#include "h/sktwsi.h"
+ #include "h/skgepnmi.h"
+ #include "h/skvpd.h"
+ #include "h/skgehw.h"
++#include "h/sky2le.h"
+ #include "h/skgeinit.h"
+ #include "h/skaddr.h"
+ #include "h/skgesirq.h"
+@@ -53,104 +54,178 @@
+ #include "h/skrlmt.h"
+ #include "h/skgedrv.h"
++/* Defines for the poll cotroller */
++#ifdef HAVE_POLL_CONTROLLER
++#define SK_POLL_CONTROLLER
++#define CONFIG_SK98LIN_NAPI
++#elif CONFIG_NET_POLL_CONTROLLER
++#define SK_POLL_CONTROLLER
++#define CONFIG_SK98LIN_NAPI
++#endif
++
+-extern SK_MBUF                *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned);
+-extern void           SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*);
+-extern SK_U64         SkOsGetTime(SK_AC*);
+-extern int            SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
+-extern int            SkPciReadCfgWord(SK_AC*, int, SK_U16*);
+-extern int            SkPciReadCfgByte(SK_AC*, int, SK_U8*);
+-extern int            SkPciWriteCfgDWord(SK_AC*, int, SK_U32);
+-extern int            SkPciWriteCfgWord(SK_AC*, int, SK_U16);
+-extern int            SkPciWriteCfgByte(SK_AC*, int, SK_U8);
+-extern int            SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
+-
+-#ifdef SK_DIAG_SUPPORT
+-extern int            SkDrvEnterDiagMode(SK_AC *pAc);
+-extern int            SkDrvLeaveDiagMode(SK_AC *pAc);
++/******************************************************************************
++ *
++ * Generic driver defines
++ *
++ ******************************************************************************/
++
++#define USE_TIST_FOR_RESET    /* Use timestamp for reset */
++#define Y2_RECOVERY           /* use specific recovery yukon2 functions */
++#define Y2_LE_CHECK           /* activate check for LE order */
++#define Y2_SYNC_CHECK         /* activate check for receiver in sync */
++#define SK_YUKON2             /* Enable Yukon2 dual net support */
++#define USE_SK_TX_CHECKSUM    /* use the tx hw checksum driver functionality */
++#define USE_SK_RX_CHECKSUM    /* use the rx hw checksum driver functionality */
++#define USE_SK_TSO_FEATURE    /* use TCP segmentation offload if possible */
++#define SK_COPY_THRESHOLD 50  /* threshold for copying small RX frames; 
++                               * 0 avoids copying, 9001 copies all */
++#define SK_MAX_CARD_PARAM 16  /* number of adapters that can be configured via 
++                               * command line params */
++//#define USE_TX_COMPLETE     /* use of a transmit complete interrupt */
++#ifndef CONFIG_SK98LIN_NAPI
++#define Y2_RX_CHECK           /* RX Check timestamp */
++#endif
++
++/*
++ * use those defines for a compile-in version of the driver instead
++ * of command line parameters
++ */
++// #define LINK_SPEED_A       {"Auto",}
++// #define LINK_SPEED_B       {"Auto",}
++// #define AUTO_NEG_A {"Sense",}
++// #define AUTO_NEG_B {"Sense"}
++// #define DUP_CAP_A  {"Both",}
++// #define DUP_CAP_B  {"Both",}
++// #define FLOW_CTRL_A        {"SymOrRem",}
++// #define FLOW_CTRL_B        {"SymOrRem",}
++// #define ROLE_A     {"Auto",}
++// #define ROLE_B     {"Auto",}
++// #define PREF_PORT  {"A",}
++// #define CON_TYPE   {"Auto",}
++// #define RLMT_MODE  {"CheckLinkState",}
++
++#ifdef Y2_RECOVERY
++#define CHECK_TRANSMIT_TIMEOUT
++#define Y2_RESYNC_WATERMARK     1000000L
+ #endif
++
++/******************************************************************************
++ *
++ * Generic ISR defines
++ *
++ ******************************************************************************/
++
++#define SkIsrRetVar     irqreturn_t
++#define SkIsrRetNone    IRQ_NONE
++#define SkIsrRetHandled IRQ_HANDLED
++
++#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
++#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
++#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)
++
++/******************************************************************************
++ *
++ * Global function prototypes
++ *
++ ******************************************************************************/
++
++extern SK_MBUF *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned);
++extern void SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*);
++extern SK_U64 SkOsGetTime(SK_AC*);
++extern int SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
++extern int SkPciReadCfgWord(SK_AC*, int, SK_U16*);
++extern int SkPciReadCfgByte(SK_AC*, int, SK_U8*);
++extern int SkPciWriteCfgDWord(SK_AC*, int, SK_U32);
++extern int SkPciWriteCfgWord(SK_AC*, int, SK_U16);
++extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8);
++extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
++extern int SkDrvEnterDiagMode(SK_AC *pAc);
++extern int SkDrvLeaveDiagMode(SK_AC *pAc);
++
++/******************************************************************************
++ *
++ * Linux specific RLMT buffer structure (SK_MBUF typedef in skdrv1st)!
++ *
++ ******************************************************************************/
++
+ struct s_DrvRlmtMbuf {
+-      SK_MBUF         *pNext;         /* Pointer to next RLMT Mbuf. */
+-      SK_U8           *pData;         /* Data buffer (virtually contig.). */
+-      unsigned        Size;           /* Data buffer size. */
+-      unsigned        Length;         /* Length of packet (<= Size). */
+-      SK_U32          PortIdx;        /* Receiving/transmitting port. */
++      SK_MBUF         *pNext;    /* Pointer to next RLMT Mbuf.       */
++      SK_U8           *pData;    /* Data buffer (virtually contig.). */
++      unsigned         Size;     /* Data buffer size.                */
++      unsigned         Length;   /* Length of packet (<= Size).      */
++      SK_U32           PortIdx;  /* Receiving/transmitting port.     */
+ #ifdef SK_RLMT_MBUF_PRIVATE
+-      SK_RLMT_MBUF    Rlmt;           /* Private part for RLMT. */
+-#endif  /* SK_RLMT_MBUF_PRIVATE */
+-      struct sk_buff  *pOs;           /* Pointer to message block */
++      SK_RLMT_MBUF     Rlmt;     /* Private part for RLMT.           */
++#endif
++      struct sk_buff  *pOs;      /* Pointer to message block         */
+ };
++/******************************************************************************
++ *
++ * Linux specific TIME defines
++ *
++ ******************************************************************************/
+-/*
+- * Time macros
+- */
+ #if SK_TICKS_PER_SEC == 100
+ #define SK_PNMI_HUNDREDS_SEC(t)       (t)
+ #else
+-#define SK_PNMI_HUNDREDS_SEC(t)       ((((unsigned long)t) * 100) / \
+-                                                                              (SK_TICKS_PER_SEC))
++#define SK_PNMI_HUNDREDS_SEC(t) ((((unsigned long)t)*100)/(SK_TICKS_PER_SEC))
+ #endif
+-/*
+- * New SkOsGetTime
+- */
+ #define SkOsGetTimeCurrent(pAC, pUsec) {\
+       struct timeval t;\
+       do_gettimeofday(&t);\
+       *pUsec = ((((t.tv_sec) * 1000000L)+t.tv_usec)/10000);\
+ }
++/******************************************************************************
++ *
++ * Linux specific IOCTL defines and typedefs
++ *
++ ******************************************************************************/
+-/*
+- * ioctl definitions
+- */
+-#define               SK_IOCTL_BASE           (SIOCDEVPRIVATE)
+-#define               SK_IOCTL_GETMIB         (SK_IOCTL_BASE + 0)
+-#define               SK_IOCTL_SETMIB         (SK_IOCTL_BASE + 1)
+-#define               SK_IOCTL_PRESETMIB      (SK_IOCTL_BASE + 2)
+-#define               SK_IOCTL_GEN            (SK_IOCTL_BASE + 3)
+-#define               SK_IOCTL_DIAG           (SK_IOCTL_BASE + 4)
+-
+-typedef struct s_IOCTL        SK_GE_IOCTL;
++#define       SK_IOCTL_BASE       (SIOCDEVPRIVATE)
++#define       SK_IOCTL_GETMIB     (SK_IOCTL_BASE + 0)
++#define       SK_IOCTL_SETMIB     (SK_IOCTL_BASE + 1)
++#define       SK_IOCTL_PRESETMIB  (SK_IOCTL_BASE + 2)
++#define       SK_IOCTL_GEN        (SK_IOCTL_BASE + 3)
++#define       SK_IOCTL_DIAG       (SK_IOCTL_BASE + 4)
++typedef struct s_IOCTL SK_GE_IOCTL;
+ struct s_IOCTL {
+       char __user *   pData;
+       unsigned int    Len;
+ };
++/******************************************************************************
++ *
++ * Generic sizes and length definitions
++ *
++ ******************************************************************************/
+-/*
+- * define sizes of descriptor rings in bytes
+- */
+-
+-#define               TX_RING_SIZE    (8*1024)
+-#define               RX_RING_SIZE    (24*1024)
+-
+-/*
+- * Buffer size for ethernet packets
+- */
+-#define       ETH_BUF_SIZE    1540
+-#define       ETH_MAX_MTU     1514
+-#define ETH_MIN_MTU   60
+-#define ETH_MULTICAST_BIT     0x01
+-#define SK_JUMBO_MTU  9000
+-
+-/*
+- * transmit priority selects the queue: LOW=asynchron, HIGH=synchron
+- */
+-#define TX_PRIO_LOW   0
+-#define TX_PRIO_HIGH  1
++#define TX_RING_SIZE  (24*1024)  /* GEnesis/Yukon */
++#define RX_RING_SIZE  (24*1024)  /* GEnesis/Yukon */
++#define RX_MAX_NBR_BUFFERS   128  /* Yukon-EC/-II */
++#define TX_MAX_NBR_BUFFERS   128  /* Yukon-EC/-II */
++
++#define       ETH_BUF_SIZE        1560  /* multiples of 8 bytes */
++#define       ETH_MAX_MTU         1514
++#define ETH_MIN_MTU         60
++#define ETH_MULTICAST_BIT   0x01
++#define SK_JUMBO_MTU        9000
++
++#define TX_PRIO_LOW    0 /* asynchronous queue */
++#define TX_PRIO_HIGH   1 /* synchronous queue */
++#define DESCR_ALIGN   64 /* alignment of Rx/Tx descriptors */
+-/*
+- * alignment of rx/tx descriptors
+- */
+-#define DESCR_ALIGN   64
++/******************************************************************************
++ *
++ * PNMI related definitions
++ *
++ ******************************************************************************/
+-/*
+- * definitions for pnmi. TODO
+- */
+ #define SK_DRIVER_RESET(pAC, IoC)     0
+ #define SK_DRIVER_SENDEVENT(pAC, IoC) 0
+ #define SK_DRIVER_SELFTEST(pAC, IoC)  0
+@@ -159,20 +234,16 @@
+ #define SK_DRIVER_SET_MTU(pAc,IoC,i,v)        0
+ #define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v)     0
+-/*
+-** Interim definition of SK_DRV_TIMER placed in this file until 
+-** common modules have boon finallized
+-*/
+-#define SK_DRV_TIMER                  11 
+-#define       SK_DRV_MODERATION_TIMER         1
+-#define SK_DRV_MODERATION_TIMER_LENGTH  1000000  /* 1 second */
+-#define SK_DRV_RX_CLEANUP_TIMER               2
+-#define SK_DRV_RX_CLEANUP_TIMER_LENGTH        1000000  /* 100 millisecs */
+-/*
+-** Definitions regarding transmitting frames 
+-** any calculating any checksum.
+-*/
++/******************************************************************************
++ *
++ * Various offsets and sizes
++ *
++ ******************************************************************************/
++
++#define       SK_DRV_MODERATION_TIMER         1   /* id */
++#define SK_DRV_MODERATION_TIMER_LENGTH  1   /* 1 second */
++
+ #define C_LEN_ETHERMAC_HEADER_DEST_ADDR 6
+ #define C_LEN_ETHERMAC_HEADER_SRC_ADDR  6
+ #define C_LEN_ETHERMAC_HEADER_LENTYPE   2
+@@ -198,114 +269,430 @@
+ #define C_PROTO_ID_UDP                  17       /* refer to RFC 790 or Stevens'   */
+ #define C_PROTO_ID_TCP                  6        /* TCP/IP illustrated for details */
+-/* TX and RX descriptors *****************************************************/
++/******************************************************************************
++ *
++ * Tx and Rx descriptor definitions
++ *
++ ******************************************************************************/
+ typedef struct s_RxD RXD; /* the receive descriptor */
+-
+ struct s_RxD {
+-      volatile SK_U32 RBControl;      /* Receive Buffer Control */
+-      SK_U32          VNextRxd;       /* Next receive descriptor,low dword */
+-      SK_U32          VDataLow;       /* Receive buffer Addr, low dword */
+-      SK_U32          VDataHigh;      /* Receive buffer Addr, high dword */
+-      SK_U32          FrameStat;      /* Receive Frame Status word */
+-      SK_U32          TimeStamp;      /* Time stamp from XMAC */
+-      SK_U32          TcpSums;        /* TCP Sum 2 / TCP Sum 1 */
+-      SK_U32          TcpSumStarts;   /* TCP Sum Start 2 / TCP Sum Start 1 */
+-      RXD             *pNextRxd;      /* Pointer to next Rxd */
+-      struct sk_buff  *pMBuf;         /* Pointer to Linux' socket buffer */
++      volatile SK_U32  RBControl;     /* Receive Buffer Control            */
++      SK_U32           VNextRxd;      /* Next receive descriptor,low dword */
++      SK_U32           VDataLow;      /* Receive buffer Addr, low dword    */
++      SK_U32           VDataHigh;     /* Receive buffer Addr, high dword   */
++      SK_U32           FrameStat;     /* Receive Frame Status word         */
++      SK_U32           TimeStamp;     /* Time stamp from XMAC              */
++      SK_U32           TcpSums;       /* TCP Sum 2 / TCP Sum 1             */
++      SK_U32           TcpSumStarts;  /* TCP Sum Start 2 / TCP Sum Start 1 */
++      RXD             *pNextRxd;      /* Pointer to next Rxd               */
++      struct sk_buff  *pMBuf;         /* Pointer to Linux' socket buffer   */
+ };
+ typedef struct s_TxD TXD; /* the transmit descriptor */
+-
+ struct s_TxD {
+-      volatile SK_U32 TBControl;      /* Transmit Buffer Control */
+-      SK_U32          VNextTxd;       /* Next transmit descriptor,low dword */
+-      SK_U32          VDataLow;       /* Transmit Buffer Addr, low dword */
+-      SK_U32          VDataHigh;      /* Transmit Buffer Addr, high dword */
+-      SK_U32          FrameStat;      /* Transmit Frame Status Word */
+-      SK_U32          TcpSumOfs;      /* Reserved / TCP Sum Offset */
+-      SK_U16          TcpSumSt;       /* TCP Sum Start */
+-      SK_U16          TcpSumWr;       /* TCP Sum Write */
+-      SK_U32          TcpReserved;    /* not used */
+-      TXD             *pNextTxd;      /* Pointer to next Txd */
+-      struct sk_buff  *pMBuf;         /* Pointer to Linux' socket buffer */
++      volatile SK_U32  TBControl;     /* Transmit Buffer Control            */
++      SK_U32           VNextTxd;      /* Next transmit descriptor,low dword */
++      SK_U32           VDataLow;      /* Transmit Buffer Addr, low dword    */
++      SK_U32           VDataHigh;     /* Transmit Buffer Addr, high dword   */
++      SK_U32           FrameStat;     /* Transmit Frame Status Word         */
++      SK_U32           TcpSumOfs;     /* Reserved / TCP Sum Offset          */
++      SK_U16           TcpSumSt;      /* TCP Sum Start                      */
++      SK_U16           TcpSumWr;      /* TCP Sum Write                      */
++      SK_U32           TcpReserved;   /* not used                           */
++      TXD             *pNextTxd;      /* Pointer to next Txd                */
++      struct sk_buff  *pMBuf;         /* Pointer to Linux' socket buffer    */
+ };
+-/* Used interrupt bits in the interrupts source register *********************/
++/******************************************************************************
++ *
++ * Generic Yukon-II defines
++ *
++ ******************************************************************************/
+-#define DRIVER_IRQS   ((IS_IRQ_SW)   | \
+-                      (IS_R1_F)      |(IS_R2_F)  | \
+-                      (IS_XS1_F)     |(IS_XA1_F) | \
+-                      (IS_XS2_F)     |(IS_XA2_F))
+-
+-#define SPECIAL_IRQS  ((IS_HW_ERR)   |(IS_I2C_READY)  | \
+-                      (IS_EXT_REG)   |(IS_TIMINT)     | \
+-                      (IS_PA_TO_RX1) |(IS_PA_TO_RX2)  | \
+-                      (IS_PA_TO_TX1) |(IS_PA_TO_TX2)  | \
+-                      (IS_MAC1)      |(IS_LNK_SYNC_M1)| \
+-                      (IS_MAC2)      |(IS_LNK_SYNC_M2)| \
+-                      (IS_R1_C)      |(IS_R2_C)       | \
+-                      (IS_XS1_C)     |(IS_XA1_C)      | \
+-                      (IS_XS2_C)     |(IS_XA2_C))
+-
+-#define IRQ_MASK      ((IS_IRQ_SW)   | \
+-                      (IS_R1_B)      |(IS_R1_F)     |(IS_R2_B) |(IS_R2_F) | \
+-                      (IS_XS1_B)     |(IS_XS1_F)    |(IS_XA1_B)|(IS_XA1_F)| \
+-                      (IS_XS2_B)     |(IS_XS2_F)    |(IS_XA2_B)|(IS_XA2_F)| \
+-                      (IS_HW_ERR)    |(IS_I2C_READY)| \
+-                      (IS_EXT_REG)   |(IS_TIMINT)   | \
+-                      (IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \
+-                      (IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \
+-                      (IS_MAC1)      |(IS_MAC2)     | \
+-                      (IS_R1_C)      |(IS_R2_C)     | \
+-                      (IS_XS1_C)     |(IS_XA1_C)    | \
+-                      (IS_XS2_C)     |(IS_XA2_C))
++#define LE_SIZE   sizeof(SK_HWLE)
++#define MAX_NUM_FRAGS   (MAX_SKB_FRAGS + 1)
++#define MIN_LEN_OF_LE_TAB   128
++#define MAX_LEN_OF_LE_TAB   4096
++#define MAX_UNUSED_RX_LE_WORKING   8
++#ifdef MAX_FRAG_OVERHEAD
++#undef MAX_FRAG_OVERHEAD
++#define MAX_FRAG_OVERHEAD   4
++#endif
++// as we have a maximum of 16 physical fragments,
++// maximum 1 ADDR64 per physical fragment
++// maximum 4 LEs for VLAN, Csum, LargeSend, Packet
++#define MIN_LE_FREE_REQUIRED   ((16*2) + 4)
++#define IS_GMAC(pAc)   (!pAc->GIni.GIGenesis)
++#ifdef USE_SYNC_TX_QUEUE
++#define TXS_MAX_LE   256
++#else /* !USE_SYNC_TX_QUEUE */
++#define TXS_MAX_LE   0
++#endif
++
++#define ETHER_MAC_HDR_LEN   (6+6+2) // MAC SRC ADDR, MAC DST ADDR, TYPE
++#define IP_HDR_LEN   20
++#define TCP_CSUM_OFFS   0x10
++#define UDP_CSUM_OFFS   0x06
++#define TXA_MAX_LE   256
++#define RX_MAX_LE   256
++#define ST_MAX_LE   (SK_MAX_MACS)*((3*RX_MAX_LE)+(TXA_MAX_LE)+(TXS_MAX_LE))
++
++#if (defined (Y2_RECOVERY) || defined (Y2_LE_CHECK))
++/* event for recovery from tx hang or rx out of sync */
++#define SK_DRV_RECOVER                  17
++#endif
++/******************************************************************************
++ *
++ * Structures specific for Yukon-II
++ *
++ ******************************************************************************/
++
++typedef       struct s_frag SK_FRAG;
++struct s_frag {
++      SK_FRAG       *pNext;
++      char          *pVirt;
++      SK_U64         pPhys;
++      unsigned int   FragLen;
++};
++
++typedef       struct s_packet SK_PACKET;
++struct s_packet {
++      /* Common infos: */
++      SK_PACKET       *pNext;         /* pointer for packet queues          */
++      unsigned int     PacketLen;     /* length of packet                   */
++      unsigned int     NumFrags;      /* nbr of fragments (for Rx always 1) */
++      SK_FRAG         *pFrag;         /* fragment list                      */
++      SK_FRAG          FragArray[MAX_NUM_FRAGS]; /* TX fragment array       */
++      unsigned int     NextLE;        /* next LE to use for the next packet */
++
++      /* Private infos: */
++      struct sk_buff  *pMBuf;         /* Pointer to Linux' socket buffer    */
++};
++
++typedef       struct s_queue SK_PKT_QUEUE;
++struct s_queue {
++      SK_PACKET       *pHead;
++      SK_PACKET       *pTail;
++      spinlock_t       QueueLock;     /* serialize packet accesses          */
++};
++
++/*******************************************************************************
++ *
++ * Macros specific for Yukon-II queues
++ *
++ ******************************************************************************/
++
++#define IS_Q_EMPTY(pQueue)  ((pQueue)->pHead != NULL) ? SK_FALSE : SK_TRUE
++#define IS_Q_LOCKED(pQueue) spin_is_locked(&((pQueue)->QueueLock))
++
++#define PLAIN_POP_FIRST_PKT_FROM_QUEUE(pQueue, pPacket)       {       \
++        if ((pQueue)->pHead != NULL) {                                \
++              (pPacket)       = (pQueue)->pHead;              \
++              (pQueue)->pHead = (pPacket)->pNext;             \
++              if ((pQueue)->pHead == NULL) {                  \
++                      (pQueue)->pTail = NULL;                 \
++              }                                               \
++              (pPacket)->pNext = NULL;                        \
++      } else {                                                \
++              (pPacket) = NULL;                               \
++      }                                                       \
++}
++
++#define PLAIN_PUSH_PKT_AS_FIRST_IN_QUEUE(pQueue, pPacket) {   \
++      if ((pQueue)->pHead != NULL) {                          \
++              (pPacket)->pNext = (pQueue)->pHead;             \
++      } else {                                                \
++              (pPacket)->pNext = NULL;                        \
++              (pQueue)->pTail  = (pPacket);                   \
++      }                                                       \
++              (pQueue)->pHead  = (pPacket);                           \
++}
++
++#define PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(pQueue, pPacket) {    \
++      (pPacket)->pNext = NULL;                                \
++      if ((pQueue)->pTail != NULL) {                          \
++              (pQueue)->pTail->pNext = (pPacket);             \
++      } else {                                                \
++              (pQueue)->pHead        = (pPacket);             \
++      }                                                       \
++      (pQueue)->pTail = (pPacket);                            \
++}
++
++#define PLAIN_PUSH_MULTIPLE_PKT_AS_LAST_IN_QUEUE(pQueue,pPktGrpStart,pPktGrpEnd) { \
++      if ((pPktGrpStart) != NULL) {                                   \
++              if ((pQueue)->pTail != NULL) {                          \
++                      (pQueue)->pTail->pNext = (pPktGrpStart);        \
++              } else {                                                \
++                      (pQueue)->pHead = (pPktGrpStart);               \
++              }                                                       \
++              (pQueue)->pTail = (pPktGrpEnd);                         \
++      }                                                               \
++}
++
++/* Required: 'Flags' */ 
++#define POP_FIRST_PKT_FROM_QUEUE(pQueue, pPacket)     {       \
++      spin_lock_irqsave(&((pQueue)->QueueLock), Flags);       \
++      if ((pQueue)->pHead != NULL) {                          \
++              (pPacket)       = (pQueue)->pHead;              \
++              (pQueue)->pHead = (pPacket)->pNext;             \
++              if ((pQueue)->pHead == NULL) {                  \
++                      (pQueue)->pTail = NULL;                 \
++              }                                               \
++              (pPacket)->pNext = NULL;                        \
++      } else {                                                \
++              (pPacket) = NULL;                               \
++      }                                                       \
++      spin_unlock_irqrestore(&((pQueue)->QueueLock), Flags);  \
++}
++
++/* Required: 'Flags' */
++#define PUSH_PKT_AS_FIRST_IN_QUEUE(pQueue, pPacket)   {       \
++      spin_lock_irqsave(&(pQueue)->QueueLock, Flags);         \
++      if ((pQueue)->pHead != NULL) {                          \
++              (pPacket)->pNext = (pQueue)->pHead;             \
++      } else {                                                \
++              (pPacket)->pNext = NULL;                        \
++              (pQueue)->pTail  = (pPacket);                   \
++      }                                                       \
++      (pQueue)->pHead = (pPacket);                            \
++      spin_unlock_irqrestore(&(pQueue)->QueueLock, Flags);    \
++}
+-#define IRQ_HWE_MASK  (IS_ERR_MSK) /* enable all HW irqs */
++/* Required: 'Flags' */
++#define PUSH_PKT_AS_LAST_IN_QUEUE(pQueue, pPacket)    {       \
++      (pPacket)->pNext = NULL;                                \
++      spin_lock_irqsave(&(pQueue)->QueueLock, Flags);         \
++      if ((pQueue)->pTail != NULL) {                          \
++              (pQueue)->pTail->pNext = (pPacket);             \
++      } else {                                                \
++              (pQueue)->pHead = (pPacket);                    \
++      }                                                       \
++      (pQueue)->pTail = (pPacket);                            \
++      spin_unlock_irqrestore(&(pQueue)->QueueLock, Flags);    \
++}
++
++/* Required: 'Flags' */
++#define PUSH_MULTIPLE_PKT_AS_LAST_IN_QUEUE(pQueue,pPktGrpStart,pPktGrpEnd) {  \
++      if ((pPktGrpStart) != NULL) {                                   \
++              spin_lock_irqsave(&(pQueue)->QueueLock, Flags);         \
++              if ((pQueue)->pTail != NULL) {                          \
++                      (pQueue)->pTail->pNext = (pPktGrpStart);        \
++              } else {                                                \
++                      (pQueue)->pHead = (pPktGrpStart);               \
++              }                                                       \
++              (pQueue)->pTail = (pPktGrpEnd);                         \
++              spin_unlock_irqrestore(&(pQueue)->QueueLock, Flags);    \
++      }                                                               \
++}
++
++/*******************************************************************************
++ *
++ * Macros specific for Yukon-II queues (tist)
++ *
++ ******************************************************************************/
++
++#ifdef USE_TIST_FOR_RESET
++/* port is fully operational */
++#define SK_PSTATE_NOT_WAITING_FOR_TIST                  0
++/* port in reset until any tist LE */
++#define SK_PSTATE_WAITING_FOR_ANY_TIST          BIT_0
++/* port in reset until timer reaches pAC->MinTistLo */
++#define SK_PSTATE_WAITING_FOR_SPECIFIC_TIST     BIT_1   
++#define SK_PSTATE_PORT_SHIFT    4
++#define SK_PSTATE_PORT_MASK             ((1 << SK_PSTATE_PORT_SHIFT) - 1)
++
++/* use this + Port to build OP_MOD_TXINDEX_NO_PORT_A|B */
++#define OP_MOD_TXINDEX 0x71
++/* opcode for a TX_INDEX LE in which Port A has to be ignored */
++#define OP_MOD_TXINDEX_NO_PORT_A 0x71
++/* opcode for a TX_INDEX LE in which Port B has to be ignored */
++#define OP_MOD_TXINDEX_NO_PORT_B 0x72
++/* opcode for LE to be ignored because port is still in reset */
++#define OP_MOD_LE 0x7F
++
++/* set tist wait mode Bit for port */ 
++#define SK_SET_WAIT_BIT_FOR_PORT(pAC, Bit, Port)        \
++      { \
++              (pAC)->AdapterResetState |= ((Bit) << (SK_PSTATE_PORT_SHIFT * Port)); \
++      }
++
++/* reset tist waiting for specified port */
++#define SK_CLR_STATE_FOR_PORT(pAC, Port)        \
++      { \
++              (pAC)->AdapterResetState &= \
++                      ~(SK_PSTATE_PORT_MASK << (SK_PSTATE_PORT_SHIFT * Port)); \
++      }
++
++/* return SK_TRUE when port is in reset waiting for tist */
++#define SK_PORT_WAITING_FOR_TIST(pAC, Port) \
++      ((((pAC)->AdapterResetState >> (SK_PSTATE_PORT_SHIFT * Port)) & \
++              SK_PSTATE_PORT_MASK) != SK_PSTATE_NOT_WAITING_FOR_TIST)
++
++/* return SK_TRUE when port is in reset waiting for any tist */
++#define SK_PORT_WAITING_FOR_ANY_TIST(pAC, Port) \
++      ((((pAC)->AdapterResetState >> (SK_PSTATE_PORT_SHIFT * Port)) & \
++              SK_PSTATE_WAITING_FOR_ANY_TIST) == SK_PSTATE_WAITING_FOR_ANY_TIST)
++
++/* return SK_TRUE when port is in reset waiting for a specific tist */
++#define SK_PORT_WAITING_FOR_SPECIFIC_TIST(pAC, Port) \
++      ((((pAC)->AdapterResetState >> (SK_PSTATE_PORT_SHIFT * Port)) & \
++              SK_PSTATE_WAITING_FOR_SPECIFIC_TIST) == \
++              SK_PSTATE_WAITING_FOR_SPECIFIC_TIST)
++        
++/* return whether adapter is expecting a tist LE */
++#define SK_ADAPTER_WAITING_FOR_TIST(pAC)        ((pAC)->AdapterResetState != 0)
++
++/* enable timestamp timer and force creation of tist LEs */
++#define Y2_ENABLE_TIST(IoC) \
++      SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8) GMT_ST_START)
++        
++/* disable timestamp timer and stop creation of tist LEs */
++#define Y2_DISABLE_TIST(IoC) \
++      SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8) GMT_ST_STOP)
++
++/* get current value of timestamp timer */
++#define Y2_GET_TIST_LOW_VAL(IoC, pVal) \
++      SK_IN32(IoC, GMAC_TI_ST_VAL, pVal)
++
++#endif
++
++
++/*******************************************************************************
++ *
++ * Used interrupt bits in the interrupts source register
++ *
++ ******************************************************************************/
++
++#define DRIVER_IRQS   ((IS_IRQ_SW) | \
++                       (IS_R1_F)   | (IS_R2_F)  | \
++                       (IS_XS1_F)  | (IS_XA1_F) | \
++                       (IS_XS2_F)  | (IS_XA2_F))
++
++#define TX_COMPL_IRQS ((IS_XS1_B)  | (IS_XS1_F) | \
++                       (IS_XA1_B)  | (IS_XA1_F) | \
++                       (IS_XS2_B)  | (IS_XS2_F) | \
++                       (IS_XA2_B)  | (IS_XA2_F))
++
++#define NAPI_DRV_IRQS ((IS_R1_F)   | (IS_R2_F) | \
++                       (IS_XS1_F)  | (IS_XA1_F)| \
++                       (IS_XS2_F)  | (IS_XA2_F))
++
++#define Y2_DRIVER_IRQS        ((Y2_IS_STAT_BMU) | (Y2_IS_IRQ_SW) | (Y2_IS_POLL_CHK))
++
++#define SPECIAL_IRQS  ((IS_HW_ERR)    |(IS_I2C_READY)  | \
++                       (IS_EXT_REG)   |(IS_TIMINT)     | \
++                       (IS_PA_TO_RX1) |(IS_PA_TO_RX2)  | \
++                       (IS_PA_TO_TX1) |(IS_PA_TO_TX2)  | \
++                       (IS_MAC1)      |(IS_LNK_SYNC_M1)| \
++                       (IS_MAC2)      |(IS_LNK_SYNC_M2)| \
++                       (IS_R1_C)      |(IS_R2_C)       | \
++                       (IS_XS1_C)     |(IS_XA1_C)      | \
++                       (IS_XS2_C)     |(IS_XA2_C))
++
++#define Y2_SPECIAL_IRQS       ((Y2_IS_HW_ERR)   |(Y2_IS_ASF)      | \
++                       (Y2_IS_TWSI_RDY) |(Y2_IS_TIMINT)   | \
++                       (Y2_IS_IRQ_PHY2) |(Y2_IS_IRQ_MAC2) | \
++                       (Y2_IS_CHK_RX2)  |(Y2_IS_CHK_TXS2) | \
++                       (Y2_IS_CHK_TXA2) |(Y2_IS_IRQ_PHY1) | \
++                       (Y2_IS_IRQ_MAC1) |(Y2_IS_CHK_RX1)  | \
++                       (Y2_IS_CHK_TXS1) |(Y2_IS_CHK_TXA1))
++
++#define IRQ_MASK      ((IS_IRQ_SW)    | \
++                       (IS_R1_F)      |(IS_R2_F)     | \
++                       (IS_XS1_F)     |(IS_XA1_F)    | \
++                       (IS_XS2_F)     |(IS_XA2_F)    | \
++                       (IS_HW_ERR)    |(IS_I2C_READY)| \
++                       (IS_EXT_REG)   |(IS_TIMINT)   | \
++                       (IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \
++                       (IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \
++                       (IS_MAC1)      |(IS_MAC2)     | \
++                       (IS_R1_C)      |(IS_R2_C)     | \
++                       (IS_XS1_C)     |(IS_XA1_C)    | \
++                       (IS_XS2_C)     |(IS_XA2_C))
++
++#define Y2_IRQ_MASK   ((Y2_DRIVER_IRQS) | (Y2_SPECIAL_IRQS))
++
++#define IRQ_HWE_MASK  (IS_ERR_MSK)            /* enable all HW irqs */
++#define Y2_IRQ_HWE_MASK       (Y2_HWE_ALL_MSK)        /* enable all HW irqs */
+ typedef struct s_DevNet DEV_NET;
+ struct s_DevNet {
+-      struct                  proc_dir_entry *proc;
+-      int             PortNr;
+-      int             NetNr;
+-      int             Mtu;
+-      int             Up;
+-      SK_AC   *pAC;
++      struct          proc_dir_entry *proc;
++      int             PortNr;
++      int             NetNr;
++      char            InitialDevName[20];
++      SK_BOOL         NetConsoleMode;
++#ifdef Y2_RECOVERY
++      struct          timer_list KernelTimer; /* Kernel timer struct  */
++      int             TransmitTimeoutTimer;   /* Transmit timer       */
++      SK_BOOL         TimerExpired;           /* Transmit timer       */
++      SK_BOOL         InRecover;              /* Recover flag         */
++#ifdef Y2_RX_CHECK
++      SK_U8           FifoReadPointer;        /* Backup of the FRP */
++      SK_U8           FifoReadLevel;          /* Backup of the FRL */
++      SK_U32          BmuStateMachine;        /* Backup of the MBU SM */
++      SK_U32          LastJiffies;            /* Backup of the jiffies */
++#endif
++#endif
++      SK_AC           *pAC;
+ };  
+-typedef struct s_TxPort               TX_PORT;
++/*******************************************************************************
++ *
++ * Rx/Tx Port structures
++ *
++ ******************************************************************************/
+-struct s_TxPort {
+-      /* the transmit descriptor rings */
+-      caddr_t         pTxDescrRing;   /* descriptor area memory */
+-      SK_U64          VTxDescrRing;   /* descr. area bus virt. addr. */
+-      TXD             *pTxdRingHead;  /* Head of Tx rings */
+-      TXD             *pTxdRingTail;  /* Tail of Tx rings */
+-      TXD             *pTxdRingPrev;  /* descriptor sent previously */
+-      int             TxdRingFree;    /* # of free entrys */
+-      spinlock_t      TxDesRingLock;  /* serialize descriptor accesses */
+-      caddr_t         HwAddr;         /* bmu registers address */
+-      int             PortIndex;      /* index number of port (0 or 1) */
++typedef struct s_TxPort       TX_PORT;
++struct s_TxPort {                       /* the transmit descriptor rings */
++      caddr_t         pTxDescrRing;   /* descriptor area memory        */
++      SK_U64          VTxDescrRing;   /* descr. area bus virt. addr.   */
++      TXD            *pTxdRingHead;   /* Head of Tx rings              */
++      TXD            *pTxdRingTail;   /* Tail of Tx rings              */
++      TXD            *pTxdRingPrev;   /* descriptor sent previously    */
++      int             TxdRingPrevFree;/* previously # of free entrys   */
++      int             TxdRingFree;    /* # of free entrys              */
++      spinlock_t      TxDesRingLock;  /* serialize descriptor accesses */
++      caddr_t         HwAddr;         /* bmu registers address         */
++      int             PortIndex;      /* index number of port (0 or 1) */
++      SK_PACKET      *TransmitPacketTable;
++      SK_LE_TABLE     TxALET;         /* tx (async) list element table */
++      SK_LE_TABLE     TxSLET;         /* tx (sync) list element table  */
++      SK_PKT_QUEUE    TxQ_free;
++      SK_PKT_QUEUE    TxAQ_waiting;
++      SK_PKT_QUEUE    TxSQ_waiting;
++      SK_PKT_QUEUE    TxAQ_working;
++      SK_PKT_QUEUE    TxSQ_working;
++      unsigned        LastDone;
+ };
+-typedef struct s_RxPort               RX_PORT;
+-
+-struct s_RxPort {
+-      /* the receive descriptor rings */
+-      caddr_t         pRxDescrRing;   /* descriptor area memory */
+-      SK_U64          VRxDescrRing;   /* descr. area bus virt. addr. */
+-      RXD             *pRxdRingHead;  /* Head of Rx rings */
+-      RXD             *pRxdRingTail;  /* Tail of Rx rings */
+-      RXD             *pRxdRingPrev;  /* descriptor given to BMU previously */
+-      int             RxdRingFree;    /* # of free entrys */
+-      spinlock_t      RxDesRingLock;  /* serialize descriptor accesses */
+-      int             RxFillLimit;    /* limit for buffers in ring */
+-      caddr_t         HwAddr;         /* bmu registers address */
+-      int             PortIndex;      /* index number of port (0 or 1) */
++typedef struct s_RxPort       RX_PORT;
++struct s_RxPort {                       /* the receive descriptor rings  */
++      caddr_t         pRxDescrRing;   /* descriptor area memory        */
++      SK_U64          VRxDescrRing;   /* descr. area bus virt. addr.   */
++      RXD            *pRxdRingHead;   /* Head of Rx rings              */
++      RXD            *pRxdRingTail;   /* Tail of Rx rings              */
++      RXD            *pRxdRingPrev;   /* descr given to BMU previously */
++      int             RxdRingFree;    /* # of free entrys              */
++      spinlock_t      RxDesRingLock;  /* serialize descriptor accesses */
++      int             RxFillLimit;    /* limit for buffers in ring     */
++      caddr_t         HwAddr;         /* bmu registers address         */
++      int             PortIndex;      /* index number of port (0 or 1) */
++      SK_BOOL         UseRxCsum;      /* use Rx checksumming (yes/no)  */
++      SK_PACKET      *ReceivePacketTable;
++      SK_LE_TABLE     RxLET;          /* rx list element table         */
++      SK_PKT_QUEUE    RxQ_working;
++      SK_PKT_QUEUE    RxQ_waiting;
++      int             RxBufSize;
+ };
+-/* Definitions needed for interrupt moderation *******************************/
++/*******************************************************************************
++ *
++ * Interrupt masks used in combination with interrupt moderation
++ *
++ ******************************************************************************/
+ #define IRQ_EOF_AS_TX     ((IS_XA1_F)     | (IS_XA2_F))
+ #define IRQ_EOF_SY_TX     ((IS_XS1_F)     | (IS_XS2_F))
+@@ -317,139 +704,150 @@
+ #define IRQ_MASK_SP_TX    ((SPECIAL_IRQS)    | (IRQ_MASK_TX_ONLY))
+ #define IRQ_MASK_RX_TX_SP ((SPECIAL_IRQS)    | (IRQ_MASK_TX_RX))
+-#define C_INT_MOD_NONE                 1
+-#define C_INT_MOD_STATIC               2
+-#define C_INT_MOD_DYNAMIC              4
+-
+-#define C_CLK_FREQ_GENESIS      53215000 /* shorter: 53.125 MHz  */
+-#define C_CLK_FREQ_YUKON        78215000 /* shorter: 78.125 MHz  */
+-
+-#define C_INTS_PER_SEC_DEFAULT      2000 
+-#define C_INT_MOD_ENABLE_PERCENTAGE   50 /* if higher 50% enable */
+-#define C_INT_MOD_DISABLE_PERCENTAGE  50 /* if lower 50% disable */
+-#define C_INT_MOD_IPS_LOWER_RANGE     30
+-#define C_INT_MOD_IPS_UPPER_RANGE     40000
+-
+-
+-typedef struct s_DynIrqModInfo  DIM_INFO;
+-struct s_DynIrqModInfo {
+-      unsigned long   PrevTimeVal;
+-      unsigned int    PrevSysLoad;
+-      unsigned int    PrevUsedTime;
+-      unsigned int    PrevTotalTime;
+-      int             PrevUsedDescrRatio;
+-      int             NbrProcessedDescr;
+-        SK_U64          PrevPort0RxIntrCts;
+-        SK_U64          PrevPort1RxIntrCts;
+-        SK_U64          PrevPort0TxIntrCts;
+-        SK_U64          PrevPort1TxIntrCts;
+-      SK_BOOL         ModJustEnabled;     /* Moderation just enabled yes/no */
+-
+-      int             MaxModIntsPerSec;            /* Moderation Threshold */
+-      int             MaxModIntsPerSecUpperLimit;  /* Upper limit for DIM  */
+-      int             MaxModIntsPerSecLowerLimit;  /* Lower limit for DIM  */
+-
+-      long            MaskIrqModeration;   /* ModIrqType (eg. 'TxRx')      */
+-      SK_BOOL         DisplayStats;        /* Stats yes/no                 */
+-      SK_BOOL         AutoSizing;          /* Resize DIM-timer on/off      */
+-      int             IntModTypeSelect;    /* EnableIntMod (eg. 'dynamic') */
++#define IRQ_MASK_Y2_TX_ONLY  (Y2_IS_STAT_BMU)
++#define IRQ_MASK_Y2_RX_ONLY  (Y2_IS_STAT_BMU)
++#define IRQ_MASK_Y2_SP_ONLY  (SPECIAL_IRQS)
++#define IRQ_MASK_Y2_TX_RX    ((IRQ_MASK_TX_ONLY)| (IRQ_MASK_RX_ONLY))
++#define IRQ_MASK_Y2_SP_RX    ((SPECIAL_IRQS)    | (IRQ_MASK_RX_ONLY))
++#define IRQ_MASK_Y2_SP_TX    ((SPECIAL_IRQS)    | (IRQ_MASK_TX_ONLY))
++#define IRQ_MASK_Y2_RX_TX_SP ((SPECIAL_IRQS)    | (IRQ_MASK_TX_RX))
+-      SK_TIMER        ModTimer; /* just some timer */
+-};
++/*******************************************************************************
++ *
++ * Defines and typedefs regarding interrupt moderation
++ *
++ ******************************************************************************/
+-typedef struct s_PerStrm      PER_STRM;
++#define C_INT_MOD_NONE                        1
++#define C_INT_MOD_STATIC              2
++#define C_INT_MOD_DYNAMIC             4
++
++#define C_CLK_FREQ_GENESIS             53215000 /* or:  53.125 MHz */
++#define C_CLK_FREQ_YUKON               78215000 /* or:  78.125 MHz */
++#define C_CLK_FREQ_YUKON_EC           125000000 /* or: 125.000 MHz */
++
++#define C_Y2_INTS_PER_SEC_DEFAULT     5000 
++#define C_INTS_PER_SEC_DEFAULT                2000 
++#define C_INT_MOD_IPS_LOWER_RANGE     30        /* in IRQs/second */
++#define C_INT_MOD_IPS_UPPER_RANGE     40000     /* in IRQs/second */
++
++typedef struct s_DynIrqModInfo {
++      SK_U64     PrevPort0RxIntrCts;
++      SK_U64     PrevPort1RxIntrCts;
++      SK_U64     PrevPort0TxIntrCts;
++      SK_U64     PrevPort1TxIntrCts;
++      SK_U64     PrevPort0StatusLeIntrCts;
++      SK_U64     PrevPort1StatusLeIntrCts;
++      int        MaxModIntsPerSec;            /* Moderation Threshold   */
++      int        MaxModIntsPerSecUpperLimit;  /* Upper limit for DIM    */
++      int        MaxModIntsPerSecLowerLimit;  /* Lower limit for DIM    */
++      long       MaskIrqModeration;           /* IRQ Mask (eg. 'TxRx')  */
++      int        IntModTypeSelect;            /* Type  (eg. 'dynamic')  */
++      int        DynIrqModSampleInterval;     /* expressed in seconds!  */
++      SK_TIMER   ModTimer;                    /* Timer for dynamic mod. */
++} DIM_INFO;
+-#define SK_ALLOC_IRQ  0x00000001
++/*******************************************************************************
++ *
++ * Defines and typedefs regarding wake-on-lan
++ *
++ ******************************************************************************/
++
++typedef struct s_WakeOnLanInfo {
++      SK_U32     SupportedWolOptions;         /* e.g. WAKE_PHY...         */
++      SK_U32     ConfiguredWolOptions;        /* e.g. WAKE_PHY...         */
++} WOL_INFO;
+-#ifdef SK_DIAG_SUPPORT
++#define SK_ALLOC_IRQ  0x00000001
+ #define       DIAG_ACTIVE             1
+ #define       DIAG_NOTACTIVE          0
+-#endif
+ /****************************************************************************
++ *
+  * Per board structure / Adapter Context structure:
+- *    Allocated within attach(9e) and freed within detach(9e).
+- *    Contains all 'per device' necessary handles, flags, locks etc.:
+- */
++ * Contains all 'per device' necessary handles, flags, locks etc.:
++ *
++ ******************************************************************************/
++
+ struct s_AC  {
+-      SK_GEINIT       GIni;           /* GE init struct */
+-      SK_PNMI         Pnmi;           /* PNMI data struct */
+-      SK_VPD          vpd;            /* vpd data struct */
+-      SK_QUEUE        Event;          /* Event queue */
+-      SK_HWT          Hwt;            /* Hardware Timer control struct */
+-      SK_TIMCTRL      Tim;            /* Software Timer control struct */
+-      SK_I2C          I2c;            /* I2C relevant data structure */
+-      SK_ADDR         Addr;           /* for Address module */
+-      SK_CSUM         Csum;           /* for checksum module */
+-      SK_RLMT         Rlmt;           /* for rlmt module */
+-      spinlock_t      SlowPathLock;   /* Normal IRQ lock */
+-      SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */
+-      int                     RlmtMode;       /* link check mode to set */
+-      int                     RlmtNets;       /* Number of nets */
+-      
+-      SK_IOC          IoBase;         /* register set of adapter */
+-      int             BoardLevel;     /* level of active hw init (0-2) */
+-      char            DeviceStr[80];  /* adapter string from vpd */
+-      SK_U32          AllocFlag;      /* flag allocation of resources */
+-      struct pci_dev  *PciDev;        /* for access to pci config space */
+-      SK_U32          PciDevId;       /* pci device id */
+-      struct SK_NET_DEVICE    *dev[2];        /* pointer to device struct */
+-      char            Name[30];       /* driver name */
+-      struct SK_NET_DEVICE    *Next;          /* link all devices (for clearing) */
+-      int             RxBufSize;      /* length of receive buffers */
+-        struct net_device_stats stats;        /* linux 'netstat -i' statistics */
+-      int             Index;          /* internal board index number */
+-
+-      /* adapter RAM sizes for queues of active port */
+-      int             RxQueueSize;    /* memory used for receive queue */
+-      int             TxSQueueSize;   /* memory used for sync. tx queue */
+-      int             TxAQueueSize;   /* memory used for async. tx queue */
+-
+-      int             PromiscCount;   /* promiscuous mode counter  */
+-      int             AllMultiCount;  /* allmulticast mode counter */
+-      int             MulticCount;    /* number of different MC    */
+-                                      /*  addresses for this board */
+-                                      /*  (may be more than HW can)*/
+-
+-      int             HWRevision;     /* Hardware revision */
+-      int             ActivePort;     /* the active XMAC port */
+-      int             MaxPorts;               /* number of activated ports */
+-      int             TxDescrPerRing; /* # of descriptors per tx ring */
+-      int             RxDescrPerRing; /* # of descriptors per rx ring */
+-
+-      caddr_t         pDescrMem;      /* Pointer to the descriptor area */
+-      dma_addr_t      pDescrMemDMA;   /* PCI DMA address of area */
+-
+-      /* the port structures with descriptor rings */
+-      TX_PORT         TxPort[SK_MAX_MACS][2];
+-      RX_PORT         RxPort[SK_MAX_MACS];
+-
+-      unsigned int    CsOfs1;         /* for checksum calculation */
+-      unsigned int    CsOfs2;         /* for checksum calculation */
+-      SK_U32          CsOfs;          /* for checksum calculation */
+-
+-      SK_BOOL         CheckQueue;     /* check event queue soon */
+-      SK_TIMER        DrvCleanupTimer;/* to check for pending descriptors */
+-      DIM_INFO        DynIrqModInfo;  /* all data related to DIM */
+-
+-      /* Only for tests */
+-      int             PortUp;
+-      int             PortDown;
+-      int             ChipsetType;    /*  Chipset family type 
+-                                       *  0 == Genesis family support
+-                                       *  1 == Yukon family support
+-                                       */
+-#ifdef SK_DIAG_SUPPORT
+-      SK_U32          DiagModeActive;         /* is diag active?      */
+-      SK_BOOL         DiagFlowCtrl;           /* for control purposes */
+-      SK_PNMI_STRUCT_DATA PnmiBackup;         /* backup structure for all Pnmi-Data */
+-      SK_BOOL         WasIfUp[SK_MAX_MACS];   /* for OpenClose while 
+-                                               * DIAG is busy with NIC 
+-                                               */
++      SK_GEINIT                GIni;          /* GE init struct             */
++      SK_PNMI                  Pnmi;          /* PNMI data struct           */
++      SK_VPD                   vpd;           /* vpd data struct            */
++      SK_QUEUE                 Event;         /* Event queue                */
++      SK_HWT                   Hwt;           /* Hardware Timer ctrl struct */
++      SK_TIMCTRL               Tim;           /* Software Timer ctrl struct */
++      SK_I2C                   I2c;           /* I2C relevant data structure*/
++      SK_ADDR                  Addr;          /* for Address module         */
++      SK_CSUM                  Csum;          /* for checksum module        */
++      SK_RLMT                  Rlmt;          /* for rlmt module            */
++      spinlock_t               SlowPathLock;  /* Normal IRQ lock            */
++      spinlock_t               TxQueueLock;   /* TX Queue lock              */
++      SK_PNMI_STRUCT_DATA      PnmiStruct;    /* struct for all Pnmi-Data   */
++      int                      RlmtMode;      /* link check mode to set     */
++      int                      RlmtNets;      /* Number of nets             */
++      SK_IOC                   IoBase;        /* register set of adapter    */
++      int                      BoardLevel;    /* level of hw init (0-2)     */
++      char                     DeviceStr[80]; /* adapter string from vpd    */
++      SK_U32                   AllocFlag;     /* alloc flag of resources    */
++      struct pci_dev          *PciDev;        /* for access to pci cfg space*/
++      SK_U32                   PciDevId;      /* pci device id              */
++      struct SK_NET_DEVICE    *dev[2];        /* pointer to device struct   */
++      char                     Name[30];      /* driver name                */
++      struct SK_NET_DEVICE    *Next;          /* link all devs for cleanup  */
++      struct net_device_stats  stats;         /* linux 'netstat -i' stats   */
++      int                      Index;         /* internal board idx number  */
++      int                      RxQueueSize;   /* memory used for RX queue   */
++      int                      TxSQueueSize;  /* memory used for TXS queue  */
++      int                      TxAQueueSize;  /* memory used for TXA queue  */
++      int                      PromiscCount;  /* promiscuous mode counter   */
++      int                      AllMultiCount; /* allmulticast mode counter  */
++      int                      MulticCount;   /* number of MC addresses used*/
++      int                      HWRevision;    /* Hardware revision          */
++      int                      ActivePort;    /* the active XMAC port       */
++      int                      MaxPorts;      /* number of activated ports  */
++      int                      TxDescrPerRing;/* # of descriptors TX ring   */
++      int                      RxDescrPerRing;/* # of descriptors RX ring   */
++      caddr_t                  pDescrMem;     /* Ptr to the descriptor area */
++      dma_addr_t               pDescrMemDMA;  /* PCI DMA address of area    */
++      SK_U32                   PciState[16];  /* PCI state */
++      TX_PORT                  TxPort[SK_MAX_MACS][2];
++      RX_PORT                  RxPort[SK_MAX_MACS];
++      SK_LE_TABLE              StatusLETable; 
++      unsigned                 SizeOfAlignedLETables; 
++      spinlock_t               SetPutIndexLock;
++      int                      MaxUnusedRxLeWorking;
++      unsigned int             CsOfs1;        /* for checksum calculation   */
++      unsigned int             CsOfs2;        /* for checksum calculation   */
++      SK_U32                   CsOfs;         /* for checksum calculation   */
++      SK_BOOL                  CheckQueue;    /* check event queue soon     */
++      DIM_INFO                 DynIrqModInfo; /* all data related to IntMod */
++      WOL_INFO                 WolInfo;       /* all info regarding WOL     */
++      int                      ChipsetType;   /* 0=GENESIS; 1=Yukon         */
++      SK_BOOL                  LowLatency;    /* LowLatency optimization on?*/
++      SK_U32                   DiagModeActive;/* is diag active?            */
++      SK_BOOL                  DiagFlowCtrl;  /* for control purposes       */
++      SK_PNMI_STRUCT_DATA      PnmiBackup;    /* backup structure for PNMI  */
++      SK_BOOL                  WasIfUp[SK_MAX_MACS];
++#ifdef USE_TIST_FOR_RESET
++      int                      AdapterResetState;
++      SK_U32                   MinTistLo;
++      SK_U32                   MinTistHi;
++#endif
++#ifdef Y2_RECOVERY
++      int                      LastPort;       /* port for curr. handled rx */
++        int                      LastOpc;        /* last rx LEs opcode              */
++#endif
++#ifdef Y2_SYNC_CHECK
++      unsigned long            FramesWithoutSyncCheck; /* since last check  */
+ #endif
+-
+ };
+-#endif /* __INC_SKDRV2ND_H */
++#endif
++
++/*******************************************************************************
++ *
++ * End of file
++ *
++ ******************************************************************************/
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skerror.h linux-2.6.9.new/drivers/net/sk98lin/h/skerror.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skerror.h    2004-10-19 05:54:08.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skerror.h    2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skerror.h
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.7 $
+- * Date:      $Date: 2003/05/13 17:25:13 $
++ * Version:   $Revision: 2.2 $
++ * Date:      $Date: 2004/05/24 15:27:19 $
+  * Purpose:   SK specific Error log support
+  *
+  ******************************************************************************/
+@@ -11,13 +11,12 @@
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2004 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+  *    the Free Software Foundation; either version 2 of the License, or
+  *    (at your option) any later version.
+- *
+  *    The information in this file is provided "AS IS" without warranty.
+  *
+  ******************************************************************************/
+@@ -36,7 +35,6 @@
+ #define       SK_ERRCL_HW                     (1L<<4) /* Hardware Failure */
+ #define       SK_ERRCL_COMM           (1L<<5) /* Communication error */
+-
+ /*
+  * Define Error Code Bases
+  */
+@@ -49,7 +47,9 @@
+ #define       SK_ERRBASE_I2C           700    /* Base Error number for I2C module */
+ #define       SK_ERRBASE_QUEUE         800    /* Base Error number for Scheduler */
+ #define       SK_ERRBASE_ADDR          900    /* Base Error number for Address module */
+-#define SK_ERRBASE_PECP               1000    /* Base Error number for PECP */
++#define SK_ERRBASE_PECP               1000    /* Base Error number for PECP */
+ #define       SK_ERRBASE_DRV          1100    /* Base Error number for Driver */
++#define SK_ERRBASE_ASF                1200    /* Base Error number for ASF */
+ #endif        /* _INC_SKERROR_H_ */
++
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skgedrv.h linux-2.6.9.new/drivers/net/sk98lin/h/skgedrv.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skgedrv.h    2004-10-19 05:54:37.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skgedrv.h    2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgedrv.h
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.10 $
+- * Date:      $Date: 2003/07/04 12:25:01 $
++ * Version:   $Revision: 2.1 $
++ * Date:      $Date: 2003/10/27 14:16:08 $
+  * Purpose:   Interface with the driver
+  *
+  ******************************************************************************/
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skgehw.h linux-2.6.9.new/drivers/net/sk98lin/h/skgehw.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skgehw.h     2004-10-19 05:55:28.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skgehw.h     2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgehw.h
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.56 $
+- * Date:      $Date: 2003/09/23 09:01:00 $
++ * Version:   $Revision: 2.49 $
++ * Date:      $Date: 2005/01/20 13:01:35 $
+  * Purpose:   Defines and Macros for the Gigabit Ethernet Adapter Product Family
+  *
+  ******************************************************************************/
+@@ -11,13 +11,12 @@
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2004 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+  *    the Free Software Foundation; either version 2 of the License, or
+  *    (at your option) any later version.
+- *
+  *    The information in this file is provided "AS IS" without warranty.
+  *
+  ******************************************************************************/
+@@ -114,6 +113,16 @@
+ #define SHIFT1(x)     ((x) << 1)
+ #define SHIFT0(x)     ((x) << 0)
++/* Macro for arbitrary alignment of a given pointer */
++#define ALIGN_ADDR( ADDRESS, GRANULARITY ) { \
++      SK_UPTR addr = (SK_UPTR)(ADDRESS); \
++      if (addr & ((GRANULARITY)-1)) { \
++              addr += (GRANULARITY); \
++              addr &= ~(SK_UPTR)((GRANULARITY)-1); \
++              ADDRESS = (void *)addr; \
++      }\
++}
++
+ /*
+  * Configuration Space header
+  * Since this module is used for different OS', those may be
+@@ -132,34 +141,74 @@
+ #define PCI_BIST              0x0f    /*  8 bit       Built-in selftest */
+ #define PCI_BASE_1ST  0x10    /* 32 bit       1st Base address */
+ #define PCI_BASE_2ND  0x14    /* 32 bit       2nd Base address */
+-      /* Byte 0x18..0x2b:     reserved */
++      /* Bytes 0x18..0x2b:    reserved */
+ #define PCI_SUB_VID           0x2c    /* 16 bit       Subsystem Vendor ID */
+ #define PCI_SUB_ID            0x2e    /* 16 bit       Subsystem ID */
+ #define PCI_BASE_ROM  0x30    /* 32 bit       Expansion ROM Base Address */
+-#define PCI_CAP_PTR           0x34    /*  8 bit       Capabilities Ptr */
+-      /* Byte 0x35..0x3b:     reserved */
++#define PCI_CAP_PTR           0x34    /*  8 bit       Capabilities Pointer */
++      /* Bytes 0x35..0x3b:    reserved */
+ #define PCI_IRQ_LINE  0x3c    /*  8 bit       Interrupt Line */
+ #define PCI_IRQ_PIN           0x3d    /*  8 bit       Interrupt Pin */
+ #define PCI_MIN_GNT           0x3e    /*  8 bit       Min_Gnt */
+ #define PCI_MAX_LAT           0x3f    /*  8 bit       Max_Lat */
+       /* Device Dependent Region */
+-#define PCI_OUR_REG_1 0x40    /* 32 bit       Our Register 1 */
+-#define PCI_OUR_REG_2 0x44    /* 32 bit       Our Register 2 */
++#define PCI_OUR_REG_1 0x40    /* 32 bit       Our Register 1 */
++#define PCI_OUR_REG_2 0x44    /* 32 bit       Our Register 2 */
+       /* Power Management Region */
+-#define PCI_PM_CAP_ID 0x48    /*  8 bit       Power Management Cap. ID */
+-#define PCI_PM_NITEM  0x49    /*  8 bit       Next Item Ptr */
+-#define PCI_PM_CAP_REG        0x4a    /* 16 bit       Power Management Capabilities */
+-#define PCI_PM_CTL_STS        0x4c    /* 16 bit       Power Manag. Control/Status */
++#define PCI_PM_CAP_ID 0x48    /*  8 bit       Power Management Cap. ID */
++#define PCI_PM_NITEM  0x49    /*  8 bit       PM Next Item Pointer */
++#define PCI_PM_CAP_REG        0x4a    /* 16 bit       Power Management Capabilities */
++#define PCI_PM_CTL_STS        0x4c    /* 16 bit       Power Manag. Control/Status */
+       /* Byte 0x4e:   reserved */
+-#define PCI_PM_DAT_REG        0x4f    /*  8 bit       Power Manag. Data Register */
++#define PCI_PM_DAT_REG        0x4f    /*  8 bit       Power Manag. Data Register */
+       /* VPD Region */
+-#define PCI_VPD_CAP_ID        0x50    /*  8 bit       VPD Cap. ID */
+-#define PCI_VPD_NITEM 0x51    /*  8 bit       Next Item Ptr */
+-#define PCI_VPD_ADR_REG       0x52    /* 16 bit       VPD Address Register */
+-#define PCI_VPD_DAT_REG       0x54    /* 32 bit       VPD Data Register */
+-      /* Byte 0x58..0x59:     reserved */
+-#define PCI_SER_LD_CTRL       0x5a    /* 16 bit       SEEPROM Loader Ctrl (YUKON only) */
+-      /* Byte 0x5c..0xff:     reserved */
++#define PCI_VPD_CAP_ID        0x50    /*  8 bit       VPD Cap. ID */
++#define PCI_VPD_NITEM 0x51    /*  8 bit       VPD Next Item Pointer */
++#define PCI_VPD_ADR_REG       0x52    /* 16 bit       VPD Address Register */
++#define PCI_VPD_DAT_REG       0x54    /* 32 bit       VPD Data Register */
++      /* Bytes 0x58..0x59:    reserved */
++#define PCI_SER_LD_CTRL       0x5a    /* 16 bit       SEEPROM Loader Ctrl (YUKON only) */
++      /* Bytes 0x5c..0xfc:    used by Yukon-2 */
++#define PCI_MSI_CAP_ID        0x5c    /*  8 bit       MSI Capability ID Register */
++#define PCI_MSI_NITEM 0x5d    /*  8 bit       MSI Next Item Pointer */
++#define PCI_MSI_CTRL  0x5e    /* 16 bit       MSI Message Control */
++#define PCI_MSI_ADR_LO        0x60    /* 32 bit       MSI Message Address (Lower) */
++#define PCI_MSI_ADR_HI        0x64    /* 32 bit       MSI Message Address (Upper) */
++#define PCI_MSI_DATA  0x68    /* 16 bit       MSI Message Data */
++      /* Bytes 0x6a..0x6b:    reserved */
++#define PCI_X_CAP_ID  0x6c    /*  8 bit       PCI-X Capability ID Register */
++#define PCI_X_NITEM           0x6d    /*  8 bit       PCI-X Next Item Pointer */
++#define PCI_X_COMMAND 0x6e    /* 16 bit       PCI-X Command */
++#define PCI_X_PE_STAT 0x70    /* 32 bit       PCI-X / PE Status */
++#define PCI_CAL_CTRL  0x74    /* 16 bit       PCI Calibration Control Register */
++#define PCI_CAL_STAT  0x76    /* 16 bit       PCI Calibration Status Register */
++#define PCI_DISC_CNT  0x78    /* 16 bit       PCI Discard Counter */
++#define PCI_RETRY_CNT 0x7a    /*  8 bit       PCI Retry Counter */
++      /* Byte 0x7b:   reserved */
++#define PCI_OUR_STATUS        0x7c    /* 32 bit       Adapter Status Register */
++      /* Bytes 0x80..0xdf:    reserved */
++
++/* PCI Express Capability */
++#define PEX_CAP_ID            0xe0    /*  8 bit       PEX Capability ID */
++#define PEX_NITEM             0xe1    /*  8 bit       PEX Next Item Pointer */
++#define PEX_CAP_REG           0xe2    /* 16 bit       PEX Capability Register */
++#define PEX_DEV_CAP           0xe4    /* 32 bit       PEX Device Capabilities */
++#define PEX_DEV_CTRL  0xe8    /* 16 bit       PEX Device Control */
++#define PEX_DEV_STAT  0xea    /* 16 bit       PEX Device Status */
++#define PEX_LNK_CAP           0xec    /* 32 bit       PEX Link Capabilities */
++#define PEX_LNK_CTRL  0xf0    /* 16 bit       PEX Link Control */
++#define PEX_LNK_STAT  0xf2    /* 16 bit       PEX Link Status */
++      /* Bytes 0xf4..0xff:    reserved */
++
++/* PCI Express Extended Capabilities */
++#define PEX_ADV_ERR_REP               0x100   /* 32 bit       PEX Advanced Error Reporting */
++#define PEX_UNC_ERR_STAT      0x104   /* 32 bit       PEX Uncorr. Errors Status */
++#define PEX_UNC_ERR_MASK      0x108   /* 32 bit       PEX Uncorr. Errors Mask */
++#define PEX_UNC_ERR_SEV               0x10c   /* 32 bit       PEX Uncorr. Errors Severity */
++#define PEX_COR_ERR_STAT      0x110   /* 32 bit       PEX Correc. Errors Status */
++#define PEX_COR_ERR_MASK      0x114   /* 32 bit       PEX Correc. Errors Mask */
++#define PEX_ADV_ERR_CAP_C     0x118   /* 32 bit       PEX Advanced Error Cap./Ctrl */
++#define PEX_HEADER_LOG                0x11c   /* 4x32 bit     PEX Header Log Register */
+ /*
+  * I2C Address (PCI Config)
+@@ -180,13 +229,13 @@
+ #define PCI_ADSTEP            BIT_7S          /* Address Stepping */
+ #define PCI_PERREN            BIT_6S          /* Parity Report Response enable */
+ #define PCI_VGA_SNOOP BIT_5S          /* VGA palette snoop */
+-#define PCI_MWIEN             BIT_4S          /* Memory write an inv cycl ena */
++#define PCI_MWIEN             BIT_4S          /* Memory write an inv cycl enable */
+ #define PCI_SCYCEN            BIT_3S          /* Special Cycle enable */
+ #define PCI_BMEN              BIT_2S          /* Bus Master enable */
+ #define PCI_MEMEN             BIT_1S          /* Memory Space Access enable */
+ #define PCI_IOEN              BIT_0S          /* I/O Space Access enable */
+-#define PCI_COMMAND_VAL       (PCI_FBTEN | PCI_SERREN | PCI_PERREN | PCI_MWIEN |\
++#define PCI_COMMAND_VAL       (PCI_INT_DIS | PCI_SERREN | PCI_PERREN | \
+                                                PCI_BMEN | PCI_MEMEN | PCI_IOEN)
+ /*    PCI_STATUS      16 bit  Status */
+@@ -220,7 +269,7 @@
+ /*    PCI_HEADER_T    8 bit   Header Type */
+ #define PCI_HD_MF_DEV BIT_7S  /* 0= single, 1= multi-func dev */
+-#define PCI_HD_TYPE           0x7f    /* Bit 6..0:    Header Layout 0= normal */
++#define PCI_HD_TYPE           0x7f    /* Bit 6..0:    Header Layout (0=normal) */
+ /*    PCI_BIST        8 bit   Built-in selftest */
+ /*    Built-in Self test not supported (optional) */
+@@ -229,33 +278,42 @@
+ #define PCI_MEMSIZE           0x4000L         /* use 16 kB Memory Base */
+ #define PCI_MEMBASE_MSK 0xffffc000L   /* Bit 31..14:  Memory Base Address */
+ #define PCI_MEMSIZE_MSK 0x00003ff0L   /* Bit 13.. 4:  Memory Size Req. */
+-#define PCI_PREFEN            BIT_3           /* Prefetchable */
+-#define PCI_MEM_TYP           (3L<<2)         /* Bit  2.. 1:  Memory Type */
++#define PCI_PREFEN            BIT_3           /* Prefetch enable */
++#define PCI_MEM_TYP_MSK       (3L<<1)         /* Bit  2.. 1:  Memory Type Mask */
++#define PCI_MEMSPACE  BIT_0           /* Memory Space Indicator */
++
+ #define PCI_MEM32BIT  (0L<<1)         /* Base addr anywhere in 32 Bit range */
+ #define PCI_MEM1M             (1L<<1)         /* Base addr below 1 MegaByte */
+ #define PCI_MEM64BIT  (2L<<1)         /* Base addr anywhere in 64 Bit range */
+-#define PCI_MEMSPACE  BIT_0           /* Memory Space Indicator */
+ /*    PCI_BASE_2ND    32 bit  2nd Base address */
+ #define PCI_IOBASE            0xffffff00L     /* Bit 31.. 8:  I/O Base address */
+ #define PCI_IOSIZE            0x000000fcL     /* Bit  7.. 2:  I/O Size Requirements */
+-                                                                      /* Bit  1:      reserved */
++                                                              /* Bit  1:      reserved */
+ #define PCI_IOSPACE           BIT_0           /* I/O Space Indicator */
+ /*    PCI_BASE_ROM    32 bit  Expansion ROM Base Address */
+ #define PCI_ROMBASE_MSK       0xfffe0000L     /* Bit 31..17:  ROM Base address */
+ #define PCI_ROMBASE_SIZ       (0x1cL<<14)     /* Bit 16..14:  Treat as Base or Size */
+ #define PCI_ROMSIZE           (0x38L<<11)     /* Bit 13..11:  ROM Size Requirements */
+-                                                                      /* Bit 10.. 1:  reserved */
++                                                              /* Bit 10.. 1:  reserved */
+ #define PCI_ROMEN             BIT_0           /* Address Decode enable */
+ /* Device Dependent Region */
+ /*    PCI_OUR_REG_1           32 bit  Our Register 1 */
+-                                                                      /* Bit 31..29:  reserved */
++                                                              /* Bit 31..29:  reserved */
+ #define PCI_PHY_COMA  BIT_28          /* Set PHY to Coma Mode (YUKON only) */
+ #define PCI_TEST_CAL  BIT_27          /* Test PCI buffer calib. (YUKON only) */
+ #define PCI_EN_CAL            BIT_26          /* Enable PCI buffer calib. (YUKON only) */
+ #define PCI_VIO                       BIT_25          /* PCI I/O Voltage, 0 = 3.3V, 1 = 5V */
++/* Yukon-2 */
++#define PCI_Y2_PIG_ENA                BIT_31  /* Enable Plug-in-Go (YUKON-2) */
++#define PCI_Y2_DLL_DIS                BIT_30  /* Disable PCI DLL (YUKON-2) */
++#define PCI_Y2_PHY2_COMA      BIT_29  /* Set PHY 2 to Coma Mode (YUKON-2) */
++#define PCI_Y2_PHY1_COMA      BIT_28  /* Set PHY 1 to Coma Mode (YUKON-2) */
++#define PCI_Y2_PHY2_POWD      BIT_27  /* Set PHY 2 to Power Down (YUKON-2) */
++#define PCI_Y2_PHY1_POWD      BIT_26  /* Set PHY 1 to Power Down (YUKON-2) */
++                                                              /* Bit 25:      reserved */
+ #define PCI_DIS_BOOT  BIT_24          /* Disable BOOT via ROM */
+ #define PCI_EN_IO             BIT_23          /* Mapping to I/O space */
+ #define PCI_EN_FPROM  BIT_22          /* Enable FLASH mapping to memory */
+@@ -266,9 +324,10 @@
+ #define PCI_PAGE_32K  (1L<<20)        /*              32 k pages      */
+ #define PCI_PAGE_64K  (2L<<20)        /*              64 k pages      */
+ #define PCI_PAGE_128K (3L<<20)        /*              128 k pages     */
+-                                                                      /* Bit 19:      reserved        */
++                                                              /* Bit 19:      reserved        */
+ #define PCI_PAGEREG           (7L<<16)        /* Bit 18..16:  Page Register   */
+ #define PCI_NOTAR             BIT_15          /* No turnaround cycle */
++#define PCI_PEX_LEGNAT        BIT_15          /* PEX PM legacy/native mode (YUKON-2) */
+ #define PCI_FORCE_BE  BIT_14          /* Assert all BEs on MR */
+ #define PCI_DIS_MRL           BIT_13          /* Disable Mem Read Line */
+ #define PCI_DIS_MRM           BIT_12          /* Disable Mem Read Multiple */
+@@ -278,13 +337,13 @@
+ #define PCI_DIS_PCI_CLK       BIT_8           /* Disable PCI clock driving */
+ #define PCI_SKEW_DAS  (0xfL<<4)       /* Bit  7.. 4:  Skew Ctrl, DAS Ext */
+ #define PCI_SKEW_BASE 0xfL            /* Bit  3.. 0:  Skew Ctrl, Base */
+-
++#define PCI_CLS_OPT           BIT_3           /* Cache Line Size opt. PCI-X (YUKON-2) */ 
+ /*    PCI_OUR_REG_2           32 bit  Our Register 2 */
+ #define PCI_VPD_WR_THR        (0xffL<<24)     /* Bit 31..24:  VPD Write Threshold */
+ #define PCI_DEV_SEL           (0x7fL<<17)     /* Bit 23..17:  EEPROM Device Select */
+ #define PCI_VPD_ROM_SZ        (7L<<14)        /* Bit 16..14:  VPD ROM Size    */
+-                                                                      /* Bit 13..12:  reserved        */
++                                                              /* Bit 13..12:  reserved        */
+ #define PCI_PATCH_DIR (0xfL<<8)       /* Bit 11.. 8:  Ext Patches dir 3..0 */
+ #define PCI_PATCH_DIR_3       BIT_11
+ #define PCI_PATCH_DIR_2       BIT_10
+@@ -297,21 +356,20 @@
+ #define PCI_EXT_PATCH_0       BIT_4
+ #define PCI_EN_DUMMY_RD       BIT_3           /* Enable Dummy Read */
+ #define PCI_REV_DESC  BIT_2           /* Reverse Desc. Bytes */
+-                                                                      /* Bit  1:      reserved */
++                                                              /* Bit  1:      reserved */
+ #define PCI_USEDATA64 BIT_0           /* Use 64Bit Data bus ext */
+-
+ /* Power Management Region */
+ /*    PCI_PM_CAP_REG          16 bit  Power Management Capabilities */
+ #define PCI_PME_SUP_MSK       (0x1f<<11)      /* Bit 15..11:  PM Event Support Mask */
+-#define PCI_PME_D3C_SUP       BIT_15S         /* PME from D3cold Support (if Vaux) */
++#define PCI_PME_D3C_SUP       BIT_15S         /* PME from D3cold Support (if VAUX) */
+ #define PCI_PME_D3H_SUP       BIT_14S         /* PME from D3hot Support */
+ #define PCI_PME_D2_SUP        BIT_13S         /* PME from D2 Support */
+ #define PCI_PME_D1_SUP        BIT_12S         /* PME from D1 Support */
+ #define PCI_PME_D0_SUP        BIT_11S         /* PME from D0 Support */
+ #define PCI_PM_D2_SUP BIT_10S         /* D2 Support in 33 MHz mode */
+ #define PCI_PM_D1_SUP BIT_9S          /* D1 Support */
+-                                                                      /* Bit  8.. 6:  reserved */
++                                                              /* Bit  8.. 6:  reserved */
+ #define PCI_PM_DSI            BIT_5S          /* Device Specific Initialization */
+ #define PCI_PM_APS            BIT_4S          /* Auxialiary Power Source */
+ #define PCI_PME_CLOCK BIT_3S          /* PM Event Clock */
+@@ -322,7 +380,7 @@
+ #define PCI_PM_DAT_SCL        (3<<13)         /* Bit 14..13:  Data Reg. scaling factor */
+ #define PCI_PM_DAT_SEL        (0xf<<9)        /* Bit 12.. 9:  PM data selector field */
+ #define PCI_PME_EN            BIT_8S          /* Enable PME# generation (YUKON only) */
+-                                                                      /* Bit  7.. 2:  reserved */
++                                                              /* Bit  7.. 2:  reserved */
+ #define PCI_PM_STATE_MSK      3               /* Bit  1.. 0:  Power Management State */
+ #define PCI_PM_STATE_D0               0               /* D0:  Operational (default) */
+@@ -333,7 +391,67 @@
+ /* VPD Region */
+ /*    PCI_VPD_ADR_REG         16 bit  VPD Address Register */
+ #define PCI_VPD_FLAG  BIT_15S         /* starts VPD rd/wr cycle */
+-#define PCI_VPD_ADR_MSK       0x7fffL         /* Bit 14.. 0:  VPD address mask */
++#define PCI_VPD_ADR_MSK       0x7fffL         /* Bit 14.. 0:  VPD Address Mask */
++
++/* PCI_OUR_STATUS             32 bit  Adapter Status Register (Yukon-2) */
++#define PCI_OS_PCI64B BIT_31          /* Conventional PCI 64 bits Bus */
++#define PCI_OS_PCIX           BIT_30          /* PCI-X Bus */
++#define PCI_OS_MODE_MSK       (3L<<28)        /* Bit 29..28:  PCI-X Bus Mode Mask */
++#define PCI_OS_PCI66M BIT_27          /* PCI 66 MHz Bus */
++#define PCI_OS_PCI_X  BIT_26          /* PCI/PCI-X Bus (0 = PEX) */
++#define PCI_OS_DLLE_MSK       (3L<<24)        /* Bit 25..24:  DLL Status Indication */
++#define PCI_OS_DLLR_MSK       (0xfL<<20)      /* Bit 23..20:  DLL Row Counters Values */
++#define PCI_OS_DLLC_MSK       (0xfL<<16)      /* Bit 19..16:  DLL Col. Counters Values */
++                                                              /* Bit 15.. 8:  reserved */
++
++#define PCI_OS_SPEED(val)     ((val & PCI_OS_MODE_MSK) >> 28) /* PCI-X Speed */
++/* possible values for the speed field of the register */
++#define PCI_OS_SPD_PCI                0               /* PCI Conventional Bus */
++#define PCI_OS_SPD_X66                1               /* PCI-X 66MHz Bus */
++#define PCI_OS_SPD_X100               2               /* PCI-X 100MHz Bus */
++#define PCI_OS_SPD_X133               3               /* PCI-X 133MHz Bus */
++
++/* PEX_DEV_CTRL                       16 bit  PEX Device Control (Yukon-2) */
++                                                              /* Bit 15       reserved */
++#define PEX_DC_MAX_RRS_MSK    (7<<12) /* Bit 14..12:  Max. Read Request Size */
++#define PEX_DC_EN_NO_SNOOP    BIT_11S /* Enable No Snoop */
++#define PEX_DC_EN_AUX_POW     BIT_10S /* Enable AUX Power */
++#define PEX_DC_EN_PHANTOM     BIT_9S  /* Enable Phantom Functions */
++#define PEX_DC_EN_EXT_TAG     BIT_8S  /* Enable Extended Tag Field */
++#define PEX_DC_MAX_PLS_MSK    (7<<5)  /* Bit  7.. 5:  Max. Payload Size Mask */
++#define PEX_DC_EN_REL_ORD     BIT_4S  /* Enable Relaxed Ordering */
++#define PEX_DC_EN_UNS_RQ_RP   BIT_3S  /* Enable Unsupported Request Reporting */
++#define PEX_DC_EN_FAT_ER_RP   BIT_2S  /* Enable Fatal Error Reporting */
++#define PEX_DC_EN_NFA_ER_RP   BIT_1S  /* Enable Non-Fatal Error Reporting */
++#define PEX_DC_EN_COR_ER_RP   BIT_0S  /* Enable Correctable Error Reporting */
++
++#define PEX_DC_MAX_RD_RQ_SIZE(x)      (SHIFT12(x) & PEX_DC_MAX_RRS_MSK)
++
++/* PEX_LNK_STAT                       16 bit  PEX Link Status (Yukon-2) */
++                                                              /* Bit 15..13   reserved */
++#define PEX_LS_SLOT_CLK_CFG   BIT_12S /* Slot Clock Config */
++#define PEX_LS_LINK_TRAIN     BIT_11S /* Link Training */
++#define PEX_LS_TRAIN_ERROR    BIT_10S /* Training Error */
++#define PEX_LS_LINK_WI_MSK    (0x3f<<4)       /* Bit  9.. 4:  Neg. Link Width Mask */
++#define PEX_LS_LINK_SP_MSK    0x0f    /* Bit  3.. 0:  Link Speed Mask */
++
++/* PEX_UNC_ERR_STAT    PEX Uncorrectable Errors Status Register (Yukon-2) */
++                                                              /* Bit 31..21   reserved */
++#define PEX_UNSUP_REQ         BIT_20          /* Unsupported Request Error */
++                                                                      /* ECRC Error (not supported) */
++#define PEX_MALFOR_TLP        BIT_18          /* Malformed TLP */
++                                                                      /* Receiver Overflow (not supported) */
++#define PEX_UNEXP_COMP        BIT_16          /* Unexpected Completion */
++                                                                      /* Completer Abort (not supported) */
++#define PEX_COMP_TO           BIT_14          /* Completion Timeout */
++#define PEX_FLOW_CTRL_P       BIT_13          /* Flow Control Protocol Error */
++#define PEX_POIS_TLP  BIT_12          /* Poisoned TLP */
++                                                              /* Bit 11.. 5:  reserved */
++#define PEX_DATA_LINK_P BIT_4         /* Data Link Protocol Error */
++                                                              /* Bit  3.. 1:  reserved */
++                                                                      /* Training Error (not supported) */
++
++#define PEX_FATAL_ERRORS      (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P)
+ /*    Control Register File (Address Map) */
+@@ -349,8 +467,14 @@
+ #define B0_IMSK                       0x000c  /* 32 bit       Interrupt Mask Register */
+ #define B0_HWE_ISRC           0x0010  /* 32 bit       HW Error Interrupt Src Reg */
+ #define B0_HWE_IMSK           0x0014  /* 32 bit       HW Error Interrupt Mask Reg */
+-#define B0_SP_ISRC            0x0018  /* 32 bit       Special Interrupt Source Reg */
+-      /* 0x001c:              reserved */
++#define B0_SP_ISRC            0x0018  /* 32 bit       Special Interrupt Source Reg 1 */
++
++/* Special ISR registers (Yukon-2 only) */
++#define B0_Y2_SP_ISRC2        0x001c  /* 32 bit       Special Interrupt Source Reg 2 */
++#define B0_Y2_SP_ISRC3        0x0020  /* 32 bit       Special Interrupt Source Reg 3 */
++#define B0_Y2_SP_EISR 0x0024  /* 32 bit       Enter ISR Reg */
++#define B0_Y2_SP_LISR 0x0028  /* 32 bit       Leave ISR Reg */
++#define B0_Y2_SP_ICR  0x002c  /* 32 bit       Interrupt Control Reg */
+ /* B0 XMAC 1 registers (GENESIS only) */
+ #define B0_XM1_IMSK           0x0020  /* 16 bit r/w   XMAC 1 Interrupt Mask Register*/
+@@ -400,14 +524,23 @@
+ #define B2_CONN_TYP           0x0118  /*  8 bit       Connector type */
+ #define B2_PMD_TYP            0x0119  /*  8 bit       PMD type */
+ #define B2_MAC_CFG            0x011a  /*  8 bit       MAC Configuration / Chip Revision */
+-#define B2_CHIP_ID            0x011b  /*  8 bit       Chip Identification Number */
+-      /* Eprom registers are currently of no use */
++#define B2_CHIP_ID            0x011b  /*  8 bit       Chip Identification Number */
++      /* Eprom registers */
+ #define B2_E_0                        0x011c  /*  8 bit       EPROM Byte 0 (ext. SRAM size */
++/* Yukon and Genesis */
+ #define B2_E_1                        0x011d  /*  8 bit       EPROM Byte 1 (PHY type) */
+ #define B2_E_2                        0x011e  /*  8 bit       EPROM Byte 2 */
++/* Yukon-2 */
++#define B2_Y2_CLK_GATE        0x011d  /*  8 bit       Clock Gating (Yukon-2) */
++#define B2_Y2_HW_RES  0x011e  /*  8 bit       HW Resources (Yukon-2) */
++
+ #define B2_E_3                        0x011f  /*  8 bit       EPROM Byte 3 */
++
++/* Yukon and Genesis */
+ #define B2_FAR                        0x0120  /* 32 bit       Flash-Prom Addr Reg/Cnt */
+ #define B2_FDP                        0x0124  /*  8 bit       Flash-Prom Data Port */
++/* Yukon-2 */
++#define B2_Y2_CLK_CTRL        0x0120  /* 32 bit       Core Clock Frequency Control */
+       /* 0x0125 - 0x0127:     reserved */
+ #define B2_LD_CTRL            0x0128  /*  8 bit       EPROM loader control register */
+ #define B2_LD_TEST            0x0129  /*  8 bit       EPROM loader test register */
+@@ -439,6 +572,10 @@
+ #define B2_BSC_CTRL           0x0178  /*  8 bit       Blink Source Counter Control */
+ #define B2_BSC_STAT           0x0179  /*  8 bit       Blink Source Counter Status */
+ #define B2_BSC_TST            0x017a  /* 16 bit       Blink Source Counter Test Reg */
++
++/* Yukon-2 */
++#define Y2_PEX_PHY_DATA       0x0170  /* 16 bit       PEX PHY Data Register */
++#define Y2_PEX_PHY_ADDR       0x0172  /* 16 bit       PEX PHY Address Register */
+       /* 0x017c - 0x017f:     reserved */
+ /*
+@@ -448,9 +585,13 @@
+ #define B3_RAM_ADDR           0x0180  /* 32 bit       RAM Address, to read or write */
+ #define B3_RAM_DATA_LO        0x0184  /* 32 bit       RAM Data Word (low dWord) */
+ #define B3_RAM_DATA_HI        0x0188  /* 32 bit       RAM Data Word (high dWord) */
++
++#define SELECT_RAM_BUFFER(rb, addr) (addr | (rb << 6))        /* Yukon-2 only */
++
+       /* 0x018c - 0x018f:     reserved */
+ /* RAM Interface Registers */
++/* Yukon-2: use SELECT_RAM_BUFFER() to access the RAM buffer */
+ /*
+  * The HW-Spec. calls this registers Timeout Value 0..11. But this names are
+  * not usable in SW. Please notice these are NOT real timeouts, these are
+@@ -517,8 +658,8 @@
+       /* 0x01ea - 0x01eb:     reserved */
+ #define B3_PA_TOVAL_TX2       0x01ec  /* 16 bit       Timeout Val Tx Path MAC 2 */
+       /* 0x01ee - 0x01ef:     reserved */
+-#define B3_PA_CTRL    0x01f0  /* 16 bit       Packet Arbiter Ctrl Register */
+-#define B3_PA_TEST    0x01f2  /* 16 bit       Packet Arbiter Test Register */
++#define B3_PA_CTRL            0x01f0  /* 16 bit       Packet Arbiter Ctrl Register */
++#define B3_PA_TEST            0x01f2  /* 16 bit       Packet Arbiter Test Register */
+       /* 0x01f4 - 0x01ff:     reserved */
+ /*
+@@ -532,7 +673,16 @@
+ #define TXA_CTRL              0x0210  /*  8 bit       Tx Arbiter Control Register */
+ #define TXA_TEST              0x0211  /*  8 bit       Tx Arbiter Test Register */
+ #define TXA_STAT              0x0212  /*  8 bit       Tx Arbiter Status Register */
+-      /* 0x0213 - 0x027f:     reserved */
++      /* 0x0213 - 0x021f:     reserved */
++
++      /* RSS key registers for Yukon-2 Family */
++#define B4_RSS_KEY            0x0220  /* 4x32 bit RSS Key register (Yukon-2) */
++      /* RSS key register offsets */
++#define KEY_IDX_0              0              /* offset for location of KEY 0 */
++#define KEY_IDX_1              4              /* offset for location of KEY 1 */
++#define KEY_IDX_2              8              /* offset for location of KEY 2 */
++#define KEY_IDX_3             12              /* offset for location of KEY 3 */
++
+       /* 0x0280 - 0x0292:     MAC 2 */
+       /* 0x0213 - 0x027f:     reserved */
+@@ -570,8 +720,37 @@
+ #define Q_T1_SV       0x3f    /*  8 bit       Test Register 1 Supervisor SM */
+ #define Q_T2  0x40    /* 32 bit       Test Register 2 */
+ #define Q_T3  0x44    /* 32 bit       Test Register 3 */
++
++/* Yukon-2 */
++#define Q_DONE        0x24    /* 16 bit       Done Index              (Yukon-2 only) */
++#define Q_WM  0x40    /* 16 bit       FIFO Watermark */
++#define Q_AL  0x42    /*  8 bit       FIFO Alignment */
++#define Q_RSP 0x44    /* 16 bit       FIFO Read Shadow Pointer */
++#define Q_RSL 0x46    /*  8 bit       FIFO Read Shadow Level */
++#define Q_RP  0x48    /*  8 bit       FIFO Read Pointer */
++#define Q_RL  0x4a    /*  8 bit       FIFO Read Level */
++#define Q_WP  0x4c    /*  8 bit       FIFO Write Pointer */
++#define Q_WSP 0x4d    /*  8 bit       FIFO Write Shadow Pointer */
++#define Q_WL  0x4e    /*  8 bit       FIFO Write Level */
++#define Q_WSL 0x4f    /*  8 bit       FIFO Write Shadow Level */
+       /* 0x48 - 0x7f: reserved */
++/* Queue Prefetch Unit Offsets, use Y2_PREF_Q_ADDR() to address (Yukon-2 only)*/
++#define Y2_B8_PREF_REGS                       0x0450
++
++#define PREF_UNIT_CTRL_REG            0x00    /* 32 bit       Prefetch Control register */
++#define PREF_UNIT_LAST_IDX_REG        0x04    /* 16 bit       Last Index */
++#define PREF_UNIT_ADDR_LOW_REG        0x08    /* 32 bit       List start addr, low part */
++#define PREF_UNIT_ADDR_HI_REG 0x0c    /* 32 bit       List start addr, high part*/
++#define PREF_UNIT_GET_IDX_REG 0x10    /* 16 bit       Get Index */
++#define PREF_UNIT_PUT_IDX_REG 0x14    /* 16 bit       Put Index */
++#define PREF_UNIT_FIFO_WP_REG 0x20    /*  8 bit       FIFO write pointer */
++#define PREF_UNIT_FIFO_RP_REG 0x24    /*  8 bit       FIFO read pointer */
++#define PREF_UNIT_FIFO_WM_REG 0x28    /*  8 bit       FIFO watermark */
++#define PREF_UNIT_FIFO_LEV_REG        0x2c    /*  8 bit       FIFO level */
++
++#define PREF_UNIT_MASK_IDX            0x0fff
++
+ /*
+  *    Bank 16 - 23
+  */
+@@ -583,17 +762,17 @@
+ #define RB_END                        0x04    /* 32 bit       RAM Buffer End Address */
+ #define RB_WP                 0x08    /* 32 bit       RAM Buffer Write Pointer */
+ #define RB_RP                 0x0c    /* 32 bit       RAM Buffer Read Pointer */
+-#define RB_RX_UTPP            0x10    /* 32 bit       Rx Upper Threshold, Pause Pack */
+-#define RB_RX_LTPP            0x14    /* 32 bit       Rx Lower Threshold, Pause Pack */
++#define RB_RX_UTPP            0x10    /* 32 bit       Rx Upper Threshold, Pause Packet */
++#define RB_RX_LTPP            0x14    /* 32 bit       Rx Lower Threshold, Pause Packet */
+ #define RB_RX_UTHP            0x18    /* 32 bit       Rx Upper Threshold, High Prio */
+ #define RB_RX_LTHP            0x1c    /* 32 bit       Rx Lower Threshold, High Prio */
+       /* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */
+ #define RB_PC                 0x20    /* 32 bit       RAM Buffer Packet Counter */
+ #define RB_LEV                        0x24    /* 32 bit       RAM Buffer Level Register */
+-#define RB_CTRL                       0x28    /*  8 bit       RAM Buffer Control Register */
++#define RB_CTRL                       0x28    /* 32 bit       RAM Buffer Control Register */
+ #define RB_TST1                       0x29    /*  8 bit       RAM Buffer Test Register 1 */
+-#define RB_TST2                       0x2A    /*  8 bit       RAM Buffer Test Register 2 */
+-      /* 0x2c - 0x7f: reserved */
++#define RB_TST2                       0x2a    /*  8 bit       RAM Buffer Test Register 2 */
++      /* 0x2b - 0x7f: reserved */
+ /*
+  *    Bank 24
+@@ -603,7 +782,7 @@
+  * use MR_ADDR() to access
+  */
+ #define RX_MFF_EA             0x0c00  /* 32 bit       Receive MAC FIFO End Address */
+-#define RX_MFF_WP             0x0c04  /* 32 bit       Receive MAC FIFO Write Pointer */
++#define RX_MFF_WP             0x0c04  /* 32 bit       Receive MAC FIFO Write Pointer */
+       /* 0x0c08 - 0x0c0b:     reserved */
+ #define RX_MFF_RP             0x0c0c  /* 32 bit       Receive MAC FIFO Read Pointer */
+ #define RX_MFF_PC             0x0c10  /* 32 bit       Receive MAC FIFO Packet Cnt */
+@@ -628,20 +807,22 @@
+ #define LNK_LED_REG           0x0c3c  /*  8 bit       Link LED Register */
+       /* 0x0c3d - 0x0c3f:     reserved */
+-/* Receive GMAC FIFO (YUKON only), use MR_ADDR() to access */
++/* Receive GMAC FIFO (YUKON and Yukon-2), use MR_ADDR() to access */
+ #define RX_GMF_EA             0x0c40  /* 32 bit       Rx GMAC FIFO End Address */
+ #define RX_GMF_AF_THR 0x0c44  /* 32 bit       Rx GMAC FIFO Almost Full Thresh. */
+ #define RX_GMF_CTRL_T 0x0c48  /* 32 bit       Rx GMAC FIFO Control/Test */
+ #define RX_GMF_FL_MSK 0x0c4c  /* 32 bit       Rx GMAC FIFO Flush Mask */
+ #define RX_GMF_FL_THR 0x0c50  /* 32 bit       Rx GMAC FIFO Flush Threshold */
+-      /* 0x0c54 - 0x0c5f:     reserved */
+-#define RX_GMF_WP             0x0c60  /* 32 bit       Rx GMAC FIFO Write Pointer */
++#define RX_GMF_TR_THR 0x0c54  /* 32 bit       Rx Truncation Threshold (Yukon-2) */
++      /* 0x0c58 - 0x0c5b:     reserved */
++#define RX_GMF_VLAN           0x0c5c  /* 32 bit       Rx VLAN Type Register (Yukon-2) */
++#define RX_GMF_WP             0x0c60  /* 32 bit       Rx GMAC FIFO Write Pointer */
+       /* 0x0c64 - 0x0c67:     reserved */
+-#define RX_GMF_WLEV           0x0c68  /* 32 bit       Rx GMAC FIFO Write Level */
++#define RX_GMF_WLEV           0x0c68  /* 32 bit       Rx GMAC FIFO Write Level */
+       /* 0x0c6c - 0x0c6f:     reserved */
+-#define RX_GMF_RP             0x0c70  /* 32 bit       Rx GMAC FIFO Read Pointer */
++#define RX_GMF_RP             0x0c70  /* 32 bit       Rx GMAC FIFO Read Pointer */
+       /* 0x0c74 - 0x0c77:     reserved */
+-#define RX_GMF_RLEV           0x0c78  /* 32 bit       Rx GMAC FIFO Read Level */
++#define RX_GMF_RLEV           0x0c78  /* 32 bit       Rx GMAC FIFO Read Level */
+       /* 0x0c7c - 0x0c7f:     reserved */
+ /*
+@@ -658,7 +839,7 @@
+  * use MR_ADDR() to access
+  */
+ #define TX_MFF_EA             0x0d00  /* 32 bit       Transmit MAC FIFO End Address */
+-#define TX_MFF_WP             0x0d04  /* 32 bit       Transmit MAC FIFO WR Pointer */
++#define TX_MFF_WP             0x0d04  /* 32 bit       Transmit MAC FIFO WR Pointer */
+ #define TX_MFF_WSP            0x0d08  /* 32 bit       Transmit MAC FIFO WR Shadow Ptr */
+ #define TX_MFF_RP             0x0d0c  /* 32 bit       Transmit MAC FIFO RD Pointer */
+ #define TX_MFF_PC             0x0d10  /* 32 bit       Transmit MAC FIFO Packet Cnt */
+@@ -676,18 +857,19 @@
+ #define TX_LED_TST            0x0d29  /*  8 bit       Transmit LED Cnt Test Reg */
+       /* 0x0d2a - 0x0d3f:     reserved */
+-/* Transmit GMAC FIFO (YUKON only), use MR_ADDR() to access */
++/* Transmit GMAC FIFO (YUKON and Yukon-2), use MR_ADDR() to access */
+ #define TX_GMF_EA             0x0d40  /* 32 bit       Tx GMAC FIFO End Address */
+ #define TX_GMF_AE_THR 0x0d44  /* 32 bit       Tx GMAC FIFO Almost Empty Thresh.*/
+ #define TX_GMF_CTRL_T 0x0d48  /* 32 bit       Tx GMAC FIFO Control/Test */
+-      /* 0x0d4c - 0x0d5f:     reserved */
+-#define TX_GMF_WP             0x0d60  /* 32 bit       Tx GMAC FIFO Write Pointer */
+-#define TX_GMF_WSP            0x0d64  /* 32 bit       Tx GMAC FIFO Write Shadow Ptr. */
+-#define TX_GMF_WLEV           0x0d68  /* 32 bit       Tx GMAC FIFO Write Level */
++      /* 0x0d4c - 0x0d5b:     reserved */
++#define TX_GMF_VLAN           0x0d5c  /* 32 bit       Tx VLAN Type Register (Yukon-2) */
++#define TX_GMF_WP             0x0d60  /* 32 bit       Tx GMAC FIFO Write Pointer */
++#define TX_GMF_WSP            0x0d64  /* 32 bit       Tx GMAC FIFO Write Shadow Pointer */
++#define TX_GMF_WLEV           0x0d68  /* 32 bit       Tx GMAC FIFO Write Level */
+       /* 0x0d6c - 0x0d6f:     reserved */
+-#define TX_GMF_RP             0x0d70  /* 32 bit       Tx GMAC FIFO Read Pointer */
+-#define TX_GMF_RSTP           0x0d74  /* 32 bit       Tx GMAC FIFO Restart Pointer */
+-#define TX_GMF_RLEV           0x0d78  /* 32 bit       Tx GMAC FIFO Read Level */
++#define TX_GMF_RP             0x0d70  /* 32 bit       Tx GMAC FIFO Read Pointer */
++#define TX_GMF_RSTP           0x0d74  /* 32 bit       Tx GMAC FIFO Restart Pointer */
++#define TX_GMF_RLEV           0x0d78  /* 32 bit       Tx GMAC FIFO Read Level */
+       /* 0x0d7c - 0x0d7f:     reserved */
+ /*
+@@ -713,12 +895,84 @@
+ #define GMAC_TI_ST_CTRL       0x0e18  /*  8 bit       Time Stamp Timer Ctrl Reg */
+       /* 0x0e19:      reserved */
+ #define GMAC_TI_ST_TST        0x0e1a  /*  8 bit       Time Stamp Timer Test Reg */
+-      /* 0x0e1b - 0x0e7f:     reserved */
++      /* 0x0e1b - 0x0e1f:     reserved */
++
++/* Polling Unit Registers (Yukon-2 only) */
++#define POLL_CTRL                     0x0e20  /* 32 bit       Polling Unit Control Reg */
++#define POLL_LAST_IDX         0x0e24  /* 16 bit       Polling Unit List Last Index */
++      /* 0x0e26 - 0x0e27:     reserved */
++#define POLL_LIST_ADDR_LO     0x0e28  /* 32 bit       Poll. List Start Addr (low) */
++#define POLL_LIST_ADDR_HI     0x0e2c  /* 32 bit       Poll. List Start Addr (high) */
++      /* 0x0e30 - 0x0e3f:     reserved */
++
++/* ASF Subsystem Registers (Yukon-2 only) */
++#define B28_Y2_SMB_CONFIG     0x0e40  /* 32 bit       ASF SMBus Config Register */
++#define B28_Y2_SMB_CSD_REG    0x0e44  /* 32 bit       ASF SMB Control/Status/Data */
++      /* 0x0e48 - 0x0e5f: reserved */
++#define B28_Y2_ASF_IRQ_V_BASE 0x0e60  /* 32 bit       ASF IRQ Vector Base */
++      /* 0x0e64 - 0x0e67: reserved */
++#define B28_Y2_ASF_STAT_CMD   0x0e68  /* 32 bit       ASF Status and Command Reg */
++#define B28_Y2_ASF_HOST_COM   0x0e6c  /* 32 bit       ASF Host Communication Reg */
++#define B28_Y2_DATA_REG_1     0x0e70  /* 32 bit       ASF/Host Data Register 1 */
++#define B28_Y2_DATA_REG_2     0x0e74  /* 32 bit       ASF/Host Data Register 2 */
++#define B28_Y2_DATA_REG_3     0x0e78  /* 32 bit       ASF/Host Data Register 3 */
++#define B28_Y2_DATA_REG_4     0x0e7c  /* 32 bit       ASF/Host Data Register 4 */
+ /*
+  *    Bank 29
+  */
+-      /* 0x0e80 - 0x0efc:     reserved */
++
++/* Status BMU Registers (Yukon-2 only)*/
++#define STAT_CTRL                     0x0e80  /* 32 bit       Status BMU Control Reg */
++#define STAT_LAST_IDX         0x0e84  /* 16 bit       Status BMU Last Index */
++      /* 0x0e85 - 0x0e86:     reserved */
++#define STAT_LIST_ADDR_LO     0x0e88  /* 32 bit       Status List Start Addr (low) */
++#define STAT_LIST_ADDR_HI     0x0e8c  /* 32 bit       Status List Start Addr (high) */
++#define STAT_TXA1_RIDX                0x0e90  /* 16 bit       Status TxA1 Report Index Reg */
++#define STAT_TXS1_RIDX                0x0e92  /* 16 bit       Status TxS1 Report Index Reg */
++#define STAT_TXA2_RIDX                0x0e94  /* 16 bit       Status TxA2 Report Index Reg */
++#define STAT_TXS2_RIDX                0x0e96  /* 16 bit       Status TxS2 Report Index Reg */
++#define STAT_TX_IDX_TH                0x0e98  /* 16 bit       Status Tx Index Threshold Reg */
++      /* 0x0e9a - 0x0e9b:     reserved */
++#define STAT_PUT_IDX          0x0e9c  /* 16 bit       Status Put Index Reg */
++      /* 0x0e9e - 0x0e9f:     reserved */
++
++/* FIFO Control/Status Registers (Yukon-2 only)*/
++#define STAT_FIFO_WP          0x0ea0  /*  8 bit       Status FIFO Write Pointer Reg */
++      /* 0x0ea1 - 0x0ea3:     reserved */
++#define STAT_FIFO_RP          0x0ea4  /*  8 bit       Status FIFO Read Pointer Reg */
++      /* 0x0ea5:      reserved */
++#define STAT_FIFO_RSP         0x0ea6  /*  8 bit       Status FIFO Read Shadow Ptr */
++      /* 0x0ea7:      reserved */
++#define STAT_FIFO_LEVEL               0x0ea8  /*  8 bit       Status FIFO Level Reg */
++      /* 0x0ea9:      reserved */
++#define STAT_FIFO_SHLVL               0x0eaa  /*  8 bit       Status FIFO Shadow Level Reg */
++      /* 0x0eab:      reserved */
++#define STAT_FIFO_WM          0x0eac  /*  8 bit       Status FIFO Watermark Reg */
++#define STAT_FIFO_ISR_WM      0x0ead  /*  8 bit       Status FIFO ISR Watermark Reg */
++      /* 0x0eae - 0x0eaf:     reserved */
++
++/* Level and ISR Timer Registers (Yukon-2 only)*/
++#define STAT_LEV_TIMER_INI    0x0eb0  /* 32 bit       Level Timer Init. Value Reg */
++#define STAT_LEV_TIMER_CNT    0x0eb4  /* 32 bit       Level Timer Counter Reg */
++#define STAT_LEV_TIMER_CTRL   0x0eb8  /*  8 bit       Level Timer Control Reg */
++#define STAT_LEV_TIMER_TEST   0x0eb9  /*  8 bit       Level Timer Test Reg */
++      /* 0x0eba - 0x0ebf:     reserved */
++#define STAT_TX_TIMER_INI     0x0ec0  /* 32 bit       Tx Timer Init. Value Reg */
++#define STAT_TX_TIMER_CNT     0x0ec4  /* 32 bit       Tx Timer Counter Reg */
++#define STAT_TX_TIMER_CTRL    0x0ec8  /*  8 bit       Tx Timer Control Reg */
++#define STAT_TX_TIMER_TEST    0x0ec9  /*  8 bit       Tx Timer Test Reg */
++      /* 0x0eca - 0x0ecf:     reserved */
++#define STAT_ISR_TIMER_INI    0x0ed0  /* 32 bit       ISR Timer Init. Value Reg */
++#define STAT_ISR_TIMER_CNT    0x0ed4  /* 32 bit       ISR Timer Counter Reg */
++#define STAT_ISR_TIMER_CTRL   0x0ed8  /*  8 bit       ISR Timer Control Reg */
++#define STAT_ISR_TIMER_TEST   0x0ed9  /*  8 bit       ISR Timer Test Reg */
++      /* 0x0eda - 0x0eff:     reserved */
++
++#define ST_LAST_IDX_MASK      0x007f  /* Last Index Mask */
++#define ST_TXRP_IDX_MASK      0x0fff  /* Tx Report Index Mask */
++#define ST_TXTH_IDX_MASK      0x0fff  /* Tx Threshold Index Mask */
++#define ST_WM_IDX_MASK                0x3f    /* FIFO Watermark Index Mask */
+ /*
+  *    Bank 30
+@@ -742,11 +996,9 @@
+ #define WOL_MATCH_RES 0x0f23  /*  8 bit       WOL Match Result Reg */
+ #define WOL_MAC_ADDR_LO       0x0f24  /* 32 bit       WOL MAC Address Low */
+ #define WOL_MAC_ADDR_HI       0x0f28  /* 16 bit       WOL MAC Address High */
+-#define WOL_PATT_RPTR 0x0f2c  /*  8 bit       WOL Pattern Read Ptr */
+-
+-/* use this macro to access above registers */
+-#define WOL_REG(Reg)  ((Reg) + (pAC->GIni.GIWolOffs))
+-
++#define WOL_PATT_PME  0x0f2a  /*  8 bit       WOL PME Match Enable (Yukon-2) */
++#define WOL_PATT_ASFM 0x0f2b  /*  8 bit       WOL ASF Match Enable (Yukon-2) */
++#define WOL_PATT_RPTR 0x0f2c  /*  8 bit       WOL Pattern Read Pointer */
+ /* WOL Pattern Length Registers (YUKON only) */
+@@ -764,11 +1016,22 @@
+  */
+ /* 0x0f80 - 0x0fff:   reserved */
++/* WOL registers link 2 */
++
++/* use this macro to access WOL registers */
++#define WOL_REG(Port, Reg)    ((Reg) + ((Port)*0x80) + (pAC->GIni.GIWolOffs))
++
+ /*
+  *    Bank 32 - 33
+  */
+ #define WOL_PATT_RAM_1        0x1000  /*  WOL Pattern RAM Link 1 */
++#define WOL_PATT_RAM_2        0x1400  /*  WOL Pattern RAM Link 2 */
++/* use this macro to retrieve the pattern ram base address */
++#define WOL_PATT_RAM_BASE(Port) (WOL_PATT_RAM_1 + (Port)*0x400)
++
++/* offset to configuration space on Yukon-2 */
++#define Y2_CFG_SPC            0x1c00
+ /*
+  *    Bank 0x22 - 0x3f
+  */
+@@ -800,13 +1063,26 @@
+  */
+ /*    B0_RAP          8 bit   Register Address Port */
+                                                               /* Bit 7:       reserved */
+-#define RAP_RAP                       0x3f    /* Bit 6..0:    0 = block 0,..,6f = block 6f */
++#define RAP_MSK                       0x7f    /* Bit 6..0:    0 = block 0,..,6f = block 6f */
++
++/*    B0_CTST                 24 bit  Control/Status register */
++                                                              /* Bit 23..18:  reserved */
++#define Y2_VMAIN_AVAIL        BIT_17          /* VMAIN available (YUKON-2 only) */
++#define Y2_VAUX_AVAIL BIT_16          /* VAUX available (YUKON-2 only) */
++                                                              /* Bit 15..14:  reserved */
++#define Y2_ASF_ENABLE BIT_13S         /* ASF Unit Enable (YUKON-2 only) */
++#define Y2_ASF_DISABLE        BIT_12S         /* ASF Unit Disable (YUKON-2 only) */
++#define Y2_CLK_RUN_ENA        BIT_11S         /* CLK_RUN Enable  (YUKON-2 only) */
++#define Y2_CLK_RUN_DIS        BIT_10S         /* CLK_RUN Disable (YUKON-2 only) */
++#define Y2_LED_STAT_ON        BIT_9S          /* Status LED On  (YUKON-2 only) */
++#define Y2_LED_STAT_OFF       BIT_8S          /* Status LED Off (YUKON-2 only) */
++                                                              /* Bit  7.. 0:  same as below */
+ /*    B0_CTST                 16 bit  Control/Status register */
+                                                               /* Bit 15..14:  reserved */
+-#define CS_CLK_RUN_HOT        BIT_13S         /* CLK_RUN hot m. (YUKON-Lite only) */
+-#define CS_CLK_RUN_RST        BIT_12S         /* CLK_RUN reset  (YUKON-Lite only) */
+-#define CS_CLK_RUN_ENA        BIT_11S         /* CLK_RUN enable (YUKON-Lite only) */
++#define CS_CLK_RUN_HOT        BIT_13S         /* CLK_RUN Hot m. (YUKON-Lite only) */
++#define CS_CLK_RUN_RST        BIT_12S         /* CLK_RUN Reset  (YUKON-Lite only) */
++#define CS_CLK_RUN_ENA        BIT_11S         /* CLK_RUN Enable (YUKON-Lite only) */
+ #define CS_VAUX_AVAIL BIT_10S         /* VAUX available (YUKON only) */
+ #define CS_BUS_CLOCK  BIT_9S          /* Bus Clock 0/1 = 33/66 MHz */
+ #define CS_BUS_SLOT_SZ        BIT_8S          /* Slot Size 0/1 = 32/64 bit slot */
+@@ -814,26 +1090,27 @@
+ #define CS_CL_SW_IRQ  BIT_6S          /* Clear IRQ SW Request */
+ #define CS_STOP_DONE  BIT_5S          /* Stop Master is finished */
+ #define CS_STOP_MAST  BIT_4S          /* Command Bit to stop the master */
+-#define CS_MRST_CLR           BIT_3S          /* Clear Master reset   */
+-#define CS_MRST_SET           BIT_2S          /* Set Master reset     */
+-#define CS_RST_CLR            BIT_1S          /* Clear Software reset */
+-#define CS_RST_SET            BIT_0S          /* Set   Software reset */
++#define CS_MRST_CLR           BIT_3S          /* Clear Master Reset */
++#define CS_MRST_SET           BIT_2S          /* Set   Master Reset */
++#define CS_RST_CLR            BIT_1S          /* Clear Software Reset */
++#define CS_RST_SET            BIT_0S          /* Set   Software Reset */
+-/*    B0_LED                   8 Bit  LED register */
++/*    B0_LED                   8 Bit  LED register (GENESIS only)*/
+                                                               /* Bit  7.. 2:  reserved */
+-#define LED_STAT_ON           BIT_1S          /* Status LED on        */
+-#define LED_STAT_OFF  BIT_0S          /* Status LED off       */
++#define LED_STAT_ON           BIT_1S          /* Status LED On        */
++#define LED_STAT_OFF  BIT_0S          /* Status LED Off       */
+ /*    B0_POWER_CTRL    8 Bit  Power Control reg (YUKON only) */
+ #define PC_VAUX_ENA           BIT_7           /* Switch VAUX Enable  */
+-#define PC_VAUX_DIS           BIT_6       /* Switch VAUX Disable */
+-#define PC_VCC_ENA            BIT_5       /* Switch VCC Enable  */
+-#define PC_VCC_DIS            BIT_4       /* Switch VCC Disable */
+-#define PC_VAUX_ON            BIT_3       /* Switch VAUX On  */
+-#define PC_VAUX_OFF           BIT_2       /* Switch VAUX Off */
+-#define PC_VCC_ON             BIT_1       /* Switch VCC On  */
+-#define PC_VCC_OFF            BIT_0       /* Switch VCC Off */
++#define PC_VAUX_DIS           BIT_6           /* Switch VAUX Disable */
++#define PC_VCC_ENA            BIT_5           /* Switch VCC Enable  */
++#define PC_VCC_DIS            BIT_4           /* Switch VCC Disable */
++#define PC_VAUX_ON            BIT_3           /* Switch VAUX On  */
++#define PC_VAUX_OFF           BIT_2           /* Switch VAUX Off */
++#define PC_VCC_ON             BIT_1           /* Switch VCC On  */
++#define PC_VCC_OFF            BIT_0           /* Switch VCC Off */
++/* Yukon and Genesis */
+ /*    B0_ISRC                 32 bit  Interrupt Source Register */
+ /*    B0_IMSK                 32 bit  Interrupt Mask Register */
+ /*    B0_SP_ISRC              32 bit  Special Interrupt Source Reg */
+@@ -879,12 +1156,51 @@
+ #define IS_XA2_F              BIT_1           /* Q_XA2 End of Frame */
+ #define IS_XA2_C              BIT_0           /* Q_XA2 Encoding Error */
++/*                                            (Yukon-2)                       */
++/*    B0_ISRC                 32 bit  Interrupt Source Register */
++/*    B0_IMSK                 32 bit  Interrupt Mask Register */
++/*    B0_SP_ISRC              32 bit  Special Interrupt Source Reg */
++/*    B2_IRQM_MSK             32 bit  IRQ Moderation Mask */
++/*    B0_Y2_SP_ISRC2  32 bit  Special Interrupt Source Reg 2 */
++/*    B0_Y2_SP_ISRC3  32 bit  Special Interrupt Source Reg 3 */
++/*    B0_Y2_SP_EISR   32 bit  Enter ISR Reg */
++/*    B0_Y2_SP_LISR   32 bit  Leave ISR Reg */
++#define Y2_IS_PORT_MASK(Port, Mask)   ((Mask) << (Port*8))
++#define Y2_IS_HW_ERR  BIT_31          /* Interrupt HW Error */
++#define Y2_IS_STAT_BMU        BIT_30          /* Status BMU Interrupt */
++#define Y2_IS_ASF             BIT_29          /* ASF subsystem Interrupt */
++                                                      /* Bit 28: reserved */
++#define Y2_IS_POLL_CHK        BIT_27          /* Check IRQ from polling unit */
++#define Y2_IS_TWSI_RDY        BIT_26          /* IRQ on end of TWSI Tx */
++#define Y2_IS_IRQ_SW  BIT_25          /* SW forced IRQ        */
++#define Y2_IS_TIMINT  BIT_24          /* IRQ from Timer       */
++                                                      /* Bit 23..16 reserved */
++                                              /* Link 2 Interrupts */
++#define Y2_IS_IRQ_PHY2        BIT_12          /* Interrupt from PHY 2 */
++#define Y2_IS_IRQ_MAC2        BIT_11          /* Interrupt from MAC 2 */
++#define Y2_IS_CHK_RX2 BIT_10          /* Descriptor error Rx 2 */
++#define Y2_IS_CHK_TXS2        BIT_9           /* Descriptor error TXS 2 */
++#define Y2_IS_CHK_TXA2        BIT_8           /* Descriptor error TXA 2 */
++                                                      /* Bit  7.. 5 reserved */
++                                              /* Link 1 interrupts */
++#define Y2_IS_IRQ_PHY1        BIT_4           /* Interrupt from PHY 1 */
++#define Y2_IS_IRQ_MAC1        BIT_3           /* Interrupt from MAC 1 */
++#define Y2_IS_CHK_RX1 BIT_2           /* Descriptor error Rx 1 */
++#define Y2_IS_CHK_TXS1        BIT_1           /* Descriptor error TXS 1 */
++#define Y2_IS_CHK_TXA1        BIT_0           /* Descriptor error TXA 1 */
++
++#define Y2_IS_L1_MASK 0x0000001fUL    /* IRQ Mask for port 1 */       
++#define Y2_IS_L2_MASK 0x00001f00UL    /* IRQ Mask for port 2 */       
++
++#define Y2_IS_ALL_MSK 0xef001f1fUL    /* All Interrupt bits */
++
++/* Yukon and Genesis */
+ /*    B0_HWE_ISRC             32 bit  HW Error Interrupt Src Reg */
+ /*    B0_HWE_IMSK             32 bit  HW Error Interrupt Mask Reg */
+ /*    B2_IRQM_HWE_MSK 32 bit  IRQ Moderation HW Error Mask */
+ #define IS_ERR_MSK            0x00000fffL     /*              All Error bits */
+-                                                              /* Bit 31..14:  reserved */
++                                                      /* Bit 31..14:  reserved */
+ #define IS_IRQ_TIST_OV        BIT_13  /* Time Stamp Timer Overflow (YUKON only) */
+ #define IS_IRQ_SENSOR BIT_12  /* IRQ from Sensor (YUKON only) */
+ #define IS_IRQ_MST_ERR        BIT_11  /* IRQ master error detected */
+@@ -900,6 +1216,43 @@
+ #define IS_R1_PAR_ERR BIT_1   /* Queue R1 Parity Error */
+ #define IS_R2_PAR_ERR BIT_0   /* Queue R2 Parity Error */
++                                              /* Yukon-2 */
++/*    B0_HWE_ISRC             32 bit  HW Error Interrupt Src Reg */
++/*    B0_HWE_IMSK             32 bit  HW Error Interrupt Mask Reg */
++/*    B2_IRQM_HWE_MSK 32 bit  IRQ Moderation HW Error Mask */
++                                              /* Bit: 31..30 reserved */
++#define Y2_IS_TIST_OV BIT_29  /* Time Stamp Timer overflow interrupt */
++#define Y2_IS_SENSOR  BIT_28  /* Sensor interrupt */
++#define Y2_IS_MST_ERR BIT_27  /* Master error interrupt */
++#define Y2_IS_IRQ_STAT        BIT_26  /* Status exception interrupt */
++#define Y2_IS_PCI_EXP BIT_25  /* PCI-Express interrupt */
++#define Y2_IS_PCI_NEXP        BIT_24  /* PCI-Express error similar to PCI error */
++                                              /* Bit: 23..14 reserved */
++                                              /* Link 2 */
++#define Y2_IS_PAR_RD2 BIT_13  /* Read RAM parity error interrupt */
++#define Y2_IS_PAR_WR2 BIT_12  /* Write RAM parity error interrupt */
++#define Y2_IS_PAR_MAC2        BIT_11  /* MAC hardware fault interrupt */
++#define Y2_IS_PAR_RX2 BIT_10  /* Parity Error Rx Queue 2 */
++#define Y2_IS_TCP_TXS2        BIT_9   /* TCP length mismatch sync Tx queue IRQ */
++#define Y2_IS_TCP_TXA2        BIT_8   /* TCP length mismatch async Tx queue IRQ */
++                                              /* Bit:  9.. 6 reserved */
++                                              /* Link 1 */
++#define Y2_IS_PAR_RD1 BIT_5   /* Read RAM parity error interrupt */
++#define Y2_IS_PAR_WR1 BIT_4   /* Write RAM parity error interrupt */
++#define Y2_IS_PAR_MAC1        BIT_3   /* MAC hardware fault interrupt */
++#define Y2_IS_PAR_RX1 BIT_2   /* Parity Error Rx Queue 1 */
++#define Y2_IS_TCP_TXS1        BIT_1   /* TCP length mismatch sync Tx queue IRQ */
++#define Y2_IS_TCP_TXA1        BIT_0   /* TCP length mismatch async Tx queue IRQ */
++
++#define Y2_HWE_L1_MASK        (Y2_IS_PAR_RD1 | Y2_IS_PAR_WR1 | Y2_IS_PAR_MAC1 |\
++                                               Y2_IS_PAR_RX1 | Y2_IS_TCP_TXS1| Y2_IS_TCP_TXA1)
++#define Y2_HWE_L2_MASK        (Y2_IS_PAR_RD2 | Y2_IS_PAR_WR2 | Y2_IS_PAR_MAC2 |\
++                                               Y2_IS_PAR_RX2 | Y2_IS_TCP_TXS2| Y2_IS_TCP_TXA2)
++
++#define Y2_HWE_ALL_MSK        (Y2_IS_TIST_OV | /* Y2_IS_SENSOR | */ Y2_IS_MST_ERR |\
++                                               Y2_IS_IRQ_STAT | Y2_IS_PCI_EXP | Y2_IS_PCI_NEXP |\
++                                               Y2_HWE_L1_MASK | Y2_HWE_L2_MASK)
++
+ /*    B2_CONN_TYP              8 bit  Connector type */
+ /*    B2_PMD_TYP               8 bit  PMD type */
+ /*    Values of connector and PMD type comply to SysKonnect internal std */
+@@ -908,19 +1261,65 @@
+ #define CFG_CHIP_R_MSK        (0xf<<4)        /* Bit 7.. 4: Chip Revision */
+                                                                       /* Bit 3.. 2:   reserved */
+ #define CFG_DIS_M2_CLK        BIT_1S          /* Disable Clock for 2nd MAC */
+-#define CFG_SNG_MAC           BIT_0S          /* MAC Config: 0=2 MACs / 1=1 MAC*/
++#define CFG_SNG_MAC           BIT_0S          /* MAC Config: 0 = 2 MACs; 1 = 1 MAC */
+-/*    B2_CHIP_ID               8 bit  Chip Identification Number */
++/*    B2_CHIP_ID               8 bit  Chip Identification Number */
+ #define CHIP_ID_GENESIS               0x0a    /* Chip ID for GENESIS */
+ #define CHIP_ID_YUKON         0xb0    /* Chip ID for YUKON */
+ #define CHIP_ID_YUKON_LITE    0xb1    /* Chip ID for YUKON-Lite (Rev. A1-A3) */
+ #define CHIP_ID_YUKON_LP      0xb2    /* Chip ID for YUKON-LP */
++#define CHIP_ID_YUKON_XL      0xb3    /* Chip ID for YUKON-2 XL */
++#define CHIP_ID_YUKON_EC      0xb6    /* Chip ID for YUKON-2 EC */
++#define CHIP_ID_YUKON_FE      0xb7    /* Chip ID for YUKON-2 FE */
+ #define CHIP_REV_YU_LITE_A1   3               /* Chip Rev. for YUKON-Lite A1,A2 */
+ #define CHIP_REV_YU_LITE_A3   7               /* Chip Rev. for YUKON-Lite A3 */
++#define CHIP_REV_YU_EC_A1     0               /* Chip Rev. for Yukon-EC A1/A0 */
++#define CHIP_REV_YU_EC_A2     1               /* Chip Rev. for Yukon-EC A2 */
++#define CHIP_REV_YU_EC_A3     2               /* Chip Rev. for Yukon-EC A3 */
++
++/*    B2_Y2_CLK_GATE   8 bit  Clock Gating (Yukon-2 only) */
++#define Y2_STATUS_LNK2_INAC   BIT_7S  /* Status Link 2 inactiv (0 = activ) */
++#define Y2_CLK_GAT_LNK2_DIS   BIT_6S  /* Disable clock gating Link 2 */
++#define Y2_COR_CLK_LNK2_DIS   BIT_5S  /* Disable Core clock Link 2 */
++#define Y2_PCI_CLK_LNK2_DIS   BIT_4S  /* Disable PCI clock Link 2 */
++#define Y2_STATUS_LNK1_INAC   BIT_3S  /* Status Link 1 inactiv (0 = activ) */
++#define Y2_CLK_GAT_LNK1_DIS   BIT_2S  /* Disable clock gating Link 1 */
++#define Y2_COR_CLK_LNK1_DIS   BIT_1S  /* Disable Core clock Link 1 */
++#define Y2_PCI_CLK_LNK1_DIS   BIT_0S  /* Disable PCI clock Link 1 */
++
++/*    B2_Y2_HW_RES    8 bit   HW Resources (Yukon-2 only) */
++                                                              /* Bit 7.. 5:   reserved */
++#define CFG_LED_MODE_MSK      (7<<2)  /* Bit  4.. 2:  LED Mode Mask */
++#define CFG_LINK_2_AVAIL      BIT_1S  /* Link 2 available */
++#define CFG_LINK_1_AVAIL      BIT_0S  /* Link 1 available */
++
++#define CFG_LED_MODE(x)               (((x) & CFG_LED_MODE_MSK) >> 2)
++#define CFG_DUAL_MAC_MSK      (CFG_LINK_2_AVAIL | CFG_LINK_1_AVAIL)
++
++#define CFG_LED_SING_ACT_LNK  0       /* Single LED ACT/LNK mode */
++#define CFG_LED_DUAL_ACT_LNK  1       /* Dual   LED ACT/LNK mode */
++
++/*    B2_E_3                   8 bit  lower 4 bits used for HW self test result */
++#define B2_E3_RES_MASK        0x0f
++
+ /*    B2_FAR                  32 bit  Flash-Prom Addr Reg/Cnt */
+-#define FAR_ADDR              0x1ffffL        /* Bit 16.. 0:  FPROM Address mask */
++#define FAR_ADDR              0x1ffffL        /* Bit 16.. 0:  FPROM Address Mask */
++
++/*    B2_Y2_CLK_CTRL  32 bit  Core Clock Frequency Control Register (Yukon-2/EC) */
++                                                              /* Bit 31..24:  reserved */
++/* Yukon-EC/FE */
++#define Y2_CLK_DIV_VAL_MSK    (0xffL<<16)     /* Bit 23..16:  Clock Divisor Value */
++#define Y2_CLK_DIV_VAL(x)     (SHIFT16(x) & Y2_CLK_DIV_VAL_MSK)
++/* Yukon-2 */
++#define Y2_CLK_DIV_VAL2_MSK   (7L<<21)        /* Bit 23..21:  Clock Divisor Value */
++#define Y2_CLK_SELECT2_MSK    (0x1fL<<16)     /* Bit 20..16:  Clock Select */
++#define Y2_CLK_DIV_VAL_2(x)   (SHIFT21(x) & Y2_CLK_DIV_VAL2_MSK)
++#define Y2_CLK_SEL_VAL_2(x)   (SHIFT16(x) & Y2_CLK_SELECT2_MSK)
++                                                              /* Bit 15.. 2:  reserved */
++#define Y2_CLK_DIV_ENA                BIT_1S  /* Enable  Core Clock Division */
++#define Y2_CLK_DIV_DIS                BIT_0S  /* Disable Core Clock Division */
+ /*    B2_LD_CTRL               8 bit  EPROM loader control register */
+ /*    Bits are currently reserved */
+@@ -960,9 +1359,6 @@
+ #define DPT_START             BIT_1S  /* Start Descriptor Poll Timer */
+ #define DPT_STOP              BIT_0S  /* Stop  Descriptor Poll Timer */
+-/*    B2_E_3                   8 bit  lower 4 bits used for HW self test result */
+-#define B2_E3_RES_MASK        0x0f
+-
+ /*    B2_TST_CTRL1     8 bit  Test Control Register 1 */
+ #define TST_FRC_DPERR_MR      BIT_7S  /* force DATAPERR on MST RD */
+ #define TST_FRC_DPERR_MW      BIT_6S  /* force DATAPERR on MST WR */
+@@ -982,7 +1378,7 @@
+ #define TST_FRC_APERR_2M64    BIT_0S  /* AddrPERR on 2. phase */
+ /*    B2_GP_IO                32 bit  General Purpose I/O Register */
+-                                                      /* Bit 31..26:  reserved */
++                                              /* Bit 31..26:  reserved */
+ #define GP_DIR_9      BIT_25  /* IO_9 direct, 0=In/1=Out */
+ #define GP_DIR_8      BIT_24  /* IO_8 direct, 0=In/1=Out */
+ #define GP_DIR_7      BIT_23  /* IO_7 direct, 0=In/1=Out */
+@@ -1032,10 +1428,8 @@
+ #define I2C_DATA              BIT_1S          /* I2C Data Port        */
+ #define I2C_CLK                       BIT_0S          /* I2C Clock Port       */
+-/*
+- * I2C Address
+- */
+-#define I2C_SENS_ADDR LM80_ADDR       /* I2C Sensor Address, (Volt and Temp)*/
++/* I2C Address */
++#define I2C_SENS_ADDR LM80_ADDR       /* I2C Sensor Address (Volt and Temp) */
+ /*    B2_BSC_CTRL              8 bit  Blink Source Counter Control */
+@@ -1052,16 +1446,20 @@
+ #define BSC_T_OFF     BIT_1S          /* Test mode off */
+ #define BSC_T_STEP    BIT_0S          /* Test step */
++/*    Y2_PEX_PHY_ADDR/DATA            PEX PHY address and data reg  (Yukon-2 only) */
++#define PEX_RD_ACCESS BIT_31  /* Access Mode Read = 1, Write = 0 */
++#define PEX_DB_ACCESS BIT_30  /* Access to debug register */
++
+ /*    B3_RAM_ADDR             32 bit  RAM Address, to read or write */
+                                       /* Bit 31..19:  reserved */
+ #define RAM_ADR_RAN   0x0007ffffL     /* Bit 18.. 0:  RAM Address Range */
+ /* RAM Interface Registers */
+-/*    B3_RI_CTRL              16 bit  RAM Iface Control Register */
++/*    B3_RI_CTRL              16 bit  RAM Interface Control Register */
+                                                               /* Bit 15..10:  reserved */
+-#define RI_CLR_RD_PERR        BIT_9S  /* Clear IRQ RAM Read Parity Err */
+-#define RI_CLR_WR_PERR        BIT_8S  /* Clear IRQ RAM Write Parity Err*/
++#define RI_CLR_RD_PERR        BIT_9S  /* Clear IRQ RAM Read  Parity Err */
++#define RI_CLR_WR_PERR        BIT_8S  /* Clear IRQ RAM Write Parity Err */
+                                                               /* Bit  7.. 2:  reserved */
+ #define RI_RST_CLR            BIT_1S  /* Clear RAM Interface Reset */
+ #define RI_RST_SET            BIT_0S  /* Set   RAM Interface Reset */
+@@ -1171,7 +1569,7 @@
+                                                               /* Bit 31..16:  reserved */
+ #define BC_MAX                        0xffff  /* Bit 15.. 0:  Byte counter */
+-/* BMU Control Status Registers */
++/* BMU Control / Status Registers     (Yukon and Genesis) */
+ /*    B0_R1_CSR               32 bit  BMU Ctrl/Stat Rx Queue 1 */
+ /*    B0_R2_CSR               32 bit  BMU Ctrl/Stat Rx Queue 2 */
+ /*    B0_XA1_CSR              32 bit  BMU Ctrl/Stat Sync Tx Queue 1 */
+@@ -1212,6 +1610,41 @@
+                                               CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\
+                                               CSR_TRANS_RUN)
++/* Rx BMU Control / Status Registers (Yukon-2) */
++#define BMU_IDLE                      BIT_31  /* BMU Idle State */
++#define BMU_RX_TCP_PKT                BIT_30  /* Rx TCP Packet (when RSS Hash enabled) */
++#define BMU_RX_IP_PKT         BIT_29  /* Rx IP  Packet (when RSS Hash enabled) */
++                                                              /* Bit 28..16:  reserved */
++#define BMU_ENA_RX_RSS_HASH   BIT_15  /* Enable  Rx RSS Hash */
++#define BMU_DIS_RX_RSS_HASH   BIT_14  /* Disable Rx RSS Hash */
++#define BMU_ENA_RX_CHKSUM     BIT_13  /* Enable  Rx TCP/IP Checksum Check */
++#define BMU_DIS_RX_CHKSUM     BIT_12  /* Disable Rx TCP/IP Checksum Check */
++#define BMU_CLR_IRQ_PAR               BIT_11  /* Clear IRQ on Parity errors (Rx) */
++#define BMU_CLR_IRQ_TCP               BIT_11  /* Clear IRQ on TCP segmen. error (Tx) */
++#define BMU_CLR_IRQ_CHK               BIT_10  /* Clear IRQ Check */
++#define BMU_STOP                      BIT_9   /* Stop  Rx/Tx Queue */
++#define BMU_START                     BIT_8   /* Start Rx/Tx Queue */
++#define BMU_FIFO_OP_ON                BIT_7   /* FIFO Operational On */
++#define BMU_FIFO_OP_OFF       BIT_6   /* FIFO Operational Off */
++#define BMU_FIFO_ENA          BIT_5   /* Enable FIFO */
++#define BMU_FIFO_RST          BIT_4   /* Reset  FIFO */
++#define BMU_OP_ON                     BIT_3   /* BMU Operational On */
++#define BMU_OP_OFF                    BIT_2   /* BMU Operational Off */
++#define BMU_RST_CLR                   BIT_1   /* Clear BMU Reset (Enable) */
++#define BMU_RST_SET                   BIT_0   /* Set   BMU Reset */
++
++#define BMU_CLR_RESET         (BMU_FIFO_RST | BMU_OP_OFF | BMU_RST_CLR)
++#define BMU_OPER_INIT         (BMU_CLR_IRQ_PAR | BMU_CLR_IRQ_CHK | BMU_START | \
++                                                      BMU_FIFO_ENA | BMU_OP_ON)
++                                                      
++/* Tx BMU Control / Status Registers (Yukon-2) */
++                                                              /* Bit 31: same as for Rx */
++                                                              /* Bit 30..14:  reserved */
++#define BMU_TX_IPIDINCR_ON    BIT_13  /* Enable  IP ID Increment */
++#define BMU_TX_IPIDINCR_OFF   BIT_12  /* Disable IP ID Increment */
++#define BMU_TX_CLR_IRQ_TCP    BIT_11  /* Clear IRQ on TCP segm. length mism. */
++                                                              /* Bit 10..0: same as for Rx */
++
+ /*    Q_F                             32 bit  Flag Register */
+                                                                       /* Bit 31..28:  reserved */
+ #define F_ALM_FULL            BIT_27          /* Rx FIFO: almost full */
+@@ -1260,6 +1693,13 @@
+                                                               /* Bit  3:      reserved */
+ #define T3_VRAM_MSK           7               /* Bit  2.. 0:  Virtual RAM Buffer Address */
++/* Queue Prefetch Unit Offsets, use Y2_PREF_Q_ADDR() to address (Yukon-2 only)*/
++/* PREF_UNIT_CTRL_REG 32 bit  Prefetch Control register */
++#define PREF_UNIT_OP_ON               BIT_3   /* prefetch unit operational */
++#define PREF_UNIT_OP_OFF      BIT_2   /* prefetch unit not operational */
++#define PREF_UNIT_RST_CLR     BIT_1   /* Clear Prefetch Unit Reset */
++#define PREF_UNIT_RST_SET     BIT_0   /* Set   Prefetch Unit Reset */
++
+ /* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
+ /*    RB_START                32 bit  RAM Buffer Start Address */
+ /*    RB_END                  32 bit  RAM Buffer End Address */
+@@ -1275,24 +1715,24 @@
+ #define RB_MSK        0x0007ffff      /* Bit 18.. 0:  RAM Buffer Pointer Bits */
+ /*    RB_TST2                  8 bit  RAM Buffer Test Register 2 */
+-                                                              /* Bit 7.. 4:   reserved */
+-#define RB_PC_DEC             BIT_3S  /* Packet Counter Decrem */
++                                                      /* Bit 7.. 4:   reserved */
++#define RB_PC_DEC             BIT_3S  /* Packet Counter Decrement */
+ #define RB_PC_T_ON            BIT_2S  /* Packet Counter Test On */
+-#define RB_PC_T_OFF           BIT_1S  /* Packet Counter Tst Off */
+-#define RB_PC_INC             BIT_0S  /* Packet Counter Increm */
++#define RB_PC_T_OFF           BIT_1S  /* Packet Counter Test Off */
++#define RB_PC_INC             BIT_0S  /* Packet Counter Increment */
+ /*    RB_TST1                  8 bit  RAM Buffer Test Register 1 */
+                                                       /* Bit 7:       reserved */
+ #define RB_WP_T_ON            BIT_6S  /* Write Pointer Test On */
+ #define RB_WP_T_OFF           BIT_5S  /* Write Pointer Test Off */
+-#define RB_WP_INC             BIT_4S  /* Write Pointer Increm */
++#define RB_WP_INC             BIT_4S  /* Write Pointer Increment */
+                                                               /* Bit 3:       reserved */
+ #define RB_RP_T_ON            BIT_2S  /* Read Pointer Test On */
+ #define RB_RP_T_OFF           BIT_1S  /* Read Pointer Test Off */
+-#define RB_RP_DEC             BIT_0S  /* Read Pointer Decrement */
++#define RB_RP_INC             BIT_0S  /* Read Pointer Increment */
+ /*    RB_CTRL                  8 bit  RAM Buffer Control Register */
+-                                                              /* Bit 7.. 6:   reserved */
++                                                      /* Bit 7.. 6:   reserved */
+ #define RB_ENA_STFWD  BIT_5S  /* Enable  Store & Forward */
+ #define RB_DIS_STFWD  BIT_4S  /* Disable Store & Forward */
+ #define RB_ENA_OP_MD  BIT_3S  /* Enable  Operation Mode */
+@@ -1300,16 +1740,31 @@
+ #define RB_RST_CLR            BIT_1S  /* Clear RAM Buf STM Reset */
+ #define RB_RST_SET            BIT_0S  /* Set   RAM Buf STM Reset */
++/* Yukon-2 */
++                                                      /* Bit 31..20:  reserved */
++#define RB_CNT_DOWN           BIT_19  /* Packet Counter Decrement */
++#define RB_CNT_TST_ON BIT_18  /* Packet Counter Test On */
++#define RB_CNT_TST_OFF        BIT_17  /* Packet Counter Test Off */
++#define RB_CNT_UP             BIT_16  /* Packet Counter Increment */
++                                                      /* Bit 15:      reserved */
++#define RB_WP_TST_ON  BIT_14  /* Write Pointer Test On */
++#define RB_WP_TST_OFF BIT_13  /* Write Pointer Test Off */
++#define RB_WP_UP              BIT_12  /* Write Pointer Increment  */
++                                                      /* Bit 11:      reserved */
++#define RB_RP_TST_ON  BIT_10  /* Read Pointer Test On */
++#define RB_RP_TST_OFF BIT_9   /* Read Pointer Test Off */
++#define RB_RP_UP              BIT_8   /* Read Pointer Increment */
++
+ /* Receive and Transmit MAC FIFO Registers (GENESIS only) */
+ /*    RX_MFF_EA               32 bit  Receive MAC FIFO End Address */
+-/*    RX_MFF_WP               32 bit  Receive MAC FIFO Write Pointer */
++/*    RX_MFF_WP               32 bit  Receive MAC FIFO Write Pointer */
+ /*    RX_MFF_RP               32 bit  Receive MAC FIFO Read Pointer */
+ /*    RX_MFF_PC               32 bit  Receive MAC FIFO Packet Counter */
+ /*    RX_MFF_LEV              32 bit  Receive MAC FIFO Level */
+ /*    TX_MFF_EA               32 bit  Transmit MAC FIFO End Address */
+-/*    TX_MFF_WP               32 bit  Transmit MAC FIFO Write Pointer */
++/*    TX_MFF_WP               32 bit  Transmit MAC FIFO Write Pointer */
+ /*    TX_MFF_WSP              32 bit  Transmit MAC FIFO WR Shadow Pointer */
+ /*    TX_MFF_RP               32 bit  Transmit MAC FIFO Read Pointer */
+ /*    TX_MFF_PC               32 bit  Transmit MAC FIFO Packet Cnt */
+@@ -1359,9 +1814,9 @@
+ /*    RX_MFF_TST2              8 bit  Receive MAC FIFO Test Register 2 */
+ /*    TX_MFF_TST2              8 bit  Transmit MAC FIFO Test Register 2 */
+                                                               /* Bit 7:       reserved */
+-#define MFF_WSP_T_ON  BIT_6S  /* Tx: Write Shadow Ptr TestOn */
+-#define MFF_WSP_T_OFF BIT_5S  /* Tx: Write Shadow Ptr TstOff */
+-#define MFF_WSP_INC           BIT_4S  /* Tx: Write Shadow Ptr Increment */
++#define MFF_WSP_T_ON  BIT_6S  /* Tx: Write Shadow Pointer Test On */
++#define MFF_WSP_T_OFF BIT_5S  /* Tx: Write Shadow Pointer Test Off */
++#define MFF_WSP_INC           BIT_4S  /* Tx: Write Shadow Pointer Increment */
+ #define MFF_PC_DEC            BIT_3S  /* Packet Counter Decrement */
+ #define MFF_PC_T_ON           BIT_2S  /* Packet Counter Test On */
+ #define MFF_PC_T_OFF  BIT_1S  /* Packet Counter Test Off */
+@@ -1372,7 +1827,7 @@
+                                       /* Bit 7:       reserved */
+ #define MFF_WP_T_ON           BIT_6S  /* Write Pointer Test On */
+ #define MFF_WP_T_OFF  BIT_5S  /* Write Pointer Test Off */
+-#define MFF_WP_INC            BIT_4S  /* Write Pointer Increm */
++#define MFF_WP_INC            BIT_4S  /* Write Pointer Increment */
+                                                       /* Bit 3:       reserved */
+ #define MFF_RP_T_ON           BIT_2S  /* Read Pointer Test On */
+ #define MFF_RP_T_OFF  BIT_1S  /* Read Pointer Test Off */
+@@ -1391,12 +1846,16 @@
+ /*    RX_LED_CTRL              8 bit  Receive LED Cnt Control Reg */
+ /*    TX_LED_CTRL              8 bit  Transmit LED Cnt Control Reg */
++                                                      /* Bit 7.. 3:   reserved */
++#define LED_START             BIT_2S  /* Start Counter */
++#define LED_STOP              BIT_1S  /* Stop Counter */
++#define LED_STATE             BIT_0S  /* Rx/Tx: LED State, 1=LED On */
++
+ /*    LNK_SYNC_CTRL    8 bit  Link Sync Cnt Control Register */
+                                                       /* Bit 7.. 3:   reserved */
+-#define LED_START             BIT_2S  /* Start Timer */
+-#define LED_STOP              BIT_1S  /* Stop Timer */
+-#define LED_STATE             BIT_0S  /* Rx/Tx: LED State, 1=LED on */
+-#define LED_CLR_IRQ           BIT_0S  /* Lnk:         Clear Link IRQ */
++#define LNK_START             BIT_2S  /* Start Counter */
++#define LNK_STOP              BIT_1S  /* Stop Counter */
++#define LNK_CLR_IRQ           BIT_0S  /* Clear Link IRQ */
+ /*    RX_LED_TST               8 bit  Receive LED Cnt Test Register */
+ /*    TX_LED_TST               8 bit  Transmit LED Cnt Test Register */
+@@ -1407,86 +1866,138 @@
+ #define LED_T_STEP            BIT_0S  /* LED Counter Step */
+ /*    LNK_LED_REG              8 bit  Link LED Register */
+-                                                              /* Bit 7.. 6:   reserved */
++                                                      /* Bit 7.. 6:   reserved */
+ #define LED_BLK_ON            BIT_5S  /* Link LED Blinking On */
+ #define LED_BLK_OFF           BIT_4S  /* Link LED Blinking Off */
+ #define LED_SYNC_ON           BIT_3S  /* Use Sync Wire to switch LED */
+ #define LED_SYNC_OFF  BIT_2S  /* Disable Sync Wire Input */
+-#define LED_ON                        BIT_1S  /* switch LED on */
+-#define LED_OFF                       BIT_0S  /* switch LED off */
++#define LED_ON                        BIT_1S  /* Switch LED On */
++#define LED_OFF                       BIT_0S  /* Switch LED Off */
+ /*    Receive and Transmit GMAC FIFO Registers (YUKON only) */
+ /*    RX_GMF_EA               32 bit  Rx GMAC FIFO End Address */
+ /*    RX_GMF_AF_THR   32 bit  Rx GMAC FIFO Almost Full Thresh. */
+-/*    RX_GMF_WP               32 bit  Rx GMAC FIFO Write Pointer */
+-/*    RX_GMF_WLEV             32 bit  Rx GMAC FIFO Write Level */
+-/*    RX_GMF_RP               32 bit  Rx GMAC FIFO Read Pointer */
+-/*    RX_GMF_RLEV             32 bit  Rx GMAC FIFO Read Level */
++/*    RX_GMF_WP               32 bit  Rx GMAC FIFO Write Pointer */
++/*    RX_GMF_WLEV             32 bit  Rx GMAC FIFO Write Level */
++/*    RX_GMF_RP               32 bit  Rx GMAC FIFO Read Pointer */
++/*    RX_GMF_RLEV             32 bit  Rx GMAC FIFO Read Level */
+ /*    TX_GMF_EA               32 bit  Tx GMAC FIFO End Address */
+ /*    TX_GMF_AE_THR   32 bit  Tx GMAC FIFO Almost Empty Thresh.*/
+-/*    TX_GMF_WP               32 bit  Tx GMAC FIFO Write Pointer */
+-/*    TX_GMF_WSP              32 bit  Tx GMAC FIFO Write Shadow Ptr. */
+-/*    TX_GMF_WLEV             32 bit  Tx GMAC FIFO Write Level */
+-/*    TX_GMF_RP               32 bit  Tx GMAC FIFO Read Pointer */
+-/*    TX_GMF_RSTP             32 bit  Tx GMAC FIFO Restart Pointer */
+-/*    TX_GMF_RLEV             32 bit  Tx GMAC FIFO Read Level */
++/*    TX_GMF_WP               32 bit  Tx GMAC FIFO Write Pointer */
++/*    TX_GMF_WSP              32 bit  Tx GMAC FIFO Write Shadow Pointer */
++/*    TX_GMF_WLEV             32 bit  Tx GMAC FIFO Write Level */
++/*    TX_GMF_RP               32 bit  Tx GMAC FIFO Read Pointer */
++/*    TX_GMF_RSTP             32 bit  Tx GMAC FIFO Restart Pointer */
++/*    TX_GMF_RLEV             32 bit  Tx GMAC FIFO Read Level */
+ /*    RX_GMF_CTRL_T   32 bit  Rx GMAC FIFO Control/Test */
+-                                              /* Bits 31..15: reserved */
+-#define GMF_WP_TST_ON BIT_14          /* Write Pointer Test On */
+-#define GMF_WP_TST_OFF        BIT_13          /* Write Pointer Test Off */
+-#define GMF_WP_STEP           BIT_12          /* Write Pointer Step/Increment */
++                                              /* Bit 31..28 reserved */
++#define RX_TRUNC_ON           BIT_27  /* enable  packet truncation */
++#define RX_TRUNC_OFF  BIT_26  /* disable packet truncation */
++#define RX_VLAN_STRIP_ON      BIT_25  /* enable  VLAN stripping */
++#define RX_VLAN_STRIP_OFF     BIT_24  /* disable VLAN stripping */
++                                              /* Bit 23..15 reserved */
++#define GMF_WP_TST_ON BIT_14  /* Write Pointer Test On */
++#define GMF_WP_TST_OFF        BIT_13  /* Write Pointer Test Off */
++#define GMF_WP_STEP           BIT_12  /* Write Pointer Step/Increment */
+                                               /* Bit 11:      reserved */
+-#define GMF_RP_TST_ON BIT_10          /* Read Pointer Test On */
+-#define GMF_RP_TST_OFF        BIT_9           /* Read Pointer Test Off */
+-#define GMF_RP_STEP           BIT_8           /* Read Pointer Step/Increment */
+-#define GMF_RX_F_FL_ON        BIT_7           /* Rx FIFO Flush Mode On */
+-#define GMF_RX_F_FL_OFF       BIT_6           /* Rx FIFO Flush Mode Off */
+-#define GMF_CLI_RX_FO BIT_5           /* Clear IRQ Rx FIFO Overrun */
+-#define GMF_CLI_RX_FC BIT_4           /* Clear IRQ Rx Frame Complete */
+-#define GMF_OPER_ON           BIT_3           /* Operational Mode On */
+-#define GMF_OPER_OFF  BIT_2           /* Operational Mode Off */
+-#define GMF_RST_CLR           BIT_1           /* Clear GMAC FIFO Reset */
+-#define GMF_RST_SET           BIT_0           /* Set   GMAC FIFO Reset */
+-
+-/*    TX_GMF_CTRL_T   32 bit  Tx GMAC FIFO Control/Test */
+-                                              /* Bits 31..19: reserved */
+-#define GMF_WSP_TST_ON        BIT_18          /* Write Shadow Pointer Test On */
+-#define GMF_WSP_TST_OFF       BIT_17          /* Write Shadow Pointer Test Off */
+-#define GMF_WSP_STEP  BIT_16          /* Write Shadow Pointer Step/Increment */
+-                                              /* Bits 15..7: same as for RX_GMF_CTRL_T */
+-#define GMF_CLI_TX_FU BIT_6           /* Clear IRQ Tx FIFO Underrun */
+-#define GMF_CLI_TX_FC BIT_5           /* Clear IRQ Tx Frame Complete */
+-#define GMF_CLI_TX_PE BIT_4           /* Clear IRQ Tx Parity Error */
++#define GMF_RP_TST_ON BIT_10  /* Read Pointer Test On */
++#define GMF_RP_TST_OFF        BIT_9   /* Read Pointer Test Off */
++#define GMF_RP_STEP           BIT_8   /* Read Pointer Step/Increment */
++#define GMF_RX_F_FL_ON        BIT_7   /* Rx FIFO Flush Mode On */
++#define GMF_RX_F_FL_OFF       BIT_6   /* Rx FIFO Flush Mode Off */
++#define GMF_CLI_RX_FO BIT_5   /* Clear IRQ Rx FIFO Overrun */
++#define GMF_CLI_RX_FC BIT_4   /* Clear IRQ Rx Frame Complete */
++#define GMF_OPER_ON           BIT_3   /* Operational Mode On */
++#define GMF_OPER_OFF  BIT_2   /* Operational Mode Off */
++#define GMF_RST_CLR           BIT_1   /* Clear GMAC FIFO Reset */
++#define GMF_RST_SET           BIT_0   /* Set   GMAC FIFO Reset */
++
++/*    TX_GMF_CTRL_T   32 bit  Tx GMAC FIFO Control/Test (YUKON and Yukon-2) */
++                                              /* Bits 31..26: reserved */
++#define TX_VLAN_TAG_ON        BIT_25  /* enable  VLAN tagging */
++#define TX_VLAN_TAG_OFF       BIT_24  /* disable VLAN tagging */
++                                              /* Bits 23..19: reserved */
++#define GMF_WSP_TST_ON        BIT_18  /* Write Shadow Pointer Test On */
++#define GMF_WSP_TST_OFF       BIT_17  /* Write Shadow Pointer Test Off */
++#define GMF_WSP_STEP  BIT_16  /* Write Shadow Pointer Step/Increment */
++                                              /* Bits 15..8: same as for RX_GMF_CTRL_T */
++                                              /* Bit 7:       reserved */
++#define GMF_CLI_TX_FU BIT_6   /* Clear IRQ Tx FIFO Underrun */
++#define GMF_CLI_TX_FC BIT_5   /* Clear IRQ Tx Frame Complete */
++#define GMF_CLI_TX_PE BIT_4   /* Clear IRQ Tx Parity Error */
+                                               /* Bits 3..0: same as for RX_GMF_CTRL_T */
+ #define GMF_RX_CTRL_DEF               (GMF_OPER_ON | GMF_RX_F_FL_ON)
+ #define GMF_TX_CTRL_DEF               GMF_OPER_ON
++#define RX_GMF_AF_THR_MIN     0x0c    /* Rx GMAC FIFO Almost Full Thresh. min. */
+ #define RX_GMF_FL_THR_DEF     0x0a    /* Rx GMAC FIFO Flush Threshold default */
+ /*    GMAC_TI_ST_CTRL  8 bit  Time Stamp Timer Ctrl Reg (YUKON only) */
+-                                                              /* Bit 7.. 3:   reserved */
+-#define GMT_ST_START  BIT_2S          /* Start Time Stamp Timer */
+-#define GMT_ST_STOP           BIT_1S          /* Stop  Time Stamp Timer */
+-#define GMT_ST_CLR_IRQ        BIT_0S          /* Clear Time Stamp Timer IRQ */
+-
++                                                      /* Bit 7.. 3:   reserved */
++#define GMT_ST_START  BIT_2S  /* Start Time Stamp Timer */
++#define GMT_ST_STOP           BIT_1S  /* Stop  Time Stamp Timer */
++#define GMT_ST_CLR_IRQ        BIT_0S  /* Clear Time Stamp Timer IRQ */
++
++/*    POLL_CTRL               32 bit  Polling Unit control register (Yukon-2 only) */
++                                                      /* Bit 31.. 6:  reserved */
++#define PC_CLR_IRQ_CHK        BIT_5   /* Clear IRQ Check */
++#define PC_POLL_RQ            BIT_4   /* Poll Request Start */
++#define PC_POLL_OP_ON BIT_3   /* Operational Mode On */
++#define PC_POLL_OP_OFF        BIT_2   /* Operational Mode Off */
++#define PC_POLL_RST_CLR       BIT_1   /* Clear Polling Unit Reset (Enable) */
++#define PC_POLL_RST_SET       BIT_0   /* Set   Polling Unit Reset */
++
++
++/* The bit definition of the following registers is still missing! */
++/* B28_Y2_SMB_CONFIG          32 bit  ASF SMBus Config Register */
++/* B28_Y2_SMB_CSD_REG         32 bit  ASF SMB Control/Status/Data */
++/* B28_Y2_ASF_IRQ_V_BASE      32 bit  ASF IRQ Vector Base */
++
++/* B28_Y2_ASF_STAT_CMD                32 bit  ASF Status and Command Reg */
++/* This register is used by the host driver software */
++                                              /* Bit 31:5     reserved */
++#define Y2_ASF_OS_PRES        BIT_4S  /* ASF operation system present */
++#define Y2_ASF_RESET  BIT_3S  /* ASF system in reset state */
++#define Y2_ASF_RUNNING        BIT_2S  /* ASF system operational */
++#define Y2_ASF_CLR_HSTI       BIT_1S  /* Clear ASF IRQ */
++#define Y2_ASF_IRQ            BIT_0S  /* Issue an IRQ to ASF system */
++
++#define Y2_ASF_UC_STATE       (3<<2)  /* ASF uC State */
++#define Y2_ASF_CLK_HALT       0               /* ASF system clock stopped */
++
++/* B28_Y2_ASF_HOST_COM        32 bit  ASF Host Communication Reg */
++/* This register is used by the ASF firmware */
++                                              /* Bit 31:2     reserved */
++#define Y2_ASF_CLR_ASFI       BIT_1   /* Clear host IRQ */
++#define Y2_ASF_HOST_IRQ       BIT_0   /* Issue an IRQ to HOST system */
++
++
++/*    STAT_CTRL               32 bit  Status BMU control register (Yukon-2 only) */
++                                                      /* Bit  7.. 5:  reserved */
++#define SC_STAT_CLR_IRQ       BIT_4   /* Status Burst IRQ clear */
++#define SC_STAT_OP_ON BIT_3   /* Operational Mode On */
++#define SC_STAT_OP_OFF        BIT_2   /* Operational Mode Off */
++#define SC_STAT_RST_CLR       BIT_1   /* Clear Status Unit Reset (Enable) */
++#define SC_STAT_RST_SET       BIT_0   /* Set   Status Unit Reset */
++      
+ /*    GMAC_CTRL               32 bit  GMAC Control Reg (YUKON only) */
+                                               /* Bits 31.. 8: reserved */
+-#define GMC_H_BURST_ON        BIT_7           /* Half Duplex Burst Mode On */
+-#define GMC_H_BURST_OFF       BIT_6           /* Half Duplex Burst Mode Off */
+-#define GMC_F_LOOPB_ON        BIT_5           /* FIFO Loopback On */
+-#define GMC_F_LOOPB_OFF       BIT_4           /* FIFO Loopback Off */
+-#define GMC_PAUSE_ON  BIT_3           /* Pause On */
+-#define GMC_PAUSE_OFF BIT_2           /* Pause Off */
+-#define GMC_RST_CLR           BIT_1           /* Clear GMAC Reset */
+-#define GMC_RST_SET           BIT_0           /* Set   GMAC Reset */
++#define GMC_H_BURST_ON        BIT_7   /* Half Duplex Burst Mode On */
++#define GMC_H_BURST_OFF       BIT_6   /* Half Duplex Burst Mode Off */
++#define GMC_F_LOOPB_ON        BIT_5   /* FIFO Loopback On */
++#define GMC_F_LOOPB_OFF       BIT_4   /* FIFO Loopback Off */
++#define GMC_PAUSE_ON  BIT_3   /* Pause On */
++#define GMC_PAUSE_OFF BIT_2   /* Pause Off */
++#define GMC_RST_CLR           BIT_1   /* Clear GMAC Reset */
++#define GMC_RST_SET           BIT_0   /* Set   GMAC Reset */
+ /*    GPHY_CTRL               32 bit  GPHY Control Reg (YUKON only) */
+                                               /* Bits 31..29: reserved */
+ #define GPC_SEL_BDT           BIT_28  /* Select Bi-Dir. Transfer for MDC/MDIO */
+-#define GPC_INT_POL_HI        BIT_27  /* IRQ Polarity is Active HIGH */
++#define GPC_INT_POL           BIT_27  /* IRQ Polarity is Active Low */
+ #define GPC_75_OHM            BIT_26  /* Use 75 Ohm Termination instead of 50 */
+ #define GPC_DIS_FC            BIT_25  /* Disable Automatic Fiber/Copper Detection */
+ #define GPC_DIS_SLEEP BIT_24  /* Disable Energy Detect */
+@@ -1540,14 +2051,14 @@
+ /*    GMAC_IRQ_SRC     8 bit  GMAC Interrupt Source Reg (YUKON only) */
+ /*    GMAC_IRQ_MSK     8 bit  GMAC Interrupt Mask   Reg (YUKON only) */
+-#define GM_IS_TX_CO_OV        BIT_5           /* Transmit Counter Overflow IRQ */
+-#define GM_IS_RX_CO_OV        BIT_4           /* Receive Counter Overflow IRQ */
+-#define GM_IS_TX_FF_UR        BIT_3           /* Transmit FIFO Underrun */
+-#define GM_IS_TX_COMPL        BIT_2           /* Frame Transmission Complete */
+-#define GM_IS_RX_FF_OR        BIT_1           /* Receive FIFO Overrun */
+-#define GM_IS_RX_COMPL        BIT_0           /* Frame Reception Complete */
++#define GM_IS_RX_CO_OV        BIT_5S          /* Receive Counter Overflow IRQ */
++#define GM_IS_TX_CO_OV        BIT_4S          /* Transmit Counter Overflow IRQ */
++#define GM_IS_TX_FF_UR        BIT_3S          /* Transmit FIFO Underrun */
++#define GM_IS_TX_COMPL        BIT_2S          /* Frame Transmission Complete */
++#define GM_IS_RX_FF_OR        BIT_1S          /* Receive FIFO Overrun */
++#define GM_IS_RX_COMPL        BIT_0S          /* Frame Reception Complete */
+-#define GMAC_DEF_MSK  (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \
++#define GMAC_DEF_MSK  (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV | \
+                                               GM_IS_TX_FF_UR)
+ /*    GMAC_LINK_CTRL  16 bit  GMAC Link Control Reg (YUKON only) */
+@@ -1579,15 +2090,19 @@
+ #define WOL_CTL_DEFAULT                               \
+       (WOL_CTL_DIS_PME_ON_LINK_CHG |  \
+-      WOL_CTL_DIS_PME_ON_PATTERN |    \
+-      WOL_CTL_DIS_PME_ON_MAGIC_PKT |  \
+-      WOL_CTL_DIS_LINK_CHG_UNIT |             \
+-      WOL_CTL_DIS_PATTERN_UNIT |              \
+-      WOL_CTL_DIS_MAGIC_PKT_UNIT)
++       WOL_CTL_DIS_PME_ON_PATTERN |   \
++       WOL_CTL_DIS_PME_ON_MAGIC_PKT | \
++       WOL_CTL_DIS_LINK_CHG_UNIT |    \
++       WOL_CTL_DIS_PATTERN_UNIT |             \
++       WOL_CTL_DIS_MAGIC_PKT_UNIT)
+ /*    WOL_MATCH_CTL    8 bit  WOL Match Control Reg */
+ #define WOL_CTL_PATT_ENA(x)                           (BIT_0 << (x))
++/*    WOL_PATT_PME    8 bit   WOL PME Match Enable (Yukon-2) */
++#define WOL_PATT_FORCE_PME                            BIT_7   /* Generates a PME */
++#define WOL_PATT_MATCH_PME_ALL                        0x7f
++
+ #define SK_NUM_WOL_PATTERN            7
+ #define SK_PATTERN_PER_WORD           4
+ #define SK_BITMASK_PATTERN            7
+@@ -1606,17 +2121,17 @@
+       SK_U32  TxAdrLo;                /* Physical Tx Buffer Address lower dword */
+       SK_U32  TxAdrHi;                /* Physical Tx Buffer Address upper dword */
+       SK_U32  TxStat;                 /* Transmit Frame Status Word */
+-#ifndef       SK_USE_REV_DESC
++#ifndef SK_USE_REV_DESC
+       SK_U16  TxTcpOffs;              /* TCP Checksum Calculation Start Value */
+       SK_U16  TxRes1;                 /* 16 bit reserved field */
+       SK_U16  TxTcpWp;                /* TCP Checksum Write Position */
+       SK_U16  TxTcpSp;                /* TCP Checksum Calculation Start Position */
+-#else /* SK_USE_REV_DESC */
++#else  /* SK_USE_REV_DESC */
+       SK_U16  TxRes1;                 /* 16 bit reserved field */
+       SK_U16  TxTcpOffs;              /* TCP Checksum Calculation Start Value */
+       SK_U16  TxTcpSp;                /* TCP Checksum Calculation Start Position */
+       SK_U16  TxTcpWp;                /* TCP Checksum Write Position */
+-#endif        /* SK_USE_REV_DESC */
++#endif /* SK_USE_REV_DESC */
+       SK_U32  TxRes2;                 /* 32 bit reserved field */
+ } SK_HWTXD;
+@@ -1628,29 +2143,262 @@
+       SK_U32  RxAdrHi;                /* Physical Rx Buffer Address upper dword */
+       SK_U32  RxStat;                 /* Receive Frame Status Word */
+       SK_U32  RxTiSt;                 /* Receive Time Stamp (from XMAC on GENESIS) */
+-#ifndef       SK_USE_REV_DESC
+-      SK_U16  RxTcpSum1;              /* TCP Checksum 1 */
+-      SK_U16  RxTcpSum2;              /* TCP Checksum 2 */
++#ifndef SK_USE_REV_DESC
++      SK_U16  RxTcpSum1;              /* Rx TCP Checksum 1 */
++      SK_U16  RxTcpSum2;              /* Rx TCP Checksum 2 */
+       SK_U16  RxTcpSp1;               /* TCP Checksum Calculation Start Position 1 */
+       SK_U16  RxTcpSp2;               /* TCP Checksum Calculation Start Position 2 */
+-#else /* SK_USE_REV_DESC */
+-      SK_U16  RxTcpSum2;              /* TCP Checksum 2 */
+-      SK_U16  RxTcpSum1;              /* TCP Checksum 1 */
++#else  /* SK_USE_REV_DESC */
++      SK_U16  RxTcpSum2;              /* Rx TCP Checksum 2 */
++      SK_U16  RxTcpSum1;              /* Rx TCP Checksum 1 */
+       SK_U16  RxTcpSp2;               /* TCP Checksum Calculation Start Position 2 */
+       SK_U16  RxTcpSp1;               /* TCP Checksum Calculation Start Position 1 */
+-#endif        /* SK_USE_REV_DESC */
++#endif /* SK_USE_REV_DESC */
+ } SK_HWRXD;
+ /*
+  * Drivers which use the reverse descriptor feature (PCI_OUR_REG_2)
+  * should set the define SK_USE_REV_DESC.
+- * Structures are 'normaly' not endianess dependent. But in
+- * this case the SK_U16 fields are bound to bit positions inside the
+- * descriptor. RxTcpSum1 e.g. must start at bit 0 within the 6.th DWord.
++ * Structures are 'normally' not endianess dependent. But in this case
++ * the SK_U16 fields are bound to bit positions inside the descriptor.
++ * RxTcpSum1 e.g. must start at bit 0 within the 7.th DWord.
+  * The bit positions inside a DWord are of course endianess dependent and
+- * swaps if the DWord is swapped by the hardware.
++ * swap if the DWord is swapped by the hardware.
+  */
++/* YUKON-2 descriptors ******************************************************/
++
++typedef struct _TxChksum {
++#ifndef SK_USE_REV_DESC
++      SK_U16  TxTcpWp;                /* TCP Checksum Write Position */
++      SK_U16  TxTcpSp;                /* TCP Checksum Calculation Start Position */
++#else  /* SK_USE_REV_DESC */
++      SK_U16  TxTcpSp;                /* TCP Checksum Calculation Start Position */
++      SK_U16  TxTcpWp;                /* TCP Checksum Write Position */
++#endif /* SK_USE_REV_DESC */
++} SK_HWTXCS;
++
++typedef struct _LargeSend {
++#ifndef SK_USE_REV_DESC
++      SK_U16 Length;          /* Large Send Segment Length */
++      SK_U16 Reserved;        /* reserved */
++#else  /* SK_USE_REV_DESC */
++      SK_U16 Reserved;        /* reserved */
++      SK_U16 Length;          /* Large Send Segment Length */
++#endif /* SK_USE_REV_DESC */
++} SK_HWTXLS;
++
++typedef union u_HwTxBuf {
++      SK_U16  BufLen;         /* Tx Buffer Length */
++      SK_U16  VlanTag;        /* VLAN Tag */
++      SK_U16  InitCsum;       /* Init. Checksum */
++} SK_HWTXBUF;
++
++/* Tx List Element structure */
++typedef struct s_HwLeTx {
++      union {
++              SK_U32  BufAddr;        /* Tx LE Buffer Address high/low */
++              SK_HWTXCS ChkSum;       /* Tx LE TCP Checksum parameters */
++              SK_HWTXLS LargeSend;/* Large Send length */
++      } TxUn;
++#ifndef SK_USE_REV_DESC
++      SK_HWTXBUF      Send;
++      SK_U8   ControlFlags;   /* Tx LE Control field or Lock Number */
++      SK_U8   Opcode;                 /* Tx LE Opcode field */
++#else  /* SK_USE_REV_DESC */
++      SK_U8   Opcode;                 /* Tx LE Opcode field */
++      SK_U8   ControlFlags;   /* Tx LE Control field or Lock Number */
++      SK_HWTXBUF      Send;
++#endif /* SK_USE_REV_DESC */
++} SK_HWLETX;
++
++typedef struct _RxChkSum{
++#ifndef SK_USE_REV_DESC
++      SK_U16  RxTcpSp1;               /* TCP Checksum Calculation Start Position 1 */
++      SK_U16  RxTcpSp2;               /* TCP Checksum Calculation Start Position 2 */
++#else  /* SK_USE_REV_DESC */
++      SK_U16  RxTcpSp2;               /* TCP Checksum Calculation Start Position 2 */
++      SK_U16  RxTcpSp1;               /* TCP Checksum Calculation Start Position 1 */
++#endif /* SK_USE_REV_DESC */
++} SK_HWRXCS;
++
++/* Rx List Element structure */
++typedef struct s_HwLeRx {
++      union {
++              SK_U32  BufAddr;        /* Rx LE Buffer Address high/low */
++              SK_HWRXCS ChkSum;       /* Rx LE TCP Checksum parameters */
++      } RxUn;
++#ifndef SK_USE_REV_DESC
++      SK_U16  BufferLength;   /* Rx LE Buffer Length field */
++      SK_U8   ControlFlags;   /* Rx LE Control field */
++      SK_U8   Opcode;                 /* Rx LE Opcode field */
++#else  /* SK_USE_REV_DESC */
++      SK_U8   Opcode;                 /* Rx LE Opcode field */
++      SK_U8   ControlFlags;   /* Rx LE Control field */
++      SK_U16  BufferLength;   /* Rx LE Buffer Length field */
++#endif /* SK_USE_REV_DESC */
++} SK_HWLERX;
++
++typedef struct s_StRxTCPChkSum {
++#ifndef SK_USE_REV_DESC
++      SK_U16  RxTCPSum1;              /* Rx TCP Checksum 1 */
++      SK_U16  RxTCPSum2;              /* Rx TCP Checksum 2 */
++#else  /* SK_USE_REV_DESC */
++      SK_U16  RxTCPSum2;              /* Rx TCP Checksum 2 */
++      SK_U16  RxTCPSum1;              /* Rx TCP Checksum 1 */
++#endif /* SK_USE_REV_DESC */
++} SK_HWSTCS;
++
++typedef struct s_StRxRssFlags {
++#ifndef SK_USE_REV_DESC
++      SK_U8   FlagField;              /* contains TCP and IP flags */
++      SK_U8   reserved;               /* reserved */
++#else  /* SK_USE_REV_DESC */
++      SK_U8   reserved;               /* reserved */
++      SK_U8   FlagField;              /* contains TCP and IP flags */
++#endif /* SK_USE_REV_DESC */
++} SK_HWSTRSS;
++
++/* bit definition of RSS LE bit 32/33 (SK_HWSTRSS.FlagField) */
++                                                              /* bit 7..2 reserved */
++#define RSS_TCP_FLAG  BIT_1S  /* RSS value related to TCP area */
++#define RSS_IP_FLAG           BIT_0S  /* RSS value related to IP area */
++/* StRxRssValue is valid if at least RSS_IP_FLAG is set. */
++/* For protocol errors or other protocols an empty RSS LE is generated. */
++
++typedef union u_HwStBuf {
++      SK_U16  BufLen;         /* Rx Buffer Length */
++      SK_U16  VlanTag;        /* VLAN Tag */
++      SK_U16  StTxStatHi;     /* Tx Queue Status (high) */
++      SK_HWSTRSS      Rss;    /* Flag Field for TCP and IP protocol */
++} SK_HWSTBUF;
++
++/* Status List Element structure */
++typedef struct s_HwLeSt {
++      union {
++              SK_U32  StRxStatWord;   /* Rx Status Dword */
++              SK_U32  StRxTimeStamp;  /* Rx Timestamp */
++              SK_HWSTCS StRxTCPCSum;  /* Rx TCP Checksum */
++              SK_U32  StTxStatLow;    /* Tx Queue Status (low) */
++              SK_U32  StRxRssValue;   /* Rx RSS value */
++      } StUn;
++#ifndef SK_USE_REV_DESC
++      SK_HWSTBUF      Stat;
++      SK_U8   Link;                   /* Status LE Link field */
++      SK_U8   Opcode;                 /* Status LE Opcode field */
++#else  /* SK_USE_REV_DESC */
++      SK_U8   Opcode;                 /* Status LE Opcode field */
++      SK_U8   Link;                   /* Status LE Link field */
++      SK_HWSTBUF      Stat;
++#endif /* SK_USE_REV_DESC */
++} SK_HWLEST;
++
++/* Special Action List Element */
++typedef struct s_HwLeSa {
++#ifndef SK_USE_REV_DESC
++      SK_U16  TxAIdxVld;              /* Special Action LE TxA Put Index field */
++      SK_U16  TxSIdxVld;              /* Special Action LE TxS Put Index field */
++      SK_U16  RxIdxVld;               /* Special Action LE Rx Put Index field */
++      SK_U8   Link;                   /* Special Action LE Link field */
++      SK_U8   Opcode;                 /* Special Action LE Opcode field */
++#else  /* SK_USE_REV_DESC */
++      SK_U16  TxSIdxVld;              /* Special Action LE TxS Put Index field */
++      SK_U16  TxAIdxVld;              /* Special Action LE TxA Put Index field */
++      SK_U8   Opcode;                 /* Special Action LE Opcode field */
++      SK_U8   Link;                   /* Special Action LE Link field */
++      SK_U16  RxIdxVld;               /* Special Action LE Rx Put Index field */
++#endif /* SK_USE_REV_DESC */
++} SK_HWLESA;
++
++/* Common List Element union */
++typedef union u_HwLeTxRxSt {
++      /* Transmit List Element Structure */
++      SK_HWLETX Tx;
++      /* Receive List Element Structure */
++      SK_HWLERX Rx;
++      /* Status List Element Structure */
++      SK_HWLEST St;
++      /* Special Action List Element Structure */
++      SK_HWLESA Sa;
++      /* Full List Element */
++      SK_U64 Full;
++} SK_HWLE;
++
++/* mask and shift value to get Tx async queue status for port 1 */
++#define STLE_TXA1_MSKL                0x00000fff
++#define STLE_TXA1_SHIFTL      0
++
++/* mask and shift value to get Tx sync queue status for port 1 */
++#define STLE_TXS1_MSKL                0x00fff000
++#define STLE_TXS1_SHIFTL      12
++
++/* mask and shift value to get Tx async queue status for port 2 */
++#define STLE_TXA2_MSKL                0xff000000
++#define STLE_TXA2_SHIFTL      24
++#define STLE_TXA2_MSKH                0x000f
++/* this one shifts up */
++#define STLE_TXA2_SHIFTH      8
++
++/* mask and shift value to get Tx sync queue status for port 2 */
++#define STLE_TXS2_MSKL                0x00000000
++#define STLE_TXS2_SHIFTL      0
++#define STLE_TXS2_MSKH                0xfff0
++#define STLE_TXS2_SHIFTH      4
++
++/* YUKON-2 bit values */
++#define HW_OWNER              BIT_7
++#define SW_OWNER              0
++
++#define PU_PUTIDX_VALID               BIT_12
++
++/* YUKON-2 Control flags */
++#define UDPTCP                        BIT_0S
++#define CALSUM                        BIT_1S
++#define WR_SUM                        BIT_2S
++#define INIT_SUM              BIT_3S
++#define LOCK_SUM              BIT_4S
++#define INS_VLAN              BIT_5S
++#define FRC_STAT              BIT_6S
++#define EOP                           BIT_7S
++
++#define TX_LOCK                       BIT_8S
++#define BUF_SEND              BIT_9S
++#define PACKET_SEND           BIT_10S
++
++#define NO_WARNING            BIT_14S
++#define NO_UPDATE             BIT_15S
++
++/* YUKON-2 Rx/Tx opcodes defines */
++#define OP_TCPWRITE           0x11
++#define OP_TCPSTART           0x12
++#define OP_TCPINIT            0x14
++#define OP_TCPLCK             0x18
++#define OP_TCPCHKSUM  OP_TCPSTART
++#define OP_TCPIS              (OP_TCPINIT | OP_TCPSTART)
++#define OP_TCPLW              (OP_TCPLCK | OP_TCPWRITE)
++#define OP_TCPLSW             (OP_TCPLCK | OP_TCPSTART | OP_TCPWRITE)
++#define OP_TCPLISW            (OP_TCPLCK | OP_TCPINIT | OP_TCPSTART | OP_TCPWRITE)
++#define OP_ADDR64             0x21
++#define OP_VLAN               0x22
++#define OP_ADDR64VLAN (OP_ADDR64 | OP_VLAN)
++#define OP_LRGLEN             0x24
++#define OP_LRGLENVLAN (OP_LRGLEN | OP_VLAN)
++#define OP_BUFFER             0x40
++#define OP_PACKET             0x41
++#define OP_LARGESEND  0x43
++
++/* YUKON-2 STATUS opcodes defines */
++#define OP_RXSTAT             0x60
++#define OP_RXTIMESTAMP        0x61
++#define OP_RXVLAN             0x62
++#define OP_RXCHKS             0x64
++#define OP_RXCHKSVLAN (OP_RXCHKS | OP_RXVLAN)
++#define OP_RXTIMEVLAN (OP_RXTIMESTAMP | OP_RXVLAN)
++#define OP_RSS_HASH           0x65
++#define OP_TXINDEXLE  0x68
++
++/* YUKON-2 SPECIAL opcodes defines */
++#define OP_PUTIDX     0x70
+ /* Descriptor Bit Definition */
+ /*    TxCtrl          Transmit Buffer Control Field */
+@@ -1685,6 +2433,10 @@
+ /* macros ********************************************************************/
++/* Macro for accessing the key registers */
++#define RSS_KEY_ADDR(Port, KeyIndex)  \
++              ((B4_RSS_KEY | ( ((Port) == 0) ? 0 : 0x80)) + (KeyIndex))
++
+ /* Receive and Transmit Queues */
+ #define Q_R1  0x0000          /* Receive Queue 1 */
+ #define Q_R2  0x0080          /* Receive Queue 2 */
+@@ -1693,6 +2445,10 @@
+ #define Q_XS2 0x0300          /* Synchronous Transmit Queue 2 */
+ #define Q_XA2 0x0380          /* Asynchronous Transmit Queue 2 */
++#define Q_ASF_R1      0x100   /* ASF Rx Queue 1 */
++#define Q_ASF_R2      0x180   /* ASF Rx Queue 2 */
++#define Q_ASF_T1      0x140   /* ASF Tx Queue 1 */
++#define Q_ASF_T2      0x1c0   /* ASF Tx Queue 2 */
+ /*
+  *    Macro Q_ADDR()
+  *
+@@ -1704,11 +2460,27 @@
+  *    Offs    Queue register offset.
+  *                            Values: Q_D, Q_DA_L ... Q_T2, Q_T3
+  *
+- * usage      SK_IN32(pAC, Q_ADDR(Q_R2, Q_BC), pVal)
++ * usage      SK_IN32(IoC, Q_ADDR(Q_R2, Q_BC), pVal)
+  */
+ #define Q_ADDR(Queue, Offs)   (B8_Q_REGS + (Queue) + (Offs))
+ /*
++ *    Macro Y2_PREF_Q_ADDR()
++ *
++ *    Use this macro to access the Prefetch Units of the receive and
++ *    transmit queues of Yukon-2.
++ *
++ * para:      
++ *    Queue   Queue to access.
++ *                            Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, Q_XA2,
++ *    Offs    Queue register offset.
++ *                            Values: PREF_UNIT_CTRL_REG ... PREF_UNIT_FIFO_LEV_REG
++ *
++ * usage      SK_IN16(IoC, Y2_Q_ADDR(Q_R2, PREF_UNIT_GET_IDX_REG), pVal)
++ */
++#define Y2_PREF_Q_ADDR(Queue, Offs)   (Y2_B8_PREF_REGS + (Queue) + (Offs))
++
++/*
+  *    Macro RB_ADDR()
+  *
+  *    Use this macro to access the RAM Buffer Registers.
+@@ -1719,14 +2491,14 @@
+  *    Offs    Queue register offset.
+  *                            Values: RB_START, RB_END ... RB_LEV, RB_CTRL
+  *
+- * usage      SK_IN32(pAC, RB_ADDR(Q_R2, RB_RP), pVal)
++ * usage      SK_IN32(IoC, RB_ADDR(Q_R2, RB_RP), pVal)
+  */
+ #define RB_ADDR(Queue, Offs)  (B16_RAM_REGS + (Queue) + (Offs))
+ /* MAC Related Registers */
+-#define MAC_1         0       /* belongs to the port near the slot */
+-#define MAC_2         1       /* belongs to the port far away from the slot */
++#define MAC_1         0       /* 1st port */
++#define MAC_2         1       /* 2nd port */
+ /*
+  *    Macro MR_ADDR()
+@@ -1740,19 +2512,10 @@
+  *                            Values: RX_MFF_EA, RX_MFF_WP ... LNK_LED_REG,
+  *                                            TX_MFF_EA, TX_MFF_WP ... TX_LED_TST
+  *
+- * usage      SK_IN32(pAC, MR_ADDR(MAC_1, TX_MFF_EA), pVal)
++ * usage      SK_IN32(IoC, MR_ADDR(MAC_1, TX_MFF_EA), pVal)
+  */
+ #define MR_ADDR(Mac, Offs)    (((Mac) << 7) + (Offs))
+-#ifdef        SK_LITTLE_ENDIAN
+-#define XM_WORD_LO    0
+-#define XM_WORD_HI    1
+-#else /* !SK_LITTLE_ENDIAN */
+-#define XM_WORD_LO    1
+-#define XM_WORD_HI    0
+-#endif        /* !SK_LITTLE_ENDIAN */
+-
+-
+ /*
+  * macros to access the XMAC (GENESIS only)
+  *
+@@ -1777,22 +2540,31 @@
+ #define XMA(Mac, Reg)                                                                 \
+       ((BASE_XMAC_1 + (Mac) * (BASE_XMAC_2 - BASE_XMAC_1)) | ((Reg) << 1))
+-#define XM_IN16(IoC, Mac, Reg, pVal)                                  \
+-      SK_IN16((IoC), XMA((Mac), (Reg)), (pVal))
++#define XM_IN16(IoC, Mac, Reg, pVal)  \
++      SK_IN16(IoC, XMA(Mac, Reg), pVal)
++
++#define XM_OUT16(IoC, Mac, Reg, Val)  \
++      SK_OUT16(IoC, XMA(Mac, Reg), Val)
++
++#ifdef SK_LITTLE_ENDIAN
++
++#define XM_IN32(IoC, Mac, Reg, pVal) {                                                                \
++      SK_IN16(IoC, XMA(Mac, Reg), (SK_U16 SK_FAR *)(pVal));                   \
++      SK_IN16(IoC, XMA(Mac, (Reg) + 2), (SK_U16 SK_FAR *)(pVal) + 1); \
++}
+-#define XM_OUT16(IoC, Mac, Reg, Val)                                  \
+-      SK_OUT16((IoC), XMA((Mac), (Reg)), (Val))
++#else  /* !SK_LITTLE_ENDIAN */
+-#define XM_IN32(IoC, Mac, Reg, pVal) {                                        \
+-      SK_IN16((IoC), XMA((Mac), (Reg)),                                       \
+-              (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]);         \
+-      SK_IN16((IoC), XMA((Mac), (Reg+2)),                                     \
+-              (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]);         \
++#define XM_IN32(IoC, Mac, Reg, pVal) {                                                        \
++      SK_IN16(IoC, XMA(Mac, Reg), (SK_U16 SK_FAR *)(pVal) + 1);       \
++      SK_IN16(IoC, XMA(Mac, (Reg) + 2), (SK_U16 SK_FAR *)(pVal));     \
+ }
++#endif /* !SK_LITTLE_ENDIAN */
++
+ #define XM_OUT32(IoC, Mac, Reg, Val) {                                                                                \
+-      SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL));                  \
+-      SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)(((Val) >> 16) & 0xffffL));\
++      SK_OUT16(IoC, XMA(Mac, Reg), (SK_U16)((Val) & 0xffffL));                                \
++      SK_OUT16(IoC, XMA(Mac, (Reg) + 2), (SK_U16)(((Val) >> 16) & 0xffffL));  \
+ }
+ /* Remember: we are always writing to / reading from LITTLE ENDIAN memory */
+@@ -1802,13 +2574,13 @@
+       SK_U8   *pByte;                                                                         \
+       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
+       SK_IN16((IoC), XMA((Mac), (Reg)), &Word);                       \
+-      pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
++      pByte[0] = (SK_U8)(Word & 0x00ff);                                      \
+       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+-      SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word);                     \
+-      pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
++      SK_IN16((IoC), XMA((Mac), (Reg) + 2), &Word);           \
++      pByte[2] = (SK_U8)(Word & 0x00ff);                                      \
+       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+-      SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word);                     \
+-      pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
++      SK_IN16((IoC), XMA((Mac), (Reg) + 4), &Word);           \
++      pByte[4] = (SK_U8)(Word & 0x00ff);                                      \
+       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+ }
+@@ -1818,10 +2590,10 @@
+       SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)                     \
+               (((SK_U16)(pByte[0]) & 0x00ff) |                                \
+               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
+-      SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)           \
++      SK_OUT16((IoC), XMA((Mac), (Reg) + 2), (SK_U16)         \
+               (((SK_U16)(pByte[2]) & 0x00ff) |                                \
+               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
+-      SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16)           \
++      SK_OUT16((IoC), XMA((Mac), (Reg) + 4), (SK_U16)         \
+               (((SK_U16)(pByte[4]) & 0x00ff) |                                \
+               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
+ }
+@@ -1831,16 +2603,16 @@
+       SK_U8   SK_FAR *pByte;                                                          \
+       pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0];   \
+       SK_IN16((IoC), XMA((Mac), (Reg)), &Word);                       \
+-      pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
++      pByte[0] = (SK_U8)(Word & 0x00ff);                                      \
+       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+-      SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word);                     \
+-      pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
++      SK_IN16((IoC), XMA((Mac), (Reg) + 2), &Word);           \
++      pByte[2] = (SK_U8)(Word & 0x00ff);                                      \
+       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+-      SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word);                     \
+-      pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
++      SK_IN16((IoC), XMA((Mac), (Reg) + 4), &Word);           \
++      pByte[4] = (SK_U8)(Word & 0x00ff);                                      \
+       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+-      SK_IN16((IoC), XMA((Mac), (Reg+6)), &Word);                     \
+-      pByte[6] = (SK_U8)(Word  & 0x00ff);                                     \
++      SK_IN16((IoC), XMA((Mac), (Reg) + 6), &Word);           \
++      pByte[6] = (SK_U8)(Word & 0x00ff);                                      \
+       pByte[7] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+ }
+@@ -1850,13 +2622,13 @@
+       SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)                     \
+               (((SK_U16)(pByte[0]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
+-      SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)           \
++      SK_OUT16((IoC), XMA((Mac), (Reg) + 2), (SK_U16)         \
+               (((SK_U16)(pByte[2]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
+-      SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16)           \
++      SK_OUT16((IoC), XMA((Mac), (Reg) + 4), (SK_U16)         \
+               (((SK_U16)(pByte[4]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
+-      SK_OUT16((IoC), XMA((Mac), (Reg+6)), (SK_U16)           \
++      SK_OUT16((IoC), XMA((Mac), (Reg) + 6), (SK_U16)         \
+               (((SK_U16)(pByte[6]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[7]) << 8) & 0xff00)));                 \
+ }
+@@ -1866,7 +2638,7 @@
+  *
+  * GM_IN16(),         to read  a 16 bit register (e.g. GM_GP_STAT)
+  * GM_OUT16(),                to write a 16 bit register (e.g. GM_GP_CTRL)
+- * GM_IN32(),         to read  a 32 bit register (e.g. GM_)
++ * GM_IN32(),         to read  a 32 bit register (e.g. GM_RXF_UC_OK)
+  * GM_OUT32(),                to write a 32 bit register (e.g. GM_)
+  * GM_INADDR(),               to read  a network address register (e.g. GM_SRC_ADDR_1L)
+  * GM_OUTADDR(),      to write a network address register (e.g. GM_SRC_ADDR_2L)
+@@ -1885,22 +2657,31 @@
+ #define GMA(Mac, Reg)                                                                 \
+       ((BASE_GMAC_1 + (Mac) * (BASE_GMAC_2 - BASE_GMAC_1)) | (Reg))
+-#define GM_IN16(IoC, Mac, Reg, pVal)                                  \
+-      SK_IN16((IoC), GMA((Mac), (Reg)), (pVal))
++#define GM_IN16(IoC, Mac, Reg, pVal)  \
++      SK_IN16(IoC, GMA(Mac, Reg), pVal)
++
++#define GM_OUT16(IoC, Mac, Reg, Val)  \
++      SK_OUT16(IoC, GMA(Mac, Reg), Val)
+-#define GM_OUT16(IoC, Mac, Reg, Val)                                  \
+-      SK_OUT16((IoC), GMA((Mac), (Reg)), (Val))
++#ifdef SK_LITTLE_ENDIAN
+-#define GM_IN32(IoC, Mac, Reg, pVal) {                                        \
+-      SK_IN16((IoC), GMA((Mac), (Reg)),                                       \
+-              (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]);         \
+-      SK_IN16((IoC), GMA((Mac), (Reg+4)),                                     \
+-              (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]);         \
++#define GM_IN32(IoC, Mac, Reg, pVal) {                                                                        \
++      SK_IN16(IoC, GMA(Mac, Reg), (SK_U16 SK_FAR *)(pVal));                           \
++      SK_IN16((IoC), GMA(Mac, (Reg) + 4), (SK_U16 SK_FAR *)(pVal) + 1);       \
+ }
++#else  /* !SK_LITTLE_ENDIAN */
++
++#define GM_IN32(IoC, Mac, Reg, pVal) {                                                        \
++      SK_IN16(IoC, GMA(Mac, Reg), (SK_U16 SK_FAR *)(pVal) + 1);       \
++      SK_IN16(IoC, GMA(Mac, (Reg) + 4), (SK_U16 SK_FAR *)(pVal));     \
++}
++
++#endif /* !SK_LITTLE_ENDIAN */
++
+ #define GM_OUT32(IoC, Mac, Reg, Val) {                                                                                \
+-      SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL));                  \
+-      SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)(((Val) >> 16) & 0xffffL));\
++      SK_OUT16(IoC, GMA(Mac, Reg), (SK_U16)((Val) & 0xffffL));                                \
++      SK_OUT16(IoC, GMA(Mac, (Reg) + 4), (SK_U16)(((Val) >> 16) & 0xffffL));  \
+ }
+ #define GM_INADDR(IoC, Mac, Reg, pVal) {                              \
+@@ -1908,13 +2689,13 @@
+       SK_U8   *pByte;                                                                         \
+       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
+       SK_IN16((IoC), GMA((Mac), (Reg)), &Word);                       \
+-      pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
++      pByte[0] = (SK_U8)(Word & 0x00ff);                                      \
+       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+-      SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word);                     \
+-      pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
++      SK_IN16((IoC), GMA((Mac), (Reg) + 4), &Word);           \
++      pByte[2] = (SK_U8)(Word & 0x00ff);                                      \
+       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+-      SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word);                     \
+-      pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
++      SK_IN16((IoC), GMA((Mac), (Reg) + 8), &Word);           \
++      pByte[4] = (SK_U8)(Word & 0x00ff);                                      \
+       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+ }
+@@ -1924,10 +2705,10 @@
+       SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)                     \
+               (((SK_U16)(pByte[0]) & 0x00ff) |                                \
+               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
+-      SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)           \
++      SK_OUT16((IoC), GMA((Mac), (Reg) + 4), (SK_U16)         \
+               (((SK_U16)(pByte[2]) & 0x00ff) |                                \
+               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
+-      SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16)           \
++      SK_OUT16((IoC), GMA((Mac), (Reg) + 8), (SK_U16)         \
+               (((SK_U16)(pByte[4]) & 0x00ff) |                                \
+               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
+ }
+@@ -1937,16 +2718,16 @@
+       SK_U8   *pByte;                                                                         \
+       pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0];                         \
+       SK_IN16((IoC), GMA((Mac), (Reg)), &Word);                       \
+-      pByte[0] = (SK_U8)(Word  & 0x00ff);                                     \
++      pByte[0] = (SK_U8)(Word & 0x00ff);                                      \
+       pByte[1] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+-      SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word);                     \
+-      pByte[2] = (SK_U8)(Word  & 0x00ff);                                     \
++      SK_IN16((IoC), GMA((Mac), (Reg) + 4), &Word);           \
++      pByte[2] = (SK_U8)(Word & 0x00ff);                                      \
+       pByte[3] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+-      SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word);                     \
+-      pByte[4] = (SK_U8)(Word  & 0x00ff);                                     \
++      SK_IN16((IoC), GMA((Mac), (Reg) + 8), &Word);           \
++      pByte[4] = (SK_U8)(Word & 0x00ff);                                      \
+       pByte[5] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+-      SK_IN16((IoC), GMA((Mac), (Reg+12)), &Word);            \
+-      pByte[6] = (SK_U8)(Word  & 0x00ff);                                     \
++      SK_IN16((IoC), GMA((Mac), (Reg) + 12), &Word);          \
++      pByte[6] = (SK_U8)(Word & 0x00ff);                                      \
+       pByte[7] = (SK_U8)((Word >> 8) & 0x00ff);                       \
+ }
+@@ -1956,13 +2737,13 @@
+       SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)                     \
+               (((SK_U16)(pByte[0]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[1]) << 8) & 0xff00)));                 \
+-      SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)           \
++      SK_OUT16((IoC), GMA((Mac), (Reg) + 4), (SK_U16)         \
+               (((SK_U16)(pByte[2]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[3]) << 8) & 0xff00)));                 \
+-      SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16)           \
++      SK_OUT16((IoC), GMA((Mac), (Reg) + 8), (SK_U16)         \
+               (((SK_U16)(pByte[4]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[5]) << 8) & 0xff00)));                 \
+-      SK_OUT16((IoC), GMA((Mac), (Reg+12)), (SK_U16)          \
++      SK_OUT16((IoC), GMA((Mac), (Reg) + 12), (SK_U16)        \
+               (((SK_U16)(pByte[6]) & 0x00ff)|                                 \
+               (((SK_U16)(pByte[7]) << 8) & 0xff00)));                 \
+ }
+@@ -2010,30 +2791,30 @@
+  *
+  * usage:     PHY_READ(IoC, pPort, MAC_1, PHY_CTRL, Value);
+  * Warning: a PHY_READ on an uninitialized PHY (PHY still in reset) never
+- *          comes back. This is checked in DEBUG mode.
++ *    comes back. This is checked in DEBUG mode.
+  */
+ #ifndef DEBUG
+ #define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) {                                             \
+-      SK_U16 Mmu;                                                                                                             \
++      SK_U16 Mmu;                                                                                                                     \
+                                                                                                                                               \
+       XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);       \
+       XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                                     \
+       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
+-              do {                                                                                                                    \
++              do {                                                                                                                    \
+                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
+               } while ((Mmu & XM_MMU_PHY_RDY) == 0);                                                  \
+               XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                             \
+-      }                                                                                                                                       \
++      }                                                                                                                                       \
+ }
+ #else
+ #define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) {                                             \
+-      SK_U16 Mmu;                                                                                                             \
++      SK_U16 Mmu;                                                                                                                     \
+       int __i = 0;                                                                                                            \
+                                                                                                                                               \
+       XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);       \
+       XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                                     \
+       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
+-              do {                                                                                                                    \
++              do {                                                                                                                    \
+                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
+                       __i++;                                                                                                          \
+                       if (__i > 100000) {                                                                                     \
+@@ -2044,7 +2825,7 @@
+                       }                                                                                                                       \
+               } while ((Mmu & XM_MMU_PHY_RDY) == 0);                                                  \
+               XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal));                                             \
+-      }                                                                                                                                       \
++      }                                                                                                                                       \
+ }
+ #endif /* DEBUG */
+@@ -2052,17 +2833,17 @@
+       SK_U16 Mmu;                                                                                                                     \
+                                                                                                                                               \
+       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
+-              do {                                                                                                                    \
++              do {                                                                                                                    \
+                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
+               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);                                                 \
+-      }                                                                                                                                       \
++      }                                                                                                                                       \
+       XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr);       \
+       XM_OUT16((IoC), (Mac), XM_PHY_DATA, (Val));                                                     \
+       if ((pPort)->PhyType != SK_PHY_XMAC) {                                                          \
+-              do {                                                                                                                    \
++              do {                                                                                                                    \
+                       XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu);                                        \
+               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);                                                 \
+-      }                                                                                                                                       \
++      }                                                                                                                                       \
+ }
+ /*
+@@ -2071,12 +2852,14 @@
+  *    Use this macro to access PCI config register from the I/O space.
+  *
+  * para:
++ *    pAC             Pointer to adapter context
+  *    Addr    PCI configuration register to access.
+  *                    Values: PCI_VENDOR_ID ... PCI_VPD_ADR_REG,
+  *
+- * usage      SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal);
++ * usage      SK_IN16(IoC, PCI_C(pAC, PCI_VENDOR_ID), pVal);
+  */
+-#define PCI_C(Addr)   (B7_CFG_SPC + (Addr))   /* PCI Config Space */
++#define PCI_C(p, Addr)                \
++      (((CHIP_ID_YUKON_2(p)) ? Y2_CFG_SPC : B7_CFG_SPC) + (Addr))
+ /*
+  *    Macro SK_HW_ADDR(Base, Addr)
+@@ -2088,7 +2871,7 @@
+  *    Addr    Address offset
+  *
+  * usage:     May be used in SK_INxx and SK_OUTxx macros
+- *            #define SK_IN8(pAC, Addr, pVal) ...\
++ *            #define SK_IN8(IoC, Addr, pVal) ...\
+  *                    *pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr)))
+  */
+ #ifdef SK_MEM_MAPPED_IO
+@@ -2107,12 +2890,27 @@
+  * para:
+  *    pAC             Pointer to adapter context struct
+  *    IoC             I/O context needed for SK I/O macros
+- *  Port      Port number
++ *    Port    Port number
+  *    Mode    Mode to set for this LED
+  */
+ #define SK_HWAC_LINK_LED(pAC, IoC, Port, Mode) \
+       SK_OUT8(IoC, MR_ADDR(Port, LNK_LED_REG), Mode);
++#define SK_SET_GP_IO(IoC, Bit) {      \
++      SK_U32  DWord;                                  \
++      SK_IN32(IoC, B2_GP_IO, &DWord); \
++      DWord |= ((GP_DIR_0 | GP_IO_0) << (Bit));\
++      SK_OUT32(IoC, B2_GP_IO, DWord); \
++}
++
++#define SK_CLR_GP_IO(IoC, Bit) {      \
++      SK_U32  DWord;                                  \
++      SK_IN32(IoC, B2_GP_IO, &DWord); \
++      DWord &= ~((GP_DIR_0 | GP_IO_0) << (Bit));\
++      SK_OUT32(IoC, B2_GP_IO, DWord); \
++}
++
++#define SK_GE_PCI_FIFO_SIZE           1600    /* PCI FIFO Size */
+ /* typedefs *******************************************************************/
+@@ -2124,3 +2922,4 @@
+ #endif        /* __cplusplus */
+ #endif        /* __INC_SKGEHW_H */
++
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skgehwt.h linux-2.6.9.new/drivers/net/sk98lin/h/skgehwt.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skgehwt.h    2004-10-19 05:53:51.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skgehwt.h    2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skhwt.h
+  * Project:   Gigabit Ethernet Adapters, Event Scheduler Module
+- * Version:   $Revision: 1.7 $
+- * Date:      $Date: 2003/09/16 12:55:08 $
++ * Version:   $Revision: 2.1 $
++ * Date:      $Date: 2003/10/27 14:16:09 $
+  * Purpose:   Defines for the hardware timer functions
+  *
+  ******************************************************************************/
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skgei2c.h linux-2.6.9.new/drivers/net/sk98lin/h/skgei2c.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skgei2c.h    2004-10-19 05:54:40.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skgei2c.h    1970-01-01 08:00:00.000000000 +0800
+@@ -1,210 +0,0 @@
+-/******************************************************************************
+- *
+- * Name:      skgei2c.h
+- * Project:   Gigabit Ethernet Adapters, TWSI-Module
+- * Version:   $Revision: 1.25 $
+- * Date:      $Date: 2003/10/20 09:06:05 $
+- * Purpose:   Special defines for TWSI
+- *
+- ******************************************************************************/
+-
+-/******************************************************************************
+- *
+- *    (C)Copyright 1998-2002 SysKonnect.
+- *    (C)Copyright 2002-2003 Marvell.
+- *
+- *    This program is free software; you can redistribute it and/or modify
+- *    it under the terms of the GNU General Public License as published by
+- *    the Free Software Foundation; either version 2 of the License, or
+- *    (at your option) any later version.
+- *
+- *    The information in this file is provided "AS IS" without warranty.
+- *
+- ******************************************************************************/
+-
+-/*
+- * SKGEI2C.H  contains all SK-98xx specific defines for the TWSI handling
+- */
+-
+-#ifndef _INC_SKGEI2C_H_
+-#define _INC_SKGEI2C_H_
+-
+-/*
+- * Macros to access the B2_I2C_CTRL
+- */
+-#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \
+-      SK_OUT32(IoC, B2_I2C_CTRL,\
+-              (flag ? 0x80000000UL : 0x0L) | \
+-              (((SK_U32)reg << 16) & I2C_ADDR) | \
+-              (((SK_U32)dev << 9) & I2C_DEV_SEL) | \
+-              (dev_size & I2C_DEV_SIZE) | \
+-              ((burst << 4) & I2C_BURST_LEN))
+-
+-#define SK_I2C_STOP(IoC) {                            \
+-      SK_U32  I2cCtrl;                                \
+-      SK_IN32(IoC, B2_I2C_CTRL, &I2cCtrl);            \
+-      SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP); \
+-}
+-
+-#define SK_I2C_GET_CTL(IoC, pI2cCtrl) SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl)
+-
+-/*
+- * Macros to access the TWSI SW Registers
+- */
+-#define SK_I2C_SET_BIT(IoC, SetBits) {                        \
+-      SK_U8   OrgBits;                                \
+-      SK_IN8(IoC, B2_I2C_SW, &OrgBits);               \
+-      SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits));    \
+-}
+-
+-#define SK_I2C_CLR_BIT(IoC, ClrBits) {                        \
+-      SK_U8   OrgBits;                                \
+-      SK_IN8(IoC, B2_I2C_SW, &OrgBits);               \
+-      SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits))); \
+-}
+-
+-#define SK_I2C_GET_SW(IoC, pI2cSw)    SK_IN8(IoC, B2_I2C_SW, pI2cSw)
+-
+-/*
+- * define the possible sensor states
+- */
+-#define       SK_SEN_IDLE             0       /* Idle: sensor not read */
+-#define       SK_SEN_VALUE    1       /* Value Read cycle */
+-#define       SK_SEN_VALEXT   2       /* Extended Value Read cycle */
+-
+-/*
+- * Conversion factor to convert read Voltage sensor to milli Volt
+- * Conversion factor to convert read Temperature sensor to 10th degree Celsius
+- */
+-#define       SK_LM80_VT_LSB          22      /* 22mV LSB resolution */
+-#define       SK_LM80_TEMP_LSB        10      /* 1 degree LSB resolution */
+-#define       SK_LM80_TEMPEXT_LSB      5      /* 0.5 degree LSB resolution for ext. val. */
+-
+-/*
+- * formula: counter = (22500*60)/(rpm * divisor * pulses/2)
+- * assuming: 6500rpm, 4 pulses, divisor 1
+- */
+-#define SK_LM80_FAN_FAKTOR    ((22500L*60)/(1*2))
+-
+-/*
+- * Define sensor management data
+- * Maximum is reached on Genesis copper dual port and Yukon-64
+- * Board specific maximum is in pAC->I2c.MaxSens
+- */
+-#define       SK_MAX_SENSORS  8       /* maximal no. of installed sensors */
+-#define       SK_MIN_SENSORS  5       /* minimal no. of installed sensors */
+-
+-/*
+- * To watch the state machine (SM) use the timer in two ways
+- * instead of one as hitherto
+- */
+-#define       SK_TIMER_WATCH_SM               0       /* Watch the SM to finish in a spec. time */
+-#define       SK_TIMER_NEW_GAUGING    1       /* Start a new gauging when timer expires */
+-
+-/*
+- * Defines for the individual thresholds
+- */
+-
+-/* Temperature sensor */
+-#define       SK_SEN_TEMP_HIGH_ERR    800     /* Temperature High Err  Threshold */
+-#define       SK_SEN_TEMP_HIGH_WARN   700     /* Temperature High Warn Threshold */
+-#define       SK_SEN_TEMP_LOW_WARN    100     /* Temperature Low  Warn Threshold */
+-#define       SK_SEN_TEMP_LOW_ERR               0     /* Temperature Low  Err  Threshold */
+-
+-/* VCC which should be 5 V */
+-#define       SK_SEN_PCI_5V_HIGH_ERR          5588    /* Voltage PCI High Err  Threshold */
+-#define       SK_SEN_PCI_5V_HIGH_WARN         5346    /* Voltage PCI High Warn Threshold */
+-#define       SK_SEN_PCI_5V_LOW_WARN          4664    /* Voltage PCI Low  Warn Threshold */
+-#define       SK_SEN_PCI_5V_LOW_ERR           4422    /* Voltage PCI Low  Err  Threshold */
+-
+-/*
+- * VIO may be 5 V or 3.3 V. Initialization takes two parts:
+- * 1. Initialize lowest lower limit and highest higher limit.
+- * 2. After the first value is read correct the upper or the lower limit to
+- *    the appropriate C constant.
+- *
+- * Warning limits are +-5% of the exepected voltage.
+- * Error limits are +-10% of the expected voltage.
+- */
+-
+-/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */
+-
+-#define       SK_SEN_PCI_IO_5V_HIGH_ERR       5566    /* + 10% V PCI-IO High Err Threshold */
+-#define       SK_SEN_PCI_IO_5V_HIGH_WARN      5324    /* +  5% V PCI-IO High Warn Threshold */
+-                                      /*              5000    mVolt */
+-#define       SK_SEN_PCI_IO_5V_LOW_WARN       4686    /* -  5% V PCI-IO Low Warn Threshold */
+-#define       SK_SEN_PCI_IO_5V_LOW_ERR        4444    /* - 10% V PCI-IO Low Err Threshold */
+-
+-#define       SK_SEN_PCI_IO_RANGE_LIMITER     4000    /* 4000 mV range delimiter */
+-
+-/* correction values for the second pass */
+-#define       SK_SEN_PCI_IO_3V3_HIGH_ERR      3850    /* + 15% V PCI-IO High Err Threshold */
+-#define       SK_SEN_PCI_IO_3V3_HIGH_WARN     3674    /* + 10% V PCI-IO High Warn Threshold */
+-                                      /*              3300    mVolt */
+-#define       SK_SEN_PCI_IO_3V3_LOW_WARN      2926    /* - 10% V PCI-IO Low Warn Threshold */
+-#define       SK_SEN_PCI_IO_3V3_LOW_ERR       2772    /* - 15% V PCI-IO Low Err  Threshold */
+-
+-/*
+- * VDD voltage
+- */
+-#define       SK_SEN_VDD_HIGH_ERR             3630    /* Voltage ASIC High Err  Threshold */
+-#define       SK_SEN_VDD_HIGH_WARN    3476    /* Voltage ASIC High Warn Threshold */
+-#define       SK_SEN_VDD_LOW_WARN             3146    /* Voltage ASIC Low  Warn Threshold */
+-#define       SK_SEN_VDD_LOW_ERR              2970    /* Voltage ASIC Low  Err  Threshold */
+-
+-/*
+- * PHY PLL 3V3 voltage
+- */
+-#define       SK_SEN_PLL_3V3_HIGH_ERR         3630    /* Voltage PMA High Err  Threshold */
+-#define       SK_SEN_PLL_3V3_HIGH_WARN        3476    /* Voltage PMA High Warn Threshold */
+-#define       SK_SEN_PLL_3V3_LOW_WARN         3146    /* Voltage PMA Low  Warn Threshold */
+-#define       SK_SEN_PLL_3V3_LOW_ERR          2970    /* Voltage PMA Low  Err  Threshold */
+-
+-/*
+- * VAUX (YUKON only)
+- */
+-#define       SK_SEN_VAUX_3V3_HIGH_ERR        3630    /* Voltage VAUX High Err Threshold */
+-#define       SK_SEN_VAUX_3V3_HIGH_WARN       3476    /* Voltage VAUX High Warn Threshold */
+-#define       SK_SEN_VAUX_3V3_LOW_WARN        3146    /* Voltage VAUX Low Warn Threshold */
+-#define       SK_SEN_VAUX_3V3_LOW_ERR         2970    /* Voltage VAUX Low Err Threshold */
+-#define       SK_SEN_VAUX_0V_WARN_ERR            0    /* if VAUX not present */
+-#define       SK_SEN_VAUX_RANGE_LIMITER       1000    /* 1000 mV range delimiter */
+-
+-/*
+- * PHY 2V5 voltage
+- */
+-#define       SK_SEN_PHY_2V5_HIGH_ERR         2750    /* Voltage PHY High Err Threshold */
+-#define       SK_SEN_PHY_2V5_HIGH_WARN        2640    /* Voltage PHY High Warn Threshold */
+-#define       SK_SEN_PHY_2V5_LOW_WARN         2376    /* Voltage PHY Low Warn Threshold */
+-#define       SK_SEN_PHY_2V5_LOW_ERR          2222    /* Voltage PHY Low Err Threshold */
+-
+-/*
+- * ASIC Core 1V5 voltage (YUKON only)
+- */
+-#define       SK_SEN_CORE_1V5_HIGH_ERR        1650    /* Voltage ASIC Core High Err Threshold */
+-#define       SK_SEN_CORE_1V5_HIGH_WARN       1575    /* Voltage ASIC Core High Warn Threshold */
+-#define       SK_SEN_CORE_1V5_LOW_WARN        1425    /* Voltage ASIC Core Low Warn Threshold */
+-#define       SK_SEN_CORE_1V5_LOW_ERR         1350    /* Voltage ASIC Core Low Err Threshold */
+-
+-/*
+- * FAN 1 speed
+- */
+-/* assuming: 6500rpm +-15%, 4 pulses,
+- * warning at:        80 %
+- * error at:  70 %
+- * no upper limit
+- */
+-#define       SK_SEN_FAN_HIGH_ERR             20000   /* FAN Speed High Err Threshold */
+-#define       SK_SEN_FAN_HIGH_WARN    20000   /* FAN Speed High Warn Threshold */
+-#define       SK_SEN_FAN_LOW_WARN              5200   /* FAN Speed Low Warn Threshold */
+-#define       SK_SEN_FAN_LOW_ERR               4550   /* FAN Speed Low Err Threshold */
+-
+-/*
+- * Some Voltages need dynamic thresholds
+- */
+-#define       SK_SEN_DYN_INIT_NONE             0  /* No dynamic init of thresholds */
+-#define       SK_SEN_DYN_INIT_PCI_IO          10  /* Init PCI-IO with new thresholds */
+-#define       SK_SEN_DYN_INIT_VAUX            11  /* Init VAUX with new thresholds */
+-
+-extern        int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
+-#endif        /* n_INC_SKGEI2C_H */
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skgeinit.h linux-2.6.9.new/drivers/net/sk98lin/h/skgeinit.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skgeinit.h   2004-10-19 05:54:40.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skgeinit.h   2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgeinit.h
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.83 $
+- * Date:      $Date: 2003/09/16 14:07:37 $
++ * Version:   $Revision: 2.37 $
++ * Date:      $Date: 2005/05/24 08:42:19 $
+  * Purpose:   Structures and prototypes for the GE Init Module
+  *
+  ******************************************************************************/
+@@ -11,13 +11,12 @@
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2005 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+  *    the Free Software Foundation; either version 2 of the License, or
+  *    (at your option) any later version.
+- *
+  *    The information in this file is provided "AS IS" without warranty.
+  *
+  ******************************************************************************/
+@@ -60,14 +59,17 @@
+ #define SK_XMIT_DUR           0x002faf08UL    /*  50 ms */
+ #define SK_BLK_DUR            0x01dcd650UL    /* 500 ms */
+-#define SK_DPOLL_DEF  0x00ee6b28UL    /* 250 ms at 62.5 MHz */
++#define SK_DPOLL_DEF  0x00ee6b28UL    /* 250 ms at 62.5 MHz (Genesis) */
++#define SK_DPOLL_DEF_Y2       0x0000124fUL    /*  75 us (Yukon-2) */
+ #define SK_DPOLL_MAX  0x00ffffffUL    /* 268 ms at 62.5 MHz */
+-                                                                              /* 215 ms at 78.12 MHz */
++                                                                              /* 215 ms at 78.12 MHz (Yukon) */
+ #define SK_FACT_62            100                     /* is given in percent */
+-#define SK_FACT_53             85         /* on GENESIS:      53.12 MHz */
++#define SK_FACT_53             85                     /* on GENESIS:  53.12 MHz */
+ #define SK_FACT_78            125                     /* on YUKON:    78.12 MHz */
++#define SK_FACT_100           161                     /* on YUKON-FE: 100 MHz */
++#define SK_FACT_125           202                     /* on YUKON-EC: 125 MHz */
+ /* Timeout values */
+ #define SK_MAC_TO_53  72                      /* MAC arbiter timeout */
+@@ -83,10 +85,16 @@
+ #define SK_RB_LLPP_B  (16 * 1024)     /* Lower Level for big Queues */
+ #ifndef SK_BMU_RX_WM
+-#define SK_BMU_RX_WM  0x600           /* BMU Rx Watermark */
++#define SK_BMU_RX_WM          0x600   /* BMU Rx Watermark */
+ #endif
++
+ #ifndef SK_BMU_TX_WM
+-#define SK_BMU_TX_WM  0x600           /* BMU Tx Watermark */
++#define SK_BMU_TX_WM          0x600   /* BMU Tx Watermark */
++#endif
++
++/* performance sensitive drivers should set this define to 0x80 */
++#ifndef SK_BMU_RX_WM_PEX
++#define SK_BMU_RX_WM_PEX      0x600   /* BMU Rx Watermark for PEX */
+ #endif
+ /* XMAC II Rx High Watermark */
+@@ -98,37 +106,31 @@
+ #define SK_XM_THR_MULL        0x01fb          /* .. for multiple link usage */
+ #define SK_XM_THR_JUMBO       0x03fc          /* .. for jumbo frame usage */
+-/* values for GIPortUsage */
++/* values for PortUsage */
+ #define SK_RED_LINK           1               /* redundant link usage */
+ #define SK_MUL_LINK           2               /* multiple link usage */
+ #define SK_JUMBO_LINK 3               /* driver uses jumbo frames */
+ /* Minimum RAM Buffer Rx Queue Size */
+-#define SK_MIN_RXQ_SIZE       16              /* 16 kB */
++#define SK_MIN_RXQ_SIZE       (((pAC)->GIni.GIYukon2) ? 10 : 16)              /* 10/16 kB */
+ /* Minimum RAM Buffer Tx Queue Size */
+-#define SK_MIN_TXQ_SIZE       16              /* 16 kB */
++#define SK_MIN_TXQ_SIZE       (((pAC)->GIni.GIYukon2) ? 10 : 16)              /* 10/16 kB */
+-/* Queue Size units */
+-#define QZ_UNITS              0x7
++/* Queue Size units (Genesis/Yukon) */
++#define QZ_UNITS              7
+ #define QZ_STEP                       8
++/* Queue Size units (Yukon-2) */
++#define QZ_STEP_Y2            1
++
+ /* Percentage of queue size from whole memory */
+ /* 80 % for receive */
+-#define RAM_QUOTA_RX  80L
+-/* 0% for sync transfer */
+-#define       RAM_QUOTA_SYNC  0L
++#define RAM_QUOTA_RX  80
++/*  0 % for sync transfer */
++#define RAM_QUOTA_SYNC        0
+ /* the rest (20%) is taken for async transfer */
+-/* Get the rounded queue size in Bytes in 8k steps */
+-#define ROUND_QUEUE_SIZE(SizeInBytes)                                 \
+-      ((((unsigned long) (SizeInBytes) + (QZ_STEP*1024L)-1) / 1024) & \
+-      ~(QZ_STEP-1))
+-
+-/* Get the rounded queue size in KBytes in 8k steps */
+-#define ROUND_QUEUE_SIZE_KB(Kilobytes) \
+-      ROUND_QUEUE_SIZE((Kilobytes) * 1024L)
+-
+ /* Types of RAM Buffer Queues */
+ #define SK_RX_SRAM_Q  1       /* small receive queue */
+ #define SK_RX_BRAM_Q  2       /* big receive queue */
+@@ -167,11 +169,11 @@
+ /* Link Speed Capabilities */
+-#define SK_LSPEED_CAP_AUTO                    (1<<0)  /* Automatic resolution */
+-#define SK_LSPEED_CAP_10MBPS          (1<<1)  /* 10 Mbps */
+-#define SK_LSPEED_CAP_100MBPS         (1<<2)  /* 100 Mbps */
+-#define SK_LSPEED_CAP_1000MBPS                (1<<3)  /* 1000 Mbps */
+-#define SK_LSPEED_CAP_INDETERMINATED (1<<4) /* indeterminated */
++#define SK_LSPEED_CAP_AUTO                    BIT_0S  /* Automatic resolution */
++#define SK_LSPEED_CAP_10MBPS          BIT_1S  /* 10 Mbps */
++#define SK_LSPEED_CAP_100MBPS         BIT_2S  /* 100 Mbps */
++#define SK_LSPEED_CAP_1000MBPS                BIT_3S  /* 1000 Mbps */
++#define SK_LSPEED_CAP_INDETERMINATED BIT_4S /* indeterminated */
+ /* Link Speed Parameter */
+ #define SK_LSPEED_AUTO                                1       /* Automatic resolution */
+@@ -189,11 +191,11 @@
+ /* Link Capability Parameter */
+-#define SK_LMODE_CAP_HALF             (1<<0)  /* Half Duplex Mode */
+-#define SK_LMODE_CAP_FULL             (1<<1)  /* Full Duplex Mode */
+-#define SK_LMODE_CAP_AUTOHALF (1<<2)  /* AutoHalf Duplex Mode */
+-#define SK_LMODE_CAP_AUTOFULL (1<<3)  /* AutoFull Duplex Mode */
+-#define SK_LMODE_CAP_INDETERMINATED (1<<4) /* indeterminated */
++#define SK_LMODE_CAP_HALF             BIT_0S  /* Half Duplex Mode */
++#define SK_LMODE_CAP_FULL             BIT_1S  /* Full Duplex Mode */
++#define SK_LMODE_CAP_AUTOHALF BIT_2S  /* AutoHalf Duplex Mode */
++#define SK_LMODE_CAP_AUTOFULL BIT_3S  /* AutoFull Duplex Mode */
++#define SK_LMODE_CAP_INDETERMINATED BIT_4S /* indeterminated */
+ /* Link Mode Current State */
+ #define SK_LMODE_STAT_UNKNOWN 1       /* Unknown Duplex Mode */
+@@ -220,10 +222,10 @@
+ #define SK_FLOW_STAT_INDETERMINATED 5 /* indeterminated */
+ /* Master/Slave Mode Capabilities */
+-#define SK_MS_CAP_AUTO                (1<<0)  /* Automatic resolution */
+-#define SK_MS_CAP_MASTER      (1<<1)  /* This station is master */
+-#define SK_MS_CAP_SLAVE               (1<<2)  /* This station is slave */
+-#define SK_MS_CAP_INDETERMINATED (1<<3)       /* indeterminated */
++#define SK_MS_CAP_AUTO                BIT_0S  /* Automatic resolution */
++#define SK_MS_CAP_MASTER      BIT_1S  /* This station is master */
++#define SK_MS_CAP_SLAVE               BIT_2S  /* This station is slave */
++#define SK_MS_CAP_INDETERMINATED BIT_3S       /* indeterminated */
+ /* Set Master/Slave Mode Parameter (and capabilities) */
+ #define SK_MS_MODE_AUTO               1       /* Automatic resolution */
+@@ -238,25 +240,25 @@
+ #define SK_MS_STAT_FAULT      4       /* M/S resolution failed */
+ #define SK_MS_STAT_INDETERMINATED 5   /* indeterminated */
+-/* parameter 'Mode' when calling SkXmSetRxCmd() */
+-#define SK_STRIP_FCS_ON               (1<<0)  /* Enable  FCS stripping of Rx frames */
+-#define SK_STRIP_FCS_OFF      (1<<1)  /* Disable FCS stripping of Rx frames */
+-#define SK_STRIP_PAD_ON               (1<<2)  /* Enable  pad byte stripping of Rx fr */
+-#define SK_STRIP_PAD_OFF      (1<<3)  /* Disable pad byte stripping of Rx fr */
+-#define SK_LENERR_OK_ON               (1<<4)  /* Don't chk fr for in range len error */
+-#define SK_LENERR_OK_OFF      (1<<5)  /* Check frames for in range len error */
+-#define SK_BIG_PK_OK_ON               (1<<6)  /* Don't set Rx Error bit for big frames */
+-#define SK_BIG_PK_OK_OFF      (1<<7)  /* Set Rx Error bit for big frames */
+-#define SK_SELF_RX_ON         (1<<8)  /* Enable  Rx of own packets */
+-#define SK_SELF_RX_OFF                (1<<9)  /* Disable Rx of own packets */
++/* parameter 'Mode' when calling SkMacSetRxCmd() */
++#define SK_STRIP_FCS_ON               BIT_0S  /* Enable  FCS stripping of Rx frames */
++#define SK_STRIP_FCS_OFF      BIT_1S  /* Disable FCS stripping of Rx frames */
++#define SK_STRIP_PAD_ON               BIT_2S  /* Enable  pad byte stripping of Rx fr */
++#define SK_STRIP_PAD_OFF      BIT_3S  /* Disable pad byte stripping of Rx fr */
++#define SK_LENERR_OK_ON               BIT_4S  /* Don't chk fr for in range len error */
++#define SK_LENERR_OK_OFF      BIT_5S  /* Check frames for in range len error */
++#define SK_BIG_PK_OK_ON               BIT_6S  /* Don't set Rx Error bit for big frames */
++#define SK_BIG_PK_OK_OFF      BIT_7S  /* Set Rx Error bit for big frames */
++#define SK_SELF_RX_ON         BIT_8S  /* Enable  Rx of own packets */
++#define SK_SELF_RX_OFF                BIT_9S  /* Disable Rx of own packets */
+ /* parameter 'Para' when calling SkMacSetRxTxEn() */
+-#define SK_MAC_LOOPB_ON               (1<<0)  /* Enable  MAC Loopback Mode */
+-#define SK_MAC_LOOPB_OFF      (1<<1)  /* Disable MAC Loopback Mode */
+-#define SK_PHY_LOOPB_ON               (1<<2)  /* Enable  PHY Loopback Mode */
+-#define SK_PHY_LOOPB_OFF      (1<<3)  /* Disable PHY Loopback Mode */
+-#define SK_PHY_FULLD_ON               (1<<4)  /* Enable  GMII Full Duplex */
+-#define SK_PHY_FULLD_OFF      (1<<5)  /* Disable GMII Full Duplex */
++#define SK_MAC_LOOPB_ON               BIT_0S  /* Enable  MAC Loopback Mode */
++#define SK_MAC_LOOPB_OFF      BIT_1S  /* Disable MAC Loopback Mode */
++#define SK_PHY_LOOPB_ON               BIT_2S  /* Enable  PHY Loopback Mode */
++#define SK_PHY_LOOPB_OFF      BIT_3S  /* Disable PHY Loopback Mode */
++#define SK_PHY_FULLD_ON               BIT_4S  /* Enable  GMII Full Duplex */
++#define SK_PHY_FULLD_OFF      BIT_5S  /* Disable GMII Full Duplex */
+ /* States of PState */
+ #define SK_PRT_RESET  0       /* the port is reset */
+@@ -266,18 +268,24 @@
+ /* PHY power down modes */
+ #define PHY_PM_OPERATIONAL_MODE               0       /* PHY operational mode */
+-#define PHY_PM_DEEP_SLEEP                     1       /* coma mode --> minimal power */
++#define PHY_PM_DEEP_SLEEP                     1       /* Coma mode --> minimal power */
+ #define PHY_PM_IEEE_POWER_DOWN                2       /* IEEE 22.2.4.1.5 compl. power down */
+-#define PHY_PM_ENERGY_DETECT          3       /* energy detect */
+-#define PHY_PM_ENERGY_DETECT_PLUS     4       /* energy detect plus */
++#define PHY_PM_ENERGY_DETECT          3       /* Energy detect */
++#define PHY_PM_ENERGY_DETECT_PLUS     4       /* Energy detect plus */
++
++/* PCI Bus Types */
++#define SK_PCI_BUS            BIT_0S          /* normal PCI bus */
++#define SK_PCIX_BUS           BIT_1S          /* PCI-X bus */
++#define SK_PEX_BUS            BIT_2S          /* PCI-Express bus */
+ /* Default receive frame limit for Workaround of XMAC Errata */
+ #define SK_DEF_RX_WA_LIM      SK_CONSTU64(100)
+ /* values for GILedBlinkCtrl (LED Blink Control) */
+-#define SK_ACT_LED_BLINK      (1<<0)  /* Active LED blinking */
+-#define SK_DUP_LED_NORMAL     (1<<1)  /* Duplex LED normal */
+-#define SK_LED_LINK100_ON     (1<<2)  /* Link 100M LED on */
++#define SK_ACT_LED_BLINK      BIT_0S  /* Active LED blinking */
++#define SK_DUP_LED_NORMAL     BIT_1S  /* Duplex LED normal */
++#define SK_LED_LINK100_ON     BIT_2S  /* Link 100M LED on */
++#define SK_DUAL_LED_ACT_LNK   BIT_3S  /* Dual LED ACT/LNK configuration */
+ /* Link Partner Status */
+ #define SK_LIPA_UNKNOWN       0       /* Link partner is in unknown state */
+@@ -290,18 +298,165 @@
+ /* Max. Auto-neg. timeouts before link detection in sense mode is reset */
+ #define SK_MAX_ANEG_TO        10      /* Max. 10 times the sense mode is reset */
++
++/******************************************************************************
++ *
++ * HW_FEATURE() macro
++ */
++
++/* DWORD 0: Features */
++#define HWF_RED_CORE_CLK_SUP  0x01000000UL    /* Reduced Core Clock supp. */
++#define HWF_SYNC_TX_SUP                       0x00800000UL    /* synch Tx queue available */
++#define HWF_SINGLE_PORT_DEVICE        0x00400000UL    /* device has only one LAN IF */
++#define HWF_JUMBO_FRAMES_SUP  0x00200000UL    /* Jumbo frames supported */
++#define HWF_TX_TCP_CSUM_SUP           0x00100000UL    /* TCP Tx checksum supported */
++#define HWF_TX_UDP_CSUM_SUP           0x00080000UL    /* UDP Tx checksum supported */
++#define HWF_RX_CSUM_SUP                       0x00040000UL    /* RX checksum supported */
++#define HWF_TCP_SEGM_SUP              0x00020000UL    /* TCP segmentation supported */
++#define HWF_RSS_HASH_SUP              0x00010000UL    /* RSS Hash supported */
++#define HWF_PORT_VLAN_SUP             0x00008000UL    /* VLAN can be config per port*/
++#define HWF_ROLE_PARAM_SUP            0x00004000UL    /* Role parameter supported */
++#define HWF_LOW_PMODE_SUP             0x00002000UL    /* Low Power Mode supported */
++#define HWF_ENERGIE_DEMO_SUP  0x00001000UL    /* Energie detect mode supp. */
++#define HWF_SPEED1000_SUP             0x00000800UL    /* Line Speed 1000 supported */
++#define HWF_SPEED100_SUP              0x00000400UL    /* Line Speed 100 supported */
++#define HWF_SPEED10_SUP                       0x00000200UL    /* Line Speed 10 supported */
++#define HWF_AUTONEGSENSE_SUP  0x00000100UL    /* Autoneg Sense supported */
++#define HWF_PHY_LOOPB_MD_SUP  0x00000080UL    /* PHY loopback mode supp. */
++#define HWF_ASF_SUP                           0x00000040UL    /* ASF support possible */
++#define HWF_QS_STEPS_1KB              0x00000020UL    /* The Rx/Tx queues can be */
++                                                                                              /* configured with 1 kB res. */
++#define HWF_OWN_RAM_PER_PORT  0x00000010UL    /* Each port has a separate */
++                                                                                              /* RAM buffer */
++#define HWF_MIN_LED_IF                        0x00000008UL    /* Minimal LED interface */
++                                                                                              /* (e.g. for Yukon-EC) */
++#define HWF_LIST_ELEMENTS_USED        0x00000004UL    /* HW uses list elements */
++                                                                                              /* (otherwise desc. are used) */
++#define HWF_GMAC_INSIDE                       0x00000002UL    /* device contains GMAC */
++#define HWF_TWSI_PRESENT              0x00000001UL    /* TWSI sensor bus present */
++
++/*-RMV- DWORD 1: Deviations */
++#define HWF_WA_DEV_4115                       0x10010000UL    /*-RMV- 4.115 (Rx MAC FIFO) */
++#define HWF_WA_DEV_4109                       0x10008000UL    /*-RMV- 4.109 (BIU hang) */
++#define HWF_WA_DEV_483                        0x10004000UL    /*-RMV- 4.83 (Rx TCP wrong) */
++#define HWF_WA_DEV_479                        0x10002000UL    /*-RMV- 4.79 (Rx BMU hang II) */
++#define HWF_WA_DEV_472                        0x10001000UL    /*-RMV- 4.72 (GPHY2 MDC clk) */
++#define HWF_WA_DEV_463                        0x10000800UL    /*-RMV- 4.63 (Rx BMU hang I) */
++#define HWF_WA_DEV_427                        0x10000400UL    /*-RMV- 4.27 (Tx Done Rep) */
++#define HWF_WA_DEV_42                 0x10000200UL    /*-RMV- 4.2 (pref unit burst) */
++#define HWF_WA_DEV_46                 0x10000100UL    /*-RMV- 4.6 (CPU crash II) */
++#define HWF_WA_DEV_43_418             0x10000080UL    /*-RMV- 4.3 & 4.18 (PCI unexp */
++                                                                                              /*-RMV- compl&Stat BMU deadl) */
++#define HWF_WA_DEV_420                        0x10000040UL    /*-RMV- 4.20 (Status BMU ov) */
++#define HWF_WA_DEV_423                        0x10000020UL    /*-RMV- 4.23 (TCP Segm Hang) */
++#define HWF_WA_DEV_424                        0x10000010UL    /*-RMV- 4.24 (MAC reg overwr) */
++#define HWF_WA_DEV_425                        0x10000008UL    /*-RMV- 4.25 (Magic packet */
++                                                                                              /*-RMV- with odd offset) */
++#define HWF_WA_DEV_428                        0x10000004UL    /*-RMV- 4.28 (Poll-U &BigEndi)*/
++#define HWF_WA_FIFO_FLUSH_YLA0        0x10000002UL    /*-RMV- dis Rx GMAC FIFO Flush*/
++                                                                                              /*-RMV- for Yu-L Rev. A0 only */
++#define HWF_WA_COMA_MODE              0x10000001UL    /*-RMV- Coma Mode WA req */
++
++/* DWORD 2: still unused */
++/* DWORD 3: still unused */
++
++
++/*
++ * HW_FEATURE()       -       returns whether the feature is serviced or not
++ */
++#define HW_FEATURE(pAC, ReqFeature) \
++      (((pAC)->GIni.HwF.Features[((ReqFeature) & 0x30000000UL) >> 28] &\
++       ((ReqFeature) & 0x0fffffffUL)) != 0)
++
++#define HW_FEAT_LIST  0
++#define HW_DEV_LIST           1
++
++#define SET_HW_FEATURE_MASK(pAC, List, OffMaskValue, OnMaskValue) {   \
++      if ((List) == HW_FEAT_LIST || (List) == HW_DEV_LIST) {                  \
++              (pAC)->GIni.HwF.OffMask[List] = (OffMaskValue);                         \
++              (pAC)->GIni.HwF.OnMask[List] = (OnMaskValue);                           \
++      }                                                                                                                               \
++}
++
++/* driver access macros for GIni structure ***********************************/
++
++#define CHIP_ID_YUKON_2(pAC)          ((pAC)->GIni.GIYukon2)
++#define HW_SYNC_TX_SUPPORTED(pAC)                                             \
++              ((pAC)->GIni.GIChipId != CHIP_ID_YUKON_EC &&    \
++               (pAC)->GIni.GIChipId != CHIP_ID_YUKON_FE)
++
++#define HW_MS_TO_TICKS(pAC, MsTime) \
++      ((MsTime) * (62500L/100) * (pAC)->GIni.GIHstClkFact)
++
++#ifdef XXX
++/* still under construction */
++#define HW_IS_SINGLE_PORT(pAC)                ((pAC)->GIni.GIMacsFound == 1)
++#define HW_NUMBER_OF_PORTS(pAC)               ((pAC)->GIni.GIMacsFound)
++
++#define HW_TX_UDP_CSUM_SUPPORTED(pAC) \
++      ((((pAC)->GIni.GIChipId >= CHIP_ID_YUKON) && ((pAC)->GIni.GIChipRev != 0))
++
++#define HW_DEFAULT_LINESPEED(pAC)     \
++      ((!(pAC)->GIni.GIGenesis && (pAC)->GIni.GICopperType) ? \
++      SK_LSPEED_AUTO : SK_LSPEED_1000MBPS)
++
++#define HW_ROLE_PARAM_SUPPORTED(pAC)  ((pAC)->GIni.GICopperType)
++
++#define HW_SPEED1000_SUPPORTED(pAC, Port)             \
++       ((pAC)->GIni.GP[Port].PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS)
++
++#define HW_SPEED100_SUPPORTED(pAC, Port)              \
++       ((pAC)->GIni.GP[Port].PLinkSpeedCap & SK_LSPEED_CAP_100MBPS)
++
++#define HW_SPEED10_SUPPORTED(pAC, Port)               \
++       ((pAC)->GIni.GP[Port].PLinkSpeedCap & SK_LSPEED_CAP_10MBPS)
++
++#define HW_AUTONEGSENSE_SUPPORTED(pAC)        ((pAC)->GIni.GP[0].PhyType==SK_PHY_XMAC)
++
++#define HW_FREQ_TO_CARD_TICKS(pAC, AdapterClkSpeed, Freq) \
++      (((AdapterClkSpeed / 100) * (pAC)->GIni.GIHstClkFact) / Freq)
++
++#define HW_IS_LINK_UP(pAC, Port)              ((pAC)->GIni.GP[Port].PHWLinkUp)
++#define HW_LINK_SPEED_USED(pAC, Port) ((pAC)->GIni.GP[Port].PLinkSpeedUsed)
++#define HW_RAM_SIZE(pAC)                              ((pAC)->GIni.GIRamSize)
++
++#define HW_PHY_LP_MODE_SUPPORTED(pAC) (pAC0->???
++#define HW_ASF_ACTIVE(pAC)                            ???
++#define RAWIO_OUT32(pAC, pAC->RegIrqMask, pAC->GIni.GIValIrqMask)...
++
++/* macro to check whether Tx checksum is supported */
++#define HW_TX_CSUM_SUPPORTED(pAC)     ((pAC)->GIni.GIChipId != CHIP_ID_GENESIS)
++
++BMU_UDP_CHECK : BMU_TCP_CHECK;
++
++/* macro for - Own Bit mirrored to DWORD7 (Yukon LP receive descriptor) */
++#endif /* 0 */
++
++
+ /* structures *****************************************************************/
+ /*
++ * HW Feature structure
++ */
++typedef struct s_HwFeatures {
++      SK_U32  Features[4];    /* Feature list */
++      SK_U32  OffMask[4];             /* Off Mask */
++      SK_U32  OnMask[4];              /* On Mask */
++} SK_HW_FEATURES;
++
++/*
+  * MAC specific functions
+  */
+ typedef struct s_GeMacFunc {
+-      int  (*pFnMacUpdateStats)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
+-      int  (*pFnMacStatistic)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
+-                                                      SK_U16 StatAddr, SK_U32 SK_FAR *pVal);
+-      int  (*pFnMacResetCounter)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
+-      int  (*pFnMacOverflow)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
+-                                                 SK_U16 IStatus, SK_U64 SK_FAR *pVal);
++      int     (*pFnMacUpdateStats)(SK_AC *, SK_IOC, unsigned int);
++      int     (*pFnMacStatistic)(SK_AC *, SK_IOC, unsigned int, SK_U16, SK_U32 SK_FAR *);
++      int     (*pFnMacResetCounter)(SK_AC *, SK_IOC, unsigned int);
++      int     (*pFnMacOverflow)(SK_AC *, SK_IOC, unsigned int, SK_U16, SK_U64 SK_FAR *);
++      void (*pSkGeSirqIsr)(SK_AC *, SK_IOC, SK_U32);
++#ifdef SK_DIAG
++      int     (*pFnMacPhyRead)(SK_AC *, SK_IOC, int, int, SK_U16 SK_FAR *);
++      int     (*pFnMacPhyWrite)(SK_AC *, SK_IOC, int, int, SK_U16);
++#endif /* SK_DIAG */
+ } SK_GEMACFUNC;
+ /*
+@@ -311,7 +466,7 @@
+ #ifndef SK_DIAG
+       SK_TIMER        PWaTimer;       /* Workaround Timer */
+       SK_TIMER        HalfDupChkTimer;
+-#endif /* SK_DIAG */
++#endif /* !SK_DIAG */
+       SK_U32  PPrevShorts;    /* Previous Short Counter checking */
+       SK_U32  PPrevFcs;               /* Previous FCS Error Counter checking */
+       SK_U64  PPrevRx;                /* Previous RxOk Counter checking */
+@@ -335,6 +490,7 @@
+       int             PXaQOff;                /* Asynchronous Tx Queue Address Offset */
+       int             PhyType;                /* PHY used on this port */
+       int             PState;                 /* Port status (reset, stop, init, run) */
++      int             PPortUsage;             /* Driver Port Usage */
+       SK_U16  PhyId1;                 /* PHY Id1 on this port */
+       SK_U16  PhyAddr;                /* MDIO/MDC PHY address */
+       SK_U16  PIsave;                 /* Saved Interrupt status word */
+@@ -367,6 +523,8 @@
+       int             PMacJamLen;             /* MAC Jam length */
+       int             PMacJamIpgVal;  /* MAC Jam IPG */
+       int             PMacJamIpgData; /* MAC IPG Jam to Data */
++      int             PMacBackOffLim; /* MAC Back-off Limit */
++      int             PMacDataBlind;  /* MAC Data Blinder */
+       int             PMacIpgData;    /* MAC Data IPG */
+       SK_BOOL PMacLimit4;             /* reset collision counter and backoff algorithm */
+ } SK_GEPORT;
+@@ -379,27 +537,37 @@
+       int                     GIChipId;               /* Chip Identification Number */
+       int                     GIChipRev;              /* Chip Revision Number */
+       SK_U8           GIPciHwRev;             /* PCI HW Revision Number */
++      SK_U8           GIPciBus;               /* PCI Bus Type (PCI / PCI-X / PCI-Express) */
++      SK_U8           GIPciMode;              /* PCI / PCI-X Mode @ Clock */
++      SK_U8           GIPexWidth;             /* PCI-Express Negotiated Link Width */
+       SK_BOOL         GIGenesis;              /* Genesis adapter ? */
+-      SK_BOOL         GIYukon;                /* YUKON-A1/Bx chip */
++      SK_BOOL         GIYukon;                /* YUKON family (1 and 2) */
+       SK_BOOL         GIYukonLite;    /* YUKON-Lite chip */
++      SK_BOOL         GIYukon2;               /* YUKON-2 chip (-XL, -EC or -FE) */
++      SK_U8           GIConTyp;               /* Connector Type */
++      SK_U8           GIPmdTyp;               /* PMD Type */
+       SK_BOOL         GICopperType;   /* Copper Type adapter ? */
+       SK_BOOL         GIPciSlot64;    /* 64-bit PCI Slot */
+       SK_BOOL         GIPciClock66;   /* 66 MHz PCI Clock */
+       SK_BOOL         GIVauxAvail;    /* VAUX available (YUKON) */
+       SK_BOOL         GIYukon32Bit;   /* 32-Bit YUKON adapter */
++      SK_BOOL         GIAsfEnabled;   /* ASF subsystem enabled */
++      SK_BOOL         GIAsfRunning;   /* ASF subsystem running */
+       SK_U16          GILedBlinkCtrl; /* LED Blink Control */
+       int                     GIMacsFound;    /* Number of MACs found on this adapter */
+       int                     GIMacType;              /* MAC Type used on this adapter */
+-      int                     GIHstClkFact;   /* Host Clock Factor (62.5 / HstClk * 100) */
+-      int                     GIPortUsage;    /* Driver Port Usage */
++      int                     GIChipCap;              /* Adapter's Capabilities */
++      int                     GIHstClkFact;   /* Host Clock Factor (HstClk / 62.5 * 100) */
+       int                     GILevel;                /* Initialization Level completed */
+       int                     GIRamSize;              /* The RAM size of the adapter in kB */
+       int                     GIWolOffs;              /* WOL Register Offset (HW-Bug in Rev. A) */
+       SK_U32          GIRamOffs;              /* RAM Address Offset for addr calculation */
+       SK_U32          GIPollTimerVal; /* Descr. Poll Timer Init Val (HstClk ticks) */
+       SK_U32          GIValIrqMask;   /* Value for Interrupt Mask */
++      SK_U32          GIValHwIrqMask; /* Value for Interrupt Mask */
+       SK_U32          GITimeStampCnt; /* Time Stamp High Counter (YUKON only) */
+       SK_GEPORT       GP[SK_MAX_MACS];/* Port Dependent Information */
++      SK_HW_FEATURES HwF;                     /* HW Features struct */
+       SK_GEMACFUNC GIFunc;            /* MAC depedent functions */
+ } SK_GEINIT;
+@@ -417,7 +585,7 @@
+ #define SKERR_HWI_E005                (SKERR_HWI_E004+1)
+ #define SKERR_HWI_E005MSG     "SkGeInitPort(): cannot init running ports"
+ #define SKERR_HWI_E006                (SKERR_HWI_E005+1)
+-#define SKERR_HWI_E006MSG     "SkGeMacInit(): PState does not match HW state"
++#define SKERR_HWI_E006MSG     "unused"
+ #define SKERR_HWI_E007                (SKERR_HWI_E006+1)
+ #define SKERR_HWI_E007MSG     "SkXmInitDupMd() called with invalid Dup Mode"
+ #define SKERR_HWI_E008                (SKERR_HWI_E007+1)
+@@ -433,11 +601,11 @@
+ #define SKERR_HWI_E013                (SKERR_HWI_E012+1)
+ #define SKERR_HWI_E013MSG     "SkGeInitPort(): cfg changed for running queue"
+ #define SKERR_HWI_E014                (SKERR_HWI_E013+1)
+-#define SKERR_HWI_E014MSG     "SkGeInitPort(): unknown GIPortUsage specified"
++#define SKERR_HWI_E014MSG     "SkGeInitPort(): unknown PortUsage specified"
+ #define SKERR_HWI_E015                (SKERR_HWI_E014+1)
+-#define SKERR_HWI_E015MSG     "Illegal Link mode parameter"
++#define SKERR_HWI_E015MSG     "Illegal Link Mode parameter"
+ #define SKERR_HWI_E016                (SKERR_HWI_E015+1)
+-#define SKERR_HWI_E016MSG     "Illegal Flow control mode parameter"
++#define SKERR_HWI_E016MSG     "Illegal Flow Control Mode parameter"
+ #define SKERR_HWI_E017                (SKERR_HWI_E016+1)
+ #define SKERR_HWI_E017MSG     "Illegal value specified for GIPollTimerVal"
+ #define SKERR_HWI_E018                (SKERR_HWI_E017+1)
+@@ -447,9 +615,9 @@
+ #define SKERR_HWI_E020                (SKERR_HWI_E019+1)
+ #define SKERR_HWI_E020MSG     "Illegal Master/Slave parameter"
+ #define SKERR_HWI_E021                (SKERR_HWI_E020+1)
+-#define       SKERR_HWI_E021MSG       "MacUpdateStats(): cannot update statistic counter"
+-#define       SKERR_HWI_E022          (SKERR_HWI_E021+1)
+-#define       SKERR_HWI_E022MSG       "MacStatistic(): illegal statistic base address"
++#define SKERR_HWI_E021MSG     "MacUpdateStats(): cannot update statistic counter"
++#define SKERR_HWI_E022                (SKERR_HWI_E021+1)
++#define SKERR_HWI_E022MSG     "MacStatistic(): illegal statistic base address"
+ #define SKERR_HWI_E023                (SKERR_HWI_E022+1)
+ #define SKERR_HWI_E023MSG     "SkGeInitPort(): Transmit Queue Size too small"
+ #define SKERR_HWI_E024                (SKERR_HWI_E023+1)
+@@ -464,6 +632,24 @@
+ /*
+  * public functions in skgeinit.c
+  */
++extern void SkGePortVlan(
++      SK_AC   *pAC,
++      SK_IOC  IoC,
++      int             Port,
++      SK_BOOL Enable);
++
++extern void SkGeRxRss(
++      SK_AC   *pAC,
++      SK_IOC  IoC,
++      int             Port,
++      SK_BOOL Enable);
++
++extern void SkGeRxCsum(
++      SK_AC   *pAC,
++      SK_IOC  IoC,
++      int             Port,
++      SK_BOOL Enable);
++
+ extern void   SkGePollRxD(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+@@ -601,13 +787,13 @@
+       int             Port,
+       SK_U16  IStatus);
+-extern void  SkMacSetRxTxEn(
++extern void   SkMacSetRxTxEn(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       int             Para);
+-extern int  SkMacRxTxEnable(
++extern int    SkMacRxTxEnable(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
+@@ -624,28 +810,28 @@
+       int             Port,
+       SK_BOOL Enable);
+-extern void   SkXmPhyRead(
++extern int    SkXmPhyRead(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       int             Addr,
+       SK_U16  SK_FAR *pVal);
+-extern void   SkXmPhyWrite(
++extern int    SkXmPhyWrite(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       int             Addr,
+       SK_U16  Val);
+-extern void   SkGmPhyRead(
++extern int    SkGmPhyRead(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+       int             Addr,
+       SK_U16  SK_FAR *pVal);
+-extern void   SkGmPhyWrite(
++extern int    SkGmPhyWrite(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port,
+@@ -713,7 +899,7 @@
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       unsigned int Port,
+-      SK_U16  IStatus,
++      SK_U16  IStatus,
+       SK_U64  SK_FAR *pStatus);
+ extern int SkGmOverflowStatus(
+@@ -729,6 +915,7 @@
+       int             Port,
+       SK_BOOL StartTest);
++#ifdef SK_PHY_LP_MODE
+ extern int SkGmEnterLowPowerMode(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+@@ -739,6 +926,7 @@
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+       int             Port);
++#endif /* SK_PHY_LP_MODE */
+ #ifdef SK_DIAG
+ extern void   SkGePhyRead(
+@@ -794,6 +982,9 @@
+ extern void   SkGeXmitLED();
+ extern void   SkGeInitRamIface();
+ extern int    SkGeInitAssignRamToQueues();
++extern void SkGePortVlan();
++extern void SkGeRxCsum();
++extern void SkGeRxRss();
+ /*
+  * public functions in skxmac2.c
+@@ -803,7 +994,7 @@
+ extern void   SkMacHardRst();
+ extern void   SkMacClearRst();
+ extern void SkMacInitPhy();
+-extern int  SkMacRxTxEnable();
++extern int    SkMacRxTxEnable();
+ extern void SkMacPromiscMode();
+ extern void SkMacHashing();
+ extern void SkMacIrqDisable();
+@@ -814,11 +1005,11 @@
+ extern void   SkMacAutoNegLipaPhy();
+ extern void SkMacSetRxTxEn();
+ extern void   SkXmInitMac();
+-extern void   SkXmPhyRead();
+-extern void   SkXmPhyWrite();
++extern int    SkXmPhyRead();
++extern int    SkXmPhyWrite();
+ extern void   SkGmInitMac();
+-extern void   SkGmPhyRead();
+-extern void   SkGmPhyWrite();
++extern int    SkGmPhyRead();
++extern int    SkGmPhyWrite();
+ extern void   SkXmClrExactAddr();
+ extern void   SkXmInitDupMd();
+ extern void   SkXmInitPauseMd();
+@@ -832,8 +1023,10 @@
+ extern int    SkXmOverflowStatus();
+ extern int    SkGmOverflowStatus();
+ extern int    SkGmCableDiagStatus();
++#ifdef SK_PHY_LP_MODE
+ extern int    SkGmEnterLowPowerMode();
+ extern int    SkGmLeaveLowPowerMode();
++#endif /* SK_PHY_LP_MODE */
+ #ifdef SK_DIAG
+ extern void   SkGePhyRead();
+@@ -844,10 +1037,11 @@
+ extern void   SkXmSendCont();
+ #endif /* SK_DIAG */
+-#endif        /* SK_KR_PROTO */
++#endif /* SK_KR_PROTO */
+ #ifdef __cplusplus
+ }
+ #endif        /* __cplusplus */
+ #endif        /* __INC_SKGEINIT_H_ */
++
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skgepnm2.h linux-2.6.9.new/drivers/net/sk98lin/h/skgepnm2.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skgepnm2.h   2004-10-19 05:54:38.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skgepnm2.h   2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgepnm2.h
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.36 $
+- * Date:      $Date: 2003/05/23 12:45:13 $
++ * Version:   $Revision: 2.4 $
++ * Date:      $Date: 2005/05/03 06:42:43 $
+  * Purpose:   Defines for Private Network Management Interface
+  *
+  ****************************************************************************/
+@@ -28,8 +28,13 @@
+ /*
+  * General definitions
+  */
+-#define SK_PNMI_CHIPSET_XMAC  1       /* XMAC11800FP */
+-#define SK_PNMI_CHIPSET_YUKON 2       /* YUKON */
++#define SK_PNMI_CHIPSET_XMAC          1       /* XMAC11800FP */
++#define SK_PNMI_CHIPSET_YUKON         2       /* YUKON */
++#define SK_PNMI_CHIPSET_YUKON_LITE    3       /* YUKON-Lite (Rev. A1-A3) */
++#define SK_PNMI_CHIPSET_YUKON_LP      4       /* YUKON-LP */
++#define SK_PNMI_CHIPSET_YUKON_XL      5       /* YUKON-2 XL */
++#define SK_PNMI_CHIPSET_YUKON_EC      6       /* YUKON-2 EC */
++#define SK_PNMI_CHIPSET_YUKON_FE      7       /* YUKON-2 FE */
+ #define       SK_PNMI_BUS_PCI         1       /* PCI bus*/
+@@ -70,9 +75,9 @@
+ /*
+  * VCT internal status values
+  */
+-#define SK_PNMI_VCT_PENDING   32
+-#define SK_PNMI_VCT_TEST_DONE 64
+-#define SK_PNMI_VCT_LINK      128
++#define SK_PNMI_VCT_PENDING           0x20
++#define SK_PNMI_VCT_TEST_DONE 0x40
++#define SK_PNMI_VCT_LINK              0x80
+ /*
+  * Internal table definitions
+@@ -323,7 +328,7 @@
+                                               vSt, \
+                                               pAC->Pnmi.MacUpdatedFlag, \
+                                               pAC->Pnmi.RlmtUpdatedFlag, \
+-                                              pAC->Pnmi.SirqUpdatedFlag))}}
++                                              pAC->Pnmi.SirqUpdatedFlag));}}
+ #else /* !DEBUG */
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skgepnmi.h linux-2.6.9.new/drivers/net/sk98lin/h/skgepnmi.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skgepnmi.h   2004-10-19 05:53:13.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skgepnmi.h   2006-12-07 14:35:03.000000000 +0800
+@@ -1,9 +1,9 @@
+ /*****************************************************************************
+  *
+  * Name:      skgepnmi.h
+- * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.62 $
+- * Date:      $Date: 2003/08/15 12:31:52 $
++ * Project:   Gigabit Ethernet Adapters, PNMI-Module
++ * Version:   $Revision: 2.9 $
++ * Date:      $Date: 2004/10/26 12:42:39 $
+  * Purpose:   Defines for Private Network Management Interface
+  *
+  ****************************************************************************/
+@@ -31,7 +31,7 @@
+ #include "h/sktypes.h"
+ #include "h/skerror.h"
+ #include "h/sktimer.h"
+-#include "h/ski2c.h"
++#include "h/sktwsi.h"
+ #include "h/skaddr.h"
+ #include "h/skrlmt.h"
+ #include "h/skvpd.h"
+@@ -41,7 +41,6 @@
+  */
+ #define SK_PNMI_MDB_VERSION           0x00030001      /* 3.1 */
+-
+ /*
+  * Event definitions
+  */
+@@ -54,16 +53,13 @@
+ #define SK_PNMI_EVT_UTILIZATION_TIMER 7       /* Timer event for Utiliza. */
+ #define SK_PNMI_EVT_CLEAR_COUNTER             8       /* Clear statistic counters */
+ #define SK_PNMI_EVT_XMAC_RESET                        9       /* XMAC will be reset */
+-
+ #define SK_PNMI_EVT_RLMT_PORT_UP              10      /* Port came logically up */
+ #define SK_PNMI_EVT_RLMT_PORT_DOWN            11      /* Port went logically down */
+ #define SK_PNMI_EVT_RLMT_SEGMENTATION 13      /* Two SP root bridges found */
+ #define SK_PNMI_EVT_RLMT_ACTIVE_DOWN  14      /* Port went logically down */
+ #define SK_PNMI_EVT_RLMT_ACTIVE_UP            15      /* Port came logically up */
+-#define SK_PNMI_EVT_RLMT_SET_NETS             16      /* 1. Parameter is number of nets
+-                                                                                              1 = single net; 2 = dual net */
+-#define SK_PNMI_EVT_VCT_RESET         17      /* VCT port reset timer event started with SET. */
+-
++#define SK_PNMI_EVT_RLMT_SET_NETS             16      /* Number of nets (1 or 2). */
++#define SK_PNMI_EVT_VCT_RESET                 17      /* VCT port reset timer event started with SET. */
+ /*
+  * Return values
+@@ -78,7 +74,6 @@
+ #define SK_PNMI_ERR_UNKNOWN_NET       7
+ #define SK_PNMI_ERR_NOT_SUPPORTED     10
+-
+ /*
+  * Return values of driver reset function SK_DRIVER_RESET() and
+  * driver event function SK_DRIVER_EVENT()
+@@ -86,19 +81,17 @@
+ #define SK_PNMI_ERR_OK                        0
+ #define SK_PNMI_ERR_FAIL              1
+-
+ /*
+  * Return values of driver test function SK_DRIVER_SELFTEST()
+  */
+ #define SK_PNMI_TST_UNKNOWN           (1 << 0)
+-#define SK_PNMI_TST_TRANCEIVER                (1 << 1)
++#define SK_PNMI_TST_TRANCEIVER        (1 << 1)
+ #define SK_PNMI_TST_ASIC              (1 << 2)
+ #define SK_PNMI_TST_SENSOR            (1 << 3)
+-#define SK_PNMI_TST_POWERMGMT         (1 << 4)
++#define SK_PNMI_TST_POWERMGMT (1 << 4)
+ #define SK_PNMI_TST_PCI                       (1 << 5)
+ #define SK_PNMI_TST_MAC                       (1 << 6)
+-
+ /*
+  * RLMT specific definitions
+  */
+@@ -352,6 +345,7 @@
+ #define OID_SKGE_VCT_GET                              0xFF020200
+ #define OID_SKGE_VCT_SET                              0xFF020201
+ #define OID_SKGE_VCT_STATUS                           0xFF020202
++#define OID_SKGE_VCT_CAPABILITIES             0xFF020203
+ #ifdef SK_DIAG_SUPPORT
+ /* Defines for driver DIAG mode. */
+@@ -367,22 +361,69 @@
+ #define OID_SKGE_PHY_TYPE                             0xFF020215
+ #define OID_SKGE_PHY_LP_MODE                  0xFF020216
++/*
++ * Added for new DualNet IM driver V2
++ * these OIDs should later  be in pnmi.h
++ */
++#define OID_SKGE_MAC_COUNT            0xFF020217
++#define OID_SKGE_DUALNET_MODE         0xFF020218
++#define OID_SKGE_SET_TAGHEADER        0xFF020219
++
++#ifdef SK_ASF
++/* Defines for ASF */
++#define OID_SKGE_ASF                    0xFF02021a
++#define OID_SKGE_ASF_STORE_CONFIG       0xFF02021b
++#define OID_SKGE_ASF_ENA                0xFF02021c
++#define OID_SKGE_ASF_RETRANS            0xFF02021d
++#define OID_SKGE_ASF_RETRANS_INT        0xFF02021e
++#define OID_SKGE_ASF_HB_ENA             0xFF02021f
++#define OID_SKGE_ASF_HB_INT             0xFF020220
++#define OID_SKGE_ASF_WD_ENA             0xFF020221
++#define OID_SKGE_ASF_WD_TIME            0xFF020222
++#define OID_SKGE_ASF_IP_SOURCE          0xFF020223
++#define OID_SKGE_ASF_MAC_SOURCE                       0xFF020224
++#define OID_SKGE_ASF_IP_DEST            0xFF020225
++#define OID_SKGE_ASF_MAC_DEST           0xFF020226
++#define OID_SKGE_ASF_COMMUNITY_NAME     0xFF020227
++#define OID_SKGE_ASF_RSP_ENA            0xFF020228  
++#define OID_SKGE_ASF_RETRANS_COUNT_MIN        0xFF020229
++#define OID_SKGE_ASF_RETRANS_COUNT_MAX        0xFF02022a
++#define OID_SKGE_ASF_RETRANS_INT_MIN  0xFF02022b
++#define OID_SKGE_ASF_RETRANS_INT_MAX  0xFF02022c
++#define OID_SKGE_ASF_HB_INT_MIN                       0xFF02022d
++#define OID_SKGE_ASF_HB_INT_MAX                       0xFF02022e
++#define OID_SKGE_ASF_WD_TIME_MIN              0xFF02022f
++#define OID_SKGE_ASF_WD_TIME_MAX              0xFF020230
++#define OID_SKGE_ASF_HB_CAP                           0xFF020231
++#define OID_SKGE_ASF_WD_TIMER_RES             0xFF020232
++#define OID_SKGE_ASF_GUID                             0xFF020233
++#define OID_SKGE_ASF_KEY_OP                           0xFF020234
++#define OID_SKGE_ASF_KEY_ADM                  0xFF020235
++#define OID_SKGE_ASF_KEY_GEN                  0xFF020236
++#define OID_SKGE_ASF_CAP                              0xFF020237
++#define OID_SKGE_ASF_PAR_1                            0xFF020238
++#define OID_SKGE_ASF_OVERALL_OID        0xFF020239
++#define OID_SKGE_ASF_FWVER_OID          0xFF020240
++#define OID_SKGE_ASF_ACPI_OID           0xFF020241
++#define OID_SKGE_ASF_SMBUS_OID          0xFF020242
++#endif /* SK_ASF */
++
+ /* VCT struct to store a backup copy of VCT data after a port reset. */
+ typedef struct s_PnmiVct {
+       SK_U8                   VctStatus;
+-      SK_U8                   PCableLen;
+-      SK_U32                  PMdiPairLen[4];
+-      SK_U8                   PMdiPairSts[4];
++      SK_U8                   CableLen;
++      SK_U32                  MdiPairLen[4];
++      SK_U8                   MdiPairSts[4];
+ } SK_PNMI_VCT;
+ /* VCT status values (to be given to CPA via OID_SKGE_VCT_STATUS). */
+-#define SK_PNMI_VCT_NONE              0
+-#define SK_PNMI_VCT_OLD_VCT_DATA      1
+-#define SK_PNMI_VCT_NEW_VCT_DATA      2
+-#define SK_PNMI_VCT_OLD_DSP_DATA      4
+-#define SK_PNMI_VCT_NEW_DSP_DATA      8
+-#define SK_PNMI_VCT_RUNNING           16
++#define SK_PNMI_VCT_NONE                      0x00
++#define SK_PNMI_VCT_OLD_VCT_DATA      0x01
++#define SK_PNMI_VCT_NEW_VCT_DATA      0x02
++#define SK_PNMI_VCT_OLD_DSP_DATA      0x04
++#define SK_PNMI_VCT_NEW_DSP_DATA      0x08
++#define SK_PNMI_VCT_RUNNING                   0x10
+ /* VCT cable test status. */
+@@ -390,7 +431,12 @@
+ #define SK_PNMI_VCT_SHORT_CABLE                       1
+ #define SK_PNMI_VCT_OPEN_CABLE                        2
+ #define SK_PNMI_VCT_TEST_FAIL                 3
+-#define SK_PNMI_VCT_IMPEDANCE_MISMATCH                4
++#define SK_PNMI_VCT_IMPEDANCE_MISMATCH        4
++#define SK_PNMI_VCT_NOT_PRESENT                       5
++
++/* VCT capabilities (needed for OID_SKGE_VCT_CAPABILITIES. */
++#define SK_PNMI_VCT_SUPPORTED                 1
++#define SK_PNMI_VCT_NOT_SUPPORTED             0
+ #define       OID_SKGE_TRAP_SEN_WAR_LOW               500
+ #define OID_SKGE_TRAP_SEN_WAR_UPP             501
+@@ -419,7 +465,6 @@
+ #define       SK_SET_FULL_MIB                 5
+ #define       SK_PRESET_FULL_MIB              6
+-
+ /*
+  * Define error numbers and messages for syslog
+  */
+@@ -452,7 +497,7 @@
+ #define SK_PNMI_ERR014                (SK_ERRBASE_PNMI + 14)
+ #define SK_PNMI_ERR014MSG     "Vpd: Cannot read VPD keys"
+ #define SK_PNMI_ERR015                (SK_ERRBASE_PNMI + 15)
+-#define SK_PNMI_ERR015MSG     "Vpd: Internal array for VPD keys to small"
++#define SK_PNMI_ERR015MSG     "Vpd: Internal array for VPD keys too small"
+ #define SK_PNMI_ERR016                (SK_ERRBASE_PNMI + 16)
+ #define SK_PNMI_ERR016MSG     "Vpd: Key string too long"
+ #define SK_PNMI_ERR017                (SK_ERRBASE_PNMI + 17)
+@@ -494,9 +539,9 @@
+ #define SK_PNMI_ERR036                (SK_ERRBASE_PNMI + 36)
+ #define SK_PNMI_ERR036MSG     ""
+ #define SK_PNMI_ERR037                (SK_ERRBASE_PNMI + 37)
+-#define SK_PNMI_ERR037MSG     "Rlmt: SK_RLMT_MODE_CHANGE event return not 0"
++#define SK_PNMI_ERR037MSG     "Rlmt: SK_RLMT_MODE_CHANGE event returned not 0"
+ #define SK_PNMI_ERR038                (SK_ERRBASE_PNMI + 38)
+-#define SK_PNMI_ERR038MSG     "Rlmt: SK_RLMT_PREFPORT_CHANGE event return not 0"
++#define SK_PNMI_ERR038MSG     "Rlmt: SK_RLMT_PREFPORT_CHANGE event returned not 0"
+ #define SK_PNMI_ERR039                (SK_ERRBASE_PNMI + 39)
+ #define SK_PNMI_ERR039MSG     "RlmtStat: Unknown OID"
+ #define SK_PNMI_ERR040                (SK_ERRBASE_PNMI + 40)
+@@ -514,9 +559,9 @@
+ #define SK_PNMI_ERR046                (SK_ERRBASE_PNMI + 46)
+ #define SK_PNMI_ERR046MSG     "Monitor: Unknown OID"
+ #define SK_PNMI_ERR047                (SK_ERRBASE_PNMI + 47)
+-#define SK_PNMI_ERR047MSG     "SirqUpdate: Event function returns not 0"
++#define SK_PNMI_ERR047MSG     "SirqUpdate: Event function returned not 0"
+ #define SK_PNMI_ERR048                (SK_ERRBASE_PNMI + 48)
+-#define SK_PNMI_ERR048MSG     "RlmtUpdate: Event function returns not 0"
++#define SK_PNMI_ERR048MSG     "RlmtUpdate: Event function returned not 0"
+ #define SK_PNMI_ERR049                (SK_ERRBASE_PNMI + 49)
+ #define SK_PNMI_ERR049MSG     "SkPnmiInit: Invalid size of 'CounterOffset' struct!!"
+ #define SK_PNMI_ERR050                (SK_ERRBASE_PNMI + 50)
+@@ -826,23 +871,25 @@
+ } SK_PNMI_STRUCT_DATA;
+ #define SK_PNMI_STRUCT_SIZE   (sizeof(SK_PNMI_STRUCT_DATA))
++
++/* The ReturnStatus field must be located before VpdFreeBytes! */
+ #define SK_PNMI_MIN_STRUCT_SIZE       ((unsigned int)(SK_UPTR)\
+                                &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes))
+-                                                                                                              /*
+-                                                                                                               * ReturnStatus field
+-                                                                                                               * must be located
+-                                                                                                               * before VpdFreeBytes
+-                                                                                                               */
+ /*
+  * Various definitions
+  */
++#define SK_PNMI_EVT_TIMER_CHECK               28125000L       /* 28125 ms */
++
++#define SK_PNMI_VCT_TIMER_CHECK                4000000L       /* 4 sec. */
++
+ #define SK_PNMI_MAX_PROTOS            3
+-#define SK_PNMI_CNT_NO                        66      /* Must have the value of the enum
+-                                                                       * SK_PNMI_MAX_IDX. Define SK_PNMI_CHECK
+-                                                                       * for check while init phase 1
+-                                                                       */
++/*
++ * SK_PNMI_CNT_NO must have the value of the enum SK_PNMI_MAX_IDX.
++ * Define SK_PNMI_CHECK to check this during init level SK_INIT_IO.
++ */
++#define SK_PNMI_CNT_NO                        66
+ /*
+  * Estimate data structure
+@@ -856,14 +903,6 @@
+ /*
+- * VCT timer data structure
+- */
+-typedef struct s_VctTimer {
+-      SK_TIMER                VctTimer;
+-} SK_PNMI_VCT_TIMER;
+-
+-
+-/*
+  * PNMI specific adapter context structure
+  */
+ typedef struct s_PnmiPort {
+@@ -933,9 +972,9 @@
+       unsigned int    TrapQueueEnd;
+       unsigned int    TrapBufPad;
+       unsigned int    TrapUnique;
+-      SK_U8           VctStatus[SK_MAX_MACS];
+-      SK_PNMI_VCT     VctBackup[SK_MAX_MACS];
+-      SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS];
++      SK_U8                   VctStatus[SK_MAX_MACS];
++      SK_PNMI_VCT             VctBackup[SK_MAX_MACS];
++      SK_TIMER                VctTimeout[SK_MAX_MACS];
+ #ifdef SK_DIAG_SUPPORT
+       SK_U32                  DiagAttached;
+ #endif /* SK_DIAG_SUPPORT */
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skgesirq.h linux-2.6.9.new/drivers/net/sk98lin/h/skgesirq.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skgesirq.h   2004-10-19 05:55:17.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skgesirq.h   2006-12-07 14:35:03.000000000 +0800
+@@ -2,22 +2,21 @@
+  *
+  * Name:      skgesirq.h
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.30 $
+- * Date:      $Date: 2003/07/04 12:34:13 $
+- * Purpose:   SK specific Gigabit Ethernet special IRQ functions
++ * Version:   $Revision: 2.3 $
++ * Date:      $Date: 2004/05/28 14:42:03 $
++ * Purpose:   Gigabit Ethernet special IRQ functions
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2004 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+  *    the Free Software Foundation; either version 2 of the License, or
+  *    (at your option) any later version.
+- *
+  *    The information in this file is provided "AS IS" without warranty.
+  *
+  ******************************************************************************/
+@@ -44,10 +43,10 @@
+ #define SK_HWEV_SET_SPEED             9       /* Set Link Speed by PNMI */
+ #define SK_HWEV_HALFDUP_CHK           10      /* Half Duplex Hangup Workaround */
+-#define SK_WA_ACT_TIME                (5000000UL)     /* 5 sec */
+-#define SK_WA_INA_TIME                (100000UL)      /* 100 msec */
++#define SK_WA_ACT_TIME                1000000UL       /* 1000 msec (1 sec) */
++#define SK_WA_INA_TIME                 100000UL       /*  100 msec */
+-#define SK_HALFDUP_CHK_TIME   (10000UL)       /* 10 msec */
++#define SK_HALFDUP_CHK_TIME     10000UL       /*   10 msec */
+ /*
+  * Define the error numbers and messages
+@@ -102,10 +101,35 @@
+ #define SKERR_SIRQ_E024MSG    "FIFO overflow error"
+ #define SKERR_SIRQ_E025               (SKERR_SIRQ_E024+1)
+ #define SKERR_SIRQ_E025MSG    "2 Pair Downshift detected"
++#define SKERR_SIRQ_E026               (SKERR_SIRQ_E025+1)
++#define SKERR_SIRQ_E026MSG    "Uncorrectable PCI Express error"
++#define SKERR_SIRQ_E027               (SKERR_SIRQ_E026+1)
++#define SKERR_SIRQ_E027MSG    "PCI express protocol violation error"
++#define SKERR_SIRQ_E028               (SKERR_SIRQ_E027+1)
++#define SKERR_SIRQ_E028MSG    "Parity error on RAM 1 (read)"
++#define SKERR_SIRQ_E029               (SKERR_SIRQ_E028+1)
++#define SKERR_SIRQ_E029MSG    "Parity error on RAM 1 (write)"
++#define SKERR_SIRQ_E030               (SKERR_SIRQ_E029+1)
++#define SKERR_SIRQ_E030MSG    "Parity error on RAM 2 (read)"
++#define SKERR_SIRQ_E031               (SKERR_SIRQ_E030+1)
++#define SKERR_SIRQ_E031MSG    "Parity error on RAM 2 (write)"
++#define SKERR_SIRQ_E032               (SKERR_SIRQ_E031+1)
++#define SKERR_SIRQ_E032MSG    "TCP segmentation error async. queue 1"
++#define SKERR_SIRQ_E033               (SKERR_SIRQ_E032+1)
++#define SKERR_SIRQ_E033MSG    "TCP segmentation error sync. queue 1"
++#define SKERR_SIRQ_E034               (SKERR_SIRQ_E033+1)
++#define SKERR_SIRQ_E034MSG    "TCP segmentation error async. queue 2"
++#define SKERR_SIRQ_E035               (SKERR_SIRQ_E034+1)
++#define SKERR_SIRQ_E035MSG    "TCP segmentation error sync. queue 2"
++#define SKERR_SIRQ_E036               (SKERR_SIRQ_E035+1)
++#define SKERR_SIRQ_E036MSG    "CHECK failure polling unit"
+ extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus);
+ extern int  SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
+ extern void SkHWLinkUp(SK_AC *pAC, SK_IOC IoC, int Port);
+ extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port);
++extern void SkGeYuSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus);
++extern void SkYuk2SirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus);
+ #endif        /* _INC_SKGESIRQ_H_ */
++
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skgetwsi.h linux-2.6.9.new/drivers/net/sk98lin/h/skgetwsi.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skgetwsi.h   1970-01-01 08:00:00.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skgetwsi.h   2006-12-07 14:35:03.000000000 +0800
+@@ -0,0 +1,241 @@
++/******************************************************************************
++ *
++ * Name:      skgetwsi.h
++ * Project:   Gigabit Ethernet Adapters, TWSI-Module
++ * Version:   $Revision: 1.7 $
++ * Date:      $Date: 2004/12/20 14:48:51 $
++ * Purpose:   Special defines for TWSI
++ *
++ ******************************************************************************/
++
++/******************************************************************************
++ *
++ *    (C)Copyright 1998-2002 SysKonnect.
++ *    (C)Copyright 2002-2004 Marvell.
++ *
++ *    This program is free software; you can redistribute it and/or modify
++ *    it under the terms of the GNU General Public License as published by
++ *    the Free Software Foundation; either version 2 of the License, or
++ *    (at your option) any later version.
++ *    The information in this file is provided "AS IS" without warranty.
++ *
++ ******************************************************************************/
++
++/*
++ * SKGETWSI.H contains all SK-98xx specific defines for the TWSI handling
++ */
++
++#ifndef _INC_SKGETWSI_H_
++#define _INC_SKGETWSI_H_
++
++/*
++ * Macros to access the B2_I2C_CTRL
++ */
++#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \
++      SK_OUT32(IoC, B2_I2C_CTRL,\
++              (flag ? 0x80000000UL : 0x0L) | \
++              (((SK_U32)reg << 16) & I2C_ADDR) | \
++              (((SK_U32)dev << 9) & I2C_DEV_SEL) | \
++              (dev_size & I2C_DEV_SIZE) | \
++              ((burst << 4) & I2C_BURST_LEN))
++
++#define SK_I2C_STOP(IoC) {                    \
++      SK_U32  I2cCtrl;                                \
++      SK_IN32(IoC, B2_I2C_CTRL, &I2cCtrl);            \
++      SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP); \
++}
++
++#define SK_I2C_GET_CTL(IoC, pI2cCtrl) SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl)
++
++/*
++ * Macros to access the TWSI SW Registers
++ */
++#define SK_I2C_SET_BIT(IoC, SetBits) {                        \
++      SK_U8   OrgBits;                                \
++      SK_IN8(IoC, B2_I2C_SW, &OrgBits);               \
++      SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits));    \
++}
++
++#define SK_I2C_CLR_BIT(IoC, ClrBits) {                        \
++      SK_U8   OrgBits;                                \
++      SK_IN8(IoC, B2_I2C_SW, &OrgBits);               \
++      SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits))); \
++}
++
++#define SK_I2C_GET_SW(IoC, pI2cSw)    SK_IN8(IoC, B2_I2C_SW, pI2cSw)
++
++/*
++ * define the possible sensor states
++ */
++#define SK_SEN_IDLE           0       /* Idle: sensor not read */
++#define SK_SEN_VALUE  1       /* Value Read cycle */
++#define SK_SEN_VALEXT 2       /* Extended Value Read cycle */
++
++/*
++ * Conversion factor to convert read Voltage sensor to milli Volt
++ * Conversion factor to convert read Temperature sensor to 10th degree Celsius
++ */
++#define SK_LM80_VT_LSB                22      /* 22mV LSB resolution */
++#define SK_LM80_TEMP_LSB      10      /* 1 degree LSB resolution */
++#define SK_LM80_TEMPEXT_LSB    5      /* 0.5 degree LSB resolution for ext. val. */
++
++/*
++ * formula: counter = (22500*60)/(rpm * divisor * pulses/2)
++ * assuming: 6500rpm, 4 pulses, divisor 1
++ */
++#define SK_LM80_FAN_FAKTOR    ((22500L*60)/(1*2))
++
++/*
++ * Define sensor management data
++ * Maximum is reached on Genesis copper dual port and Yukon-64
++ * Board specific maximum is in pAC->I2c.MaxSens
++ */
++#define SK_MAX_SENSORS        8       /* maximal no. of installed sensors */
++#define SK_MIN_SENSORS        5       /* minimal no. of installed sensors */
++
++/*
++ * To watch the state machine (SM) use the timer in two ways
++ * instead of one as hitherto
++ */
++#define SK_TIMER_WATCH_SM             0       /* Watch the SM to finish in a spec. time */
++#define SK_TIMER_NEW_GAUGING  1       /* Start a new gauging when timer expires */
++
++/*
++ * Defines for the individual thresholds
++ */
++
++#define C_PLUS_20             120 / 100
++#define C_PLUS_15             115 / 100
++#define C_PLUS_10             110 / 100
++#define C_PLUS_5              105 / 100
++#define C_MINUS_5              95 / 100
++#define C_MINUS_10             90 / 100
++#define C_MINUS_15             85 / 100
++
++/* Temperature sensor */
++#define SK_SEN_TEMP_HIGH_ERR  800     /* Temperature High Err  Threshold */
++#define SK_SEN_TEMP_HIGH_WARN 700     /* Temperature High Warn Threshold */
++#define SK_SEN_TEMP_LOW_WARN  100     /* Temperature Low  Warn Threshold */
++#define SK_SEN_TEMP_LOW_ERR             0     /* Temperature Low  Err  Threshold */
++
++/* VCC which should be 5 V */
++#define SK_SEN_PCI_5V_HIGH_ERR                5588    /* Voltage PCI High Err  Threshold */
++#define SK_SEN_PCI_5V_HIGH_WARN               5346    /* Voltage PCI High Warn Threshold */
++#define SK_SEN_PCI_5V_LOW_WARN                4664    /* Voltage PCI Low  Warn Threshold */
++#define SK_SEN_PCI_5V_LOW_ERR         4422    /* Voltage PCI Low  Err  Threshold */
++
++/*
++ * VIO may be 5 V or 3.3 V. Initialization takes two parts:
++ * 1. Initialize lowest lower limit and highest higher limit.
++ * 2. After the first value is read correct the upper or the lower limit to
++ *    the appropriate C constant.
++ *
++ * Warning limits are +-5% of the exepected voltage.
++ * Error limits are +-10% of the expected voltage.
++ */
++
++/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */
++
++#define SK_SEN_PCI_IO_5V_HIGH_ERR     5566    /* + 10% V PCI-IO High Err Threshold */
++#define SK_SEN_PCI_IO_5V_HIGH_WARN    5324    /* +  5% V PCI-IO High Warn Threshold */
++                                      /*              5000    mVolt */
++#define SK_SEN_PCI_IO_5V_LOW_WARN     4686    /* -  5% V PCI-IO Low Warn Threshold */
++#define SK_SEN_PCI_IO_5V_LOW_ERR      4444    /* - 10% V PCI-IO Low Err Threshold */
++
++#define SK_SEN_PCI_IO_RANGE_LIMITER   4000    /* 4000 mV range delimiter */
++
++/* correction values for the second pass */
++#define SK_SEN_PCI_IO_3V3_HIGH_ERR    3850    /* + 15% V PCI-IO High Err Threshold */
++#define SK_SEN_PCI_IO_3V3_HIGH_WARN   3674    /* + 10% V PCI-IO High Warn Threshold */
++                                      /*              3300    mVolt */
++#define SK_SEN_PCI_IO_3V3_LOW_WARN    2926    /* - 10% V PCI-IO Low Warn Threshold */
++#define SK_SEN_PCI_IO_3V3_LOW_ERR     2772    /* - 15% V PCI-IO Low Err  Threshold */
++
++/*
++ * VDD voltage
++ */
++#define SK_SEN_VDD_HIGH_ERR           3630    /* Voltage ASIC High Err  Threshold */
++#define SK_SEN_VDD_HIGH_WARN  3476    /* Voltage ASIC High Warn Threshold */
++#define SK_SEN_VDD_LOW_WARN           3146    /* Voltage ASIC Low  Warn Threshold */
++#define SK_SEN_VDD_LOW_ERR            2970    /* Voltage ASIC Low  Err  Threshold */
++
++/*
++ * PHY PLL 3V3 voltage
++ */
++#define SK_SEN_PLL_3V3_HIGH_ERR               3630    /* Voltage PMA High Err  Threshold */
++#define SK_SEN_PLL_3V3_HIGH_WARN      3476    /* Voltage PMA High Warn Threshold */
++#define SK_SEN_PLL_3V3_LOW_WARN               3146    /* Voltage PMA Low  Warn Threshold */
++#define SK_SEN_PLL_3V3_LOW_ERR                2970    /* Voltage PMA Low  Err  Threshold */
++
++/*
++ * VAUX (YUKON only)
++ */
++#define SK_SEN_VAUX_3V3_VAL           3300    /* Voltage VAUX 3.3 Volt */
++
++#define SK_SEN_VAUX_3V3_HIGH_ERR      (SK_I32)(SK_SEN_VAUX_3V3_VAL * C_PLUS_10)
++#define SK_SEN_VAUX_3V3_HIGH_WARN     (SK_I32)(SK_SEN_VAUX_3V3_VAL * C_PLUS_5)
++#define SK_SEN_VAUX_3V3_LOW_WARN      (SK_I32)(SK_SEN_VAUX_3V3_VAL * C_MINUS_5)
++#define SK_SEN_VAUX_3V3_LOW_ERR               (SK_I32)(SK_SEN_VAUX_3V3_VAL * C_MINUS_10)
++
++#define SK_SEN_VAUX_RANGE_LIMITER     1000    /* 1000 mV range delimiter */
++
++/*
++ * PHY 2V5 voltage
++ */
++#define SK_SEN_PHY_2V5_VAL            2500    /* Voltage PHY 2.5 Volt */
++
++#define SK_SEN_PHY_2V5_HIGH_ERR               (SK_I32)(SK_SEN_PHY_2V5_VAL * C_PLUS_10)
++#define SK_SEN_PHY_2V5_HIGH_WARN      (SK_I32)(SK_SEN_PHY_2V5_VAL * C_PLUS_5)
++#define SK_SEN_PHY_2V5_LOW_WARN               (SK_I32)(SK_SEN_PHY_2V5_VAL * C_MINUS_5)
++#define SK_SEN_PHY_2V5_LOW_ERR                (SK_I32)(SK_SEN_PHY_2V5_VAL * C_MINUS_10)
++
++/*
++ * ASIC Core 1V5 voltage (YUKON only)
++ */
++#define SK_SEN_CORE_1V5_VAL           1500    /* Voltage ASIC Core 1.5 Volt */
++
++#define SK_SEN_CORE_1V5_HIGH_ERR      (SK_I32)(SK_SEN_CORE_1V5_VAL * C_PLUS_10)
++#define SK_SEN_CORE_1V5_HIGH_WARN     (SK_I32)(SK_SEN_CORE_1V5_VAL * C_PLUS_5)
++#define SK_SEN_CORE_1V5_LOW_WARN      (SK_I32)(SK_SEN_CORE_1V5_VAL * C_MINUS_5)
++#define SK_SEN_CORE_1V5_LOW_ERR       (SK_I32)(SK_SEN_CORE_1V5_VAL * C_MINUS_10)
++
++/*
++ * ASIC Core 1V2 (1V3) voltage (YUKON-2 only)
++ */
++#define SK_SEN_CORE_1V2_VAL           1200    /* Voltage ASIC Core 1.2 Volt */
++
++#define SK_SEN_CORE_1V2_HIGH_ERR      (SK_I32)(SK_SEN_CORE_1V2_VAL * C_PLUS_20)
++#define SK_SEN_CORE_1V2_HIGH_WARN     (SK_I32)(SK_SEN_CORE_1V2_VAL * C_PLUS_15)
++#define SK_SEN_CORE_1V2_LOW_WARN      (SK_I32)(SK_SEN_CORE_1V2_VAL * C_MINUS_5)
++#define SK_SEN_CORE_1V2_LOW_ERR       (SK_I32)(SK_SEN_CORE_1V2_VAL * C_MINUS_10)
++
++#define SK_SEN_CORE_1V3_VAL           1300    /* Voltage ASIC Core 1.3 Volt */
++
++#define SK_SEN_CORE_1V3_HIGH_ERR      (SK_I32)(SK_SEN_CORE_1V3_VAL * C_PLUS_15)
++#define SK_SEN_CORE_1V3_HIGH_WARN     (SK_I32)(SK_SEN_CORE_1V3_VAL * C_PLUS_10)
++#define SK_SEN_CORE_1V3_LOW_WARN      (SK_I32)(SK_SEN_CORE_1V3_VAL * C_MINUS_5)
++#define SK_SEN_CORE_1V3_LOW_ERR       (SK_I32)(SK_SEN_CORE_1V3_VAL * C_MINUS_10)
++
++/*
++ * FAN 1 speed
++ */
++/* assuming: 6500rpm +-15%, 4 pulses,
++ * warning at:        80 %
++ * error at:  70 %
++ * no upper limit
++ */
++#define SK_SEN_FAN_HIGH_ERR           20000   /* FAN Speed High Err Threshold */
++#define SK_SEN_FAN_HIGH_WARN  20000   /* FAN Speed High Warn Threshold */
++#define SK_SEN_FAN_LOW_WARN            5200   /* FAN Speed Low Warn Threshold */
++#define SK_SEN_FAN_LOW_ERR             4550   /* FAN Speed Low Err Threshold */
++
++/*
++ * Some Voltages need dynamic thresholds
++ */
++#define SK_SEN_DYN_INIT_NONE           0  /* No dynamic init of thresholds */
++#define SK_SEN_DYN_INIT_PCI_IO                10  /* Init PCI-IO with new thresholds */
++#define SK_SEN_DYN_INIT_VAUX          11  /* Init VAUX with new thresholds */
++
++extern        int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
++#endif        /* n_INC_SKGETWSI_H */
++
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/ski2c.h linux-2.6.9.new/drivers/net/sk98lin/h/ski2c.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/ski2c.h      2004-10-19 05:53:45.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/ski2c.h      1970-01-01 08:00:00.000000000 +0800
+@@ -1,177 +0,0 @@
+-/******************************************************************************
+- *
+- * Name:      ski2c.h
+- * Project:   Gigabit Ethernet Adapters, TWSI-Module
+- * Version:   $Revision: 1.35 $
+- * Date:      $Date: 2003/10/20 09:06:30 $
+- * Purpose:   Defines to access Voltage and Temperature Sensor
+- *
+- ******************************************************************************/
+-
+-/******************************************************************************
+- *
+- *    (C)Copyright 1998-2002 SysKonnect.
+- *    (C)Copyright 2002-2003 Marvell.
+- *
+- *    This program is free software; you can redistribute it and/or modify
+- *    it under the terms of the GNU General Public License as published by
+- *    the Free Software Foundation; either version 2 of the License, or
+- *    (at your option) any later version.
+- *
+- *    The information in this file is provided "AS IS" without warranty.
+- *
+- ******************************************************************************/
+-
+-/*
+- * SKI2C.H    contains all I2C specific defines
+- */
+-
+-#ifndef _SKI2C_H_
+-#define _SKI2C_H_
+-
+-typedef struct  s_Sensor SK_SENSOR;
+-
+-#include "h/skgei2c.h"
+-
+-/*
+- * Define the I2C events.
+- */
+-#define SK_I2CEV_IRQ  1       /* IRQ happened Event */
+-#define SK_I2CEV_TIM  2       /* Timeout event */
+-#define SK_I2CEV_CLEAR        3       /* Clear MIB Values */
+-
+-/*
+- * Define READ and WRITE Constants.
+- */
+-#define I2C_READ      0
+-#define I2C_WRITE     1
+-#define I2C_BURST     1
+-#define I2C_SINGLE    0
+-
+-#define SKERR_I2C_E001                (SK_ERRBASE_I2C+0)
+-#define SKERR_I2C_E001MSG     "Sensor index unknown"
+-#define SKERR_I2C_E002                (SKERR_I2C_E001+1)
+-#define SKERR_I2C_E002MSG     "TWSI: transfer does not complete"
+-#define SKERR_I2C_E003                (SKERR_I2C_E002+1)
+-#define SKERR_I2C_E003MSG     "LM80: NAK on device send"
+-#define SKERR_I2C_E004                (SKERR_I2C_E003+1)
+-#define SKERR_I2C_E004MSG     "LM80: NAK on register send"
+-#define SKERR_I2C_E005                (SKERR_I2C_E004+1)
+-#define SKERR_I2C_E005MSG     "LM80: NAK on device (2) send"
+-#define SKERR_I2C_E006                (SKERR_I2C_E005+1)
+-#define SKERR_I2C_E006MSG     "Unknown event"
+-#define SKERR_I2C_E007                (SKERR_I2C_E006+1)
+-#define SKERR_I2C_E007MSG     "LM80 read out of state"
+-#define SKERR_I2C_E008                (SKERR_I2C_E007+1)
+-#define SKERR_I2C_E008MSG     "Unexpected sensor read completed"
+-#define SKERR_I2C_E009                (SKERR_I2C_E008+1)
+-#define SKERR_I2C_E009MSG     "WARNING: temperature sensor out of range"
+-#define SKERR_I2C_E010                (SKERR_I2C_E009+1)
+-#define SKERR_I2C_E010MSG     "WARNING: voltage sensor out of range"
+-#define SKERR_I2C_E011                (SKERR_I2C_E010+1)
+-#define SKERR_I2C_E011MSG     "ERROR: temperature sensor out of range"
+-#define SKERR_I2C_E012                (SKERR_I2C_E011+1)
+-#define SKERR_I2C_E012MSG     "ERROR: voltage sensor out of range"
+-#define SKERR_I2C_E013                (SKERR_I2C_E012+1)
+-#define SKERR_I2C_E013MSG     "ERROR: couldn't init sensor"
+-#define SKERR_I2C_E014                (SKERR_I2C_E013+1)
+-#define SKERR_I2C_E014MSG     "WARNING: fan sensor out of range"
+-#define SKERR_I2C_E015                (SKERR_I2C_E014+1)
+-#define SKERR_I2C_E015MSG     "ERROR: fan sensor out of range"
+-#define SKERR_I2C_E016                (SKERR_I2C_E015+1)
+-#define SKERR_I2C_E016MSG     "TWSI: active transfer does not complete"
+-
+-/*
+- * Define Timeout values
+- */
+-#define SK_I2C_TIM_LONG               2000000L        /* 2 seconds */
+-#define SK_I2C_TIM_SHORT       100000L        /* 100 milliseconds */
+-#define SK_I2C_TIM_WATCH      1000000L        /* 1 second */
+-
+-/*
+- * Define trap and error log hold times
+- */
+-#ifndef       SK_SEN_ERR_TR_HOLD
+-#define SK_SEN_ERR_TR_HOLD            (4*SK_TICKS_PER_SEC)
+-#endif
+-#ifndef       SK_SEN_ERR_LOG_HOLD
+-#define SK_SEN_ERR_LOG_HOLD           (60*SK_TICKS_PER_SEC)
+-#endif
+-#ifndef       SK_SEN_WARN_TR_HOLD
+-#define SK_SEN_WARN_TR_HOLD           (15*SK_TICKS_PER_SEC)
+-#endif
+-#ifndef       SK_SEN_WARN_LOG_HOLD
+-#define SK_SEN_WARN_LOG_HOLD  (15*60*SK_TICKS_PER_SEC)
+-#endif
+-
+-/*
+- * Defines for SenType
+- */
+-#define SK_SEN_UNKNOWN        0
+-#define SK_SEN_TEMP           1
+-#define SK_SEN_VOLT           2
+-#define SK_SEN_FAN            3
+-
+-/*
+- * Define for the SenErrorFlag
+- */
+-#define SK_SEN_ERR_NOT_PRESENT        0       /* Error Flag: Sensor not present */
+-#define SK_SEN_ERR_OK                 1       /* Error Flag: O.K. */
+-#define SK_SEN_ERR_WARN                       2       /* Error Flag: Warning */
+-#define SK_SEN_ERR_ERR                        3       /* Error Flag: Error */
+-#define SK_SEN_ERR_FAULTY             4       /* Error Flag: Faulty */
+-
+-/*
+- * Define the Sensor struct
+- */
+-struct        s_Sensor {
+-      char    *SenDesc;                       /* Description */
+-      int             SenType;                        /* Voltage or Temperature */
+-      SK_I32  SenValue;                       /* Current value of the sensor */
+-      SK_I32  SenThreErrHigh;         /* High error Threshhold of this sensor */
+-      SK_I32  SenThreWarnHigh;        /* High warning Threshhold of this sensor */
+-      SK_I32  SenThreErrLow;          /* Lower error Threshold of the sensor */
+-      SK_I32  SenThreWarnLow;         /* Lower warning Threshold of the sensor */
+-      int             SenErrFlag;                     /* Sensor indicated an error */
+-      SK_BOOL SenInit;                        /* Is sensor initialized ? */
+-      SK_U64  SenErrCts;                      /* Error trap counter */
+-      SK_U64  SenWarnCts;                     /* Warning trap counter */
+-      SK_U64  SenBegErrTS;            /* Begin error timestamp */
+-      SK_U64  SenBegWarnTS;           /* Begin warning timestamp */
+-      SK_U64  SenLastErrTrapTS;       /* Last error trap timestamp */
+-      SK_U64  SenLastErrLogTS;        /* Last error log timestamp */
+-      SK_U64  SenLastWarnTrapTS;      /* Last warning trap timestamp */
+-      SK_U64  SenLastWarnLogTS;       /* Last warning log timestamp */
+-      int             SenState;                       /* Sensor State (see HW specific include) */
+-      int             (*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen);
+-                                                              /* Sensors read function */
+-      SK_U16  SenReg;                         /* Register Address for this sensor */
+-      SK_U8   SenDev;                         /* Device Selection for this sensor */
+-};
+-
+-typedef       struct  s_I2c {
+-      SK_SENSOR       SenTable[SK_MAX_SENSORS];       /* Sensor Table */
+-      int                     CurrSens;       /* Which sensor is currently queried */
+-      int                     MaxSens;        /* Max. number of sensors */
+-      int                     TimerMode;      /* Use the timer also to watch the state machine */
+-      int                     InitLevel;      /* Initialized Level */
+-#ifndef SK_DIAG
+-      int                     DummyReads;     /* Number of non-checked dummy reads */
+-      SK_TIMER        SenTimer;       /* Sensors timer */
+-#endif /* !SK_DIAG */
+-} SK_I2C;
+-
+-extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
+-extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size,
+-                                         int Reg, int Burst);
+-extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
+-#ifdef SK_DIAG
+-extern        SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg,
+-                                               int Burst);
+-#else /* !SK_DIAG */
+-extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
+-extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC);
+-extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC);
+-#endif /* !SK_DIAG */
+-#endif /* n_SKI2C_H */
+-
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skqueue.h linux-2.6.9.new/drivers/net/sk98lin/h/skqueue.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skqueue.h    2004-10-19 05:55:29.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skqueue.h    2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skqueue.h
+  * Project:   Gigabit Ethernet Adapters, Event Scheduler Module
+- * Version:   $Revision: 1.16 $
+- * Date:      $Date: 2003/09/16 12:50:32 $
++ * Version:   $Revision: 2.3 $
++ * Date:      $Date: 2004/05/14 13:39:15 $
+  * Purpose:   Defines for the Event queue
+  *
+  ******************************************************************************/
+@@ -45,6 +45,9 @@
+ #define       SKGE_RSF        11      /* RSF Aggregation Event Class */
+ #define       SKGE_MARKER     12      /* MARKER Aggregation Event Class */
+ #define       SKGE_FD         13      /* FD Distributor Event Class */
++#ifdef SK_ASF
++#define       SKGE_ASF        14      /* ASF Event Class */
++#endif
+ /*
+  * define event queue as circular buffer
+@@ -90,5 +93,11 @@
+ #define       SKERR_Q_E001MSG "Event queue overflow"
+ #define       SKERR_Q_E002    (SKERR_Q_E001+1)
+ #define       SKERR_Q_E002MSG "Undefined event class"
++#define       SKERR_Q_E003    (SKERR_Q_E001+2)
++#define       SKERR_Q_E003MSG "Event queued in Init Level 0"
++#define       SKERR_Q_E004    (SKERR_Q_E001+3)
++#define       SKERR_Q_E004MSG "Error Reported from Event Fuction (Queue Blocked)"
++#define       SKERR_Q_E005    (SKERR_Q_E001+4)
++#define       SKERR_Q_E005MSG "Event scheduler called in Init Level 0 or 1"
+ #endif        /* _SKQUEUE_H_ */
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skrlmt.h linux-2.6.9.new/drivers/net/sk98lin/h/skrlmt.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skrlmt.h     2004-10-19 05:55:36.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skrlmt.h     2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skrlmt.h
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.37 $
+- * Date:      $Date: 2003/04/15 09:43:43 $
++ * Version:   $Revision: 2.1 $
++ * Date:      $Date: 2003/10/27 14:16:09 $
+  * Purpose:   Header file for Redundant Link ManagemenT.
+  *
+  ******************************************************************************/
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/sktimer.h linux-2.6.9.new/drivers/net/sk98lin/h/sktimer.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/sktimer.h    2004-10-19 05:53:35.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/sktimer.h    2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      sktimer.h
+  * Project:   Gigabit Ethernet Adapters, Event Scheduler Module
+- * Version:   $Revision: 1.11 $
+- * Date:      $Date: 2003/09/16 12:58:18 $
++ * Version:   $Revision: 2.1 $
++ * Date:      $Date: 2003/10/27 14:16:09 $
+  * Purpose:   Defines for the timer functions
+  *
+  ******************************************************************************/
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/sktwsi.h linux-2.6.9.new/drivers/net/sk98lin/h/sktwsi.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/sktwsi.h     1970-01-01 08:00:00.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/sktwsi.h     2006-12-07 14:35:03.000000000 +0800
+@@ -0,0 +1,177 @@
++/******************************************************************************
++ *
++ * Name:      sktwsi.h
++ * Project:   Gigabit Ethernet Adapters, TWSI-Module
++ * Version:   $Revision: 1.1 $
++ * Date:      $Date: 2003/12/19 14:02:56 $
++ * Purpose:   Defines to access Voltage and Temperature Sensor
++ *
++ ******************************************************************************/
++
++/******************************************************************************
++ *
++ *    (C)Copyright 1998-2002 SysKonnect.
++ *    (C)Copyright 2002-2003 Marvell.
++ *
++ *    This program is free software; you can redistribute it and/or modify
++ *    it under the terms of the GNU General Public License as published by
++ *    the Free Software Foundation; either version 2 of the License, or
++ *    (at your option) any later version.
++ *
++ *    The information in this file is provided "AS IS" without warranty.
++ *
++ ******************************************************************************/
++
++/*
++ * SKTWSI.H   contains all TWSI specific defines
++ */
++
++#ifndef _SKTWSI_H_
++#define _SKTWSI_H_
++
++typedef struct  s_Sensor SK_SENSOR;
++
++#include "h/skgetwsi.h"
++
++/*
++ * Define the TWSI events.
++ */
++#define SK_I2CEV_IRQ  1       /* IRQ happened Event */
++#define SK_I2CEV_TIM  2       /* Timeout event */
++#define SK_I2CEV_CLEAR        3       /* Clear MIB Values */
++
++/*
++ * Define READ and WRITE Constants.
++ */
++#define I2C_READ      0
++#define I2C_WRITE     1
++#define I2C_BURST     1
++#define I2C_SINGLE    0
++
++#define SKERR_I2C_E001                (SK_ERRBASE_I2C+0)
++#define SKERR_I2C_E001MSG     "Sensor index unknown"
++#define SKERR_I2C_E002                (SKERR_I2C_E001+1)
++#define SKERR_I2C_E002MSG     "TWSI: transfer does not complete"
++#define SKERR_I2C_E003                (SKERR_I2C_E002+1)
++#define SKERR_I2C_E003MSG     "LM80: NAK on device send"
++#define SKERR_I2C_E004                (SKERR_I2C_E003+1)
++#define SKERR_I2C_E004MSG     "LM80: NAK on register send"
++#define SKERR_I2C_E005                (SKERR_I2C_E004+1)
++#define SKERR_I2C_E005MSG     "LM80: NAK on device (2) send"
++#define SKERR_I2C_E006                (SKERR_I2C_E005+1)
++#define SKERR_I2C_E006MSG     "Unknown event"
++#define SKERR_I2C_E007                (SKERR_I2C_E006+1)
++#define SKERR_I2C_E007MSG     "LM80 read out of state"
++#define SKERR_I2C_E008                (SKERR_I2C_E007+1)
++#define SKERR_I2C_E008MSG     "Unexpected sensor read completed"
++#define SKERR_I2C_E009                (SKERR_I2C_E008+1)
++#define SKERR_I2C_E009MSG     "WARNING: temperature sensor out of range"
++#define SKERR_I2C_E010                (SKERR_I2C_E009+1)
++#define SKERR_I2C_E010MSG     "WARNING: voltage sensor out of range"
++#define SKERR_I2C_E011                (SKERR_I2C_E010+1)
++#define SKERR_I2C_E011MSG     "ERROR: temperature sensor out of range"
++#define SKERR_I2C_E012                (SKERR_I2C_E011+1)
++#define SKERR_I2C_E012MSG     "ERROR: voltage sensor out of range"
++#define SKERR_I2C_E013                (SKERR_I2C_E012+1)
++#define SKERR_I2C_E013MSG     "ERROR: couldn't init sensor"
++#define SKERR_I2C_E014                (SKERR_I2C_E013+1)
++#define SKERR_I2C_E014MSG     "WARNING: fan sensor out of range"
++#define SKERR_I2C_E015                (SKERR_I2C_E014+1)
++#define SKERR_I2C_E015MSG     "ERROR: fan sensor out of range"
++#define SKERR_I2C_E016                (SKERR_I2C_E015+1)
++#define SKERR_I2C_E016MSG     "TWSI: active transfer does not complete"
++
++/*
++ * Define Timeout values
++ */
++#define SK_I2C_TIM_LONG               2000000L        /* 2 seconds */
++#define SK_I2C_TIM_SHORT       100000L        /* 100 milliseconds */
++#define SK_I2C_TIM_WATCH      1000000L        /* 1 second */
++
++/*
++ * Define trap and error log hold times
++ */
++#ifndef       SK_SEN_ERR_TR_HOLD
++#define SK_SEN_ERR_TR_HOLD            (4*SK_TICKS_PER_SEC)
++#endif
++#ifndef       SK_SEN_ERR_LOG_HOLD
++#define SK_SEN_ERR_LOG_HOLD           (60*SK_TICKS_PER_SEC)
++#endif
++#ifndef       SK_SEN_WARN_TR_HOLD
++#define SK_SEN_WARN_TR_HOLD           (15*SK_TICKS_PER_SEC)
++#endif
++#ifndef       SK_SEN_WARN_LOG_HOLD
++#define SK_SEN_WARN_LOG_HOLD  (15*60*SK_TICKS_PER_SEC)
++#endif
++
++/*
++ * Defines for SenType
++ */
++#define SK_SEN_UNKNOWN        0
++#define SK_SEN_TEMP           1
++#define SK_SEN_VOLT           2
++#define SK_SEN_FAN            3
++
++/*
++ * Define for the SenErrorFlag
++ */
++#define SK_SEN_ERR_NOT_PRESENT        0       /* Error Flag: Sensor not present */
++#define SK_SEN_ERR_OK                 1       /* Error Flag: O.K. */
++#define SK_SEN_ERR_WARN                       2       /* Error Flag: Warning */
++#define SK_SEN_ERR_ERR                        3       /* Error Flag: Error */
++#define SK_SEN_ERR_FAULTY             4       /* Error Flag: Faulty */
++
++/*
++ * Define the Sensor struct
++ */
++struct        s_Sensor {
++      char    *SenDesc;                       /* Description */
++      int             SenType;                        /* Voltage or Temperature */
++      SK_I32  SenValue;                       /* Current value of the sensor */
++      SK_I32  SenThreErrHigh;         /* High error Threshhold of this sensor */
++      SK_I32  SenThreWarnHigh;        /* High warning Threshhold of this sensor */
++      SK_I32  SenThreErrLow;          /* Lower error Threshold of the sensor */
++      SK_I32  SenThreWarnLow;         /* Lower warning Threshold of the sensor */
++      int             SenErrFlag;                     /* Sensor indicated an error */
++      SK_BOOL SenInit;                        /* Is sensor initialized ? */
++      SK_U64  SenErrCts;                      /* Error trap counter */
++      SK_U64  SenWarnCts;                     /* Warning trap counter */
++      SK_U64  SenBegErrTS;            /* Begin error timestamp */
++      SK_U64  SenBegWarnTS;           /* Begin warning timestamp */
++      SK_U64  SenLastErrTrapTS;       /* Last error trap timestamp */
++      SK_U64  SenLastErrLogTS;        /* Last error log timestamp */
++      SK_U64  SenLastWarnTrapTS;      /* Last warning trap timestamp */
++      SK_U64  SenLastWarnLogTS;       /* Last warning log timestamp */
++      int             SenState;                       /* Sensor State (see HW specific include) */
++      int             (*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen);
++                                                              /* Sensors read function */
++      SK_U16  SenReg;                         /* Register Address for this sensor */
++      SK_U8   SenDev;                         /* Device Selection for this sensor */
++};
++
++typedef       struct  s_I2c {
++      SK_SENSOR       SenTable[SK_MAX_SENSORS];       /* Sensor Table */
++      int                     CurrSens;       /* Which sensor is currently queried */
++      int                     MaxSens;        /* Max. number of sensors */
++      int                     TimerMode;      /* Use the timer also to watch the state machine */
++      int                     InitLevel;      /* Initialized Level */
++#ifndef SK_DIAG
++      int                     DummyReads;     /* Number of non-checked dummy reads */
++      SK_TIMER        SenTimer;       /* Sensors timer */
++#endif /* !SK_DIAG */
++} SK_I2C;
++
++extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
++extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size,
++                                         int Reg, int Burst);
++extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
++#ifdef SK_DIAG
++extern        SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg,
++                                               int Burst);
++#else /* !SK_DIAG */
++extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
++extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC);
++extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC);
++#endif /* !SK_DIAG */
++#endif /* n_SKTWSI_H */
++
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/sktypes.h linux-2.6.9.new/drivers/net/sk98lin/h/sktypes.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/sktypes.h    2004-10-19 05:55:35.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/sktypes.h    2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      sktypes.h
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.2 $
+- * Date:      $Date: 2003/10/07 08:16:51 $
++ * Version:   $Revision: 1.2.2.1 $
++ * Date:      $Date: 2005/04/11 09:00:53 $
+  * Purpose:   Define data types for Linux
+  *
+  ******************************************************************************/
+@@ -11,7 +11,7 @@
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect GmbH.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2005 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+@@ -22,48 +22,28 @@
+  *
+  ******************************************************************************/
+  
+-/******************************************************************************
+- *
+- * Description:
+- *
+- * In this file, all data types that are needed by the common modules
+- * are mapped to Linux data types.
+- * 
+- *
+- * Include File Hierarchy:
+- *
+- *
+- ******************************************************************************/
+-
+ #ifndef __INC_SKTYPES_H
+ #define __INC_SKTYPES_H
+-
+-/* defines *******************************************************************/
+-
+-/*
+- * Data types with a specific size. 'I' = signed, 'U' = unsigned.
+- */
+-#define SK_I8 s8
+-#define SK_U8 u8
+-#define SK_I16        s16
+-#define SK_U16        u16
+-#define SK_I32        s32
+-#define SK_U32        u32
+-#define SK_I64        s64
+-#define SK_U64        u64
+-
+-#define SK_UPTR       ulong           /* casting pointer <-> integral */
+-
+-/*
+-* Boolean type.
+-*/
+-#define SK_BOOL               SK_U8
+-#define SK_FALSE      0
+-#define SK_TRUE               (!SK_FALSE)
+-
+-/* typedefs *******************************************************************/
+-
+-/* function prototypes ********************************************************/
++#define SK_I8    s8    /* 8 bits (1 byte) signed       */
++#define SK_U8    u8    /* 8 bits (1 byte) unsigned     */
++#define SK_I16  s16    /* 16 bits (2 bytes) signed     */
++#define SK_U16  u16    /* 16 bits (2 bytes) unsigned   */
++#define SK_I32  s32    /* 32 bits (4 bytes) signed     */
++#define SK_U32  u32    /* 32 bits (4 bytes) unsigned   */
++#define SK_I64  s64    /* 64 bits (8 bytes) signed     */
++#define SK_U64  u64    /* 64 bits (8 bytes) unsigned   */
++
++#define SK_UPTR       ulong  /* casting pointer <-> integral */
++
++#define SK_BOOL   SK_U8
++#define SK_FALSE  0
++#define SK_TRUE   (!SK_FALSE)
+ #endif        /* __INC_SKTYPES_H */
++
++/*******************************************************************************
++ *
++ * End of file
++ *
++ ******************************************************************************/
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skversion.h linux-2.6.9.new/drivers/net/sk98lin/h/skversion.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skversion.h  2004-10-19 05:54:32.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skversion.h  2006-12-07 14:35:03.000000000 +0800
+@@ -1,17 +1,17 @@
+ /******************************************************************************
+  *
+- * Name:      version.h
++ * Name:      skversion.h
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.5 $
+- * Date:      $Date: 2003/10/07 08:16:51 $
+- * Purpose:   SK specific Error log support
++ * Version:   $Revision: 1.3.2.1 $
++ * Date:      $Date: 2005/04/11 09:00:53 $
++ * Purpose:   specific version strings and numbers
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect GmbH.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2005 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+@@ -22,17 +22,15 @@
+  *
+  ******************************************************************************/
+-#ifdef        lint
+-static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH.";
+-static const char SysKonnectBuildNumber[] =
+-      "@(#)SK-BUILD: 6.23 PL: 01"; 
+-#endif        /* !defined(lint) */
+-
+-#define BOOT_STRING   "sk98lin: Network Device Driver v6.23\n" \
+-                      "(C)Copyright 1999-2004 Marvell(R)."
+-
+-#define VER_STRING    "6.23"
+-#define DRIVER_FILE_NAME      "sk98lin"
+-#define DRIVER_REL_DATE               "Feb-13-2004"
+-
++#define BOOT_STRING  "sk98lin: Network Device Driver v8.23.1.3\n" \
++                     "(C)Copyright 1999-2005 Marvell(R)."
++#define VER_STRING   "8.23.1.3"
++#define PATCHLEVEL   "01"
++#define DRIVER_FILE_NAME   "sk98lin"
++#define DRIVER_REL_DATE    "Jun-20-2005"
++/*******************************************************************************
++ *
++ * End of file
++ *
++ ******************************************************************************/
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/skvpd.h linux-2.6.9.new/drivers/net/sk98lin/h/skvpd.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/skvpd.h      2004-10-19 05:53:46.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/skvpd.h      2006-12-07 14:35:03.000000000 +0800
+@@ -1,22 +1,22 @@
+ /******************************************************************************
+  *
+  * Name:      skvpd.h
+- * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.15 $
+- * Date:      $Date: 2003/01/13 10:39:38 $
++ * Project:   Gigabit Ethernet Adapters, VPD-Module
++ * Version:   $Revision: 2.6 $
++ * Date:      $Date: 2004/11/09 15:18:00 $
+  * Purpose:   Defines and Macros for VPD handling
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+- *    (C)Copyright 1998-2003 SysKonnect GmbH.
++ *    (C)Copyright 1998-2002 SysKonnect.
++ *    (C)Copyright 2002-2004 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+  *    the Free Software Foundation; either version 2 of the License, or
+  *    (at your option) any later version.
+- *
+  *    The information in this file is provided "AS IS" without warranty.
+  *
+  ******************************************************************************/
+@@ -31,7 +31,7 @@
+ /*
+  * Define Resource Type Identifiers and VPD keywords
+  */
+-#define       RES_ID          0x82    /* Resource Type ID String (Product Name) */
++#define RES_ID                0x82    /* Resource Type ID String (Product Name) */
+ #define RES_VPD_R     0x90    /* start of VPD read only area */
+ #define RES_VPD_W     0x91    /* start of VPD read/write area */
+ #define RES_END               0x78    /* Resource Type End Tag */
+@@ -40,14 +40,16 @@
+ #define VPD_NAME      "Name"  /* Product Name, VPD name of RES_ID */
+ #endif        /* VPD_NAME */
+ #define VPD_PN                "PN"    /* Adapter Part Number */
+-#define       VPD_EC          "EC"    /* Adapter Engineering Level */
++#define VPD_EC                "EC"    /* Adapter Engineering Level */
+ #define VPD_MN                "MN"    /* Manufacture ID */
+ #define VPD_SN                "SN"    /* Serial Number */
+ #define VPD_CP                "CP"    /* Extended Capability */
+ #define VPD_RV                "RV"    /* Checksum and Reserved */
+-#define       VPD_YA          "YA"    /* Asset Tag Identifier */
++#define VPD_YA                "YA"    /* Asset Tag Identifier */
+ #define VPD_VL                "VL"    /* First Error Log Message (SK specific) */
+ #define VPD_VF                "VF"    /* Second Error Log Message (SK specific) */
++#define VPD_VB                "VB"    /* Boot Agent ROM Configuration (SK specific) */
++#define VPD_VE                "VE"    /* EFI UNDI Configuration (SK specific) */
+ #define VPD_RW                "RW"    /* Remaining Read / Write Area */
+ /* 'type' values for vpd_setup_para() */
+@@ -55,7 +57,7 @@
+ #define VPD_RW_KEY    2       /* RW keys are "Yx", "Vx", and "RW" */
+ /* 'op' values for vpd_setup_para() */
+-#define       ADD_KEY         1       /* add the key at the pos "RV" or "RW" */
++#define ADD_KEY               1       /* add the key at the pos "RV" or "RW" */
+ #define OWR_KEY               2       /* overwrite key if already exists */
+ /*
+@@ -64,18 +66,18 @@
+ #define VPD_DEV_ID_GENESIS    0x4300
+-#define       VPD_SIZE_YUKON          256
+-#define       VPD_SIZE_GENESIS        512
+-#define       VPD_SIZE                        512
++#define VPD_SIZE_YUKON                256
++#define VPD_SIZE_GENESIS      512
++#define VPD_SIZE                      512
+ #define VPD_READ      0x0000
+ #define VPD_WRITE     0x8000
+ #define VPD_STOP(pAC,IoC)     VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG,VPD_WRITE)
+-#define VPD_GET_RES_LEN(p)    ((unsigned int) \
+-                                      (* (SK_U8 *)&(p)[1]) |\
+-                                      ((* (SK_U8 *)&(p)[2]) << 8))
+-#define VPD_GET_VPD_LEN(p)    ((unsigned int)(* (SK_U8 *)&(p)[2]))
++#define VPD_GET_RES_LEN(p)    ((unsigned int)\
++                                      (*(SK_U8 *)&(p)[1]) |\
++                                      ((*(SK_U8 *)&(p)[2]) << 8))
++#define VPD_GET_VPD_LEN(p)    ((unsigned int)(*(SK_U8 *)&(p)[2]))
+ #define VPD_GET_VAL(p)                ((char *)&(p)[3])
+ #define VPD_MAX_LEN   50
+@@ -126,7 +128,7 @@
+ /*
+  * System specific VPD macros
+  */
+-#ifndef SKDIAG
++#ifndef SK_DIAG
+ #ifndef VPD_DO_IO
+ #define VPD_OUT8(pAC,IoC,Addr,Val)    (void)SkPciWriteCfgByte(pAC,Addr,Val)
+ #define VPD_OUT16(pAC,IoC,Addr,Val)   (void)SkPciWriteCfgWord(pAC,Addr,Val)
+@@ -135,61 +137,61 @@
+ #define VPD_IN16(pAC,IoC,Addr,pVal)   (void)SkPciReadCfgWord(pAC,Addr,pVal)
+ #define VPD_IN32(pAC,IoC,Addr,pVal)   (void)SkPciReadCfgDWord(pAC,Addr,pVal)
+ #else /* VPD_DO_IO */
+-#define VPD_OUT8(pAC,IoC,Addr,Val)    SK_OUT8(IoC,PCI_C(Addr),Val)
+-#define VPD_OUT16(pAC,IoC,Addr,Val)   SK_OUT16(IoC,PCI_C(Addr),Val)
+-#define VPD_OUT32(pAC,IoC,Addr,Val)   SK_OUT32(IoC,PCI_C(Addr),Val)
+-#define VPD_IN8(pAC,IoC,Addr,pVal)    SK_IN8(IoC,PCI_C(Addr),pVal)
+-#define VPD_IN16(pAC,IoC,Addr,pVal)   SK_IN16(IoC,PCI_C(Addr),pVal)
+-#define VPD_IN32(pAC,IoC,Addr,pVal)   SK_IN32(IoC,PCI_C(Addr),pVal)
++#define VPD_OUT8(pAC,IoC,Addr,Val)    SK_OUT8(IoC,PCI_C(pAC,Addr),Val)
++#define VPD_OUT16(pAC,IoC,Addr,Val)   SK_OUT16(IoC,PCI_C(pAC,Addr),Val)
++#define VPD_OUT32(pAC,IoC,Addr,Val)   SK_OUT32(IoC,PCI_C(pAC,Addr),Val)
++#define VPD_IN8(pAC,IoC,Addr,pVal)    SK_IN8(IoC,PCI_C(pAC,Addr),pVal)
++#define VPD_IN16(pAC,IoC,Addr,pVal)   SK_IN16(IoC,PCI_C(pAC,Addr),pVal)
++#define VPD_IN32(pAC,IoC,Addr,pVal)   SK_IN32(IoC,PCI_C(pAC,Addr),pVal)
+ #endif        /* VPD_DO_IO */
+-#else /* SKDIAG */
++#else /* SK_DIAG */
+ #define VPD_OUT8(pAC,Ioc,Addr,Val) {                  \
+               if ((pAC)->DgT.DgUseCfgCycle)                   \
+                       SkPciWriteCfgByte(pAC,Addr,Val);        \
+               else                                                                    \
+-                      SK_OUT8(pAC,PCI_C(Addr),Val);           \
++                      SK_OUT8(pAC,PCI_C(pAC,Addr),Val);       \
+               }
+ #define VPD_OUT16(pAC,Ioc,Addr,Val) {                 \
+               if ((pAC)->DgT.DgUseCfgCycle)                   \
+                       SkPciWriteCfgWord(pAC,Addr,Val);        \
+               else                                            \
+-                      SK_OUT16(pAC,PCI_C(Addr),Val);          \
++                      SK_OUT16(pAC,PCI_C(pAC,Addr),Val);      \
+               }
+ #define VPD_OUT32(pAC,Ioc,Addr,Val) {                 \
+               if ((pAC)->DgT.DgUseCfgCycle)                   \
+                       SkPciWriteCfgDWord(pAC,Addr,Val);       \
+               else                                            \
+-                      SK_OUT32(pAC,PCI_C(Addr),Val);          \
++                      SK_OUT32(pAC,PCI_C(pAC,Addr),Val);      \
+               }
+ #define VPD_IN8(pAC,Ioc,Addr,pVal) {                  \
+-              if ((pAC)->DgT.DgUseCfgCycle)                   \
++              if ((pAC)->DgT.DgUseCfgCycle)                   \
+                       SkPciReadCfgByte(pAC,Addr,pVal);        \
+               else                                            \
+-                      SK_IN8(pAC,PCI_C(Addr),pVal);           \
++                      SK_IN8(pAC,PCI_C(pAC,Addr),pVal);       \
+               }
+ #define VPD_IN16(pAC,Ioc,Addr,pVal) {                 \
+-              if ((pAC)->DgT.DgUseCfgCycle)                   \
++              if ((pAC)->DgT.DgUseCfgCycle)                   \
+                       SkPciReadCfgWord(pAC,Addr,pVal);        \
+               else                                            \
+-                      SK_IN16(pAC,PCI_C(Addr),pVal);          \
++                      SK_IN16(pAC,PCI_C(pAC,Addr),pVal);      \
+               }
+ #define VPD_IN32(pAC,Ioc,Addr,pVal) {                 \
+               if ((pAC)->DgT.DgUseCfgCycle)                   \
+                       SkPciReadCfgDWord(pAC,Addr,pVal);       \
+               else                                            \
+-                      SK_IN32(pAC,PCI_C(Addr),pVal);          \
++                      SK_IN32(pAC,PCI_C(pAC,Addr),pVal);      \
+               }
+-#endif        /* nSKDIAG */
++#endif /* SK_DIAG */
+ /* function prototypes ********************************************************/
+ #ifndef       SK_KR_PROTO
+-#ifdef SKDIAG
++#ifdef SK_DIAG
+ extern SK_U32 VpdReadDWord(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+       int                     addr);
+-#endif        /* SKDIAG */
++#endif /* SK_DIAG */
+ extern int    VpdSetupPara(
+       SK_AC           *pAC,
+@@ -240,7 +242,12 @@
+       SK_IOC          IoC,
+       char            *msg);
+-#ifdef        SKDIAG
++int VpdInit(
++      SK_AC           *pAC,
++      SK_IOC          IoC);
++
++#if defined(SK_DIAG) || defined(SK_ASF)
++
+ extern int    VpdReadBlock(
+       SK_AC           *pAC,
+       SK_IOC          IoC,
+@@ -254,7 +261,9 @@
+       char            *buf,
+       int                     addr,
+       int                     len);
+-#endif        /* SKDIAG */
++
++#endif /* SK_DIAG || SK_ASF */
++
+ #else /* SK_KR_PROTO */
+ extern SK_U32 VpdReadDWord();
+ extern int    VpdSetupPara();
+@@ -269,3 +278,4 @@
+ #endif        /* SK_KR_PROTO */
+ #endif        /* __INC_SKVPD_H_ */
++
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/sky2le.h linux-2.6.9.new/drivers/net/sk98lin/h/sky2le.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/sky2le.h     1970-01-01 08:00:00.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/sky2le.h     2006-12-07 14:35:03.000000000 +0800
+@@ -0,0 +1,891 @@
++/******************************************************************************
++ *
++ * Name:      sky2le.h
++ * Project:   Gigabit Ethernet Adapters, Common Modules
++ * Version:   $Revision: 1.9 $
++ * Date:      $Date: 2005/01/26 10:53:34 $
++ * Purpose:   Common list element definitions and access macros.
++ *
++ ******************************************************************************/
++
++/******************************************************************************
++ *
++ *    (C)Copyright 2003-2004 Marvell
++ *
++ *    This program is free software; you can redistribute it and/or modify
++ *    it under the terms of the GNU General Public License as published by
++ *    the Free Software Foundation; either version 2 of the License, or
++ *    (at your option) any later version.
++ *    The information in this file is provided "AS IS" without warranty.
++ *
++ ******************************************************************************/
++
++#ifndef __INC_SKY2LE_H
++#define __INC_SKY2LE_H
++
++#ifdef __cplusplus
++extern "C" {
++#endif        /* __cplusplus */
++
++/* defines ********************************************************************/
++
++#define MIN_LEN_OF_LE_TAB     128
++#define MAX_LEN_OF_LE_TAB     4096
++#ifdef USE_POLLING_UNIT
++#define NUM_LE_POLLING_UNIT   2
++#endif
++#define MAX_FRAG_OVERHEAD     10
++
++/* Macro for aligning a given value */
++#define SK_ALIGN_SIZE(Value, Alignment, AlignedVal) {                                 \
++      (AlignedVal) = (((Value) + (Alignment) - 1) & (~((Alignment) - 1)));\
++}
++
++/******************************************************************************
++ *
++ * LE2DWord() - Converts the given Little Endian value to machine order value
++ *
++ * Description:
++ *    This function converts the Little Endian value received as an argument to
++ *    the machine order value.
++ *
++ * Returns:
++ *    The converted value
++ *
++ */
++
++#ifdef SK_LITTLE_ENDIAN
++
++#ifndef       SK_USE_REV_DESC
++#define LE2DWord(value)       (value)
++#else /* SK_USE_REV_DESC */
++#define LE2DWord(value)                                       \
++      ((((value)<<24L) & 0xff000000L) +       \
++       (((value)<< 8L) & 0x00ff0000L) +       \
++       (((value)>> 8L) & 0x0000ff00L) +       \
++       (((value)>>24L) & 0x000000ffL))
++#endif        /* SK_USE_REV_DESC */
++
++#else /* !SK_LITTLE_ENDIAN */
++
++#ifndef       SK_USE_REV_DESC
++#define LE2DWord(value)                                       \
++      ((((value)<<24L) & 0xff000000L) +       \
++       (((value)<< 8L) & 0x00ff0000L) +       \
++       (((value)>> 8L) & 0x0000ff00L) +       \
++       (((value)>>24L) & 0x000000ffL))
++#else /* SK_USE_REV_DESC */
++#define LE2DWord(value)       (value)
++#endif        /* SK_USE_REV_DESC */
++
++#endif        /* !SK_LITTLE_ENDIAN */
++
++/******************************************************************************
++ *
++ * DWord2LE() - Converts the given value to a Little Endian value
++ *
++ * Description:
++ *    This function converts the value received as an argument to a Little Endian
++ *    value on Big Endian machines. If the machine running the code is Little
++ *    Endian, then no conversion is done.
++ *
++ * Returns:
++ *    The converted value
++ *
++ */
++
++#ifdef SK_LITTLE_ENDIAN
++
++#ifndef       SK_USE_REV_DESC
++#define DWord2LE(value) (value)
++#else /* SK_USE_REV_DESC */
++#define DWord2LE(value)                                       \
++      ((((value)<<24L) & 0xff000000L) +       \
++       (((value)<< 8L) & 0x00ff0000L) +       \
++       (((value)>> 8L) & 0x0000ff00L) +       \
++       (((value)>>24L) & 0x000000ffL))
++#endif        /* SK_USE_REV_DESC */
++
++#else /* !SK_LITTLE_ENDIAN */
++
++#ifndef       SK_USE_REV_DESC
++#define DWord2LE(value)                                       \
++      ((((value)<<24L) & 0xff000000L) +       \
++       (((value)<< 8L) & 0x00ff0000L) +       \
++       (((value)>> 8L) & 0x0000ff00L) +       \
++       (((value)>>24L) & 0x000000ffL))
++#else /* SK_USE_REV_DESC */
++#define DWord2LE(value) (value)
++#endif        /* SK_USE_REV_DESC */
++#endif        /* !SK_LITTLE_ENDIAN */
++
++/******************************************************************************
++ *
++ * LE2Word() - Converts the given Little Endian value to machine order value
++ *
++ * Description:
++ *    This function converts the Little Endian value received as an argument to
++ *    the machine order value.
++ *
++ * Returns:
++ *    The converted value
++ *
++ */
++
++#ifdef SK_LITTLE_ENDIAN
++#ifndef       SK_USE_REV_DESC
++#define LE2Word(value) (value)
++#else /* SK_USE_REV_DESC */
++#define LE2Word(value)                                \
++      ((((value)<< 8L) & 0xff00) +    \
++       (((value)>> 8L) & 0x00ff))
++#endif        /* SK_USE_REV_DESC */
++
++#else /* !SK_LITTLE_ENDIAN */
++#ifndef       SK_USE_REV_DESC
++#define LE2Word(value)                                \
++      ((((value)<< 8L) & 0xff00) +    \
++       (((value)>> 8L) & 0x00ff))
++#else /* SK_USE_REV_DESC */
++#define LE2Word(value) (value)
++#endif        /* SK_USE_REV_DESC */
++#endif        /* !SK_LITTLE_ENDIAN */
++
++/******************************************************************************
++ *
++ * Word2LE() - Converts the given value to a Little Endian value
++ *
++ * Description:
++ *    This function converts the value received as an argument to a Little Endian
++ *    value on Big Endian machines. If the machine running the code is Little
++ *    Endian, then no conversion is done.
++ *
++ * Returns:
++ *    The converted value
++ *
++ */
++
++#ifdef SK_LITTLE_ENDIAN
++#ifndef       SK_USE_REV_DESC
++#define Word2LE(value) (value)
++#else /* SK_USE_REV_DESC */
++#define Word2LE(value)                                \
++      ((((value)<< 8L) & 0xff00) +    \
++       (((value)>> 8L) & 0x00ff))
++#endif        /* SK_USE_REV_DESC */
++
++#else /* !SK_LITTLE_ENDIAN */
++#ifndef       SK_USE_REV_DESC
++#define Word2LE(value)                                \
++      ((((value)<< 8L) & 0xff00) +    \
++       (((value)>> 8L) & 0x00ff))
++#else /* SK_USE_REV_DESC */
++#define Word2LE(value) (value)
++#endif        /* SK_USE_REV_DESC */
++#endif        /* !SK_LITTLE_ENDIAN */
++
++/******************************************************************************
++ *
++ * Transmit list element macros
++ *
++ */
++
++#define TXLE_SET_ADDR(pLE, Addr)      \
++      ((pLE)->Tx.TxUn.BufAddr = DWord2LE(Addr))
++#define TXLE_SET_LSLEN(pLE, Len)      \
++      ((pLE)->Tx.TxUn.LargeSend.Length = Word2LE(Len))
++#define TXLE_SET_STACS(pLE, Start)    \
++      ((pLE)->Tx.TxUn.ChkSum.TxTcpSp = Word2LE(Start))
++#define TXLE_SET_WRICS(pLE, Write)    \
++      ((pLE)->Tx.TxUn.ChkSum.TxTcpWp = Word2LE(Write))
++#define TXLE_SET_INICS(pLE, Ini)      ((pLE)->Tx.Send.InitCsum = Word2LE(Ini))
++#define TXLE_SET_LEN(pLE, Len)                ((pLE)->Tx.Send.BufLen = Word2LE(Len))
++#define TXLE_SET_VLAN(pLE, Vlan)      ((pLE)->Tx.Send.VlanTag = Word2LE(Vlan))
++#define TXLE_SET_LCKCS(pLE, Lock)     ((pLE)->Tx.ControlFlags = (Lock))
++#define TXLE_SET_CTRL(pLE, Ctrl)      ((pLE)->Tx.ControlFlags = (Ctrl))
++#define TXLE_SET_OPC(pLE, Opc)                ((pLE)->Tx.Opcode = (Opc))
++
++#define TXLE_GET_ADDR(pLE)            LE2DWord((pLE)->Tx.TxUn.BufAddr)
++#define TXLE_GET_LSLEN(pLE)           LE2Word((pLE)->Tx.TxUn.LargeSend.Length)
++#define TXLE_GET_STACS(pLE)           LE2Word((pLE)->Tx.TxUn.ChkSum.TxTcpSp)
++#define TXLE_GET_WRICS(pLE)           LE2Word((pLE)->Tx.TxUn.ChkSum.TxTcpWp)
++#define TXLE_GET_INICS(pLE)           LE2Word((pLE)->Tx.Send.InitCsum)
++#define TXLE_GET_LEN(pLE)             LE2Word((pLE)->Tx.Send.BufLen)
++#define TXLE_GET_VLAN(pLE)            LE2Word((pLE)->Tx.Send.VlanTag)
++#define TXLE_GET_LCKCS(pLE)           ((pLE)->Tx.ControlFlags)
++#define TXLE_GET_CTRL(pLE)            ((pLE)->Tx.ControlFlags)
++#define TXLE_GET_OPC(pLE)             ((pLE)->Tx.Opcode)
++
++/******************************************************************************
++ *
++ * Receive list element macros
++ *
++ */
++
++#define RXLE_SET_ADDR(pLE, Addr)      \
++      ((pLE)->Rx.RxUn.BufAddr = (SK_U32) DWord2LE(Addr))
++#define RXLE_SET_STACS2(pLE, Offs)    \
++      ((pLE)->Rx.RxUn.ChkSum.RxTcpSp2 = Word2LE(Offs))
++#define RXLE_SET_STACS1(pLE, Offs)    \
++      ((pLE)->Rx.RxUn.ChkSum.RxTcpSp1 = Word2LE(Offs))
++#define RXLE_SET_LEN(pLE, Len)                ((pLE)->Rx.BufferLength = Word2LE(Len))
++#define RXLE_SET_CTRL(pLE, Ctrl)      ((pLE)->Rx.ControlFlags = (Ctrl))
++#define RXLE_SET_OPC(pLE, Opc)                ((pLE)->Rx.Opcode = (Opc))
++
++#define RXLE_GET_ADDR(pLE)            LE2DWord((pLE)->Rx.RxUn.BufAddr)
++#define RXLE_GET_STACS2(pLE)  LE2Word((pLE)->Rx.RxUn.ChkSum.RxTcpSp2)
++#define RXLE_GET_STACS1(pLE)  LE2Word((pLE)->Rx.RxUn.ChkSum.RxTcpSp1)
++#define RXLE_GET_LEN(pLE)             LE2Word((pLE)->Rx.BufferLength)
++#define RXLE_GET_CTRL(pLE)            ((pLE)->Rx.ControlFlags)
++#define RXLE_GET_OPC(pLE)             ((pLE)->Rx.Opcode)
++
++/******************************************************************************
++ *
++ * Status list element macros
++ *
++ */
++
++#define STLE_SET_OPC(pLE, Opc)                ((pLE)->St.Opcode = (Opc))
++
++#define STLE_GET_FRSTATUS(pLE)        LE2DWord((pLE)->St.StUn.StRxStatWord)
++#define STLE_GET_TIST(pLE)            LE2DWord((pLE)->St.StUn.StRxTimeStamp)
++#define STLE_GET_TCP1(pLE)            LE2Word((pLE)->St.StUn.StRxTCPCSum.RxTCPSum1)
++#define STLE_GET_TCP2(pLE)            LE2Word((pLE)->St.StUn.StRxTCPCSum.RxTCPSum2)
++#define STLE_GET_LEN(pLE)             LE2Word((pLE)->St.Stat.BufLen)
++#define STLE_GET_VLAN(pLE)            LE2Word((pLE)->St.Stat.VlanTag)
++#define STLE_GET_LINK(pLE)            ((pLE)->St.Link)
++#define STLE_GET_OPC(pLE)             ((pLE)->St.Opcode)
++#define STLE_GET_DONE_IDX(pLE,LowVal,HighVal) {                       \
++      (LowVal) = LE2DWord((pLE)->St.StUn.StTxStatLow);        \
++      (HighVal) = LE2Word((pLE)->St.Stat.StTxStatHi);         \
++}
++
++#define STLE_GET_RSS(pLE)             LE2DWord((pLE)->St.StUn.StRxRssValue)
++#define STLE_GET_IPBIT(pLE)           ((pLE)->St.Stat.Rss.FlagField & RSS_IP_FLAG)
++#define STLE_GET_TCPBIT(pLE)  ((pLE)->St.Stat.Rss.FlagField & RSS_TCP_FLAG)
++
++
++/* I always take both values as a paramter to avoid typos */
++#define STLE_GET_DONE_IDX_TXA1(LowVal,HighVal)                        \
++      (((LowVal) & STLE_TXA1_MSKL) >> STLE_TXA1_SHIFTL)
++#define STLE_GET_DONE_IDX_TXS1(LowVal,HighVal)                        \
++      ((LowVal & STLE_TXS1_MSKL) >> STLE_TXS1_SHIFTL)
++#define STLE_GET_DONE_IDX_TXA2(LowVal,HighVal)                        \
++      (((LowVal & STLE_TXA2_MSKL) >> STLE_TXA2_SHIFTL) +      \
++      ((HighVal & STLE_TXA2_MSKH) << STLE_TXA2_SHIFTH))
++#define STLE_GET_DONE_IDX_TXS2(LowVal,HighVal)                        \
++      ((HighVal & STLE_TXS2_MSKH) >> STLE_TXS2_SHIFTH)
++
++
++#define SK_Y2_RXSTAT_CHECK_PKT(Len, RxStat, IsOk) {                   \
++      (IsOk) = (((RxStat) & GMR_FS_RX_OK) != 0) &&                    \
++                       (((RxStat) & GMR_FS_ANY_ERR) == 0);                    \
++                                                                                                                      \
++      if ((IsOk) && ((SK_U16)(((RxStat) & GMR_FS_LEN_MSK) >>  \
++              GMR_FS_LEN_SHIFT) != (Len))) {                                          \
++              /* length in MAC status differs from length in LE */\
++              (IsOk) = SK_FALSE;                                                                      \
++      }                                                                                                               \
++}
++
++
++/******************************************************************************
++ *
++ * Polling unit list element macros
++ *
++ * NOTE: the Idx must be <= 0xfff and PU_PUTIDX_VALID makes them valid
++ *
++ */
++
++#ifdef USE_POLLING_UNIT
++
++#define POLE_SET_OPC(pLE, Opc)                ((pLE)->Sa.Opcode = (Opc))
++#define POLE_SET_LINK(pLE, Port)      ((pLE)->Sa.Link = (Port))
++#define POLE_SET_RXIDX(pLE, Idx)      ((pLE)->Sa.RxIdxVld = Word2LE(Idx))
++#define POLE_SET_TXAIDX(pLE, Idx)     ((pLE)->Sa.TxAIdxVld = Word2LE(Idx))
++#define POLE_SET_TXSIDX(pLE, Idx)     ((pLE)->Sa.TxSIdxVld = Word2LE(Idx))
++
++#define POLE_GET_OPC(pLE)             ((pLE)->Sa.Opcode)
++#define POLE_GET_LINK(pLE)            ((pLE)->Sa.Link)
++#define POLE_GET_RXIDX(pLE)           LE2Word((pLE)->Sa.RxIdxVld)
++#define POLE_GET_TXAIDX(pLE)  LE2Word((pLE)->Sa.TxAIdxVld)
++#define POLE_GET_TXSIDX(pLE)  LE2Word((pLE)->Sa.TxSIdxVld)
++
++#endif        /* USE_POLLING_UNIT */
++
++/******************************************************************************
++ *
++ * Debug macros for list elements
++ *
++ */
++
++#ifdef DEBUG
++
++#define SK_DBG_DUMP_RX_LE(pLE)        {                                                                               \
++      SK_U8   Opcode;                                                                                                         \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("=== RX_LIST_ELEMENT @addr: %p cont: %02x %02x %02x %02x %02x %02x %02x %02x\n",       \
++              pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\
++              ((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5],             \
++              ((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7]));                                               \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\t (16bit) %04x %04x %04x %04x\n",                                                    \
++              ((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2],  \
++              ((SK_U16 *) pLE)[3]));                                                                                  \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\t (32bit) %08x %08x\n",                                                                              \
++              ((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1]));                                     \
++      Opcode = RXLE_GET_OPC(pLE);                                                                                     \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == HW_OWNER) ?   \
++               "Hardware" : "Software"));                                                                             \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\tOpc: 0x%x ",Opcode));                                                                               \
++      switch (Opcode & (~HW_OWNER)) {                                                                         \
++      case OP_BUFFER:                                                                                                         \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_BUFFER\n"));                                                                                     \
++              break;                                                                                                                  \
++      case OP_PACKET:                                                                                                         \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_PACKET\n"));                                                                                     \
++              break;                                                                                                                  \
++      case OP_ADDR64:                                                                                                         \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_ADDR64\n"));                                                                                     \
++              break;                                                                                                                  \
++      case OP_TCPSTART:                                                                                                       \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_TCPPAR\n"));                                                                                     \
++              break;                                                                                                                  \
++      case SW_OWNER:                                                                                                          \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tunused LE\n"));                                                                                     \
++              break;                                                                                                                  \
++      default:                                                                                                                        \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tunknown Opcode!!!\n"));                                                                     \
++              break;                                                                                                                  \
++      }                                                                                                                                       \
++      if ((Opcode & OP_BUFFER) == OP_BUFFER) {                                                        \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tControl: 0x%x\n", RXLE_GET_CTRL(pLE)));                                     \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tBufLen: 0x%x\n", RXLE_GET_LEN(pLE)));                                       \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tLowAddr: 0x%x\n", RXLE_GET_ADDR(pLE)));                                     \
++      }                                                                                                                                       \
++      if ((Opcode & OP_ADDR64) == OP_ADDR64) {                                                        \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tHighAddr: 0x%x\n", RXLE_GET_ADDR(pLE)));                            \
++      }                                                                                                                                       \
++      if ((Opcode & OP_TCPSTART) == OP_TCPSTART) {                                            \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tTCP Sum Start 1 : 0x%x\n", RXLE_GET_STACS1(pLE)));          \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tTCP Sum Start 2 : 0x%x\n", RXLE_GET_STACS2(pLE)));          \
++      }                                                                                                                                       \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("=====================\n"));                                                                   \
++}
++
++#define SK_DBG_DUMP_TX_LE(pLE)        {                                                                               \
++      SK_U8   Opcode;                                                                                                         \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("=== TX_LIST_ELEMENT @addr: %p cont: %02x %02x %02x %02x %02x %02x %02x %02x\n",       \
++              pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\
++              ((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5],             \
++              ((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7]));                                               \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\t (16bit) %04x %04x %04x %04x\n",                                                    \
++              ((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2],  \
++              ((SK_U16 *) pLE)[3]));                                                                                  \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\t (32bit) %08x %08x\n",                                                                              \
++              ((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1]));                                     \
++      Opcode = TXLE_GET_OPC(pLE);                                                                                     \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == HW_OWNER) ?   \
++              "Hardware" : "Software"));                                                                              \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\tOpc: 0x%x ",Opcode));                                                                               \
++      switch (Opcode & (~HW_OWNER)) {                                                                         \
++      case OP_TCPCHKSUM:                                                                                                      \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_TCPCHKSUM\n"));                                                                          \
++              break;                                                                                                                  \
++      case OP_TCPIS:                                                                                                          \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_TCPIS\n"));                                                                                      \
++              break;                                                                                                                  \
++      case OP_TCPLCK:                                                                                                         \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_TCPLCK\n"));                                                                                     \
++              break;                                                                                                                  \
++      case OP_TCPLW:                                                                                                          \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_TCPLW\n"));                                                                                      \
++              break;                                                                                                                  \
++      case OP_TCPLSW:                                                                                                         \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_TCPLSW\n"));                                                                                     \
++              break;                                                                                                                  \
++      case OP_TCPLISW:                                                                                                        \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_TCPLISW\n"));                                                                            \
++              break;                                                                                                                  \
++      case OP_ADDR64:                                                                                                         \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_ADDR64\n"));                                                                                     \
++              break;                                                                                                                  \
++      case OP_VLAN:                                                                                                           \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_VLAN\n"));                                                                                       \
++              break;                                                                                                                  \
++      case OP_ADDR64VLAN:                                                                                                     \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_ADDR64VLAN\n"));                                                                         \
++              break;                                                                                                                  \
++      case OP_LRGLEN:                                                                                                         \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_LRGLEN\n"));                                                                                     \
++              break;                                                                                                                  \
++      case OP_LRGLENVLAN:                                                                                                     \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_LRGLENVLAN\n"));                                                                         \
++              break;                                                                                                                  \
++      case OP_BUFFER:                                                                                                         \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_BUFFER\n"));                                                                                     \
++              break;                                                                                                                  \
++      case OP_PACKET:                                                                                                         \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_PACKET\n"));                                                                                     \
++              break;                                                                                                                  \
++      case OP_LARGESEND:                                                                                                      \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_LARGESEND\n"));                                                                          \
++              break;                                                                                                                  \
++      case SW_OWNER:                                                                                                          \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tunused LE\n"));                                                                                     \
++              break;                                                                                                                  \
++      default:                                                                                                                        \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tunknown Opcode!!!\n"));                                                                     \
++              break;                                                                                                                  \
++      }                                                                                                                                       \
++      if ((Opcode & OP_BUFFER) == OP_BUFFER) {                                                        \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tControl: 0x%x\n", TXLE_GET_CTRL(pLE)));                                     \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tBufLen: 0x%x\n", TXLE_GET_LEN(pLE)));                                       \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tLowAddr: 0x%x\n", TXLE_GET_ADDR(pLE)));                                     \
++      }                                                                                                                                       \
++      if ((Opcode & OP_ADDR64) == OP_ADDR64) {                                                        \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tHighAddr: 0x%x\n", TXLE_GET_ADDR(pLE)));                            \
++      }                                                                                                                                       \
++      if ((Opcode & OP_VLAN) == OP_VLAN) {                                                            \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tVLAN Id: 0x%x\n", TXLE_GET_VLAN(pLE)));                                     \
++      }                                                                                                                                       \
++      if ((Opcode & OP_LRGLEN) == OP_LRGLEN) {                                                        \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tLarge send length: 0x%x\n", TXLE_GET_LSLEN(pLE)));          \
++      }                                                                                                                                       \
++      if ((Opcode &(~HW_OWNER)) <= OP_ADDR64) {                                                       \
++              if ((Opcode & OP_TCPWRITE) == OP_TCPWRITE) {                                    \
++                      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                          \
++                              ("\tTCP Sum Write: 0x%x\n", TXLE_GET_WRICS(pLE)));              \
++              }                                                                                                                               \
++              if ((Opcode & OP_TCPSTART) == OP_TCPSTART) {                                    \
++                      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                          \
++                              ("\tTCP Sum Start: 0x%x\n", TXLE_GET_STACS(pLE)));              \
++              }                                                                                                                               \
++              if ((Opcode & OP_TCPINIT) == OP_TCPINIT) {                                              \
++                      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                          \
++                              ("\tTCP Sum Init: 0x%x\n", TXLE_GET_INICS(pLE)));               \
++              }                                                                                                                               \
++              if ((Opcode & OP_TCPLCK) == OP_TCPLCK) {                                                \
++                      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                          \
++                              ("\tTCP Sum Lock: 0x%x\n", TXLE_GET_LCKCS(pLE)));               \
++              }                                                                                                                               \
++      }                                                                                                                                       \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("=====================\n"));                                                                   \
++}
++      
++#define SK_DBG_DUMP_ST_LE(pLE)        {                                                                               \
++      SK_U8   Opcode;                                                                                                         \
++      SK_U16  HighVal;                                                                                                        \
++      SK_U32  LowVal;                                                                                                         \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("=== ST_LIST_ELEMENT @addr: %p contains: %02x %02x %02x %02x %02x %02x %02x %02x\n",\
++              pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\
++              ((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5],             \
++              ((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7]));                                               \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\t (16bit) %04x %04x %04x %04x\n",                                                    \
++              ((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2],  \
++              ((SK_U16 *) pLE)[3]));                                                                                  \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\t (32bit) %08x %08x\n",                                                                              \
++              ((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1]));                                             \
++      Opcode = STLE_GET_OPC(pLE);                                                                                     \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == SW_OWNER) ?   \
++              "Hardware" : "Software"));                                                                              \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\tOpc: 0x%x", Opcode));                                                                               \
++      Opcode &= (~HW_OWNER);                                                                                          \
++      switch (Opcode) {                                                                                                       \
++      case OP_RXSTAT:                                                                                                         \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_RXSTAT\n"));                                                                                     \
++              break;                                                                                                                  \
++      case OP_RXTIMESTAMP:                                                                                            \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_RXTIMESTAMP\n"));                                                                        \
++              break;                                                                                                                  \
++      case OP_RXVLAN:                                                                                                         \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_RXVLAN\n"));                                                                                     \
++              break;                                                                                                                  \
++      case OP_RXCHKS:                                                                                                         \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_RXCHKS\n"));                                                                                     \
++              break;                                                                                                                  \
++      case OP_RXCHKSVLAN:                                                                                                     \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_RXCHKSVLAN\n"));                                                                         \
++              break;                                                                                                                  \
++      case OP_RXTIMEVLAN:                                                                                                     \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_RXTIMEVLAN\n"));                                                                         \
++              break;                                                                                                                  \
++      case OP_RSS_HASH:                                                                                                       \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_RSS_HASH\n"));                                                                           \
++              break;                                                                                                                  \
++      case OP_TXINDEXLE:                                                                                                      \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_TXINDEXLE\n"));                                                                          \
++              break;                                                                                                                  \
++      case HW_OWNER:                                                                                                          \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tunused LE\n"));                                                                                     \
++              break;                                                                                                                  \
++      default:                                                                                                                        \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tunknown status list element!!!\n"));                                        \
++              break;                                                                                                                  \
++      }                                                                                                                                       \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\tPort: %c\n", 'A' + STLE_GET_LINK(pLE)));                                    \
++      if (Opcode == OP_RXSTAT) {                                                                                      \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tFrameLen: 0x%x\n", STLE_GET_LEN(pLE)));                                     \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tFrameStat: 0x%x\n", STLE_GET_FRSTATUS(pLE)));                       \
++      }                                                                                                                                       \
++      if ((Opcode & OP_RXVLAN) == OP_RXVLAN) {                                                        \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tVLAN Id: 0x%x\n", STLE_GET_VLAN(pLE)));                                     \
++      }                                                                                                                                       \
++      if ((Opcode & OP_RXTIMESTAMP) == OP_RXTIMESTAMP) {                                      \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tTimestamp: 0x%x\n", STLE_GET_TIST(pLE)));                           \
++      }                                                                                                                                       \
++      if ((Opcode & OP_RXCHKS) == OP_RXCHKS) {                                                        \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tTCP: 0x%x 0x%x\n", STLE_GET_TCP1(pLE),                                      \
++                      STLE_GET_TCP2(pLE)));                                                                           \
++      }                                                                                                                                       \
++      if (Opcode == OP_TXINDEXLE) {                                                                           \
++              STLE_GET_DONE_IDX(pLE, LowVal, HighVal);                                                \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tTx Index TxA1: 0x%x\n",                                                                     \
++                      STLE_GET_DONE_IDX_TXA1(LowVal,HighVal)));                                       \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tTx Index TxS1: 0x%x\n",                                                                     \
++                      STLE_GET_DONE_IDX_TXS1(LowVal,HighVal)));                                       \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tTx Index TxA2: 0x%x\n",                                                                     \
++                      STLE_GET_DONE_IDX_TXA2(LowVal,HighVal)));                                       \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tTx Index TxS2: 0x%x\n",                                                                     \
++                      STLE_GET_DONE_IDX_TXS2(LowVal,HighVal)));                                       \
++      }                                                                                                                                       \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("=====================\n"));                                                                   \
++}
++
++#ifdef USE_POLLING_UNIT
++#define SK_DBG_DUMP_PO_LE(pLE)        {                                                                               \
++      SK_U8   Opcode;                                                                                                         \
++      SK_U16  Idx;                                                                                                            \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("=== PO_LIST_ELEMENT @addr: %p cont: %02x %02x %02x %02x %02x %02x %02x %02x\n",       \
++              pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\
++              ((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5],             \
++              ((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7]));                                               \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\t (16bit) %04x %04x %04x %04x\n",                                                    \
++              ((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2],  \
++              ((SK_U16 *) pLE)[3]));                                                                                  \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\t (32bit) %08x %08x\n",                                                                              \
++              ((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1]));                                             \
++      Opcode = POLE_GET_OPC(pLE);                                                                                     \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++               ("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == HW_OWNER) ?  \
++                "Hardware" : "Software"));                                                                    \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++               ("\tOpc: 0x%x ",Opcode));                                                                              \
++      if ((Opcode & ~HW_OWNER) == OP_PUTIDX) {                                                        \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tOP_PUTIDX\n"));                                                                                     \
++      }                                                                                                                                       \
++      else {                                                                                                                          \
++              SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                  \
++                      ("\tunknown Opcode!!!\n"));                                                                     \
++      }                                                                                                                                       \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\tPort %c\n", 'A' + POLE_GET_LINK(pLE)));                                             \
++      Idx = POLE_GET_TXAIDX(pLE);                                                                                     \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\tTxA Index is 0x%X and %svalid\n", Idx,                                              \
++              (Idx & PU_PUTIDX_VALID) ? "" : "not "));                                                \
++      Idx = POLE_GET_TXSIDX(pLE);                                                                                     \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\tTxS Index is 0x%X and %svalid\n", Idx,                                              \
++              (Idx & PU_PUTIDX_VALID) ? "" : "not "));                                                \
++      Idx = POLE_GET_RXIDX(pLE);                                                                                      \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("\tRx Index is 0x%X and %svalid\n", Idx,                                               \
++              (Idx & PU_PUTIDX_VALID) ? "" : "not "));                                                \
++      SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT,                                          \
++              ("=====================\n"));                                                                   \
++}
++#endif        /* USE_POLLING_UNIT */
++
++#else /* !DEBUG */
++
++#define SK_DBG_DUMP_RX_LE(pLE)
++#define SK_DBG_DUMP_TX_LE(pLE)
++#define SK_DBG_DUMP_ST_LE(pLE)
++#define SK_DBG_DUMP_PO_LE(pLE)
++
++#endif        /* !DEBUG */
++
++/******************************************************************************
++ *
++ * Macros for listelement tables
++ *
++ *
++ */
++
++#define LE_SIZE sizeof(SK_HWLE)
++#define LE_TAB_SIZE(NumElements)      ((NumElements) * LE_SIZE)
++
++/* Number of unused list elements in table
++ * this macro always returns the number of free listelements - 1
++ * this way we want to guarantee that always one LE remains unused
++ */
++#define NUM_FREE_LE_IN_TABLE(pTable)                                                          \
++      ( ((pTable)->Put >= (pTable)->Done) ?                                                   \
++      (NUM_LE_IN_TABLE(pTable) - (pTable)->Put + (pTable)->Done - 1) :\
++      ((pTable)->Done - (pTable)->Put - 1) )
++
++/* total number of list elements in table */
++#define NUM_LE_IN_TABLE(pTable)               ((pTable)->Num)
++
++/* get next unused Rx list element */
++#define GET_RX_LE(pLE, pTable) {                                                                      \
++      pLE = &(pTable)->pLETab[(pTable)->Put];                                                 \
++      (pTable)->Put = ((pTable)->Put + 1) & (NUM_LE_IN_TABLE(pTable) - 1);\
++}
++
++/* get next unused Tx list element */
++#define GET_TX_LE(pLE, pTable)        GET_RX_LE(pLE, pTable)
++
++/* get next status list element expected to be finished by hw */
++#define GET_ST_LE(pLE, pTable) {                                                                      \
++      pLE = &(pTable)->pLETab[(pTable)->Done];                                                \
++              (pTable)->Done = ((pTable)->Done +1) & (NUM_LE_IN_TABLE(pTable) - 1);\
++}
++
++#ifdef USE_POLLING_UNIT
++/* get next polling unit list element for port */
++#define GET_PO_LE(pLE, pTable, Port) {                                                                \
++      pLE = &(pTable)->pLETab[(Port)];                                                                \
++}
++#endif        /* USE_POLLING_UNIT */
++
++#define GET_PUT_IDX(pTable)                   ((pTable)->Put)
++
++#define UPDATE_HWPUT_IDX(pTable)      {(pTable)->HwPut = (pTable)->Put; }
++
++/*
++ * get own bit of next status LE
++ * if the result is != 0 there has been at least one status LE finished
++ */
++#define OWN_OF_FIRST_LE(pTable)                                                                       \
++      (STLE_GET_OPC(&(pTable)->pLETab[(pTable)->Done]) & HW_OWNER)
++
++#define SET_DONE_INDEX(pTable, Idx)   (pTable)->Done = (Idx);
++
++#define GET_DONE_INDEX(pTable)        ((pTable)->Done)
++
++#ifdef SAFE_BUT_SLOW
++
++/* check own bit of LE before current done idx */
++#define CHECK_STLE_OVERFLOW(pTable, IsOk) {                                           \
++              unsigned i;                                                                                             \
++              if ((i = (pTable)->Done) == 0) {                                                \
++                      i = NUM_LE_IN_TABLE(pTable);                                            \
++              }                                                                                                               \
++              else {                                                                                                  \
++                      i = i - 1;                                                                                      \
++              }                                                                                                               \
++              if (STLE_GET_OPC(&(pTable)->pLETab[i]) == HW_OWNER) {   \
++                      (IsOk) = SK_TRUE;                                                                       \
++              }                                                                                                               \
++              else {                                                                                                  \
++                      (IsOk) = SK_FALSE;                                                                      \
++              }                                                                                                               \
++      }
++
++
++/*
++ * for Yukon-2 the hardware is not polling the list elements, so it
++ * is not necessary to change the own-bit of Rx or Tx LEs before
++ * reusing them
++ * but it might make debugging easier if one simply can see whether
++ * a LE has been worked on
++ */
++
++#define CLEAR_LE_OWN(pTable, Idx)                                                             \
++      STLE_SET_OPC(&(pTable)->pLETab[(Idx)], SW_OWNER)
++
++/*
++ * clear all own bits starting from old done index up to the LE before
++ * the new done index
++ */
++#define CLEAR_LE_OWN_FROM_DONE_TO(pTable, To) {                                       \
++              int i;                                                                                                  \
++              i = (pTable)->Done;                                                                             \
++              while (i != To) {                                                                               \
++                      CLEAR_LE_OWN(pTable, i);                                                        \
++                      i = (i + 1) & (NUM_LE_IN_TABLE(pTable) - 1);            \
++              }                                                                                                               \
++      }
++
++#else /* !SAFE_BUT_SLOW */
++
++#define CHECK_STLE_OVERFLOW(pTable, IsOk)
++#define CLEAR_LE_OWN(pTable, Idx)
++#define CLEAR_LE_OWN_FROM_DONE_TO(pTable, To)
++
++#endif        /* !SAFE_BUT_SLOW */
++
++
++/* typedefs *******************************************************************/
++
++typedef struct s_LetRxTx {
++      SK_U16  VlanId;                 /* VLAN Id given down last time */
++      SK_U16  TcpWp;                  /* TCP Checksum Write Position */
++      SK_U16  TcpSp1;                 /* TCP Checksum Calculation Start Position 1 */
++      SK_U16  TcpSp2;                 /* TCP Checksum Calculation Start Position 2 */
++      SK_U16  MssValue;               /* Maximum Segment Size */
++      SK_U16  Reserved1;              /* reserved word for furture extensions */
++      SK_U16  Reserved2;              /* reserved word for furture extensions */
++      SK_U16  Reserved3;              /* reserved word for furture extensions */
++} SK_LET_RX_TX;
++
++typedef struct s_LetStat {
++      SK_U32  RxTimeStamp;    /* Receive Timestamp */
++      SK_U32  RssHashValue;   /* RSS Hash Value */
++      SK_BOOL RssIsIp;                /* RSS Hash Value: IP packet detected */
++      SK_BOOL RssIsTcp;               /* RSS Hash Value: IP+TCP packet detected */
++      SK_U16  VlanId;                 /* VLAN Id given received by Status BMU */
++      SK_U16  TcpSum1;                /* TCP checksum 1 (status BMU) */
++      SK_U16  TcpSum2;                /* TCP checksum 2 (status BMU) */
++} SK_LET_STAT;
++
++typedef union s_LetBmuSpec {
++      SK_LET_RX_TX    RxTx;   /* Rx/Tx BMU specific variables */
++      SK_LET_STAT             Stat;   /* Status BMU specific variables */
++} SK_LET_BMU_S;
++
++typedef       struct s_le_table {
++      /* all LE's between Done and HWPut are owned by the hardware */
++      /* all LE's between Put and Done can be used from Software */
++      /* all LE's between HWPut and Put are currently processed in DriverSend */
++      unsigned Done;                  /* done index - consumed from HW and available */
++      unsigned Put;                   /* put index - to be given to hardware */
++      unsigned HwPut;                 /* put index actually given to hardware */
++      unsigned Num;                   /* total number of list elements */
++      SK_HWLE *pLETab;                /* virtual address of list element table */
++      SK_U32  pPhyLETABLow;   /* physical address of list element table */
++      SK_U32  pPhyLETABHigh;  /* physical address of list element table */
++      /* values to remember in order to save some LEs */
++      SK_U32  BufHighAddr;    /* high addr given down last time */
++      SK_LET_BMU_S Bmu;               /* contains BMU specific information */
++      SK_U32  private;                /* driver private variable free usable */
++      SK_U16  TcpInitCsum;    /* Init. Checksum */
++} SK_LE_TABLE;
++
++/* function prototypes ********************************************************/
++
++#ifndef       SK_KR_PROTO
++
++/*
++ * public functions in sky2le.c
++ */
++extern void SkGeY2SetPutIndex(
++      SK_AC   *pAC,
++      SK_IOC  IoC,
++      SK_U32  StartAddrPrefetchUnit,
++      SK_LE_TABLE *pLETab);
++
++extern void SkGeY2InitPrefetchUnit(
++      SK_AC   *pAC,
++      SK_IOC  IoC,
++      unsigned int Queue,
++      SK_LE_TABLE *pLETab);
++
++extern void SkGeY2InitStatBmu(
++      SK_AC   *pAC,
++      SK_IOC  IoC,
++      SK_LE_TABLE *pLETab);
++
++extern void SkGeY2InitPollUnit(
++      SK_AC   *pAC,
++      SK_IOC  IoC,
++      SK_LE_TABLE *pLETab);
++
++extern void SkGeY2InitSingleLETable(
++      SK_AC   *pAC,
++      SK_LE_TABLE *pLETab,
++      unsigned int NumLE,
++      void    *pVMem,
++      SK_U32  PMemLowAddr,
++      SK_U32  PMemHighAddr);
++
++#else /* SK_KR_PROTO */
++extern void SkGeY2SetPutIndex();
++extern void SkGeY2InitPrefetchUnit();
++extern void SkGeY2InitStatBmu();
++extern void SkGeY2InitPollUnit();
++extern void SkGeY2InitSingleLETable();
++#endif        /* SK_KR_PROTO */
++
++#ifdef __cplusplus
++}
++#endif        /* __cplusplus */
++
++#endif        /* __INC_SKY2LE_H */
++
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/h/xmac_ii.h linux-2.6.9.new/drivers/net/sk98lin/h/xmac_ii.h
+--- linux-2.6.9.old/drivers/net/sk98lin/h/xmac_ii.h    2004-10-19 05:54:55.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/h/xmac_ii.h    2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      xmac_ii.h
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.52 $
+- * Date:      $Date: 2003/10/02 16:35:50 $
++ * Version:   $Revision: 2.11 $
++ * Date:      $Date: 2005/01/04 14:14:20 $
+  * Purpose:   Defines and Macros for Gigabit Ethernet Controller
+  *
+  ******************************************************************************/
+@@ -11,13 +11,12 @@
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2004 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+  *    the Free Software Foundation; either version 2 of the License, or
+  *    (at your option) any later version.
+- *
+  *    The information in this file is provided "AS IS" without warranty.
+  *
+  ******************************************************************************/
+@@ -449,7 +448,7 @@
+ /*
+  * Receive Frame Status Encoding
+  */
+-#define XMR_FS_LEN    (0x3fffUL<<18)  /* Bit 31..18:  Rx Frame Length */
++#define XMR_FS_LEN_MSK        (0x3fffUL<<18)  /* Bit 31..18:  Rx Frame Length */
+ #define XMR_FS_2L_VLAN        (1L<<17)        /* Bit 17:      tagged wh 2Lev VLAN ID*/
+ #define XMR_FS_1L_VLAN        (1L<<16)        /* Bit 16:      tagged wh 1Lev VLAN ID*/
+ #define XMR_FS_BC             (1L<<15)        /* Bit 15:      Broadcast Frame */
+@@ -469,6 +468,8 @@
+ #define XMR_FS_ERR            (1L<<1)         /* Bit  1:      Frame Error */
+ #define XMR_FS_MCTRL  (1L<<0)         /* Bit  0:      MAC Control Packet */
++#define XMR_FS_LEN_SHIFT      18
++
+ /*
+  * XMR_FS_ERR will be set if
+  *    XMR_FS_FCS_ERR, XMR_FS_LNG_ERR, XMR_FS_RUNT,
+@@ -510,7 +511,7 @@
+ #define PHY_BCOM_NEPG         0x07    /* 16 bit r/w   Next Page Register */
+ #define PHY_BCOM_NEPG_LP      0x08    /* 16 bit r/o   Next Page Link Partner */
+       /* Broadcom-specific registers */
+-#define PHY_BCOM_1000T_CTRL   0x09    /* 16 bit r/w   1000Base-T Ctrl Reg */
++#define PHY_BCOM_1000T_CTRL   0x09    /* 16 bit r/w   1000Base-T Control Reg */
+ #define PHY_BCOM_1000T_STAT   0x0a    /* 16 bit r/o   1000Base-T Status Reg */
+       /* 0x0b - 0x0e:         reserved */
+ #define PHY_BCOM_EXT_STAT     0x0f    /* 16 bit r/o   Extended Status Reg */
+@@ -541,24 +542,32 @@
+ #define PHY_MARV_NEPG         0x07    /* 16 bit r/w   Next Page Register */
+ #define PHY_MARV_NEPG_LP      0x08    /* 16 bit r/o   Next Page Link Partner */
+       /* Marvel-specific registers */
+-#define PHY_MARV_1000T_CTRL   0x09    /* 16 bit r/w   1000Base-T Ctrl Reg */
++#define PHY_MARV_1000T_CTRL   0x09    /* 16 bit r/w   1000Base-T Control Reg */
+ #define PHY_MARV_1000T_STAT   0x0a    /* 16 bit r/o   1000Base-T Status Reg */
+       /* 0x0b - 0x0e:         reserved */
+ #define PHY_MARV_EXT_STAT     0x0f    /* 16 bit r/o   Extended Status Reg */
+-#define PHY_MARV_PHY_CTRL     0x10    /* 16 bit r/w   PHY Specific Ctrl Reg */
+-#define PHY_MARV_PHY_STAT     0x11    /* 16 bit r/o   PHY Specific Stat Reg */
++#define PHY_MARV_PHY_CTRL     0x10    /* 16 bit r/w   PHY Specific Control Reg */
++#define PHY_MARV_PHY_STAT     0x11    /* 16 bit r/o   PHY Specific Status Reg */
+ #define PHY_MARV_INT_MASK     0x12    /* 16 bit r/w   Interrupt Mask Reg */
+ #define PHY_MARV_INT_STAT     0x13    /* 16 bit r/o   Interrupt Status Reg */
+ #define PHY_MARV_EXT_CTRL     0x14    /* 16 bit r/w   Ext. PHY Specific Ctrl */
+ #define PHY_MARV_RXE_CNT      0x15    /* 16 bit r/w   Receive Error Counter */
+ #define PHY_MARV_EXT_ADR      0x16    /* 16 bit r/w   Ext. Ad. for Cable Diag. */
+-      /* 0x17:                reserved */
++#define PHY_MARV_PORT_IRQ     0x17    /* 16 bit r/o   Port 0 IRQ (88E1111 only) */
+ #define PHY_MARV_LED_CTRL     0x18    /* 16 bit r/w   LED Control Reg */
+ #define PHY_MARV_LED_OVER     0x19    /* 16 bit r/w   Manual LED Override Reg */
+ #define PHY_MARV_EXT_CTRL_2   0x1a    /* 16 bit r/w   Ext. PHY Specific Ctrl 2 */
+ #define PHY_MARV_EXT_P_STAT   0x1b    /* 16 bit r/w   Ext. PHY Spec. Stat Reg */
+ #define PHY_MARV_CABLE_DIAG   0x1c    /* 16 bit r/o   Cable Diagnostic Reg */
+-      /* 0x1d - 0x1f:         reserved */
++#define PHY_MARV_PAGE_ADDR    0x1d    /* 16 bit r/w   Extended Page Address Reg */
++#define PHY_MARV_PAGE_DATA    0x1e    /* 16 bit r/w   Extended Page Data Reg */
++
++/* for 10/100 Fast Ethernet PHY (88E3082 only) */
++#define PHY_MARV_FE_LED_PAR   0x16    /* 16 bit r/w   LED Parallel Select Reg. */
++#define PHY_MARV_FE_LED_SER   0x17    /* 16 bit r/w   LED Stream Select S. LED */
++#define PHY_MARV_FE_VCT_TX    0x1a    /* 16 bit r/w   VCT Reg. for TXP/N Pins */
++#define PHY_MARV_FE_VCT_RX    0x1b    /* 16 bit r/o   VCT Reg. for RXP/N Pins */
++#define PHY_MARV_FE_SPEC_2    0x1c    /* 16 bit r/w   Specific Control Reg. 2 */
+ /*----------------------------------------------------------------------------*/
+ /*
+@@ -574,9 +583,9 @@
+ #define PHY_LONE_NEPG         0x07    /* 16 bit r/w   Next Page Register */
+ #define PHY_LONE_NEPG_LP      0x08    /* 16 bit r/o   Next Page Link Partner */
+       /* Level One-specific registers */
+-#define PHY_LONE_1000T_CTRL   0x09    /* 16 bit r/w   1000Base-T Control Reg*/
++#define PHY_LONE_1000T_CTRL   0x09    /* 16 bit r/w   1000Base-T Control Reg */
+ #define PHY_LONE_1000T_STAT   0x0a    /* 16 bit r/o   1000Base-T Status Reg */
+-      /* 0x0b -0x0e:          reserved */
++      /* 0x0b - 0x0e:         reserved */
+ #define PHY_LONE_EXT_STAT     0x0f    /* 16 bit r/o   Extended Status Reg */
+ #define PHY_LONE_PORT_CFG     0x10    /* 16 bit r/w   Port Configuration Reg*/
+ #define PHY_LONE_Q_STAT               0x11    /* 16 bit r/o   Quick Status Reg */
+@@ -585,7 +594,7 @@
+ #define PHY_LONE_LED_CFG      0x14    /* 16 bit r/w   LED Configuration Reg */
+ #define PHY_LONE_PORT_CTRL    0x15    /* 16 bit r/w   Port Control Reg */
+ #define PHY_LONE_CIM          0x16    /* 16 bit r/o   CIM Reg */
+-      /* 0x17 -0x1c:          reserved */
++      /* 0x17 - 0x1c:         reserved */
+ /*----------------------------------------------------------------------------*/
+ /*
+@@ -603,14 +612,14 @@
+       /* National-specific registers */
+ #define PHY_NAT_1000T_CTRL    0x09    /* 16 bit r/w   1000Base-T Control Reg */
+ #define PHY_NAT_1000T_STAT    0x0a    /* 16 bit r/o   1000Base-T Status Reg */
+-      /* 0x0b -0x0e:          reserved */
++      /* 0x0b - 0x0e:         reserved */
+ #define PHY_NAT_EXT_STAT      0x0f    /* 16 bit r/o   Extended Status Register */
+ #define PHY_NAT_EXT_CTRL1     0x10    /* 16 bit r/o   Extended Control Reg1 */
+ #define PHY_NAT_Q_STAT1               0x11    /* 16 bit r/o   Quick Status Reg1 */
+ #define PHY_NAT_10B_OP                0x12    /* 16 bit r/o   10Base-T Operations Reg */
+ #define PHY_NAT_EXT_CTRL2     0x13    /* 16 bit r/o   Extended Control Reg1 */
+ #define PHY_NAT_Q_STAT2               0x14    /* 16 bit r/o   Quick Status Reg2 */
+-      /* 0x15 -0x18:          reserved */
++      /* 0x15 - 0x18:         reserved */
+ #define PHY_NAT_PHY_ADDR      0x19    /* 16 bit r/o   PHY Address Register */
+@@ -618,7 +627,7 @@
+ /*
+  * PHY bit definitions
+- * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are
++ * Bits defined as PHY_X_..., PHY_B_..., PHY_L_..., PHY_N_... or PHY_M_... are
+  * XMAC/Broadcom/LevelOne/National/Marvell-specific.
+  * All other are general.
+  */
+@@ -629,14 +638,14 @@
+ /*****  PHY_LONE_CTRL 16 bit r/w      PHY Control Register *****/
+ #define PHY_CT_RESET  (1<<15) /* Bit 15: (sc) clear all PHY related regs */
+ #define PHY_CT_LOOP           (1<<14) /* Bit 14:      enable Loopback over PHY */
+-#define PHY_CT_SPS_LSB        (1<<13) /* Bit 13: (BC,L1) Speed select, lower bit */
++#define PHY_CT_SPS_LSB        (1<<13) /* Bit 13:      Speed select, lower bit */
+ #define PHY_CT_ANE            (1<<12) /* Bit 12:      Auto-Negotiation Enabled */
+-#define PHY_CT_PDOWN  (1<<11) /* Bit 11: (BC,L1) Power Down Mode */
+-#define PHY_CT_ISOL           (1<<10) /* Bit 10: (BC,L1) Isolate Mode */
+-#define PHY_CT_RE_CFG (1<<9)  /* Bit  9: (sc) Restart Auto-Negotiation */
++#define PHY_CT_PDOWN  (1<<11) /* Bit 11:      Power Down Mode */
++#define PHY_CT_ISOL           (1<<10) /* Bit 10:      Isolate Mode */
++#define PHY_CT_RE_CFG (1<<9)  /* Bit  9:      (sc) Restart Auto-Negotiation */
+ #define PHY_CT_DUP_MD (1<<8)  /* Bit  8:      Duplex Mode */
+-#define PHY_CT_COL_TST        (1<<7)  /* Bit  7: (BC,L1) Collision Test enabled */
+-#define PHY_CT_SPS_MSB        (1<<6)  /* Bit  6: (BC,L1) Speed select, upper bit */
++#define PHY_CT_COL_TST        (1<<7)  /* Bit  7:      Collision Test enabled */
++#define PHY_CT_SPS_MSB        (1<<6)  /* Bit  6:      Speed select, upper bit */
+                                                               /* Bit  5..0:   reserved */
+ #define PHY_CT_SP1000 PHY_CT_SPS_MSB  /* enable speed of 1000 Mbps */
+@@ -649,25 +658,25 @@
+ /*****  PHY_MARV_STAT 16 bit r/w      PHY Status Register *****/
+ /*****  PHY_LONE_STAT 16 bit r/w      PHY Status Register *****/
+                                                               /* Bit 15..9:   reserved */
+-                              /*      (BC/L1) 100/10 Mbps cap bits ignored*/
++                              /*      (BC/L1) 100/10 Mbps cap bits ignored */
+ #define PHY_ST_EXT_ST (1<<8)  /* Bit  8:      Extended Status Present */
+                                                               /* Bit  7:      reserved */
+-#define PHY_ST_PRE_SUP        (1<<6)  /* Bit  6: (BC/L1) preamble suppression */
++#define PHY_ST_PRE_SUP        (1<<6)  /* Bit  6:      Preamble Suppression */
+ #define PHY_ST_AN_OVER        (1<<5)  /* Bit  5:      Auto-Negotiation Over */
+ #define PHY_ST_REM_FLT        (1<<4)  /* Bit  4:      Remote Fault Condition Occured */
+ #define PHY_ST_AN_CAP (1<<3)  /* Bit  3:      Auto-Negotiation Capability */
+ #define PHY_ST_LSYNC  (1<<2)  /* Bit  2:      Link Synchronized */
+-#define PHY_ST_JAB_DET        (1<<1)  /* Bit  1: (BC/L1) Jabber Detected */
++#define PHY_ST_JAB_DET        (1<<1)  /* Bit  1:      Jabber Detected */
+ #define PHY_ST_EXT_REG        (1<<0)  /* Bit  0:      Extended Register available */
+-/*****        PHY_XMAC_ID1            16 bit r/o      PHY ID1 Register */
+-/*****        PHY_BCOM_ID1            16 bit r/o      PHY ID1 Register */
+-/*****        PHY_MARV_ID1            16 bit r/o      PHY ID1 Register */
+-/*****        PHY_LONE_ID1            16 bit r/o      PHY ID1 Register */
++/*****  PHY_XMAC_ID1          16 bit r/o      PHY ID1 Register */
++/*****  PHY_BCOM_ID1          16 bit r/o      PHY ID1 Register */
++/*****  PHY_MARV_ID1          16 bit r/o      PHY ID1 Register */
++/*****  PHY_LONE_ID1          16 bit r/o      PHY ID1 Register */
+ #define PHY_I1_OUI_MSK        (0x3f<<10)      /* Bit 15..10:  Organization Unique ID */
+ #define PHY_I1_MOD_NUM        (0x3f<<4)       /* Bit  9.. 4:  Model Number */
+-#define PHY_I1_REV_MSK        0x0f            /* Bit  3.. 0:  Revision Number */
++#define PHY_I1_REV_MSK        0xf                     /* Bit  3.. 0:  Revision Number */
+ /* different Broadcom PHY Ids */
+ #define PHY_BCOM_ID1_A1               0x6041
+@@ -675,11 +684,19 @@
+ #define PHY_BCOM_ID1_C0               0x6044
+ #define PHY_BCOM_ID1_C5               0x6047
++/* different Marvell PHY Ids */
++#define PHY_MARV_ID0_VAL      0x0141          /* Marvell Unique Identifier */
++
++#define PHY_MARV_ID1_B0               0x0C23          /* Yukon (PHY 88E1011) */
++#define PHY_MARV_ID1_B2               0x0C25          /* Yukon-Plus (PHY 88E1011) */
++#define PHY_MARV_ID1_C2               0x0CC2          /* Yukon-EC (PHY 88E1111) */
++#define PHY_MARV_ID1_Y2               0x0C91          /* Yukon-2 (PHY 88E1112) */
++
+ /*****  PHY_XMAC_AUNE_ADV     16 bit r/w      Auto-Negotiation Advertisement *****/
+ /*****  PHY_XMAC_AUNE_LP      16 bit r/o      Link Partner Ability Reg *****/
+ #define PHY_AN_NXT_PG (1<<15) /* Bit 15:      Request Next Page */
+-#define PHY_X_AN_ACK  (1<<14) /* Bit 14: (ro) Acknowledge Received */
++#define PHY_X_AN_ACK  (1<<14) /* Bit 14:      (ro) Acknowledge Received */
+ #define PHY_X_AN_RFB  (3<<12) /* Bit 13..12:  Remote Fault Bits */
+                                                               /* Bit 11.. 9:  reserved */
+ #define PHY_X_AN_PAUSE        (3<<7)  /* Bit  8.. 7:  Pause Bits */
+@@ -827,7 +844,7 @@
+ #define PHY_B_PEC_BY_MLT3     (1<<8)  /* Bit  8:      Bypass MLT3 Encoder */
+ #define PHY_B_PEC_BY_RXA      (1<<7)  /* Bit  7:      Bypass Rx Alignm. */
+ #define PHY_B_PEC_RES_SCR     (1<<6)  /* Bit  6:      Reset Scrambler */
+-#define PHY_B_PEC_EN_LTR      (1<<5)  /* Bit  5:      Ena LED Traffic Mode */
++#define PHY_B_PEC_EN_LTR      (1<<5)  /* Bit  5:      Enable LED Traffic Mode */
+ #define PHY_B_PEC_LED_ON      (1<<4)  /* Bit  4:      Force LED's on */
+ #define PHY_B_PEC_LED_OFF     (1<<3)  /* Bit  3:      Force LED's off */
+ #define PHY_B_PEC_EX_IPG      (1<<2)  /* Bit  2:      Extend Tx IPG Mode */
+@@ -981,7 +998,7 @@
+ #define PHY_L_QS_DUP_MOD      (1<<9)  /* Bit  9:      Full/Half Duplex */
+ #define PHY_L_QS_AN                   (1<<8)  /* Bit  8:      AutoNeg is On */
+ #define PHY_L_QS_AN_C         (1<<7)  /* Bit  7:      AN is Complete */
+-#define PHY_L_QS_LLE          (7<<4)  /* Bit  6:      Line Length Estim. */
++#define PHY_L_QS_LLE          (7<<4)  /* Bit  6..4:   Line Length Estim. */
+ #define PHY_L_QS_PAUSE                (1<<3)  /* Bit  3:      LP advertised Pause */
+ #define PHY_L_QS_AS_PAUSE     (1<<2)  /* Bit  2:      LP adv. asym. Pause */
+ #define PHY_L_QS_ISOLATE      (1<<1)  /* Bit  1:      CIM Isolated */
+@@ -1029,9 +1046,8 @@
+                                                                       /* Bit  9..0:   not described */
+ /*****  PHY_LONE_CIM          16 bit r/o      CIM Reg *****/
+-#define PHY_L_CIM_ISOL                (255<<8)/* Bit 15..8:   Isolate Count */
+-#define PHY_L_CIM_FALSE_CAR   (255<<0)/* Bit  7..0:   False Carrier Count */
+-
++#define PHY_L_CIM_ISOL                (0xff<<8)       /* Bit 15..8:   Isolate Count */
++#define PHY_L_CIM_FALSE_CAR   0xff            /* Bit  7..0:   False Carrier Count */
+ /*
+  * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
+@@ -1041,7 +1057,6 @@
+ #define PHY_L_P_ASYM_MD               (2<<10) /* Bit 11..10:  asymmetric Pause Mode */
+ #define PHY_L_P_BOTH_MD               (3<<10) /* Bit 11..10:  both Pause Mode */
+-
+ /*
+  * National-Specific
+  */
+@@ -1086,22 +1101,24 @@
+  */
+ /*****  PHY_MARV_AUNE_ADV     16 bit r/w      Auto-Negotiation Advertisement *****/
+ /*****  PHY_MARV_AUNE_LP      16 bit r/w      Link Part Ability Reg *****/
+-#define PHY_M_AN_NXT_PG               BIT_15  /* Request Next Page */
+-#define PHY_M_AN_ACK          BIT_14  /* (ro) Acknowledge Received */
+-#define PHY_M_AN_RF                   BIT_13  /* Remote Fault */
+-                                                                      /* Bit 12:      reserved */
+-#define PHY_M_AN_ASP          BIT_11  /* Asymmetric Pause */
+-#define PHY_M_AN_PC                   BIT_10  /* MAC Pause implemented */
+-#define PHY_M_AN_100_FD               BIT_8   /* Advertise 100Base-TX Full Duplex */
+-#define PHY_M_AN_100_HD               BIT_7   /* Advertise 100Base-TX Half Duplex */
+-#define PHY_M_AN_10_FD                BIT_6   /* Advertise 10Base-TX Full Duplex */
+-#define PHY_M_AN_10_HD                BIT_5   /* Advertise 10Base-TX Half Duplex */
++#define PHY_M_AN_NXT_PG               BIT_15S /* Request Next Page */
++#define PHY_M_AN_ACK          BIT_14S /* (ro) Acknowledge Received */
++#define PHY_M_AN_RF                   BIT_13S /* Remote Fault */
++                                                              /* Bit 12:      reserved */
++#define PHY_M_AN_ASP          BIT_11S /* Asymmetric Pause */
++#define PHY_M_AN_PC                   BIT_10S /* MAC Pause implemented */
++#define PHY_M_AN_100_T4               BIT_9S  /* Not cap. 100Base-T4 (always 0) */
++#define PHY_M_AN_100_FD               BIT_8S  /* Advertise 100Base-TX Full Duplex */
++#define PHY_M_AN_100_HD               BIT_7S  /* Advertise 100Base-TX Half Duplex */
++#define PHY_M_AN_10_FD                BIT_6S  /* Advertise 10Base-TX Full Duplex */
++#define PHY_M_AN_10_HD                BIT_5S  /* Advertise 10Base-TX Half Duplex */
++#define PHY_M_AN_SEL_MSK      (0x1f<<4)       /* Bit  4.. 0: Selector Field Mask */
+ /* special defines for FIBER (88E1011S only) */
+-#define PHY_M_AN_ASP_X                BIT_8   /* Asymmetric Pause */
+-#define PHY_M_AN_PC_X         BIT_7   /* MAC Pause implemented */
+-#define PHY_M_AN_1000X_AHD    BIT_6   /* Advertise 10000Base-X Half Duplex */
+-#define PHY_M_AN_1000X_AFD    BIT_5   /* Advertise 10000Base-X Full Duplex */
++#define PHY_M_AN_ASP_X                BIT_8S  /* Asymmetric Pause */
++#define PHY_M_AN_PC_X         BIT_7S  /* MAC Pause implemented */
++#define PHY_M_AN_1000X_AHD    BIT_6S  /* Advertise 10000Base-X Half Duplex */
++#define PHY_M_AN_1000X_AFD    BIT_5S  /* Advertise 10000Base-X Full Duplex */
+ /* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */
+ #define PHY_M_P_NO_PAUSE_X    (0<<7)  /* Bit  8.. 7:  no Pause Mode */
+@@ -1111,105 +1128,162 @@
+ /*****  PHY_MARV_1000T_CTRL   16 bit r/w      1000Base-T Control Reg *****/
+ #define PHY_M_1000C_TEST      (7<<13) /* Bit 15..13:  Test Modes */
+-#define PHY_M_1000C_MSE               (1<<12) /* Bit 12:      Manual Master/Slave Enable */
+-#define PHY_M_1000C_MSC               (1<<11) /* Bit 11:      M/S Configuration (1=Master) */
+-#define PHY_M_1000C_MPD               (1<<10) /* Bit 10:      Multi-Port Device */
+-#define PHY_M_1000C_AFD               (1<<9)  /* Bit  9:      Advertise Full Duplex */
+-#define PHY_M_1000C_AHD               (1<<8)  /* Bit  8:      Advertise Half Duplex */
++#define PHY_M_1000C_MSE               BIT_12S /* Manual Master/Slave Enable */
++#define PHY_M_1000C_MSC               BIT_11S /* M/S Configuration (1=Master) */
++#define PHY_M_1000C_MPD               BIT_10S /* Multi-Port Device */
++#define PHY_M_1000C_AFD               BIT_9S  /* Advertise Full Duplex */
++#define PHY_M_1000C_AHD               BIT_8S  /* Advertise Half Duplex */
+                                                                       /* Bit  7..0:   reserved */
+ /*****  PHY_MARV_PHY_CTRL     16 bit r/w      PHY Specific Ctrl Reg *****/
+-#define PHY_M_PC_TX_FFD_MSK   (3<<14) /* Bit 15..14:  Tx FIFO Depth Mask */
+-#define PHY_M_PC_RX_FFD_MSK   (3<<12) /* Bit 13..12:  Rx FIFO Depth Mask */
+-#define PHY_M_PC_ASS_CRS_TX   (1<<11) /* Bit 11:      Assert CRS on Transmit */
+-#define PHY_M_PC_FL_GOOD      (1<<10) /* Bit 10:      Force Link Good */
+-#define PHY_M_PC_EN_DET_MSK   (3<<8)  /* Bit  9.. 8:  Energy Detect Mask */
+-#define PHY_M_PC_ENA_EXT_D    (1<<7)  /* Bit  7:      Enable Ext. Distance (10BT) */
+-#define PHY_M_PC_MDIX_MSK     (3<<5)  /* Bit  6.. 5:  MDI/MDIX Config. Mask */
+-#define PHY_M_PC_DIS_125CLK   (1<<4)  /* Bit  4:      Disable 125 CLK */
+-#define PHY_M_PC_MAC_POW_UP   (1<<3)  /* Bit  3:      MAC Power up */
+-#define PHY_M_PC_SQE_T_ENA    (1<<2)  /* Bit  2:      SQE Test Enabled */
+-#define PHY_M_PC_POL_R_DIS    (1<<1)  /* Bit  1:      Polarity Reversal Disabled */
+-#define PHY_M_PC_DIS_JABBER   (1<<0)  /* Bit  0:      Disable Jabber */
++#define PHY_M_PC_TX_FFD_MSK   (3<<14) /* Bit 15..14: Tx FIFO Depth Mask */
++#define PHY_M_PC_RX_FFD_MSK   (3<<12) /* Bit 13..12: Rx FIFO Depth Mask */
++#define PHY_M_PC_ASS_CRS_TX   BIT_11S /* Assert CRS on Transmit */
++#define PHY_M_PC_FL_GOOD      BIT_10S /* Force Link Good */
++#define PHY_M_PC_EN_DET_MSK   (3<<8)  /* Bit  9.. 8: Energy Detect Mask */
++#define PHY_M_PC_ENA_EXT_D    BIT_7S  /* Enable Ext. Distance (10BT) */
++#define PHY_M_PC_MDIX_MSK     (3<<5)  /* Bit  6.. 5: MDI/MDIX Config. Mask */
++#define PHY_M_PC_DIS_125CLK   BIT_4S  /* Disable 125 CLK */
++#define PHY_M_PC_MAC_POW_UP   BIT_3S  /* MAC Power up */
++#define PHY_M_PC_SQE_T_ENA    BIT_2S  /* SQE Test Enabled */
++#define PHY_M_PC_POL_R_DIS    BIT_1S  /* Polarity Reversal Disabled */
++#define PHY_M_PC_DIS_JABBER   BIT_0S  /* Disable Jabber */
+ #define PHY_M_PC_EN_DET                       SHIFT8(2)       /* Energy Detect (Mode 1) */
+ #define PHY_M_PC_EN_DET_PLUS  SHIFT8(3)       /* Energy Detect Plus (Mode 2) */
+-#define PHY_M_PC_MDI_XMODE(x) SHIFT5(x)       
+-#define PHY_M_PC_MAN_MDI      0       /* 00 = Manual MDI configuration */
++#define PHY_M_PC_MDI_XMODE(x) (SHIFT5(x) & PHY_M_PC_MDIX_MSK) 
++
++#define PHY_M_PC_MAN_MDI      0               /* 00 = Manual MDI configuration */
+ #define PHY_M_PC_MAN_MDIX     1               /* 01 = Manual MDIX configuration */
+ #define PHY_M_PC_ENA_AUTO     3               /* 11 = Enable Automatic Crossover */
++/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
++#define PHY_M_PC_DIS_LINK_P   BIT_15S /* Disable Link Pulses */
++#define PHY_M_PC_DSC_MSK      (7<<12) /* Bit 14..12:  Downshift Counter */
++#define PHY_M_PC_DOWN_S_ENA   BIT_11S /* Downshift Enable */
++                                                                      /* !!! Errata in spec. (1 = disable) */
++
++#define PHY_M_PC_DSC(x)                       (SHIFT12(x) & PHY_M_PC_DSC_MSK)
++                                                                              /* 000=1x; 001=2x; 010=3x; 011=4x */
++                                                                              /* 100=5x; 101=6x; 110=7x; 111=8x */
++
++/* for 10/100 Fast Ethernet PHY (88E3082 only) */
++#define PHY_M_PC_ENA_DTE_DT   BIT_15S /* Enable Data Terminal Equ. (DTE) Detect */
++#define PHY_M_PC_ENA_ENE_DT   BIT_14S /* Enable Energy Detect (sense & pulse) */
++#define PHY_M_PC_DIS_NLP_CK   BIT_13S /* Disable Normal Link Puls (NLP) Check */
++#define PHY_M_PC_ENA_LIP_NP   BIT_12S /* Enable Link Partner Next Page Reg. */
++#define PHY_M_PC_DIS_NLP_GN   BIT_11S /* Disable Normal Link Puls Generation */
++
++#define PHY_M_PC_DIS_SCRAMB   BIT_9S  /* Disable Scrambler */
++#define PHY_M_PC_DIS_FEFI     BIT_8S  /* Disable Far End Fault Indic. (FEFI) */
++
++#define PHY_M_PC_SH_TP_SEL    BIT_6S  /* Shielded Twisted Pair Select */
++#define PHY_M_PC_RX_FD_MSK    (3<<2)  /* Bit  3.. 2: Rx FIFO Depth Mask */
++
+ /*****  PHY_MARV_PHY_STAT     16 bit r/o      PHY Specific Status Reg *****/
+-#define PHY_M_PS_SPEED_MSK    (3<<14) /* Bit 15..14:  Speed Mask */
+-#define PHY_M_PS_SPEED_1000   (1<<15) /*       10 = 1000 Mbps */
+-#define PHY_M_PS_SPEED_100    (1<<14) /*       01 =  100 Mbps */
+-#define PHY_M_PS_SPEED_10     0               /*       00 =   10 Mbps */
+-#define PHY_M_PS_FULL_DUP     (1<<13) /* Bit 13:      Full Duplex */
+-#define PHY_M_PS_PAGE_REC     (1<<12) /* Bit 12:      Page Received */
+-#define PHY_M_PS_SPDUP_RES    (1<<11) /* Bit 11:      Speed & Duplex Resolved */
+-#define PHY_M_PS_LINK_UP      (1<<10) /* Bit 10:      Link Up */
+-#define PHY_M_PS_CABLE_MSK    (3<<7)  /* Bit  9.. 7:  Cable Length Mask */
+-#define PHY_M_PS_MDI_X_STAT   (1<<6)  /* Bit  6:      MDI Crossover Stat (1=MDIX) */
+-#define PHY_M_PS_DOWNS_STAT   (1<<5)  /* Bit  5:      Downshift Status (1=downsh.) */
+-#define PHY_M_PS_ENDET_STAT   (1<<4)  /* Bit  4:      Energy Detect Status (1=act) */
+-#define PHY_M_PS_TX_P_EN      (1<<3)  /* Bit  3:      Tx Pause Enabled */
+-#define PHY_M_PS_RX_P_EN      (1<<2)  /* Bit  2:      Rx Pause Enabled */
+-#define PHY_M_PS_POL_REV      (1<<1)  /* Bit  1:      Polarity Reversed */
+-#define PHY_M_PC_JABBER               (1<<0)  /* Bit  0:      Jabber */
++#define PHY_M_PS_SPEED_MSK    (3<<14) /* Bit 15..14: Speed Mask */
++#define PHY_M_PS_SPEED_1000   BIT_15S /*              10 = 1000 Mbps */
++#define PHY_M_PS_SPEED_100    BIT_14S /*              01 =  100 Mbps */
++#define PHY_M_PS_SPEED_10     0               /*              00 =   10 Mbps */
++#define PHY_M_PS_FULL_DUP     BIT_13S /* Full Duplex */
++#define PHY_M_PS_PAGE_REC     BIT_12S /* Page Received */
++#define PHY_M_PS_SPDUP_RES    BIT_11S /* Speed & Duplex Resolved */
++#define PHY_M_PS_LINK_UP      BIT_10S /* Link Up */
++#define PHY_M_PS_CABLE_MSK    (7<<7)  /* Bit  9.. 7: Cable Length Mask */
++#define PHY_M_PS_MDI_X_STAT   BIT_6S  /* MDI Crossover Stat (1=MDIX) */
++#define PHY_M_PS_DOWNS_STAT   BIT_5S  /* Downshift Status (1=downsh.) */
++#define PHY_M_PS_ENDET_STAT   BIT_4S  /* Energy Detect Status (1=act) */
++#define PHY_M_PS_TX_P_EN      BIT_3S  /* Tx Pause Enabled */
++#define PHY_M_PS_RX_P_EN      BIT_2S  /* Rx Pause Enabled */
++#define PHY_M_PS_POL_REV      BIT_1S  /* Polarity Reversed */
++#define PHY_M_PS_JABBER               BIT_0S  /* Jabber */
+ #define PHY_M_PS_PAUSE_MSK    (PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN)
++/* for 10/100 Fast Ethernet PHY (88E3082 only) */
++#define PHY_M_PS_DTE_DETECT   BIT_15S /* Data Terminal Equipment (DTE) Detected */
++#define PHY_M_PS_RES_SPEED    BIT_14S /* Resolved Speed (1=100 Mbps, 0=10 Mbps */
++
+ /*****  PHY_MARV_INT_MASK     16 bit r/w      Interrupt Mask Reg *****/
+ /*****  PHY_MARV_INT_STAT     16 bit r/o      Interrupt Status Reg *****/
+-#define PHY_M_IS_AN_ERROR     (1<<15) /* Bit 15:      Auto-Negotiation Error */
+-#define PHY_M_IS_LSP_CHANGE   (1<<14) /* Bit 14:      Link Speed Changed */
+-#define PHY_M_IS_DUP_CHANGE   (1<<13) /* Bit 13:      Duplex Mode Changed */
+-#define PHY_M_IS_AN_PR                (1<<12) /* Bit 12:      Page Received */
+-#define PHY_M_IS_AN_COMPL     (1<<11) /* Bit 11:      Auto-Negotiation Completed */
+-#define PHY_M_IS_LST_CHANGE   (1<<10) /* Bit 10:      Link Status Changed */
+-#define PHY_M_IS_SYMB_ERROR   (1<<9)  /* Bit  9:      Symbol Error */
+-#define PHY_M_IS_FALSE_CARR   (1<<8)  /* Bit  8:      False Carrier */
+-#define PHY_M_IS_FIFO_ERROR   (1<<7)  /* Bit  7:      FIFO Overflow/Underrun Error */
+-#define PHY_M_IS_MDI_CHANGE   (1<<6)  /* Bit  6:      MDI Crossover Changed */
+-#define PHY_M_IS_DOWNSH_DET   (1<<5)  /* Bit  5:      Downshift Detected */
+-#define PHY_M_IS_END_CHANGE   (1<<4)  /* Bit  4:      Energy Detect Changed */
+-                                                                      /* Bit  3..2:   reserved */
+-#define PHY_M_IS_POL_CHANGE   (1<<1)  /* Bit  1:      Polarity Changed */
+-#define PHY_M_IS_JABBER               (1<<0)  /* Bit  0:      Jabber */
++#define PHY_M_IS_AN_ERROR     BIT_15S /* Auto-Negotiation Error */
++#define PHY_M_IS_LSP_CHANGE   BIT_14S /* Link Speed Changed */
++#define PHY_M_IS_DUP_CHANGE   BIT_13S /* Duplex Mode Changed */
++#define PHY_M_IS_AN_PR                BIT_12S /* Page Received */
++#define PHY_M_IS_AN_COMPL     BIT_11S /* Auto-Negotiation Completed */
++#define PHY_M_IS_LST_CHANGE   BIT_10S /* Link Status Changed */
++#define PHY_M_IS_SYMB_ERROR   BIT_9S  /* Symbol Error */
++#define PHY_M_IS_FALSE_CARR   BIT_8S  /* False Carrier */
++#define PHY_M_IS_FIFO_ERROR   BIT_7S  /* FIFO Overflow/Underrun Error */
++#define PHY_M_IS_MDI_CHANGE   BIT_6S  /* MDI Crossover Changed */
++#define PHY_M_IS_DOWNSH_DET   BIT_5S  /* Downshift Detected */
++#define PHY_M_IS_END_CHANGE   BIT_4S  /* Energy Detect Changed */
++                                                              /* Bit   3:     reserved */
++#define PHY_M_IS_DTE_CHANGE   BIT_2S  /* DTE Power Det. Status Changed */
++                                                                      /* (88E1111 only) */
++#define PHY_M_IS_POL_CHANGE   BIT_1S  /* Polarity Changed */
++#define PHY_M_IS_JABBER               BIT_0S  /* Jabber */
+ #define PHY_M_DEF_MSK         (PHY_M_IS_AN_ERROR | PHY_M_IS_AN_PR | \
+                                                       PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR)
+ /*****  PHY_MARV_EXT_CTRL     16 bit r/w      Ext. PHY Specific Ctrl *****/
+-#define PHY_M_EC_M_DSC_MSK    (3<<10) /* Bit 11..10:  Master downshift counter */
+-#define PHY_M_EC_S_DSC_MSK    (3<<8)  /* Bit  9.. 8:  Slave  downshift counter */
++#define PHY_M_EC_ENA_BC_EXT   BIT_15S /* Enable Block Carr. Ext. (88E1111 only) */
++#define PHY_M_EC_ENA_LIN_LB   BIT_14S /* Enable Line Loopback (88E1111 only) */
++                                                              /* Bit 13:      reserved */
++#define PHY_M_EC_DIS_LINK_P   BIT_12S /* Disable Link Pulses (88E1111 only) */
++#define PHY_M_EC_M_DSC_MSK    (3<<10) /* Bit 11..10:  Master Downshift Counter */
++                                                                      /* (88E1011 only) */
++#define PHY_M_EC_S_DSC_MSK    (3<<8)  /* Bit  9.. 8:  Slave  Downshift Counter */
++                                                                      /* (88E1011 only) */
++#define PHY_M_EC_DSC_MSK_2    (7<<9)  /* Bit 11.. 9:  Downshift Counter */
++                                                                      /* (88E1111 only) */
++#define PHY_M_EC_DOWN_S_ENA   BIT_8S  /* Downshift Enable (88E1111 only) */
++                                                                      /* !!! Errata in spec. (1 = disable) */
++#define PHY_M_EC_RX_TIM_CT    BIT_7S  /* RGMII Rx Timing Control*/
+ #define PHY_M_EC_MAC_S_MSK    (7<<4)  /* Bit  6.. 4:  Def. MAC interface speed */
+-#define PHY_M_EC_FIB_AN_ENA   (1<<3)  /* Bit  3:      Fiber Auto-Neg. Enable */
+-
+-#define PHY_M_EC_M_DSC(x)             SHIFT10(x)      /* 00=1x; 01=2x; 10=3x; 11=4x */
+-#define PHY_M_EC_S_DSC(x)             SHIFT8(x)       /* 00=dis; 01=1x; 10=2x; 11=3x */
+-#define PHY_M_EC_MAC_S(x)             SHIFT4(x)       /* 01X=0; 110=2.5; 111=25 (MHz) */
+-
++#define PHY_M_EC_FIB_AN_ENA   BIT_3S  /* Fiber Auto-Neg. Enable (88E1011S only) */
++#define PHY_M_EC_DTE_D_ENA    BIT_2S  /* DTE Detect Enable (88E1111 only) */
++#define PHY_M_EC_TX_TIM_CT    BIT_1S  /* RGMII Tx Timing Control */
++#define PHY_M_EC_TRANS_DIS    BIT_0S  /* Transmitter Disable (88E1111 only) */
++
++#define PHY_M_EC_M_DSC(x)             (SHIFT10(x) & PHY_M_EC_M_DSC_MSK)
++                                                                      /* 00=1x; 01=2x; 10=3x; 11=4x */
++#define PHY_M_EC_S_DSC(x)             (SHIFT8(x) & PHY_M_EC_S_DSC_MSK)
++                                                                      /* 00=dis; 01=1x; 10=2x; 11=3x */
++#define PHY_M_EC_MAC_S(x)             (SHIFT4(x) & PHY_M_EC_MAC_S_MSK)
++                                                                      /* 01X=0; 110=2.5; 111=25 (MHz) */
++
++#define PHY_M_EC_DSC_2(x)             (SHIFT9(x) & PHY_M_EC_DSC_MSK_2)
++                                                                      /* 000=1x; 001=2x; 010=3x; 011=4x */
++                                                                      /* 100=5x; 101=6x; 110=7x; 111=8x */
+ #define MAC_TX_CLK_0_MHZ      2
+ #define MAC_TX_CLK_2_5_MHZ    6
+ #define MAC_TX_CLK_25_MHZ     7
+ /*****  PHY_MARV_LED_CTRL     16 bit r/w      LED Control Reg *****/
+-#define PHY_M_LEDC_DIS_LED    (1<<15) /* Bit 15:      Disable LED */
+-#define PHY_M_LEDC_PULS_MSK   (7<<12) /* Bit 14..12:  Pulse Stretch Mask */
+-#define PHY_M_LEDC_F_INT      (1<<11) /* Bit 11:      Force Interrupt */
+-#define PHY_M_LEDC_BL_R_MSK   (7<<8)  /* Bit 10.. 8:  Blink Rate Mask */
+-                                                                      /* Bit  7.. 5:  reserved */
+-#define PHY_M_LEDC_LINK_MSK   (3<<3)  /* Bit  4.. 3:  Link Control Mask */
+-#define PHY_M_LEDC_DP_CTRL    (1<<2)  /* Bit  2:      Duplex Control */
+-#define PHY_M_LEDC_RX_CTRL    (1<<1)  /* Bit  1:      Rx activity / Link */
+-#define PHY_M_LEDC_TX_CTRL    (1<<0)  /* Bit  0:      Tx activity / Link */
++#define PHY_M_LEDC_DIS_LED    BIT_15S /* Disable LED */
++#define PHY_M_LEDC_PULS_MSK   (7<<12) /* Bit 14..12: Pulse Stretch Mask */
++#define PHY_M_LEDC_F_INT      BIT_11S /* Force Interrupt */
++#define PHY_M_LEDC_BL_R_MSK   (7<<8)  /* Bit 10.. 8: Blink Rate Mask */
++#define PHY_M_LEDC_DP_C_LSB   BIT_7S  /* Duplex Control (LSB, 88E1111 only) */
++#define PHY_M_LEDC_TX_C_LSB   BIT_6S  /* Tx Control (LSB, 88E1111 only) */
++#define PHY_M_LEDC_LK_C_MSK   (7<<3)  /* Bit  5.. 3: Link Control Mask */
++                                                                      /* (88E1111 only) */
++                                                              /* Bit  7.. 5:  reserved (88E1011 only) */
++#define PHY_M_LEDC_LINK_MSK   (3<<3)  /* Bit  4.. 3: Link Control Mask */
++                                                                      /* (88E1011 only) */
++#define PHY_M_LEDC_DP_CTRL    BIT_2S  /* Duplex Control */
++#define PHY_M_LEDC_DP_C_MSB   BIT_2S  /* Duplex Control (MSB, 88E1111 only) */
++#define PHY_M_LEDC_RX_CTRL    BIT_1S  /* Rx Activity / Link */
++#define PHY_M_LEDC_TX_CTRL    BIT_0S  /* Tx Activity / Link */
++#define PHY_M_LEDC_TX_C_MSB   BIT_0S  /* Tx Control (MSB, 88E1111 only) */
+-#define PHY_M_LED_PULS_DUR(x) SHIFT12(x)      /* Pulse Stretch Duration */
++#define PHY_M_LED_PULS_DUR(x) (SHIFT12(x) & PHY_M_LEDC_PULS_MSK)
+-#define       PULS_NO_STR             0               /* no pulse stretching */
+-#define       PULS_21MS               1               /* 21 ms to 42 ms */
++#define PULS_NO_STR           0               /* no pulse stretching */
++#define PULS_21MS             1               /* 21 ms to 42 ms */
+ #define PULS_42MS             2               /* 42 ms to 84 ms */
+ #define PULS_84MS             3               /* 84 ms to 170 ms */
+ #define PULS_170MS            4               /* 170 ms to 340 ms */
+@@ -1217,7 +1291,7 @@
+ #define PULS_670MS            6               /* 670 ms to 1.3 s */
+ #define PULS_1300MS           7               /* 1.3 s to 2.7 s */
+-#define PHY_M_LED_BLINK_RT(x) SHIFT8(x)       /* Blink Rate */
++#define PHY_M_LED_BLINK_RT(x) (SHIFT8(x) & PHY_M_LEDC_BL_R_MSK)
+ #define BLINK_42MS            0               /* 42 ms */
+ #define BLINK_84MS            1               /* 84 ms */
+@@ -1227,6 +1301,8 @@
+                                                               /* values 5 - 7: reserved */
+ /*****  PHY_MARV_LED_OVER     16 bit r/w      Manual LED Override Reg *****/
++#define PHY_M_LED_MO_SGMII(x) SHIFT14(x)      /* Bit 15..14:  SGMII AN Timer */
++                                                                              /* Bit 13..12:  reserved */
+ #define PHY_M_LED_MO_DUP(x)           SHIFT10(x)      /* Bit 11..10:  Duplex */
+ #define PHY_M_LED_MO_10(x)            SHIFT8(x)       /* Bit  9.. 8:  Link 10 */
+ #define PHY_M_LED_MO_100(x)           SHIFT6(x)       /* Bit  7.. 6:  Link 100 */
+@@ -1240,30 +1316,35 @@
+ #define MO_LED_ON                     3
+ /*****  PHY_MARV_EXT_CTRL_2   16 bit r/w      Ext. PHY Specific Ctrl 2 *****/
+-                                                                      /* Bit 15.. 7:  reserved */
+-#define PHY_M_EC2_FI_IMPED    (1<<6)  /* Bit  6:      Fiber Input  Impedance */
+-#define PHY_M_EC2_FO_IMPED    (1<<5)  /* Bit  5:      Fiber Output Impedance */
+-#define PHY_M_EC2_FO_M_CLK    (1<<4)  /* Bit  4:      Fiber Mode Clock Enable */
+-#define PHY_M_EC2_FO_BOOST    (1<<3)  /* Bit  3:      Fiber Output Boost */
++                                                              /* Bit 15.. 7:  reserved */
++#define PHY_M_EC2_FI_IMPED    BIT_6S  /* Fiber Input  Impedance */
++#define PHY_M_EC2_FO_IMPED    BIT_5S  /* Fiber Output Impedance */
++#define PHY_M_EC2_FO_M_CLK    BIT_4S  /* Fiber Mode Clock Enable */
++#define PHY_M_EC2_FO_BOOST    BIT_3S  /* Fiber Output Boost */
+ #define PHY_M_EC2_FO_AM_MSK   7               /* Bit  2.. 0:  Fiber Output Amplitude */
+-/*****        PHY_MARV_EXT_P_STAT 16 bit r/w  Ext. PHY Specific Status *****/
+-#define PHY_M_FC_AUTO_SEL     (1<<15) /* Bit 15:      Fiber/Copper Auto Sel. dis. */
+-#define PHY_M_FC_AN_REG_ACC (1<<14) /* Bit 14:        Fiber/Copper Autoneg. reg acc */
+-#define PHY_M_FC_RESULUTION (1<<13)   /* Bit 13:      Fiber/Copper Resulution */
+-#define PHY_M_SER_IF_AN_BP  (1<<12) /* Bit 12:        Ser IF autoneg. bypass enable */
+-#define PHY_M_SER_IF_BP_ST    (1<<11) /* Bit 11:      Ser IF autoneg. bypass status */
+-#define PHY_M_IRQ_POLARITY    (1<<10) /* Bit 10:      IRQ polarity */
+-                                                                      /* Bit 9..4: reserved */
+-#define PHY_M_UNDOC1          (1<< 7) /* undocumented bit !! */
+-#define PHY_M_MODE_MASK               (0xf<<0)/* Bit 3..0: copy of HWCFG MODE[3:0] */
+-
++/*****  PHY_MARV_EXT_P_STAT 16 bit r/w        Ext. PHY Specific Status *****/
++#define PHY_M_FC_AUTO_SEL     BIT_15S /* Fiber/Copper Auto Sel. Dis. */
++#define PHY_M_FC_AN_REG_ACC   BIT_14S /* Fiber/Copper AN Reg. Access */
++#define PHY_M_FC_RESOLUTION   BIT_13S /* Fiber/Copper Resolution */
++#define PHY_M_SER_IF_AN_BP    BIT_12S /* Ser. IF AN Bypass Enable */
++#define PHY_M_SER_IF_BP_ST    BIT_11S /* Ser. IF AN Bypass Status */
++#define PHY_M_IRQ_POLARITY    BIT_10S /* IRQ polarity */
++#define PHY_M_DIS_AUT_MED     BIT_9S  /* Disable Aut. Medium Reg. Selection */
++                                                                      /* (88E1111 only) */
++                                                              /* Bit  9.. 4: reserved (88E1011 only) */
++#define PHY_M_UNDOC1          BIT_7S  /* undocumented bit !! */
++#define PHY_M_DTE_POW_STAT    BIT_4S  /* DTE Power Status (88E1111 only) */
++#define PHY_M_MODE_MASK               0xf             /* Bit  3.. 0: copy of HWCFG MODE[3:0] */
+ /*****  PHY_MARV_CABLE_DIAG   16 bit r/o      Cable Diagnostic Reg *****/
+-#define PHY_M_CABD_ENA_TEST   (1<<15) /* Bit 15:      Enable Test */
+-#define PHY_M_CABD_STAT_MSK   (3<<13) /* Bit 14..13:  Status */
+-                                                                      /* Bit 12.. 8:  reserved */
+-#define PHY_M_CABD_DIST_MSK   0xff    /* Bit  7.. 0:  Distance */
++#define PHY_M_CABD_ENA_TEST   BIT_15S         /* Enable Test (Page 0) */
++#define PHY_M_CABD_DIS_WAIT   BIT_15S         /* Disable Waiting Period (Page 1) */
++                                                                              /* (88E1111 only) */
++#define PHY_M_CABD_STAT_MSK   (3<<13)         /* Bit 14..13: Status Mask */
++#define PHY_M_CABD_AMPL_MSK   (0x1f<<8)       /* Bit 12.. 8: Amplitude Mask */
++                                                                              /* (88E1111 only) */
++#define PHY_M_CABD_DIST_MSK   0xff            /* Bit  7.. 0: Distance Mask */
+ /* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */
+ #define CABD_STAT_NORMAL      0
+@@ -1271,6 +1352,72 @@
+ #define CABD_STAT_OPEN                2
+ #define CABD_STAT_FAIL                3
++/* for 10/100 Fast Ethernet PHY (88E3082 only) */
++/*****  PHY_MARV_FE_LED_PAR           16 bit r/w      LED Parallel Select Reg. *****/
++                                                                      /* Bit 15..12: reserved (used internally) */
++#define PHY_M_FELP_LED2_MSK   (0xf<<8)        /* Bit 11.. 8: LED2 Mask (LINK) */
++#define PHY_M_FELP_LED1_MSK   (0xf<<4)        /* Bit  7.. 4: LED1 Mask (ACT) */
++#define PHY_M_FELP_LED0_MSK   0xf                     /* Bit  3.. 0: LED0 Mask (SPEED) */
++
++#define PHY_M_FELP_LED2_CTRL(x)       (SHIFT8(x) & PHY_M_FELP_LED2_MSK)
++#define PHY_M_FELP_LED1_CTRL(x)       (SHIFT4(x) & PHY_M_FELP_LED1_MSK)
++#define PHY_M_FELP_LED0_CTRL(x)       (SHIFT0(x) & PHY_M_FELP_LED0_MSK)
++
++#define LED_PAR_CTRL_COLX     0x00
++#define LED_PAR_CTRL_ERROR    0x01
++#define LED_PAR_CTRL_DUPLEX   0x02
++#define LED_PAR_CTRL_DP_COL   0x03
++#define LED_PAR_CTRL_SPEED    0x04
++#define LED_PAR_CTRL_LINK     0x05
++#define LED_PAR_CTRL_TX               0x06
++#define LED_PAR_CTRL_RX               0x07
++#define LED_PAR_CTRL_ACT      0x08
++#define LED_PAR_CTRL_LNK_RX   0x09
++#define LED_PAR_CTRL_LNK_AC   0x0a
++#define LED_PAR_CTRL_ACT_BL   0x0b
++#define LED_PAR_CTRL_TX_BL    0x0c
++#define LED_PAR_CTRL_RX_BL    0x0d
++#define LED_PAR_CTRL_COL_BL   0x0e
++#define LED_PAR_CTRL_INACT    0x0f
++
++/*****  PHY_MARV_FE_SPEC_2            16 bit r/w      Specific Control Reg. 2 *****/
++#define PHY_M_FESC_DIS_WAIT   BIT_2S          /* Disable TDR Waiting Period */
++#define PHY_M_FESC_ENA_MCLK   BIT_1S          /* Enable MAC Rx Clock in sleep mode */
++#define PHY_M_FESC_SEL_CL_A   BIT_0S          /* Select Class A driver (100B-TX) */
++
++/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
++/*****  PHY_MARV_PHY_CTRL (page 2)            16 bit r/w      MAC Specific Ctrl *****/
++#define PHY_M_MAC_MD_MSK      (7<<7)          /* Bit  9.. 7: Mode Select Mask */
++#define PHY_M_MAC_MD_AUTO             3       /* Auto Copper/1000Base-X */
++#define PHY_M_MAC_MD_COPPER           5       /* Copper only */
++#define PHY_M_MAC_MD_1000BX           7       /* 1000Base-X only */
++#define PHY_M_MAC_MODE_SEL(x) (SHIFT7(x) & PHY_M_MAC_MD_MSK)
++
++/*****  PHY_MARV_PHY_CTRL (page 3)            16 bit r/w      LED Control Reg. *****/
++#define PHY_M_LEDC_LOS_MSK    (0xf<<12)       /* Bit 15..12: LOS LED Ctrl. Mask */
++#define PHY_M_LEDC_INIT_MSK   (0xf<<8)        /* Bit 11.. 8: INIT LED Ctrl. Mask */
++#define PHY_M_LEDC_STA1_MSK   (0xf<<4)        /* Bit  7.. 4: STAT1 LED Ctrl. Mask */
++#define PHY_M_LEDC_STA0_MSK   0xf                     /* Bit  3.. 0: STAT0 LED Ctrl. Mask */
++
++#define PHY_M_LEDC_LOS_CTRL(x)        (SHIFT12(x) & PHY_M_LEDC_LOS_MSK)
++#define PHY_M_LEDC_INIT_CTRL(x)       (SHIFT8(x) & PHY_M_LEDC_INIT_MSK)
++#define PHY_M_LEDC_STA1_CTRL(x)       (SHIFT4(x) & PHY_M_LEDC_STA1_MSK)
++#define PHY_M_LEDC_STA0_CTRL(x)       (SHIFT0(x) & PHY_M_LEDC_STA0_MSK)
++
++/*****  PHY_MARV_PHY_STAT (page 3)            16 bit r/w      Polarity Control Reg. *****/
++#define PHY_M_POLC_LS1M_MSK   (0xf<<12)       /* Bit 15..12: LOS,STAT1 Mix % Mask */
++#define PHY_M_POLC_IS0M_MSK   (0xf<<8)        /* Bit 11.. 8: INIT,STAT0 Mix % Mask */
++#define PHY_M_POLC_LOS_MSK    (0x3<<6)        /* Bit  7.. 6: LOS Pol. Ctrl. Mask */
++#define PHY_M_POLC_INIT_MSK   (0x3<<4)        /* Bit  5.. 4: INIT Pol. Ctrl. Mask */
++#define PHY_M_POLC_STA1_MSK   (0x3<<2)        /* Bit  3.. 2: STAT1 Pol. Ctrl. Mask */
++#define PHY_M_POLC_STA0_MSK   0x3                     /* Bit  1.. 0: STAT0 Pol. Ctrl. Mask */
++
++#define PHY_M_POLC_LS1_P_MIX(x)       (SHIFT12(x) & PHY_M_POLC_LS1M_MSK)
++#define PHY_M_POLC_IS0_P_MIX(x)       (SHIFT8(x) & PHY_M_POLC_IS0M_MSK)
++#define PHY_M_POLC_LOS_CTRL(x)        (SHIFT6(x) & PHY_M_POLC_LOS_MSK)
++#define PHY_M_POLC_INIT_CTRL(x)       (SHIFT4(x) & PHY_M_POLC_INIT_MSK)
++#define PHY_M_POLC_STA1_CTRL(x)       (SHIFT2(x) & PHY_M_POLC_STA1_MSK)
++#define PHY_M_POLC_STA0_CTRL(x)       (SHIFT0(x) & PHY_M_POLC_STA0_MSK)
+ /*
+  * GMAC registers
+@@ -1431,141 +1578,159 @@
+  */
+ /*    GM_GP_STAT      16 bit r/o      General Purpose Status Register */
+-#define GM_GPSR_SPEED         (1<<15) /* Bit 15:      Port Speed (1 = 100 Mbps) */
+-#define GM_GPSR_DUPLEX                (1<<14) /* Bit 14:      Duplex Mode (1 = Full) */
+-#define GM_GPSR_FC_TX_DIS     (1<<13) /* Bit 13:      Tx Flow-Control Mode Disabled */
+-#define GM_GPSR_LINK_UP               (1<<12) /* Bit 12:      Link Up Status */
+-#define GM_GPSR_PAUSE         (1<<11) /* Bit 11:      Pause State */
+-#define GM_GPSR_TX_ACTIVE     (1<<10) /* Bit 10:      Tx in Progress */
+-#define GM_GPSR_EXC_COL               (1<<9)  /* Bit  9:      Excessive Collisions Occured */
+-#define GM_GPSR_LAT_COL               (1<<8)  /* Bit  8:      Late Collisions Occured */
+-                                                              /* Bit  7..6:   reserved */
+-#define GM_GPSR_PHY_ST_CH     (1<<5)  /* Bit  5:      PHY Status Change */
+-#define GM_GPSR_GIG_SPEED     (1<<4)  /* Bit  4:      Gigabit Speed (1 = 1000 Mbps) */
+-#define GM_GPSR_PART_MODE     (1<<3)  /* Bit  3:      Partition mode */
+-#define GM_GPSR_FC_RX_DIS     (1<<2)  /* Bit  2:      Rx Flow-Control Mode Disabled */
+-#define GM_GPSR_PROM_EN               (1<<1)  /* Bit  1:      Promiscuous Mode Enabled */
+-                                                              /* Bit  0:      reserved */
+-      
++#define GM_GPSR_SPEED         BIT_15S /* Port Speed (1 = 100 Mbps) */
++#define GM_GPSR_DUPLEX                BIT_14S /* Duplex Mode (1 = Full) */
++#define GM_GPSR_FC_TX_DIS     BIT_13S /* Tx Flow-Control Mode Disabled */
++#define GM_GPSR_LINK_UP               BIT_12S /* Link Up Status */
++#define GM_GPSR_PAUSE         BIT_11S /* Pause State */
++#define GM_GPSR_TX_ACTIVE     BIT_10S /* Tx in Progress */
++#define GM_GPSR_EXC_COL               BIT_9S  /* Excessive Collisions Occured */
++#define GM_GPSR_LAT_COL               BIT_8S  /* Late Collisions Occured */
++                                                              /* Bit   7.. 6: reserved */
++#define GM_GPSR_PHY_ST_CH     BIT_5S  /* PHY Status Change */
++#define GM_GPSR_GIG_SPEED     BIT_4S  /* Gigabit Speed (1 = 1000 Mbps) */
++#define GM_GPSR_PART_MODE     BIT_3S  /* Partition mode */
++#define GM_GPSR_FC_RX_DIS     BIT_2S  /* Rx Flow-Control Mode Disabled */
++                                                              /* Bit   2.. 0: reserved */
++
+ /*    GM_GP_CTRL      16 bit r/w      General Purpose Control Register */
+-                                                              /* Bit 15:      reserved */
+-#define GM_GPCR_PROM_ENA      (1<<14) /* Bit 14:      Enable Promiscuous Mode */
+-#define GM_GPCR_FC_TX_DIS     (1<<13) /* Bit 13:      Disable Tx Flow-Control Mode */
+-#define GM_GPCR_TX_ENA                (1<<12) /* Bit 12:      Enable Transmit */
+-#define GM_GPCR_RX_ENA                (1<<11) /* Bit 11:      Enable Receive */
+-#define GM_GPCR_BURST_ENA     (1<<10) /* Bit 10:      Enable Burst Mode */
+-#define GM_GPCR_LOOP_ENA      (1<<9)  /* Bit  9:      Enable MAC Loopback Mode */
+-#define GM_GPCR_PART_ENA      (1<<8)  /* Bit  8:      Enable Partition Mode */
+-#define GM_GPCR_GIGS_ENA      (1<<7)  /* Bit  7:      Gigabit Speed (1000 Mbps) */
+-#define GM_GPCR_FL_PASS               (1<<6)  /* Bit  6:      Force Link Pass */
+-#define GM_GPCR_DUP_FULL      (1<<5)  /* Bit  5:      Full Duplex Mode */
+-#define GM_GPCR_FC_RX_DIS     (1<<4)  /* Bit  4:      Disable Rx Flow-Control Mode */
+-#define GM_GPCR_SPEED_100     (1<<3)  /* Bit  3:      Port Speed 100 Mbps */
+-#define GM_GPCR_AU_DUP_DIS    (1<<2)  /* Bit  2:      Disable Auto-Update Duplex */
+-#define GM_GPCR_AU_FCT_DIS    (1<<1)  /* Bit  1:      Disable Auto-Update Flow-C. */
+-#define GM_GPCR_AU_SPD_DIS    (1<<0)  /* Bit  0:      Disable Auto-Update Speed */
++#define GM_GPCR_RMII_PH_ENA   BIT_15S /* Enable RMII for PHY (Yukon-FE only) */
++#define GM_GPCR_RMII_LB_ENA   BIT_14S /* Enable RMII Loopback (Yukon-FE only) */
++#define GM_GPCR_FC_TX_DIS     BIT_13S /* Disable Tx Flow-Control Mode */
++#define GM_GPCR_TX_ENA                BIT_12S /* Enable Transmit */
++#define GM_GPCR_RX_ENA                BIT_11S /* Enable Receive */
++                                                              /* Bit 10:      reserved */
++#define GM_GPCR_LOOP_ENA      BIT_9S  /* Enable MAC Loopback Mode */
++#define GM_GPCR_PART_ENA      BIT_8S  /* Enable Partition Mode */
++#define GM_GPCR_GIGS_ENA      BIT_7S  /* Gigabit Speed (1000 Mbps) */
++#define GM_GPCR_FL_PASS               BIT_6S  /* Force Link Pass */
++#define GM_GPCR_DUP_FULL      BIT_5S  /* Full Duplex Mode */
++#define GM_GPCR_FC_RX_DIS     BIT_4S  /* Disable Rx Flow-Control Mode */
++#define GM_GPCR_SPEED_100     BIT_3S  /* Port Speed 100 Mbps */
++#define GM_GPCR_AU_DUP_DIS    BIT_2S  /* Disable Auto-Update Duplex */
++#define GM_GPCR_AU_FCT_DIS    BIT_1S  /* Disable Auto-Update Flow-C. */
++#define GM_GPCR_AU_SPD_DIS    BIT_0S  /* Disable Auto-Update Speed */
+ #define GM_GPCR_SPEED_1000    (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
+ #define GM_GPCR_AU_ALL_DIS    (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |\
+                                                        GM_GPCR_AU_SPD_DIS)
+-      
++
+ /*    GM_TX_CTRL                              16 bit r/w      Transmit Control Register */
+-#define GM_TXCR_FORCE_JAM     (1<<15) /* Bit 15:      Force Jam / Flow-Control */
+-#define GM_TXCR_CRC_DIS               (1<<14) /* Bit 14:      Disable insertion of CRC */
+-#define GM_TXCR_PAD_DIS               (1<<13) /* Bit 13:      Disable padding of packets */
+-#define GM_TXCR_COL_THR_MSK   (1<<10) /* Bit 12..10:  Collision Threshold */
++#define GM_TXCR_FORCE_JAM     BIT_15S /* Force Jam / Flow-Control */
++#define GM_TXCR_CRC_DIS               BIT_14S /* Disable insertion of CRC */
++#define GM_TXCR_PAD_DIS               BIT_13S /* Disable padding of packets */
++#define GM_TXCR_COL_THR_MSK   (7<<10) /* Bit 12..10: Collision Threshold Mask */
++                                                              /* Bit   9.. 8: reserved */
++#define GM_TXCR_PAD_PAT_MSK   0xff    /* Bit  7.. 0: Padding Pattern Mask */
++                                                                      /* (Yukon-2 only) */
+ #define TX_COL_THR(x)         (SHIFT10(x) & GM_TXCR_COL_THR_MSK)
+ #define TX_COL_DEF                    0x04
+-      
++
+ /*    GM_RX_CTRL                              16 bit r/w      Receive Control Register */
+-#define GM_RXCR_UCF_ENA               (1<<15) /* Bit 15:      Enable Unicast filtering */
+-#define GM_RXCR_MCF_ENA               (1<<14) /* Bit 14:      Enable Multicast filtering */
+-#define GM_RXCR_CRC_DIS               (1<<13) /* Bit 13:      Remove 4-byte CRC */
+-#define GM_RXCR_PASS_FC               (1<<12) /* Bit 12:      Pass FC packets to FIFO */
+-      
++#define GM_RXCR_UCF_ENA               BIT_15S /* Enable Unicast filtering */
++#define GM_RXCR_MCF_ENA               BIT_14S /* Enable Multicast filtering */
++#define GM_RXCR_CRC_DIS               BIT_13S /* Remove 4-byte CRC */
++#define GM_RXCR_PASS_FC               BIT_12S /* Pass FC packets to FIFO (Yukon-1 only) */
++                                                              /* Bit  11.. 0: reserved */
++
+ /*    GM_TX_PARAM                             16 bit r/w      Transmit Parameter Register */
+-#define GM_TXPA_JAMLEN_MSK    (0x03<<14)      /* Bit 15..14:  Jam Length */
+-#define GM_TXPA_JAMIPG_MSK    (0x1f<<9)       /* Bit 13..9:   Jam IPG */
+-#define GM_TXPA_JAMDAT_MSK    (0x1f<<4)       /* Bit  8..4:   IPG Jam to Data */
+-                                                              /* Bit  3..0:   reserved */
++#define GM_TXPA_JAMLEN_MSK    (3<<14)         /* Bit 15..14: Jam Length Mask */
++#define GM_TXPA_JAMIPG_MSK    (0x1f<<9)       /* Bit 13.. 9: Jam IPG Mask */
++#define GM_TXPA_JAMDAT_MSK    (0x1f<<4)       /* Bit  8.. 4: IPG Jam to Data Mask */
++#define GM_TXPA_BO_LIM_MSK    0x0f            /* Bit  3.. 0: Backoff Limit Mask */
++                                                                              /* (Yukon-2 only) */
+ #define TX_JAM_LEN_VAL(x)     (SHIFT14(x) & GM_TXPA_JAMLEN_MSK)
+ #define TX_JAM_IPG_VAL(x)     (SHIFT9(x) & GM_TXPA_JAMIPG_MSK)
+ #define TX_IPG_JAM_DATA(x)    (SHIFT4(x) & GM_TXPA_JAMDAT_MSK)
++#define TX_BACK_OFF_LIM(x)    ((x) & GM_TXPA_BO_LIM_MSK)
+ #define TX_JAM_LEN_DEF                0x03
+ #define TX_JAM_IPG_DEF                0x0b
+ #define TX_IPG_JAM_DEF                0x1c
++#define TX_BOF_LIM_DEF                0x04
+ /*    GM_SERIAL_MODE                  16 bit r/w      Serial Mode Register */
+-#define GM_SMOD_DATABL_MSK    (0x1f<<11)      /* Bit 15..11:  Data Blinder (r/o) */
+-#define GM_SMOD_LIMIT_4               (1<<10) /* Bit 10:      4 consecutive Tx trials */
+-#define GM_SMOD_VLAN_ENA      (1<<9)  /* Bit  9:      Enable VLAN  (Max. Frame Len) */
+-#define GM_SMOD_JUMBO_ENA     (1<<8)  /* Bit  8:      Enable Jumbo (Max. Frame Len) */
+-                                                              /* Bit  7..5:   reserved */
+-#define GM_SMOD_IPG_MSK               0x1f    /* Bit 4..0:    Inter-Packet Gap (IPG) */
+-      
++#define GM_SMOD_DATABL_MSK    (0x1f<<11)      /* Bit 15..11:  Data Blinder */
++                                                                              /* r/o on Yukon, r/w on Yukon-EC */
++#define GM_SMOD_LIMIT_4               BIT_10S /* 4 consecutive Tx trials */
++#define GM_SMOD_VLAN_ENA      BIT_9S  /* Enable VLAN  (Max. Frame Len) */
++#define GM_SMOD_JUMBO_ENA     BIT_8S  /* Enable Jumbo (Max. Frame Len) */
++                                                              /* Bit   7.. 5: reserved */
++#define GM_SMOD_IPG_MSK               0x1f    /* Bit  4.. 0:  Inter-Packet Gap (IPG) */
++
+ #define DATA_BLIND_VAL(x)     (SHIFT11(x) & GM_SMOD_DATABL_MSK)
+-#define DATA_BLIND_DEF                0x04
++#define IPG_DATA_VAL(x)               ((x) & GM_SMOD_IPG_MSK)
+-#define IPG_DATA_VAL(x)               (x & GM_SMOD_IPG_MSK)
++#define DATA_BLIND_DEF                0x04
+ #define IPG_DATA_DEF          0x1e
+ /*    GM_SMI_CTRL                             16 bit r/w      SMI Control Register */
+ #define GM_SMI_CT_PHY_A_MSK   (0x1f<<11)      /* Bit 15..11:  PHY Device Address */
+ #define GM_SMI_CT_REG_A_MSK   (0x1f<<6)       /* Bit 10.. 6:  PHY Register Address */
+-#define GM_SMI_CT_OP_RD               (1<<5)  /* Bit  5:      OpCode Read (0=Write)*/
+-#define GM_SMI_CT_RD_VAL      (1<<4)  /* Bit  4:      Read Valid (Read completed) */
+-#define GM_SMI_CT_BUSY                (1<<3)  /* Bit  3:      Busy (Operation in progress) */
+-                                                              /* Bit   2..0:  reserved */
+-      
++#define GM_SMI_CT_OP_RD               BIT_5S  /* OpCode Read (0=Write)*/
++#define GM_SMI_CT_RD_VAL      BIT_4S  /* Read Valid (Read completed) */
++#define GM_SMI_CT_BUSY                BIT_3S  /* Busy (Operation in progress) */
++                                                              /* Bit   2.. 0: reserved */
++
+ #define GM_SMI_CT_PHY_AD(x)   (SHIFT11(x) & GM_SMI_CT_PHY_A_MSK)
+ #define GM_SMI_CT_REG_AD(x)   (SHIFT6(x) & GM_SMI_CT_REG_A_MSK)
+       /*      GM_PHY_ADDR                             16 bit r/w      GPHY Address Register */
+-                                                              /* Bit  15..6:  reserved */
+-#define GM_PAR_MIB_CLR                (1<<5)  /* Bit  5:      Set MIB Clear Counter Mode */
+-#define GM_PAR_MIB_TST                (1<<4)  /* Bit  4:      MIB Load Counter (Test Mode) */
+-                                                              /* Bit   3..0:  reserved */
+-      
++                                                              /* Bit  15.. 6: reserved */
++#define GM_PAR_MIB_CLR                BIT_5S  /* Set MIB Clear Counter Mode */
++#define GM_PAR_MIB_TST                BIT_4S  /* MIB Load Counter (Test Mode) */
++                                                              /* Bit   3.. 0: reserved */
++
+ /* Receive Frame Status Encoding */
+-#define GMR_FS_LEN    (0xffffUL<<16)  /* Bit 31..16:  Rx Frame Length */
++#define GMR_FS_LEN_MSK        (0xffffUL<<16)  /* Bit 31..16:  Rx Frame Length */
+                                                               /* Bit  15..14: reserved */
+-#define GMR_FS_VLAN           (1L<<13)        /* Bit 13:      VLAN Packet */
+-#define GMR_FS_JABBER (1L<<12)        /* Bit 12:      Jabber Packet */
+-#define GMR_FS_UN_SIZE        (1L<<11)        /* Bit 11:      Undersize Packet */
+-#define GMR_FS_MC             (1L<<10)        /* Bit 10:      Multicast Packet */
+-#define GMR_FS_BC             (1L<<9)         /* Bit  9:      Broadcast Packet */
+-#define GMR_FS_RX_OK  (1L<<8)         /* Bit  8:      Receive OK (Good Packet) */
+-#define GMR_FS_GOOD_FC        (1L<<7)         /* Bit  7:      Good Flow-Control Packet */
+-#define GMR_FS_BAD_FC (1L<<6)         /* Bit  6:      Bad  Flow-Control Packet */
+-#define GMR_FS_MII_ERR        (1L<<5)         /* Bit  5:      MII Error */
+-#define GMR_FS_LONG_ERR       (1L<<4)         /* Bit  4:      Too Long Packet */
+-#define GMR_FS_FRAGMENT       (1L<<3)         /* Bit  3:      Fragment */
++#define GMR_FS_VLAN                   BIT_13  /* VLAN Packet */
++#define GMR_FS_JABBER         BIT_12  /* Jabber Packet */
++#define GMR_FS_UN_SIZE                BIT_11  /* Undersize Packet */
++#define GMR_FS_MC                     BIT_10  /* Multicast Packet */
++#define GMR_FS_BC                     BIT_9   /* Broadcast Packet */
++#define GMR_FS_RX_OK          BIT_8   /* Receive OK (Good Packet) */
++#define GMR_FS_GOOD_FC                BIT_7   /* Good Flow-Control Packet */
++#define GMR_FS_BAD_FC         BIT_6   /* Bad  Flow-Control Packet */
++#define GMR_FS_MII_ERR                BIT_5   /* MII Error */
++#define GMR_FS_LONG_ERR               BIT_4   /* Too Long Packet */
++#define GMR_FS_FRAGMENT               BIT_3   /* Fragment */
+                                                               /* Bit  2:      reserved */
+-#define GMR_FS_CRC_ERR        (1L<<1)         /* Bit  1:      CRC Error */
+-#define GMR_FS_RX_FF_OV       (1L<<0)         /* Bit  0:      Rx FIFO Overflow */
++#define GMR_FS_CRC_ERR                BIT_1   /* CRC Error */
++#define GMR_FS_RX_FF_OV               BIT_0   /* Rx FIFO Overflow */
++
++#define GMR_FS_LEN_SHIFT      16
+ /*
+  * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
+  */
+-#define GMR_FS_ANY_ERR        (GMR_FS_CRC_ERR | \
+-                      GMR_FS_LONG_ERR | \
++#ifdef SK_DIAG
++#define GMR_FS_ANY_ERR                ( \
++                      GMR_FS_RX_FF_OV | \
++                      GMR_FS_CRC_ERR | \
++                      GMR_FS_FRAGMENT | \
+                       GMR_FS_MII_ERR | \
+                       GMR_FS_BAD_FC | \
+                       GMR_FS_GOOD_FC | \
+                       GMR_FS_JABBER)
+-
+-/* Rx GMAC FIFO Flush Mask (default) */
+-#define RX_FF_FL_DEF_MSK      (GMR_FS_CRC_ERR | \
++#else
++#define GMR_FS_ANY_ERR                ( \
+                       GMR_FS_RX_FF_OV | \
++                      GMR_FS_CRC_ERR | \
++                      GMR_FS_FRAGMENT | \
++                      GMR_FS_LONG_ERR | \
+                       GMR_FS_MII_ERR | \
+                       GMR_FS_BAD_FC | \
+                       GMR_FS_GOOD_FC | \
+                       GMR_FS_UN_SIZE | \
+                       GMR_FS_JABBER)
++#endif
++
++/* Rx GMAC FIFO Flush Mask (default) */
++#define RX_FF_FL_DEF_MSK      GMR_FS_ANY_ERR
+ /* typedefs *******************************************************************/
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/Makefile linux-2.6.9.new/drivers/net/sk98lin/Makefile
+--- linux-2.6.9.old/drivers/net/sk98lin/Makefile       2004-10-19 05:53:05.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/Makefile       2006-12-07 14:35:03.000000000 +0800
+@@ -1,6 +1,59 @@
++#******************************************************************************
+ #
+-# Makefile for the SysKonnect SK-98xx device driver.
++# Name:         skge.c
++# Project:      GEnesis, PCI Gigabit Ethernet Adapter
++# Version:      $Revision: 1.9.2.1 $
++# Date:         $Date: 2005/04/11 09:01:18 $
++# Purpose:      The main driver source module
+ #
++#******************************************************************************
++
++#******************************************************************************
++#
++#     (C)Copyright 1998-2002 SysKonnect GmbH.
++#     (C)Copyright 2002-2005 Marvell.
++#
++#     Makefile for Marvell Yukon chipset and SysKonnect Gigabit Ethernet 
++#     Server Adapter driver. (Kernel 2.6)
++#
++#     Author: Mirko Lindner (mlindner@syskonnect.de)
++#             Ralph Roesler (rroesler@syskonnect.de)
++#
++#     Address all question to: linux@syskonnect.de
++#
++#     This program is free software; you can redistribute it and/or modify
++#     it under the terms of the GNU General Public License as published by
++#     the Free Software Foundation; either version 2 of the License, or
++#     (at your option) any later version.
++#
++#     The information in this file is provided "AS IS" without warranty.
++# 
++#******************************************************************************
++
++#******************************************************************************
++#
++# History:
++#
++#     $Log: Makefile2.6,v $
++#     Revision 1.9.2.1  2005/04/11 09:01:18  mlindner
++#     Fix: Copyright year changed
++#     
++#     Revision 1.9  2004/07/13 15:54:50  rroesler
++#     Add: file skethtool.c
++#     Fix: corrected header regarding copyright
++#     Fix: minor typos corrected
++#     
++#     Revision 1.8  2004/06/08 08:39:38  mlindner
++#     Fix: Add CONFIG_SK98LIN_ZEROCOPY as default
++#     
++#     Revision 1.7  2004/06/03 16:06:56  mlindner
++#     Fix: Added compile flag SK_DIAG_SUPPORT
++#     
++#     Revision 1.6  2004/06/02 08:02:59  mlindner
++#     Add: Changed header information and inserted a GPL statement
++#     
++#
++#******************************************************************************
+ #
+@@ -13,13 +66,16 @@
+ obj-$(CONFIG_SK98LIN) += sk98lin.o
+ sk98lin-objs    :=    \
+               skge.o          \
++              sky2.o          \
++              skethtool.o     \
++              sky2le.o        \
+               skdim.o         \
+               skaddr.o        \
+               skgehwt.o       \
+               skgeinit.o      \
+               skgepnmi.o      \
+               skgesirq.o      \
+-              ski2c.o         \
++              sktwsi.o                \
+               sklm80.o        \
+               skqueue.o       \
+               skrlmt.o        \
+@@ -76,13 +132,11 @@
+ # SK_DBGCAT_DRV_INT_SRC         0x04000000      interrupts sources
+ # SK_DBGCAT_DRV_EVENT           0x08000000      driver events
+-EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
++EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_USE_CSUM -DSK_DIAG_SUPPORT \
++              -DGENESIS -DYUKON -DYUK2 -DCONFIG_SK98LIN_ZEROCOPY \
++              $(DBGDEF) $(SKPARAM)
+ clean:
+       rm -f core *.o *.a *.s
+-
+-
+-
+-
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skaddr.c linux-2.6.9.new/drivers/net/sk98lin/skaddr.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skaddr.c       2004-10-19 05:54:32.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skaddr.c       2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skaddr.c
+  * Project:   Gigabit Ethernet Adapters, ADDR-Module
+- * Version:   $Revision: 1.52 $
+- * Date:      $Date: 2003/06/02 13:46:15 $
++ * Version:   $Revision: 2.6 $
++ * Date:      $Date: 2005/05/11 10:05:14 $
+  * Purpose:   Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
+  *
+  ******************************************************************************/
+@@ -44,7 +44,7 @@
+ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: skaddr.c,v 1.52 2003/06/02 13:46:15 tschilli Exp $ (C) Marvell.";
++      "@(#) $Id: skaddr.c,v 2.6 2005/05/11 10:05:14 tschilli Exp $ (C) Marvell.";
+ #endif /* DEBUG ||!LINT || !SK_SLIM */
+ #define __SKADDR_C
+@@ -191,11 +191,11 @@
+               pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] =
+                       pAC->Addr.Net[0].CurrentMacAddress;
+ #if SK_MAX_NETS > 1
+-              /* Set logical MAC address for net 2 to (log | 3). */
++              /* Set logical MAC address for net 2 to. */
+               if (!pAC->Addr.Net[1].CurrentMacAddressSet) {
+                       pAC->Addr.Net[1].PermanentMacAddress =
+                               pAC->Addr.Net[0].PermanentMacAddress;
+-                      pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3;
++                      pAC->Addr.Net[1].PermanentMacAddress.a[5] += 1;
+                       /* Set the current logical MAC address to the permanent one. */
+                       pAC->Addr.Net[1].CurrentMacAddress =
+                               pAC->Addr.Net[1].PermanentMacAddress;
+@@ -213,7 +213,7 @@
+                                       pAC->Addr.Net[i].PermanentMacAddress.a[2],
+                                       pAC->Addr.Net[i].PermanentMacAddress.a[3],
+                                       pAC->Addr.Net[i].PermanentMacAddress.a[4],
+-                                      pAC->Addr.Net[i].PermanentMacAddress.a[5]))
++                                      pAC->Addr.Net[i].PermanentMacAddress.a[5]));
+                       
+                       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
+                               ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
+@@ -223,7 +223,7 @@
+                                       pAC->Addr.Net[i].CurrentMacAddress.a[2],
+                                       pAC->Addr.Net[i].CurrentMacAddress.a[3],
+                                       pAC->Addr.Net[i].CurrentMacAddress.a[4],
+-                                      pAC->Addr.Net[i].CurrentMacAddress.a[5]))
++                                      pAC->Addr.Net[i].CurrentMacAddress.a[5]));
+               }
+ #endif        /* DEBUG */
+@@ -266,7 +266,7 @@
+                                       pAPort->PermanentMacAddress.a[2],
+                                       pAPort->PermanentMacAddress.a[3],
+                                       pAPort->PermanentMacAddress.a[4],
+-                                      pAPort->PermanentMacAddress.a[5]))
++                                      pAPort->PermanentMacAddress.a[5]));
+                       
+                       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
+                               ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
+@@ -275,7 +275,7 @@
+                                       pAPort->CurrentMacAddress.a[2],
+                                       pAPort->CurrentMacAddress.a[3],
+                                       pAPort->CurrentMacAddress.a[4],
+-                                      pAPort->CurrentMacAddress.a[5]))
++                                      pAPort->CurrentMacAddress.a[5]));
+ #endif /* DEBUG */
+               }
+               /* pAC->Addr.InitDone = SK_INIT_IO; */
+@@ -339,10 +339,14 @@
+       }
+       
+       if (pAC->GIni.GIGenesis) {
++#ifdef GENESIS
+               ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags);
++#endif
+       }
+       else {
++#ifdef YUKON
+               ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags);
++#endif
+       }
+       return (ReturnCode);
+@@ -352,7 +356,7 @@
+ #endif /* !SK_SLIM */
+ #ifndef SK_SLIM
+-
++#ifdef GENESIS
+ /******************************************************************************
+  *
+  *    SkAddrXmacMcClear - clear the multicast table
+@@ -404,11 +408,11 @@
+       return (SK_ADDR_SUCCESS);
+       
+ }     /* SkAddrXmacMcClear */
+-
++#endif        /* GENESIS */
+ #endif /* !SK_SLIM */
+ #ifndef SK_SLIM
+-
++#ifdef YUKON
+ /******************************************************************************
+  *
+  *    SkAddrGmacMcClear - clear the multicast table
+@@ -447,7 +451,7 @@
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
+-                      pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
++                      pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]));
+ #endif        /* DEBUG */
+       /* Clear InexactFilter */
+@@ -489,7 +493,7 @@
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
+                       pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
+-                      pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
++                      pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]));
+ #endif        /* DEBUG */
+       
+       if (!(Flags & SK_MC_SW_ONLY)) {
+@@ -499,9 +503,10 @@
+       return (SK_ADDR_SUCCESS);
+ }     /* SkAddrGmacMcClear */
++#endif        /* YUKON */
+ #ifndef SK_ADDR_CHEAT
+-
++#ifdef GENESIS
+ /******************************************************************************
+  *
+  *    SkXmacMcHash - hash multicast address
+@@ -538,8 +543,9 @@
+       return (Crc & ((1 << HASH_BITS) - 1));
+ }     /* SkXmacMcHash */
++#endif        /* GENESIS */
+-
++#ifdef YUKON
+ /******************************************************************************
+  *
+  *    SkGmacMcHash - hash multicast address
+@@ -597,7 +603,7 @@
+       return (Crc & ((1 << HASH_BITS) - 1));
+ }     /* SkGmacMcHash */
+-
++#endif        /* YUKON */
+ #endif        /* !SK_ADDR_CHEAT */
+ /******************************************************************************
+@@ -638,17 +644,21 @@
+       }
+       
+       if (pAC->GIni.GIGenesis) {
++#ifdef GENESIS
+               ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
++#endif
+       }
+       else {
++#ifdef YUKON
+               ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
++#endif
+       }
+       return (ReturnCode);
+ }     /* SkAddrMcAdd */
+-
++#ifdef GENESIS
+ /******************************************************************************
+  *
+  *    SkAddrXmacMcAdd - add a multicast address to a port
+@@ -758,8 +768,9 @@
+       }
+ }     /* SkAddrXmacMcAdd */
++#endif        /* GENESIS */
+-
++#ifdef YUKON
+ /******************************************************************************
+  *
+  *    SkAddrGmacMcAdd - add a multicast address to a port
+@@ -821,7 +832,7 @@
+                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4],
+                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5],
+                       pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6],
+-                      pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7]))
++                      pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7]));
+ #endif        /* DEBUG */
+       }
+       else {  /* not permanent => DRV */
+@@ -845,7 +856,7 @@
+                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4],
+                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5],
+                       pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6],
+-                      pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7]))
++                      pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7]));
+ #endif        /* DEBUG */
+       }
+       
+@@ -860,7 +871,7 @@
+       return (SK_MC_FILTERING_INEXACT);
+       
+ }     /* SkAddrGmacMcAdd */
+-
++#endif        /* YUKON */
+ #endif /* !SK_SLIM */
+ /******************************************************************************
+@@ -892,7 +903,7 @@
+ SK_IOC        IoC,            /* I/O context */
+ SK_U32        PortNumber)     /* Port Number */
+ {
+-      int ReturnCode = 0;
++      int ReturnCode = SK_ADDR_ILLEGAL_PORT;
+ #if (!defined(SK_SLIM) || defined(DEBUG))
+       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+               return (SK_ADDR_ILLEGAL_PORT);
+@@ -948,13 +959,13 @@
+       SK_ADDR_PORT    *pAPort;
+       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+-              ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber))
++              ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber));
+       
+       pAPort = &pAC->Addr.Port[PortNumber];
+ #ifdef DEBUG
+       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+-              ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
++              ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]));
+ #endif /* DEBUG */
+       /* Start with 0 to also program the logical MAC address. */
+@@ -1043,7 +1054,7 @@
+                               pAPort->Exact[i].a[2],
+                               pAPort->Exact[i].a[3],
+                               pAPort->Exact[i].a[4],
+-                              pAPort->Exact[i].a[5]))
++                              pAPort->Exact[i].a[5]));
+       }
+ #endif /* DEBUG */
+@@ -1095,13 +1106,13 @@
+       SK_ADDR_PORT    *pAPort;
+       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+-              ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber))
++              ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber));
+       
+       pAPort = &pAC->Addr.Port[PortNumber];
+ #ifdef DEBUG
+       SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+-              ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
++              ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]));
+ #endif /* DEBUG */
+       
+ #ifndef SK_SLIM
+@@ -1157,7 +1168,7 @@
+                       pAPort->Exact[0].a[2],
+                       pAPort->Exact[0].a[3],
+                       pAPort->Exact[0].a[4],
+-                      pAPort->Exact[0].a[5]))
++                      pAPort->Exact[0].a[5]));
+       
+       SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+               ("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
+@@ -1166,7 +1177,7 @@
+                       pAPort->CurrentMacAddress.a[2],
+                       pAPort->CurrentMacAddress.a[3],
+                       pAPort->CurrentMacAddress.a[4],
+-                      pAPort->CurrentMacAddress.a[5]))
++                      pAPort->CurrentMacAddress.a[5]));
+ #endif /* DEBUG */
+       
+ #ifndef SK_SLIM
+@@ -1275,26 +1286,42 @@
+               (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
+       }
+       else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) {    /* Physical MAC address. */
+-              if (SK_ADDR_EQUAL(pNewAddr->a,
+-                      pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
+-                      return (SK_ADDR_DUPLICATE_ADDRESS);
+-              }
+-
+               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
+                       if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
+                               return (SK_ADDR_TOO_EARLY);
+                       }
++              }
++              /*
++               * In dual net mode it should be possible to set all MAC
++               * addresses independently. Therefore the equality checks
++               * against the locical address of the same port and the
++               * physical address of the other port are suppressed here.
++               */
++              if (pAC->Rlmt.NumNets == 1) {
+                       if (SK_ADDR_EQUAL(pNewAddr->a,
+-                              pAC->Addr.Port[i].CurrentMacAddress.a)) {
+-                              if (i == PortNumber) {
+-                                      return (SK_ADDR_SUCCESS);
+-                              }
+-                              else {
+-                                      return (SK_ADDR_DUPLICATE_ADDRESS);
++                              pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
++                              return (SK_ADDR_DUPLICATE_ADDRESS);
++                      }
++
++                      for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
++                              if (SK_ADDR_EQUAL(pNewAddr->a,
++                                      pAC->Addr.Port[i].CurrentMacAddress.a)) {
++                                      if (i == PortNumber) {
++                                              return (SK_ADDR_SUCCESS);
++                                      }
++                                      else {
++                                              return (SK_ADDR_DUPLICATE_ADDRESS);
++                                      }
+                               }
+                       }
+               }
++              else {
++                      if (SK_ADDR_EQUAL(pNewAddr->a,
++                              pAC->Addr.Port[PortNumber].CurrentMacAddress.a)) {
++                              return (SK_ADDR_SUCCESS);
++                      }
++              }
+               pAC->Addr.Port[PortNumber].PreviousMacAddress =
+                       pAC->Addr.Port[PortNumber].CurrentMacAddress;
+@@ -1325,18 +1352,28 @@
+                       pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
+                       return (SK_ADDR_SUCCESS);
+               }
+-              
++
+               for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
+                       if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
+                               return (SK_ADDR_TOO_EARLY);
+                       }
++              }
+-                      if (SK_ADDR_EQUAL(pNewAddr->a,
+-                              pAC->Addr.Port[i].CurrentMacAddress.a)) {
+-                              return (SK_ADDR_DUPLICATE_ADDRESS);
++              /*
++               * In dual net mode on Yukon-2 adapters the physical address
++               * of port 0 and the logical address of port 1 are equal - in
++               * this case the equality check of the physical address leads
++               * to an error and is suppressed here.
++               */
++              if (pAC->Rlmt.NumNets == 1) {
++                      for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
++                              if (SK_ADDR_EQUAL(pNewAddr->a,
++                                      pAC->Addr.Port[i].CurrentMacAddress.a)) {
++                                      return (SK_ADDR_DUPLICATE_ADDRESS);
++                              }
+                       }
+               }
+-              
++
+               /*
+                * In case that the physical and the logical MAC addresses are equal
+                * we must also change the physical MAC address here.
+@@ -1424,7 +1461,7 @@
+ SK_U32        PortNumber,             /* port whose promiscuous mode changes */
+ int           NewPromMode)    /* new promiscuous mode */
+ {
+-      int ReturnCode = 0;
++      int ReturnCode = SK_ADDR_ILLEGAL_PORT;
+ #if (!defined(SK_SLIM) || defined(DEBUG))
+       if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+               return (SK_ADDR_ILLEGAL_PORT);
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skcsum.c linux-2.6.9.new/drivers/net/sk98lin/skcsum.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skcsum.c       2004-10-19 05:53:07.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skcsum.c       2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skcsum.c
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.12 $
+- * Date:      $Date: 2003/08/20 13:55:53 $
++ * Version:   $Revision: 2.1 $
++ * Date:      $Date: 2003/10/27 14:16:08 $
+  * Purpose:   Store/verify Internet checksum in send/receive packets.
+  *
+  ******************************************************************************/
+@@ -25,7 +25,7 @@
+ #ifndef lint
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: skcsum.c,v 1.12 2003/08/20 13:55:53 mschmid Exp $ (C) SysKonnect.";
++      "@(#) $Id: skcsum.c,v 2.1 2003/10/27 14:16:08 amock Exp $ (C) SysKonnect.";
+ #endif        /* !lint */
+ /******************************************************************************
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skdim.c linux-2.6.9.new/drivers/net/sk98lin/skdim.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skdim.c        2004-10-19 05:53:45.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skdim.c        2006-12-07 14:35:03.000000000 +0800
+@@ -1,17 +1,25 @@
+ /******************************************************************************
+  *
+- * Name:      skdim.c
+- * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.5 $
+- * Date:      $Date: 2003/11/28 12:55:40 $
+- * Purpose:   All functions to maintain interrupt moderation
++ * Name:        skdim.c
++ * Project:     GEnesis, PCI Gigabit Ethernet Adapter
++ * Version:     $Revision: 1.5.2.2 $
++ * Date:        $Date: 2005/05/23 13:47:33 $
++ * Purpose:     All functions regardig interrupt moderation
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect GmbH.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2005 Marvell.
++ *
++ *    Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet 
++ *      Server Adapters.
++ *
++ *    Author: Ralph Roesler (rroesler@syskonnect.de)
++ *            Mirko Lindner (mlindner@syskonnect.de)
++ *
++ *    Address all question to: linux@syskonnect.de
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+@@ -20,723 +28,367 @@
+  *
+  *    The information in this file is provided "AS IS" without warranty.
+  *
+- ******************************************************************************/
++ *****************************************************************************/
+-/******************************************************************************
+- *
+- * Description:
+- *
+- * This module is intended to manage the dynamic interrupt moderation on both   
+- * GEnesis and Yukon adapters.
+- *
+- * Include File Hierarchy:
+- *
+- *    "skdrv1st.h"
+- *    "skdrv2nd.h"
+- *
+- ******************************************************************************/
+-
+-#ifndef       lint
+-static const char SysKonnectFileId[] =
+-      "@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect.";
+-#endif
+-
+-#define __SKADDR_C
+-
+-#ifdef __cplusplus
+-#error C++ is not yet supported.
+-extern "C" {
+-#endif
+-
+-/*******************************************************************************
+-**
+-** Includes
+-**
+-*******************************************************************************/
+-
+-#ifndef __INC_SKDRV1ST_H
+ #include "h/skdrv1st.h"
+-#endif
+-
+-#ifndef __INC_SKDRV2ND_H
+ #include "h/skdrv2nd.h"
+-#endif
+-#include      <linux/kernel_stat.h>
+-
+-/*******************************************************************************
+-**
+-** Defines
+-**
+-*******************************************************************************/
+-
+-/*******************************************************************************
+-**
+-** Typedefs
+-**
+-*******************************************************************************/
++/******************************************************************************
++ *
++ * Local Function Prototypes
++ *
++ *****************************************************************************/
+-/*******************************************************************************
+-**
+-** Local function prototypes 
+-**
+-*******************************************************************************/
+-
+-static unsigned int GetCurrentSystemLoad(SK_AC *pAC);
+-static SK_U64       GetIsrCalls(SK_AC *pAC);
+-static SK_BOOL      IsIntModEnabled(SK_AC *pAC);
+-static void         SetCurrIntCtr(SK_AC *pAC);
+-static void         EnableIntMod(SK_AC *pAC); 
+-static void         DisableIntMod(SK_AC *pAC);
+-static void         ResizeDimTimerDuration(SK_AC *pAC);
+-static void         DisplaySelectedModerationType(SK_AC *pAC);
+-static void         DisplaySelectedModerationMask(SK_AC *pAC);
+-static void         DisplayDescrRatio(SK_AC *pAC);
++static SK_U64 getIsrCalls(SK_AC *pAC);
++static SK_BOOL isIntModEnabled(SK_AC *pAC);
++static void setCurrIntCtr(SK_AC *pAC);
++static void enableIntMod(SK_AC *pAC); 
++static void disableIntMod(SK_AC *pAC);
+-/*******************************************************************************
+-**
+-** Global variables
+-**
+-*******************************************************************************/
++#define M_DIMINFO pAC->DynIrqModInfo
+-/*******************************************************************************
+-**
+-** Local variables
+-**
+-*******************************************************************************/
++/******************************************************************************
++ *
++ * Global Functions
++ *
++ *****************************************************************************/
+-/*******************************************************************************
+-**
+-** Global functions 
+-**
+-*******************************************************************************/
++/*****************************************************************************
++ *
++ *    SkDimModerate - Moderates the IRQs depending on the current needs
++ *
++ * Description:
++ *    Moderation of IRQs depends on the number of occurred IRQs with 
++ *    respect to the previous moderation cycle.
++ *
++ * Returns:   N/A
++ *
++ */
++void SkDimModerate(
++SK_AC *pAC)  /* pointer to adapter control context */
++{
++      SK_U64  IsrCalls = getIsrCalls(pAC);
++
++      SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==> SkDimModerate\n"));
++
++      if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
++              if (isIntModEnabled(pAC)) {
++                      if (IsrCalls < M_DIMINFO.MaxModIntsPerSecLowerLimit) {
++                              disableIntMod(pAC);
++                      }
++              } else {
++                      if (IsrCalls > M_DIMINFO.MaxModIntsPerSecUpperLimit) {
++                              enableIntMod(pAC);
++                      }
++              }
++      }
++      setCurrIntCtr(pAC);
+-/*******************************************************************************
+-** Function     : SkDimModerate
+-** Description  : Called in every ISR to check if moderation is to be applied
+-**                or not for the current number of interrupts
+-** Programmer   : Ralph Roesler
+-** Last Modified: 22-mar-03
+-** Returns      : void (!)
+-** Notes        : -
+-*******************************************************************************/
+-
+-void 
+-SkDimModerate(SK_AC *pAC) {
+-    unsigned int CurrSysLoad    = 0;  /* expressed in percent */
+-    unsigned int LoadIncrease   = 0;  /* expressed in percent */
+-    SK_U64       ThresholdInts  = 0;
+-    SK_U64       IsrCallsPerSec = 0;
++      SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("<== SkDimModerate\n"));
++}
+-#define M_DIMINFO pAC->DynIrqModInfo
++/*****************************************************************************
++ *
++ *    SkDimStartModerationTimer - Starts the moderation timer
++ *
++ * Description:
++ *    Dynamic interrupt moderation is regularly checked using the
++ *    so-called moderation timer. This timer is started with this function.
++ *
++ * Returns:   N/A
++ */
++void SkDimStartModerationTimer(
++SK_AC *pAC) /* pointer to adapter control context */
++{
++      SK_EVPARA   EventParam;   /* Event struct for timer event */
++ 
++      SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
++                      ("==> SkDimStartModerationTimer\n"));
+-    if (!IsIntModEnabled(pAC)) {
+-        if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+-            CurrSysLoad = GetCurrentSystemLoad(pAC);
+-            if (CurrSysLoad > 75) {
+-                    /* 
+-                    ** More than 75% total system load! Enable the moderation 
+-                    ** to shield the system against too many interrupts.
+-                    */
+-                    EnableIntMod(pAC);
+-            } else if (CurrSysLoad > M_DIMINFO.PrevSysLoad) {
+-                LoadIncrease = (CurrSysLoad - M_DIMINFO.PrevSysLoad);
+-                if (LoadIncrease > ((M_DIMINFO.PrevSysLoad *
+-                                         C_INT_MOD_ENABLE_PERCENTAGE) / 100)) {
+-                    if (CurrSysLoad > 10) {
+-                        /* 
+-                        ** More than 50% increase with respect to the 
+-                        ** previous load of the system. Most likely this 
+-                        ** is due to our ISR-proc...
+-                        */
+-                        EnableIntMod(pAC);
+-                    }
+-                }
+-            } else {
+-                /*
+-                ** Neither too much system load at all nor too much increase
+-                ** with respect to the previous system load. Hence, we can leave
+-                ** the ISR-handling like it is without enabling moderation.
+-                */
+-            }
+-            M_DIMINFO.PrevSysLoad = CurrSysLoad;
+-        }   
+-    } else {
+-        if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+-            ThresholdInts  = ((M_DIMINFO.MaxModIntsPerSec *
+-                                   C_INT_MOD_DISABLE_PERCENTAGE) / 100);
+-            IsrCallsPerSec = GetIsrCalls(pAC);
+-            if (IsrCallsPerSec <= ThresholdInts) {
+-                /* 
+-                ** The number of interrupts within the last second is 
+-                ** lower than the disable_percentage of the desried 
+-                ** maxrate. Therefore we can disable the moderation.
+-                */
+-                DisableIntMod(pAC);
+-                M_DIMINFO.MaxModIntsPerSec = 
+-                   (M_DIMINFO.MaxModIntsPerSecUpperLimit +
+-                    M_DIMINFO.MaxModIntsPerSecLowerLimit) / 2;
+-            } else {
+-                /*
+-                ** The number of interrupts per sec is the same as expected.
+-                ** Evalulate the descriptor-ratio. If it has changed, a resize 
+-                ** in the moderation timer might be usefull
+-                */
+-                if (M_DIMINFO.AutoSizing) {
+-                    ResizeDimTimerDuration(pAC);
+-                }
+-            }
+-        }
+-    }
+-
+-    /*
+-    ** Some information to the log...
+-    */
+-    if (M_DIMINFO.DisplayStats) {
+-        DisplaySelectedModerationType(pAC);
+-        DisplaySelectedModerationMask(pAC);
+-        DisplayDescrRatio(pAC);
+-    }
++      if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
++              SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
++              EventParam.Para32[0] = SK_DRV_MODERATION_TIMER;
++              SkTimerStart(pAC, pAC->IoBase,
++                      &pAC->DynIrqModInfo.ModTimer,
++                      pAC->DynIrqModInfo.DynIrqModSampleInterval * 1000000,
++                      SKGE_DRV, SK_DRV_TIMER, EventParam);
++      }
+-    M_DIMINFO.NbrProcessedDescr = 0; 
+-    SetCurrIntCtr(pAC);
++      SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
++                      ("<== SkDimStartModerationTimer\n"));
+ }
+-/*******************************************************************************
+-** Function     : SkDimStartModerationTimer
+-** Description  : Starts the audit-timer for the dynamic interrupt moderation
+-** Programmer   : Ralph Roesler
+-** Last Modified: 22-mar-03
+-** Returns      : void (!)
+-** Notes        : -
+-*******************************************************************************/
+-
+-void 
+-SkDimStartModerationTimer(SK_AC *pAC) {
+-    SK_EVPARA    EventParam;   /* Event struct for timer event */
+- 
+-    SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
+-    EventParam.Para32[0] = SK_DRV_MODERATION_TIMER;
+-    SkTimerStart(pAC, pAC->IoBase, &pAC->DynIrqModInfo.ModTimer,
+-                 SK_DRV_MODERATION_TIMER_LENGTH,
+-                 SKGE_DRV, SK_DRV_TIMER, EventParam);
+-}
++/*****************************************************************************
++ *
++ *    SkDimEnableModerationIfNeeded - Enables or disables any moderationtype
++ *
++ * Description:
++ *    This function effectively initializes the IRQ moderation of a network
++ *    adapter. Depending on the configuration, this might be either static
++ *    or dynamic. If no moderation is configured, this function will do
++ *    nothing.
++ *
++ * Returns:   N/A
++ */
++void SkDimEnableModerationIfNeeded(
++SK_AC *pAC)  /* pointer to adapter control context */
++{
++      SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
++                      ("==> SkDimEnableModerationIfNeeded\n"));
++
++      if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_NONE) {
++              if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) {
++                      enableIntMod(pAC);   
++              } else { /* must be C_INT_MOD_DYNAMIC */
++                      SkDimStartModerationTimer(pAC);
++              }
++      }
+-/*******************************************************************************
+-** Function     : SkDimEnableModerationIfNeeded
+-** Description  : Either enables or disables moderation
+-** Programmer   : Ralph Roesler
+-** Last Modified: 22-mar-03
+-** Returns      : void (!)
+-** Notes        : This function is called when a particular adapter is opened
+-**                There is no Disable function, because when all interrupts 
+-**                might be disable, the moderation timer has no meaning at all
+-******************************************************************************/
+-
+-void
+-SkDimEnableModerationIfNeeded(SK_AC *pAC) {
+-
+-    if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) {
+-        EnableIntMod(pAC);   /* notification print in this function */
+-    } else if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+-        SkDimStartModerationTimer(pAC);
+-        if (M_DIMINFO.DisplayStats) {
+-            printk("Dynamic moderation has been enabled\n");
+-        }
+-    } else {
+-        if (M_DIMINFO.DisplayStats) {
+-            printk("No moderation has been enabled\n");
+-        }
+-    }
++      SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
++                      ("<== SkDimEnableModerationIfNeeded\n"));
+ }
+-/*******************************************************************************
+-** Function     : SkDimDisplayModerationSettings
+-** Description  : Displays the current settings regaring interrupt moderation
+-** Programmer   : Ralph Roesler
+-** Last Modified: 22-mar-03
+-** Returns      : void (!)
+-** Notes        : -
+-*******************************************************************************/
+-
+-void 
+-SkDimDisplayModerationSettings(SK_AC *pAC) {
+-    DisplaySelectedModerationType(pAC);
+-    DisplaySelectedModerationMask(pAC);
+-}
++/*****************************************************************************
++ *
++ *    SkDimDisableModeration - disables moderation if it is enabled
++ *
++ * Description:
++ *    Disabling of the moderation requires that is enabled already.
++ *
++ * Returns:   N/A
++ */
++void SkDimDisableModeration(
++SK_AC  *pAC,                /* pointer to adapter control context */
++int     CurrentModeration)  /* type of current moderation         */
++{
++      SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
++                      ("==> SkDimDisableModeration\n"));
++
++      if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_NONE) {
++              if (CurrentModeration == C_INT_MOD_STATIC) {
++                      disableIntMod(pAC);
++              } else { /* must be C_INT_MOD_DYNAMIC */
++                      SkTimerStop(pAC, pAC->IoBase, &M_DIMINFO.ModTimer);
++                      disableIntMod(pAC);
++              }
++      }
+-/*******************************************************************************
+-**
+-** Local functions 
+-**
+-*******************************************************************************/
++      SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
++                      ("<== SkDimDisableModeration\n"));
++}
+-/*******************************************************************************
+-** Function     : GetCurrentSystemLoad
+-** Description  : Retrieves the current system load of the system. This load
+-**                is evaluated for all processors within the system.
+-** Programmer   : Ralph Roesler
+-** Last Modified: 22-mar-03
+-** Returns      : unsigned int: load expressed in percentage
+-** Notes        : The possible range being returned is from 0 up to 100.
+-**                Whereas 0 means 'no load at all' and 100 'system fully loaded'
+-**                It is impossible to determine what actually causes the system
+-**                to be in 100%, but maybe that is due to too much interrupts.
+-*******************************************************************************/
+-
+-static unsigned int
+-GetCurrentSystemLoad(SK_AC *pAC) {
+-      unsigned long jif         = jiffies;
+-      unsigned int  UserTime    = 0;
+-      unsigned int  SystemTime  = 0;
+-      unsigned int  NiceTime    = 0;
+-      unsigned int  IdleTime    = 0;
+-      unsigned int  TotalTime   = 0;
+-      unsigned int  UsedTime    = 0;
+-      unsigned int  SystemLoad  = 0;
++/******************************************************************************
++ *
++ * Local Functions
++ *
++ *****************************************************************************/
+-      /* unsigned int  NbrCpu      = 0; */
++/*****************************************************************************
++ *
++ *    getIsrCalls - evaluate the number of IRQs handled in mod interval
++ *
++ * Description:
++ *    Depending on the selected moderation mask, this function will return
++ *    the number of interrupts handled in the previous moderation interval.
++ *    This evaluated number is based on the current number of interrupts
++ *    stored in PNMI-context and the previous stored interrupts.
++ *
++ * Returns:
++ *    the number of IRQs handled
++ */
++static SK_U64 getIsrCalls(
++SK_AC *pAC)  /* pointer to adapter control context */
++{
++      SK_U64   RxPort0IntDiff = 0, RxPort1IntDiff = 0;
++      SK_U64   TxPort0IntDiff = 0, TxPort1IntDiff = 0;
++      SK_U64   StatusPort0IntDiff = 0, StatusPort1IntDiff = 0;
++
++        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==>getIsrCalls\n"));
++
++      if (!CHIP_ID_YUKON_2(pAC)) {
++              if ((M_DIMINFO.MaskIrqModeration == IRQ_MASK_TX_ONLY) ||
++                  (M_DIMINFO.MaskIrqModeration == IRQ_MASK_SP_TX)) {
++                      if (pAC->GIni.GIMacsFound == 2) {
++                              TxPort1IntDiff = 
++                                      pAC->Pnmi.Port[1].TxIntrCts - 
++                                      M_DIMINFO.PrevPort1TxIntrCts;
++                      }
++                      TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - 
++                                      M_DIMINFO.PrevPort0TxIntrCts;
++              } else if ((M_DIMINFO.MaskIrqModeration == IRQ_MASK_RX_ONLY) ||
++                         (M_DIMINFO.MaskIrqModeration == IRQ_MASK_SP_RX)) {
++                      if (pAC->GIni.GIMacsFound == 2) {
++                              RxPort1IntDiff =
++                                      pAC->Pnmi.Port[1].RxIntrCts - 
++                                      M_DIMINFO.PrevPort1RxIntrCts;
++                      }
++                      RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
++                                      M_DIMINFO.PrevPort0RxIntrCts;
++              } else {
++                      if (pAC->GIni.GIMacsFound == 2) {
++                              RxPort1IntDiff = 
++                                      pAC->Pnmi.Port[1].RxIntrCts - 
++                                      M_DIMINFO.PrevPort1RxIntrCts;
++                              TxPort1IntDiff =
++                                      pAC->Pnmi.Port[1].TxIntrCts - 
++                                      M_DIMINFO.PrevPort1TxIntrCts;
++                      } 
++                      RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
++                                      M_DIMINFO.PrevPort0RxIntrCts;
++                      TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - 
++                                      M_DIMINFO.PrevPort0TxIntrCts;
++              }
++              SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
++                              ("==>getIsrCalls (!CHIP_ID_YUKON_2)\n"));
++              return (RxPort0IntDiff + RxPort1IntDiff + 
++                      TxPort0IntDiff + TxPort1IntDiff);
++      }
+       /*
+-      ** The following lines have been commented out, because
+-      ** from kernel 2.5.44 onwards, the kernel-owned structure
+-      **
+-      **      struct kernel_stat kstat
+-      **
+-      ** is not marked as an exported symbol in the file
++      ** We have a Yukon2 compliant chipset if we come up to here
+       **
+-      **      kernel/ksyms.c 
+-      **
+-      ** As a consequence, using this driver as KLM is not possible
+-      ** and any access of the structure kernel_stat via the 
+-      ** dedicated macros kstat_cpu(i).cpustat.xxx is to be avoided.
+-      **
+-      ** The kstat-information might be added again in future 
+-      ** versions of the 2.5.xx kernel, but for the time being, 
+-      ** number of interrupts will serve as indication how much 
+-      ** load we currently have... 
+-      **
+-      ** for (NbrCpu = 0; NbrCpu < num_online_cpus(); NbrCpu++) {
+-      **      UserTime   = UserTime   + kstat_cpu(NbrCpu).cpustat.user;
+-      **      NiceTime   = NiceTime   + kstat_cpu(NbrCpu).cpustat.nice;
+-      **      SystemTime = SystemTime + kstat_cpu(NbrCpu).cpustat.system;
+-      ** }
++      if (pAC->GIni.GIMacsFound == 2) {
++              StatusPort1IntDiff = pAC->Pnmi.Port[1].StatusLeIntrCts - 
++                                      M_DIMINFO.PrevPort1StatusIntrCts;
++      }
++      StatusPort0IntDiff = pAC->Pnmi.Port[0].StatusLeIntrCts - 
++                              M_DIMINFO.PrevPort0StatusIntrCts;
+       */
+-      SK_U64 ThresholdInts  = 0;
+-      SK_U64 IsrCallsPerSec = 0;
+-
+-      ThresholdInts  = ((M_DIMINFO.MaxModIntsPerSec *
+-                         C_INT_MOD_ENABLE_PERCENTAGE) + 100);
+-      IsrCallsPerSec = GetIsrCalls(pAC);
+-      if (IsrCallsPerSec >= ThresholdInts) {
+-          /*
+-          ** We do not know how much the real CPU-load is!
+-          ** Return 80% as a default in order to activate DIM
+-          */
+-          SystemLoad = 80;
+-          return (SystemLoad);  
+-      } 
+-
+-      UsedTime  = UserTime + NiceTime + SystemTime;
+-
+-      IdleTime  = jif * num_online_cpus() - UsedTime;
+-      TotalTime = UsedTime + IdleTime;
+-
+-      SystemLoad = ( 100 * (UsedTime  - M_DIMINFO.PrevUsedTime) ) /
+-                                              (TotalTime - M_DIMINFO.PrevTotalTime);
++        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
++                      ("==>getIsrCalls (CHIP_ID_YUKON_2)\n"));
++      return (StatusPort0IntDiff + StatusPort1IntDiff);
++}
+-      if (M_DIMINFO.DisplayStats) {
+-              printk("Current system load is: %u\n", SystemLoad);
++/*****************************************************************************
++ *
++ *    setCurrIntCtr - stores the current number of interrupts
++ *
++ * Description:
++ *    Stores the current number of occurred interrupts in the adapter
++ *    context. This is needed to evaluate the  umber of interrupts within
++ *    the moderation interval.
++ *
++ * Returns:   N/A
++ *
++ */
++static void setCurrIntCtr(
++SK_AC *pAC)  /* pointer to adapter control context */
++{
++        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==>setCurrIntCtr\n"));
++
++      if (!CHIP_ID_YUKON_2(pAC)) {
++              if (pAC->GIni.GIMacsFound == 2) {
++                      M_DIMINFO.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts;
++                      M_DIMINFO.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts;
++              } 
++              M_DIMINFO.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts;
++              M_DIMINFO.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts;
++              SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
++                              ("<== setCurrIntCtr (!CHIP_ID_YUKON_2)\n"));
++              return;
+       }
+-      M_DIMINFO.PrevTotalTime = TotalTime;
+-      M_DIMINFO.PrevUsedTime  = UsedTime;
+-
+-      return (SystemLoad);
++      /*
++      ** We have a Yukon2 compliant chipset if we come up to here
++      **
++      if (pAC->GIni.GIMacsFound == 2) {
++              M_DIMINFO.PrevPort1StatusIntrCts = pAC->Pnmi.Port[1].StatusLeIntrCts;
++      } 
++      M_DIMINFO.PrevPort0StatusIntrCts = pAC->Pnmi.Port[0].StatusLeIntrCts;
++      */
++        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
++                      ("<== setCurrIntCtr (CHIP_ID_YUKON_2)\n"));
+ }
+-/*******************************************************************************
+-** Function     : GetIsrCalls
+-** Description  : Depending on the selected moderation mask, this function will
+-**                return the number of interrupts handled in the previous time-
+-**                frame. This evaluated number is based on the current number 
+-**                of interrupts stored in PNMI-context and the previous stored 
+-**                interrupts.
+-** Programmer   : Ralph Roesler
+-** Last Modified: 23-mar-03
+-** Returns      : int:   the number of interrupts being executed in the last
+-**                       timeframe
+-** Notes        : It makes only sense to call this function, when dynamic 
+-**                interrupt moderation is applied
+-*******************************************************************************/
+-
+-static SK_U64
+-GetIsrCalls(SK_AC *pAC) {
+-    SK_U64   RxPort0IntDiff = 0;
+-    SK_U64   RxPort1IntDiff = 0;
+-    SK_U64   TxPort0IntDiff = 0;
+-    SK_U64   TxPort1IntDiff = 0;
+-
+-    if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_TX_ONLY) {
+-        if (pAC->GIni.GIMacsFound == 2) {
+-            TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts - 
+-                             pAC->DynIrqModInfo.PrevPort1TxIntrCts;
+-        }
+-        TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - 
+-                         pAC->DynIrqModInfo.PrevPort0TxIntrCts;
+-    } else if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_RX_ONLY) {
+-        if (pAC->GIni.GIMacsFound == 2) {
+-            RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - 
+-                             pAC->DynIrqModInfo.PrevPort1RxIntrCts;
+-        }
+-        RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
+-                         pAC->DynIrqModInfo.PrevPort0RxIntrCts;
+-    } else {
+-        if (pAC->GIni.GIMacsFound == 2) {
+-            RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - 
+-                             pAC->DynIrqModInfo.PrevPort1RxIntrCts;
+-            TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts - 
+-                             pAC->DynIrqModInfo.PrevPort1TxIntrCts;
+-        } 
+-        RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
+-                         pAC->DynIrqModInfo.PrevPort0RxIntrCts;
+-        TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - 
+-                         pAC->DynIrqModInfo.PrevPort0TxIntrCts;
+-    }
+-
+-    return (RxPort0IntDiff + RxPort1IntDiff + TxPort0IntDiff + TxPort1IntDiff);
++/*****************************************************************************
++ *
++ *    isIntModEnabled - returns the current state of interrupt moderation
++ *
++ * Description:
++ *    This function retrieves the current value of the interrupt moderation
++ *    command register. Its content determines whether any moderation is 
++ *    running or not.
++ *
++ * Returns:
++ *    SK_TRUE : IRQ moderation is currently active
++ *    SK_FALSE: No IRQ moderation is active
++ */
++static SK_BOOL isIntModEnabled(
++SK_AC *pAC)  /* pointer to adapter control context */
++{
++      unsigned long CtrCmd;
++
++        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==>isIntModEnabled\n"));
++
++      SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd);
++      if ((CtrCmd & TIM_START) == TIM_START) {
++              SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
++                      ("<== isIntModEnabled (SK_TRUE)\n"));
++              return SK_TRUE;
++      }
++        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,
++                      ("<== isIntModEnabled (SK_FALSE)\n"));
++      return SK_FALSE;
+ }
+-/*******************************************************************************
+-** Function     : GetRxCalls
+-** Description  : This function will return the number of times a receive inter-
+-**                rupt was processed. This is needed to evaluate any resizing 
+-**                factor.
+-** Programmer   : Ralph Roesler
+-** Last Modified: 23-mar-03
+-** Returns      : SK_U64: the number of RX-ints being processed
+-** Notes        : It makes only sense to call this function, when dynamic 
+-**                interrupt moderation is applied
+-*******************************************************************************/
+-
+-static SK_U64
+-GetRxCalls(SK_AC *pAC) {
+-    SK_U64   RxPort0IntDiff = 0;
+-    SK_U64   RxPort1IntDiff = 0;
+-
+-    if (pAC->GIni.GIMacsFound == 2) {
+-        RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - 
+-                         pAC->DynIrqModInfo.PrevPort1RxIntrCts;
+-    }
+-    RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - 
+-                     pAC->DynIrqModInfo.PrevPort0RxIntrCts;
+-
+-    return (RxPort0IntDiff + RxPort1IntDiff);
+-}
++/*****************************************************************************
++ *
++ *    enableIntMod - enables the interrupt moderation
++ *
++ * Description:
++ *    Enabling the interrupt moderation is done by putting the desired
++ *    moderation interval in the B2_IRQM_INI register, specifying the
++ *    desired maks in the B2_IRQM_MSK register and finally starting the
++ *    IRQ moderation timer using the B2_IRQM_CTRL register.
++ *
++ * Returns:   N/A
++ *
++ */
++static void enableIntMod(
++SK_AC *pAC)  /* pointer to adapter control context */
++{
++      unsigned long ModBase;
++
++        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==> enableIntMod\n"));
++
++      if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
++              ModBase = C_CLK_FREQ_GENESIS / M_DIMINFO.MaxModIntsPerSec;
++      } else if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) {
++              ModBase = C_CLK_FREQ_YUKON_EC / M_DIMINFO.MaxModIntsPerSec;
++      } else {
++              ModBase = C_CLK_FREQ_YUKON / M_DIMINFO.MaxModIntsPerSec;
++      }
+-/*******************************************************************************
+-** Function     : SetCurrIntCtr
+-** Description  : Will store the current number orf occured interrupts in the 
+-**                adapter context. This is needed to evaluated the number of 
+-**                interrupts within a current timeframe.
+-** Programmer   : Ralph Roesler
+-** Last Modified: 23-mar-03
+-** Returns      : void (!)
+-** Notes        : -
+-*******************************************************************************/
+-
+-static void
+-SetCurrIntCtr(SK_AC *pAC) {
+-    if (pAC->GIni.GIMacsFound == 2) {
+-        pAC->DynIrqModInfo.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts;
+-        pAC->DynIrqModInfo.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts;
+-    } 
+-    pAC->DynIrqModInfo.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts;
+-    pAC->DynIrqModInfo.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts;
+-}
++      SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
++      SK_OUT32(pAC->IoBase, B2_IRQM_MSK, M_DIMINFO.MaskIrqModeration);
++      SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
+-/*******************************************************************************
+-** Function     : IsIntModEnabled()
+-** Description  : Retrieves the current value of the interrupts moderation
+-**                command register. Its content determines whether any 
+-**                moderation is running or not.
+-** Programmer   : Ralph Roesler
+-** Last Modified: 23-mar-03
+-** Returns      : SK_TRUE  : if mod timer running
+-**                SK_FALSE : if no moderation is being performed
+-** Notes        : -
+-*******************************************************************************/
+-
+-static SK_BOOL
+-IsIntModEnabled(SK_AC *pAC) {
+-    unsigned long CtrCmd;
+-
+-    SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd);
+-    if ((CtrCmd & TIM_START) == TIM_START) {
+-       return SK_TRUE;
+-    } else {
+-       return SK_FALSE;
+-    }
++        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("<== enableIntMod\n"));
+ }
+-/*******************************************************************************
+-** Function     : EnableIntMod()
+-** Description  : Enables the interrupt moderation using the values stored in
+-**                in the pAC->DynIntMod data structure
+-** Programmer   : Ralph Roesler
+-** Last Modified: 22-mar-03
+-** Returns      : -
+-** Notes        : -
+-*******************************************************************************/
+-
+-static void
+-EnableIntMod(SK_AC *pAC) {
+-    unsigned long ModBase;
+-
+-    if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+-       ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
+-    } else {
+-       ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
+-    }
+-
+-    SK_OUT32(pAC->IoBase, B2_IRQM_INI,  ModBase);
+-    SK_OUT32(pAC->IoBase, B2_IRQM_MSK,  pAC->DynIrqModInfo.MaskIrqModeration);
+-    SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
+-    if (M_DIMINFO.DisplayStats) {
+-        printk("Enabled interrupt moderation (%i ints/sec)\n",
+-               M_DIMINFO.MaxModIntsPerSec);
+-    }
+-}
++/*****************************************************************************
++ *
++ *    disableIntMod - disables the interrupt moderation
++ *
++ * Description:
++ *    Disabling the interrupt moderation is done by stopping the
++ *    IRQ moderation timer using the B2_IRQM_CTRL register.
++ *
++ * Returns:   N/A
++ *
++ */
++static void disableIntMod(
++SK_AC *pAC)  /* pointer to adapter control context */
++{
++        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==> disableIntMod\n"));
+-/*******************************************************************************
+-** Function     : DisableIntMod()
+-** Description  : Disbles the interrupt moderation independent of what inter-
+-**                rupts are running or not
+-** Programmer   : Ralph Roesler
+-** Last Modified: 23-mar-03
+-** Returns      : -
+-** Notes        : -
+-*******************************************************************************/
+-
+-static void 
+-DisableIntMod(SK_AC *pAC) {
+-
+-    SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP);
+-    if (M_DIMINFO.DisplayStats) {
+-        printk("Disabled interrupt moderation\n");
+-    }
+-} 
++      SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP);
+-/*******************************************************************************
+-** Function     : ResizeDimTimerDuration();
+-** Description  : Checks the current used descriptor ratio and resizes the 
+-**                duration timer (longer/smaller) if possible. 
+-** Programmer   : Ralph Roesler
+-** Last Modified: 23-mar-03
+-** Returns      : -
+-** Notes        : There are both maximum and minimum timer duration value. 
+-**                This function assumes that interrupt moderation is already
+-**                enabled!
+-*******************************************************************************/
+-
+-static void 
+-ResizeDimTimerDuration(SK_AC *pAC) {
+-    SK_BOOL IncreaseTimerDuration;
+-    int     TotalMaxNbrDescr;
+-    int     UsedDescrRatio;
+-    int     RatioDiffAbs;
+-    int     RatioDiffRel;
+-    int     NewMaxModIntsPerSec;
+-    int     ModAdjValue;
+-    long    ModBase;
+-
+-    /*
+-    ** Check first if we are allowed to perform any modification
+-    */
+-    if (IsIntModEnabled(pAC)) { 
+-        if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_DYNAMIC) {
+-            return; 
+-        } else {
+-            if (M_DIMINFO.ModJustEnabled) {
+-                M_DIMINFO.ModJustEnabled = SK_FALSE;
+-                return;
+-            }
+-        }
+-    }
+-
+-    /*
+-    ** If we got until here, we have to evaluate the amount of the
+-    ** descriptor ratio change...
+-    */
+-    TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
+-    UsedDescrRatio   = (M_DIMINFO.NbrProcessedDescr * 100) / TotalMaxNbrDescr;
+-
+-    if (UsedDescrRatio > M_DIMINFO.PrevUsedDescrRatio) {
+-        RatioDiffAbs = (UsedDescrRatio - M_DIMINFO.PrevUsedDescrRatio);
+-        RatioDiffRel = (RatioDiffAbs * 100) / UsedDescrRatio;
+-        M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
+-        IncreaseTimerDuration = SK_FALSE;  /* in other words: DECREASE */
+-    } else if (UsedDescrRatio < M_DIMINFO.PrevUsedDescrRatio) {
+-        RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
+-        RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
+-        M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
+-        IncreaseTimerDuration = SK_TRUE;   /* in other words: INCREASE */
+-    } else {
+-        RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
+-        RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
+-        M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
+-        IncreaseTimerDuration = SK_TRUE;   /* in other words: INCREASE */
+-    }
+-
+-    /*
+-    ** Now we can determine the change in percent
+-    */
+-    if ((RatioDiffRel >= 0) && (RatioDiffRel <= 5) ) {
+-       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
+-    } else if ((RatioDiffRel > 5) && (RatioDiffRel <= 10) ) {
+-       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
+-    } else if ((RatioDiffRel > 10) && (RatioDiffRel <= 15) ) {
+-       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
+-    } else {
+-       ModAdjValue = 1;  /*  1% change - maybe some other value in future */
+-    }
+-
+-    if (IncreaseTimerDuration) {
+-       NewMaxModIntsPerSec =  M_DIMINFO.MaxModIntsPerSec +
+-                             (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
+-    } else {
+-       NewMaxModIntsPerSec =  M_DIMINFO.MaxModIntsPerSec -
+-                             (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
+-    }
+-
+-    /* 
+-    ** Check if we exceed boundaries...
+-    */
+-    if ( (NewMaxModIntsPerSec > M_DIMINFO.MaxModIntsPerSecUpperLimit) ||
+-         (NewMaxModIntsPerSec < M_DIMINFO.MaxModIntsPerSecLowerLimit)) {
+-        if (M_DIMINFO.DisplayStats) {
+-            printk("Cannot change ModTim from %i to %i ints/sec\n",
+-                   M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
+-        }
+-        return;
+-    } else {
+-        if (M_DIMINFO.DisplayStats) {
+-            printk("Resized ModTim from %i to %i ints/sec\n",
+-                   M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
+-        }
+-    }
+-
+-    M_DIMINFO.MaxModIntsPerSec = NewMaxModIntsPerSec;
+-
+-    if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+-        ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
+-    } else {
+-        ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
+-    }
+-
+-    /* 
+-    ** We do not need to touch any other registers
+-    */
+-    SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
++        SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("<== disableIntMod\n"));
+ } 
+ /*******************************************************************************
+-** Function     : DisplaySelectedModerationType()
+-** Description  : Displays what type of moderation we have
+-** Programmer   : Ralph Roesler
+-** Last Modified: 23-mar-03
+-** Returns      : void!
+-** Notes        : -
+-*******************************************************************************/
+-
+-static void
+-DisplaySelectedModerationType(SK_AC *pAC) {
+-
+-    if (pAC->DynIrqModInfo.DisplayStats) {
+-        if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) {
+-             printk("Static int moderation runs with %i INTS/sec\n",
+-                    pAC->DynIrqModInfo.MaxModIntsPerSec);
+-        } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+-             if (IsIntModEnabled(pAC)) {
+-                printk("Dynamic int moderation runs with %i INTS/sec\n",
+-                       pAC->DynIrqModInfo.MaxModIntsPerSec);
+-             } else {
+-                printk("Dynamic int moderation currently not applied\n");
+-             }
+-        } else {
+-             printk("No interrupt moderation selected!\n");
+-        }
+-    }
+-}
+-
+-/*******************************************************************************
+-** Function     : DisplaySelectedModerationMask()
+-** Description  : Displays what interrupts are moderated
+-** Programmer   : Ralph Roesler
+-** Last Modified: 23-mar-03
+-** Returns      : void!
+-** Notes        : -
+-*******************************************************************************/
+-
+-static void
+-DisplaySelectedModerationMask(SK_AC *pAC) {
+-
+-    if (pAC->DynIrqModInfo.DisplayStats) {
+-        if (pAC->DynIrqModInfo.IntModTypeSelect != C_INT_MOD_NONE) {
+-            switch (pAC->DynIrqModInfo.MaskIrqModeration) {
+-                case IRQ_MASK_TX_ONLY: 
+-                   printk("Only Tx-interrupts are moderated\n");
+-                   break;
+-                case IRQ_MASK_RX_ONLY: 
+-                   printk("Only Rx-interrupts are moderated\n");
+-                   break;
+-                case IRQ_MASK_SP_ONLY: 
+-                   printk("Only special-interrupts are moderated\n");
+-                   break;
+-                case IRQ_MASK_TX_RX: 
+-                   printk("Tx- and Rx-interrupts are moderated\n");
+-                   break;
+-                case IRQ_MASK_SP_RX: 
+-                   printk("Special- and Rx-interrupts are moderated\n");
+-                   break;
+-                case IRQ_MASK_SP_TX: 
+-                   printk("Special- and Tx-interrupts are moderated\n");
+-                   break;
+-                case IRQ_MASK_RX_TX_SP:
+-                   printk("All Rx-, Tx and special-interrupts are moderated\n");
+-                   break;
+-                default:
+-                   printk("Don't know what is moderated\n");
+-                   break;
+-            }
+-        } else {
+-            printk("No specific interrupts masked for moderation\n");
+-        }
+-    } 
+-}
+-
+-/*******************************************************************************
+-** Function     : DisplayDescrRatio
+-** Description  : Like the name states...
+-** Programmer   : Ralph Roesler
+-** Last Modified: 23-mar-03
+-** Returns      : void!
+-** Notes        : -
+-*******************************************************************************/
+-
+-static void
+-DisplayDescrRatio(SK_AC *pAC) {
+-    int TotalMaxNbrDescr = 0;
+-
+-    if (pAC->DynIrqModInfo.DisplayStats) {
+-        TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
+-        printk("Ratio descriptors: %i/%i\n",
+-               M_DIMINFO.NbrProcessedDescr, TotalMaxNbrDescr);
+-    }
+-}
+-
+-/*******************************************************************************
+-**
+-** End of file
+-**
+-*******************************************************************************/
++ *
++ * End of file
++ *
++ ******************************************************************************/
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skethtool.c linux-2.6.9.new/drivers/net/sk98lin/skethtool.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skethtool.c    1970-01-01 08:00:00.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skethtool.c    2006-12-07 14:35:03.000000000 +0800
+@@ -0,0 +1,1333 @@
++/******************************************************************************
++ *
++ * Name:        skethtool.c
++ * Project:     GEnesis, PCI Gigabit Ethernet Adapter
++ * Version:     $Revision: 1.3.2.9 $
++ * Date:        $Date: 2005/05/23 13:47:33 $
++ * Purpose:     All functions regarding ethtool handling
++ *
++ ******************************************************************************/
++
++/******************************************************************************
++ *
++ *    (C)Copyright 1998-2002 SysKonnect GmbH.
++ *    (C)Copyright 2002-2005 Marvell.
++ *
++ *    Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet 
++ *      Server Adapters.
++ *
++ *    Author: Ralph Roesler (rroesler@syskonnect.de)
++ *            Mirko Lindner (mlindner@syskonnect.de)
++ *
++ *    Address all question to: linux@syskonnect.de
++ *
++ *    This program is free software; you can redistribute it and/or modify
++ *    it under the terms of the GNU General Public License as published by
++ *    the Free Software Foundation; either version 2 of the License, or
++ *    (at your option) any later version.
++ *
++ *    The information in this file is provided "AS IS" without warranty.
++ *
++ *****************************************************************************/
++
++#include "h/skdrv1st.h"
++#include "h/skdrv2nd.h"
++#include "h/skversion.h"
++#include <linux/ethtool.h>
++#include <linux/module.h>
++#include <linux/timer.h>
++
++/******************************************************************************
++ *
++ * External Functions and Data
++ *
++ *****************************************************************************/
++
++extern void SkDimDisableModeration(SK_AC *pAC, int CurrentModeration);
++extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);
++
++/******************************************************************************
++ *
++ * Defines
++ *
++ *****************************************************************************/
++
++#ifndef ETHT_STATSTRING_LEN
++#define ETHT_STATSTRING_LEN 32
++#endif
++
++#define SK98LIN_STAT(m)       sizeof(((SK_AC *)0)->m),offsetof(SK_AC, m)
++
++#define SUPP_COPPER_ALL (SUPPORTED_10baseT_Half  | SUPPORTED_10baseT_Full  | \
++                         SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
++                         SUPPORTED_1000baseT_Half| SUPPORTED_1000baseT_Full| \
++                         SUPPORTED_TP)
++
++#define ADV_COPPER_ALL  (ADVERTISED_10baseT_Half  | ADVERTISED_10baseT_Full  | \
++                         ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
++                         ADVERTISED_1000baseT_Half| ADVERTISED_1000baseT_Full| \
++                         ADVERTISED_TP)
++
++#define SUPP_FIBRE_ALL  (SUPPORTED_1000baseT_Full | \
++                         SUPPORTED_FIBRE          | \
++                         SUPPORTED_Autoneg)
++
++#define ADV_FIBRE_ALL   (ADVERTISED_1000baseT_Full | \
++                         ADVERTISED_FIBRE          | \
++                         ADVERTISED_Autoneg)
++
++/******************************************************************************
++ *
++ * Local Function Prototypes
++ *
++ *****************************************************************************/
++
++#ifdef ETHTOOL_GSET
++static void getSettings(SK_AC *pAC, int port, struct ethtool_cmd *ecmd);
++#endif
++#ifdef ETHTOOL_SSET
++static int setSettings(SK_AC *pAC, int port, struct ethtool_cmd *ecmd);
++#endif
++#ifdef ETHTOOL_GPAUSEPARAM
++static void getPauseParams(SK_AC *pAC, int port, struct ethtool_pauseparam *epause);
++#endif
++#ifdef ETHTOOL_SPAUSEPARAM
++static int setPauseParams(SK_AC *pAC, int port, struct ethtool_pauseparam *epause);
++#endif
++#ifdef ETHTOOL_GDRVINFO
++static void getDriverInfo(SK_AC *pAC, int port, struct ethtool_drvinfo *edrvinfo);
++#endif
++#ifdef ETHTOOL_PHYS_ID
++static int startLocateNIC(SK_AC *pAC, int port, struct ethtool_value *blinkSecs);
++static void toggleLeds(unsigned long ptr);
++#endif
++#ifdef ETHTOOL_GCOALESCE
++static void getModerationParams(SK_AC *pAC, int port, struct ethtool_coalesce *ecoalesc);
++#endif
++#ifdef ETHTOOL_SCOALESCE
++static int setModerationParams(SK_AC *pAC, int port, struct ethtool_coalesce *ecoalesc);
++#endif
++#ifdef ETHTOOL_GWOL
++static void getWOLsettings(SK_AC *pAC, int port, struct ethtool_wolinfo *ewol);
++#endif
++#ifdef ETHTOOL_SWOL
++static int setWOLsettings(SK_AC *pAC, int port, struct ethtool_wolinfo *ewol);
++#endif
++
++static int getPortNumber(struct net_device *netdev, struct ifreq *ifr);
++
++/******************************************************************************
++ *
++ * Local Variables
++ *
++ *****************************************************************************/
++
++struct sk98lin_stats {
++      char stat_string[ETHT_STATSTRING_LEN];
++      int  sizeof_stat;
++      int  stat_offset;
++};
++
++static struct sk98lin_stats sk98lin_etht_stats_port0[] = {
++      { "rx_packets" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxOkCts) },
++      { "tx_packets" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxOkCts) },
++      { "rx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxOctetsOkCts) },
++      { "tx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxOctetsOkCts) },
++      { "rx_errors" , SK98LIN_STAT(PnmiStruct.InErrorsCts) },
++      { "tx_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxSingleCollisionCts) },
++      { "rx_dropped" , SK98LIN_STAT(PnmiStruct.RxNoBufCts) },
++      { "tx_dropped" , SK98LIN_STAT(PnmiStruct.TxNoBufCts) },
++      { "multicasts" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxMulticastOkCts) },
++      { "collisions" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxSingleCollisionCts) },
++      { "rx_length_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxRuntCts) },
++      { "rx_buffer_overflow_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxFifoOverflowCts) },
++      { "rx_crc_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxFcsCts) },
++      { "rx_frame_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxFramingCts) },
++      { "rx_too_short_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxShortsCts) },
++      { "rx_too_long_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxTooLongCts) },
++      { "rx_carrier_extension_errors", SK98LIN_STAT(PnmiStruct.Stat[0].StatRxCextCts) },
++      { "rx_symbol_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxSymbolCts) },
++      { "rx_llc_mac_size_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxIRLengthCts) },
++      { "rx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxCarrierCts) },
++      { "rx_jabber_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxJabberCts) },
++      { "rx_missed_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxMissedCts) },
++      { "tx_abort_collision_errors" , SK98LIN_STAT(stats.tx_aborted_errors) },
++      { "tx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxCarrierCts) },
++      { "tx_buffer_underrun_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxFifoUnderrunCts) },
++      { "tx_heartbeat_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxCarrierCts) } ,
++      { "tx_window_errors" , SK98LIN_STAT(stats.tx_window_errors) }
++};
++
++static struct sk98lin_stats sk98lin_etht_stats_port1[] = {
++      { "rx_packets" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxOkCts) },
++      { "tx_packets" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxOkCts) },
++      { "rx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxOctetsOkCts) },
++      { "tx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxOctetsOkCts) },
++      { "rx_errors" , SK98LIN_STAT(PnmiStruct.InErrorsCts) },
++      { "tx_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxSingleCollisionCts) },
++      { "rx_dropped" , SK98LIN_STAT(PnmiStruct.RxNoBufCts) },
++      { "tx_dropped" , SK98LIN_STAT(PnmiStruct.TxNoBufCts) },
++      { "multicasts" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxMulticastOkCts) },
++      { "collisions" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxSingleCollisionCts) },
++      { "rx_length_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxRuntCts) },
++      { "rx_buffer_overflow_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxFifoOverflowCts) },
++      { "rx_crc_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxFcsCts) },
++      { "rx_frame_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxFramingCts) },
++      { "rx_too_short_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxShortsCts) },
++      { "rx_too_long_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxTooLongCts) },
++      { "rx_carrier_extension_errors", SK98LIN_STAT(PnmiStruct.Stat[1].StatRxCextCts) },
++      { "rx_symbol_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxSymbolCts) },
++      { "rx_llc_mac_size_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxIRLengthCts) },
++      { "rx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxCarrierCts) },
++      { "rx_jabber_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxJabberCts) },
++      { "rx_missed_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxMissedCts) },
++      { "tx_abort_collision_errors" , SK98LIN_STAT(stats.tx_aborted_errors) },
++      { "tx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxCarrierCts) },
++      { "tx_buffer_underrun_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxFifoUnderrunCts) },
++      { "tx_heartbeat_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxCarrierCts) } ,
++      { "tx_window_errors" , SK98LIN_STAT(stats.tx_window_errors) }
++};
++
++#define SK98LIN_STATS_LEN sizeof(sk98lin_etht_stats_port0) / sizeof(struct sk98lin_stats)
++
++static int nbrBlinkQuarterSeconds;
++static int currentPortIndex;
++static SK_BOOL isLocateNICrunning   = SK_FALSE;
++static SK_BOOL isDualNetCard        = SK_FALSE;
++static SK_BOOL doSwitchLEDsOn       = SK_FALSE;
++static SK_BOOL boardWasDown[2]      = { SK_FALSE, SK_FALSE };
++static struct timer_list locateNICtimer;
++
++/******************************************************************************
++ *
++ * Global Functions
++ *
++ *****************************************************************************/
++
++/*****************************************************************************
++ *
++ *    SkEthIoctl - IOCTL entry point for all ethtool queries
++ *
++ * Description:
++ *    Any IOCTL request that has to deal with the ethtool command tool is
++ *    dispatched via this function.
++ *
++ * Returns:
++ *    ==0:    everything fine, no error
++ *    !=0:    the return value is the error code of the failure 
++ */
++int SkEthIoctl(
++struct net_device *netdev,  /* the pointer to netdev structure       */
++struct ifreq      *ifr)     /* what interface the request refers to? */
++{
++      DEV_NET             *pNet        = (DEV_NET*) netdev->priv;
++      SK_AC               *pAC         = pNet->pAC;
++      void                *pAddr       = ifr->ifr_data;
++      int                  port        = getPortNumber(netdev, ifr);
++      SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
++      SK_U32               Size        = sizeof(SK_PNMI_STRUCT_DATA);
++      SK_U32               cmd;
++      struct sk98lin_stats *sk98lin_etht_stats = 
++              (port == 0) ? sk98lin_etht_stats_port0 : sk98lin_etht_stats_port1;
++
++        if (get_user(cmd, (uint32_t *) pAddr)) {
++                return -EFAULT;
++      }
++
++      switch(cmd) {
++#ifdef ETHTOOL_GSET
++      case ETHTOOL_GSET: {
++              struct ethtool_cmd ecmd = { ETHTOOL_GSET };
++              getSettings(pAC, port, &ecmd);
++              if(copy_to_user(pAddr, &ecmd, sizeof(ecmd))) {
++                      return -EFAULT;
++              }
++              return 0;
++      }
++      break;
++#endif
++#ifdef ETHTOOL_SSET
++      case ETHTOOL_SSET: {
++              struct ethtool_cmd ecmd;
++              if(copy_from_user(&ecmd, pAddr, sizeof(ecmd))) {
++                      return -EFAULT;
++              }
++              return setSettings(pAC, port, &ecmd);
++      }
++      break;
++#endif
++#ifdef ETHTOOL_GDRVINFO
++      case ETHTOOL_GDRVINFO: {
++              struct ethtool_drvinfo drvinfo = { ETHTOOL_GDRVINFO };
++              getDriverInfo(pAC, port, &drvinfo);
++              if(copy_to_user(pAddr, &drvinfo, sizeof(drvinfo))) {
++                      return -EFAULT;
++              }
++              return 0;
++      }
++      break;
++#endif
++#ifdef ETHTOOL_GSTRINGS
++      case ETHTOOL_GSTRINGS: {
++              struct ethtool_gstrings gstrings = { ETHTOOL_GSTRINGS };
++              char *strings = NULL;
++              int err = 0;
++              if(copy_from_user(&gstrings, pAddr, sizeof(gstrings))) {
++                      return -EFAULT;
++              }
++              switch(gstrings.string_set) {
++#ifdef ETHTOOL_GSTATS
++                      case ETH_SS_STATS: {
++                              int i;
++                              gstrings.len = SK98LIN_STATS_LEN;
++                              if ((strings = kmalloc(SK98LIN_STATS_LEN*ETHT_STATSTRING_LEN,GFP_KERNEL)) == NULL) {
++                                      return -ENOMEM;
++                              }
++                              for(i=0; i < SK98LIN_STATS_LEN; i++) {
++                                      memcpy(&strings[i * ETHT_STATSTRING_LEN],
++                                              &(sk98lin_etht_stats[i].stat_string),
++                                              ETHT_STATSTRING_LEN);
++                              }
++                      }
++                      break;
++#endif
++                      default:
++                              return -EOPNOTSUPP;
++              }
++              if(copy_to_user(pAddr, &gstrings, sizeof(gstrings))) {
++                      err = -EFAULT;
++              }
++              pAddr = (void *) ((unsigned long int) pAddr + offsetof(struct ethtool_gstrings, data));
++              if(!err && copy_to_user(pAddr, strings, gstrings.len * ETH_GSTRING_LEN)) {
++                      err = -EFAULT;
++              }
++              kfree(strings);
++              return err;
++      }
++#endif
++#ifdef ETHTOOL_GSTATS
++      case ETHTOOL_GSTATS: {
++              struct {
++                      struct ethtool_stats eth_stats;
++                      uint64_t data[SK98LIN_STATS_LEN];
++              } stats = { {ETHTOOL_GSTATS, SK98LIN_STATS_LEN} };
++              int i;
++
++              if (netif_running(pAC->dev[port])) {
++                      SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, port);
++              }
++              for(i = 0; i < SK98LIN_STATS_LEN; i++) {
++                      if (netif_running(pAC->dev[port])) {
++                              stats.data[i] = (sk98lin_etht_stats[i].sizeof_stat ==
++                                      sizeof(uint64_t)) ?
++                                      *(uint64_t *)((char *)pAC +
++                                              sk98lin_etht_stats[i].stat_offset) :
++                                      *(uint32_t *)((char *)pAC +
++                                              sk98lin_etht_stats[i].stat_offset);
++                      } else {
++                              stats.data[i] = (sk98lin_etht_stats[i].sizeof_stat ==
++                                      sizeof(uint64_t)) ? (uint64_t) 0 : (uint32_t) 0;
++                      }
++              }
++              if(copy_to_user(pAddr, &stats, sizeof(stats))) {
++                      return -EFAULT;
++              }
++              return 0;
++      }
++#endif
++#ifdef ETHTOOL_PHYS_ID
++      case ETHTOOL_PHYS_ID: {
++              struct ethtool_value blinkSecs;
++              if(copy_from_user(&blinkSecs, pAddr, sizeof(blinkSecs))) {
++                      return -EFAULT;
++              }
++              return startLocateNIC(pAC, port, &blinkSecs);
++      }
++#endif
++#ifdef ETHTOOL_GPAUSEPARAM
++      case ETHTOOL_GPAUSEPARAM: {
++              struct ethtool_pauseparam epause = { ETHTOOL_GPAUSEPARAM };
++              getPauseParams(pAC, port, &epause);
++              if(copy_to_user(pAddr, &epause, sizeof(epause))) {
++                      return -EFAULT;
++              }
++              return 0;
++      }
++#endif
++#ifdef ETHTOOL_SPAUSEPARAM
++      case ETHTOOL_SPAUSEPARAM: {
++              struct ethtool_pauseparam epause;
++              if(copy_from_user(&epause, pAddr, sizeof(epause))) {
++                      return -EFAULT;
++              }
++              return setPauseParams(pAC, port, &epause);
++      }
++#endif
++#ifdef ETHTOOL_GSG
++      case ETHTOOL_GSG: {
++              struct ethtool_value edata = { ETHTOOL_GSG };
++              edata.data = (netdev->features & NETIF_F_SG) != 0;
++              if (copy_to_user(pAddr, &edata, sizeof(edata))) {
++                      return -EFAULT;
++              }
++              return 0;
++      }
++#endif
++#ifdef ETHTOOL_SSG
++      case ETHTOOL_SSG: {
++              struct ethtool_value edata;
++              if (copy_from_user(&edata, pAddr, sizeof(edata))) {
++                        return -EFAULT;
++              }
++              if (pAC->ChipsetType) { /* Don't handle if Genesis */
++                      if (edata.data) {
++                              netdev->features |= NETIF_F_SG;
++                      } else {
++                              netdev->features &= ~NETIF_F_SG;
++                      }
++              }
++              return 0;
++      }
++#endif
++#ifdef ETHTOOL_GRXCSUM
++      case ETHTOOL_GRXCSUM: {
++              struct ethtool_value edata = { ETHTOOL_GRXCSUM };
++              edata.data = pAC->RxPort[port].UseRxCsum;
++              if (copy_to_user(pAddr, &edata, sizeof(edata))) {
++                      return -EFAULT;
++              }
++              return 0;
++      }
++#endif
++#ifdef ETHTOOL_SRXCSUM
++      case ETHTOOL_SRXCSUM: {
++              struct ethtool_value edata;
++              if (copy_from_user(&edata, pAddr, sizeof(edata))) {
++                      return -EFAULT;
++              }
++              pAC->RxPort[port].UseRxCsum = edata.data;
++                return 0;
++      }
++#endif
++#ifdef ETHTOOL_GTXCSUM
++      case ETHTOOL_GTXCSUM: {
++              struct ethtool_value edata = { ETHTOOL_GTXCSUM };
++              edata.data = ((netdev->features & NETIF_F_IP_CSUM) != 0);
++              if (copy_to_user(pAddr, &edata, sizeof(edata))) {
++                      return -EFAULT;
++              }
++              return 0;
++      }
++#endif
++#ifdef ETHTOOL_STXCSUM
++      case ETHTOOL_STXCSUM: {
++              struct ethtool_value edata;
++              if (copy_from_user(&edata, pAddr, sizeof(edata))) {
++                      return -EFAULT;
++              }
++              if (pAC->ChipsetType) { /* Don't handle if Genesis */
++                      if (edata.data) {
++                              netdev->features |= NETIF_F_IP_CSUM;
++                      } else {
++                              netdev->features &= ~NETIF_F_IP_CSUM;
++                      }
++              }
++              return 0;
++      }
++#endif
++#ifdef ETHTOOL_NWAY_RST
++      case ETHTOOL_NWAY_RST: {
++              if(netif_running(netdev)) {
++                      (*netdev->stop)(netdev);
++                      (*netdev->open)(netdev);
++              }
++              return 0;
++      }
++#endif
++#ifdef NETIF_F_TSO
++#ifdef ETHTOOL_GTSO
++      case ETHTOOL_GTSO: {
++              struct ethtool_value edata = { ETHTOOL_GTSO };
++              edata.data = (netdev->features & NETIF_F_TSO) != 0;
++              if (copy_to_user(pAddr, &edata, sizeof(edata))) {
++                      return -EFAULT;
++              }
++              return 0;
++      }
++#endif
++#ifdef ETHTOOL_STSO
++      case ETHTOOL_STSO: {
++              struct ethtool_value edata;
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      if (copy_from_user(&edata, pAddr, sizeof(edata))) {
++                              return -EFAULT;
++                      }
++                      if (edata.data) {
++                              netdev->features |= NETIF_F_TSO;
++                      } else {
++                              netdev->features &= ~NETIF_F_TSO;
++                      }
++                      return 0;
++              }
++                return -EOPNOTSUPP;
++      }
++#endif
++#endif
++#ifdef ETHTOOL_GCOALESCE
++      case ETHTOOL_GCOALESCE: {
++              struct ethtool_coalesce ecoalesc = { ETHTOOL_GCOALESCE };
++              getModerationParams(pAC, port, &ecoalesc);
++              if(copy_to_user(pAddr, &ecoalesc, sizeof(ecoalesc))) {
++                      return -EFAULT;
++              }
++              return 0;
++      }
++#endif
++#ifdef ETHTOOL_SCOALESCE
++      case ETHTOOL_SCOALESCE: {
++              struct ethtool_coalesce ecoalesc;
++              if(copy_from_user(&ecoalesc, pAddr, sizeof(ecoalesc))) {
++                      return -EFAULT;
++              }
++              return setModerationParams(pAC, port, &ecoalesc);
++      }
++#endif
++#ifdef ETHTOOL_GWOL
++      case ETHTOOL_GWOL: {
++              struct ethtool_wolinfo ewol = { ETHTOOL_GWOL };
++              getWOLsettings(pAC, port, &ewol);
++              if(copy_to_user(pAddr, &ewol, sizeof(ewol))) {
++                      return -EFAULT;
++              }
++              return 0;
++      }
++#endif
++#ifdef ETHTOOL_SWOL
++      case ETHTOOL_SWOL: {
++              struct ethtool_wolinfo ewol;
++              if(copy_from_user(&ewol, pAddr, sizeof(ewol))) {
++                      return -EFAULT;
++              }
++              return setWOLsettings(pAC, port, &ewol);
++      }
++#endif
++        default:
++                return -EOPNOTSUPP;
++        }
++} /* SkEthIoctl() */
++
++/******************************************************************************
++ *
++ * Local Functions
++ *
++ *****************************************************************************/
++
++#ifdef ETHTOOL_GSET
++/*****************************************************************************
++ *
++ *    getSettings - retrieves the current settings of the selected adapter
++ *
++ * Description:
++ *    The current configuration of the selected adapter is returned.
++ *    This configuration involves a)speed, b)duplex and c)autoneg plus
++ *    a number of other variables.
++ *
++ * Returns:   N/A
++ *
++ */
++static void getSettings(
++SK_AC              *pAC,  /* pointer to adapter control context      */
++int                 port, /* the port of the selected adapter        */
++struct ethtool_cmd *ecmd) /* mandatory command structure for results */
++{
++      SK_GEPORT *pPort = &pAC->GIni.GP[port];
++
++      static int DuplexAutoNegConfMap[9][3]= {
++              { -1                     , -1         , -1              },
++              { 0                      , -1         , -1              },
++              { SK_LMODE_HALF          , DUPLEX_HALF, AUTONEG_DISABLE },
++              { SK_LMODE_FULL          , DUPLEX_FULL, AUTONEG_DISABLE },
++              { SK_LMODE_AUTOHALF      , DUPLEX_HALF, AUTONEG_ENABLE  },
++              { SK_LMODE_AUTOFULL      , DUPLEX_FULL, AUTONEG_ENABLE  },
++              { SK_LMODE_AUTOBOTH      , DUPLEX_FULL, AUTONEG_ENABLE  },
++              { SK_LMODE_AUTOSENSE     , -1         , -1              },
++              { SK_LMODE_INDETERMINATED, -1         , -1              }
++      };
++
++      static int SpeedConfMap[6][2] = {
++              { 0                       , -1         },
++              { SK_LSPEED_AUTO          , -1         },
++              { SK_LSPEED_10MBPS        , SPEED_10   },
++              { SK_LSPEED_100MBPS       , SPEED_100  },
++              { SK_LSPEED_1000MBPS      , SPEED_1000 },
++              { SK_LSPEED_INDETERMINATED, -1         }
++      };
++
++      static int AdvSpeedMap[6][2] = {
++              { 0                       , -1         },
++              { SK_LSPEED_AUTO          , -1         },
++              { SK_LSPEED_10MBPS        , ADVERTISED_10baseT_Half   | ADVERTISED_10baseT_Full },
++              { SK_LSPEED_100MBPS       , ADVERTISED_100baseT_Half  | ADVERTISED_100baseT_Full },
++              { SK_LSPEED_1000MBPS      , ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full},
++              { SK_LSPEED_INDETERMINATED, -1         }
++      };
++
++      ecmd->phy_address = port;
++      ecmd->speed       = SpeedConfMap[pPort->PLinkSpeedUsed][1];
++      ecmd->duplex      = DuplexAutoNegConfMap[pPort->PLinkModeStatus][1];
++      ecmd->autoneg     = DuplexAutoNegConfMap[pPort->PLinkModeStatus][2];
++      ecmd->transceiver = XCVR_INTERNAL;
++
++      if (pAC->GIni.GICopperType) {
++              ecmd->port        = PORT_TP;
++              ecmd->supported   = (SUPP_COPPER_ALL|SUPPORTED_Autoneg);
++              if (pAC->GIni.GIGenesis) {
++                      ecmd->supported &= ~(SUPPORTED_10baseT_Half);
++                      ecmd->supported &= ~(SUPPORTED_10baseT_Full);
++                      ecmd->supported &= ~(SUPPORTED_100baseT_Half);
++                      ecmd->supported &= ~(SUPPORTED_100baseT_Full);
++              } else {
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
++                              ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
++                      } 
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
++                              ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
++                              ecmd->supported &= ~(SUPPORTED_1000baseT_Full);
++                      }
++              }
++              if (pAC->GIni.GP[0].PLinkSpeed != SK_LSPEED_AUTO) {
++                      ecmd->advertising = AdvSpeedMap[pPort->PLinkSpeed][1];
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
++                              ecmd->advertising &= ~(SUPPORTED_1000baseT_Half);
++                      } 
++              } else {
++                      ecmd->advertising = ecmd->supported;
++              }
++              if (ecmd->autoneg == AUTONEG_ENABLE) {
++                      ecmd->advertising |= ADVERTISED_Autoneg;
++              } 
++      } else {
++              ecmd->port        = PORT_FIBRE;
++              ecmd->supported   = (SUPP_FIBRE_ALL);
++              ecmd->advertising = (ADV_FIBRE_ALL);
++      }
++}
++#endif
++
++#ifdef ETHTOOL_SSET
++/*****************************************************************************
++ *
++ *    setSettings - configures the settings of a selected adapter
++ *
++ * Description:
++ *    Possible settings that may be altered are a)speed, b)duplex or 
++ *    c)autonegotiation.
++ *
++ * Returns:
++ *    ==0:    everything fine, no error
++ *    !=0:    the return value is the error code of the failure 
++ */
++static int setSettings(
++SK_AC              *pAC,  /* pointer to adapter control context    */
++int                 port, /* the port of the selected adapter      */
++struct ethtool_cmd *ecmd) /* command structure containing settings */
++{
++      DEV_NET     *pNet  = (DEV_NET *) pAC->dev[port]->priv;
++      SK_U32       Instance;
++      char         Buf[4];
++      unsigned int Len = 1;
++      int Ret;
++
++      if (port == 0) {
++              Instance = (pAC->RlmtNets == 2) ? 1 : 2;
++      } else {
++              Instance = (pAC->RlmtNets == 2) ? 2 : 3;
++      }
++
++      if (((ecmd->autoneg == AUTONEG_DISABLE) || (ecmd->autoneg == AUTONEG_ENABLE)) &&
++          ((ecmd->duplex == DUPLEX_FULL) || (ecmd->duplex == DUPLEX_HALF))) {
++              if (ecmd->autoneg == AUTONEG_DISABLE) {
++                      if (ecmd->duplex == DUPLEX_FULL) { 
++                              *Buf = (char) SK_LMODE_FULL;
++                      } else {
++                              *Buf = (char) SK_LMODE_HALF;
++                      }
++              } else {
++                      if (ecmd->duplex == DUPLEX_FULL) { 
++                              *Buf = (char) SK_LMODE_AUTOFULL;
++                      } else {
++                              *Buf = (char) SK_LMODE_AUTOHALF;
++                      }
++              }
++
++              Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE, 
++                                      &Buf, &Len, Instance, pNet->NetNr);
++      
++              if (Ret != SK_PNMI_ERR_OK) {
++                      return -EINVAL;
++              }
++      }
++
++      if ((ecmd->speed == SPEED_1000) ||
++          (ecmd->speed == SPEED_100)  || 
++          (ecmd->speed == SPEED_10)) {
++              if (ecmd->speed == SPEED_1000) {
++                      *Buf = (char) SK_LSPEED_1000MBPS;
++              } else if (ecmd->speed == SPEED_100) {
++                      *Buf = (char) SK_LSPEED_100MBPS;
++              } else {
++                      *Buf = (char) SK_LSPEED_10MBPS;
++              }
++
++              Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, 
++                                      &Buf, &Len, Instance, pNet->NetNr);
++      
++              if (Ret != SK_PNMI_ERR_OK) {
++                      return -EINVAL;
++              }
++      } else {
++              return -EINVAL;
++      }
++      return 0;
++}
++#endif
++
++#ifdef ETHTOOL_GPAUSEPARAM
++/*****************************************************************************
++ *
++ *    getPauseParams - retrieves the pause parameters
++ *
++ * Description:
++ *    All current pause parameters of a selected adapter are placed 
++ *    in the passed ethtool_pauseparam structure and are returned.
++ *
++ * Returns:   N/A
++ *
++ */
++static void getPauseParams(
++SK_AC                     *pAC,    /* pointer to adapter control context */
++int                        port,   /* the port of the selected adapter   */
++struct ethtool_pauseparam *epause) /* pause parameter struct for result  */
++{
++      SK_GEPORT *pPort            = &pAC->GIni.GP[port];
++
++      epause->rx_pause = 0;
++      epause->tx_pause = 0;
++
++      if (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND) {
++              epause->tx_pause = 1;
++      } 
++      if ((pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) ||
++          (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM)) {
++              epause->tx_pause = 1;
++              epause->rx_pause = 1;
++      }
++
++      if ((epause->rx_pause == 0) && (epause->tx_pause == 0)) {
++              epause->autoneg = SK_FALSE;
++      } else {
++              epause->autoneg = SK_TRUE;
++      }
++}
++#endif
++
++#ifdef ETHTOOL_SPAUSEPARAM
++/*****************************************************************************
++ *
++ *    setPauseParams - configures the pause parameters of an adapter
++ *
++ * Description:
++ *    This function sets the Rx or Tx pause parameters 
++ *
++ * Returns:
++ *    ==0:    everything fine, no error
++ *    !=0:    the return value is the error code of the failure 
++ */
++static int setPauseParams(
++SK_AC                     *pAC,    /* pointer to adapter control context */
++int                        port,   /* the port of the selected adapter   */
++struct ethtool_pauseparam *epause) /* pause parameter struct with params */
++{
++      SK_GEPORT *pPort            = &pAC->GIni.GP[port];
++      DEV_NET   *pNet             = (DEV_NET *) pAC->dev[port]->priv;
++      int        PrevSpeedVal     = pPort->PLinkSpeedUsed;
++
++      SK_U32         Instance;
++      char           Buf[4];
++      int            Ret;
++      SK_BOOL        prevAutonegValue = SK_TRUE;
++      int            prevTxPause      = 0;
++      int            prevRxPause      = 0;
++      unsigned int   Len              = 1;
++
++        if (port == 0) {
++                Instance = (pAC->RlmtNets == 2) ? 1 : 2;
++        } else {
++                Instance = (pAC->RlmtNets == 2) ? 2 : 3;
++        }
++
++      /*
++      ** we have to determine the current settings to see if 
++      ** the operator requested any modification of the flow 
++      ** control parameters...
++      */
++      if (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND) {
++              prevTxPause = 1;
++      } 
++      if ((pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) ||
++          (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM)) {
++              prevTxPause = 1;
++              prevRxPause = 1;
++      }
++
++      if ((prevRxPause == 0) && (prevTxPause == 0)) {
++              prevAutonegValue = SK_FALSE;
++      }
++
++
++      /*
++      ** perform modifications regarding the changes 
++      ** requested by the operator
++      */
++      if (epause->autoneg != prevAutonegValue) {
++              if (epause->autoneg == AUTONEG_DISABLE) {
++                      *Buf = (char) SK_FLOW_MODE_NONE;
++              } else {
++                      *Buf = (char) SK_FLOW_MODE_SYMMETRIC;
++              }
++      } else {
++              if(epause->rx_pause && epause->tx_pause) {
++                      *Buf = (char) SK_FLOW_MODE_SYMMETRIC;
++              } else if (epause->rx_pause && !epause->tx_pause) {
++                      *Buf = (char) SK_FLOW_MODE_SYM_OR_REM;
++              } else if(!epause->rx_pause && epause->tx_pause) {
++                      *Buf = (char) SK_FLOW_MODE_LOC_SEND;
++              } else {
++                      *Buf = (char) SK_FLOW_MODE_NONE;
++              }
++      }
++
++      Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE,
++                      &Buf, &Len, Instance, pNet->NetNr);
++
++      if (Ret != SK_PNMI_ERR_OK) {
++              SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
++              ("ethtool (sk98lin): error changing rx/tx pause (%i)\n", Ret));
++      }  else {
++              Len = 1; /* set buffer length to correct value */
++      }
++
++      /*
++      ** It may be that autoneg has been disabled! Therefore
++      ** set the speed to the previously used value...
++      */
++      *Buf = (char) PrevSpeedVal;
++
++      Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, 
++                      &Buf, &Len, Instance, pNet->NetNr);
++
++      if (Ret != SK_PNMI_ERR_OK) {
++              SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
++              ("ethtool (sk98lin): error setting speed (%i)\n", Ret));
++      }
++        return 0;
++}
++#endif
++
++#ifdef ETHTOOL_GCOALESCE
++/*****************************************************************************
++ *
++ *    getModerationParams - retrieves the IRQ moderation settings 
++ *
++ * Description:
++ *    All current IRQ moderation settings of a selected adapter are placed 
++ *    in the passed ethtool_coalesce structure and are returned.
++ *
++ * Returns:   N/A
++ *
++ */
++static void getModerationParams(
++SK_AC                   *pAC,      /* pointer to adapter control context */
++int                      port,     /* the port of the selected adapter   */
++struct ethtool_coalesce *ecoalesc) /* IRQ moderation struct for results  */
++{
++      DIM_INFO *Info = &pAC->DynIrqModInfo;
++      SK_BOOL UseTxIrqModeration = SK_FALSE;
++      SK_BOOL UseRxIrqModeration = SK_FALSE;
++
++      if (Info->IntModTypeSelect != C_INT_MOD_NONE) {
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      UseRxIrqModeration = SK_TRUE;
++                      UseTxIrqModeration = SK_TRUE;
++              } else {
++                      if ((Info->MaskIrqModeration == IRQ_MASK_RX_ONLY) ||
++                          (Info->MaskIrqModeration == IRQ_MASK_SP_RX)   ||
++                          (Info->MaskIrqModeration == IRQ_MASK_RX_TX_SP)) {
++                              UseRxIrqModeration = SK_TRUE;
++                      }
++                      if ((Info->MaskIrqModeration == IRQ_MASK_TX_ONLY) ||
++                          (Info->MaskIrqModeration == IRQ_MASK_SP_TX)   ||
++                          (Info->MaskIrqModeration == IRQ_MASK_RX_TX_SP)) {
++                              UseTxIrqModeration = SK_TRUE;
++                      }
++              }
++
++              if (UseRxIrqModeration) {
++                      ecoalesc->rx_coalesce_usecs = 1000000 / Info->MaxModIntsPerSec;
++              }
++              if (UseTxIrqModeration) {
++                      ecoalesc->tx_coalesce_usecs = 1000000 / Info->MaxModIntsPerSec;
++              }
++              if (Info->IntModTypeSelect == C_INT_MOD_DYNAMIC) {
++                      ecoalesc->rate_sample_interval = Info->DynIrqModSampleInterval; 
++                      if (UseRxIrqModeration) {
++                              ecoalesc->use_adaptive_rx_coalesce = 1;
++                              ecoalesc->rx_coalesce_usecs_low = 
++                                      1000000 / Info->MaxModIntsPerSecLowerLimit;
++                              ecoalesc->rx_coalesce_usecs_high = 
++                                      1000000 / Info->MaxModIntsPerSecUpperLimit;
++                      }
++                      if (UseTxIrqModeration) {
++                              ecoalesc->use_adaptive_tx_coalesce = 1;
++                              ecoalesc->tx_coalesce_usecs_low = 
++                                      1000000 / Info->MaxModIntsPerSecLowerLimit;
++                              ecoalesc->tx_coalesce_usecs_high = 
++                                      1000000 / Info->MaxModIntsPerSecUpperLimit;
++                      }
++              }
++      }
++}
++#endif
++
++#ifdef ETHTOOL_SCOALESCE
++/*****************************************************************************
++ *
++ *    setModerationParams - configures the IRQ moderation of an adapter
++ *
++ * Description:
++ *    Depending on the desired IRQ moderation parameters, either a) static,
++ *    b) dynamic or c) no moderation is configured. 
++ *
++ * Returns:
++ *    ==0:    everything fine, no error
++ *    !=0:    the return value is the error code of the failure 
++ *
++ * Notes:
++ *    The supported timeframe for the coalesced interrupts ranges from
++ *    33.333us (30 IntsPerSec) down to 25us (40.000 IntsPerSec).
++ *    Any requested value that is not in this range will abort the request!
++ */
++static int setModerationParams(
++SK_AC                   *pAC,      /* pointer to adapter control context */
++int                      port,     /* the port of the selected adapter   */
++struct ethtool_coalesce *ecoalesc) /* IRQ moderation struct with params  */
++{
++      DIM_INFO  *Info             = &pAC->DynIrqModInfo;
++      int        PrevModeration   = Info->IntModTypeSelect;
++
++      Info->IntModTypeSelect = C_INT_MOD_NONE; /* initial default */
++
++      if ((ecoalesc->rx_coalesce_usecs) || (ecoalesc->tx_coalesce_usecs)) {
++              if (ecoalesc->rx_coalesce_usecs) {
++                      if ((ecoalesc->rx_coalesce_usecs < 25) ||
++                          (ecoalesc->rx_coalesce_usecs > 33333)) {
++                              return -EINVAL; 
++                      }
++              }
++              if (ecoalesc->tx_coalesce_usecs) {
++                      if ((ecoalesc->tx_coalesce_usecs < 25) ||
++                          (ecoalesc->tx_coalesce_usecs > 33333)) {
++                              return -EINVAL; 
++                      }
++              }
++              if (!CHIP_ID_YUKON_2(pAC)) {
++                      if ((Info->MaskIrqModeration == IRQ_MASK_SP_RX) ||
++                          (Info->MaskIrqModeration == IRQ_MASK_SP_TX) ||
++                          (Info->MaskIrqModeration == IRQ_MASK_RX_TX_SP)) {
++                              Info->MaskIrqModeration = IRQ_MASK_SP_ONLY;
++                      } 
++              }
++              Info->IntModTypeSelect = C_INT_MOD_STATIC;
++              if (ecoalesc->rx_coalesce_usecs) {
++                      Info->MaxModIntsPerSec = 
++                              1000000 / ecoalesc->rx_coalesce_usecs;
++                      if (!CHIP_ID_YUKON_2(pAC)) {
++                              if (Info->MaskIrqModeration == IRQ_MASK_TX_ONLY) {
++                                      Info->MaskIrqModeration = IRQ_MASK_TX_RX;
++                              } 
++                              if (Info->MaskIrqModeration == IRQ_MASK_SP_ONLY) {
++                                      Info->MaskIrqModeration = IRQ_MASK_SP_RX;
++                              } 
++                              if (Info->MaskIrqModeration == IRQ_MASK_SP_TX) {
++                                      Info->MaskIrqModeration = IRQ_MASK_RX_TX_SP;
++                              }
++                      } else {
++                              Info->MaskIrqModeration = Y2_IRQ_MASK;
++                      }
++              }
++              if (ecoalesc->tx_coalesce_usecs) {
++                      Info->MaxModIntsPerSec = 
++                              1000000 / ecoalesc->tx_coalesce_usecs;
++                      if (!CHIP_ID_YUKON_2(pAC)) {
++                              if (Info->MaskIrqModeration == IRQ_MASK_RX_ONLY) {
++                                      Info->MaskIrqModeration = IRQ_MASK_TX_RX;
++                              } 
++                              if (Info->MaskIrqModeration == IRQ_MASK_SP_ONLY) {
++                                      Info->MaskIrqModeration = IRQ_MASK_SP_TX;
++                              } 
++                              if (Info->MaskIrqModeration == IRQ_MASK_SP_RX) {
++                                      Info->MaskIrqModeration = IRQ_MASK_RX_TX_SP;
++                              }
++                      } else {
++                              Info->MaskIrqModeration = Y2_IRQ_MASK;
++                      }
++              }
++      }
++      if ((ecoalesc->rate_sample_interval)  ||
++          (ecoalesc->rx_coalesce_usecs_low) ||
++          (ecoalesc->tx_coalesce_usecs_low) ||
++          (ecoalesc->rx_coalesce_usecs_high)||
++          (ecoalesc->tx_coalesce_usecs_high)) {
++              if (ecoalesc->rate_sample_interval) {
++                      if ((ecoalesc->rate_sample_interval < 1) ||
++                          (ecoalesc->rate_sample_interval > 10)) {
++                              return -EINVAL; 
++                      }
++              }
++              if (ecoalesc->rx_coalesce_usecs_low) {
++                      if ((ecoalesc->rx_coalesce_usecs_low < 25) ||
++                          (ecoalesc->rx_coalesce_usecs_low > 33333)) {
++                              return -EINVAL; 
++                      }
++              }
++              if (ecoalesc->rx_coalesce_usecs_high) {
++                      if ((ecoalesc->rx_coalesce_usecs_high < 25) ||
++                          (ecoalesc->rx_coalesce_usecs_high > 33333)) {
++                              return -EINVAL; 
++                      }
++              }
++              if (ecoalesc->tx_coalesce_usecs_low) {
++                      if ((ecoalesc->tx_coalesce_usecs_low < 25) ||
++                          (ecoalesc->tx_coalesce_usecs_low > 33333)) {
++                              return -EINVAL; 
++                      }
++              }
++              if (ecoalesc->tx_coalesce_usecs_high) {
++                      if ((ecoalesc->tx_coalesce_usecs_high < 25) ||
++                          (ecoalesc->tx_coalesce_usecs_high > 33333)) {
++                              return -EINVAL; 
++                      }
++              }
++
++              Info->IntModTypeSelect = C_INT_MOD_DYNAMIC;
++              if (ecoalesc->rate_sample_interval) {
++                      Info->DynIrqModSampleInterval = 
++                              ecoalesc->rate_sample_interval; 
++              }
++              if (ecoalesc->rx_coalesce_usecs_low) {
++                      Info->MaxModIntsPerSecLowerLimit = 
++                              1000000 / ecoalesc->rx_coalesce_usecs_low;
++              }
++              if (ecoalesc->tx_coalesce_usecs_low) {
++                      Info->MaxModIntsPerSecLowerLimit = 
++                              1000000 / ecoalesc->tx_coalesce_usecs_low;
++              }
++              if (ecoalesc->rx_coalesce_usecs_high) {
++                      Info->MaxModIntsPerSecUpperLimit = 
++                              1000000 / ecoalesc->rx_coalesce_usecs_high;
++              }
++              if (ecoalesc->tx_coalesce_usecs_high) {
++                      Info->MaxModIntsPerSecUpperLimit = 
++                              1000000 / ecoalesc->tx_coalesce_usecs_high;
++              }
++      }
++
++      if ((PrevModeration         == C_INT_MOD_NONE) &&
++          (Info->IntModTypeSelect != C_INT_MOD_NONE)) {
++              SkDimEnableModerationIfNeeded(pAC);
++      }
++      if (PrevModeration != C_INT_MOD_NONE) {
++              SkDimDisableModeration(pAC, PrevModeration);
++              if (Info->IntModTypeSelect != C_INT_MOD_NONE) {
++                      SkDimEnableModerationIfNeeded(pAC);
++              }
++      }
++
++        return 0;
++}
++#endif
++
++#ifdef ETHTOOL_GWOL
++/*****************************************************************************
++ *
++ *    getWOLsettings - retrieves the WOL settings of the selected adapter
++ *
++ * Description:
++ *    All current WOL settings of a selected adapter are placed in the 
++ *    passed ethtool_wolinfo structure and are returned to the caller.
++ *
++ * Returns:   N/A
++ *
++ */
++static void getWOLsettings(
++SK_AC                  *pAC,  /* pointer to adapter control context  */
++int                     port, /* the port of the selected adapter    */
++struct ethtool_wolinfo *ewol) /* mandatory WOL structure for results */
++{
++      ewol->supported = pAC->WolInfo.SupportedWolOptions;
++      ewol->wolopts   = pAC->WolInfo.ConfiguredWolOptions;
++
++      return;
++}
++#endif
++
++#ifdef ETHTOOL_SWOL
++/*****************************************************************************
++ *
++ *    setWOLsettings - configures the WOL settings of a selected adapter
++ *
++ * Description:
++ *    The WOL settings of a selected adapter are configured regarding
++ *    the parameters in the passed ethtool_wolinfo structure.
++ *    Note that currently only wake on magic packet is supported!
++ *
++ * Returns:
++ *    ==0:    everything fine, no error
++ *    !=0:    the return value is the error code of the failure 
++ */
++static int setWOLsettings(
++SK_AC                  *pAC,  /* pointer to adapter control context */
++int                     port, /* the port of the selected adapter   */
++struct ethtool_wolinfo *ewol) /* WOL structure containing settings  */
++{
++      if (((ewol->wolopts & WAKE_MAGIC) == WAKE_MAGIC) || (ewol->wolopts == 0)) {
++              pAC->WolInfo.ConfiguredWolOptions = ewol->wolopts;
++              return 0;
++      }
++      return -EFAULT;
++}
++#endif
++
++#ifdef ETHTOOL_GDRVINFO
++/*****************************************************************************
++ *
++ *    getDriverInfo - returns generic driver and adapter information
++ *
++ * Description:
++ *    Generic driver information is returned via this function, such as
++ *    the name of the driver, its version and and firmware version.
++ *    In addition to this, the location of the selected adapter is 
++ *    returned as a bus info string (e.g. '01:05.0').
++ *    
++ * Returns:   N/A
++ *
++ */
++static void getDriverInfo(
++SK_AC                  *pAC,      /* pointer to adapter control context   */
++int                     port,     /* the port of the selected adapter     */
++struct ethtool_drvinfo *edrvinfo) /* mandatory info structure for results */
++{
++      char versionString[32];
++
++      snprintf(versionString, 32, "%s (%s)", VER_STRING, PATCHLEVEL);
++      strncpy(edrvinfo->driver, DRIVER_FILE_NAME , 32);
++      strncpy(edrvinfo->version, versionString , 32);
++      strncpy(edrvinfo->fw_version, "N/A", 32);
++      strncpy(edrvinfo->bus_info, pci_name(pAC->PciDev), 32);
++
++#ifdef  ETHTOOL_GSTATS
++      edrvinfo->n_stats = SK98LIN_STATS_LEN;
++#endif
++}
++#endif
++
++#ifdef ETHTOOL_PHYS_ID
++/*****************************************************************************
++ *
++ *    startLocateNIC - start the locate NIC feature of the elected adapter 
++ *
++ * Description:
++ *    This function is used if the user want to locate a particular NIC.
++ *    All LEDs are regularly switched on and off, so the NIC can easily
++ *    be identified.
++ *
++ * Returns:   
++ *    ==0:    everything fine, no error, locateNIC test was started
++ *    !=0:    one locateNIC test runs already
++ *
++ */
++static int startLocateNIC(
++SK_AC                *pAC,        /* pointer to adapter control context        */
++int                   port,       /* the port of the selected adapter          */
++struct ethtool_value *blinkSecs)  /* how long the LEDs should blink in seconds */
++{
++      struct SK_NET_DEVICE *pDev      = pAC->dev[port];
++      int                   OtherPort = (port) ? 0 : 1;
++      struct SK_NET_DEVICE *pOtherDev = pAC->dev[OtherPort];
++
++      if (isLocateNICrunning) {
++              return -EFAULT;
++      }
++      isLocateNICrunning = SK_TRUE;
++      currentPortIndex = port;
++      isDualNetCard = (pDev != pOtherDev) ? SK_TRUE : SK_FALSE;
++
++      if (netif_running(pAC->dev[port])) {
++              boardWasDown[0] = SK_FALSE;
++      } else {
++              (*pDev->open)(pDev);
++              boardWasDown[0] = SK_TRUE;
++      }
++
++      if (isDualNetCard) {
++              if (netif_running(pAC->dev[OtherPort])) {
++                      boardWasDown[1] = SK_FALSE;
++              } else {
++                      (*pOtherDev->open)(pOtherDev);
++                      boardWasDown[1] = SK_TRUE;
++              }
++      }
++
++      if ((blinkSecs->data < 1) || (blinkSecs->data > 30)) {
++              blinkSecs->data = 3; /* three seconds default */
++      }
++      nbrBlinkQuarterSeconds = 4*blinkSecs->data;
++
++      init_timer(&locateNICtimer);
++      locateNICtimer.function = toggleLeds;
++      locateNICtimer.data     = (unsigned long) pAC;
++      locateNICtimer.expires  = jiffies + HZ; /* initially 1sec */
++      add_timer(&locateNICtimer);
++
++      return 0;
++}
++
++/*****************************************************************************
++ *
++ *    toggleLeds - Changes the LED state of an adapter
++ *
++ * Description:
++ *    This function changes the current state of all LEDs of an adapter so
++ *    that it can be located by a user. If the requested time interval for
++ *    this test has elapsed, this function cleans up everything that was 
++ *    temporarily setup during the locate NIC test. This involves of course
++ *    also closing or opening any adapter so that the initial board state 
++ *    is recovered.
++ *
++ * Returns:   N/A
++ *
++ */
++static void toggleLeds(
++unsigned long ptr)  /* holds the pointer to adapter control context */
++{
++      SK_AC                *pAC       = (SK_AC *) ptr;
++      int                   port      = currentPortIndex;
++      SK_IOC                IoC       = pAC->IoBase;
++      struct SK_NET_DEVICE *pDev      = pAC->dev[port];
++      int                   OtherPort = (port) ? 0 : 1;
++      struct SK_NET_DEVICE *pOtherDev = pAC->dev[OtherPort];
++
++      SK_U16  YukLedOn = (PHY_M_LED_MO_DUP(MO_LED_ON)  |
++                          PHY_M_LED_MO_10(MO_LED_ON)   |
++                          PHY_M_LED_MO_100(MO_LED_ON)  |
++                          PHY_M_LED_MO_1000(MO_LED_ON) | 
++                          PHY_M_LED_MO_RX(MO_LED_ON));
++      SK_U16  YukLedOff = (PHY_M_LED_MO_DUP(MO_LED_OFF)  |
++                           PHY_M_LED_MO_10(MO_LED_OFF)   |
++                           PHY_M_LED_MO_100(MO_LED_OFF)  |
++                           PHY_M_LED_MO_1000(MO_LED_OFF) | 
++                           PHY_M_LED_MO_RX(MO_LED_OFF));
++
++      nbrBlinkQuarterSeconds--;
++      if (nbrBlinkQuarterSeconds <= 0) {
++              (*pDev->stop)(pDev);
++              if (isDualNetCard) {
++                      (*pOtherDev->stop)(pOtherDev);
++              }
++
++              if (!boardWasDown[0]) {
++                      (*pDev->open)(pDev);
++              }
++              if (isDualNetCard) {
++                      (*pOtherDev->open)(pOtherDev);
++              }
++              isDualNetCard      = SK_FALSE;
++              isLocateNICrunning = SK_FALSE;
++              return;
++      }
++
++      doSwitchLEDsOn = (doSwitchLEDsOn) ? SK_FALSE : SK_TRUE;
++      if (doSwitchLEDsOn) {
++              if (pAC->GIni.GIGenesis) {
++                      SK_OUT8(IoC,MR_ADDR(port,LNK_LED_REG),(SK_U8)SK_LNK_ON);
++                      SkGeYellowLED(pAC,IoC,LED_ON >> 1);
++                      SkGeXmitLED(pAC,IoC,MR_ADDR(port,RX_LED_INI),SK_LED_TST);
++                      if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM) {
++                              SkXmPhyWrite(pAC,IoC,port,PHY_BCOM_P_EXT_CTRL,PHY_B_PEC_LED_ON);
++                      } else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE) {
++                              SkXmPhyWrite(pAC,IoC,port,PHY_LONE_LED_CFG,0x0800);
++                      } else {
++                              SkGeXmitLED(pAC,IoC,MR_ADDR(port,TX_LED_INI),SK_LED_TST);
++                      }
++              } else {
++                      SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_CTRL,0);
++                      SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_OVER,YukLedOn);
++              }
++      } else {
++              if (pAC->GIni.GIGenesis) {
++                      SK_OUT8(IoC,MR_ADDR(port,LNK_LED_REG),(SK_U8)SK_LNK_OFF);
++                      SkGeYellowLED(pAC,IoC,LED_OFF >> 1);
++                      SkGeXmitLED(pAC,IoC,MR_ADDR(port,RX_LED_INI),SK_LED_DIS);
++                      if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM) {
++                              SkXmPhyWrite(pAC,IoC,port,PHY_BCOM_P_EXT_CTRL,PHY_B_PEC_LED_OFF);
++                      } else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE) {
++                              SkXmPhyWrite(pAC,IoC,port,PHY_LONE_LED_CFG,PHY_L_LC_LEDT);
++                      } else {
++                              SkGeXmitLED(pAC,IoC,MR_ADDR(port,TX_LED_INI),SK_LED_DIS);
++                      }
++              } else {
++                      SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_CTRL,0);
++                      SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_OVER,YukLedOff);
++              }
++      }
++
++      locateNICtimer.function = toggleLeds;
++      locateNICtimer.data     = (unsigned long) pAC;
++      locateNICtimer.expires  = jiffies + (HZ/4); /* 250ms */
++      add_timer(&locateNICtimer);
++} 
++#endif
++
++/*****************************************************************************
++ *
++ *    getPortNumber - evaluates the port number of an interface
++ *
++ * Description:
++ *    It may be that the current interface refers to one which is located
++ *    on a dual net adapter. Hence, this function will return the correct
++ *    port for further use.
++ *
++ * Returns:
++ *    the port number that corresponds to the selected adapter
++ *
++ */
++static int getPortNumber(
++struct net_device *netdev,  /* the pointer to netdev structure       */
++struct ifreq      *ifr)     /* what interface the request refers to? */
++{
++      DEV_NET *pNet = (DEV_NET*) netdev->priv;
++      SK_AC   *pAC  = pNet->pAC;
++
++      if (pAC->dev[1] != pAC->dev[0]) {
++              if (!strcmp(pAC->dev[1]->name, ifr->ifr_name)) {
++                      return 1; /* port index 1 */
++              }
++      }
++      return 0;
++}
++
++/*******************************************************************************
++ *
++ * End of file
++ *
++ ******************************************************************************/
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skge.c linux-2.6.9.new/drivers/net/sk98lin/skge.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skge.c 2006-08-01 06:23:10.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skge.c 2006-12-07 14:35:03.000000000 +0800
+@@ -1,32 +1,26 @@
+ /******************************************************************************
+  *
+- * Name:      skge.c
+- * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.45 $
+- * Date:              $Date: 2004/02/12 14:41:02 $
+- * Purpose:   The main driver source module
++ * Name:        skge.c
++ * Project:     GEnesis, PCI Gigabit Ethernet Adapter
++ * Version:     $Revision: 1.60.2.51 $
++ * Date:        $Date: 2005/06/17 14:09:14 $
++ * Purpose:     The main driver source module
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect GmbH.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2005 Marvell.
+  *
+  *    Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet 
+  *      Server Adapters.
+  *
+- *    Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
+- *    SysKonnects GEnesis Solaris driver
+- *    Author: Christoph Goos (cgoos@syskonnect.de)
+- *            Mirko Lindner (mlindner@syskonnect.de)
++ *    Author: Mirko Lindner (mlindner@syskonnect.de)
++ *            Ralph Roesler (rroesler@syskonnect.de)
+  *
+  *    Address all question to: linux@syskonnect.de
+  *
+- *    The technical manual for the adapters is available from SysKonnect's
+- *    web pages: www.syskonnect.com
+- *    Goto "Support" and search Knowledge Base for "manual".
+- *    
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+  *    the Free Software Foundation; either version 2 of the License, or
+@@ -38,71 +32,33 @@
+ /******************************************************************************
+  *
+- * Possible compiler options (#define xxx / -Dxxx):
+- *
+- *    debugging can be enable by changing SK_DEBUG_CHKMOD and
+- *    SK_DEBUG_CHKCAT in makefile (described there).
+- *
+- ******************************************************************************/
+-
+-/******************************************************************************
+- *
+  * Description:
+  *
+- *    This is the main module of the Linux GE driver.
+- *    
+- *    All source files except skge.c, skdrv1st.h, skdrv2nd.h and sktypes.h
+- *    are part of SysKonnect's COMMON MODULES for the SK-98xx adapters.
+- *    Those are used for drivers on multiple OS', so some thing may seem
+- *    unnecessary complicated on Linux. Please do not try to 'clean up'
+- *    them without VERY good reasons, because this will make it more
+- *    difficult to keep the Linux driver in synchronisation with the
+- *    other versions.
+- *
+- * Include file hierarchy:
+- *
+- *    <linux/module.h>
+- *
+- *    "h/skdrv1st.h"
+- *            <linux/types.h>
+- *            <linux/kernel.h>
+- *            <linux/string.h>
+- *            <linux/errno.h>
+- *            <linux/ioport.h>
+- *            <linux/slab.h>
+- *            <linux/interrupt.h>
+- *            <linux/pci.h>
+- *            <asm/byteorder.h>
+- *            <asm/bitops.h>
+- *            <asm/io.h>
+- *            <linux/netdevice.h>
+- *            <linux/etherdevice.h>
+- *            <linux/skbuff.h>
+- *        those three depending on kernel version used:
+- *            <linux/bios32.h>
+- *            <linux/init.h>
+- *            <asm/uaccess.h>
+- *            <net/checksum.h>
+- *
+- *            "h/skerror.h"
+- *            "h/skdebug.h"
+- *            "h/sktypes.h"
+- *            "h/lm80.h"
+- *            "h/xmac_ii.h"
+- *
+- *      "h/skdrv2nd.h"
+- *            "h/skqueue.h"
+- *            "h/skgehwt.h"
+- *            "h/sktimer.h"
+- *            "h/ski2c.h"
+- *            "h/skgepnmi.h"
+- *            "h/skvpd.h"
+- *            "h/skgehw.h"
+- *            "h/skgeinit.h"
+- *            "h/skaddr.h"
+- *            "h/skgesirq.h"
+- *            "h/skcsum.h"
+- *            "h/skrlmt.h"
++ *    All source files in this sk98lin directory except of the sk98lin 
++ *    Linux specific files
++ *
++ *            - skdim.c
++ *            - skethtool.c
++ *            - skge.c
++ *            - skproc.c
++ *            - sky2.c
++ *            - Makefile
++ *            - h/skdrv1st.h
++ *            - h/skdrv2nd.h
++ *            - h/sktypes.h
++ *            - h/skversion.h
++ *
++ *    are part of SysKonnect's common modules for the SK-9xxx adapters.
++ *
++ *    Those common module files which are not Linux specific are used to 
++ *    build drivers on different OS' (e.g. Windows, MAC OS) so that those
++ *    drivers are based on the same set of files
++ *
++ *    At a first glance, this seems to complicate things unnescessarily on 
++ *    Linux, but please do not try to 'clean up' them without VERY good 
++ *    reasons, because this will make it more difficult to keep the sk98lin
++ *    driver for Linux in synchronisation with the other drivers running on
++ *    other operating systems.
+  *
+  ******************************************************************************/
+@@ -110,11 +66,19 @@
+ #include      <linux/module.h>
+ #include      <linux/init.h>
++#include      <linux/ethtool.h>
++
++#ifdef CONFIG_PROC_FS
+ #include      <linux/proc_fs.h>
++#endif
+ #include      "h/skdrv1st.h"
+ #include      "h/skdrv2nd.h"
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
++#include      <linux/moduleparam.h>
++#endif
++
+ /*******************************************************************************
+  *
+  * Defines
+@@ -124,62 +88,14 @@
+ /* for debuging on x86 only */
+ /* #define BREAKPOINT() asm(" int $3"); */
+-/* use the transmit hw checksum driver functionality */
+-#define USE_SK_TX_CHECKSUM
+-
+-/* use the receive hw checksum driver functionality */
+-#define USE_SK_RX_CHECKSUM
+-
+-/* use the scatter-gather functionality with sendfile() */
+-#define SK_ZEROCOPY
+-
+-/* use of a transmit complete interrupt */
+-#define USE_TX_COMPLETE
+-
+-/*
+- * threshold for copying small receive frames
+- * set to 0 to avoid copying, set to 9001 to copy all frames
+- */
+-#define SK_COPY_THRESHOLD     50
+-
+-/* number of adapters that can be configured via command line params */
+-#define SK_MAX_CARD_PARAM     16
+-
+-
+-
+-/*
+- * use those defines for a compile-in version of the driver instead
+- * of command line parameters
+- */
+-// #define LINK_SPEED_A       {"Auto", }
+-// #define LINK_SPEED_B       {"Auto", }
+-// #define AUTO_NEG_A {"Sense", }
+-// #define AUTO_NEG_B {"Sense", }
+-// #define DUP_CAP_A  {"Both", }
+-// #define DUP_CAP_B  {"Both", }
+-// #define FLOW_CTRL_A        {"SymOrRem", }
+-// #define FLOW_CTRL_B        {"SymOrRem", }
+-// #define ROLE_A     {"Auto", }
+-// #define ROLE_B     {"Auto", }
+-// #define PREF_PORT  {"A", }
+-// #define CON_TYPE   {"Auto", }
+-// #define RLMT_MODE  {"CheckLinkState", }
+-
+-#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
+-#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
+-#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)
+-
+ /* Set blink mode*/
+ #define OEM_CONFIG_VALUE (    SK_ACT_LED_BLINK | \
+                               SK_DUP_LED_NORMAL | \
+                               SK_LED_LINK100_ON)
+-
+-/* Isr return value */
+-#define SkIsrRetVar   irqreturn_t
+-#define SkIsrRetNone  IRQ_NONE
+-#define SkIsrRetHandled       IRQ_HANDLED
++#define CLEAR_AND_START_RX(Port) SK_OUT8(pAC->IoBase, RxQueueAddr[(Port)]+Q_CSR, CSR_START | CSR_IRQ_CL_F)
++#define CLEAR_TX_IRQ(Port,Prio) SK_OUT8(pAC->IoBase, TxQueueAddr[(Port)][(Prio)]+Q_CSR, CSR_IRQ_CL_F)
+ /*******************************************************************************
+@@ -188,12 +104,23 @@
+  *
+  ******************************************************************************/
++static int    __devinit sk98lin_init_device(struct pci_dev *pdev, const struct pci_device_id *ent);
++static void   sk98lin_remove_device(struct pci_dev *pdev);
++#ifdef CONFIG_PM
++static int    sk98lin_suspend(struct pci_dev *pdev, u32 state);
++static int    sk98lin_resume(struct pci_dev *pdev);
++static void   SkEnableWOMagicPacket(SK_AC *pAC, SK_IOC IoC, SK_MAC_ADDR MacAddr);
++#endif
++#ifdef Y2_RECOVERY
++static void   SkGeHandleKernelTimer(unsigned long ptr);
++void          SkGeCheckTimer(DEV_NET *pNet);
++#endif
+ static void   FreeResources(struct SK_NET_DEVICE *dev);
+ static int    SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC);
+ static SK_BOOL        BoardAllocMem(SK_AC *pAC);
+ static void   BoardFreeMem(SK_AC *pAC);
+ static void   BoardInitMem(SK_AC *pAC);
+-static void   SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL);
++static void   SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, int*, SK_BOOL);
+ static SkIsrRetVar    SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);
+ static SkIsrRetVar    SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);
+ static int    SkGeOpen(struct SK_NET_DEVICE *dev);
+@@ -209,24 +136,37 @@
+ static void   FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
+ static void   FillRxRing(SK_AC*, RX_PORT*);
+ static SK_BOOL        FillRxDescriptor(SK_AC*, RX_PORT*);
++#ifdef CONFIG_SK98LIN_NAPI
++static int    SkGePoll(struct net_device *dev, int *budget);
++static void   ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL, int*, int);
++#else
+ static void   ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL);
+-static void   ClearAndStartRx(SK_AC*, int);
+-static void   ClearTxIrq(SK_AC*, int, int);
++#endif
++#ifdef SK_POLL_CONTROLLER
++static void   SkGeNetPoll(struct SK_NET_DEVICE *dev);
++#endif
+ static void   ClearRxRing(SK_AC*, RX_PORT*);
+ static void   ClearTxRing(SK_AC*, TX_PORT*);
+ static int    SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu);
+ static void   PortReInitBmu(SK_AC*, int);
+ static int    SkGeIocMib(DEV_NET*, unsigned int, int);
+ static int    SkGeInitPCI(SK_AC *pAC);
+-static void   StartDrvCleanupTimer(SK_AC *pAC);
+-static void   StopDrvCleanupTimer(SK_AC *pAC);
+-static int    XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
+-
+-#ifdef SK_DIAG_SUPPORT
+ static SK_U32   ParseDeviceNbrFromSlotName(const char *SlotName);
+ static int      SkDrvInitAdapter(SK_AC *pAC, int devNbr);
+ static int      SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
+-#endif
++extern void   SkLocalEventQueue(      SK_AC *pAC,
++                                      SK_U32 Class,
++                                      SK_U32 Event,
++                                      SK_U32 Param1,
++                                      SK_U32 Param2,
++                                      SK_BOOL Flag);
++extern void   SkLocalEventQueue64(    SK_AC *pAC,
++                                      SK_U32 Class,
++                                      SK_U32 Event,
++                                      SK_U64 Param,
++                                      SK_BOOL Flag);
++
++static int    XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
+ /*******************************************************************************
+  *
+@@ -234,17 +174,33 @@
+  *
+  ******************************************************************************/
+-#ifdef CONFIG_PROC_FS
+-static const char     SK_Root_Dir_entry[] = "sk98lin";
+-static struct         proc_dir_entry *pSkRootDir;
+-extern struct file_operations sk_proc_fops;
++extern SK_BOOL SkY2AllocateResources(SK_AC *pAC);
++extern void SkY2FreeResources(SK_AC *pAC);
++extern void SkY2AllocateRxBuffers(SK_AC *pAC,SK_IOC IoC,int Port);
++extern void SkY2FreeRxBuffers(SK_AC *pAC,SK_IOC IoC,int Port);
++extern void SkY2FreeTxBuffers(SK_AC *pAC,SK_IOC IoC,int Port);
++extern SkIsrRetVar SkY2Isr(int irq,void *dev_id,struct pt_regs *ptregs);
++extern int SkY2Xmit(struct sk_buff *skb,struct SK_NET_DEVICE *dev);
++extern void SkY2PortStop(SK_AC *pAC,SK_IOC IoC,int Port,int Dir,int RstMode);
++extern void SkY2PortStart(SK_AC *pAC,SK_IOC IoC,int Port);
++extern int SkY2RlmtSend(SK_AC *pAC,int PortNr,struct sk_buff *pMessage);
++extern void SkY2RestartStatusUnit(SK_AC *pAC);
++#ifdef CONFIG_SK98LIN_NAPI
++extern int SkY2Poll(struct net_device *dev, int *budget);
+ #endif
+ extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);        
+-extern void SkDimDisplayModerationSettings(SK_AC *pAC);
+ extern void SkDimStartModerationTimer(SK_AC *pAC);
+ extern void SkDimModerate(SK_AC *pAC);
++extern int SkEthIoctl(struct net_device *netdev, struct ifreq *ifr);
++
++#ifdef CONFIG_PROC_FS
++static const char     SK_Root_Dir_entry[] = "sk98lin";
++static struct         proc_dir_entry *pSkRootDir;
++extern struct file_operations sk_proc_fops;
++#endif
++
+ #ifdef DEBUG
+ static void   DumpMsg(struct sk_buff*, char*);
+ static void   DumpData(char*, int);
+@@ -252,12 +208,424 @@
+ #endif
+ /* global variables *********************************************************/
++static const char *BootString = BOOT_STRING;
+ struct SK_NET_DEVICE *SkGeRootDev = NULL;
+ static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
+ /* local variables **********************************************************/
+ static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
+ static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
++static int sk98lin_max_boards_found = 0;
++
++#ifdef CONFIG_PROC_FS
++static struct proc_dir_entry  *pSkRootDir;
++#endif
++
++
++
++static struct pci_device_id sk98lin_pci_tbl[] __devinitdata = {
++/*    { pci_vendor_id, pci_device_id, * SAMPLE ENTRY! *
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, */
++      { 0x10b7, 0x1700, /* 3Com (10b7), Gigabit Ethernet Adapter */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x10b7, 0x80eb, /* 3Com (10b7), 3Com 3C940B Gigabit LOM Ethernet Adapter */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x1148, 0x4300, /* SysKonnect (1148), SK-98xx Gigabit Ethernet Server Adapter */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x1148, 0x4320, /* SysKonnect (1148), SK-98xx V2.0 Gigabit Ethernet Adapter */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x1148, 0x9000, /* SysKonnect (1148), SK-9Sxx 10/100/1000Base-T Server Adapter  */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x1148, 0x9E00, /* SysKonnect (1148), SK-9Exx 10/100/1000Base-T Adapter */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x1186, 0x4b00, /* D-Link (1186), Gigabit Ethernet Adapter */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x1186, 0x4b01, /* D-Link (1186), Gigabit Ethernet Adapter */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x1186, 0x4c00, /* D-Link (1186), Gigabit Ethernet Adapter */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x4320, /* Marvell (11ab), Gigabit Ethernet Controller */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x4340, /* Marvell (11ab), Gigabit Ethernet Controller  */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x4341, /* Marvell (11ab), Gigabit Ethernet Controller  */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x4342, /* Marvell (11ab), Gigabit Ethernet Controller  */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x4343, /* Marvell (11ab), Gigabit Ethernet Controller  */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x4344, /* Marvell (11ab), Gigabit Ethernet Controller  */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x4345, /* Marvell (11ab), Gigabit Ethernet Controller  */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x4346, /* Marvell (11ab), Gigabit Ethernet Controller  */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x4347, /* Marvell (11ab), Gigabit Ethernet Controller  */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x4350, /* Marvell (11ab), Fast Ethernet Controller */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x4351, /* Marvell (11ab), Fast Ethernet Controller */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x4360, /* Marvell (11ab), Gigabit Ethernet Controller */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x4361, /* Marvell (11ab), Gigabit Ethernet Controller */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x4362, /* Marvell (11ab), Gigabit Ethernet Controller */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x11ab, 0x5005, /* Marvell (11ab), Belkin */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x1371, 0x434e, /* CNet (1371), GigaCard Network Adapter */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x1737, 0x1032, /* Linksys (1737), Gigabit Network Adapter */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0x1737, 0x1064, /* Linksys (1737), Gigabit Network Adapter */
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { 0, }
++};
++
++MODULE_DEVICE_TABLE(pci, sk98lin_pci_tbl);
++
++static struct pci_driver sk98lin_driver = {
++      .name           = DRIVER_FILE_NAME,
++      .id_table       = sk98lin_pci_tbl,
++      .probe          = sk98lin_init_device,
++      .remove         = __devexit_p(sk98lin_remove_device),
++#ifdef CONFIG_PM
++      .suspend        = sk98lin_suspend,
++      .resume         = sk98lin_resume
++#endif
++};
++
++
++/*****************************************************************************
++ *
++ *    sk98lin_init_device - initialize the adapter
++ *
++ * Description:
++ *    This function initializes the adapter. Resources for
++ *    the adapter are allocated and the adapter is brought into Init 1
++ *    state.
++ *
++ * Returns:
++ *    0, if everything is ok
++ *    !=0, on error
++ */
++static int __devinit sk98lin_init_device(struct pci_dev *pdev,
++                                const struct pci_device_id *ent)
++
++{
++      static SK_BOOL          sk98lin_boot_string = SK_FALSE;
++      static SK_BOOL          sk98lin_proc_entry = SK_FALSE;
++      static int              sk98lin_boards_found = 0;
++      SK_AC                   *pAC;
++      DEV_NET                 *pNet = NULL;
++      struct SK_NET_DEVICE *dev = NULL;
++      int                     retval;
++#ifdef CONFIG_PROC_FS
++      struct proc_dir_entry   *pProcFile;
++#endif
++
++      retval = pci_enable_device(pdev);
++      if (retval) {
++              printk(KERN_ERR "Cannot enable PCI device, "
++                      "aborting.\n");
++              return retval;
++      }
++
++      dev = NULL;
++      pNet = NULL;
++
++
++      /* INSERT * We have to find the power-management capabilities */
++      /* Find power-management capability. */
++
++
++
++      /* Configure DMA attributes. */
++      retval = pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL);
++      if (!retval) {
++              retval = pci_set_dma_mask(pdev, (u64) 0xffffffff);
++              if (retval)
++                      return retval;
++      } else {
++              return retval;
++      }
++
++
++      if ((dev = alloc_etherdev(sizeof(DEV_NET))) == NULL) {
++              printk(KERN_ERR "Unable to allocate etherdev "
++                      "structure!\n");
++              return -ENODEV;
++      }
++
++      pNet = dev->priv;
++      pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
++      if (pNet->pAC == NULL){
++              free_netdev(dev);
++              printk(KERN_ERR "Unable to allocate adapter "
++                      "structure!\n");
++              return -ENODEV;
++      }
++
++
++      /* Print message */
++      if (!sk98lin_boot_string) {
++              /* set display flag to TRUE so that */
++              /* we only display this string ONCE */
++              sk98lin_boot_string = SK_TRUE;
++              printk("%s\n", BootString);
++      }
++
++      memset(pNet->pAC, 0, sizeof(SK_AC));
++      pAC = pNet->pAC;
++      pAC->PciDev = pdev;
++      pAC->PciDevId = pdev->device;
++      pAC->dev[0] = dev;
++      pAC->dev[1] = dev;
++      sprintf(pAC->Name, "SysKonnect SK-98xx");
++      pAC->CheckQueue = SK_FALSE;
++
++      dev->irq = pdev->irq;
++      retval = SkGeInitPCI(pAC);
++      if (retval) {
++              printk("SKGE: PCI setup failed: %i\n", retval);
++              free_netdev(dev);
++              return -ENODEV;
++      }
++
++      SET_MODULE_OWNER(dev);
++
++      dev->open               =  &SkGeOpen;
++      dev->stop               =  &SkGeClose;
++      dev->get_stats          =  &SkGeStats;
++      dev->set_multicast_list =  &SkGeSetRxMode;
++      dev->set_mac_address    =  &SkGeSetMacAddr;
++      dev->do_ioctl           =  &SkGeIoctl;
++      dev->change_mtu         =  &SkGeChangeMtu;
++      dev->flags              &= ~IFF_RUNNING;
++#ifdef SK_POLL_CONTROLLER
++      dev->poll_controller    =  SkGeNetPoll;
++#endif
++      SET_NETDEV_DEV(dev, &pdev->dev);
++
++      pAC->Index = sk98lin_boards_found;
++
++      if (SkGeBoardInit(dev, pAC)) {
++              free_netdev(dev);
++              return -ENODEV;
++      } else {
++              ProductStr(pAC);
++      }
++
++      /* shifter to later moment in time... */
++      if (CHIP_ID_YUKON_2(pAC)) {
++              dev->hard_start_xmit =  &SkY2Xmit;
++#ifdef CONFIG_SK98LIN_NAPI
++              dev->poll =  &SkY2Poll;
++              dev->weight = 64;
++#endif
++      } else {
++              dev->hard_start_xmit =  &SkGeXmit;
++#ifdef CONFIG_SK98LIN_NAPI
++              dev->poll =  &SkGePoll;
++              dev->weight = 64;
++#endif
++      }
++
++#ifdef NETIF_F_TSO
++#ifdef USE_SK_TSO_FEATURE     
++      if (CHIP_ID_YUKON_2(pAC)) {
++              dev->features |= NETIF_F_TSO;
++      }
++#endif
++#endif
++#ifdef CONFIG_SK98LIN_ZEROCOPY
++      if (pAC->GIni.GIChipId != CHIP_ID_GENESIS)
++              dev->features |= NETIF_F_SG;
++#endif
++#ifdef USE_SK_TX_CHECKSUM
++      if (pAC->GIni.GIChipId != CHIP_ID_GENESIS)
++              dev->features |= NETIF_F_IP_CSUM;
++#endif
++#ifdef USE_SK_RX_CHECKSUM
++      pAC->RxPort[0].UseRxCsum = SK_TRUE;
++      if (pAC->GIni.GIMacsFound == 2 ) {
++              pAC->RxPort[1].UseRxCsum = SK_TRUE;
++      }
++#endif
++
++      /* Save the hardware revision */
++      pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
++              (pAC->GIni.GIPciHwRev & 0x0F);
++
++      /* Set driver globals */
++      pAC->Pnmi.pDriverFileName    = DRIVER_FILE_NAME;
++      pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE;
++
++      SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA));
++      SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), 
++                      sizeof(SK_PNMI_STRUCT_DATA));
++
++      /* Register net device */
++      retval = register_netdev(dev);
++      if (retval) {
++              printk(KERN_ERR "SKGE: Could not register device.\n");
++              FreeResources(dev);
++              free_netdev(dev);
++              return retval;
++      }
++
++      /* Save initial device name */
++      strcpy(pNet->InitialDevName, dev->name);
++
++      /* Set network to off */
++      netif_stop_queue(dev);
++      netif_carrier_off(dev);
++
++      /* Print adapter specific string from vpd and config settings */
++      printk("%s: %s\n", pNet->InitialDevName, pAC->DeviceStr);
++      printk("      PrefPort:%c  RlmtMode:%s\n",
++              'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
++              (pAC->RlmtMode==0)  ? "Check Link State" :
++              ((pAC->RlmtMode==1) ? "Check Link State" :
++              ((pAC->RlmtMode==3) ? "Check Local Port" :
++              ((pAC->RlmtMode==7) ? "Check Segmentation" :
++              ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
++
++      SkGeYellowLED(pAC, pAC->IoBase, 1);
++
++      memcpy((caddr_t) &dev->dev_addr,
++              (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
++
++      /* First adapter... Create proc and print message */
++#ifdef CONFIG_PROC_FS
++      if (!sk98lin_proc_entry) {
++              sk98lin_proc_entry = SK_TRUE;
++              SK_MEMCPY(&SK_Root_Dir_entry, BootString,
++                      sizeof(SK_Root_Dir_entry) - 1);
++
++              /*Create proc (directory)*/
++              if(!pSkRootDir) {
++                      pSkRootDir = proc_mkdir(SK_Root_Dir_entry, proc_net);
++                      if (!pSkRootDir) {
++                              printk(KERN_WARNING "%s: Unable to create /proc/net/%s",
++                                      dev->name, SK_Root_Dir_entry);
++                      } else {
++                              pSkRootDir->owner = THIS_MODULE;
++                      }
++              }
++      }
++
++      /* Create proc file */
++      if (pSkRootDir && 
++              (pProcFile = create_proc_entry(pNet->InitialDevName, S_IRUGO,
++                      pSkRootDir))) {
++              pProcFile->proc_fops = &sk_proc_fops;
++              pProcFile->data      = dev;
++      }
++
++#endif
++
++      pNet->PortNr = 0;
++      pNet->NetNr  = 0;
++
++      sk98lin_boards_found++;
++      pci_set_drvdata(pdev, dev);
++
++      /* More then one port found */
++      if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
++              if ((dev = alloc_etherdev(sizeof(DEV_NET))) == 0) {
++                      printk(KERN_ERR "Unable to allocate etherdev "
++                              "structure!\n");
++                      return -ENODEV;
++              }
++
++              pAC->dev[1]   = dev;
++              pNet          = dev->priv;
++              pNet->PortNr  = 1;
++              pNet->NetNr   = 1;
++              pNet->pAC     = pAC;
++
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      dev->hard_start_xmit = &SkY2Xmit;
++#ifdef CONFIG_SK98LIN_NAPI
++                      dev->poll =  &SkY2Poll;
++                      dev->weight = 64;
++#endif
++              } else {
++                      dev->hard_start_xmit = &SkGeXmit;
++#ifdef CONFIG_SK98LIN_NAPI
++                      dev->poll =  &SkGePoll;
++                      dev->weight = 64;
++#endif
++              }
++              dev->open               = &SkGeOpen;
++              dev->stop               = &SkGeClose;
++              dev->get_stats          = &SkGeStats;
++              dev->set_multicast_list = &SkGeSetRxMode;
++              dev->set_mac_address    = &SkGeSetMacAddr;
++              dev->do_ioctl           = &SkGeIoctl;
++              dev->change_mtu         = &SkGeChangeMtu;
++              dev->flags             &= ~IFF_RUNNING;
++#ifdef SK_POLL_CONTROLLER
++              dev->poll_controller    = SkGeNetPoll;
++#endif
++
++#ifdef NETIF_F_TSO
++#ifdef USE_SK_TSO_FEATURE     
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      dev->features |= NETIF_F_TSO;
++              }
++#endif
++#endif
++#ifdef CONFIG_SK98LIN_ZEROCOPY
++              /* Don't handle if Genesis chipset */
++              if (pAC->GIni.GIChipId != CHIP_ID_GENESIS)
++                      dev->features |= NETIF_F_SG;
++#endif
++#ifdef USE_SK_TX_CHECKSUM
++              /* Don't handle if Genesis chipset */
++              if (pAC->GIni.GIChipId != CHIP_ID_GENESIS)
++                      dev->features |= NETIF_F_IP_CSUM;
++#endif
++
++              if (register_netdev(dev)) {
++                      printk(KERN_ERR "SKGE: Could not register device.\n");
++                      free_netdev(dev);
++                      pAC->dev[1] = pAC->dev[0];
++              } else {
++
++              /* Save initial device name */
++              strcpy(pNet->InitialDevName, dev->name);
++
++              /* Set network to off */
++              netif_stop_queue(dev);
++              netif_carrier_off(dev);
++
++
++#ifdef CONFIG_PROC_FS
++              if (pSkRootDir 
++                  && (pProcFile = create_proc_entry(pNet->InitialDevName, 
++                                              S_IRUGO, pSkRootDir))) {
++                      pProcFile->proc_fops = &sk_proc_fops;
++                      pProcFile->data      = dev;
++              }
++#endif
++
++              memcpy((caddr_t) &dev->dev_addr,
++              (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
++      
++              printk("%s: %s\n", pNet->InitialDevName, pAC->DeviceStr);
++              printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
++              }
++      }
++
++      pAC->Index = sk98lin_boards_found;
++      sk98lin_max_boards_found = sk98lin_boards_found;
++      return 0;
++}
++
++
+ /*****************************************************************************
+  *
+@@ -282,7 +650,7 @@
+       dev->mem_start = pci_resource_start (pdev, 0);
+       pci_set_master(pdev);
+-      if (pci_request_regions(pdev, pAC->Name) != 0) {
++      if (pci_request_regions(pdev, DRIVER_FILE_NAME) != 0) {
+               retval = 2;
+               goto out_disable;
+       }
+@@ -298,26 +666,406 @@
+               our2 |= PCI_REV_DESC;
+               SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
+       }
+-#endif
++#endif
++
++      /*
++       * Remap the regs into kernel space.
++       */
++      pAC->IoBase = (char*)ioremap_nocache(dev->mem_start, 0x4000);
++
++      if (!pAC->IoBase){
++              retval = 3;
++              goto out_release;
++      }
++
++      return 0;
++
++ out_release:
++      pci_release_regions(pdev);
++ out_disable:
++      pci_disable_device(pdev);
++      return retval;
++}
++
++#ifdef Y2_RECOVERY
++/*****************************************************************************
++ *
++ *    SkGeHandleKernelTimer - Handle the kernel timer requests
++ *
++ * Description:
++ *    If the requested time interval for the timer has elapsed, 
++ *    this function checks the link state.
++ *
++ * Returns:   N/A
++ *
++ */
++static void SkGeHandleKernelTimer(
++unsigned long ptr)  /* holds the pointer to adapter control context */
++{
++      DEV_NET         *pNet = (DEV_NET*) ptr;
++
++      pNet->TimerExpired = SK_TRUE;
++}
++
++/*****************************************************************************
++ *
++ *    sk98lin_check_timer - Resume the the card
++ *
++ * Description:
++ *    This function checks the kernel timer
++ *
++ * Returns: N/A
++ *    
++ */
++void SkGeCheckTimer(
++DEV_NET *pNet)  /* holds the pointer to adapter control context */
++{
++      SK_AC           *pAC = pNet->pAC;
++      SK_BOOL         StartTimer = SK_TRUE;
++#ifdef Y2_RX_CHECK
++      SK_BOOL         ZeroRegister = SK_FALSE;
++      SK_U8           FifoReadPointer;
++      SK_U8           FifoReadLevel;
++      SK_U32          BmuStateMachine;
++#endif
++
++      if (pNet->InRecover)
++              return;
++
++#define TXPORT pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]
++#define RXPORT pAC->RxPort[pNet->PortNr]
++
++      if (    (CHIP_ID_YUKON_2(pAC)) &&
++              (netif_running(pAC->dev[pNet->PortNr]))) {
++              
++#ifdef Y2_RX_CHECK
++              /* Check the receiver only if link is up*/
++              if (    (netif_carrier_ok(pAC->dev[pNet->PortNr])) &&
++                      (pNet->LastJiffies == pAC->dev[pNet->PortNr]->last_rx)) {
++
++                      /* Nothing received */
++                      /* Get the register values */
++                      SK_IN8(pAC->IoBase, 0x0448, &FifoReadPointer);
++                      SK_IN8(pAC->IoBase, 0x044a, &FifoReadLevel);
++                      SK_IN32(pAC->IoBase, 0x043c, &BmuStateMachine);
++
++                      /* Check the register values */
++                      if      ((pNet->FifoReadPointer != FifoReadPointer) ||
++                              (pNet->FifoReadLevel != FifoReadLevel)      ||
++                              (pNet->BmuStateMachine != BmuStateMachine)) {
++
++                              /* Check the values */
++                              if      ((pNet->FifoReadPointer) ||
++                                      (pNet->FifoReadLevel)   ||
++                                      (pNet->BmuStateMachine)) {
++
++                                      /* Check the jiffies again */
++                                      if (pNet->LastJiffies == 
++                                              pAC->dev[pNet->PortNr]->last_rx) {
++                                              /* Still nothing received */
++                                              SkLocalEventQueue(pAC, SKGE_DRV, 
++                                                      SK_DRV_RECOVER,pNet->PortNr,-1,SK_FALSE);
++                                      } else {
++                                              ZeroRegister = SK_TRUE;
++                                      }
++                              } else {
++                                      pNet->FifoReadPointer = FifoReadPointer;
++                                      pNet->FifoReadLevel = FifoReadLevel;
++                                      pNet->BmuStateMachine = BmuStateMachine;
++                                      
++                              }
++                      } else {
++                              if ((FifoReadLevel != 0) && 
++                                      (FifoReadPointer > 0)) {
++                                      /* Check the jiffies again */
++                                      if (pNet->LastJiffies == 
++                                              pAC->dev[pNet->PortNr]->last_rx) {
++                                              /* Still nothing received */
++                                              SkLocalEventQueue(pAC, SKGE_DRV, 
++                                                      SK_DRV_RECOVER,pNet->PortNr,-1,SK_FALSE);
++                                      } else {
++                                              ZeroRegister = SK_TRUE;
++                                      }
++                              } else {
++                                      ZeroRegister = SK_TRUE;
++                              }
++                      }
++              } else {
++                      /* Clear the values */
++                      if      ((pNet->FifoReadPointer) ||
++                              (pNet->FifoReadLevel)   ||
++                              (pNet->BmuStateMachine)) {
++                                      ZeroRegister = SK_TRUE;
++                      }
++                      pNet->LastJiffies = 
++                              pAC->dev[pNet->PortNr]->last_rx;
++              }
++
++              /* Clear the register values */
++              if (ZeroRegister) {
++                      pNet->FifoReadPointer = 0; 
++                      pNet->FifoReadLevel   = 0;
++                      pNet->BmuStateMachine = 0;
++              }
++#endif
++
++              /* Checkthe transmitter */
++              if (!(IS_Q_EMPTY(&TXPORT.TxAQ_working))) {
++                      if (TXPORT.LastDone != TXPORT.TxALET.Done) {
++                              TXPORT.LastDone = TXPORT.TxALET.Done;
++                              pNet->TransmitTimeoutTimer = 0;
++                      } else {
++                              pNet->TransmitTimeoutTimer++;
++                              if (pNet->TransmitTimeoutTimer >= 10) {
++                                      pNet->TransmitTimeoutTimer = 0;
++#ifdef CHECK_TRANSMIT_TIMEOUT
++                                      StartTimer =  SK_FALSE;
++                                      SkLocalEventQueue(pAC, SKGE_DRV, 
++                                              SK_DRV_RECOVER,pNet->PortNr,-1,SK_FALSE);
++#endif
++                              }
++                      } 
++              } 
++
++#ifdef CHECK_TRANSMIT_TIMEOUT
++//            if (!timer_pending(&pNet->KernelTimer)) {
++                      pNet->KernelTimer.expires = jiffies + (HZ/4); /* 250ms */
++                      add_timer(&pNet->KernelTimer);
++                      pNet->TimerExpired = SK_FALSE;
++//            }
++#endif
++      }
++}
++#endif
++
++
++#ifdef CONFIG_PM
++/*****************************************************************************
++ *
++ *    sk98lin_resume - Resume the the card
++ *
++ * Description:
++ *    This function resumes the card into the D0 state
++ *
++ * Returns: N/A
++ *    
++ */
++static int sk98lin_resume(
++struct pci_dev *pdev)   /* the device that is to resume */
++{
++      struct net_device   *dev  = pci_get_drvdata(pdev);
++      DEV_NET             *pNet = (DEV_NET*) dev->priv;
++      SK_AC               *pAC  = pNet->pAC;
++      SK_U16               PmCtlSts;
++
++      /* Set the power state to D0 */
++      pci_set_power_state(pdev, 0);
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
++      pci_restore_state(pdev);
++#else
++      pci_restore_state(pdev, pAC->PciState);
++#endif
++
++      /* Set the adapter power state to D0 */
++      SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);
++      PmCtlSts &= ~(PCI_PM_STATE_D3); /* reset all DState bits */
++      PmCtlSts |= PCI_PM_STATE_D0;
++      SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PmCtlSts);
++
++      /* Reinit the adapter and start the port again */
++      pAC->BoardLevel = SK_INIT_DATA;
++      SkDrvLeaveDiagMode(pAC);
++
++      netif_device_attach(dev);
++      netif_start_queue(dev);
++      return 0;
++}
++ 
++/*****************************************************************************
++ *
++ *    sk98lin_suspend - Suspend the card
++ *
++ * Description:
++ *    This function suspends the card into a defined state
++ *
++ * Returns: N/A
++ *    
++ */
++static int sk98lin_suspend(
++struct pci_dev        *pdev,   /* pointer to the device that is to suspend */
++u32           state)  /* what power state is desired by Linux?    */
++{
++      struct net_device   *dev  = pci_get_drvdata(pdev);
++      DEV_NET             *pNet = (DEV_NET*) dev->priv;
++      SK_AC               *pAC  = pNet->pAC;
++      SK_U16               PciPMControlStatus;
++      SK_U16               PciPMCapabilities;
++      SK_MAC_ADDR          MacAddr;
++      int                  i;
++
++      /* GEnesis and first yukon revs do not support power management */
++      if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
++              if (pAC->GIni.GIChipRev == 0) {
++                      return 0; /* power management not supported */
++              }
++      } 
++
++      if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
++              return 0; /* not supported for this chipset */
++      }
++
++      if (pAC->WolInfo.ConfiguredWolOptions == 0) {
++              return 0; /* WOL possible, but disabled via ethtool */
++      }
++
++      if(netif_running(dev)) {
++              netif_stop_queue(dev); /* stop device if running */
++      }
++
++      netif_device_detach(dev);
++      
++      /* read the PM control/status register from the PCI config space */
++      SK_IN16(pAC->IoBase, PCI_C(pAC, PCI_PM_CTL_STS), &PciPMControlStatus);
++
++      /* read the power management capabilities from the config space */
++      SK_IN16(pAC->IoBase, PCI_C(pAC, PCI_PM_CAP_REG), &PciPMCapabilities);
++
++      /* Enable WakeUp with Magic Packet - get MAC address from adapter */
++      for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
++              /* virtual address: will be used for data */
++              SK_IN8(pAC->IoBase, (B2_MAC_1 + i), &MacAddr.a[i]);
++      }
++
++      SkDrvEnterDiagMode(pAC);
++      SkEnableWOMagicPacket(pAC, pAC->IoBase, MacAddr);
++
++      pci_enable_wake(pdev, 3, 1);
++      pci_enable_wake(pdev, 4, 1);    /* 4 == D3 cold */
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
++      pci_save_state(pdev);
++#else
++      pci_save_state(pdev, pAC->PciState);
++#endif
++      pci_set_power_state(pdev, state); /* set the state */
++
++      return 0;
++}
++
++
++/******************************************************************************
++ *
++ *    SkEnableWOMagicPacket - Enable Wake on Magic Packet on the adapter
++ *
++ * Context:
++ *    init, pageable
++ *    the adapter should be de-initialized before calling this function
++ *
++ * Returns:
++ *    nothing
++ */
++
++static void SkEnableWOMagicPacket(
++SK_AC         *pAC,      /* Adapter Control Context          */
++SK_IOC         IoC,      /* I/O control context              */
++SK_MAC_ADDR    MacAddr)  /* MacAddr expected in magic packet */
++{
++      SK_U16  Word;
++      SK_U32  DWord;
++      int     i;
++      int     HwPortIndex;
++      int     Port = 0;
++
++      /* use Port 0 as long as we do not have any dual port cards which support WOL */
++      HwPortIndex = 0;
++      DWord = 0;
++
++      SK_OUT16(IoC, 0x0004, 0x0002);  /* clear S/W Reset */
++      SK_OUT16(IoC, 0x0f10, 0x0002);  /* clear Link Reset */
++
++      /*
++       * PHY Configuration:
++       * Autonegotioation is enalbed, advertise 10 HD, 10 FD,
++       * 100 HD, and 100 FD.
++       */
++      if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) ||
++              (pAC->GIni.GIChipId == CHIP_ID_YUKON) ||
++              (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) {
++
++              SK_OUT16(IoC, 0x0004, 0x0800);                  /* enable CLK_RUN */
++              SK_OUT8(IoC, 0x0007, 0xa9);                     /* enable VAUX */
++
++              /* WA code for COMA mode */
++              /* Only for yukon plus based chipsets rev A3 */
++              if (pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
++                      SK_IN32(IoC, B2_GP_IO, &DWord);
++                      DWord |= GP_DIR_9;                      /* set to output */
++                      DWord &= ~GP_IO_9;                      /* clear PHY reset (active high) */
++                      SK_OUT32(IoC, B2_GP_IO, DWord);         /* clear PHY reset */
++              }
++
++              if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) ||
++                      (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
++                      SK_OUT32(IoC, 0x0f04, 0x01f04001);      /* set PHY reset */
++                      SK_OUT32(IoC, 0x0f04, 0x01f04002);      /* clear PHY reset */
++              } else {
++                      SK_OUT8(IoC, 0x0f04, 0x02);             /* clear PHY reset */
++              }
++
++              SK_OUT8(IoC, 0x0f00, 0x02);                     /* clear MAC reset */
++              SkGmPhyWrite(pAC, IoC, Port, 4, 0x01e1);        /* advertise 10/100 HD/FD */
++              SkGmPhyWrite(pAC, IoC, Port, 9, 0x0000);        /* do not advertise 1000 HD/FD */
++              SkGmPhyWrite(pAC, IoC, Port, 00, 0xB300);       /* 100 MBit, disable Autoneg */
++      } else if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
++              SK_OUT8(IoC, 0x0007, 0xa9);                     /* enable VAUX */
++              SK_OUT8(IoC, 0x0f04, 0x02);                     /* clear PHY reset */
++              SK_OUT8(IoC, 0x0f00, 0x02);                     /* clear MAC reset */
++              SkGmPhyWrite(pAC, IoC, Port, 16, 0x0130);       /* Enable Automatic Crossover */
++              SkGmPhyWrite(pAC, IoC, Port, 00, 0xB300);       /* 100 MBit, disable Autoneg */
++      }
++
+       /*
+-       * Remap the regs into kernel space.
++       * MAC Configuration:
++       * Set the MAC to 100 HD and enable the auto update features
++       * for Speed, Flow Control and Duplex Mode.
++       * If autonegotiation completes successfully the
++       * MAC takes the link parameters from the PHY.
++       * If the link partner doesn't support autonegotiation
++       * the MAC can receive magic packets if the link partner
++       * uses 100 HD.
+        */
+-      pAC->IoBase = (char*)ioremap_nocache(dev->mem_start, 0x4000);
++      SK_OUT16(IoC, 0x2804, 0x3832);
++   
+-      if (!pAC->IoBase){
+-              retval = 3;
+-              goto out_release;
++      /*
++       * Set Up Magic Packet parameters
++       */
++      for (i = 0; i < 6; i+=2) {              /* set up magic packet MAC address */
++              SK_IN16(IoC, 0x100 + i, &Word);
++              SK_OUT16(IoC, 0xf24 + i, Word);
+       }
+-      return 0;
++      SK_OUT16(IoC, 0x0f20, 0x0208);          /* enable PME on magic packet */
++                                              /* and on wake up frame */
+- out_release:
+-      pci_release_regions(pdev);
+- out_disable:
+-      pci_disable_device(pdev);
+-      return retval;
+-}
++      /*
++       * Set up PME generation
++       */
++      /* set PME legacy mode */
++      /* Only for PCI express based chipsets */
++      if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) ||
++              (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE)) {
++              SkPciReadCfgDWord(pAC, 0x40, &DWord);
++              DWord |= 0x8000;
++              SkPciWriteCfgDWord(pAC, 0x40, DWord);
++      }
++
++      /* clear PME status and switch adapter to DState */
++      SkPciReadCfgWord(pAC, 0x4c, &Word);
++      Word |= 0x103;
++      SkPciWriteCfgWord(pAC, 0x4c, Word);
++}     /* SkEnableWOMagicPacket */
++#endif
+ /*****************************************************************************
+@@ -350,7 +1098,9 @@
+               if (pAC->IoBase) {
+                       iounmap(pAC->IoBase);
+               }
+-              if (pAC->pDescrMem) {
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      SkY2FreeResources(pAC);
++              } else {
+                       BoardFreeMem(pAC);
+               }
+       }
+@@ -360,25 +1110,6 @@
+ MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
+ MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
+ MODULE_LICENSE("GPL");
+-MODULE_PARM(Speed_A,    "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(Speed_B,    "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(AutoNeg_A,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(AutoNeg_B,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(DupCap_A,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(DupCap_B,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(FlowCtrl_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(FlowCtrl_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(Role_A,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(Role_B,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(ConType,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(PrefPort,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(RlmtMode,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-/* used for interrupt moderation */
+-MODULE_PARM(IntsPerSec,     "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i");
+-MODULE_PARM(Moderation,     "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(Stats,          "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(ModerationMask, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+-MODULE_PARM(AutoSizing,     "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
+ #ifdef LINK_SPEED_A
+@@ -462,8 +1193,137 @@
+ static int   IntsPerSec[SK_MAX_CARD_PARAM];
+ static char *Moderation[SK_MAX_CARD_PARAM];
+ static char *ModerationMask[SK_MAX_CARD_PARAM];
+-static char *AutoSizing[SK_MAX_CARD_PARAM];
+-static char *Stats[SK_MAX_CARD_PARAM];
++
++static char *LowLatency[SK_MAX_CARD_PARAM];
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
++module_param_array(Speed_A, charp, NULL, 0);
++module_param_array(Speed_B, charp, NULL, 0);
++module_param_array(AutoNeg_A, charp, NULL, 0);
++module_param_array(AutoNeg_B, charp, NULL, 0);
++module_param_array(DupCap_A, charp, NULL, 0);
++module_param_array(DupCap_B, charp, NULL, 0);
++module_param_array(FlowCtrl_A, charp, NULL, 0);
++module_param_array(FlowCtrl_B, charp, NULL, 0);
++module_param_array(Role_A, charp, NULL, 0);
++module_param_array(Role_B, charp, NULL, 0);
++module_param_array(ConType, charp, NULL, 0);
++module_param_array(PrefPort, charp, NULL, 0);
++module_param_array(RlmtMode, charp, NULL, 0);
++/* used for interrupt moderation */
++module_param_array(IntsPerSec, int, NULL, 0);
++module_param_array(Moderation, charp, NULL, 0);
++module_param_array(ModerationMask, charp, NULL, 0);
++module_param_array(LowLatency, charp, NULL, 0);
++#else
++MODULE_PARM(Speed_A,    "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(Speed_B,    "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(AutoNeg_A,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(AutoNeg_B,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(DupCap_A,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(DupCap_B,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(FlowCtrl_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(FlowCtrl_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(Role_A,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(Role_B,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(ConType,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(PrefPort,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(RlmtMode,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(IntsPerSec,     "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i");
++MODULE_PARM(Moderation,     "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(ModerationMask, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++MODULE_PARM(LowLatency, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
++#endif
++
++
++/*****************************************************************************
++ *
++ *    sk98lin_remove_device - device deinit function
++ *
++ * Description:
++ *    Disable adapter if it is still running, free resources,
++ *    free device struct.
++ *
++ * Returns: N/A
++ */
++
++static void sk98lin_remove_device(struct pci_dev *pdev)
++{
++DEV_NET               *pNet;
++SK_AC         *pAC;
++struct SK_NET_DEVICE *next;
++unsigned long Flags;
++struct net_device *dev = pci_get_drvdata(pdev);
++
++
++      /* Device not available. Return. */
++      if (!dev)
++              return;
++
++      pNet = (DEV_NET*) dev->priv;
++      pAC = pNet->pAC;
++      next = pAC->Next;
++
++      netif_stop_queue(dev);
++      SkGeYellowLED(pAC, pAC->IoBase, 0);
++
++      if(pAC->BoardLevel == SK_INIT_RUN) {
++              /* board is still alive */
++              spin_lock_irqsave(&pAC->SlowPathLock, Flags);
++              SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP,
++                                      0, -1, SK_FALSE);
++              SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP,
++                                      1, -1, SK_TRUE);
++
++              /* disable interrupts */
++              SK_OUT32(pAC->IoBase, B0_IMSK, 0);
++              SkGeDeInit(pAC, pAC->IoBase);
++              spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
++              pAC->BoardLevel = SK_INIT_DATA;
++              /* We do NOT check here, if IRQ was pending, of course*/
++      }
++
++      if(pAC->BoardLevel == SK_INIT_IO) {
++              /* board is still alive */
++              SkGeDeInit(pAC, pAC->IoBase);
++              pAC->BoardLevel = SK_INIT_DATA;
++      }
++
++      if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
++              unregister_netdev(pAC->dev[1]);
++              free_netdev(pAC->dev[1]);
++      }
++
++      FreeResources(dev);
++
++#ifdef CONFIG_PROC_FS
++      /* Remove the sk98lin procfs device entries */
++      if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
++              remove_proc_entry(pAC->dev[1]->name, pSkRootDir);
++      }
++      remove_proc_entry(pNet->InitialDevName, pSkRootDir);
++#endif
++
++      dev->get_stats = NULL;
++      /*
++       * otherwise unregister_netdev calls get_stats with
++       * invalid IO ...  :-(
++       */
++      unregister_netdev(dev);
++      free_netdev(dev);
++      kfree(pAC);
++      sk98lin_max_boards_found--;
++
++#ifdef CONFIG_PROC_FS
++      /* Remove all Proc entries if last device */
++      if (sk98lin_max_boards_found == 0) {
++              /* clear proc-dir */
++              remove_proc_entry(pSkRootDir->name, proc_net);
++      }
++#endif
++
++}
++
+ /*****************************************************************************
+  *
+@@ -501,7 +1361,10 @@
+               spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock);
+               spin_lock_init(&pAC->RxPort[i].RxDesRingLock);
+       }
++
+       spin_lock_init(&pAC->SlowPathLock);
++      spin_lock_init(&pAC->TxQueueLock);      /* for Yukon2 chipsets */
++      spin_lock_init(&pAC->SetPutIndexLock);  /* for Yukon2 chipsets */
+       /* level 0 init common modules here */
+       
+@@ -520,15 +1383,13 @@
+       SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA);
+       pAC->BoardLevel = SK_INIT_DATA;
+-      pAC->RxBufSize  = ETH_BUF_SIZE;
++      pAC->RxPort[0].RxBufSize = ETH_BUF_SIZE;
++      pAC->RxPort[1].RxBufSize = ETH_BUF_SIZE;
+       SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString);
+       SK_PNMI_SET_DRIVER_VER(pAC, VerStr);
+-      spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+-
+       /* level 1 init common modules here (HW init) */
+-      spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+       if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
+               printk("sk98lin: HWInit (1) failed.\n");
+               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+@@ -540,51 +1401,93 @@
+       SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
+       SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
+       SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
++#ifdef Y2_RECOVERY
++      /* mark entries invalid */
++      pAC->LastPort = 3;
++      pAC->LastOpc = 0xFF;
++#endif
+       /* Set chipset type support */
+-      pAC->ChipsetType = 0;
+       if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) ||
+-              (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) {
+-              pAC->ChipsetType = 1;
++              (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) ||
++              (pAC->GIni.GIChipId == CHIP_ID_YUKON_LP)) {
++              pAC->ChipsetType = 1;   /* Yukon chipset (descriptor logic) */
++      } else if (CHIP_ID_YUKON_2(pAC)) {
++              pAC->ChipsetType = 2;   /* Yukon2 chipset (list logic) */
++      } else {
++              pAC->ChipsetType = 0;   /* Genesis chipset (descriptor logic) */
++      }
++
++      /* wake on lan support */
++      pAC->WolInfo.SupportedWolOptions = 0;
++#if defined (ETHTOOL_GWOL) && defined (ETHTOOL_SWOL)
++      if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) {
++              pAC->WolInfo.SupportedWolOptions  = WAKE_MAGIC;
++              if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
++                      if (pAC->GIni.GIChipRev == 0) {
++                              pAC->WolInfo.SupportedWolOptions = 0;
++                      }
++              } 
+       }
++#endif
++      pAC->WolInfo.ConfiguredWolOptions = pAC->WolInfo.SupportedWolOptions;
+       GetConfiguration(pAC);
+       if (pAC->RlmtNets == 2) {
+-              pAC->GIni.GIPortUsage = SK_MUL_LINK;
++              pAC->GIni.GP[0].PPortUsage = SK_MUL_LINK;
++              pAC->GIni.GP[1].PPortUsage = SK_MUL_LINK;
+       }
+       pAC->BoardLevel = SK_INIT_IO;
+       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+-      if (pAC->GIni.GIMacsFound == 2) {
+-               Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
+-      } else if (pAC->GIni.GIMacsFound == 1) {
+-              Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ,
+-                      pAC->Name, dev);
+-      } else {
+-              printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
+-                     pAC->GIni.GIMacsFound);
+-              return -EAGAIN;
++      if (!CHIP_ID_YUKON_2(pAC)) {
++              if (pAC->GIni.GIMacsFound == 2) {
++                      Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, dev->name, dev);
++              } else if (pAC->GIni.GIMacsFound == 1) {
++                      Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, dev->name, dev);
++              } else {
++                      printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
++                              pAC->GIni.GIMacsFound);
++                      return -EAGAIN;
++              }
++      }
++      else {
++              Ret = request_irq(dev->irq, SkY2Isr, SA_SHIRQ, dev->name, dev);
+       }
+       if (Ret) {
+               printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n",
+-                     dev->irq);
++                      dev->irq);
+               return -EAGAIN;
+       }
+       pAC->AllocFlag |= SK_ALLOC_IRQ;
+-      /* Alloc memory for this board (Mem for RxD/TxD) : */
+-      if(!BoardAllocMem(pAC)) {
+-              printk("No memory for descriptor rings.\n");
+-                      return(-EAGAIN);
++      /* 
++      ** Alloc descriptor/LETable memory for this board (both RxD/TxD)
++      */
++      if (CHIP_ID_YUKON_2(pAC)) {
++              if (!SkY2AllocateResources(pAC)) {
++                      printk("No memory for Yukon2 settings\n");
++                      return(-EAGAIN);
++              }
++      } else {
++              if(!BoardAllocMem(pAC)) {
++                      printk("No memory for descriptor rings.\n");
++                      return(-EAGAIN);
++              }
+       }
++#ifdef SK_USE_CSUM
+       SkCsSetReceiveFlags(pAC,
+               SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP,
+               &pAC->CsOfs1, &pAC->CsOfs2, 0);
+       pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1;
++#endif
++      /*
++      ** Function BoardInitMem() for Yukon dependent settings...
++      */
+       BoardInitMem(pAC);
+       /* tschilling: New common function with minimum size check. */
+       DualNet = SK_FALSE;
+@@ -596,7 +1499,12 @@
+               pAC,
+               pAC->ActivePort,
+               DualNet)) {
+-              BoardFreeMem(pAC);
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      SkY2FreeResources(pAC);
++              } else {
++                      BoardFreeMem(pAC);
++              }
++
+               printk("sk98lin: SkGeInitAssignRamToQueues failed.\n");
+               return(-EAGAIN);
+       }
+@@ -696,16 +1604,20 @@
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("BoardFreeMem\n"));
++
++      if (pAC->pDescrMem) {
++
+ #if (BITS_PER_LONG == 32)
+-      AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
++              AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
+ #else
+-      AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
+-              + RX_RING_SIZE + 8;
++              AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
++                      + RX_RING_SIZE + 8;
+ #endif
+-      pci_free_consistent(pAC->PciDev, AllocLength,
++              pci_free_consistent(pAC->PciDev, AllocLength,
+                           pAC->pDescrMem, pAC->pDescrMemDMA);
+-      pAC->pDescrMem = NULL;
++              pAC->pDescrMem = NULL;
++      }
+ } /* BoardFreeMem */
+@@ -714,7 +1626,7 @@
+  *    BoardInitMem - initiate the descriptor rings
+  *
+  * Description:
+- *    This function sets the descriptor rings up in memory.
++ *    This function sets the descriptor rings or LETables up in memory.
+  *    The adapter is initialized with the descriptor start addresses.
+  *
+  * Returns:   N/A
+@@ -729,34 +1641,37 @@
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("BoardInitMem\n"));
+-      RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
+-      pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize;
+-      TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
+-      pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize;
++      if (!pAC->GIni.GIYukon2) {
++              RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
++              pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize;
++              TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
++              pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize;
+       
+-      for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+-              SetupRing(
+-                      pAC,
+-                      pAC->TxPort[i][0].pTxDescrRing,
+-                      pAC->TxPort[i][0].VTxDescrRing,
+-                      (RXD**)&pAC->TxPort[i][0].pTxdRingHead,
+-                      (RXD**)&pAC->TxPort[i][0].pTxdRingTail,
+-                      (RXD**)&pAC->TxPort[i][0].pTxdRingPrev,
+-                      &pAC->TxPort[i][0].TxdRingFree,
+-                      SK_TRUE);
+-              SetupRing(
+-                      pAC,
+-                      pAC->RxPort[i].pRxDescrRing,
+-                      pAC->RxPort[i].VRxDescrRing,
+-                      &pAC->RxPort[i].pRxdRingHead,
+-                      &pAC->RxPort[i].pRxdRingTail,
+-                      &pAC->RxPort[i].pRxdRingPrev,
+-                      &pAC->RxPort[i].RxdRingFree,
+-                      SK_FALSE);
++              for (i=0; i<pAC->GIni.GIMacsFound; i++) {
++                      SetupRing(
++                              pAC,
++                              pAC->TxPort[i][0].pTxDescrRing,
++                              pAC->TxPort[i][0].VTxDescrRing,
++                              (RXD**)&pAC->TxPort[i][0].pTxdRingHead,
++                              (RXD**)&pAC->TxPort[i][0].pTxdRingTail,
++                              (RXD**)&pAC->TxPort[i][0].pTxdRingPrev,
++                              &pAC->TxPort[i][0].TxdRingFree,
++                              &pAC->TxPort[i][0].TxdRingPrevFree,
++                              SK_TRUE);
++                      SetupRing(
++                              pAC,
++                              pAC->RxPort[i].pRxDescrRing,
++                              pAC->RxPort[i].VRxDescrRing,
++                              &pAC->RxPort[i].pRxdRingHead,
++                              &pAC->RxPort[i].pRxdRingTail,
++                              &pAC->RxPort[i].pRxdRingPrev,
++                              &pAC->RxPort[i].RxdRingFree,
++                              &pAC->RxPort[i].RxdRingFree,
++                              SK_FALSE);
++              }
+       }
+ } /* BoardInitMem */
+-
+ /*****************************************************************************
+  *
+  *    SetupRing - create one descriptor ring
+@@ -776,6 +1691,7 @@
+ RXD           **ppRingTail,   /* address where the tail should be written */
+ RXD           **ppRingPrev,   /* address where the tail should be written */
+ int           *pRingFree,     /* address where the # of free descr. goes */
++int           *pRingPrevFree, /* address where the # of free descr. goes */
+ SK_BOOL               IsTx)           /* flag: is this a tx ring */
+ {
+ int   i;              /* loop counter */
+@@ -818,11 +1734,12 @@
+       }
+       pPrevDescr->pNextRxd = (RXD*) pMemArea;
+       pPrevDescr->VNextRxd = VMemArea;
+-      pDescr = (RXD*) pMemArea;
+-      *ppRingHead = (RXD*) pMemArea;
+-      *ppRingTail = *ppRingHead;
+-      *ppRingPrev = pPrevDescr;
+-      *pRingFree = DescrNum;
++      pDescr               = (RXD*) pMemArea;
++      *ppRingHead          = (RXD*) pMemArea;
++      *ppRingTail          = *ppRingHead;
++      *ppRingPrev          = pPrevDescr;
++      *pRingFree           = DescrNum;
++      *pRingPrevFree       = DescrNum;
+ } /* SetupRing */
+@@ -894,10 +1811,28 @@
+        * Check and process if its our interrupt
+        */
+       SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
+-      if (IntSrc == 0) {
++      if ((IntSrc == 0) && (!pNet->NetConsoleMode)) {
+               return SkIsrRetNone;
+       }
++#ifdef CONFIG_SK98LIN_NAPI
++      if (netif_rx_schedule_prep(dev)) {
++              pAC->GIni.GIValIrqMask &= ~(NAPI_DRV_IRQS);
++              SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
++              __netif_rx_schedule(dev);
++      }
++
++#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
++      if (IntSrc & IS_XA1_F) {
++              CLEAR_TX_IRQ(0, TX_PRIO_LOW);
++      }
++      if (IntSrc & IS_XA2_F) {
++              CLEAR_TX_IRQ(1, TX_PRIO_LOW);
++      }
++#endif
++
++
++#else
+       while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
+ #if 0 /* software irq currently not used */
+               if (IntSrc & IS_IRQ_SW) {
+@@ -911,6 +1846,7 @@
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF RX1 IRQ\n"));
+                       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
++                      CLEAR_AND_START_RX(0);
+                       SK_PNMI_CNT_RX_INTR(pAC, 0);
+               }
+               if (IntSrc & IS_R2_F) {
+@@ -918,6 +1854,7 @@
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF RX2 IRQ\n"));
+                       ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
++                      CLEAR_AND_START_RX(1);
+                       SK_PNMI_CNT_RX_INTR(pAC, 1);
+               }
+ #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
+@@ -925,6 +1862,7 @@
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF AS TX1 IRQ\n"));
++                      CLEAR_TX_IRQ(0, TX_PRIO_LOW);
+                       SK_PNMI_CNT_TX_INTR(pAC, 0);
+                       spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
+                       FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
+@@ -934,6 +1872,7 @@
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF AS TX2 IRQ\n"));
++                      CLEAR_TX_IRQ(1, TX_PRIO_LOW);
+                       SK_PNMI_CNT_TX_INTR(pAC, 1);
+                       spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
+                       FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
+@@ -944,38 +1883,28 @@
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF SY TX1 IRQ\n"));
++                      CLEAR_TX_IRQ(0, TX_PRIO_HIGH);
+                       SK_PNMI_CNT_TX_INTR(pAC, 1);
+                       spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
+                       FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
+                       spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
+-                      ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
+               }
+               if (IntSrc & IS_XS2_F) {
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF SY TX2 IRQ\n"));
++                      CLEAR_TX_IRQ(1, TX_PRIO_HIGH);
+                       SK_PNMI_CNT_TX_INTR(pAC, 1);
+                       spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
+                       FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH);
+                       spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
+-                      ClearTxIrq(pAC, 1, TX_PRIO_HIGH);
+               }
+ #endif
+ #endif
+-              /* do all IO at once */
+-              if (IntSrc & IS_R1_F)
+-                      ClearAndStartRx(pAC, 0);
+-              if (IntSrc & IS_R2_F)
+-                      ClearAndStartRx(pAC, 1);
+-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
+-              if (IntSrc & IS_XA1_F)
+-                      ClearTxIrq(pAC, 0, TX_PRIO_LOW);
+-              if (IntSrc & IS_XA2_F)
+-                      ClearTxIrq(pAC, 1, TX_PRIO_LOW);
+-#endif
+               SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
+       } /* while (IntSrc & IRQ_MASK != 0) */
++#endif
+       IntSrc &= pAC->GIni.GIValIrqMask;
+       if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
+@@ -989,18 +1918,12 @@
+               SkEventDispatcher(pAC, pAC->IoBase);
+               spin_unlock(&pAC->SlowPathLock);
+       }
+-      /*
+-       * do it all again is case we cleared an interrupt that
+-       * came in after handling the ring (OUTs may be delayed
+-       * in hardware buffers, but are through after IN)
+-       *
+-       * rroesler: has been commented out and shifted to
+-       *           SkGeDrvEvent(), because it is timer
+-       *           guarded now
+-       *
++
++#ifndef CONFIG_SK98LIN_NAPI
++      /* Handle interrupts */
+       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
+       ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
+-       */
++#endif
+       if (pAC->CheckQueue) {
+               pAC->CheckQueue = SK_FALSE;
+@@ -1043,10 +1966,25 @@
+        * Check and process if its our interrupt
+        */
+       SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
+-      if (IntSrc == 0) {
++      if ((IntSrc == 0) && (!pNet->NetConsoleMode)) {
+               return SkIsrRetNone;
+       }
+       
++#ifdef CONFIG_SK98LIN_NAPI
++      if (netif_rx_schedule_prep(dev)) {
++              // CLEAR_AND_START_RX(0);
++              // CLEAR_TX_IRQ(0, TX_PRIO_LOW);
++              pAC->GIni.GIValIrqMask &= ~(NAPI_DRV_IRQS);
++              SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
++              __netif_rx_schedule(dev);
++      } 
++
++#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
++      if (IntSrc & IS_XA1_F) {
++              CLEAR_TX_IRQ(0, TX_PRIO_LOW);
++      }
++#endif
++#else
+       while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
+ #if 0 /* software irq currently not used */
+               if (IntSrc & IS_IRQ_SW) {
+@@ -1060,6 +1998,7 @@
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF RX1 IRQ\n"));
+                       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
++                      CLEAR_AND_START_RX(0);
+                       SK_PNMI_CNT_RX_INTR(pAC, 0);
+               }
+ #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
+@@ -1067,6 +2006,7 @@
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF AS TX1 IRQ\n"));
++                      CLEAR_TX_IRQ(0, TX_PRIO_LOW);
+                       SK_PNMI_CNT_TX_INTR(pAC, 0);
+                       spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
+                       FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
+@@ -1077,24 +2017,18 @@
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_INT_SRC,
+                               ("EOF SY TX1 IRQ\n"));
++                      CLEAR_TX_IRQ(0, TX_PRIO_HIGH);
+                       SK_PNMI_CNT_TX_INTR(pAC, 0);
+                       spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
+                       FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
+                       spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
+-                      ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
+               }
+ #endif
+ #endif
+-              /* do all IO at once */
+-              if (IntSrc & IS_R1_F)
+-                      ClearAndStartRx(pAC, 0);
+-#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
+-              if (IntSrc & IS_XA1_F)
+-                      ClearTxIrq(pAC, 0, TX_PRIO_LOW);
+-#endif
+               SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
+       } /* while (IntSrc & IRQ_MASK != 0) */
++#endif
+       
+       IntSrc &= pAC->GIni.GIValIrqMask;
+       if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
+@@ -1108,17 +2042,10 @@
+               SkEventDispatcher(pAC, pAC->IoBase);
+               spin_unlock(&pAC->SlowPathLock);
+       }
+-      /*
+-       * do it all again is case we cleared an interrupt that
+-       * came in after handling the ring (OUTs may be delayed
+-       * in hardware buffers, but are through after IN)
+-       *
+-       * rroesler: has been commented out and shifted to
+-       *           SkGeDrvEvent(), because it is timer
+-       *           guarded now
+-       *
++
++#ifndef CONFIG_SK98LIN_NAPI
+       ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
+-       */
++#endif
+       /* IRQ is processed - Enable IRQs again*/
+       SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
+@@ -1126,7 +2053,6 @@
+               return SkIsrRetHandled;
+ } /* SkGeIsrOnePort */
+-
+ /****************************************************************************
+  *
+  *    SkGeOpen - handle start of initialized adapter
+@@ -1144,27 +2070,21 @@
+  *    != 0 on error
+  */
+ static int SkGeOpen(
+-struct SK_NET_DEVICE  *dev)
++struct SK_NET_DEVICE *dev)  /* the device that is to be opened */
+ {
+-      DEV_NET                 *pNet;
+-      SK_AC                   *pAC;
+-      unsigned long   Flags;          /* for spin lock */
+-      int                             i;
+-      SK_EVPARA               EvPara;         /* an event parameter union */
++      DEV_NET        *pNet = (DEV_NET*) dev->priv;
++      SK_AC          *pAC  = pNet->pAC;
++      unsigned long   Flags;    /* for the spin locks    */
++      int             CurrMac;  /* loop ctr for ports    */
+-      pNet = (DEV_NET*) dev->priv;
+-      pAC = pNet->pAC;
+-      
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
+-#ifdef SK_DIAG_SUPPORT
+       if (pAC->DiagModeActive == DIAG_ACTIVE) {
+               if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
+                       return (-1);   /* still in use by diag; deny actions */
+               } 
+       }
+-#endif
+       if (!try_module_get(THIS_MODULE)) {
+               return (-1);    /* increase of usage count not possible */
+@@ -1188,6 +2108,11 @@
+               SkRlmtInit      (pAC, pAC->IoBase, SK_INIT_IO);
+               SkTimerInit     (pAC, pAC->IoBase, SK_INIT_IO);
+               pAC->BoardLevel = SK_INIT_IO;
++#ifdef Y2_RECOVERY
++              /* mark entries invalid */
++              pAC->LastPort = 3;
++              pAC->LastOpc = 0xFF;
++#endif
+       }
+       if (pAC->BoardLevel != SK_INIT_RUN) {
+@@ -1206,45 +2131,61 @@
+               pAC->BoardLevel = SK_INIT_RUN;
+       }
+-      for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+-              /* Enable transmit descriptor polling. */
+-              SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
+-              FillRxRing(pAC, &pAC->RxPort[i]);
++      for (CurrMac=0; CurrMac<pAC->GIni.GIMacsFound; CurrMac++) {
++              if (!CHIP_ID_YUKON_2(pAC)) {
++                      /* Enable transmit descriptor polling. */
++                      SkGePollTxD(pAC, pAC->IoBase, CurrMac, SK_TRUE);
++                      FillRxRing(pAC, &pAC->RxPort[CurrMac]);
++                      SkMacRxTxEnable(pAC, pAC->IoBase, pNet->PortNr);
++              }
+       }
+-      SkGeYellowLED(pAC, pAC->IoBase, 1);
+-      StartDrvCleanupTimer(pAC);
++      SkGeYellowLED(pAC, pAC->IoBase, 1);
+       SkDimEnableModerationIfNeeded(pAC);     
+-      SkDimDisplayModerationSettings(pAC);
+-
+-      pAC->GIni.GIValIrqMask &= IRQ_MASK;
+-      /* enable Interrupts */
+-      SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
+-      SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
++      if (!CHIP_ID_YUKON_2(pAC)) {
++              /*
++              ** Has been setup already at SkGeInit(SK_INIT_IO),
++              ** but additional masking added for Genesis & Yukon
++              ** chipsets -> modify it...
++              */
++              pAC->GIni.GIValIrqMask &= IRQ_MASK;
++#ifndef USE_TX_COMPLETE
++              pAC->GIni.GIValIrqMask &= ~(TX_COMPL_IRQS);
++#endif
++      }
+       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+       if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) {
+-              EvPara.Para32[0] = pAC->RlmtNets;
+-              EvPara.Para32[1] = -1;
+-              SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
+-                      EvPara);
+-              EvPara.Para32[0] = pAC->RlmtMode;
+-              EvPara.Para32[1] = 0;
+-              SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE,
+-                      EvPara);
++              SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
++                                      pAC->RlmtNets, -1, SK_FALSE);
++              SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE,
++                                      pAC->RlmtMode, 0, SK_FALSE);
+       }
+-      EvPara.Para32[0] = pNet->NetNr;
+-      EvPara.Para32[1] = -1;
+-      SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+-      SkEventDispatcher(pAC, pAC->IoBase);
++      SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_START,
++                              pNet->NetNr, -1, SK_TRUE);
+       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+-      pAC->MaxPorts++;
+-      pNet->Up = 1;
++#ifdef Y2_RECOVERY
++      pNet->TimerExpired = SK_FALSE;
++      pNet->InRecover = SK_FALSE;
++      pNet->NetConsoleMode = SK_FALSE;
++
++      /* Initialize the kernel timer */
++      init_timer(&pNet->KernelTimer);
++      pNet->KernelTimer.function      = SkGeHandleKernelTimer;
++      pNet->KernelTimer.data          = (unsigned long) pNet;
++      pNet->KernelTimer.expires       = jiffies + (HZ/4); /* initially 250ms */
++      add_timer(&pNet->KernelTimer);
++#endif
++
++      /* enable Interrupts */
++      SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
++      SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
++      pAC->MaxPorts++;
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeOpen suceeded\n"));
+@@ -1265,24 +2206,26 @@
+  *    error code - on error
+  */
+ static int SkGeClose(
+-struct SK_NET_DEVICE  *dev)
++struct SK_NET_DEVICE *dev)  /* the device that is to be closed */
+ {
+-      DEV_NET         *pNet;
+-      DEV_NET         *newPtrNet;
+-      SK_AC           *pAC;
+-
+-      unsigned long   Flags;          /* for spin lock */
+-      int             i;
+-      int             PortIdx;
+-      SK_EVPARA       EvPara;
+-
++      DEV_NET         *pNet = (DEV_NET*) dev->priv;
++      SK_AC           *pAC  = pNet->pAC;
++      DEV_NET         *newPtrNet;
++      unsigned long    Flags;        /* for the spin locks           */
++      int              CurrMac;      /* loop ctr for the current MAC */
++      int              PortIdx;
++#ifdef CONFIG_SK98LIN_NAPI
++      int              WorkToDo = 1; /* min(*budget, dev->quota);    */
++      int              WorkDone = 0;
++#endif
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
+-      pNet = (DEV_NET*) dev->priv;
+-      pAC = pNet->pAC;
++#ifdef Y2_RECOVERY
++      pNet->InRecover = SK_TRUE;
++      del_timer(&pNet->KernelTimer);
++#endif
+-#ifdef SK_DIAG_SUPPORT
+       if (pAC->DiagModeActive == DIAG_ACTIVE) {
+               if (pAC->DiagFlowCtrl == SK_FALSE) {
+                       module_put(THIS_MODULE);
+@@ -1302,7 +2245,6 @@
+                       pAC->DiagFlowCtrl = SK_FALSE;
+               }
+       }
+-#endif
+       netif_stop_queue(dev);
+@@ -1311,8 +2253,6 @@
+       else
+               PortIdx = pNet->NetNr;
+-        StopDrvCleanupTimer(pAC);
+-
+       /*
+        * Clear multicast table, promiscuous mode ....
+        */
+@@ -1324,46 +2264,101 @@
+               spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+               /* disable interrupts */
+               SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+-              EvPara.Para32[0] = pNet->NetNr;
+-              EvPara.Para32[1] = -1;
+-              SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+-              SkEventDispatcher(pAC, pAC->IoBase);
++              SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP,
++                                      pNet->NetNr, -1, SK_TRUE);
+               SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+               /* stop the hardware */
+-              SkGeDeInit(pAC, pAC->IoBase);
+-              pAC->BoardLevel = SK_INIT_DATA;
++
++
++              if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 1)) {
++              /* RLMT check link state mode */
++                      for (CurrMac=0; CurrMac<pAC->GIni.GIMacsFound; CurrMac++) {
++                              if (CHIP_ID_YUKON_2(pAC))
++                                      SkY2PortStop(   pAC, 
++                                                      pAC->IoBase,
++                                                      CurrMac,
++                                                      SK_STOP_ALL,
++                                                      SK_HARD_RST);
++                              else
++                                      SkGeStopPort(   pAC,
++                                                      pAC->IoBase,
++                                                      CurrMac,
++                                                      SK_STOP_ALL,
++                                                      SK_HARD_RST);
++                      } /* for */
++              } else {
++              /* Single link or single port */
++                      if (CHIP_ID_YUKON_2(pAC))
++                              SkY2PortStop(   pAC, 
++                                              pAC->IoBase,
++                                              PortIdx,
++                                              SK_STOP_ALL,
++                                              SK_HARD_RST);
++                      else
++                              SkGeStopPort(   pAC,
++                                              pAC->IoBase,
++                                              PortIdx,
++                                              SK_STOP_ALL,
++                                              SK_HARD_RST);
++              }
+               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+       } else {
+-
+               spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+-              EvPara.Para32[0] = pNet->NetNr;
+-              EvPara.Para32[1] = -1;
+-              SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+-              SkPnmiEvent(pAC, pAC->IoBase, SK_PNMI_EVT_XMAC_RESET, EvPara);
+-              SkEventDispatcher(pAC, pAC->IoBase);
++              SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP,
++                                      pNet->NetNr, -1, SK_FALSE);
++              SkLocalEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET,
++                                      pNet->NetNr, -1, SK_TRUE);
+               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+               
+               /* Stop port */
+               spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]
+                       [TX_PRIO_LOW].TxDesRingLock, Flags);
+-              SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
+-                      SK_STOP_ALL, SK_HARD_RST);
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      SkY2PortStop(pAC, pAC->IoBase, pNet->PortNr,
++                              SK_STOP_ALL, SK_HARD_RST);
++              }
++              else {
++                      SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
++                              SK_STOP_ALL, SK_HARD_RST);
++              }
+               spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]
+                       [TX_PRIO_LOW].TxDesRingLock, Flags);
+       }
+       if (pAC->RlmtNets == 1) {
+               /* clear all descriptor rings */
+-              for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+-                      ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
+-                      ClearRxRing(pAC, &pAC->RxPort[i]);
+-                      ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
++              for (CurrMac=0; CurrMac<pAC->GIni.GIMacsFound; CurrMac++) {
++                      if (!CHIP_ID_YUKON_2(pAC)) {
++#ifdef CONFIG_SK98LIN_NAPI
++                              WorkToDo = 1;
++                              ReceiveIrq(pAC,&pAC->RxPort[CurrMac],
++                                              SK_TRUE,&WorkDone,WorkToDo);
++#else
++                              ReceiveIrq(pAC,&pAC->RxPort[CurrMac],SK_TRUE);
++#endif
++                              ClearRxRing(pAC, &pAC->RxPort[CurrMac]);
++                              ClearTxRing(pAC, &pAC->TxPort[CurrMac][TX_PRIO_LOW]);
++                      } else {
++                              SkY2FreeRxBuffers(pAC, pAC->IoBase, CurrMac);
++                              SkY2FreeTxBuffers(pAC, pAC->IoBase, CurrMac);
++                      }
++              }
++      } else {
++              /* clear port descriptor rings */
++              if (!CHIP_ID_YUKON_2(pAC)) {
++#ifdef CONFIG_SK98LIN_NAPI
++                      WorkToDo = 1;
++                      ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE, &WorkDone, WorkToDo);
++#else
++                      ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);
++#endif
++                      ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
++                      ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
++              }
++              else {
++                      SkY2FreeRxBuffers(pAC, pAC->IoBase, pNet->PortNr);
++                      SkY2FreeTxBuffers(pAC, pAC->IoBase, pNet->PortNr);
+               }
+-      } else {
+-              /* clear port descriptor rings */
+-              ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);
+-              ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
+-              ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
+       }
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+@@ -1374,9 +2369,12 @@
+                       sizeof(SK_PNMI_STRUCT_DATA));
+       pAC->MaxPorts--;
+-      pNet->Up = 0;
+-
+       module_put(THIS_MODULE);
++
++#ifdef Y2_RECOVERY
++      pNet->InRecover = SK_FALSE;
++#endif
++
+       return (0);
+ } /* SkGeClose */
+@@ -1434,9 +2432,11 @@
+       }
+       /* Transmitter out of resources? */
++#ifdef USE_TX_COMPLETE
+       if (Rc <= 0) {
+               netif_stop_queue(dev);
+       }
++#endif
+       /* If not taken, give buffer ownership back to the
+        * queueing layer.
+@@ -1448,6 +2448,94 @@
+       return (0);
+ } /* SkGeXmit */
++#ifdef CONFIG_SK98LIN_NAPI
++/*****************************************************************************
++ *
++ *    SkGePoll - NAPI Rx polling callback for GEnesis and Yukon chipsets
++ *
++ * Description:
++ *    Called by the Linux system in case NAPI polling is activated
++ *
++ * Returns:
++ *    The number of work data still to be handled
++ */
++static int SkGePoll(struct net_device *dev, int *budget) 
++{
++SK_AC *pAC = ((DEV_NET*)(dev->priv))->pAC; /* pointer to adapter context */
++int   WorkToDo = min(*budget, dev->quota);
++int   WorkDone = 0;
++
++      if (pAC->dev[0] != pAC->dev[1]) {
++#ifdef USE_TX_COMPLETE
++              spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
++              FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
++              spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
++#endif
++              ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE, &WorkDone, WorkToDo);
++              CLEAR_AND_START_RX(1);
++      }
++#ifdef USE_TX_COMPLETE
++      spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
++      FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
++      spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
++#endif
++      ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE, &WorkDone, WorkToDo);
++      CLEAR_AND_START_RX(0);
++
++      *budget -= WorkDone;
++      dev->quota -= WorkDone;
++
++      if(WorkDone < WorkToDo) {
++              netif_rx_complete(dev);
++              /* enable interrupts again */
++              pAC->GIni.GIValIrqMask |= (NAPI_DRV_IRQS);
++#ifndef USE_TX_COMPLETE
++              pAC->GIni.GIValIrqMask &= ~(TX_COMPL_IRQS);
++#endif
++              SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
++      }
++      return (WorkDone >= WorkToDo);
++} /* SkGePoll */
++#endif
++
++#ifdef SK_POLL_CONTROLLER
++/*****************************************************************************
++ *
++ *    SkGeNetPoll - Polling "interrupt"
++ *
++ * Description:
++ *    Polling 'interrupt' - used by things like netconsole and netdump
++ *    to send skbs without having to re-enable interrupts.
++ *    It's not called while the interrupt routine is executing.
++ */
++static void SkGeNetPoll(
++struct SK_NET_DEVICE *dev) 
++{
++DEV_NET               *pNet;
++SK_AC         *pAC;
++
++      pNet = (DEV_NET*) dev->priv;
++      pAC = pNet->pAC;
++      pNet->NetConsoleMode = SK_TRUE;
++
++              /*  Prevent any reconfiguration while handling
++                  the 'interrupt' */
++              SK_OUT32(pAC->IoBase, B0_IMSK, 0);
++
++              if (!CHIP_ID_YUKON_2(pAC)) {
++              /* Handle the GENESIS Isr */
++                      if (pAC->GIni.GIMacsFound == 2)
++                              SkGeIsr(dev->irq, dev, NULL);
++                      else
++                              SkGeIsrOnePort(dev->irq, dev, NULL);
++              } else {
++              /* Handle the Yukon2 Isr */
++                      SkY2Isr(dev->irq, dev, NULL);
++              }
++
++}
++#endif
++
+ /*****************************************************************************
+  *
+@@ -1472,7 +2560,7 @@
+  *    < 0 - on failure: other problems ( -> return failure to upper layers)
+  */
+ static int XmitFrame(
+-SK_AC                 *pAC,           /* pointer to adapter context           */
++SK_AC                 *pAC,           /* pointer to adapter context           */
+ TX_PORT               *pTxPort,       /* pointer to struct of port to send to */
+ struct sk_buff        *pMessage)      /* pointer to send-message              */
+ {
+@@ -1488,11 +2576,14 @@
+       spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
+ #ifndef USE_TX_COMPLETE
+-      FreeTxDescriptors(pAC, pTxPort);
++      if ((pTxPort->TxdRingPrevFree - pTxPort->TxdRingFree) > 6)  {
++              FreeTxDescriptors(pAC, pTxPort);
++              pTxPort->TxdRingPrevFree = pTxPort->TxdRingFree;
++      }
+ #endif
+       if (pTxPort->TxdRingFree == 0) {
+               /* 
+-              ** no enough free descriptors in ring at the moment.
++              ** not enough free descriptors in ring at the moment.
+               ** Maybe free'ing some old one help?
+               */
+               FreeTxDescriptors(pAC, pTxPort);
+@@ -1578,7 +2669,7 @@
+                                  BMU_IRQ_EOF |
+ #endif
+                                  pMessage->len;
+-        } else {
++      } else {
+               pTxd->TBControl = BMU_OWN | BMU_STF | BMU_CHECK | 
+                                 BMU_SW  | BMU_EOF |
+ #ifdef USE_TX_COMPLETE
+@@ -1914,7 +3005,7 @@
+ SK_U16                Length;         /* data fragment length */
+ SK_U64                PhysAddr;       /* physical address of a rx buffer */
+-      pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC);
++      pMsgBlock = alloc_skb(pRxPort->RxBufSize, GFP_ATOMIC);
+       if (pMsgBlock == NULL) {
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                       SK_DBGCAT_DRV_ENTRY,
+@@ -1928,12 +3019,12 @@
+       pRxd = pRxPort->pRxdRingTail;
+       pRxPort->pRxdRingTail = pRxd->pNextRxd;
+       pRxPort->RxdRingFree--;
+-      Length = pAC->RxBufSize;
++      Length = pRxPort->RxBufSize;
+       PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
+               virt_to_page(pMsgBlock->data),
+               ((unsigned long) pMsgBlock->data &
+               ~PAGE_MASK),
+-              pAC->RxBufSize - 2,
++              pRxPort->RxBufSize - 2,
+               PCI_DMA_FROMDEVICE);
+       pRxd->VDataLow  = (SK_U32) (PhysAddr & 0xffffffff);
+@@ -1973,7 +3064,7 @@
+       pRxd = pRxPort->pRxdRingTail;
+       pRxPort->pRxdRingTail = pRxd->pNextRxd;
+       pRxPort->RxdRingFree--;
+-      Length = pAC->RxBufSize;
++      Length = pRxPort->RxBufSize;
+       pRxd->VDataLow  = PhysLow;
+       pRxd->VDataHigh = PhysHigh;
+@@ -1998,33 +3089,40 @@
+  * Returns:   N/A
+  */
+ static void ReceiveIrq(
+-      SK_AC           *pAC,                   /* pointer to adapter context */
+-      RX_PORT         *pRxPort,               /* pointer to receive port struct */
+-      SK_BOOL         SlowPathLock)   /* indicates if SlowPathLock is needed */
+-{
+-RXD                           *pRxd;                  /* pointer to receive descriptors */
+-SK_U32                        Control;                /* control field of descriptor */
+-struct sk_buff        *pMsg;                  /* pointer to message holding frame */
+-struct sk_buff        *pNewMsg;               /* pointer to a new message for copying frame */
+-int                           FrameLength;    /* total length of received frame */
+-int                           IpFrameLength;
+-SK_MBUF                       *pRlmtMbuf;             /* ptr to a buffer for giving a frame to rlmt */
+-SK_EVPARA             EvPara;                 /* an event parameter union */  
+-unsigned long Flags;                  /* for spin lock */
+-int                           PortIndex = pRxPort->PortIndex;
+-unsigned int  Offset;
+-unsigned int  NumBytes;
+-unsigned int  ForRlmt;
+-SK_BOOL                       IsBc;
+-SK_BOOL                       IsMc;
+-SK_BOOL  IsBadFrame;                  /* Bad frame */
+-
+-SK_U32                        FrameStat;
+-unsigned short        Csum1;
+-unsigned short        Csum2;
+-unsigned short        Type;
+-int                           Result;
+-SK_U64                        PhysAddr;
++#ifdef CONFIG_SK98LIN_NAPI
++SK_AC    *pAC,          /* pointer to adapter context          */
++RX_PORT  *pRxPort,      /* pointer to receive port struct      */
++SK_BOOL   SlowPathLock, /* indicates if SlowPathLock is needed */
++int      *WorkDone,
++int       WorkToDo)
++#else
++SK_AC    *pAC,          /* pointer to adapter context          */
++RX_PORT  *pRxPort,      /* pointer to receive port struct      */
++SK_BOOL   SlowPathLock) /* indicates if SlowPathLock is needed */
++#endif
++{
++      RXD             *pRxd;          /* pointer to receive descriptors         */
++      struct sk_buff  *pMsg;          /* pointer to message holding frame       */
++      struct sk_buff  *pNewMsg;       /* pointer to new message for frame copy  */
++      SK_MBUF         *pRlmtMbuf;     /* ptr to buffer for giving frame to RLMT */
++      SK_EVPARA        EvPara;        /* an event parameter union        */   
++      SK_U32           Control;       /* control field of descriptor     */
++      unsigned long    Flags;         /* for spin lock handling          */
++      int              PortIndex = pRxPort->PortIndex;
++      int              FrameLength;   /* total length of received frame  */
++      int              IpFrameLength; /* IP length of the received frame */
++      unsigned int     Offset;
++      unsigned int     NumBytes;
++      unsigned int     RlmtNotifier;
++      SK_BOOL          IsBc;          /* we received a broadcast packet  */
++      SK_BOOL          IsMc;          /* we received a multicast packet  */
++      SK_BOOL          IsBadFrame;    /* the frame received is bad!      */
++      SK_U32           FrameStat;
++      unsigned short   Csum1;
++      unsigned short   Csum2;
++      unsigned short   Type;
++      int              Result;
++      SK_U64           PhysAddr;
+ rx_start:     
+       /* do forever; exit if BMU_OWN found */
+@@ -2046,6 +3144,13 @@
+               Control = pRxd->RBControl;
+       
++#ifdef CONFIG_SK98LIN_NAPI
++              if (*WorkDone >= WorkToDo) {
++                      break;
++              }
++              (*WorkDone)++;
++#endif
++
+               /* check if this descriptor is ready */
+               if ((Control & BMU_OWN) != 0) {
+                       /* this descriptor is not yet ready */
+@@ -2054,11 +3159,10 @@
+                       FillRxRing(pAC, pRxPort);
+                       return;
+               }
+-                pAC->DynIrqModInfo.NbrProcessedDescr++;
+               /* get length of frame and check it */
+               FrameLength = Control & BMU_BBC;
+-              if (FrameLength > pAC->RxBufSize) {
++              if (FrameLength > pRxPort->RxBufSize) {
+                       goto rx_failed;
+               }
+@@ -2073,8 +3177,8 @@
+               FrameStat = pRxd->FrameStat;
+               /* check for frame length mismatch */
+-#define XMR_FS_LEN_SHIFT        18
+-#define GMR_FS_LEN_SHIFT        16
++#define XMR_FS_LEN_SHIFT      18
++#define GMR_FS_LEN_SHIFT      16
+               if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+                       if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) {
+                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+@@ -2084,8 +3188,7 @@
+                                       (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
+                               goto rx_failed;
+                       }
+-              }
+-              else {
++              } else {
+                       if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) {
+                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                                       SK_DBGCAT_DRV_RX_PROGRESS,
+@@ -2118,9 +3221,6 @@
+ /* DumpMsg(pMsg, "Rx");       */
+               if ((Control & BMU_STAT_VAL) != BMU_STAT_VAL || (IsBadFrame)) {
+-#if 0
+-                      (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) {
+-#endif
+                       /* there is a receive error in this frame */
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+                               SK_DBGCAT_DRV_RX_PROGRESS,
+@@ -2128,6 +3228,20 @@
+                               "Control: %x\nRxStat: %x\n",
+                               Control, FrameStat));
++                      PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
++                      PhysAddr |= (SK_U64) pRxd->VDataLow;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5)
++                      pci_dma_sync_single(pAC->PciDev,
++                                              (dma_addr_t) PhysAddr,
++                                              FrameLength,
++                                              PCI_DMA_FROMDEVICE);
++#else
++                      pci_dma_sync_single_for_cpu(pAC->PciDev,
++                                              (dma_addr_t) PhysAddr,
++                                              FrameLength,
++                                              PCI_DMA_FROMDEVICE);
++#endif
+                       ReQueueRxBuffer(pAC, pRxPort, pMsg,
+                               pRxd->VDataHigh, pRxd->VDataLow);
+@@ -2147,150 +3261,107 @@
+                       skb_put(pNewMsg, FrameLength);
+                       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+                       PhysAddr |= (SK_U64) pRxd->VDataLow;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5)
++                      pci_dma_sync_single(pAC->PciDev,
++                                              (dma_addr_t) PhysAddr,
++                                              FrameLength,
++                                              PCI_DMA_FROMDEVICE);
++#else
++                      pci_dma_sync_single_for_device(pAC->PciDev,
++                                              (dma_addr_t) PhysAddr,
++                                              FrameLength,
++                                              PCI_DMA_FROMDEVICE);
++#endif
+-                      pci_dma_sync_single_for_cpu(pAC->PciDev,
+-                                                  (dma_addr_t) PhysAddr,
+-                                                  FrameLength,
+-                                                  PCI_DMA_FROMDEVICE);
+                       eth_copy_and_sum(pNewMsg, pMsg->data,
+                               FrameLength, 0);
+-                      pci_dma_sync_single_for_device(pAC->PciDev,
+-                                                     (dma_addr_t) PhysAddr,
+-                                                     FrameLength,
+-                                                     PCI_DMA_FROMDEVICE);
+                       ReQueueRxBuffer(pAC, pRxPort, pMsg,
+                               pRxd->VDataHigh, pRxd->VDataLow);
+                       pMsg = pNewMsg;
+-              }
+-              else {
++              } else {
+                       /*
+                        * if large frame, or SKB allocation failed, pass
+                        * the SKB directly to the networking
+                        */
+-
+                       PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+                       PhysAddr |= (SK_U64) pRxd->VDataLow;
+                       /* release the DMA mapping */
+                       pci_unmap_single(pAC->PciDev,
+                                        PhysAddr,
+-                                       pAC->RxBufSize - 2,
++                                       pRxPort->RxBufSize - 2,
+                                        PCI_DMA_FROMDEVICE);
++                      skb_put(pMsg, FrameLength); /* set message len */
++                      pMsg->ip_summed = CHECKSUM_NONE; /* initial default */
+-                      /* set length in message */
+-                      skb_put(pMsg, FrameLength);
+-                      /* hardware checksum */
+-                      Type = ntohs(*((short*)&pMsg->data[12]));
+-
+-#ifdef USE_SK_RX_CHECKSUM
+-                      if (Type == 0x800) {
+-                              Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff);
+-                              Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff);
+-                              IpFrameLength = (int) ntohs((unsigned short)
+-                                                              ((unsigned short *) pMsg->data)[8]);
+-
+-                              /*
+-                               * Test: If frame is padded, a check is not possible!
+-                               * Frame not padded? Length difference must be 14 (0xe)!
+-                               */
+-                              if ((FrameLength - IpFrameLength) != 0xe) {
+-                              /* Frame padded => TCP offload not possible! */
+-                                      pMsg->ip_summed = CHECKSUM_NONE;
+-                              } else {
+-                              /* Frame not padded => TCP offload! */
+-                                      if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) &&
+-                                              (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) ||
+-                                              (pAC->ChipsetType)) {
+-                                              Result = SkCsGetReceiveInfo(pAC,
+-                                                      &pMsg->data[14],
+-                                                      Csum1, Csum2, pRxPort->PortIndex);
+-                                              if (Result ==
+-                                                      SKCS_STATUS_IP_FRAGMENT ||
+-                                                      Result ==
+-                                                      SKCS_STATUS_IP_CSUM_OK ||
+-                                                      Result ==
+-                                                      SKCS_STATUS_TCP_CSUM_OK ||
+-                                                      Result ==
+-                                                      SKCS_STATUS_UDP_CSUM_OK) {
+-                                                              pMsg->ip_summed =
+-                                                              CHECKSUM_UNNECESSARY;
+-                                              }
+-                                              else if (Result ==
+-                                                      SKCS_STATUS_TCP_CSUM_ERROR ||
+-                                                      Result ==
+-                                                      SKCS_STATUS_UDP_CSUM_ERROR ||
+-                                                      Result ==
+-                                                      SKCS_STATUS_IP_CSUM_ERROR_UDP ||
+-                                                      Result ==
+-                                                      SKCS_STATUS_IP_CSUM_ERROR_TCP ||
+-                                                      Result ==
+-                                                      SKCS_STATUS_IP_CSUM_ERROR ) {
+-                                                      /* HW Checksum error */
+-                                                      SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+-                                                      SK_DBGCAT_DRV_RX_PROGRESS,
+-                                                      ("skge: CRC error. Frame dropped!\n"));
+-                                                      goto rx_failed;
+-                                              } else {
+-                                                              pMsg->ip_summed =
+-                                                              CHECKSUM_NONE;
+-                                              }
+-                                      }/* checksumControl calculation valid */
+-                              } /* Frame length check */
+-                      } /* IP frame */
+-#else
+-                      pMsg->ip_summed = CHECKSUM_NONE;        
+-#endif
++                      if (pRxPort->UseRxCsum) {
++                              Type = ntohs(*((short*)&pMsg->data[12]));
++                              if (Type == 0x800) {
++                                      IpFrameLength = (int) ntohs((unsigned short)
++                                                      ((unsigned short *) pMsg->data)[8]);
++                                      if ((FrameLength - IpFrameLength) == 0xe) {
++                                              Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff);
++                                              Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff);
++                                              if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) &&
++                                                      (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) ||
++                                                      (pAC->ChipsetType)) {
++                                                      Result = SkCsGetReceiveInfo(pAC, &pMsg->data[14],
++                                                              Csum1, Csum2, PortIndex);
++                                                      if ((Result == SKCS_STATUS_IP_FRAGMENT) ||
++                                                          (Result == SKCS_STATUS_IP_CSUM_OK)  ||
++                                                          (Result == SKCS_STATUS_TCP_CSUM_OK) ||
++                                                          (Result == SKCS_STATUS_UDP_CSUM_OK)) {
++                                                              pMsg->ip_summed = CHECKSUM_UNNECESSARY;
++                                                      } else if ((Result == SKCS_STATUS_TCP_CSUM_ERROR)    ||
++                                                                 (Result == SKCS_STATUS_UDP_CSUM_ERROR)    ||
++                                                                 (Result == SKCS_STATUS_IP_CSUM_ERROR_UDP) ||
++                                                                 (Result == SKCS_STATUS_IP_CSUM_ERROR_TCP) ||
++                                                                 (Result == SKCS_STATUS_IP_CSUM_ERROR)) {
++                                                              /* HW Checksum error */
++                                                              SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
++                                                              SK_DBGCAT_DRV_RX_PROGRESS,
++                                                              ("skge: CRC error. Frame dropped!\n"));
++                                                              goto rx_failed;
++                                                      } else {
++                                                              pMsg->ip_summed = CHECKSUM_NONE;
++                                                      }
++                                              }/* checksumControl calculation valid */
++                                      } /* Frame length check */
++                              } /* IP frame */
++                      } /* pRxPort->UseRxCsum */
+               } /* frame > SK_COPY_TRESHOLD */
+               
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V"));
+-              ForRlmt = SK_RLMT_RX_PROTOCOL;
+-#if 0
+-              IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
+-#endif
++              RlmtNotifier = SK_RLMT_RX_PROTOCOL;
+               SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
+-                      IsBc, &Offset, &NumBytes);
++                                      IsBc, &Offset, &NumBytes);
+               if (NumBytes != 0) {
+-#if 0
+-                      IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
+-#endif
+-                      SK_RLMT_LOOKAHEAD(pAC, PortIndex,
+-                              &pMsg->data[Offset],
+-                              IsBc, IsMc, &ForRlmt);
++                      SK_RLMT_LOOKAHEAD(pAC,PortIndex,&pMsg->data[Offset],
++                                              IsBc,IsMc,&RlmtNotifier);
+               }
+-              if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
+-                                      SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W"));
++              if (RlmtNotifier == SK_RLMT_RX_PROTOCOL) {
++                      SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W"));
+                       /* send up only frames from active port */
+-                      if ((PortIndex == pAC->ActivePort) ||
+-                              (pAC->RlmtNets == 2)) {
+-                              /* frame for upper layer */
++                      if ((PortIndex == pAC->ActivePort)||(pAC->RlmtNets == 2)) {
+                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U"));
+ #ifdef xDEBUG
+                               DumpMsg(pMsg, "Rx");
+ #endif
+-                              SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
+-                                      FrameLength, pRxPort->PortIndex);
+-
+-                              pMsg->dev = pAC->dev[pRxPort->PortIndex];
+-                              pMsg->protocol = eth_type_trans(pMsg,
+-                                      pAC->dev[pRxPort->PortIndex]);
+-                              netif_rx(pMsg);
+-                              pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
+-                      }
+-                      else {
+-                              /* drop frame */
++                              SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,FrameLength,PortIndex);
++                              pMsg->dev = pAC->dev[PortIndex];
++                              pMsg->protocol = eth_type_trans(pMsg,pAC->dev[PortIndex]);
++                              netif_rx(pMsg); /* frame for upper layer */
++                              pAC->dev[PortIndex]->last_rx = jiffies;
++                      } else {
+                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+-                                      SK_DBGCAT_DRV_RX_PROGRESS,
+-                                      ("D"));
+-                              DEV_KFREE_SKB(pMsg);
++                                      SK_DBGCAT_DRV_RX_PROGRESS,("D"));
++                              DEV_KFREE_SKB(pMsg); /* drop frame */
+                       }
+-                      
+-              } /* if not for rlmt */
+-              else {
+-                      /* packet for rlmt */
++              } else { /* packet for RLMT stack */
+                       SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+-                              SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
++                              SK_DBGCAT_DRV_RX_PROGRESS,("R"));
+                       pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
+                               pAC->IoBase, FrameLength);
+                       if (pRlmtMbuf != NULL) {
+@@ -2318,32 +3389,22 @@
+                               }
+                               SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+-                                      SK_DBGCAT_DRV_RX_PROGRESS,
+-                                      ("Q"));
++                                      SK_DBGCAT_DRV_RX_PROGRESS,("Q"));
+                       }
+-                      if ((pAC->dev[pRxPort->PortIndex]->flags &
+-                              (IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
+-                              (ForRlmt & SK_RLMT_RX_PROTOCOL) ==
+-                              SK_RLMT_RX_PROTOCOL) {
+-                              pMsg->dev = pAC->dev[pRxPort->PortIndex];
+-                              pMsg->protocol = eth_type_trans(pMsg,
+-                                      pAC->dev[pRxPort->PortIndex]);
++                      if ((pAC->dev[PortIndex]->flags & (IFF_PROMISC | IFF_ALLMULTI)) ||
++                          (RlmtNotifier & SK_RLMT_RX_PROTOCOL)) {
++                              pMsg->dev = pAC->dev[PortIndex];
++                              pMsg->protocol = eth_type_trans(pMsg,pAC->dev[PortIndex]);
+                               netif_rx(pMsg);
+-                              pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
+-                      }
+-                      else {
++                              pAC->dev[PortIndex]->last_rx = jiffies;
++                      } else {
+                               DEV_KFREE_SKB(pMsg);
+                       }
+-
+-              } /* if packet for rlmt */
++              } /* if packet for RLMT stack */
+       } /* for ... scanning the RXD ring */
+       /* RXD ring is empty -> fill and restart */
+       FillRxRing(pAC, pRxPort);
+-      /* do not start if called from Close */
+-      if (pAC->BoardLevel > SK_INIT_DATA) {
+-              ClearAndStartRx(pAC, PortIndex);
+-      }
+       return;
+ rx_failed:
+@@ -2357,7 +3418,7 @@
+       PhysAddr |= (SK_U64) pRxd->VDataLow;
+       pci_unmap_page(pAC->PciDev,
+                        PhysAddr,
+-                       pAC->RxBufSize - 2,
++                       pRxPort->RxBufSize - 2,
+                        PCI_DMA_FROMDEVICE);
+       DEV_KFREE_SKB_IRQ(pRxd->pMBuf);
+       pRxd->pMBuf = NULL;
+@@ -2367,49 +3428,6 @@
+ } /* ReceiveIrq */
+-
+-/*****************************************************************************
+- *
+- *    ClearAndStartRx - give a start receive command to BMU, clear IRQ
+- *
+- * Description:
+- *    This function sends a start command and a clear interrupt
+- *    command for one receive queue to the BMU.
+- *
+- * Returns: N/A
+- *    none
+- */
+-static void ClearAndStartRx(
+-SK_AC *pAC,           /* pointer to the adapter context */
+-int   PortIndex)      /* index of the receive port (XMAC) */
+-{
+-      SK_OUT8(pAC->IoBase,
+-              RxQueueAddr[PortIndex]+Q_CSR,
+-              CSR_START | CSR_IRQ_CL_F);
+-} /* ClearAndStartRx */
+-
+-
+-/*****************************************************************************
+- *
+- *    ClearTxIrq - give a clear transmit IRQ command to BMU
+- *
+- * Description:
+- *    This function sends a clear tx IRQ command for one
+- *    transmit queue to the BMU.
+- *
+- * Returns: N/A
+- */
+-static void ClearTxIrq(
+-SK_AC *pAC,           /* pointer to the adapter context */
+-int   PortIndex,      /* index of the transmit port (XMAC) */
+-int   Prio)           /* priority or normal queue */
+-{
+-      SK_OUT8(pAC->IoBase, 
+-              TxQueueAddr[PortIndex][Prio]+Q_CSR,
+-              CSR_IRQ_CL_F);
+-} /* ClearTxIrq */
+-
+-
+ /*****************************************************************************
+  *
+  *    ClearRxRing - remove all buffers from the receive ring
+@@ -2440,7 +3458,7 @@
+                       PhysAddr |= (SK_U64) pRxd->VDataLow;
+                       pci_unmap_page(pAC->PciDev,
+                                        PhysAddr,
+-                                       pAC->RxBufSize - 2,
++                                       pRxPort->RxBufSize - 2,
+                                        PCI_DMA_FROMDEVICE);
+                       DEV_KFREE_SKB(pRxd->pMBuf);
+                       pRxd->pMBuf = NULL;
+@@ -2500,29 +3518,30 @@
+ DEV_NET *pNet = (DEV_NET*) dev->priv;
+ SK_AC *pAC = pNet->pAC;
++int   Ret;
+ struct sockaddr       *addr = p;
+ unsigned long Flags;
+       
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeSetMacAddr starts now...\n"));
+-      if(netif_running(dev))
+-              return -EBUSY;
+       memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
+       
+       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+       if (pAC->RlmtNets == 2)
+-              SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr,
++              Ret = SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr,
+                       (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
+       else
+-              SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
++              Ret = SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
+                       (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
+-
+-      
+       
+       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
++
++      if (Ret != SK_ADDR_OVERRIDE_SUCCESS)
++              return -EBUSY;
++
+       return 0;
+ } /* SkGeSetMacAddr */
+@@ -2604,6 +3623,45 @@
+ /*****************************************************************************
+  *
++ *    SkSetMtuBufferSize - set the MTU buffer to another value
++ *
++ * Description:
++ *    This function sets the new buffers and is called whenever the MTU 
++ *      size is changed
++ *
++ * Returns:
++ *    N/A
++ */
++
++static void SkSetMtuBufferSize(
++SK_AC *pAC,           /* pointer to adapter context */
++int   PortNr,         /* Port number */
++int   Mtu)            /* pointer to tx prt struct */
++{
++      pAC->RxPort[PortNr].RxBufSize = Mtu + 32;
++
++      /* RxBufSize must be a multiple of 8 */
++      while (pAC->RxPort[PortNr].RxBufSize % 8) {
++              pAC->RxPort[PortNr].RxBufSize = 
++                      pAC->RxPort[PortNr].RxBufSize + 1;
++      }
++
++      if (Mtu > 1500) {
++              pAC->GIni.GP[PortNr].PPortUsage = SK_JUMBO_LINK;
++      } else {
++              if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
++                      pAC->GIni.GP[PortNr].PPortUsage = SK_MUL_LINK;
++              } else {
++                      pAC->GIni.GP[PortNr].PPortUsage = SK_RED_LINK;
++              }
++      }
++
++      return;
++}
++
++
++/*****************************************************************************
++ *
+  *    SkGeChangeMtu - set the MTU to another value
+  *
+  * Description:
+@@ -2617,12 +3675,13 @@
+  */
+ static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu)
+ {
+-DEV_NET               *pNet;
+-DEV_NET               *pOtherNet;
+-SK_AC         *pAC;
+-unsigned long Flags;
+-int           i;
+-SK_EVPARA     EvPara;
++DEV_NET                       *pNet;
++SK_AC                 *pAC;
++unsigned long         Flags;
++#ifdef CONFIG_SK98LIN_NAPI
++int                   WorkToDo = 1; // min(*budget, dev->quota);
++int                   WorkDone = 0;
++#endif
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeChangeMtu starts now...\n"));
+@@ -2630,15 +3689,12 @@
+       pNet = (DEV_NET*) dev->priv;
+       pAC  = pNet->pAC;
++      /* MTU size outside the spec */
+       if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
+               return -EINVAL;
+       }
+-      if(pAC->BoardLevel != SK_INIT_RUN) {
+-              return -EINVAL;
+-      }
+-
+-#ifdef SK_DIAG_SUPPORT
++      /* Diag access active */
+       if (pAC->DiagModeActive == DIAG_ACTIVE) {
+               if (pAC->DiagFlowCtrl == SK_FALSE) {
+                       return -1; /* still in use, deny any actions of MTU */
+@@ -2646,200 +3702,74 @@
+                       pAC->DiagFlowCtrl = SK_FALSE;
+               }
+       }
+-#endif
+-
+-      pNet->Mtu = NewMtu;
+-      pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv;
+-      if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) {
+-              return(0);
+-      }
+-      pAC->RxBufSize = NewMtu + 32;
+       dev->mtu = NewMtu;
++      SkSetMtuBufferSize(pAC, pNet->PortNr, NewMtu);
+-      SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+-              ("New MTU: %d\n", NewMtu));
++      if(!netif_running(dev)) {
++      /* Preset MTU size if device not ready/running */
++              return 0;
++      }
+-      /* 
+-      ** Prevent any reconfiguration while changing the MTU 
+-      ** by disabling any interrupts 
+-      */
++      /*  Prevent any reconfiguration while changing the MTU 
++          by disabling any interrupts */
+       SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+-      /* 
+-      ** Notify RLMT that any ports are to be stopped
+-      */
+-      EvPara.Para32[0] =  0;
+-      EvPara.Para32[1] = -1;
+-      if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
+-              SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+-              EvPara.Para32[0] =  1;
+-              SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+-      } else {
+-              SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+-      }
+-
+-      /*
+-      ** After calling the SkEventDispatcher(), RLMT is aware about
+-      ** the stopped ports -> configuration can take place!
+-      */
+-      SkEventDispatcher(pAC, pAC->IoBase);
+-
+-      for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+-              spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
+-              netif_stop_queue(pAC->dev[i]);
++      /* Notify RLMT that the port has to be stopped */
++      netif_stop_queue(dev);
++      SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP,
++                              pNet->PortNr, -1, SK_TRUE);
++      spin_lock(&pAC->TxPort[pNet->PortNr][TX_PRIO_LOW].TxDesRingLock);
+-      }
+-      /*
+-      ** Depending on the desired MTU size change, a different number of 
+-      ** RX buffers need to be allocated
+-      */
+-      if (NewMtu > 1500) {
+-          /* 
+-          ** Use less rx buffers 
+-          */
+-          for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+-              if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
+-                  pAC->RxPort[i].RxFillLimit =  pAC->RxDescrPerRing -
+-                                               (pAC->RxDescrPerRing / 4);
+-              } else {
+-                  if (i == pAC->ActivePort) {
+-                      pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 
+-                                                  (pAC->RxDescrPerRing / 4);
+-                  } else {
+-                      pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 
+-                                                  (pAC->RxDescrPerRing / 10);
+-                  }
+-              }
+-          }
++      /* Change RxFillLimit to 1 */
++      if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
++              pAC->RxPort[pNet->PortNr].RxFillLimit = 1;
+       } else {
+-          /* 
+-          ** Use the normal amount of rx buffers 
+-          */
+-          for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+-              if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
+-                  pAC->RxPort[i].RxFillLimit = 1;
+-              } else {
+-                  if (i == pAC->ActivePort) {
+-                      pAC->RxPort[i].RxFillLimit = 1;
+-                  } else {
+-                      pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
+-                                                  (pAC->RxDescrPerRing / 4);
+-                  }
+-              }
+-          }
++              pAC->RxPort[1 - pNet->PortNr].RxFillLimit = 1;
++              pAC->RxPort[pNet->PortNr].RxFillLimit = pAC->RxDescrPerRing -
++                                      (pAC->RxDescrPerRing / 4);
+       }
+-      
+-      SkGeDeInit(pAC, pAC->IoBase);
+-      /*
+-      ** enable/disable hardware support for long frames
+-      */
+-      if (NewMtu > 1500) {
+-// pAC->JumboActivated = SK_TRUE; /* is never set back !!! */
+-              pAC->GIni.GIPortUsage = SK_JUMBO_LINK;
++      /* clear and reinit the rx rings here, because of new MTU size */
++      if (CHIP_ID_YUKON_2(pAC)) {
++              SkY2PortStop(pAC, pAC->IoBase, pNet->PortNr, SK_STOP_ALL, SK_SOFT_RST);
++              SkY2AllocateRxBuffers(pAC, pAC->IoBase, pNet->PortNr);
++              SkY2PortStart(pAC, pAC->IoBase, pNet->PortNr);
+       } else {
+-          if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
+-              pAC->GIni.GIPortUsage = SK_MUL_LINK;
+-          } else {
+-              pAC->GIni.GIPortUsage = SK_RED_LINK;
+-          }
+-      }
++//            SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr, SK_STOP_ALL, SK_SOFT_RST);
++#ifdef CONFIG_SK98LIN_NAPI
++              WorkToDo = 1;
++              ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE, &WorkDone, WorkToDo);
++#else
++              ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);
++#endif
++              ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
++              FillRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
+-      SkGeInit(   pAC, pAC->IoBase, SK_INIT_IO);
+-      SkI2cInit(  pAC, pAC->IoBase, SK_INIT_IO);
+-      SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
+-      SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
+-      SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
+-      SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
+-      SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
+-      
+-      /*
+-      ** tschilling:
+-      ** Speed and others are set back to default in level 1 init!
+-      */
+-      GetConfiguration(pAC);
+-      
+-      SkGeInit(   pAC, pAC->IoBase, SK_INIT_RUN);
+-      SkI2cInit(  pAC, pAC->IoBase, SK_INIT_RUN);
+-      SkEventInit(pAC, pAC->IoBase, SK_INIT_RUN);
+-      SkPnmiInit( pAC, pAC->IoBase, SK_INIT_RUN);
+-      SkAddrInit( pAC, pAC->IoBase, SK_INIT_RUN);
+-      SkRlmtInit( pAC, pAC->IoBase, SK_INIT_RUN);
+-      SkTimerInit(pAC, pAC->IoBase, SK_INIT_RUN);
++              /* Enable transmit descriptor polling */
++              SkGePollTxD(pAC, pAC->IoBase, pNet->PortNr, SK_TRUE);
++              FillRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
++      }
+-      /*
+-      ** clear and reinit the rx rings here
+-      */
+-      for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+-              ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
+-              ClearRxRing(pAC, &pAC->RxPort[i]);
+-              FillRxRing(pAC, &pAC->RxPort[i]);
++      netif_start_queue(pAC->dev[pNet->PortNr]);
+-              /* 
+-              ** Enable transmit descriptor polling
+-              */
+-              SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
+-              FillRxRing(pAC, &pAC->RxPort[i]);
+-      };
++      spin_unlock(&pAC->TxPort[pNet->PortNr][TX_PRIO_LOW].TxDesRingLock);
+-      SkGeYellowLED(pAC, pAC->IoBase, 1);
+-      SkDimEnableModerationIfNeeded(pAC);     
+-      SkDimDisplayModerationSettings(pAC);
+-      netif_start_queue(pAC->dev[pNet->PortNr]);
+-      for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) {
+-              spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
+-      }
++      /* Notify RLMT about the changing and restarting one (or more) ports */
++      SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_START,
++                                      pNet->PortNr, -1, SK_TRUE);
+-      /* 
+-      ** Enable Interrupts again 
+-      */
++      /* Enable Interrupts again */
+       SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
+       SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
+-      SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+-      SkEventDispatcher(pAC, pAC->IoBase);
+-
+-      /* 
+-      ** Notify RLMT about the changing and restarting one (or more) ports
+-      */
+-      if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
+-              EvPara.Para32[0] = pAC->RlmtNets;
+-              EvPara.Para32[1] = -1;
+-              SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, EvPara);
+-              EvPara.Para32[0] = pNet->PortNr;
+-              EvPara.Para32[1] = -1;
+-              SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+-                      
+-              if (pOtherNet->Up) {
+-                      EvPara.Para32[0] = pOtherNet->PortNr;
+-                      SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+-              }
+-      } else {
+-              SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+-      }
+-
+-      SkEventDispatcher(pAC, pAC->IoBase);
+       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+-      
+-      /*
+-      ** While testing this driver with latest kernel 2.5 (2.5.70), it 
+-      ** seems as if upper layers have a problem to handle a successful
+-      ** return value of '0'. If such a zero is returned, the complete 
+-      ** system hangs for several minutes (!), which is in acceptable.
+-      **
+-      ** Currently it is not clear, what the exact reason for this problem
+-      ** is. The implemented workaround for 2.5 is to return the desired 
+-      ** new MTU size if all needed changes for the new MTU size where 
+-      ** performed. In kernels 2.2 and 2.4, a zero value is returned,
+-      ** which indicates the successful change of the mtu-size.
+-      */
+-      return NewMtu;
++      return 0;
+-} /* SkGeChangeMtu */
++}
+ /*****************************************************************************
+@@ -2857,42 +3787,38 @@
+ {
+ DEV_NET *pNet = (DEV_NET*) dev->priv;
+ SK_AC *pAC = pNet->pAC;
+-SK_PNMI_STRUCT_DATA *pPnmiStruct;       /* structure for all Pnmi-Data */
+-SK_PNMI_STAT    *pPnmiStat;             /* pointer to virtual XMAC stat. data */
+-SK_PNMI_CONF    *pPnmiConf;             /* pointer to virtual link config. */
+-unsigned int    Size;                   /* size of pnmi struct */
++SK_PNMI_STRUCT_DATA *pPnmiStruct;     /* structure for all Pnmi-Data */
++SK_PNMI_STAT    *pPnmiStat;           /* pointer to virtual XMAC stat. data */
++SK_PNMI_CONF    *pPnmiConf;           /* pointer to virtual link config. */
++unsigned int    Size;                 /* size of pnmi struct */
+ unsigned long Flags;                  /* for spin lock */
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeStats starts now...\n"));
+       pPnmiStruct = &pAC->PnmiStruct;
+-#ifdef SK_DIAG_SUPPORT
+-        if ((pAC->DiagModeActive == DIAG_NOTACTIVE) &&
+-                (pAC->BoardLevel == SK_INIT_RUN)) {
+-#endif
+-        SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
+-        spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+-        Size = SK_PNMI_STRUCT_SIZE;
+-              SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
+-        spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+-#ifdef SK_DIAG_SUPPORT
++      if ((pAC->DiagModeActive == DIAG_NOTACTIVE) &&
++              (pAC->BoardLevel == SK_INIT_RUN)) {
++              SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
++              spin_lock_irqsave(&pAC->SlowPathLock, Flags);
++              Size = SK_PNMI_STRUCT_SIZE;
++                      SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
++              spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+       }
+-#endif
+-        pPnmiStat = &pPnmiStruct->Stat[0];
+-        pPnmiConf = &pPnmiStruct->Conf[0];
++      pPnmiStat = &pPnmiStruct->Stat[0];
++      pPnmiConf = &pPnmiStruct->Conf[0];
+       pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF;
+       pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF;
+       pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
+       pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
+       
+-        if (pNet->Mtu <= 1500) {
+-                pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
+-        } else {
+-                pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
+-                        pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF);
++      if (dev->mtu <= 1500) {
++              pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
++      } else {
++              pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
++                      pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF);
+       }
+@@ -2937,32 +3863,35 @@
+  *    0, if everything is ok
+  *    !=0, on error
+  */
+-static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd)
+-{
+-DEV_NET               *pNet;
+-SK_AC         *pAC;
+-void          *pMemBuf;
+-struct pci_dev  *pdev = NULL;
+-SK_GE_IOCTL   Ioctl;
+-unsigned int  Err = 0;
+-int           Size = 0;
+-int             Ret = 0;
+-unsigned int  Length = 0;
+-int           HeaderLength = sizeof(SK_U32) + sizeof(SK_U32);
++static int SkGeIoctl(
++struct SK_NET_DEVICE *dev,  /* the device the IOCTL is to be performed on   */
++struct ifreq         *rq,   /* additional request structure containing data */
++int                   cmd)  /* requested IOCTL command number               */
++{
++      DEV_NET          *pNet = (DEV_NET*) dev->priv;
++      SK_AC            *pAC  = pNet->pAC;
++      struct pci_dev   *pdev = NULL;
++      void             *pMemBuf;
++      SK_GE_IOCTL       Ioctl;
++      unsigned long     Flags; /* for spin lock */
++      unsigned int      Err = 0;
++      unsigned int      Length = 0;
++      int               HeaderLength = sizeof(SK_U32) + sizeof(SK_U32);
++      int               Size = 0;
++      int               Ret = 0;
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeIoctl starts now...\n"));
+-      pNet = (DEV_NET*) dev->priv;
+-      pAC = pNet->pAC;
+-      
+       if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
+               return -EFAULT;
+       }
+       switch(cmd) {
+-      case SK_IOCTL_SETMIB:
+-      case SK_IOCTL_PRESETMIB:
++      case SIOCETHTOOL:
++              return SkEthIoctl(dev, rq);
++      case SK_IOCTL_SETMIB:     /* FALL THRU */
++      case SK_IOCTL_PRESETMIB:  /* FALL THRU (if capable!) */
+               if (!capable(CAP_NET_ADMIN)) return -EPERM;
+       case SK_IOCTL_GETMIB:
+               if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData,
+@@ -2989,6 +3918,7 @@
+               if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
+                       return -ENOMEM;
+               }
++              spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+               if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
+                       Err = -EFAULT;
+                       goto fault_gen;
+@@ -3007,10 +3937,10 @@
+                       goto fault_gen;
+               }
+ fault_gen:
++              spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+               kfree(pMemBuf); /* cleanup everything */
+               break;
+-#ifdef SK_DIAG_SUPPORT
+-       case SK_IOCTL_DIAG:
++      case SK_IOCTL_DIAG:
+               if (!capable(CAP_NET_ADMIN)) return -EPERM;
+               if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
+                       Length = Ioctl.Len;
+@@ -3034,7 +3964,7 @@
+               */
+               * ((SK_U32 *)pMemBuf) = 0;
+               * ((SK_U32 *)pMemBuf + 1) = pdev->bus->number;
+-              * ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pdev->slot_name);
++              * ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pci_name(pdev));
+               if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
+                       Err = -EFAULT;
+                       goto fault_diag;
+@@ -3047,7 +3977,6 @@
+ fault_diag:
+               kfree(pMemBuf); /* cleanup everything */
+               break;
+-#endif
+       default:
+               Err = -EOPNOTSUPP;
+       }
+@@ -3079,12 +4008,12 @@
+ unsigned int  Size,   /* length of ioctl data */
+ int           mode)   /* flag for set/preset */
+ {
+-unsigned long Flags;  /* for spin lock */
+-SK_AC         *pAC;
++      SK_AC           *pAC = pNet->pAC;
++      unsigned long   Flags;  /* for spin lock */
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeIocMib starts now...\n"));
+-      pAC = pNet->pAC;
++
+       /* access MIB */
+       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+       switch(mode) {
+@@ -3127,17 +4056,18 @@
+ SK_I32        Port;           /* preferred port */
+ SK_BOOL       AutoSet;
+ SK_BOOL DupSet;
+-int   LinkSpeed          = SK_LSPEED_AUTO;    /* Link speed */
+-int   AutoNeg            = 1;                 /* autoneg off (0) or on (1) */
+-int   DuplexCap          = 0;                 /* 0=both,1=full,2=half */
+-int   FlowCtrl           = SK_FLOW_MODE_SYM_OR_REM;   /* FlowControl  */
+-int   MSMode             = SK_MS_MODE_AUTO;   /* master/slave mode    */
+-
+-SK_BOOL IsConTypeDefined   = SK_TRUE;
+-SK_BOOL IsLinkSpeedDefined = SK_TRUE;
+-SK_BOOL IsFlowCtrlDefined  = SK_TRUE;
+-SK_BOOL IsRoleDefined      = SK_TRUE;
+-SK_BOOL IsModeDefined      = SK_TRUE;
++int   LinkSpeed               = SK_LSPEED_AUTO;       /* Link speed */
++int   AutoNeg                 = 1;                    /* autoneg off (0) or on (1) */
++int   DuplexCap               = 0;                    /* 0=both,1=full,2=half */
++int   FlowCtrl                = SK_FLOW_MODE_SYM_OR_REM;      /* FlowControl  */
++int   MSMode                  = SK_MS_MODE_AUTO;      /* master/slave mode    */
++int   IrqModMaskOffset        = 6;                    /* all ints moderated=default */
++
++SK_BOOL IsConTypeDefined      = SK_TRUE;
++SK_BOOL IsLinkSpeedDefined    = SK_TRUE;
++SK_BOOL IsFlowCtrlDefined     = SK_TRUE;
++SK_BOOL IsRoleDefined         = SK_TRUE;
++SK_BOOL IsModeDefined         = SK_TRUE;
+ /*
+  *    The two parameters AutoNeg. and DuplexCap. map to one configuration
+  *    parameter. The mapping is described by this table:
+@@ -3155,6 +4085,15 @@
+                 {SK_LMODE_AUTOBOTH , SK_LMODE_AUTOFULL , SK_LMODE_AUTOHALF },
+                 {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} };
++SK_U32        IrqModMask[7][2] =
++              { { IRQ_MASK_RX_ONLY , Y2_DRIVER_IRQS  },
++                { IRQ_MASK_TX_ONLY , Y2_DRIVER_IRQS  },
++                { IRQ_MASK_SP_ONLY , Y2_SPECIAL_IRQS },
++                { IRQ_MASK_SP_RX   , Y2_IRQ_MASK     },
++                { IRQ_MASK_TX_RX   , Y2_DRIVER_IRQS  },
++                { IRQ_MASK_SP_TX   , Y2_IRQ_MASK     },
++                { IRQ_MASK_RX_TX_SP, Y2_IRQ_MASK     } };
++
+ #define DC_BOTH       0
+ #define DC_FULL 1
+ #define DC_HALF 2
+@@ -3194,7 +4133,7 @@
+       ** 
+       ** This ConType parameter is used for all ports of the adapter!
+       */
+-        if ( (ConType != NULL)                && 
++      if ( (ConType != NULL)                && 
+            (pAC->Index < SK_MAX_CARD_PARAM) &&
+            (ConType[pAC->Index] != NULL) ) {
+@@ -3220,40 +4159,40 @@
+                       M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
+                       M_CurrPort.PLinkSpeed    = SK_LSPEED_AUTO;
+                   }
+-                } else if (strcmp(ConType[pAC->Index],"100FD")==0) {
++              } else if (strcmp(ConType[pAC->Index],"100FD")==0) {
+                   for (Port = 0; Port < SK_MAX_MACS; Port++) {
+                       M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
+                       M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
+                       M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
+                       M_CurrPort.PLinkSpeed    = SK_LSPEED_100MBPS;
+                   }
+-                } else if (strcmp(ConType[pAC->Index],"100HD")==0) {
++              } else if (strcmp(ConType[pAC->Index],"100HD")==0) {
+                   for (Port = 0; Port < SK_MAX_MACS; Port++) {
+                       M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
+                       M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
+                       M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
+                       M_CurrPort.PLinkSpeed    = SK_LSPEED_100MBPS;
+                   }
+-                } else if (strcmp(ConType[pAC->Index],"10FD")==0) {
++              } else if (strcmp(ConType[pAC->Index],"10FD")==0) {
+                   for (Port = 0; Port < SK_MAX_MACS; Port++) {
+                       M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
+                       M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
+                       M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
+                       M_CurrPort.PLinkSpeed    = SK_LSPEED_10MBPS;
+                   }
+-                } else if (strcmp(ConType[pAC->Index],"10HD")==0) {
++              } else if (strcmp(ConType[pAC->Index],"10HD")==0) {
+                   for (Port = 0; Port < SK_MAX_MACS; Port++) {
+                       M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
+                       M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
+                       M_CurrPort.PMSMode       = SK_MS_MODE_AUTO;
+                       M_CurrPort.PLinkSpeed    = SK_LSPEED_10MBPS;
+                   }
+-                } else { 
++              } else { 
+                   printk("sk98lin: Illegal value \"%s\" for ConType\n", 
+                       ConType[pAC->Index]);
+                   IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */
+               }
+-        } else {
++      } else {
+           IsConTypeDefined = SK_FALSE; /* No ConType defined */
+       }
+@@ -3272,14 +4211,30 @@
+               } else if (strcmp(Speed_A[pAC->Index],"100")==0) {
+                   LinkSpeed = SK_LSPEED_100MBPS;
+               } else if (strcmp(Speed_A[pAC->Index],"1000")==0) {
+-                  LinkSpeed = SK_LSPEED_1000MBPS;
++                  if ((pAC->PciDev->vendor == 0x11ab ) &&
++                      (pAC->PciDev->device == 0x4350)) {
++                              LinkSpeed = SK_LSPEED_100MBPS;
++                              printk("sk98lin: Illegal value \"%s\" for Speed_A.\n"
++                                      "Gigabit speed not possible with this chip revision!",
++                                      Speed_A[pAC->Index]);
++                      } else {
++                              LinkSpeed = SK_LSPEED_1000MBPS;
++                  }
+               } else {
+                   printk("sk98lin: Illegal value \"%s\" for Speed_A\n",
+                       Speed_A[pAC->Index]);
+                   IsLinkSpeedDefined = SK_FALSE;
+               }
+       } else {
+-          IsLinkSpeedDefined = SK_FALSE;
++              if ((pAC->PciDev->vendor == 0x11ab ) && 
++                      (pAC->PciDev->device == 0x4350)) {
++                      /* Gigabit speed not supported
++                       * Swith to speed 100
++                       */
++                      LinkSpeed = SK_LSPEED_100MBPS;
++              } else {
++                      IsLinkSpeedDefined = SK_FALSE;
++              }
+       }
+       /* 
+@@ -3374,9 +4329,6 @@
+       }
+       
+       if (!AutoSet && DupSet) {
+-              printk("sk98lin: Port A: Duplex setting not"
+-                      " possible in\n    default AutoNegotiation mode"
+-                      " (Sense).\n    Using AutoNegotiation On\n");
+               AutoNeg = AN_ON;
+       }
+       
+@@ -3404,7 +4356,7 @@
+                   FlowCtrl = SK_FLOW_MODE_NONE;
+               } else {
+                   printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n",
+-                        FlowCtrl_A[pAC->Index]);
++                      FlowCtrl_A[pAC->Index]);
+                   IsFlowCtrlDefined = SK_FALSE;
+               }
+       } else {
+@@ -3496,7 +4448,7 @@
+       ** Decide whether to set new config value if somethig valid has
+       ** been received.
+       */
+-        if (IsLinkSpeedDefined) {
++      if (IsLinkSpeedDefined) {
+           pAC->GIni.GP[1].PLinkSpeed = LinkSpeed;
+       }
+@@ -3572,9 +4524,6 @@
+       }
+       
+       if (!AutoSet && DupSet) {
+-              printk("sk98lin: Port B: Duplex setting not"
+-                      " possible in\n    default AutoNegotiation mode"
+-                      " (Sense).\n    Using AutoNegotiation On\n");
+               AutoNeg = AN_ON;
+       }
+@@ -3687,11 +4636,15 @@
+       }
+       pAC->RlmtNets = 1;
++      pAC->RlmtMode = 0;
+       if (RlmtMode != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+               RlmtMode[pAC->Index] != NULL) {
+               if (strcmp(RlmtMode[pAC->Index], "") == 0) {
+-                      pAC->RlmtMode = 0;
++                      if (pAC->GIni.GIMacsFound == 2) {
++                              pAC->RlmtMode = SK_RLMT_CHECK_LINK;
++                              pAC->RlmtNets = 2;
++                      }
+               } else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) {
+                       pAC->RlmtMode = SK_RLMT_CHECK_LINK;
+               } else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) {
+@@ -3712,12 +4665,37 @@
+                       pAC->RlmtMode = 0;
+               }
+       } else {
+-              pAC->RlmtMode = 0;
++              if (pAC->GIni.GIMacsFound == 2) {
++                      pAC->RlmtMode = SK_RLMT_CHECK_LINK;
++                      pAC->RlmtNets = 2;
++              }
+       }
+-      
++
++#ifdef SK_YUKON2
++      /*
++      ** use dualnet config per default
++      *
++      pAC->RlmtMode = SK_RLMT_CHECK_LINK;
++      pAC->RlmtNets = 2;
++      */
++#endif
++
++
++      /*
++      ** Check the LowLatance parameters
++      */
++      pAC->LowLatency = SK_FALSE;
++      if (LowLatency[pAC->Index] != NULL) {
++              if (strcmp(LowLatency[pAC->Index], "On") == 0) {
++                      pAC->LowLatency = SK_TRUE;
++              }
++      }
++
++
+       /*
+       ** Check the interrupt moderation parameters
+       */
++      pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
+       if (Moderation[pAC->Index] != NULL) {
+               if (strcmp(Moderation[pAC->Index], "") == 0) {
+                       pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
+@@ -3731,70 +4709,49 @@
+                       printk("sk98lin: Illegal value \"%s\" for Moderation.\n"
+                               "      Disable interrupt moderation.\n",
+                               Moderation[pAC->Index]);
+-                      pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
+-              }
+-      } else {
+-              pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
+-      }
+-
+-      if (Stats[pAC->Index] != NULL) {
+-              if (strcmp(Stats[pAC->Index], "Yes") == 0) {
+-                      pAC->DynIrqModInfo.DisplayStats = SK_TRUE;
+-              } else {
+-                      pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
+               }
+       } else {
+-              pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
++/* Set interrupt moderation if wished */
++#ifdef CONFIG_SK98LIN_STATINT
++              pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC;
++#endif
+       }
+       if (ModerationMask[pAC->Index] != NULL) {
+               if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
++                      IrqModMaskOffset = 0;
+               } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY;
++                      IrqModMaskOffset = 1;
+               } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY;
++                      IrqModMaskOffset = 2;
+               } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
++                      IrqModMaskOffset = 3;
+               } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
++                      IrqModMaskOffset = 3;
+               } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
++                      IrqModMaskOffset = 4;
+               } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
++                      IrqModMaskOffset = 4;
+               } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
++                      IrqModMaskOffset = 5;
+               } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
+-              } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+-              } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+-              } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+-              } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+-              } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+-              } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) {
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+-              } else { /* some rubbish */
+-                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
+-              }
+-      } else {  /* operator has stated nothing */
+-              pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
+-      }
+-
+-      if (AutoSizing[pAC->Index] != NULL) {
+-              if (strcmp(AutoSizing[pAC->Index], "On") == 0) {
+-                      pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
+-              } else {
+-                      pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
++                      IrqModMaskOffset = 5;
++              } else { /* some rubbish stated */
++                      // IrqModMaskOffset = 6; ->has been initialized
++                      // already at the begin of this function...
+               }
+-      } else {  /* operator has stated nothing */
+-              pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
++      }
++      if (!CHIP_ID_YUKON_2(pAC)) {
++              pAC->DynIrqModInfo.MaskIrqModeration = IrqModMask[IrqModMaskOffset][0];
++      } else {
++              pAC->DynIrqModInfo.MaskIrqModeration = IrqModMask[IrqModMaskOffset][1];
+       }
++      if (!CHIP_ID_YUKON_2(pAC)) {
++              pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
++      } else {
++              pAC->DynIrqModInfo.MaxModIntsPerSec = C_Y2_INTS_PER_SEC_DEFAULT;
++      }
+       if (IntsPerSec[pAC->Index] != 0) {
+               if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) || 
+                       (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) {
+@@ -3803,28 +4760,25 @@
+                               IntsPerSec[pAC->Index],
+                               C_INT_MOD_IPS_LOWER_RANGE,
+                               C_INT_MOD_IPS_UPPER_RANGE,
+-                              C_INTS_PER_SEC_DEFAULT);
+-                      pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
++                              pAC->DynIrqModInfo.MaxModIntsPerSec);
+               } else {
+                       pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index];
+               }
+-      } else {
+-              pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
+-      }
++      } 
+       /*
+       ** Evaluate upper and lower moderation threshold
+       */
+       pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit =
+               pAC->DynIrqModInfo.MaxModIntsPerSec +
+-              (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
++              (pAC->DynIrqModInfo.MaxModIntsPerSec / 5);
+       pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit =
+               pAC->DynIrqModInfo.MaxModIntsPerSec -
+-              (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
+-
+-      pAC->DynIrqModInfo.PrevTimeVal = jiffies;  /* initial value */
++              (pAC->DynIrqModInfo.MaxModIntsPerSec / 5);
++      pAC->DynIrqModInfo.DynIrqModSampleInterval = 
++              SK_DRV_MODERATION_TIMER_LENGTH;
+ } /* GetConfiguration */
+@@ -3860,45 +4814,6 @@
+       }
+ } /* ProductStr */
+-/*****************************************************************************
+- *
+- *      StartDrvCleanupTimer - Start timer to check for descriptors which
+- *                             might be placed in descriptor ring, but
+- *                             havent been handled up to now
+- *
+- * Description:
+- *      This function requests a HW-timer fo the Yukon card. The actions to
+- *      perform when this timer expires, are located in the SkDrvEvent().
+- *
+- * Returns: N/A
+- */
+-static void
+-StartDrvCleanupTimer(SK_AC *pAC) {
+-    SK_EVPARA    EventParam;   /* Event struct for timer event */
+-
+-    SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
+-    EventParam.Para32[0] = SK_DRV_RX_CLEANUP_TIMER;
+-    SkTimerStart(pAC, pAC->IoBase, &pAC->DrvCleanupTimer,
+-                 SK_DRV_RX_CLEANUP_TIMER_LENGTH,
+-                 SKGE_DRV, SK_DRV_TIMER, EventParam);
+-}
+-
+-/*****************************************************************************
+- *
+- *      StopDrvCleanupTimer - Stop timer to check for descriptors
+- *
+- * Description:
+- *      This function requests a HW-timer fo the Yukon card. The actions to
+- *      perform when this timer expires, are located in the SkDrvEvent().
+- *
+- * Returns: N/A
+- */
+-static void
+-StopDrvCleanupTimer(SK_AC *pAC) {
+-    SkTimerStop(pAC, pAC->IoBase, &pAC->DrvCleanupTimer);
+-    SK_MEMSET((char *) &pAC->DrvCleanupTimer, 0, sizeof(SK_TIMER));
+-}
+-
+ /****************************************************************************/
+ /* functions for common modules *********************************************/
+ /****************************************************************************/
+@@ -3987,7 +4902,9 @@
+ SK_U64 SkOsGetTime(SK_AC *pAC)
+ {
+       SK_U64  PrivateJiffies;
++
+       SkOsGetTimeCurrent(pAC, &PrivateJiffies);
++
+       return PrivateJiffies;
+ } /* SkOsGetTime */
+@@ -4142,29 +5059,26 @@
+  *    
+  */
+ int SkDrvEvent(
+-SK_AC *pAC,           /* pointer to adapter context */
+-SK_IOC IoC,           /* io-context */
+-SK_U32 Event,         /* event-id */
+-SK_EVPARA Param)      /* event-parameter */
+-{
+-SK_MBUF               *pRlmtMbuf;     /* pointer to a rlmt-mbuf structure */
+-struct sk_buff        *pMsg;          /* pointer to a message block */
+-int           FromPort;       /* the port from which we switch away */
+-int           ToPort;         /* the port we switch to */
+-SK_EVPARA     NewPara;        /* parameter for further events */
+-int           Stat;
+-unsigned long Flags;
+-SK_BOOL               DualNet;
++SK_AC     *pAC,    /* pointer to adapter context */
++SK_IOC     IoC,    /* IO control context         */
++SK_U32     Event,  /* event-id                   */
++SK_EVPARA  Param)  /* event-parameter            */
++{
++      SK_MBUF         *pRlmtMbuf;   /* pointer to a rlmt-mbuf structure   */
++      struct sk_buff  *pMsg;        /* pointer to a message block         */
++      SK_BOOL          DualNet;
++      SK_U32           Reason;
++      unsigned long    Flags;
++      int              FromPort;    /* the port from which we switch away */
++      int              ToPort;      /* the port we switch to              */
++      int              Stat;
++      DEV_NET         *pNet = NULL;
++#ifdef CONFIG_SK98LIN_NAPI
++      int              WorkToDo = 1; /* min(*budget, dev->quota); */
++      int              WorkDone = 0;
++#endif
+       switch (Event) {
+-      case SK_DRV_ADAP_FAIL:
+-              SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+-                      ("ADAPTER FAIL EVENT\n"));
+-              printk("%s: Adapter failed.\n", pAC->dev[0]->name);
+-              /* disable interrupts */
+-              SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+-              /* cgoos */
+-              break;
+       case SK_DRV_PORT_FAIL:
+               FromPort = Param.Para32[0];
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+@@ -4174,219 +5088,294 @@
+               } else {
+                       printk("%s: Port B failed.\n", pAC->dev[1]->name);
+               }
+-              /* cgoos */
+               break;
+-      case SK_DRV_PORT_RESET:  /* SK_U32 PortIdx */
+-              /* action list 4 */
++      case SK_DRV_PORT_RESET:
+               FromPort = Param.Para32[0];
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+                       ("PORT RESET EVENT, Port: %d ", FromPort));
+-              NewPara.Para64 = FromPort;
+-              SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
++              SkLocalEventQueue64(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET,
++                                      FromPort, SK_FALSE);
+               spin_lock_irqsave(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+-
+-              SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      SkY2PortStop(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
++              } else {
++                      SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
++              }
+               pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING;
+               spin_unlock_irqrestore(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+               
+-              /* clear rx ring from received frames */
+-              ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
+-              
+-              ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
++              if (!CHIP_ID_YUKON_2(pAC)) {
++#ifdef CONFIG_SK98LIN_NAPI
++                      WorkToDo = 1;
++                      ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE, &WorkDone, WorkToDo);
++#else
++                      ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
++#endif
++                      ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
++              }
+               spin_lock_irqsave(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+-              
+-              /* tschilling: Handling of return value inserted. */
+-              if (SkGeInitPort(pAC, IoC, FromPort)) {
+-                      if (FromPort == 0) {
+-                              printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name);
++
++#ifdef USE_TIST_FOR_RESET
++                if (pAC->GIni.GIYukon2) {
++#ifdef Y2_RECOVERY
++                      /* for Yukon II we want to have tist enabled all the time */
++                      if (!SK_ADAPTER_WAITING_FOR_TIST(pAC)) {
++                              Y2_ENABLE_TIST(pAC->IoBase);
++                      }
++#else
++                      /* make sure that we do not accept any status LEs from now on */
++                      if (SK_ADAPTER_WAITING_FOR_TIST(pAC)) {
++#endif
++                              /* port already waiting for tist */
++                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP,
++                                      ("Port %c is now waiting for specific Tist\n",
++                                      'A' +  FromPort));
++                              SK_SET_WAIT_BIT_FOR_PORT(
++                                      pAC,
++                                      SK_PSTATE_WAITING_FOR_SPECIFIC_TIST,
++                                      FromPort);
++                              /* get current timestamp */
++                              Y2_GET_TIST_LOW_VAL(pAC->IoBase, &pAC->MinTistLo);
++                              pAC->MinTistHi = pAC->GIni.GITimeStampCnt;
++#ifndef Y2_RECOVERY
+                       } else {
+-                              printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name);
++                              /* nobody is waiting yet */
++                              SK_SET_WAIT_BIT_FOR_PORT(
++                                      pAC,
++                                      SK_PSTATE_WAITING_FOR_ANY_TIST,
++                                      FromPort);
++                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP,
++                                      ("Port %c is now waiting for any Tist (0x%X)\n",
++                                      'A' +  FromPort, pAC->AdapterResetState));
++                              /* start tist */
++                              Y2_ENABLE_TIST(pAC-IoBase);
++                      }
++#endif
++              }
++#endif
++
++#ifdef Y2_LE_CHECK
++              /* mark entries invalid */
++              pAC->LastPort = 3;
++              pAC->LastOpc = 0xFF;
++#endif
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      SkY2PortStart(pAC, IoC, FromPort);
++              } else {
++                      /* tschilling: Handling of return value inserted. */
++                      if (SkGeInitPort(pAC, IoC, FromPort)) {
++                              if (FromPort == 0) {
++                                      printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name);
++                              } else {
++                                      printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name);
++                              }
+                       }
++                      SkAddrMcUpdate(pAC,IoC, FromPort);
++                      PortReInitBmu(pAC, FromPort);
++                      SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
++                      CLEAR_AND_START_RX(FromPort);
+               }
+-              SkAddrMcUpdate(pAC,IoC, FromPort);
+-              PortReInitBmu(pAC, FromPort);
+-              SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
+-              ClearAndStartRx(pAC, FromPort);
+               spin_unlock_irqrestore(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+               break;
+-      case SK_DRV_NET_UP:      /* SK_U32 PortIdx */
+-              /* action list 5 */
++      case SK_DRV_NET_UP:
+               FromPort = Param.Para32[0];
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+-                      ("NET UP EVENT, Port: %d ", Param.Para32[0]));
+-              /* Mac update */
+-              SkAddrMcUpdate(pAC,IoC, FromPort);
+-
++                      ("NET UP EVENT, Port: %d ", FromPort));
++              SkAddrMcUpdate(pAC,IoC, FromPort); /* Mac update */
+               if (DoPrintInterfaceChange) {
+-              printk("%s: network connection up using"
+-                      " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
++                      printk("%s: network connection up using port %c\n",
++                              pAC->dev[FromPort]->name, 'A'+FromPort);
+-              /* tschilling: Values changed according to LinkSpeedUsed. */
+-              Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed;
+-              if (Stat == SK_LSPEED_STAT_10MBPS) {
+-                      printk("    speed:           10\n");
+-              } else if (Stat == SK_LSPEED_STAT_100MBPS) {
+-                      printk("    speed:           100\n");
+-              } else if (Stat == SK_LSPEED_STAT_1000MBPS) {
+-                      printk("    speed:           1000\n");
+-              } else {
+-                      printk("    speed:           unknown\n");
+-              }
++                      /* tschilling: Values changed according to LinkSpeedUsed. */
++                      Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed;
++                      if (Stat == SK_LSPEED_STAT_10MBPS) {
++                              printk("    speed:           10\n");
++                      } else if (Stat == SK_LSPEED_STAT_100MBPS) {
++                              printk("    speed:           100\n");
++                      } else if (Stat == SK_LSPEED_STAT_1000MBPS) {
++                              printk("    speed:           1000\n");
++                      } else {
++                              printk("    speed:           unknown\n");
++                      }
++                      Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
++                      if ((Stat == SK_LMODE_STAT_AUTOHALF) ||
++                          (Stat == SK_LMODE_STAT_AUTOFULL)) {
++                              printk("    autonegotiation: yes\n");
++                      } else {
++                              printk("    autonegotiation: no\n");
++                      }
+-              Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
+-              if (Stat == SK_LMODE_STAT_AUTOHALF ||
+-                      Stat == SK_LMODE_STAT_AUTOFULL) {
+-                      printk("    autonegotiation: yes\n");
+-              }
+-              else {
+-                      printk("    autonegotiation: no\n");
+-              }
+-              if (Stat == SK_LMODE_STAT_AUTOHALF ||
+-                      Stat == SK_LMODE_STAT_HALF) {
+-                      printk("    duplex mode:     half\n");
+-              }
+-              else {
+-                      printk("    duplex mode:     full\n");
+-              }
+-              Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus;
+-              if (Stat == SK_FLOW_STAT_REM_SEND ) {
+-                      printk("    flowctrl:        remote send\n");
+-              }
+-              else if (Stat == SK_FLOW_STAT_LOC_SEND ){
+-                      printk("    flowctrl:        local send\n");
+-              }
+-              else if (Stat == SK_FLOW_STAT_SYMMETRIC ){
+-                      printk("    flowctrl:        symmetric\n");
+-              }
+-              else {
+-                      printk("    flowctrl:        none\n");
+-              }
+-              
+-              /* tschilling: Check against CopperType now. */
+-              if ((pAC->GIni.GICopperType == SK_TRUE) &&
+-                      (pAC->GIni.GP[FromPort].PLinkSpeedUsed ==
+-                      SK_LSPEED_STAT_1000MBPS)) {
+-                      Stat = pAC->GIni.GP[FromPort].PMSStatus;
+-                      if (Stat == SK_MS_STAT_MASTER ) {
+-                              printk("    role:            master\n");
++                      if ((Stat == SK_LMODE_STAT_AUTOHALF) ||
++                          (Stat == SK_LMODE_STAT_HALF)) {
++                              printk("    duplex mode:     half\n");
++                      } else {
++                              printk("    duplex mode:     full\n");
+                       }
+-                      else if (Stat == SK_MS_STAT_SLAVE ) {
+-                              printk("    role:            slave\n");
++
++                      Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus;
++                      if (Stat == SK_FLOW_STAT_REM_SEND ) {
++                              printk("    flowctrl:        remote send\n");
++                      } else if (Stat == SK_FLOW_STAT_LOC_SEND ) {
++                              printk("    flowctrl:        local send\n");
++                      } else if (Stat == SK_FLOW_STAT_SYMMETRIC ) {
++                              printk("    flowctrl:        symmetric\n");
++                      } else {
++                              printk("    flowctrl:        none\n");
+                       }
+-                      else {
+-                              printk("    role:            ???\n");
++              
++                      /* tschilling: Check against CopperType now. */
++                      if ((pAC->GIni.GICopperType == SK_TRUE) &&
++                              (pAC->GIni.GP[FromPort].PLinkSpeedUsed ==
++                              SK_LSPEED_STAT_1000MBPS)) {
++                              Stat = pAC->GIni.GP[FromPort].PMSStatus;
++                              if (Stat == SK_MS_STAT_MASTER ) {
++                                      printk("    role:            master\n");
++                              } else if (Stat == SK_MS_STAT_SLAVE ) {
++                                      printk("    role:            slave\n");
++                              } else {
++                                      printk("    role:            ???\n");
++                              }
+                       }
+-              }
+-              /* 
+-                 Display dim (dynamic interrupt moderation) 
+-                 informations
+-               */
+-              if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC)
+-                      printk("    irq moderation:  static (%d ints/sec)\n",
++                      /* Display interrupt moderation informations */
++                      if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) {
++                              printk("    irq moderation:  static (%d ints/sec)\n",
+                                       pAC->DynIrqModInfo.MaxModIntsPerSec);
+-              else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC)
+-                      printk("    irq moderation:  dynamic (%d ints/sec)\n",
++                      } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
++                              printk("    irq moderation:  dynamic (%d ints/sec)\n",
+                                       pAC->DynIrqModInfo.MaxModIntsPerSec);
+-              else
+-                      printk("    irq moderation:  disabled\n");
++                      } else {
++                              printk("    irq moderation:  disabled\n");
++                      }
++      
++#ifdef NETIF_F_TSO
++                      if (CHIP_ID_YUKON_2(pAC)) {
++                              if (pAC->dev[FromPort]->features & NETIF_F_TSO) {
++                                      printk("    tcp offload:     enabled\n");
++                              } else {
++                                      printk("    tcp offload:     disabled\n");
++                              }
++                      }
++#endif
++                      if (pAC->dev[FromPort]->features & NETIF_F_SG) {
++                              printk("    scatter-gather:  enabled\n");
++                      } else {
++                              printk("    scatter-gather:  disabled\n");
++                      }
+-#ifdef SK_ZEROCOPY
+-              if (pAC->ChipsetType)
+-#ifdef USE_SK_TX_CHECKSUM
+-                      printk("    scatter-gather:  enabled\n");
+-#else
+-                      printk("    tx-checksum:     disabled\n");
+-#endif
+-              else
+-                      printk("    scatter-gather:  disabled\n");
+-#else
+-                      printk("    scatter-gather:  disabled\n");
+-#endif
++                      if (pAC->dev[FromPort]->features & NETIF_F_IP_CSUM) {
++                              printk("    tx-checksum:     enabled\n");
++                      } else {
++                              printk("    tx-checksum:     disabled\n");
++                      }
+-#ifndef USE_SK_RX_CHECKSUM
+-                      printk("    rx-checksum:     disabled\n");
++                      if (pAC->RxPort[FromPort].UseRxCsum) {
++                              printk("    rx-checksum:     enabled\n");
++                      } else {
++                              printk("    rx-checksum:     disabled\n");
++                      }
++#ifdef CONFIG_SK98LIN_NAPI
++                      printk("    rx-polling:      enabled\n");
+ #endif
+-
++                      if (pAC->LowLatency) {
++                              printk("    low latency:     enabled\n");
++                      }
+               } else {
+-                        DoPrintInterfaceChange = SK_TRUE;
+-                }
++                      DoPrintInterfaceChange = SK_TRUE;
++              }
+       
+-              if ((Param.Para32[0] != pAC->ActivePort) &&
+-                      (pAC->RlmtNets == 1)) {
+-                      NewPara.Para32[0] = pAC->ActivePort;
+-                      NewPara.Para32[1] = Param.Para32[0];
+-                      SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
+-                              NewPara);
++              if ((FromPort != pAC->ActivePort)&&(pAC->RlmtNets == 1)) {
++                      SkLocalEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
++                                              pAC->ActivePort, FromPort, SK_FALSE);
+               }
+               /* Inform the world that link protocol is up. */
+-              pAC->dev[Param.Para32[0]]->flags |= IFF_RUNNING;
+-
++              netif_wake_queue(pAC->dev[FromPort]);
++              netif_carrier_on(pAC->dev[FromPort]);
++              pAC->dev[FromPort]->flags |= IFF_RUNNING;
+               break;
+-      case SK_DRV_NET_DOWN:    /* SK_U32 Reason */
+-              /* action list 7 */
++      case SK_DRV_NET_DOWN:   
++              Reason   = Param.Para32[0];
++              FromPort = Param.Para32[1];
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+                       ("NET DOWN EVENT "));
++
++              /* Stop queue and carrier */
++              netif_stop_queue(pAC->dev[FromPort]);
++              netif_carrier_off(pAC->dev[FromPort]);
++
++              /* Print link change */
+               if (DoPrintInterfaceChange) {
+-                      printk("%s: network connection down\n", 
+-                              pAC->dev[Param.Para32[1]]->name);
++                      if (pAC->dev[FromPort]->flags & IFF_RUNNING) {
++                              printk("%s: network connection down\n", 
++                                      pAC->dev[FromPort]->name);
++                      }
+               } else {
+                       DoPrintInterfaceChange = SK_TRUE;
+               }
+-              pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING;
++              pAC->dev[FromPort]->flags &= ~IFF_RUNNING;
+               break;
+-      case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
+-              SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+-                      ("PORT SWITCH HARD "));
+-      case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
+-      /* action list 6 */
+-              printk("%s: switching to port %c\n", pAC->dev[0]->name,
+-                      'A'+Param.Para32[1]);
+-      case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
++      case SK_DRV_SWITCH_HARD:   /* FALL THRU */
++      case SK_DRV_SWITCH_SOFT:   /* FALL THRU */
++      case SK_DRV_SWITCH_INTERN: 
+               FromPort = Param.Para32[0];
+-              ToPort = Param.Para32[1];
++              ToPort   = Param.Para32[1];
++              printk("%s: switching from port %c to port %c\n",
++                      pAC->dev[0]->name, 'A'+FromPort, 'A'+ToPort);
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+                       ("PORT SWITCH EVENT, From: %d  To: %d (Pref %d) ",
+                       FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort));
+-              NewPara.Para64 = FromPort;
+-              SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
+-              NewPara.Para64 = ToPort;
+-              SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
++              SkLocalEventQueue64(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET,
++                                      FromPort, SK_FALSE);
++              SkLocalEventQueue64(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET,
++                                      ToPort, SK_FALSE);
+               spin_lock_irqsave(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+               spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
+-              SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
+-              SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      SkY2PortStop(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
++                      SkY2PortStop(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
++              }
++              else {
++                      SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
++                      SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
++              }
+               spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
+               spin_unlock_irqrestore(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+-              ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */
+-              ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */
+               
+-              ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
+-              ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]);
++              if (!CHIP_ID_YUKON_2(pAC)) {
++#ifdef CONFIG_SK98LIN_NAPI
++                      WorkToDo = 1;
++                      ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE, &WorkDone, WorkToDo);
++                      ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE, &WorkDone, WorkToDo);
++#else
++                      ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */
++                      ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */
++#endif
++                      ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
++                      ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]);
++              } 
++
+               spin_lock_irqsave(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+               spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
+               pAC->ActivePort = ToPort;
+-#if 0
+-              SetQueueSizes(pAC);
+-#else
++
+               /* tschilling: New common function with minimum size check. */
+               DualNet = SK_FALSE;
+               if (pAC->RlmtNets == 2) {
+@@ -4404,76 +5393,340 @@
+                       printk("SkGeInitAssignRamToQueues failed.\n");
+                       break;
+               }
+-#endif
+-              /* tschilling: Handling of return values inserted. */
+-              if (SkGeInitPort(pAC, IoC, FromPort) ||
+-                      SkGeInitPort(pAC, IoC, ToPort)) {
+-                      printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name);
++
++              if (!CHIP_ID_YUKON_2(pAC)) {
++                      /* tschilling: Handling of return values inserted. */
++                      if (SkGeInitPort(pAC, IoC, FromPort) ||
++                              SkGeInitPort(pAC, IoC, ToPort)) {
++                              printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name);
++                      }
+               }
+-              if (Event == SK_DRV_SWITCH_SOFT) {
+-                      SkMacRxTxEnable(pAC, IoC, FromPort);
++              if (!CHIP_ID_YUKON_2(pAC)) {
++                      if (Event == SK_DRV_SWITCH_SOFT) {
++                              SkMacRxTxEnable(pAC, IoC, FromPort);
++                      }
++                      SkMacRxTxEnable(pAC, IoC, ToPort);
+               }
+-              SkMacRxTxEnable(pAC, IoC, ToPort);
++
+               SkAddrSwap(pAC, IoC, FromPort, ToPort);
+               SkAddrMcUpdate(pAC, IoC, FromPort);
+               SkAddrMcUpdate(pAC, IoC, ToPort);
+-              PortReInitBmu(pAC, FromPort);
+-              PortReInitBmu(pAC, ToPort);
+-              SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
+-              SkGePollTxD(pAC, IoC, ToPort, SK_TRUE);
+-              ClearAndStartRx(pAC, FromPort);
+-              ClearAndStartRx(pAC, ToPort);
++
++#ifdef USE_TIST_FOR_RESET
++                if (pAC->GIni.GIYukon2) {
++                      /* make sure that we do not accept any status LEs from now on */
++                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP,
++                              ("both Ports now waiting for specific Tist\n"));
++                      SK_SET_WAIT_BIT_FOR_PORT(
++                              pAC,
++                              SK_PSTATE_WAITING_FOR_ANY_TIST,
++                              0);
++                      SK_SET_WAIT_BIT_FOR_PORT(
++                              pAC,
++                              SK_PSTATE_WAITING_FOR_ANY_TIST,
++                              1);
++
++                      /* start tist */
++                      Y2_ENABLE_TIST(pAC->IoBase);
++              }
++#endif
++              if (!CHIP_ID_YUKON_2(pAC)) {
++                      PortReInitBmu(pAC, FromPort);
++                      PortReInitBmu(pAC, ToPort);
++                      SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
++                      SkGePollTxD(pAC, IoC, ToPort, SK_TRUE);
++                      CLEAR_AND_START_RX(FromPort);
++                      CLEAR_AND_START_RX(ToPort);
++              } else {
++                      SkY2PortStart(pAC, IoC, FromPort);
++                      SkY2PortStart(pAC, IoC, ToPort);
++#ifdef SK_YUKON2
++                      /* in yukon-II always port 0 has to be started first */
++                      // SkY2PortStart(pAC, IoC, 0);
++                      // SkY2PortStart(pAC, IoC, 1);
++#endif
++              }
+               spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
+               spin_unlock_irqrestore(
+                       &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+                       Flags);
+               break;
+       case SK_DRV_RLMT_SEND:   /* SK_MBUF *pMb */
+-              SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+-                      ("RLS "));
++              SK_DBG_MSG(NULL,SK_DBGMOD_DRV,SK_DBGCAT_DRV_EVENT,("RLS "));
+               pRlmtMbuf = (SK_MBUF*) Param.pParaPtr;
+               pMsg = (struct sk_buff*) pRlmtMbuf->pOs;
+               skb_put(pMsg, pRlmtMbuf->Length);
+-              if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW],
+-                      pMsg) < 0)
+-
+-                      DEV_KFREE_SKB_ANY(pMsg);
++              if (!CHIP_ID_YUKON_2(pAC)) {
++                      if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW],
++                              pMsg) < 0) {
++                              DEV_KFREE_SKB_ANY(pMsg);
++                      }
++              } else {
++                      if (SkY2RlmtSend(pAC, pRlmtMbuf->PortIdx, pMsg) < 0) {
++                              DEV_KFREE_SKB_ANY(pMsg);
++                      }
++              }
+               break;
+       case SK_DRV_TIMER:
+               if (Param.Para32[0] == SK_DRV_MODERATION_TIMER) {
+-                      /*
+-                      ** expiration of the moderation timer implies that
+-                      ** dynamic moderation is to be applied
+-                      */
++                      /* check what IRQs are to be moderated */
+                       SkDimStartModerationTimer(pAC);
+                       SkDimModerate(pAC);
+-                        if (pAC->DynIrqModInfo.DisplayStats) {
+-                          SkDimDisplayModerationSettings(pAC);
+-                        }
+-                } else if (Param.Para32[0] == SK_DRV_RX_CLEANUP_TIMER) {
+-                      /*
+-                      ** check if we need to check for descriptors which
+-                      ** haven't been handled the last millisecs
+-                      */
+-                      StartDrvCleanupTimer(pAC);
+-                      if (pAC->GIni.GIMacsFound == 2) {
+-                              ReceiveIrq(pAC, &pAC->RxPort[1], SK_FALSE);
+-                      }
+-                      ReceiveIrq(pAC, &pAC->RxPort[0], SK_FALSE);
+               } else {
+                       printk("Expiration of unknown timer\n");
+               }
+               break;
++      case SK_DRV_ADAP_FAIL:
++#if (!defined (Y2_RECOVERY) && !defined (Y2_LE_CHECK))
++              SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
++                      ("ADAPTER FAIL EVENT\n"));
++              printk("%s: Adapter failed.\n", pAC->dev[0]->name);
++              SK_OUT32(pAC->IoBase, B0_IMSK, 0); /* disable interrupts */
++              break;
++#endif
++
++#if (defined (Y2_RECOVERY) || defined (Y2_LE_CHECK))
++      case SK_DRV_RECOVER:
++              pNet = (DEV_NET *) pAC->dev[0]->priv;
++
++              /* Recover already in progress */
++              if (pNet->InRecover) {
++                      break;
++              }
++
++              netif_stop_queue(pAC->dev[0]); /* stop device if running */
++              pNet->InRecover = SK_TRUE;
++
++              FromPort = Param.Para32[0];
++              SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
++                      ("PORT RESET EVENT, Port: %d ", FromPort));
++
++              /* Disable interrupts */
++              SK_OUT32(pAC->IoBase, B0_IMSK, 0);
++              SK_OUT32(pAC->IoBase, B0_HWE_IMSK, 0);
++
++              SkLocalEventQueue64(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET,
++                                      FromPort, SK_FALSE);
++              spin_lock_irqsave(
++                      &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
++                      Flags);
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      if (pAC->GIni.GIMacsFound > 1) {
++                              SkY2PortStop(pAC, IoC, 0, SK_STOP_ALL, SK_SOFT_RST);
++                              SkY2PortStop(pAC, IoC, 1, SK_STOP_ALL, SK_SOFT_RST);
++                      } else {
++                              SkY2PortStop(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
++                      }
++              } else {
++                      SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
++              }
++              pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING;
++              spin_unlock_irqrestore(
++                      &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
++                      Flags);
++              
++              if (!CHIP_ID_YUKON_2(pAC)) {
++#ifdef CONFIG_SK98LIN_NAPI
++                      WorkToDo = 1;
++                      ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE, &WorkDone, WorkToDo);
++#else
++                      ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
++#endif
++                      ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
++              }
++              spin_lock_irqsave(
++                      &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
++                      Flags);
++
++#ifdef USE_TIST_FOR_RESET
++              if (pAC->GIni.GIYukon2) {
++#if 0
++                      /* make sure that we do not accept any status LEs from now on */
++                      Y2_ENABLE_TIST(pAC->IoBase);
++
++                      /* get current timestamp */
++                      Y2_GET_TIST_LOW_VAL(pAC->IoBase, &pAC->MinTistLo);
++                      pAC->MinTistHi = pAC->GIni.GITimeStampCnt;
++
++                      SK_SET_WAIT_BIT_FOR_PORT(
++                              pAC,
++                              SK_PSTATE_WAITING_FOR_SPECIFIC_TIST,
++                              FromPort);
++#endif
++                      if (pAC->GIni.GIMacsFound > 1) {
++                              SK_SET_WAIT_BIT_FOR_PORT(
++                                      pAC,
++                                      SK_PSTATE_WAITING_FOR_ANY_TIST,
++                                      0);
++                              SK_SET_WAIT_BIT_FOR_PORT(
++                                      pAC,
++                                      SK_PSTATE_WAITING_FOR_ANY_TIST,
++                                      1);
++                      } else {
++                              SK_SET_WAIT_BIT_FOR_PORT(
++                                      pAC,
++                                      SK_PSTATE_WAITING_FOR_ANY_TIST,
++                                      FromPort);
++                      }
++
++                      /* start tist */
++                        Y2_ENABLE_TIST(pAC->IoBase);
++              }
++#endif
++
++
++
++#ifdef Y2_LE_CHECK
++              /* mark entries invalid */
++              pAC->LastPort = 3;
++              pAC->LastOpc = 0xFF;
++#endif
++
++#endif
++              /* Restart ports but do not initialize PHY. */
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      if (pAC->GIni.GIMacsFound > 1) {
++                              SkY2PortStart(pAC, IoC, 0);
++                              SkY2PortStart(pAC, IoC, 1);
++                      } else {
++                              SkY2PortStart(pAC, IoC, FromPort);
++                      }
++              } else {
++                      /* tschilling: Handling of return value inserted. */
++                      if (SkGeInitPort(pAC, IoC, FromPort)) {
++                              if (FromPort == 0) {
++                                      printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name);
++                              } else {
++                                      printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name);
++                              }
++                      }
++                      SkAddrMcUpdate(pAC,IoC, FromPort);
++                      PortReInitBmu(pAC, FromPort);
++                      SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
++                      CLEAR_AND_START_RX(FromPort);
++              }
++              spin_unlock_irqrestore(
++                      &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
++                      Flags);
++
++#if 0
++              /* restart the kernel timer */
++              pNet = (DEV_NET *) pAC->dev[FromPort]->priv;
++              if (!timer_pending(&pNet->KernelTimer)) {
++                      pNet->KernelTimer.expires =
++                              jiffies + (HZ/4);       /* 250ms */
++                      add_timer(&pNet->KernelTimer);
++              }
++#endif
++              pNet->InRecover = SK_FALSE;
++              /* enable Interrupts */
++              SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
++              SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
++              netif_wake_queue(pAC->dev[0]);
++              break;
+       default:
+               break;
+       }
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+               ("END EVENT "));
+-      
++
+       return (0);
+ } /* SkDrvEvent */
++/******************************************************************************
++ *
++ *    SkLocalEventQueue()     -       add event to queue
++ *
++ * Description:
++ *    This function adds an event to the event queue and run the
++ *    SkEventDispatcher. At least Init Level 1 is required to queue events,
++ *    but will be scheduled add Init Level 2.
++ *
++ * returns:
++ *    nothing
++ */
++void SkLocalEventQueue(
++SK_AC *pAC,           /* Adapters context */
++SK_U32 Class,         /* Event Class */
++SK_U32 Event,         /* Event to be queued */
++SK_U32 Param1,                /* Event parameter 1 */
++SK_U32 Param2,                /* Event parameter 2 */
++SK_BOOL Dispatcher)   /* Dispatcher flag:
++                       *      TRUE == Call SkEventDispatcher
++                       *      FALSE == Don't execute SkEventDispatcher
++                       */
++{
++      SK_EVPARA       EvPara;
++      EvPara.Para32[0] = Param1;
++      EvPara.Para32[1] = Param2;
++      
++
++      if (Class == SKGE_PNMI) {
++              SkPnmiEvent(    pAC,
++                              pAC->IoBase,
++                              Event,
++                              EvPara);
++      } else {
++              SkEventQueue(   pAC,
++                              Class,
++                              Event,
++                              EvPara);
++      }
++
++      /* Run the dispatcher */
++      if (Dispatcher) {
++              SkEventDispatcher(pAC, pAC->IoBase);
++      }
++
++}
++
++/******************************************************************************
++ *
++ *    SkLocalEventQueue64()   -       add event to queue (64bit version)
++ *
++ * Description:
++ *    This function adds an event to the event queue and run the
++ *    SkEventDispatcher. At least Init Level 1 is required to queue events,
++ *    but will be scheduled add Init Level 2.
++ *
++ * returns:
++ *    nothing
++ */
++void SkLocalEventQueue64(
++SK_AC *pAC,           /* Adapters context */
++SK_U32 Class,         /* Event Class */
++SK_U32 Event,         /* Event to be queued */
++SK_U64 Param,         /* Event parameter */
++SK_BOOL Dispatcher)   /* Dispatcher flag:
++                       *      TRUE == Call SkEventDispatcher
++                       *      FALSE == Don't execute SkEventDispatcher
++                       */
++{
++      SK_EVPARA       EvPara;
++      EvPara.Para64 = Param;
++
++
++      if (Class == SKGE_PNMI) {
++              SkPnmiEvent(    pAC,
++                              pAC->IoBase,
++                              Event,
++                              EvPara);
++      } else {
++              SkEventQueue(   pAC,
++                              Class,
++                              Event,
++                              EvPara);
++      }
++
++      /* Run the dispatcher */
++      if (Dispatcher) {
++              SkEventDispatcher(pAC, pAC->IoBase);
++      }
++
++}
++
++
+ /*****************************************************************************
+  *
+  *    SkErrorLog - log errors
+@@ -4523,8 +5776,6 @@
+ } /* SkErrorLog */
+-#ifdef SK_DIAG_SUPPORT
+-
+ /*****************************************************************************
+  *
+  *    SkDrvEnterDiagMode - handles DIAG attach request
+@@ -4550,7 +5801,7 @@
+       pAC->DiagModeActive = DIAG_ACTIVE;
+       if (pAC->BoardLevel > SK_INIT_DATA) {
+-              if (pNet->Up) {
++              if (netif_running(pAC->dev[0])) {
+                       pAC->WasIfUp[0] = SK_TRUE;
+                       pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose      */
+                       DoPrintInterfaceChange = SK_FALSE;
+@@ -4558,9 +5809,10 @@
+               } else {
+                       pAC->WasIfUp[0] = SK_FALSE;
+               }
++
+               if (pNet != (DEV_NET *) pAc->dev[1]->priv) {
+                       pNet = (DEV_NET *) pAc->dev[1]->priv;
+-                      if (pNet->Up) {
++                      if (netif_running(pAC->dev[1])) {
+                               pAC->WasIfUp[1] = SK_TRUE;
+                               pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
+                               DoPrintInterfaceChange = SK_FALSE;
+@@ -4592,16 +5844,16 @@
+                       sizeof(SK_PNMI_STRUCT_DATA));
+       pAc->DiagModeActive    = DIAG_NOTACTIVE;
+       pAc->Pnmi.DiagAttached = SK_DIAG_IDLE;
+-        if (pAc->WasIfUp[0] == SK_TRUE) {
+-                pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
++      if (pAc->WasIfUp[0] == SK_TRUE) {
++              pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
+               DoPrintInterfaceChange = SK_FALSE;
+-                SkDrvInitAdapter(pAc, 0);    /* first device  */
+-        }
+-        if (pAc->WasIfUp[1] == SK_TRUE) {
+-                pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
++              SkDrvInitAdapter(pAc, 0);    /* first device  */
++      }
++      if (pAc->WasIfUp[1] == SK_TRUE) {
++              pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
+               DoPrintInterfaceChange = SK_FALSE;
+-                SkDrvInitAdapter(pAc, 1);    /* second device */
+-        }
++              SkDrvInitAdapter(pAc, 1);    /* second device */
++      }
+       return(0);
+ }
+@@ -4746,14 +5998,25 @@
+ } /* SkDrvInitAdapter */
+-#endif
++static int __init sk98lin_init(void)
++{
++      return pci_module_init(&sk98lin_driver);
++}
++
++static void __exit sk98lin_cleanup(void)
++{
++      pci_unregister_driver(&sk98lin_driver);
++}
++
++module_init(sk98lin_init);
++module_exit(sk98lin_cleanup);
++
+ #ifdef DEBUG
+ /****************************************************************************/
+ /* "debug only" section *****************************************************/
+ /****************************************************************************/
+-
+ /*****************************************************************************
+  *
+  *    DumpMsg - print a frame
+@@ -4764,9 +6027,11 @@
+  * Returns: N/A
+  *    
+  */
+-static void DumpMsg(struct sk_buff *skb, char *str)
++static void DumpMsg(
++struct sk_buff *skb,  /* linux' socket buffer  */
++char           *str)  /* additional msg string */
+ {
+-      int     msglen;
++      int msglen = (skb->len > 64) ? 64 : skb->len;
+       if (skb == NULL) {
+               printk("DumpMsg(): NULL-Message\n");
+@@ -4778,19 +6043,14 @@
+               return;
+       }
+-      msglen = skb->len;
+-      if (msglen > 64)
+-              msglen = 64;
+-
+-      printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len);
+-
++      printk("DumpMsg: PhysPage: %p\n", 
++              page_address(virt_to_page(skb->data)));
++      printk("--- Begin of message from %s , len %d (from %d) ----\n", 
++              str, msglen, skb->len);
+       DumpData((char *)skb->data, msglen);
+-
+       printk("------- End of message ---------\n");
+ } /* DumpMsg */
+-
+-
+ /*****************************************************************************
+  *
+  *    DumpData - print a data area
+@@ -4802,23 +6062,22 @@
+  * Returns: N/A
+  *    
+  */
+-static void DumpData(char *p, int size)
+-{
+-register int    i;
+-int   haddr, addr;
+-char  hex_buffer[180];
+-char  asc_buffer[180];
+-char  HEXCHAR[] = "0123456789ABCDEF";
+-
+-      addr = 0;
+-      haddr = 0;
+-      hex_buffer[0] = 0;
+-      asc_buffer[0] = 0;
++static void DumpData(
++char  *p,     /* pointer to area containing the data */
++int    size)  /* the size of that data area in bytes */
++{
++      register int  i;
++      int           haddr = 0, addr = 0;
++      char          hex_buffer[180] = { '\0' };
++      char          asc_buffer[180] = { '\0' };
++      char          HEXCHAR[] = "0123456789ABCDEF";
++
+       for (i=0; i < size; ) {
+-              if (*p >= '0' && *p <='z')
++              if (*p >= '0' && *p <='z') {
+                       asc_buffer[addr] = *p;
+-              else
++              } else {
+                       asc_buffer[addr] = '.';
++              }
+               addr++;
+               asc_buffer[addr] = 0;
+               hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4];
+@@ -4844,27 +6103,24 @@
+  *    DumpLong - print a data area as long values
+  *
+  * Description:
+- *    This function prints a area of data to the system logfile/to the
++ *    This function prints a long variable to the system logfile/to the
+  *    console.
+  *
+  * Returns: N/A
+  *    
+  */
+-static void DumpLong(char *pc, int size)
+-{
+-register int    i;
+-int   haddr, addr;
+-char  hex_buffer[180];
+-char  asc_buffer[180];
+-char  HEXCHAR[] = "0123456789ABCDEF";
+-long  *p;
+-int   l;
+-
+-      addr = 0;
+-      haddr = 0;
+-      hex_buffer[0] = 0;
+-      asc_buffer[0] = 0;
+-      p = (long*) pc;
++static void DumpLong(
++char  *pc,    /* location of the variable to print */
++int    size)  /* how large is the variable?        */
++{
++      register int   i;
++      int            haddr = 0, addr = 0;
++      char           hex_buffer[180] = { '\0' };
++      char           asc_buffer[180] = { '\0' };
++      char           HEXCHAR[] = "0123456789ABCDEF";
++      long          *p = (long*) pc;
++      int            l;
++
+       for (i=0; i < size; ) {
+               l = (long) *p;
+               hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf];
+@@ -4898,330 +6154,9 @@
+ #endif
+-static int __devinit skge_probe_one(struct pci_dev *pdev,
+-              const struct pci_device_id *ent)
+-{
+-      SK_AC                   *pAC;
+-      DEV_NET                 *pNet = NULL;
+-      struct net_device       *dev = NULL;
+-#ifdef CONFIG_PROC_FS
+-      struct proc_dir_entry   *pProcFile;
+-#endif
+-      static int boards_found = 0;
+-      int error = -ENODEV;
+-
+-      if (pci_enable_device(pdev))
+-              goto out;
+- 
+-      /* Configure DMA attributes. */
+-      if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL) &&
+-          pci_set_dma_mask(pdev, (u64) 0xffffffff))
+-              goto out_disable_device;
+-
+-
+-      if ((dev = alloc_etherdev(sizeof(DEV_NET))) == NULL) {
+-              printk(KERN_ERR "Unable to allocate etherdev "
+-                     "structure!\n");
+-              goto out_disable_device;
+-      }
+-
+-      pNet = dev->priv;
+-      pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
+-      if (!pNet->pAC) {
+-              printk(KERN_ERR "Unable to allocate adapter "
+-                     "structure!\n");
+-              goto out_free_netdev;
+-      }
+-
+-      memset(pNet->pAC, 0, sizeof(SK_AC));
+-      pAC = pNet->pAC;
+-      pAC->PciDev = pdev;
+-      pAC->PciDevId = pdev->device;
+-      pAC->dev[0] = dev;
+-      pAC->dev[1] = dev;
+-      sprintf(pAC->Name, "SysKonnect SK-98xx");
+-      pAC->CheckQueue = SK_FALSE;
+-
+-      pNet->Mtu = 1500;
+-      pNet->Up = 0;
+-      dev->irq = pdev->irq;
+-      error = SkGeInitPCI(pAC);
+-      if (error) {
+-              printk("SKGE: PCI setup failed: %i\n", error);
+-              goto out_free_netdev;
+-      }
+-
+-      SET_MODULE_OWNER(dev);
+-      dev->open =             &SkGeOpen;
+-      dev->stop =             &SkGeClose;
+-      dev->hard_start_xmit =  &SkGeXmit;
+-      dev->get_stats =        &SkGeStats;
+-      dev->set_multicast_list = &SkGeSetRxMode;
+-      dev->set_mac_address =  &SkGeSetMacAddr;
+-      dev->do_ioctl =         &SkGeIoctl;
+-      dev->change_mtu =       &SkGeChangeMtu;
+-      dev->flags &=           ~IFF_RUNNING;
+-      SET_NETDEV_DEV(dev, &pdev->dev);
+-
+-#ifdef SK_ZEROCOPY
+-#ifdef USE_SK_TX_CHECKSUM
+-      if (pAC->ChipsetType) {
+-              /* Use only if yukon hardware */
+-              /* SK and ZEROCOPY - fly baby... */
+-              dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+-      }
+-#endif
+-#endif
+-
+-      pAC->Index = boards_found++;
+-
+-      if (SkGeBoardInit(dev, pAC))
+-              goto out_free_netdev;
+-
+-      /* Register net device */
+-      if (register_netdev(dev)) {
+-              printk(KERN_ERR "SKGE: Could not register device.\n");
+-              goto out_free_resources;
+-      }
+-
+-      /* Print adapter specific string from vpd */
+-      ProductStr(pAC);
+-      printk("%s: %s\n", dev->name, pAC->DeviceStr);
+-
+-      /* Print configuration settings */
+-      printk("      PrefPort:%c  RlmtMode:%s\n",
+-              'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
+-              (pAC->RlmtMode==0)  ? "Check Link State" :
+-              ((pAC->RlmtMode==1) ? "Check Link State" :
+-              ((pAC->RlmtMode==3) ? "Check Local Port" :
+-              ((pAC->RlmtMode==7) ? "Check Segmentation" :
+-              ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
+-
+-      SkGeYellowLED(pAC, pAC->IoBase, 1);
+-
+-
+-      memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
+-
+-#ifdef CONFIG_PROC_FS
+-      pProcFile = create_proc_entry(dev->name, S_IRUGO, pSkRootDir);
+-      if (pProcFile) {
+-              pProcFile->proc_fops = &sk_proc_fops;
+-              pProcFile->data = dev;
+-              pProcFile->owner = THIS_MODULE;
+-      }
+-#endif
+-
+-      pNet->PortNr = 0;
+-      pNet->NetNr  = 0;
+-
+-      boards_found++;
+-
+-      /* More then one port found */
+-      if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
+-              if ((dev = alloc_etherdev(sizeof(DEV_NET))) == 0) {
+-                      printk(KERN_ERR "Unable to allocate etherdev "
+-                              "structure!\n");
+-                      goto out;
+-              }
+-
+-              pAC->dev[1]   = dev;
+-              pNet          = dev->priv;
+-              pNet->PortNr  = 1;
+-              pNet->NetNr   = 1;
+-              pNet->pAC     = pAC;
+-              pNet->Mtu     = 1500;
+-              pNet->Up      = 0;
+-
+-              dev->open               = &SkGeOpen;
+-              dev->stop               = &SkGeClose;
+-              dev->hard_start_xmit    = &SkGeXmit;
+-              dev->get_stats          = &SkGeStats;
+-              dev->set_multicast_list = &SkGeSetRxMode;
+-              dev->set_mac_address    = &SkGeSetMacAddr;
+-              dev->do_ioctl           = &SkGeIoctl;
+-              dev->change_mtu         = &SkGeChangeMtu;
+-              dev->flags             &= ~IFF_RUNNING;
+-
+-#ifdef SK_ZEROCOPY
+-#ifdef USE_SK_TX_CHECKSUM
+-              if (pAC->ChipsetType) {
+-                      /* SG and ZEROCOPY - fly baby... */
+-                      dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+-              }
+-#endif
+-#endif
+-
+-              if (register_netdev(dev)) {
+-                      printk(KERN_ERR "SKGE: Could not register device.\n");
+-                      free_netdev(dev);
+-                      pAC->dev[1] = pAC->dev[0];
+-              } else {
+-#ifdef CONFIG_PROC_FS
+-                      pProcFile = create_proc_entry(dev->name, S_IRUGO,
+-                                      pSkRootDir);
+-                      if (pProcFile) {
+-                              pProcFile->proc_fops = &sk_proc_fops;
+-                              pProcFile->data = dev;
+-                              pProcFile->owner = THIS_MODULE;
+-                      }
+-#endif
+-
+-                      memcpy(&dev->dev_addr,
+-                                      &pAC->Addr.Net[1].CurrentMacAddress, 6);
+-      
+-                      printk("%s: %s\n", dev->name, pAC->DeviceStr);
+-                      printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
+-              }
+-      }
+-
+-      /* Save the hardware revision */
+-      pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
+-              (pAC->GIni.GIPciHwRev & 0x0F);
+-
+-      /* Set driver globals */
+-      pAC->Pnmi.pDriverFileName    = DRIVER_FILE_NAME;
+-      pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE;
+-
+-      memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA));
+-      memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA));
+-
+-      pci_set_drvdata(pdev, dev);
+-      return 0;
+-
+- out_free_resources:
+-      FreeResources(dev);
+- out_free_netdev:
+-      free_netdev(dev);
+- out_disable_device:
+-      pci_disable_device(pdev);
+- out:
+-      return error;
+-}
+-
+-static void __devexit skge_remove_one(struct pci_dev *pdev)
+-{
+-      struct net_device *dev = pci_get_drvdata(pdev);
+-      DEV_NET *pNet = (DEV_NET *) dev->priv;
+-      SK_AC *pAC = pNet->pAC;
+-      int have_second_mac = 0;
+-
+-      if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2)
+-              have_second_mac = 1;
+-
+-      remove_proc_entry(dev->name, pSkRootDir);
+-      unregister_netdev(dev);
+-      if (have_second_mac) {
+-              remove_proc_entry(pAC->dev[1]->name, pSkRootDir);
+-              unregister_netdev(pAC->dev[1]);
+-      }
+-
+-      SkGeYellowLED(pAC, pAC->IoBase, 0);
+-
+-      if (pAC->BoardLevel == SK_INIT_RUN) {
+-              SK_EVPARA EvPara;
+-              unsigned long Flags;
+-
+-              /* board is still alive */
+-              spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+-              EvPara.Para32[0] = 0;
+-              EvPara.Para32[1] = -1;
+-              SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+-              EvPara.Para32[0] = 1;
+-              EvPara.Para32[1] = -1;
+-              SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+-              SkEventDispatcher(pAC, pAC->IoBase);
+-              /* disable interrupts */
+-              SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+-              SkGeDeInit(pAC, pAC->IoBase);
+-              spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+-              pAC->BoardLevel = SK_INIT_DATA;
+-              /* We do NOT check here, if IRQ was pending, of course*/
+-      }
+-
+-      if (pAC->BoardLevel == SK_INIT_IO) {
+-              /* board is still alive */
+-              SkGeDeInit(pAC, pAC->IoBase);
+-              pAC->BoardLevel = SK_INIT_DATA;
+-      }
+-
+-      FreeResources(dev);
+-      free_netdev(dev);
+-      if (have_second_mac)
+-              free_netdev(pAC->dev[1]);
+-      kfree(pAC);
+-}
+-
+-static struct pci_device_id skge_pci_tbl[] = {
+-      { PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+-      { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+-      { PCI_VENDOR_ID_SYSKONNECT, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+-      { PCI_VENDOR_ID_SYSKONNECT, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+-      { PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+-      { PCI_VENDOR_ID_MARVELL, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+-#if 0 /* don't handle Yukon2 cards at the moment -- mlindner@syskonnect.de */
+-      { PCI_VENDOR_ID_MARVELL, 0x4360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+-      { PCI_VENDOR_ID_MARVELL, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+-#endif
+-      { PCI_VENDOR_ID_MARVELL, 0x5005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+-      { PCI_VENDOR_ID_CNET, 0x434e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+-      { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+-      { PCI_VENDOR_ID_LINKSYS, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+-      { 0, }
+-};
+-
+-/*****************************************************************************
++/*******************************************************************************
+  *
+- * Avoid PCI ID confusion w/ skge by limiting advertised IDs so we don't
+- * needlessly overlap...
++ * End of file
+  *
+- */
+-static struct pci_device_id advertised_skge_pci_tbl[] = {
+-      { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+-      { 0, }
+-};
+-
+-MODULE_DEVICE_TABLE(pci, advertised_skge_pci_tbl);
+-
+-static struct pci_driver skge_driver = {
+-      .name           = "skge",
+-      .id_table       = skge_pci_tbl,
+-      .probe          = skge_probe_one,
+-      .remove         = __devexit_p(skge_remove_one),
+-};
+-
+-static int __init skge_init(void)
+-{
+-      int error;
+-
+-#ifdef CONFIG_PROC_FS
+-      memcpy(&SK_Root_Dir_entry, BOOT_STRING, sizeof(SK_Root_Dir_entry) - 1);
+-
+-      pSkRootDir = proc_mkdir(SK_Root_Dir_entry, proc_net);
+-      if (!pSkRootDir) {
+-              printk(KERN_WARNING "Unable to create /proc/net/%s",
+-                              SK_Root_Dir_entry);
+-              return -ENOMEM;
+-      }
+-      pSkRootDir->owner = THIS_MODULE;
+-#endif
+-
+-      error = pci_module_init(&skge_driver);
+-      if (error) {
+-#ifdef CONFIG_PROC_FS
+-              remove_proc_entry(pSkRootDir->name, proc_net);
+-#endif
+-      }
+-
+-      return error;
+-}
+-
+-static void __exit skge_exit(void)
+-{
+-       pci_unregister_driver(&skge_driver);
+-#ifdef CONFIG_PROC_FS
+-      remove_proc_entry(pSkRootDir->name, proc_net);
+-#endif
+-}
++ ******************************************************************************/
+-module_init(skge_init);
+-module_exit(skge_exit);
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skgehwt.c linux-2.6.9.new/drivers/net/sk98lin/skgehwt.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skgehwt.c      2004-10-19 05:55:07.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skgehwt.c      2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgehwt.c
+  * Project:   Gigabit Ethernet Adapters, Event Scheduler Module
+- * Version:   $Revision: 1.15 $
+- * Date:      $Date: 2003/09/16 13:41:23 $
++ * Version:   $Revision: 2.2 $
++ * Date:      $Date: 2004/05/28 13:39:04 $
+  * Purpose:   Hardware Timer
+  *
+  ******************************************************************************/
+@@ -11,7 +11,7 @@
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect GmbH.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2004 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+@@ -27,7 +27,7 @@
+  */
+ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: skgehwt.c,v 1.15 2003/09/16 13:41:23 rschmidt Exp $ (C) Marvell.";
++      "@(#) $Id: skgehwt.c,v 2.2 2004/05/28 13:39:04 rschmidt Exp $ (C) Marvell.";
+ #endif
+ #include "h/skdrv1st.h"               /* Driver Specific Definitions */
+@@ -44,10 +44,10 @@
+ /*
+  * Prototypes of local functions.
+  */
+-#define       SK_HWT_MAX      (65000)
++#define       SK_HWT_MAX      65000UL * 160           /* ca. 10 sec. */
+ /* correction factor */
+-#define       SK_HWT_FAC      (1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100)
++#define       SK_HWT_FAC      (10 * (SK_U32)pAC->GIni.GIHstClkFact / 16)
+ /*
+  * Initialize hardware timer.
+@@ -73,29 +73,21 @@
+ void  SkHwtStart(
+ SK_AC *pAC,   /* Adapters context */
+ SK_IOC        Ioc,    /* IoContext */
+-SK_U32        Time)   /* Time in units of 16us to load the timer with. */
++SK_U32        Time)   /* Time in usec to load the timer */
+ {
+-      SK_U32  Cnt;
+-
+       if (Time > SK_HWT_MAX)
+               Time = SK_HWT_MAX;
+       pAC->Hwt.TStart = Time;
+       pAC->Hwt.TStop = 0L;
+-      Cnt = Time;
+-
+-      /*
+-       * if time < 16 us
+-       *      time = 16 us
+-       */
+-      if (!Cnt) {
+-              Cnt++;
++      if (!Time) {
++              Time = 1L;
+       }
+-      SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC);
+-      
+-      SK_OUT16(Ioc, B2_TI_CTRL, TIM_START);   /* Start timer. */
++      SK_OUT32(Ioc, B2_TI_INI, Time * SK_HWT_FAC);
++
++      SK_OUT16(Ioc, B2_TI_CTRL, TIM_START);   /* Start timer */
+       pAC->Hwt.TActive = SK_TRUE;
+ }
+@@ -109,13 +101,12 @@
+ SK_IOC        Ioc)    /* IoContext */
+ {
+       SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP);
+-      
++
+       SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ);
+       pAC->Hwt.TActive = SK_FALSE;
+ }
+-
+ /*
+  *    Stop hardware timer and read time elapsed since last start.
+  *
+@@ -129,6 +120,9 @@
+ {
+       SK_U32  TRead;
+       SK_U32  IStatus;
++      SK_U32  TimerInt;
++
++      TimerInt = CHIP_ID_YUKON_2(pAC) ? Y2_IS_TIMINT : IS_TIMINT;
+       if (pAC->Hwt.TActive) {
+               
+@@ -139,15 +133,15 @@
+               SK_IN32(Ioc, B0_ISRC, &IStatus);
+-              /* Check if timer expired (or wraped around) */
+-              if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) {
+-                      
++              /* Check if timer expired (or wrapped around) */
++              if ((TRead > pAC->Hwt.TStart) || ((IStatus & TimerInt) != 0)) {
++
+                       SkHwtStop(pAC, Ioc);
+-                      
++
+                       pAC->Hwt.TStop = pAC->Hwt.TStart;
+               }
+               else {
+-                      
++
+                       pAC->Hwt.TStop = pAC->Hwt.TStart - TRead;
+               }
+       }
+@@ -162,9 +156,9 @@
+ SK_IOC        Ioc)    /* IoContext */
+ {
+       SkHwtStop(pAC, Ioc);
+-      
++
+       pAC->Hwt.TStop = pAC->Hwt.TStart;
+-      
++
+       SkTimerDone(pAC, Ioc);
+ }
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skgeinit.c linux-2.6.9.new/drivers/net/sk98lin/skgeinit.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skgeinit.c     2004-10-19 05:54:30.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skgeinit.c     2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgeinit.c
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.97 $
+- * Date:      $Date: 2003/10/02 16:45:31 $
++ * Version:   $Revision: 2.73 $
++ * Date:      $Date: 2005/05/24 08:05:45 $
+  * Purpose:   Contains functions to initialize the adapter
+  *
+  ******************************************************************************/
+@@ -11,13 +11,12 @@
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2005 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+  *    the Free Software Foundation; either version 2 of the License, or
+  *    (at your option) any later version.
+- *
+  *    The information in this file is provided "AS IS" without warranty.
+  *
+  ******************************************************************************/
+@@ -31,7 +30,7 @@
+ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: skgeinit.c,v 1.97 2003/10/02 16:45:31 rschmidt Exp $ (C) Marvell.";
++      "@(#) $Id: skgeinit.c,v 2.73 2005/05/24 08:05:45 rschmidt Exp $ (C) Marvell.";
+ #endif
+ struct s_QOffTab {
+@@ -59,6 +58,101 @@
+ /******************************************************************************
+  *
++ *    SkGePortVlan() -        Enable / Disable VLAN support
++ *
++ * Description:
++ *    Enable or disable the VLAN support of the selected port.
++ *    The new configuration is *not* saved over any SkGeStopPort() and
++ *    SkGeInitPort() calls.
++ *    Currently this function is only supported on Yukon-2/EC adapters.
++ *
++ * Returns:
++ *    nothing
++ */
++void SkGePortVlan(
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
++int           Port,   /* Port number */
++SK_BOOL       Enable) /* Flag */
++{
++      if (CHIP_ID_YUKON_2(pAC)) {
++              if (Enable) {
++                      SK_OUT32(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
++                      SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
++              }
++              else {
++                      SK_OUT32(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
++                      SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
++              }
++      }
++}
++
++
++/******************************************************************************
++ *
++ *    SkGeRxRss() -   Enable / Disable RSS Hash Calculation
++ *
++ * Description:
++ *    Enable or disable the RSS hash calculation of the selected port.
++ *    The new configuration is *not* saved over any SkGeStopPort() and
++ *    SkGeInitPort() calls.
++ *    Currently this function is only supported on Yukon-2/EC adapters.
++ *
++ * Returns:
++ *    nothing
++ */
++void SkGeRxRss(
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
++int           Port,   /* Port number */
++SK_BOOL       Enable) /* Flag */
++{
++      if (CHIP_ID_YUKON_2(pAC)) {
++              if (Enable) {
++                      SK_OUT32(IoC, Q_ADDR(pAC->GIni.GP[Port].PRxQOff, Q_CSR),
++                              BMU_ENA_RX_RSS_HASH);
++              }
++              else {
++                      SK_OUT32(IoC, Q_ADDR(pAC->GIni.GP[Port].PRxQOff, Q_CSR),
++                              BMU_DIS_RX_RSS_HASH);
++              }
++      }
++}
++
++/******************************************************************************
++ *
++ *    SkGeRxCsum() -  Enable / Disable Receive Checksum
++ *
++ * Description:
++ *    Enable or disable the checksum of the selected port.
++ *    The new configuration is *not* saved over any SkGeStopPort() and
++ *    SkGeInitPort() calls.
++ *    Currently this function is only supported on Yukon-2/EC adapters.
++ *
++ * Returns:
++ *    nothing
++ */
++void SkGeRxCsum(
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
++int           Port,   /* Port number */
++SK_BOOL       Enable) /* Flag */
++{
++      if (CHIP_ID_YUKON_2(pAC)) {
++              if (Enable) {
++                      SK_OUT32(IoC, Q_ADDR(pAC->GIni.GP[Port].PRxQOff, Q_CSR),
++                              BMU_ENA_RX_CHKSUM);
++              }
++              else {
++                      SK_OUT32(IoC, Q_ADDR(pAC->GIni.GP[Port].PRxQOff, Q_CSR),
++                              BMU_DIS_RX_CHKSUM);
++              }
++      }
++}
++
++
++/******************************************************************************
++ *
+  *    SkGePollRxD() - Enable / Disable Descriptor Polling of RxD Ring
+  *
+  * Description:
+@@ -71,8 +165,8 @@
+  *    nothing
+  */
+ void SkGePollRxD(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ SK_BOOL PollRxD)      /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
+ {
+@@ -80,8 +174,8 @@
+       pPrt = &pAC->GIni.GP[Port];
+-      SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (PollRxD) ?
+-              CSR_ENA_POL : CSR_DIS_POL);
++      SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (SK_U32)((PollRxD) ?
++              CSR_ENA_POL : CSR_DIS_POL));
+ }     /* SkGePollRxD */
+@@ -99,8 +193,8 @@
+  *    nothing
+  */
+ void SkGePollTxD(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ SK_BOOL PollTxD)      /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
+ {
+@@ -114,7 +208,7 @@
+       if (pPrt->PXSQSize != 0) {
+               SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord);
+       }
+-      
++
+       if (pPrt->PXAQSize != 0) {
+               SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord);
+       }
+@@ -135,17 +229,27 @@
+  *    nothing
+  */
+ void SkGeYellowLED(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           State)          /* yellow LED state, 0 = OFF, 0 != ON */
+ {
++      int     LedReg;
++
++      if (CHIP_ID_YUKON_2(pAC)) {
++              /* different mapping on Yukon-2 */
++              LedReg = B0_CTST + 1;
++      }
++      else {
++              LedReg = B0_LED;
++      }
++
+       if (State == 0) {
+-              /* Switch yellow LED OFF */
+-              SK_OUT8(IoC, B0_LED, LED_STAT_OFF);
++              /* Switch state LED OFF */
++              SK_OUT8(IoC, LedReg, LED_STAT_OFF);
+       }
+       else {
+-              /* Switch yellow LED ON */
+-              SK_OUT8(IoC, B0_LED, LED_STAT_ON);
++              /* Switch state LED ON */
++              SK_OUT8(IoC, LedReg, LED_STAT_ON);
+       }
+ }     /* SkGeYellowLED */
+@@ -169,8 +273,8 @@
+  *    nothing
+  */
+ void SkGeXmitLED(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Led,            /* offset to the LED Init Value register */
+ int           Mode)           /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */
+ {
+@@ -197,13 +301,13 @@
+               SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF);
+               break;
+       }
+-                      
++
+       /*
+-       * 1000BT: The Transmit LED is driven by the PHY.
++       * 1000BT: the Transmit LED is driven by the PHY.
+        * But the default LED configuration is used for
+        * Level One and Broadcom PHYs.
+-       * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.)
+-       * (In this case it has to be added here. But we will see. XXX)
++       * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.
++       * In this case it has to be added here.)
+        */
+ }     /* SkGeXmitLED */
+ #endif        /* !SK_SLIM || GENESIS */
+@@ -227,7 +331,7 @@
+  *    1:      configuration error
+  */
+ static int DoCalcAddr(
+-SK_AC         *pAC,                           /* adapter context */
++SK_AC         *pAC,                           /* Adapter Context */
+ SK_GEPORT     SK_FAR *pPrt,           /* port index */
+ int                   QuSize,                         /* size of the queue to configure in kB */
+ SK_U32                SK_FAR *StartVal,       /* start value for address calculation */
+@@ -264,12 +368,35 @@
+ /******************************************************************************
+  *
++ *    SkGeRoundQueueSize() - Round the given queue size to the adpaters QZ units
++ *
++ * Description:
++ *    This function rounds the given queue size in kBs to adapter specific
++ *    queue size units (Genesis and Yukon: 8 kB, Yukon-2/EC: 1 kB).
++ *
++ * Returns:
++ *    the rounded queue size in kB    
++ */
++static int SkGeRoundQueueSize(
++SK_AC *pAC,           /* Adapter Context */
++int   QueueSizeKB)    /* Queue size in kB */
++{
++      int QueueSizeSteps;
++
++      QueueSizeSteps = (CHIP_ID_YUKON_2(pAC)) ? QZ_STEP_Y2 : QZ_STEP;
++
++      return((QueueSizeKB + QueueSizeSteps - 1) & ~(QueueSizeSteps - 1));
++}     /* SkGeRoundQueueSize */
++
++
++/******************************************************************************
++ *
+  *    SkGeInitAssignRamToQueues() - allocate default queue sizes
+  *
+  * Description:
+  *    This function assigns the memory to the different queues and ports.
+  *    When DualNet is set to SK_TRUE all ports get the same amount of memory.
+- *  Otherwise the first port gets most of the memory and all the
++ *    Otherwise the first port gets most of the memory and all the
+  *    other ports just the required minimum.
+  *    This function can only be called when pAC->GIni.GIRamSize and
+  *    pAC->GIni.GIMacsFound have been initialized, usually this happens
+@@ -282,102 +409,141 @@
+  */
+ int SkGeInitAssignRamToQueues(
+-SK_AC *pAC,                   /* Adapter context */
++SK_AC *pAC,                   /* Adapter Context */
+ int           ActivePort,             /* Active Port in RLMT mode */
+-SK_BOOL       DualNet)                /* adapter context */
++SK_BOOL       DualNet)                /* Dual Net active */
+ {
+       int     i;
+       int     UsedKilobytes;                  /* memory already assigned */
+       int     ActivePortKilobytes;    /* memory available for active port */
+-      SK_GEPORT *pGePort;
+-
+-      UsedKilobytes = 0;
++      int     MinQueueSize;                   /* min. memory for queues */
++      int     TotalRamSize;                   /* total memory for queues */
++      SK_BOOL DualPortYukon2;
++      SK_GEPORT *pPrt;
+       if (ActivePort >= pAC->GIni.GIMacsFound) {
++
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+                       ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n",
+                       ActivePort));
+               return(1);
+       }
+-      if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) +
+-              ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) {
++
++      DualPortYukon2 = (CHIP_ID_YUKON_2(pAC) && pAC->GIni.GIMacsFound == 2);
++
++      TotalRamSize = pAC->GIni.GIRamSize;
++
++      if (DualPortYukon2) {
++              TotalRamSize *= 2;
++      }
++
++      MinQueueSize = SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE;
++
++      if (MinQueueSize > pAC->GIni.GIRamSize) {
++              MinQueueSize = pAC->GIni.GIRamSize;
++      }
++
++      if ((pAC->GIni.GIMacsFound * MinQueueSize +
++               RAM_QUOTA_SYNC * SK_MIN_TXQ_SIZE) > TotalRamSize) {
++
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+                       ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n",
+-                       pAC->GIni.GIRamSize));
++                      TotalRamSize));
+               return(2);
+       }
+       if (DualNet) {
+               /* every port gets the same amount of memory */
+-              ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound;
++              ActivePortKilobytes = TotalRamSize / pAC->GIni.GIMacsFound;
++
+               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+-                      pGePort = &pAC->GIni.GP[i];
+-                      
++                      pPrt = &pAC->GIni.GP[i];
++
++                      if (DualPortYukon2) {
++                              ActivePortKilobytes = pAC->GIni.GIRamSize;
++                      }
+                       /* take away the minimum memory for active queues */
+-                      ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
++                      ActivePortKilobytes -= MinQueueSize;
+                       /* receive queue gets the minimum + 80% of the rest */
+-                      pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((
+-                              ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100))
++                      pPrt->PRxQSize = SkGeRoundQueueSize(pAC,
++                              (int)((long)ActivePortKilobytes * RAM_QUOTA_RX) / 100)
+                               + SK_MIN_RXQ_SIZE;
+-                      ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
++                      ActivePortKilobytes -= (pPrt->PRxQSize - SK_MIN_RXQ_SIZE);
+                       /* synchronous transmit queue */
+-                      pGePort->PXSQSize = 0;
++                      pPrt->PXSQSize = 0;
+                       /* asynchronous transmit queue */
+-                      pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes +
+-                              SK_MIN_TXQ_SIZE);
++                      pPrt->PXAQSize = SkGeRoundQueueSize(pAC,
++                              ActivePortKilobytes + SK_MIN_TXQ_SIZE);
+               }
+       }
+-      else {  
+-              /* Rlmt Mode or single link adapter */
++      else {  /* RLMT Mode or single link adapter */
+-              /* Set standby queue size defaults for all standby ports */
++              UsedKilobytes = 0;
++
++              /* set standby queue size defaults for all standby ports */
+               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+                       if (i != ActivePort) {
+-                              pGePort = &pAC->GIni.GP[i];
++                              pPrt = &pAC->GIni.GP[i];
+-                              pGePort->PRxQSize = SK_MIN_RXQ_SIZE;
+-                              pGePort->PXAQSize = SK_MIN_TXQ_SIZE;
+-                              pGePort->PXSQSize = 0;
++                              if (DualPortYukon2) {
++                                      pPrt->PRxQSize = SkGeRoundQueueSize(pAC,
++                                              (int)((long)pAC->GIni.GIRamSize * RAM_QUOTA_RX) / 100);
++                                      pPrt->PXAQSize = pAC->GIni.GIRamSize - pPrt->PRxQSize;
++                              }
++                              else {
++                                      pPrt->PRxQSize = SK_MIN_RXQ_SIZE;
++                                      pPrt->PXAQSize = SK_MIN_TXQ_SIZE;
++                              }
++                              pPrt->PXSQSize = 0;
+                               /* Count used RAM */
+-                              UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize;
++                              UsedKilobytes += pPrt->PRxQSize + pPrt->PXAQSize;
+                       }
+               }
+               /* what's left? */
+-              ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes;
++              ActivePortKilobytes = TotalRamSize - UsedKilobytes;
+               /* assign it to the active port */
+               /* first take away the minimum memory */
+-              ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
+-              pGePort = &pAC->GIni.GP[ActivePort];
++              ActivePortKilobytes -= MinQueueSize;
++              pPrt = &pAC->GIni.GP[ActivePort];
+               /* receive queue get's the minimum + 80% of the rest */
+-              pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes *
+-                      (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE;
++              pPrt->PRxQSize = SkGeRoundQueueSize(pAC,
++                      (int)((long)ActivePortKilobytes * RAM_QUOTA_RX) / 100) +
++                      MinQueueSize/2;
+-              ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
++              ActivePortKilobytes -= (pPrt->PRxQSize - MinQueueSize/2);
+               /* synchronous transmit queue */
+-              pGePort->PXSQSize = 0;
++              pPrt->PXSQSize = 0;
+               /* asynchronous transmit queue */
+-              pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) +
+-                      SK_MIN_TXQ_SIZE;
++              pPrt->PXAQSize = SkGeRoundQueueSize(pAC, ActivePortKilobytes) +
++                      MinQueueSize/2;
+       }
+-#ifdef VCPU
+-      VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n",
+-              pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize);
+-#endif /* VCPU */
++
++#ifdef DEBUG
++      for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
++
++              pPrt = &pAC->GIni.GP[i];
++
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++                      ("Port %d: RxQSize=%u, TxAQSize=%u, TxSQSize=%u\n",
++                      i, pPrt->PRxQSize, pPrt->PXAQSize, pPrt->PXSQSize));
++      }
++#endif /* DEBUG */
+       return(0);
+ }     /* SkGeInitAssignRamToQueues */
++
+ /******************************************************************************
+  *
+  *    SkGeCheckQSize() - Checks the Adapters Queue Size Configuration
+@@ -388,12 +554,12 @@
+  *    used ports.
+  *    This requirements must be fullfilled to have a valid configuration:
+  *            - The size of all queues must not exceed GIRamSize.
+- *            - The queue sizes must be specified in units of 8 kB.
++ *            - The queue sizes must be specified in units of 8 kB (Genesis & Yukon).
+  *            - The size of Rx queues of available ports must not be
+- *              smaller than 16 kB.
++ *              smaller than 16 kB (Genesis & Yukon) resp. 10 kB (Yukon-2).
+  *            - The size of at least one Tx queue (synch. or asynch.)
+- *        of available ports must not be smaller than 16 kB
+- *        when Jumbo Frames are used.
++ *              of available ports must not be smaller than 16 kB (Genesis & Yukon),
++ *              resp. 10 kB (Yukon-2) when Jumbo Frames are used.
+  *            - The RAM start and end addresses must not be changed
+  *              for ports which are already initialized.
+  *    Furthermore SkGeCheckQSize() defines the Start and End Addresses
+@@ -404,7 +570,7 @@
+  *    1:      Queue Size Configuration invalid
+  */
+ static int SkGeCheckQSize(
+-SK_AC  *pAC,          /* adapter context */
++SK_AC  *pAC,          /* Adapter Context */
+ int            Port)          /* port index */
+ {
+       SK_GEPORT *pPrt;
+@@ -414,55 +580,68 @@
+       SK_U32  StartAddr;
+ #ifndef SK_SLIM
+       int     UsedMem;        /* total memory used (max. found ports) */
+-#endif        
++#endif
+       Rtv = 0;
+-      
++
+ #ifndef SK_SLIM
+       UsedMem = 0;
++      Rtv = 0;
+       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+               pPrt = &pAC->GIni.GP[i];
+-              if ((pPrt->PRxQSize & QZ_UNITS) != 0 ||
+-                      (pPrt->PXSQSize & QZ_UNITS) != 0 ||
+-                      (pPrt->PXAQSize & QZ_UNITS) != 0) {
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      UsedMem = 0;
++              }
++              else if (((pPrt->PRxQSize & QZ_UNITS) != 0 ||
++                                (pPrt->PXSQSize & QZ_UNITS) != 0 ||
++                                (pPrt->PXAQSize & QZ_UNITS) != 0)) {
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
+                       return(1);
+               }
+-              if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) {
++#ifndef SK_DIAG
++              if (i == Port && pAC->GIni.GIRamSize > SK_MIN_RXQ_SIZE &&
++                      pPrt->PRxQSize < SK_MIN_RXQ_SIZE) {
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG);
+                       return(1);
+               }
+-              
++
+               /*
+                * the size of at least one Tx queue (synch. or asynch.) has to be > 0.
+                * if Jumbo Frames are used, this size has to be >= 16 kB.
+                */
+               if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) ||
+-                      (pAC->GIni.GIPortUsage == SK_JUMBO_LINK &&
+-            ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) ||
++                      (pPrt->PPortUsage == SK_JUMBO_LINK &&
++                      ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) ||
+                        (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) {
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG);
+                               return(1);
+               }
+-              
++#endif /* !SK_DIAG */
++
+               UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize;
++
++              if (UsedMem > pAC->GIni.GIRamSize) {
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
++                      return(1);
++              }
+       }
+-      
+-      if (UsedMem > pAC->GIni.GIRamSize) {
+-              SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
+-              return(1);
+-      }
++
+ #endif        /* !SK_SLIM */
+       /* Now start address calculation */
+       StartAddr = pAC->GIni.GIRamOffs;
+       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
++
+               pPrt = &pAC->GIni.GP[i];
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      StartAddr = 0;
++              }
++
+               /* Calculate/Check values for the receive queue */
+               Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr,
+                       &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd);
+@@ -502,8 +681,8 @@
+  *    nothing
+  */
+ static void SkGeInitMacArb(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC)            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC)            /* I/O Context */
+ {
+       /* release local reset */
+       SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR);
+@@ -542,8 +721,8 @@
+  *    nothing
+  */
+ static void SkGeInitPktArb(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC)            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC)            /* I/O Context */
+ {
+       /* release local reset */
+       SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR);
+@@ -559,7 +738,8 @@
+        * NOTE: the packet arbiter timeout interrupt is needed for
+        * half duplex hangup workaround
+        */
+-      if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) {
++      if (pAC->GIni.GP[MAC_1].PPortUsage != SK_JUMBO_LINK &&
++              pAC->GIni.GP[MAC_2].PPortUsage != SK_JUMBO_LINK) {
+               if (pAC->GIni.GIMacsFound == 1) {
+                       SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1);
+               }
+@@ -582,14 +762,11 @@
+  *    nothing
+  */
+ static void SkGeInitMacFifo(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_U16  Word;
+-#ifdef VCPU
+-      SK_U32  DWord;
+-#endif /* VCPU */
+       /*
+        * For each FIFO:
+        *      - release local reset
+@@ -597,31 +774,29 @@
+        *      - setup defaults for the control register
+        *      - enable the FIFO
+        */
+-      
++
+ #ifdef GENESIS
+       if (pAC->GIni.GIGenesis) {
+-              /* Configure Rx MAC FIFO */
++              /* configure Rx MAC FIFO */
+               SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR);
+               SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF);
+               SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
+-      
++
+               /* Configure Tx MAC FIFO */
+               SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR);
+               SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
+               SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
+-      
+-              /* Enable frame flushing if jumbo frames used */
+-              if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
++
++              /* enable frame flushing if jumbo frames used */
++              if (pAC->GIni.GP[Port].PPortUsage == SK_JUMBO_LINK) {
+                       SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH);
+               }
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+-              /* set Rx GMAC FIFO Flush Mask */
+-              SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK);
+-              
++
+               Word = (SK_U16)GMF_RX_CTRL_DEF;
+               /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */
+@@ -629,23 +804,52 @@
+                       Word &= ~GMF_RX_F_FL_ON;
+               }
+-              
+-              /* Configure Rx MAC FIFO */
++
++              /* Configure Rx GMAC FIFO */
+               SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
+               SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word);
+-              
+-              /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */
+-              SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
+-              
+-              /* Configure Tx MAC FIFO */
++
++              Word = RX_FF_FL_DEF_MSK;
++
++#ifndef SK_DIAG
++              if (HW_FEATURE(pAC, HWF_WA_DEV_4115)) {
++                      /*
++                       * Flushing must be enabled (needed for ASF see dev. #4.29),
++                       * but the flushing mask should be disabled (see dev. #4.115)
++                       */
++                      Word = 0;
++              }
++#endif /* !SK_DIAG */
++
++              /* set Rx GMAC FIFO Flush Mask (after clearing reset) */
++              SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), Word);
++
++              /* default: 0x0a -> 56 bytes on Yukon-1 and 64 bytes on Yukon-2 */
++              Word = (SK_U16)RX_GMF_FL_THR_DEF;
++
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC &&
++                              pAC->GIni.GIAsfEnabled) {
++                              /* WA for dev. #4.30 (reduce to 0x08 -> 48 bytes) */
++                              Word -= 2;
++                      }
++              }
++              else {
++                      /*
++                      * because Pause Packet Truncation in GMAC is not working
++                      * we have to increase the Flush Threshold to 64 bytes
++                      * in order to flush pause packets in Rx FIFO on Yukon-1
++                      */
++                      Word++;
++              }
++
++              /* set Rx GMAC FIFO Flush Threshold (after clearing reset) */
++              SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), Word);
++
++              /* Configure Tx GMAC FIFO */
+               SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
+               SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF);
+-              
+-#ifdef VCPU
+-              SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord);
+-              SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord);
+-#endif /* VCPU */
+-              
++
+               /* set Tx GMAC FIFO Almost Empty Threshold */
+ /*            SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */
+       }
+@@ -653,7 +857,7 @@
+ }     /* SkGeInitMacFifo */
+-#ifdef        SK_LNK_SYNC_CNT
++#ifdef SK_LNK_SYNC_CNT
+ /******************************************************************************
+  *
+  *    SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting
+@@ -674,8 +878,8 @@
+  *    nothing
+  */
+ void SkGeLoadLnkSyncCnt(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ SK_U32        CntVal)         /* Counter value */
+ {
+@@ -685,7 +889,7 @@
+       SK_BOOL IrqPend;
+       /* stop counter */
+-      SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP);
++      SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LNK_STOP);
+       /*
+        * ASIC problem:
+@@ -698,6 +902,7 @@
+       IrqPend = SK_FALSE;
+       SK_IN32(IoC, B0_ISRC, &ISrc);
+       SK_IN32(IoC, B0_IMSK, &OrgIMsk);
++      
+       if (Port == MAC_1) {
+               NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1;
+               if ((ISrc & IS_LNK_SYNC_M1) != 0) {
+@@ -710,6 +915,7 @@
+                       IrqPend = SK_TRUE;
+               }
+       }
++
+       if (!IrqPend) {
+               SK_OUT32(IoC, B0_IMSK, NewIMsk);
+       }
+@@ -718,15 +924,17 @@
+       SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal);
+       /* start counter */
+-      SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START);
++      SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LNK_START);
+       if (!IrqPend) {
+-              /* clear the unexpected IRQ, and restore the interrupt mask */
+-              SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ);
++              /* clear the unexpected IRQ */
++              SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LNK_CLR_IRQ);
++              
++              /* restore the interrupt mask */
+               SK_OUT32(IoC, B0_IMSK, OrgIMsk);
+       }
+ }     /* SkGeLoadLnkSyncCnt*/
+-#endif        /* SK_LNK_SYNC_CNT */
++#endif /* SK_LNK_SYNC_CNT */
+ #if defined(SK_DIAG) || defined(SK_CFG_SYNC)
+ /******************************************************************************
+@@ -758,8 +966,8 @@
+  *            synchronous queue is configured
+  */
+ int SkGeCfgSync(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ SK_U32        IntTime,        /* Interval Timer Value in units of 8ns */
+ SK_U32        LimCount,       /* Number of bytes to transfer during IntTime */
+@@ -777,16 +985,16 @@
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
+               return(1);
+       }
+-      
++
+       if (pAC->GIni.GP[Port].PXSQSize == 0) {
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG);
+               return(2);
+       }
+-      
++
+       /* calculate register values */
+       IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100;
+       LimCount = LimCount / 8;
+-      
++
+       if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) {
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
+               return(1);
+@@ -804,13 +1012,13 @@
+        */
+       SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
+               TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
+-      
++
+       SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime);
+       SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount);
+-      
++
+       SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
+               (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC)));
+-      
++
+       if (IntTime != 0 || LimCount != 0) {
+               SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC);
+       }
+@@ -831,10 +1039,10 @@
+  * Returns:
+  *    nothing
+  */
+-static void DoInitRamQueue(
+-SK_AC *pAC,                   /* adapter context */
+-SK_IOC        IoC,                    /* IO context */
+-int           QuIoOffs,               /* Queue IO Address Offset */
++void DoInitRamQueue(
++SK_AC *pAC,                   /* Adapter Context */
++SK_IOC        IoC,                    /* I/O Context */
++int           QuIoOffs,               /* Queue I/O Address Offset */
+ SK_U32        QuStartAddr,    /* Queue Start Address */
+ SK_U32        QuEndAddr,              /* Queue End Address */
+ int           QuType)                 /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */
+@@ -867,8 +1075,7 @@
+                       /* continue with SK_RX_BRAM_Q */
+               case SK_RX_BRAM_Q:
+-                      /* write threshold for Rx Queue */
+-
++                      /* write threshold for Rx Queue (Pause packets) */
+                       SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal);
+                       SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal);
+@@ -882,7 +1089,8 @@
+                        * or YUKON is used ((GMAC Tx FIFO is only 1 kB)
+                        * we NEED Store & Forward of the RAM buffer.
+                        */
+-                      if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK ||
++                      if (pAC->GIni.GP[MAC_1].PPortUsage == SK_JUMBO_LINK ||
++                              pAC->GIni.GP[MAC_2].PPortUsage == SK_JUMBO_LINK ||
+                               pAC->GIni.GIYukon) {
+                               /* enable Store & Forward Mode for the Tx Side */
+                               SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD);
+@@ -911,8 +1119,8 @@
+  *    nothing
+  */
+ static void SkGeInitRamBufs(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT *pPrt;
+@@ -920,8 +1128,8 @@
+       pPrt = &pAC->GIni.GP[Port];
+-      if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) {
+-              RxQType = SK_RX_SRAM_Q;         /* small Rx Queue */
++      if (pPrt->PRxQSize <= SK_MIN_RXQ_SIZE) {
++              RxQType = SK_RX_SRAM_Q;         /* small Rx Queue */
+       }
+       else {
+               RxQType = SK_RX_BRAM_Q;         /* big Rx Queue */
+@@ -929,10 +1137,10 @@
+       DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart,
+               pPrt->PRxQRamEnd, RxQType);
+-      
++
+       DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart,
+               pPrt->PXsQRamEnd, SK_TX_RAM_Q);
+-      
++
+       DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart,
+               pPrt->PXaQRamEnd, SK_TX_RAM_Q);
+@@ -953,26 +1161,37 @@
+  *    nothing
+  */
+ void SkGeInitRamIface(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC)            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC)            /* I/O Context */
+ {
+-      /* release local reset */
+-      SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR);
++      int i;
++      int RamBuffers;
+-      /* configure timeout values */
+-      SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53);
+-      SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53);
+-      SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53);
+-      SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53);
+-      SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53);
+-      SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53);
+-      SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53);
+-      SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53);
+-      SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53);
+-      SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53);
+-      SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53);
+-      SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53);
++      if (CHIP_ID_YUKON_2(pAC)) {
++              RamBuffers = pAC->GIni.GIMacsFound;
++      }
++      else {
++              RamBuffers = 1;
++      }
++      
++      for (i = 0; i < RamBuffers; i++) {
++              /* release local reset */
++              SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_CTRL), (SK_U8)RI_RST_CLR);
++              /* configure timeout values */
++              SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_R1), SK_RI_TO_53);
++              SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XA1), SK_RI_TO_53);
++              SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XS1), SK_RI_TO_53);
++              SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_R1), SK_RI_TO_53);
++              SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XA1), SK_RI_TO_53);
++              SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XS1), SK_RI_TO_53);
++              SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_R2), SK_RI_TO_53);
++              SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XA2), SK_RI_TO_53);
++              SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XS2), SK_RI_TO_53);
++              SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_R2), SK_RI_TO_53);
++              SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XA2), SK_RI_TO_53);
++              SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
++      }
+ }     /* SkGeInitRamIface */
+@@ -987,8 +1206,8 @@
+  *    nothing
+  */
+ static void SkGeInitBmu(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+@@ -999,29 +1218,63 @@
+       RxWm = SK_BMU_RX_WM;
+       TxWm = SK_BMU_TX_WM;
+-      
+-      if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) {
+-              /* for better performance */
+-              RxWm /= 2;
+-              TxWm /= 2;
+-      }
+-      /* Rx Queue: Release all local resets and set the watermark */
+-      SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET);
+-      SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm);
++      if (CHIP_ID_YUKON_2(pAC)) {
+-      /*
+-       * Tx Queue: Release all local resets if the queue is used !
+-       *              set watermark
+-       */
+-      if (pPrt->PXSQSize != 0) {
+-              SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET);
+-              SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm);
++              if (pAC->GIni.GIPciBus == SK_PEX_BUS) {
++                      /* for better performance set it to 128 */
++                      RxWm = SK_BMU_RX_WM_PEX;
++              }
++
++              /* Rx Queue: Release all local resets and set the watermark */
++              SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_CLR_RESET);
++              SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_OPER_INIT);
++              SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_FIFO_OP_ON);
++              SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_WM), RxWm);
++
++              /*
++               * Tx Queue: Release all local resets if the queue is used !
++               *              set watermark
++               */
++              if (pPrt->PXSQSize != 0 && HW_SYNC_TX_SUPPORTED(pAC)) {
++                      /* Yukon-EC doesn't have a synchronous Tx queue */
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_CLR_RESET);
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_OPER_INIT);
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_FIFO_OP_ON);
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_WM), TxWm);
++              }
++              
++              if (pPrt->PXAQSize != 0) {
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_CLR_RESET);
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_OPER_INIT);
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_FIFO_OP_ON);
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_WM), TxWm);
++              }
+       }
+-      
+-      if (pPrt->PXAQSize != 0) {
+-              SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET);
+-              SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm);
++      else {
++              if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) {
++                      /* for better performance */
++                      RxWm /= 2;
++                      TxWm /= 2;
++              }
++
++              /* Rx Queue: Release all local resets and set the watermark */
++              SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET);
++              SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm);
++
++              /*
++               * Tx Queue: Release all local resets if the queue is used !
++               *              set watermark
++               */
++              if (pPrt->PXSQSize != 0) {
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET);
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm);
++              }
++
++              if (pPrt->PXAQSize != 0) {
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET);
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm);
++              }
+       }
+       /*
+        * Do NOT enable the descriptor poll timers here, because
+@@ -1045,20 +1298,29 @@
+  */
+ static SK_U32 TestStopBit(
+ SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* IO Context */
+-int           QuIoOffs)       /* Queue IO Address Offset */
++SK_IOC        IoC,            /* I/O Context */
++int           QuIoOffs)       /* Queue I/O Address Offset */
+ {
+       SK_U32  QuCsr;  /* CSR contents */
+       SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
+       
+-      if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) {
+-              /* Stop Descriptor overridden by start command */
+-              SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP);
++      if (CHIP_ID_YUKON_2(pAC)) {
++              if ((QuCsr & (BMU_STOP | BMU_IDLE)) == 0) {
++                      /* Stop Descriptor overridden by start command */
++                      SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), BMU_STOP);
+-              SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
++                      SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
++              }
++      }
++      else {
++              if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) {
++                      /* Stop Descriptor overridden by start command */
++                      SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP);
++
++                      SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
++              }
+       }
+-      
+       return(QuCsr);
+ }     /* TestStopBit */
+@@ -1142,56 +1404,82 @@
+  *      SWITCH_PORT.
+  */
+ void SkGeStopPort(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* I/O context */
+-int           Port,   /* port to stop (MAC_1 + n) */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
++int           Port,   /* Port to stop (MAC_1 + n) */
+ int           Dir,    /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */
+ int           RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */
+ {
+-#ifndef SK_DIAG
+-      SK_EVPARA Para;
+-#endif /* !SK_DIAG */
+       SK_GEPORT *pPrt;
+-      SK_U32  DWord;
++      SK_U32  RxCsr;
+       SK_U32  XsCsr;
+       SK_U32  XaCsr;
+       SK_U64  ToutStart;
++      SK_U32  CsrStart;
++      SK_U32  CsrStop;
++      SK_U32  CsrIdle;
++      SK_U32  CsrTest;
++      SK_U8   rsl;    /* FIFO read shadow level */
++      SK_U8   rl;             /* FIFO read level */
+       int             i;
+       int             ToutCnt;
+       pPrt = &pAC->GIni.GP[Port];
++      /* set the proper values of Q_CSR register layout depending on the chip */
++      if (CHIP_ID_YUKON_2(pAC)) {
++              CsrStart = BMU_START;
++              CsrStop = BMU_STOP;
++              CsrIdle = BMU_IDLE;
++              CsrTest = BMU_IDLE;
++      }
++      else {
++              CsrStart = CSR_START;
++              CsrStop = CSR_STOP;
++              CsrIdle = CSR_SV_IDLE;
++              CsrTest = CSR_SV_IDLE | CSR_STOP;
++      }
++
+       if ((Dir & SK_STOP_TX) != 0) {
+-              /* disable receiver and transmitter */
+-              SkMacRxTxDisable(pAC, IoC, Port);
+-              
++
++              if (!pAC->GIni.GIAsfEnabled) {
++                      /* disable receiver and transmitter */
++                      SkMacRxTxDisable(pAC, IoC, Port);
++              }
++
+               /* stop both transmit queues */
++              SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CsrStop);
++              SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CsrStop);
+               /*
+                * If the BMU is in the reset state CSR_STOP will terminate
+                * immediately.
+                */
+-              SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP);
+-              SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP);
+               ToutStart = SkOsGetTime(pAC);
+               ToutCnt = 0;
+               do {
+-                      /*
+-                       * Clear packet arbiter timeout to make sure
+-                       * this loop will terminate.
+-                       */
+-                      SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
+-                              PA_CLR_TO_TX1 : PA_CLR_TO_TX2));
+-
+-                      /*
+-                       * If the transfer stucks at the MAC the STOP command will not
+-                       * terminate if we don't flush the XMAC's transmit FIFO !
+-                       */
+-                      SkMacFlushTxFifo(pAC, IoC, Port);
++#ifdef GENESIS
++                      if (pAC->GIni.GIGenesis) {
++                              /* clear Tx packet arbiter timeout IRQ */
++                              SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
++                                      PA_CLR_TO_TX1 : PA_CLR_TO_TX2));
++                              /*
++                               * If the transfer stucks at the XMAC the STOP command will not
++                               * terminate if we don't flush the XMAC's transmit FIFO !
++                               */
++                              SkMacFlushTxFifo(pAC, IoC, Port);
++                      }
++#endif /* GENESIS */
+-                      XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
+                       XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);
++                      if (HW_SYNC_TX_SUPPORTED(pAC)) {
++                              XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
++                      }
++                      else {
++                              XsCsr = XaCsr;
++                      }
++
+                       if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) {
+                               /*
+                                * Timeout of 1/18 second reached.
+@@ -1199,67 +1487,111 @@
+                                */
+                               ToutCnt++;
+                               if (ToutCnt > 1) {
+-                                      /* Might be a problem when the driver event handler
+-                                       * calls StopPort again. XXX.
++                                      /*
++                                       * If BMU stop doesn't terminate, we assume that
++                                       * we have a stable state and can reset the BMU,
++                                       * the Prefetch Unit, and RAM buffer now.
+                                        */
+-
+-                                      /* Fatal Error, Loop aborted */
+-                                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018,
+-                                              SKERR_HWI_E018MSG);
+-#ifndef SK_DIAG
+-                                      Para.Para64 = Port;
+-                                      SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+-#endif /* !SK_DIAG */
+-                                      return;
++                                      break;                  /* ===> leave do/while loop here */
+                               }
+                               /*
+-                               * Cache incoherency workaround: Assume a start command
++                               * Cache incoherency workaround: assume a start command
+                                * has been lost while sending the frame.
+                                */
+                               ToutStart = SkOsGetTime(pAC);
+-                              if ((XsCsr & CSR_STOP) != 0) {
+-                                      SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START);
++                              if ((XsCsr & CsrStop) != 0) {
++                                      SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CsrStart);
+                               }
+-                              if ((XaCsr & CSR_STOP) != 0) {
+-                                      SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START);
++
++                              if ((XaCsr & CsrStop) != 0) {
++                                      SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CsrStart);
+                               }
+-                      }
++                              /*
++                               * After the previous operations the X(s|a)Csr does no
++                               * longer contain the proper values
++                               */
++                              XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);
++
++                              if (HW_SYNC_TX_SUPPORTED(pAC)) {
++                                      XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
++                              }
++                              else {
++                                      XsCsr = XaCsr;
++                              }
++                      }
+                       /*
+                        * Because of the ASIC problem report entry from 21.08.1998 it is
+                        * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
++                       * (valid for GENESIS only)
+                        */
+-              } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE ||
+-                               (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
++              } while (((XsCsr & CsrTest) != CsrIdle ||
++                                (XaCsr & CsrTest) != CsrIdle));
++
++              if (pAC->GIni.GIAsfEnabled) {
+-              /* Reset the MAC depending on the RstMode */
+-              if (RstMode == SK_SOFT_RST) {
+-                      SkMacSoftRst(pAC, IoC, Port);
++                      pPrt->PState = (RstMode == SK_SOFT_RST) ? SK_PRT_STOP :
++                              SK_PRT_RESET;
+               }
+               else {
+-                      SkMacHardRst(pAC, IoC, Port);
++                      /* Reset the MAC depending on the RstMode */
++                      if (RstMode == SK_SOFT_RST) {
++
++                              SkMacSoftRst(pAC, IoC, Port);
++                      }
++                      else {
++                              if (HW_FEATURE(pAC, HWF_WA_DEV_472) && Port == MAC_1 &&
++                                      pAC->GIni.GP[MAC_2].PState == SK_PRT_RUN) {
++
++                                      pAC->GIni.GP[MAC_1].PState = SK_PRT_RESET;
++
++                                      /* set GPHY Control reset */
++                                      SK_OUT8(IoC, MR_ADDR(MAC_1, GPHY_CTRL), (SK_U8)GPC_RST_SET);
++                              }
++                              else {
++
++                                      SkMacHardRst(pAC, IoC, Port);
++                              }
++                      }
+               }
+-              
+-              /* Disable Force Sync bit and Enable Alloc bit */
++
++              /* disable Force Sync bit and Enable Alloc bit */
+               SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
+                       TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
+-              
++
+               /* Stop Interval Timer and Limit Counter of Tx Arbiter */
+               SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L);
+               SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L);
+               /* Perform a local reset of the port's Tx path */
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      /* Reset the PCI FIFO of the async Tx queue */
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR),
++                              BMU_RST_SET | BMU_FIFO_RST);
++
++                      /* Reset the PCI FIFO of the sync Tx queue */
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR),
++                              BMU_RST_SET | BMU_FIFO_RST);
++
++                      /* Reset the Tx prefetch units */
++                      SK_OUT32(IoC, Y2_PREF_Q_ADDR(pPrt->PXaQOff, PREF_UNIT_CTRL_REG),
++                              PREF_UNIT_RST_SET);
++                      SK_OUT32(IoC, Y2_PREF_Q_ADDR(pPrt->PXsQOff, PREF_UNIT_CTRL_REG),
++                              PREF_UNIT_RST_SET);
++              }
++              else {
++                      /* Reset the PCI FIFO of the async Tx queue */
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET);
++                      /* Reset the PCI FIFO of the sync Tx queue */
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET);
++              }
+-              /* Reset the PCI FIFO of the async Tx queue */
+-              SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET);
+-              /* Reset the PCI FIFO of the sync Tx queue */
+-              SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET);
+               /* Reset the RAM Buffer async Tx queue */
+               SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET);
+               /* Reset the RAM Buffer sync Tx queue */
+               SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET);
+-              
++
+               /* Reset Tx MAC FIFO */
+ #ifdef GENESIS
+               if (pAC->GIni.GIGenesis) {
+@@ -1271,71 +1603,116 @@
+                       SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS);
+               }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+               if (pAC->GIni.GIYukon) {
+-                      /* Reset TX MAC FIFO */
+-                      SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
++                      /* do the reset only if ASF is not enabled */
++                      if (!pAC->GIni.GIAsfEnabled) {
++                              /* Reset Tx MAC FIFO */
++                              SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
++                      }
++
++                      /* set Pause Off */
++                      SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_PAUSE_OFF);
+               }
+ #endif /* YUKON */
+       }
+       if ((Dir & SK_STOP_RX) != 0) {
+-              /*
+-               * The RX Stop Command will not terminate if no buffers
+-               * are queued in the RxD ring. But it will always reach
+-               * the Idle state. Therefore we can use this feature to
+-               * stop the transfer of received packets.
+-               */
+-              /* stop the port's receive queue */
+-              SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP);
+-              
+-              i = 100;
+-              do {
++
++              if (CHIP_ID_YUKON_2(pAC)) {
+                       /*
+-                       * Clear packet arbiter timeout to make sure
+-                       * this loop will terminate
++                       * The RX Stop command will not work for Yukon-2 if the BMU does not
++                       * reach the end of packet and since we can't make sure that we have
++                       * incoming data, we must reset the BMU while it is not during a DMA
++                       * transfer. Since it is possible that the RX path is still active,
++                       * the RX RAM buffer will be stopped first, so any possible incoming
++                       * data will not trigger a DMA. After the RAM buffer is stopped, the
++                       * BMU is polled until any DMA in progress is ended and only then it
++                       * will be reset.
+                        */
+-                      SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
+-                              PA_CLR_TO_RX1 : PA_CLR_TO_RX2));
+-                      DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff);
++                      /* disable the RAM Buffer receive queue */
++                      SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_DIS_OP_MD);
+-                      /* timeout if i==0 (bug fix for #10748) */
+-                      if (--i == 0) {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024,
+-                                      SKERR_HWI_E024MSG);
+-                              break;
++                      i = 0xffff;
++                      while (--i) {
++                              SK_IN8(IoC, RB_ADDR(pPrt->PRxQOff, Q_RSL), &rsl);
++                              SK_IN8(IoC, RB_ADDR(pPrt->PRxQOff, Q_RL), &rl);
++
++                              if (rsl == rl) {
++                                      break;
++                              }
+                       }
++
+                       /*
+-                       * because of the ASIC problem report entry from 21.08.98
+-                       * it is required to wait until CSR_STOP is reset and
+-                       * CSR_SV_IDLE is set.
++                       * If the Rx side is blocked, the above loop cannot terminate.
++                       * But, if there was any traffic it should be terminated, now.
++                       * However, stop the Rx BMU and the Prefetch Unit !
+                        */
+-              } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR),
++                              BMU_RST_SET | BMU_FIFO_RST);
++                      /* reset the Rx prefetch unit */
++                      SK_OUT32(IoC, Y2_PREF_Q_ADDR(pPrt->PRxQOff, PREF_UNIT_CTRL_REG),
++                              PREF_UNIT_RST_SET);
++              }
++              else {
++                      /*
++                       * The RX Stop Command will not terminate if no buffers
++                       * are queued in the RxD ring. But it will always reach
++                       * the Idle state. Therefore we can use this feature to
++                       * stop the transfer of received packets.
++                       */
++                      /* stop the port's receive queue */
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CsrStop);
+-              /* The path data transfer activity is fully stopped now */
++                      i = 100;
++                      do {
++#ifdef GENESIS
++                              if (pAC->GIni.GIGenesis) {
++                                      /* clear Rx packet arbiter timeout IRQ */
++                                      SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
++                                              PA_CLR_TO_RX1 : PA_CLR_TO_RX2));
++                              }
++#endif /* GENESIS */
++
++                              RxCsr = TestStopBit(pAC, IoC, pPrt->PRxQOff);
++
++                              /* timeout if i==0 (bug fix for #10748) */
++                              if (--i == 0) {
++                                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024,
++                                              SKERR_HWI_E024MSG);
++                                      break;
++                              }
++                      /*
++                       * Because of the ASIC problem report entry from 21.08.1998 it is
++                       * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
++                       * (valid for GENESIS only)
++                       */
++                      } while ((RxCsr & CsrTest) != CsrIdle);
++                      /* The path data transfer activity is fully stopped now */
+-              /* Perform a local reset of the port's Rx path */
++                      /* Perform a local reset of the port's Rx path */
++                      /* Reset the PCI FIFO of the Rx queue */
++                      SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET);
++              }
+-               /*     Reset the PCI FIFO of the Rx queue */
+-              SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET);
+               /* Reset the RAM Buffer receive queue */
+               SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET);
+               /* Reset Rx MAC FIFO */
+ #ifdef GENESIS
+               if (pAC->GIni.GIGenesis) {
+-                      
++
+                       SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET);
+                       /* switch Rx LED off, stop the LED counter */
+                       SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS);
+               }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+-              if (pAC->GIni.GIYukon) {
++              if (pAC->GIni.GIYukon && !pAC->GIni.GIAsfEnabled) {
+                       /* Reset Rx MAC FIFO */
+                       SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
+               }
+@@ -1355,8 +1732,8 @@
+  *    nothing
+  */
+ static void SkGeInit0(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC)            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC)            /* I/O Context */
+ {
+       int i;
+       SK_GEPORT *pPrt;
+@@ -1365,6 +1742,7 @@
+               pPrt = &pAC->GIni.GP[i];
+               pPrt->PState = SK_PRT_RESET;
++              pPrt->PPortUsage = SK_RED_LINK;
+               pPrt->PRxQOff = QOffTab[i].RxQOff;
+               pPrt->PXsQOff = QOffTab[i].XsQOff;
+               pPrt->PXaQOff = QOffTab[i].XaQOff;
+@@ -1393,24 +1771,30 @@
+               pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN;
+               pPrt->PAutoNegFail = SK_FALSE;
+               pPrt->PHWLinkUp = SK_FALSE;
+-              pPrt->PLinkBroken = SK_TRUE; /* See WA code */
++              pPrt->PLinkBroken = SK_TRUE;    /* See WA code */
+               pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
+               pPrt->PMacColThres = TX_COL_DEF;
+               pPrt->PMacJamLen = TX_JAM_LEN_DEF;
+               pPrt->PMacJamIpgVal     = TX_JAM_IPG_DEF;
+               pPrt->PMacJamIpgData = TX_IPG_JAM_DEF;
++              pPrt->PMacBackOffLim = TX_BOF_LIM_DEF;
++              pPrt->PMacDataBlind = DATA_BLIND_DEF;
+               pPrt->PMacIpgData = IPG_DATA_DEF;
+               pPrt->PMacLimit4 = SK_FALSE;
+       }
+-      pAC->GIni.GIPortUsage = SK_RED_LINK;
+       pAC->GIni.GILedBlinkCtrl = (SK_U16)OemConfig.Value;
+-      pAC->GIni.GIValIrqMask = IS_ALL_MSK;
++      pAC->GIni.GIChipCap = 0;
++
++      for (i = 0; i < 4; i++) {
++              pAC->GIni.HwF.Features[i]= 0x00000000;
++              pAC->GIni.HwF.OnMask[i]  = 0x00000000;
++              pAC->GIni.HwF.OffMask[i] = 0x00000000;
++      }
+ }     /* SkGeInit0*/
+ #ifdef SK_PCI_RESET
+-
+ /******************************************************************************
+  *
+  *    SkGePciReset() - Reset PCI interface
+@@ -1426,8 +1810,8 @@
+  *    1:      Power state could not be changed to 3.
+  */
+ static int SkGePciReset(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC)            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC)            /* I/O Context */
+ {
+       int             i;
+       SK_U16  PmCtlSts;
+@@ -1450,7 +1834,7 @@
+       /* We know the RAM Interface Arbiter is enabled. */
+       SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D3);
+       SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);
+-      
++
+       if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D3) {
+               return(1);
+       }
+@@ -1460,7 +1844,7 @@
+       /* Check for D0 state. */
+       SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);
+-      
++
+       if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D0) {
+               return(1);
+       }
+@@ -1469,11 +1853,24 @@
+       SkPciReadCfgWord(pAC, PCI_COMMAND, &PciCmd);
+       SkPciReadCfgByte(pAC, PCI_CACHE_LSZ, &Cls);
+       SkPciReadCfgDWord(pAC, PCI_BASE_1ST, &Bp1);
+-      SkPciReadCfgDWord(pAC, PCI_BASE_2ND, &Bp2);
++
++      /*
++       * Compute the location in PCI config space of BAR2
++       * relativ to the location of BAR1
++       */
++      if ((Bp1 & PCI_MEM_TYP_MSK) == PCI_MEM64BIT) {
++              /* BAR1 is 64 bits wide */
++              i = 8;
++      }
++      else {
++              i = 4;
++      }
++
++      SkPciReadCfgDWord(pAC, PCI_BASE_1ST + i, &Bp2);
+       SkPciReadCfgByte(pAC, PCI_LAT_TIM, &Lat);
+-      
+-      if (PciCmd != 0 || Cls != (SK_U8)0 || Lat != (SK_U8)0 ||
+-              (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1) {
++
++      if (PciCmd != 0 || Cls != 0 || (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1 ||
++              Lat != 0) {
+               return(1);
+       }
+@@ -1484,9 +1881,80 @@
+       return(0);
+ }     /* SkGePciReset */
+-
+ #endif /* SK_PCI_RESET */
++
++/******************************************************************************
++ *
++ *    SkGeSetUpSupFeatures() - Collect Feature List for HW_FEATURE Macro
++ *
++ * Description:
++ *    This function collects the available features and required
++ *    deviation services of the Adapter and provides these
++ *    information in the GIHwF struct. This information is used as
++ *    default value and may be overritten by the driver using the
++ *    SET_HW_FEATURE_MASK() macro in its Init0 phase.
++ *
++ * Notice:
++ *    Using the On and Off mask: Never switch on the same bit in both
++ *    masks simultaneously. However, if doing the Off mask will win.
++ *
++ * Returns:
++ *    nothing
++ */
++static void SkGeSetUpSupFeatures(
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC)            /* I/O Context */
++{
++      int i;
++
++      switch (pAC->GIni.GIChipId) {
++      case CHIP_ID_YUKON_EC:
++              if (pAC->GIni.GIChipRev == CHIP_REV_YU_EC_A1) {
++                      /* A0/A1 */
++                      pAC->GIni.HwF.Features[HW_DEV_LIST] =
++                              HWF_WA_DEV_42  | HWF_WA_DEV_46 | HWF_WA_DEV_43_418 |
++                              HWF_WA_DEV_420 | HWF_WA_DEV_423 |
++                              HWF_WA_DEV_424 | HWF_WA_DEV_425 | HWF_WA_DEV_427 |
++                              HWF_WA_DEV_428 | HWF_WA_DEV_483 | HWF_WA_DEV_4109;
++              }
++              else {
++                      /* A2/A3 */
++                      pAC->GIni.HwF.Features[HW_DEV_LIST] =
++                              HWF_WA_DEV_424 | HWF_WA_DEV_425 | HWF_WA_DEV_427 |
++                              HWF_WA_DEV_428 | HWF_WA_DEV_483 | HWF_WA_DEV_4109;
++              }
++              break;
++      case CHIP_ID_YUKON_FE:
++              pAC->GIni.HwF.Features[HW_DEV_LIST] = HWF_WA_DEV_427 | HWF_WA_DEV_4109;
++              break;
++      case CHIP_ID_YUKON_XL:
++              /* still needed for Diag */
++              if (pAC->GIni.GIChipRev == 0) {
++                      pAC->GIni.HwF.Features[HW_DEV_LIST] =
++                              HWF_WA_DEV_427 | HWF_WA_DEV_463 | HWF_WA_DEV_472 |
++                              HWF_WA_DEV_479 | HWF_WA_DEV_483 | HWF_WA_DEV_4115;
++              }
++              else if (pAC->GIni.GIChipRev == 1) {
++                      pAC->GIni.HwF.Features[HW_DEV_LIST] =
++                              HWF_WA_DEV_427 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 |
++                              HWF_WA_DEV_4115;
++              }
++              else {
++                      pAC->GIni.HwF.Features[HW_DEV_LIST] =
++                              HWF_WA_DEV_427 | HWF_WA_DEV_483 | HWF_WA_DEV_4109;
++              }
++              break;
++      }
++
++      for (i = 0; i < 4; i++) {
++              pAC->GIni.HwF.Features[i] =
++                      (pAC->GIni.HwF.Features[i] | pAC->GIni.HwF.OnMask[i]) &
++                              ~pAC->GIni.HwF.OffMask[i];
++      }
++}     /* SkGeSetUpSupFeatures */
++
++
+ /******************************************************************************
+  *
+  *    SkGeInit1() - Level 1 Initialization
+@@ -1509,73 +1977,216 @@
+  *    6:      HW self test failed
+  */
+ static int SkGeInit1(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC)            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC)            /* I/O Context */
+ {
+       SK_U8   Byte;
+       SK_U16  Word;
+-      SK_U16  CtrlStat;
++      SK_U32  CtrlStat;
++      SK_U32  VauxAvail;
+       SK_U32  DWord;
++      SK_U32  PowerDownBit;
++      SK_GEPORT *pPrt;
+       int     RetVal;
+       int     i;
+       RetVal = 0;
+-      /* save CLK_RUN bits (YUKON-Lite) */
+-      SK_IN16(IoC, B0_CTST, &CtrlStat);
++      /* save CLK_RUN & ASF_ENABLE bits (YUKON-Lite, YUKON-EC) */
++      SK_IN32(IoC, B0_CTST, &CtrlStat);
+ #ifdef SK_PCI_RESET
+       (void)SkGePciReset(pAC, IoC);
+ #endif /* SK_PCI_RESET */
+-      /* do the SW-reset */
+-      SK_OUT8(IoC, B0_CTST, CS_RST_SET);
+-
+       /* release the SW-reset */
++      /* Important: SW-reset has to be cleared here, to ensure
++       * the CHIP_ID can be read IO-mapped based, too -
++       * remember the RAP register can only be written if
++       * SW-reset is cleared.
++       */
+       SK_OUT8(IoC, B0_CTST, CS_RST_CLR);
++      /* read Chip Identification Number */
++      SK_IN8(IoC, B2_CHIP_ID, &Byte);
++      pAC->GIni.GIChipId = Byte;
++
++      pAC->GIni.GIAsfEnabled = SK_FALSE;
++
++      /* ASF support only for Yukon-2 */
++      if ((pAC->GIni.GIChipId >= CHIP_ID_YUKON_XL) &&
++              (pAC->GIni.GIChipId <= CHIP_ID_YUKON_EC)) {
++#ifdef SK_ASF
++              if ((CtrlStat & Y2_ASF_ENABLE) != 0) {
++                      /* do the SW-reset only if ASF is not enabled */
++                      pAC->GIni.GIAsfEnabled = SK_TRUE;
++              }
++#else /* !SK_ASF */
++
++              SK_IN8(IoC, B28_Y2_ASF_STAT_CMD, &Byte);
++
++              pAC->GIni.GIAsfRunning = Byte & Y2_ASF_RUNNING;
++
++              /* put ASF system in reset state */
++              SK_OUT8(IoC, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
++
++              /* disable ASF Unit */
++              SK_OUT16(IoC, B0_CTST, Y2_ASF_DISABLE);
++#endif /* !SK_ASF */
++      }
++
++      if (!pAC->GIni.GIAsfEnabled) {
++              /* Yukon-2: required for Diag and Power Management */
++              /* set the SW-reset */
++              SK_OUT8(IoC, B0_CTST, CS_RST_SET);
++
++              /* release the SW-reset */
++              SK_OUT8(IoC, B0_CTST, CS_RST_CLR);
++      }
++
+       /* reset all error bits in the PCI STATUS register */
+       /*
+        * Note: PCI Cfg cycles cannot be used, because they are not
+        *               available on some platforms after 'boot time'.
+        */
+-      SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
+-      
++      SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word);
++
+       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+-      SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
+-      SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
++
++      SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), Word | (SK_U16)PCI_ERRBITS);
+       /* release Master Reset */
+       SK_OUT8(IoC, B0_CTST, CS_MRST_CLR);
+ #ifdef CLK_RUN
+       CtrlStat |= CS_CLK_RUN_ENA;
+-#endif /* CLK_RUN */
+       /* restore CLK_RUN bits */
+       SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat &
+               (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA)));
++#endif /* CLK_RUN */
++
++      if ((pAC->GIni.GIChipId >= CHIP_ID_YUKON_XL) &&
++              (pAC->GIni.GIChipId <= CHIP_ID_YUKON_FE)) {
++
++              pAC->GIni.GIYukon2 = SK_TRUE;
++              pAC->GIni.GIValIrqMask = Y2_IS_ALL_MSK;
++              pAC->GIni.GIValHwIrqMask = Y2_HWE_ALL_MSK;
++
++              VauxAvail = Y2_VAUX_AVAIL;
++
++              SK_IN32(IoC, PCI_C(pAC, PCI_OUR_STATUS), &DWord);
++
++              if ((DWord & PCI_OS_PCI_X) != 0) {
++                      /* this is a PCI / PCI-X bus */
++                      if ((DWord & PCI_OS_PCIX) != 0) {
++                              /* this is a PCI-X bus */
++                              pAC->GIni.GIPciBus = SK_PCIX_BUS;
++
++                              /* PCI-X is always 64-bit wide */
++                              pAC->GIni.GIPciSlot64 = SK_TRUE;
++
++                              pAC->GIni.GIPciMode = (SK_U8)(PCI_OS_SPEED(DWord));
++                      }
++                      else {
++                              /* this is a conventional PCI bus */
++                              pAC->GIni.GIPciBus = SK_PCI_BUS;
++
++                              SK_IN16(IoC, PCI_C(pAC, PCI_OUR_REG_2), &Word);
++
++                              /* check if 64-bit width is used */
++                              pAC->GIni.GIPciSlot64 = (SK_BOOL)
++                                      (((DWord & PCI_OS_PCI64B) != 0) &&
++                                      ((Word & PCI_USEDATA64) != 0));
++
++                              /* check if 66 MHz PCI Clock is active */
++                              pAC->GIni.GIPciClock66 = (SK_BOOL)((DWord & PCI_OS_PCI66M) != 0);
++                      }
++              }
++              else {
++                      /* this is a PEX bus */
++                      pAC->GIni.GIPciBus = SK_PEX_BUS;
++
++                      /* clear any PEX errors */
++                      SK_OUT32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), 0xffffffffUL);
++
++                      SK_IN16(IoC, PCI_C(pAC, PEX_LNK_STAT), &Word);
++
++                      pAC->GIni.GIPexWidth = (SK_U8)((Word & PEX_LS_LINK_WI_MSK) >> 4);
++              }
++              /*
++               * Yukon-2 chips family has a different way of providing
++               * the number of MACs available
++               */
++              pAC->GIni.GIMacsFound = 1;
++
++              SK_IN8(IoC, B2_Y2_HW_RES, &Byte);
++
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      /*
++                       * OEM config value is overwritten and should not
++                       * be used for Yukon-2
++                       */
++                      pAC->GIni.GILedBlinkCtrl |= SK_ACT_LED_BLINK;
++
++                      if (CFG_LED_MODE(Byte) == CFG_LED_DUAL_ACT_LNK) {
++
++                              pAC->GIni.GILedBlinkCtrl |= SK_DUAL_LED_ACT_LNK;
++                      }
++              }
++
++              if ((Byte & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
++
++                      SK_IN8(IoC, B2_Y2_CLK_GATE, &Byte);
++
++                      if (!(Byte & Y2_STATUS_LNK2_INAC)) {
++                              /* Link 2 activ */
++                              pAC->GIni.GIMacsFound++;
++                      }
++              }
++
++#ifdef VCPU
++              if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) {
++                      /* temporary WA for reported number of links */
++                      pAC->GIni.GIMacsFound = 2;
++              }
++#endif /* VCPU */
++
++              /* read Chip Revision */
++              SK_IN8(IoC, B2_MAC_CFG, &Byte);
++
++              pAC->GIni.GIChipCap = Byte & 0x0f;
++      }
++      else {
++              pAC->GIni.GIYukon2 = SK_FALSE;
++              pAC->GIni.GIValIrqMask = IS_ALL_MSK;
++              pAC->GIni.GIValHwIrqMask = 0;   /* not activated */
++
++              VauxAvail = CS_VAUX_AVAIL;
++
++              /* read number of MACs and Chip Revision */
++              SK_IN8(IoC, B2_MAC_CFG, &Byte);
++
++              pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2;
++      }
+-      /* read Chip Identification Number */
+-      SK_IN8(IoC, B2_CHIP_ID, &Byte);
+-      pAC->GIni.GIChipId = Byte;
+-      
+-      /* read number of MACs */
+-      SK_IN8(IoC, B2_MAC_CFG, &Byte);
+-      pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2;
+-      
+       /* get Chip Revision Number */
+       pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4);
+-      /* get diff. PCI parameters */
+-      SK_IN16(IoC, B0_CTST, &CtrlStat);
+-      
++#ifndef SK_DIAG
++      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL && pAC->GIni.GIChipRev == 0) {
++              /* Yukon-2 Chip Rev. A0 */
++              return(6);
++      }
++#endif /* !SK_DIAG */
++
+       /* read the adapters RAM size */
+       SK_IN8(IoC, B2_E_0, &Byte);
+-      
++
+       pAC->GIni.GIGenesis = SK_FALSE;
+       pAC->GIni.GIYukon = SK_FALSE;
+       pAC->GIni.GIYukonLite = SK_FALSE;
++      pAC->GIni.GIVauxAvail = SK_FALSE;
+ #ifdef GENESIS
+       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+@@ -1591,57 +2202,77 @@
+                       pAC->GIni.GIRamSize = (int)Byte * 512;
+                       pAC->GIni.GIRamOffs = 0;
+               }
+-              /* all GE adapters work with 53.125 MHz host clock */
++              /* all GENESIS adapters work with 53.125 MHz host clock */
+               pAC->GIni.GIHstClkFact = SK_FACT_53;
+-              
++
+               /* set Descr. Poll Timer Init Value to 250 ms */
+               pAC->GIni.GIPollTimerVal =
+                       SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100;
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) {
+-              
++
+               pAC->GIni.GIYukon = SK_TRUE;
+-              
++
+               pAC->GIni.GIRamSize = (Byte == (SK_U8)0) ? 128 : (int)Byte * 4;
+-              
++
+               pAC->GIni.GIRamOffs = 0;
+-              
+-              /* WA for chip Rev. A */
++
++              /* WA for Yukon chip Rev. A */
+               pAC->GIni.GIWolOffs = (pAC->GIni.GIChipId == CHIP_ID_YUKON &&
+                       pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0;
+-              
++
+               /* get PM Capabilities of PCI config space */
+-              SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word);
++              SK_IN16(IoC, PCI_C(pAC, PCI_PM_CAP_REG), &Word);
+               /* check if VAUX is available */
+-              if (((CtrlStat & CS_VAUX_AVAIL) != 0) &&
++              if (((CtrlStat & VauxAvail) != 0) &&
+                       /* check also if PME from D3cold is set */
+                       ((Word & PCI_PME_D3C_SUP) != 0)) {
+                       /* set entry in GE init struct */
+                       pAC->GIni.GIVauxAvail = SK_TRUE;
+               }
+-              
+-              if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) {
+-                      /* this is Rev. A1 */
+-                      pAC->GIni.GIYukonLite = SK_TRUE;
+-              }
+-              else {
+-                      /* save Flash-Address Register */
+-                      SK_IN32(IoC, B2_FAR, &DWord);
+-                      /* test Flash-Address Register */
+-                      SK_OUT8(IoC, B2_FAR + 3, 0xff);
+-                      SK_IN8(IoC, B2_FAR + 3, &Byte);
++              if (!CHIP_ID_YUKON_2(pAC)) {
+-                      if (Byte != 0) {
+-                              /* this is Rev. A0 */
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) {
++                              /* this is Rev. A1 */
+                               pAC->GIni.GIYukonLite = SK_TRUE;
++                      }
++                      else {
++                              /* save Flash-Address Register */
++                              SK_IN32(IoC, B2_FAR, &DWord);
+-                              /* restore Flash-Address Register */
+-                              SK_OUT32(IoC, B2_FAR, DWord);
++                              /* test Flash-Address Register */
++                              SK_OUT8(IoC, B2_FAR + 3, 0xff);
++                              SK_IN8(IoC, B2_FAR + 3, &Byte);
++
++                              if (Byte != 0) {
++                                      /* this is Rev. A0 */
++                                      pAC->GIni.GIYukonLite = SK_TRUE;
++
++                                      /* restore Flash-Address Register */
++                                      SK_OUT32(IoC, B2_FAR, DWord);
++                              }
++                      }
++              }
++              else {
++                      /* Check for CLS = 0 (dev. #4.55) */
++                      if (pAC->GIni.GIPciBus != SK_PEX_BUS) {
++                              /* PCI and PCI-X */
++                              SK_IN8(IoC, PCI_C(pAC, PCI_CACHE_LSZ), &Byte);
++                              if (Byte == 0) {
++                                      /* set CLS to 2 if configured to 0 */
++                                      SK_OUT8(IoC, PCI_C(pAC, PCI_CACHE_LSZ), 2);
++                              }
++                              if (pAC->GIni.GIPciBus == SK_PCIX_BUS) {
++                                      /* set Cache Line Size opt. */
++                                      SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord);
++                                      DWord |= PCI_CLS_OPT;
++                                      SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord);
++                              }
+                       }
+               }
+@@ -1649,70 +2280,147 @@
+               SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA |
+                       PC_VAUX_OFF | PC_VCC_ON));
+-              /* read the Interrupt source */
+-              SK_IN32(IoC, B0_ISRC, &DWord);
+-              
+-              if ((DWord & IS_HW_ERR) != 0) {
+-                      /* read the HW Error Interrupt source */
+-                      SK_IN32(IoC, B0_HWE_ISRC, &DWord);
+-                      
+-                      if ((DWord & IS_IRQ_SENSOR) != 0) {
+-                              /* disable HW Error IRQ */
+-                              pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
++              Byte = 0;
++
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      /* PEX adapters work with different host clock */
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) {
++                              /* Yukon-EC works with 125 MHz host clock */
++                              pAC->GIni.GIHstClkFact = SK_FACT_125;
++                      }
++                      else if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
++                              /* Yukon-FE works with 100 MHz host clock */
++                              pAC->GIni.GIHstClkFact = SK_FACT_100;
++                      }
++                      else {          /* CHIP_ID_YUKON_XL */
++                              /* all Yukon-2 adapters work with 156 MHz host clock */
++                              pAC->GIni.GIHstClkFact = 2 * SK_FACT_78;
++
++                              if (pAC->GIni.GIChipRev > 1) {
++                                      /* enable bits are inverted */
++                                      Byte = (SK_U8)(Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
++                                              Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
++                                              Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
++                              }
+                       }
++
++                      pAC->GIni.GIPollTimerVal =
++                              SK_DPOLL_DEF_Y2 * (SK_U32)pAC->GIni.GIHstClkFact / 100;
++
++                      /* set power down bit */
++                      PowerDownBit = PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD;
++
++                      /* disable Core Clock Division, set Clock Select to 0 (Yukon-2) */
++                      SK_OUT32(IoC, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS);
++
++                      /* enable PCI & Core Clock, enable clock gating for both Links */
++                      SK_OUT8(IoC, B2_Y2_CLK_GATE, Byte);
+               }
+-              
+-              for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+-                      /* set GMAC Link Control reset */
+-                      SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET);
++              else {
++                      /* YUKON adapters work with 78 MHz host clock */
++                      pAC->GIni.GIHstClkFact = SK_FACT_78;
++
++                      pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;        /* 215 ms */
++
++                      /* read the Interrupt source */
++                      SK_IN32(IoC, B0_ISRC, &DWord);
++
++                      if ((DWord & IS_HW_ERR) != 0) {
++                              /* read the HW Error Interrupt source */
++                              SK_IN32(IoC, B0_HWE_ISRC, &DWord);
++
++                              if ((DWord & IS_IRQ_SENSOR) != 0) {
++                                      /* disable HW Error IRQ */
++                                      pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
++                              }
++                      }
++                      /* set power down bit */
++                      PowerDownBit = PCI_PHY_COMA;
++              }
++
++              SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord);
++
++              DWord &= ~PowerDownBit;
++
++              if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL && pAC->GIni.GIChipRev > 1) {
++                      /* deassert Low Power for 1st PHY */
++                      DWord |= PCI_Y2_PHY1_COMA;
+-                      /* clear GMAC Link Control reset */
+-                      SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
++                      if (pAC->GIni.GIMacsFound > 1) {
++                              /* deassert Low Power for 2nd PHY */
++                              DWord |= PCI_Y2_PHY2_COMA;
++                      }
++              }
++
++              /* Release PHY from PowerDown/COMA Mode */
++              SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord);
++
++              if (!pAC->GIni.GIAsfEnabled) {
++
++                      for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
++                              /* set GMAC Link Control reset */
++                              SK_OUT8(IoC, MR_ADDR(i, GMAC_LINK_CTRL), (SK_U8)GMLC_RST_SET);
++
++                              /* clear GMAC Link Control reset */
++                              SK_OUT8(IoC, MR_ADDR(i, GMAC_LINK_CTRL), (SK_U8)GMLC_RST_CLR);
++                      }
+               }
+-              /* all YU chips work with 78.125 MHz host clock */
+-              pAC->GIni.GIHstClkFact = SK_FACT_78;
+-              
+-              pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;        /* 215 ms */
+       }
+ #endif /* YUKON */
+-      /* check if 64-bit PCI Slot is present */
+-      pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0);
+-      
+-      /* check if 66 MHz PCI Clock is active */
+-      pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0);
++      SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
++
++      if (!CHIP_ID_YUKON_2(pAC)) {
++              /* this is a conventional PCI bus */
++              pAC->GIni.GIPciBus = SK_PCI_BUS;
++
++              /* check if 64-bit PCI Slot is present */
++              pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0);
++
++              /* check if 66 MHz PCI Clock is active */
++              pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0);
++      }
+       /* read PCI HW Revision Id. */
+-      SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte);
++      SK_IN8(IoC, PCI_C(pAC, PCI_REV_ID), &Byte);
+       pAC->GIni.GIPciHwRev = Byte;
++      /* read connector type */
++      SK_IN8(IoC, B2_CONN_TYP, &pAC->GIni.GIConTyp);
++
+       /* read the PMD type */
+       SK_IN8(IoC, B2_PMD_TYP, &Byte);
+-      pAC->GIni.GICopperType = (SK_U8)(Byte == 'T');
+-      /* read the PHY type */
++      pAC->GIni.GIPmdTyp = Byte;
++
++      pAC->GIni.GICopperType = (SK_BOOL)(Byte == 'T' || Byte == '1' ||
++              (pAC->GIni.GIYukon2 && !(Byte == 'L' || Byte == 'S')));
++
++      /* read the PHY type (Yukon and Genesis) */
+       SK_IN8(IoC, B2_E_1, &Byte);
+       Byte &= 0x0f;   /* the PHY type is stored in the lower nibble */
+       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+-              
++
++              pPrt = &pAC->GIni.GP[i];
++
+ #ifdef GENESIS
+               if (pAC->GIni.GIGenesis) {
+                       switch (Byte) {
+                       case SK_PHY_XMAC:
+-                              pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC;
++                              pPrt->PhyAddr = PHY_ADDR_XMAC;
+                               break;
+                       case SK_PHY_BCOM:
+-                              pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM;
+-                              pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
++                              pPrt->PhyAddr = PHY_ADDR_BCOM;
++                              pPrt->PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
+                                       SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
+                               break;
+ #ifdef OTHER_PHY
+                       case SK_PHY_LONE:
+-                              pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE;
++                              pPrt->PhyAddr = PHY_ADDR_LONE;
+                               break;
+                       case SK_PHY_NAT:
+-                              pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT;
++                              pPrt->PhyAddr = PHY_ADDR_NAT;
+                               break;
+ #endif /* OTHER_PHY */
+                       default:
+@@ -1722,65 +2430,98 @@
+                       }
+               }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+               if (pAC->GIni.GIYukon) {
+-                      
+-                      if (Byte < (SK_U8)SK_PHY_MARV_COPPER) {
++
++                      if ((Byte < (SK_U8)SK_PHY_MARV_COPPER) &&
++                              pAC->GIni.GIPmdTyp != 'L' && pAC->GIni.GIPmdTyp != 'S') {
+                               /* if this field is not initialized */
+                               Byte = (SK_U8)SK_PHY_MARV_COPPER;
+-                              
++
+                               pAC->GIni.GICopperType = SK_TRUE;
+                       }
+-                      
+-                      pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV;
+-                      
++
++                      pPrt->PhyAddr = PHY_ADDR_MARV;
++
+                       if (pAC->GIni.GICopperType) {
+-                              pAC->GIni.GP[i].PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_AUTO |
+-                                      SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS |
+-                                      SK_LSPEED_CAP_1000MBPS);
+-                              
+-                              pAC->GIni.GP[i].PLinkSpeed = (SK_U8)SK_LSPEED_AUTO;
+-                              
+-                              pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
++                              if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE ||
++                                      (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC &&
++                                      pAC->GIni.GIChipCap == 2)) {
++
++                                      pPrt->PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_100MBPS |
++                                              SK_LSPEED_CAP_10MBPS);
++
++                                      pAC->GIni.GIRamSize = 4;
++                              }
++                              else {
++                                      pPrt->PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_1000MBPS |
++                                              SK_LSPEED_CAP_100MBPS | SK_LSPEED_CAP_10MBPS |
++                                              SK_LSPEED_CAP_AUTO);
++                              }
++
++                              pPrt->PLinkSpeed = (SK_U8)SK_LSPEED_AUTO;
++
++                              pPrt->PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
+                                       SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
+                       }
+                       else {
+                               Byte = (SK_U8)SK_PHY_MARV_FIBER;
+                       }
+               }
++
++              /* clear TWSI IRQ */
++              SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
++
+ #endif /* YUKON */
+-              
+-              pAC->GIni.GP[i].PhyType = (int)Byte;
+-              
++
++              pPrt->PhyType = (int)Byte;
++
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+-                      ("PHY type: %d  PHY addr: %04x\n", Byte,
+-                      pAC->GIni.GP[i].PhyAddr));
++                      ("PHY type: %d  PHY addr: %04x\n",
++                      Byte, pPrt->PhyAddr));
+       }
+-      
++
+       /* get MAC Type & set function pointers dependent on */
+ #ifdef GENESIS
+       if (pAC->GIni.GIGenesis) {
+-              
++
+               pAC->GIni.GIMacType = SK_MAC_XMAC;
+               pAC->GIni.GIFunc.pFnMacUpdateStats      = SkXmUpdateStats;
+               pAC->GIni.GIFunc.pFnMacStatistic        = SkXmMacStatistic;
+               pAC->GIni.GIFunc.pFnMacResetCounter     = SkXmResetCounter;
+               pAC->GIni.GIFunc.pFnMacOverflow         = SkXmOverflowStatus;
++#ifdef SK_DIAG
++              pAC->GIni.GIFunc.pFnMacPhyRead          = SkXmPhyRead;
++              pAC->GIni.GIFunc.pFnMacPhyWrite         = SkXmPhyWrite;
++#else /* SK_DIAG */
++              pAC->GIni.GIFunc.pSkGeSirqIsr           = SkGeYuSirqIsr;
++#endif /* !SK_DIAG */
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+-              
++
+               pAC->GIni.GIMacType = SK_MAC_GMAC;
+               pAC->GIni.GIFunc.pFnMacUpdateStats      = SkGmUpdateStats;
+               pAC->GIni.GIFunc.pFnMacStatistic        = SkGmMacStatistic;
+               pAC->GIni.GIFunc.pFnMacResetCounter     = SkGmResetCounter;
+               pAC->GIni.GIFunc.pFnMacOverflow         = SkGmOverflowStatus;
++#ifdef SK_DIAG
++              pAC->GIni.GIFunc.pFnMacPhyRead          = SkGmPhyRead;
++              pAC->GIni.GIFunc.pFnMacPhyWrite         = SkGmPhyWrite;
++#else /* SK_DIAG */
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      pAC->GIni.GIFunc.pSkGeSirqIsr   = SkYuk2SirqIsr;
++              }
++              else {
++                      pAC->GIni.GIFunc.pSkGeSirqIsr   = SkGeYuSirqIsr;
++              }
++#endif /* !SK_DIAG */
+ #ifdef SPECIAL_HANDLING
+               if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
+@@ -1793,7 +2534,9 @@
+ #endif
+       }
+ #endif /* YUKON */
+-      
++
++      SkGeSetUpSupFeatures(pAC, IoC);
++
+       return(RetVal);
+ }     /* SkGeInit1 */
+@@ -1814,9 +2557,12 @@
+  *    nothing
+  */
+ static void SkGeInit2(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC)            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC)            /* I/O Context */
+ {
++#ifdef YUKON
++      SK_U16  Word;
++#endif /* YUKON */
+ #ifdef GENESIS
+       SK_U32  DWord;
+ #endif /* GENESIS */
+@@ -1850,13 +2596,13 @@
+               SkGeInitPktArb(pAC, IoC);
+       }
+ #endif /* GENESIS */
+-      
+-#ifdef YUKON
++
++#ifdef xSK_DIAG
+       if (pAC->GIni.GIYukon) {
+               /* start Time Stamp Timer */
+               SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START);
+       }
+-#endif /* YUKON */
++#endif /* SK_DIAG */
+       /* enable the Tx Arbiters */
+       for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+@@ -1866,8 +2612,34 @@
+       /* enable the RAM Interface Arbiter */
+       SkGeInitRamIface(pAC, IoC);
++#ifdef YUKON
++      if (CHIP_ID_YUKON_2(pAC)) {
++
++              if (pAC->GIni.GIPciBus == SK_PEX_BUS) {
++
++                      SK_IN16(IoC, PCI_C(pAC, PEX_DEV_CTRL), &Word);
++
++                      /* change Max. Read Request Size to 2048 bytes */
++                      Word &= ~PEX_DC_MAX_RRS_MSK;
++                      Word |= PEX_DC_MAX_RD_RQ_SIZE(4);
++
++                      SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
++
++                      SK_OUT16(IoC, PCI_C(pAC, PEX_DEV_CTRL), Word);
++
++                      SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
++              }
++
++              /*
++               * Writing the HW Error Mask Reg. will not generate an IRQ
++               * as long as the B0_IMSK is not set by the driver.
++               */
++              SK_OUT32(IoC, B0_HWE_IMSK, pAC->GIni.GIValHwIrqMask);
++      }
++#endif /* YUKON */
+ }     /* SkGeInit2 */
++
+ /******************************************************************************
+  *
+  *    SkGeInit() - Initialize the GE Adapter with the specified level.
+@@ -1889,7 +2661,7 @@
+  *                            if Number of MACs > SK_MAX_MACS
+  *
+  *                    After returning from Level 0 the adapter
+- *                    may be accessed with IO operations.
++ *                    may be accessed with I/O operations.
+  *
+  *    Level   2:      start the Blink Source Counter
+  *
+@@ -1898,14 +2670,14 @@
+  *    1:      Number of MACs exceeds SK_MAX_MACS      (after level 1)
+  *    2:      Adapter not present or not accessible
+  *    3:      Illegal initialization level
+- *    4:      Initialization Level 1 Call missing
++ *    4:      Initialization level 1 call missing
+  *    5:      Unexpected PHY type detected
+  *    6:      HW self test failed
+  */
+ int   SkGeInit(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
+-int           Level)          /* initialization level */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
++int           Level)          /* Initialization Level */
+ {
+       int             RetVal;         /* return value */
+       SK_U32  DWord;
+@@ -1920,7 +2692,7 @@
+               SkGeInit0(pAC, IoC);
+               pAC->GIni.GILevel = SK_INIT_DATA;
+               break;
+-      
++
+       case SK_INIT_IO:
+               /* Initialization Level 1 */
+               RetVal = SkGeInit1(pAC, IoC);
+@@ -1932,22 +2704,24 @@
+               SK_OUT32(IoC, B2_IRQM_INI, SK_TEST_VAL);
+               SK_IN32(IoC, B2_IRQM_INI, &DWord);
+               SK_OUT32(IoC, B2_IRQM_INI, 0L);
+-              
++
+               if (DWord != SK_TEST_VAL) {
+                       RetVal = 2;
+                       break;
+               }
++#ifdef DEBUG
+               /* check if the number of GIMacsFound matches SK_MAX_MACS */
+               if (pAC->GIni.GIMacsFound > SK_MAX_MACS) {
+                       RetVal = 1;
+                       break;
+               }
++#endif /* DEBUG */
+               /* Level 1 successfully passed */
+               pAC->GIni.GILevel = SK_INIT_IO;
+               break;
+-      
++
+       case SK_INIT_RUN:
+               /* Initialization Level 2 */
+               if (pAC->GIni.GILevel != SK_INIT_IO) {
+@@ -1957,12 +2731,13 @@
+                       RetVal = 4;
+                       break;
+               }
++
+               SkGeInit2(pAC, IoC);
+               /* Level 2 successfully passed */
+               pAC->GIni.GILevel = SK_INIT_RUN;
+               break;
+-      
++
+       default:
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG);
+               RetVal = 3;
+@@ -1985,77 +2760,79 @@
+  *    nothing
+  */
+ void SkGeDeInit(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC)            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC)            /* I/O Context */
+ {
+       int     i;
+       SK_U16  Word;
+-#ifdef SK_PHY_LP_MODE
+-      SK_U8   Byte;
++#ifdef SK_PHY_LP_MODE_DEEP_SLEEP
+       SK_U16  PmCtlSts;
+-#endif /* SK_PHY_LP_MODE */
++#endif
+ #if (!defined(SK_SLIM) && !defined(VCPU))
+       /* ensure I2C is ready */
+       SkI2cWaitIrq(pAC, IoC);
+-#endif        
+-
+-      /* stop all current transfer activity */
+-      for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+-              if (pAC->GIni.GP[i].PState != SK_PRT_STOP &&
+-                      pAC->GIni.GP[i].PState != SK_PRT_RESET) {
+-
+-                      SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST);
+-              }
+-      }
++#endif
+-#ifdef SK_PHY_LP_MODE
+-    /*
++#ifdef SK_PHY_LP_MODE_DEEP_SLEEP
++      /*
+        * for power saving purposes within mobile environments
+-       * we set the PHY to coma mode and switch to D3 power state.
++       * we set the PHY to coma mode.
+        */
+-      if (pAC->GIni.GIYukonLite &&
+-              pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
++#ifdef XXX
++      if (pAC->GIni.GIVauxAvail) {
++              /* switch power to VAUX */
++              SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA |
++                      PC_VAUX_ON | PC_VCC_OFF));
++      }
++#endif /* XXX */
++
++      if (CHIP_ID_YUKON_2(pAC) && /* pAC->GIni.GIMacsFound == 1 && */
++              !pAC->GIni.GIAsfEnabled
++#ifdef XXX
++              || (pAC->GIni.GIYukonLite && pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3)
++#endif /* XXX */
++              ) {
+               /* for all ports switch PHY to coma mode */
+               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+-                      
+-                      SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP);
+-              }
+-              if (pAC->GIni.GIVauxAvail) {
+-                      /* switch power to VAUX */
+-                      Byte = PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF;
+-
+-                      SK_OUT8(IoC, B0_POWER_CTRL, Byte);
++                      (void)SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP);
+               }
+-              
+-              /* switch to D3 state */
+-              SK_IN16(IoC, PCI_C(PCI_PM_CTL_STS), &PmCtlSts);
+-
+-              PmCtlSts |= PCI_PM_STATE_D3;
++      }
++#else /* !SK_PHY_LP_MODE_DEEP_SLEEP */
+-              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
++      if (!pAC->GIni.GIAsfEnabled) {
++              /* stop all current transfer activity */
++              for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
++                      if (pAC->GIni.GP[i].PState != SK_PRT_STOP &&
++                              pAC->GIni.GP[i].PState != SK_PRT_RESET) {
+-              SK_OUT16(IoC, PCI_C(PCI_PM_CTL_STS), PmCtlSts);
++                              SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST);
++                      }
++              }
+       }
+-#endif /* SK_PHY_LP_MODE */
+-      /* Reset all bits in the PCI STATUS register */
++      /* reset all bits in the PCI STATUS register */
+       /*
+        * Note: PCI Cfg cycles cannot be used, because they are not
+        *       available on some platforms after 'boot time'.
+        */
+-      SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
+-      
++      SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word);
++
+       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+-      SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
++
++      SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), Word | (SK_U16)PCI_ERRBITS);
++
+       SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+-      /* do the reset, all LEDs are switched off now */
+-      SK_OUT8(IoC, B0_CTST, CS_RST_SET);
+-      
++      if (!pAC->GIni.GIAsfEnabled) {
++              /* set the SW-reset */
++              SK_OUT8(IoC, B0_CTST, CS_RST_SET);
++      }
++#endif /* !SK_PHY_LP_MODE_DEEP_SLEEP */
++
+       pAC->GIni.GILevel = SK_INIT_DATA;
+ }     /* SkGeDeInit */
+@@ -2089,8 +2866,8 @@
+  *    2:      The port has to be stopped before it can be initialized again.
+  */
+ int SkGeInitPort(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port to configure */
+ {
+       SK_GEPORT *pPrt;
+@@ -2101,8 +2878,8 @@
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG);
+               return(1);
+       }
+-      
+-      if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) {
++
++      if (pPrt->PState >= SK_PRT_INIT) {
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG);
+               return(2);
+       }
+@@ -2119,29 +2896,29 @@
+               SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
+               SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA);
+               /* The Link LED is initialized by RLMT or Diagnostics itself */
+-              
++
+               SkXmInitMac(pAC, IoC, Port);
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+               SkGmInitMac(pAC, IoC, Port);
+       }
+ #endif /* YUKON */
+-      
++
+       /* do NOT initialize the Link Sync Counter */
+       SkGeInitMacFifo(pAC, IoC, Port);
+-      
++
+       SkGeInitRamBufs(pAC, IoC, Port);
+-      
++
+       if (pPrt->PXSQSize != 0) {
+               /* enable Force Sync bit if synchronous queue available */
+               SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC);
+       }
+-      
++
+       SkGeInitBmu(pAC, IoC, Port);
+       /* mark port as initialized */
+@@ -2149,3 +2926,4 @@
+       return(0);
+ }     /* SkGeInitPort */
++
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skgemib.c linux-2.6.9.new/drivers/net/sk98lin/skgemib.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skgemib.c      2004-10-19 05:53:06.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skgemib.c      2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgemib.c
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.11 $
+- * Date:      $Date: 2003/09/15 13:38:12 $
++ * Version:   $Revision: 2.7 $
++ * Date:      $Date: 2004/10/26 12:42:18 $
+  * Purpose:   Private Network Management Interface Management Database
+  *
+  ****************************************************************************/
+@@ -251,6 +251,183 @@
+               0,
+               SK_PNMI_RW, DiagActions, 0},
+ #endif /* SK_DIAG_SUPPORT */
++#ifdef SK_ASF
++    {OID_SKGE_ASF,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_STORE_CONFIG,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_ENA,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_RETRANS,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_RETRANS_INT,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_HB_ENA,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_HB_INT,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_WD_ENA,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_WD_TIME,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_IP_SOURCE,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_MAC_SOURCE,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_IP_DEST,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_MAC_DEST,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_COMMUNITY_NAME,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_RSP_ENA,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_RETRANS_COUNT_MIN,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_RETRANS_COUNT_MAX,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_RETRANS_INT_MIN,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_RETRANS_INT_MAX,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_HB_INT_MIN,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_HB_INT_MAX,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_WD_TIME_MIN,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_WD_TIME_MAX,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_HB_CAP,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_WD_TIMER_RES,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_GUID,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_KEY_OP,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_KEY_ADM,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_KEY_GEN,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_CAP,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_PAR_1,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_OVERALL_OID,
++        0,
++        0,
++        0,
++        SK_PNMI_RW, Asf, 0},
++    {OID_SKGE_ASF_FWVER_OID,
++        0,
++        0,
++        0,
++        SK_PNMI_RO, Asf, 0},
++    {OID_SKGE_ASF_ACPI_OID,
++        0,
++        0,
++        0,
++        SK_PNMI_RO, Asf, 0},
++    {OID_SKGE_ASF_SMBUS_OID,
++        0,
++        0,
++        0,
++        SK_PNMI_RO, Asf, 0},
++#endif /* SK_ASF */
+       {OID_SKGE_MDB_VERSION,
+               1,
+               0,
+@@ -1073,6 +1250,11 @@
+               0,
+               0,
+               SK_PNMI_RO, Vct, 0},
++      {OID_SKGE_VCT_CAPABILITIES,
++              0,
++              0,
++              0,
++              SK_PNMI_RO, Vct, 0},
+       {OID_SKGE_BOARDLEVEL,
+               0,
+               0,
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skgepnmi.c linux-2.6.9.new/drivers/net/sk98lin/skgepnmi.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skgepnmi.c     2004-10-19 05:54:40.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skgepnmi.c     2006-12-07 14:35:03.000000000 +0800
+@@ -1,9 +1,9 @@
+ /*****************************************************************************
+  *
+  * Name:      skgepnmi.c
+- * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.111 $
+- * Date:      $Date: 2003/09/15 13:35:35 $
++ * Project:   Gigabit Ethernet Adapters, PNMI-Module
++ * Version:   $Revision: 2.21 $
++ * Date:      $Date: 2005/05/11 11:50:12 $
+  * Purpose:   Private Network Management Interface
+  *
+  ****************************************************************************/
+@@ -22,11 +22,10 @@
+  *
+  ******************************************************************************/
+-
+-#ifndef _lint
++#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
+-#endif /* !_lint */
++      "@(#) $Id: skgepnmi.c,v 2.21 2005/05/11 11:50:12 tschilli Exp $ (C) Marvell.";
++#endif
+ #include "h/skdrv1st.h"
+ #include "h/sktypes.h"
+@@ -38,12 +37,14 @@
+ #include "h/skcsum.h"
+ #include "h/skvpd.h"
+ #include "h/skgehw.h"
++#include "h/sky2le.h"
+ #include "h/skgeinit.h"
+ #include "h/skdrv2nd.h"
+ #include "h/skgepnm2.h"
+ #ifdef SK_POWER_MGMT
+ #include "h/skgepmgt.h"
+-#endif
++#endif /* SK_POWER_MGMT */
++
+ /* defines *******************************************************************/
+ #ifndef DEBUG
+@@ -72,7 +73,6 @@
+ int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
+       unsigned int * pLen, SK_U32 NetIndex);
+-
+ /*
+  * Private Function prototypes
+  */
+@@ -112,6 +112,12 @@
+ PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
+       unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
+ PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
++PNMI_STATIC void VctGetResults(SK_AC *, SK_IOC, SK_U32);
++#ifdef SK_ASF
++PNMI_STATIC int Asf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
++    char *pBuf, unsigned int *pLen, SK_U32 Instance,
++    unsigned int TableIndex, SK_U32 NetIndex);
++#endif /* SK_ASF */
+ /*
+  * Table to correlate OID with handler function and index to
+@@ -353,17 +359,13 @@
+  *    Always 0
+  */
+ int SkPnmiInit(
+-SK_AC *pAC,           /* Pointer to adapter context */
+-SK_IOC IoC,           /* IO context handle */
+-int Level)            /* Initialization level */
++SK_AC *pAC,           /* Pointer to adapter context */
++SK_IOC        IoC,            /* IO context handle */
++int           Level)          /* Initialization level */
+ {
+       unsigned int    PortMax;        /* Number of ports */
+       unsigned int    PortIndex;      /* Current port index in loop */
+-      SK_U16          Val16;          /* Multiple purpose 16 bit variable */
+-      SK_U8           Val8;           /* Mulitple purpose 8 bit variable */
+-      SK_EVPARA       EventParam;     /* Event struct for timer event */
+-      SK_PNMI_VCT     *pVctBackupData;
+-
++      SK_EVPARA               EventParam;     /* Event struct for timer event */
+       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+               ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
+@@ -372,9 +374,11 @@
+       case SK_INIT_DATA:
+               SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
++              
+               pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
+               pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
+               pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
++              
+               for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
+                       pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
+@@ -408,51 +412,42 @@
+               break;
+       case SK_INIT_IO:
+-              /*
+-               * Reset MAC counters
+-               */
++
++              /* Reset MAC counters. */
+               PortMax = pAC->GIni.GIMacsFound;
+               for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
+                       pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
+               }
+-              
++
+               /* Initialize DSP variables for Vct() to 0xff => Never written! */              
+               for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
+                       pAC->GIni.GP[PortIndex].PCableLen = 0xff;
+-                      pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
+-                      pVctBackupData->PCableLen = 0xff;
++                      pAC->Pnmi.VctBackup[PortIndex].CableLen = 0xff;
+               }
+-              
+-              /*
+-               * Get pci bus speed
+-               */
+-              SK_IN16(IoC, B0_CTST, &Val16);
+-              if ((Val16 & CS_BUS_CLOCK) == 0) {
+-                      pAC->Pnmi.PciBusSpeed = 33;
++              /* Get PCI bus speed. */
++              if (pAC->GIni.GIPciClock66) {
++
++                      pAC->Pnmi.PciBusSpeed = 66;
+               }
+               else {
+-                      pAC->Pnmi.PciBusSpeed = 66;
++                      pAC->Pnmi.PciBusSpeed = 33;
+               }
+-              /*
+-               * Get pci bus width
+-               */
+-              SK_IN16(IoC, B0_CTST, &Val16);
+-              if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
++              /* Get PCI bus width. */
++              if (pAC->GIni.GIPciSlot64) {
+-                      pAC->Pnmi.PciBusWidth = 32;
++                      pAC->Pnmi.PciBusWidth = 64;
+               }
+               else {
+-                      pAC->Pnmi.PciBusWidth = 64;
++                      pAC->Pnmi.PciBusWidth = 32;
+               }
+-              /*
+-               * Get chipset
+-               */
++              /* Get chipset. */
+               switch (pAC->GIni.GIChipId) {
++
+               case CHIP_ID_GENESIS:
+                       pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
+                       break;
+@@ -460,58 +455,52 @@
+               case CHIP_ID_YUKON:
+                       pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
+                       break;
++\r
++              case CHIP_ID_YUKON_LITE:\r
++                      pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_LITE;\r
++                      break;\r
++\r
++              case CHIP_ID_YUKON_LP:\r
++                      pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_LP;\r
++                      break;\r
++\r
++              case CHIP_ID_YUKON_XL:\r
++                      pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_XL;\r
++                      break;\r
++\r
++              case CHIP_ID_YUKON_EC:\r
++                      pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_EC;\r
++                      break;\r
++\r
++              case CHIP_ID_YUKON_FE:\r
++                      pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_FE;\r
++                      break;\r
+               default:
+                       break;
+               }
+-              /*
+-               * Get PMD and DeviceType
+-               */
+-              SK_IN8(IoC, B2_PMD_TYP, &Val8);
+-              switch (Val8) {
++              /* Get PMD and Device Type. */
++              switch (pAC->GIni.GIPmdTyp) {
++              
+               case 'S':
+                       pAC->Pnmi.PMD = 3;
+-                      if (pAC->GIni.GIMacsFound > 1) {
+-
+-                              pAC->Pnmi.DeviceType = 0x00020002;
+-                      }
+-                      else {
+-                              pAC->Pnmi.DeviceType = 0x00020001;
+-                      }
++                      pAC->Pnmi.DeviceType = 0x00020001;
+                       break;
+               case 'L':
+                       pAC->Pnmi.PMD = 2;
+-                      if (pAC->GIni.GIMacsFound > 1) {
+-
+-                              pAC->Pnmi.DeviceType = 0x00020004;
+-                      }
+-                      else {
+-                              pAC->Pnmi.DeviceType = 0x00020003;
+-                      }
++                      pAC->Pnmi.DeviceType = 0x00020003;
+                       break;
+               case 'C':
+                       pAC->Pnmi.PMD = 4;
+-                      if (pAC->GIni.GIMacsFound > 1) {
+-
+-                              pAC->Pnmi.DeviceType = 0x00020006;
+-                      }
+-                      else {
+-                              pAC->Pnmi.DeviceType = 0x00020005;
+-                      }
++                      pAC->Pnmi.DeviceType = 0x00020005;
+                       break;
+               case 'T':
+                       pAC->Pnmi.PMD = 5;
+-                      if (pAC->GIni.GIMacsFound > 1) {
+-
+-                              pAC->Pnmi.DeviceType = 0x00020008;
+-                      }
+-                      else {
+-                              pAC->Pnmi.DeviceType = 0x00020007;
+-                      }
++                      pAC->Pnmi.DeviceType = 0x00020007;
+                       break;
+               default :
+@@ -520,11 +509,14 @@
+                       break;
+               }
+-              /*
+-               * Get connector
+-               */
+-              SK_IN8(IoC, B2_CONN_TYP, &Val8);
+-              switch (Val8) {
++              if (pAC->GIni.GIMacsFound > 1) {
++
++                      pAC->Pnmi.DeviceType++;
++              }
++              
++              /* Get connector type. */
++              switch (pAC->GIni.GIConTyp) {
++              
+               case 'C':
+                       pAC->Pnmi.Connector = 2;
+                       break;
+@@ -552,17 +544,17 @@
+               break;
+       case SK_INIT_RUN:
+-              /*
+-               * Start timer for RLMT change counter
+-               */
++
++              /* Start timer for RLMT change counter. */
+               SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
++              
+               SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
+-                      28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
++                      SK_PNMI_EVT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
+                       EventParam);
+               break;
+       default:
+-              break; /* Nothing todo */
++              break; /* Nothing to do. */
+       }
+       return (0);
+@@ -642,7 +634,6 @@
+               ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
+                       Id, *pLen, Instance, NetIndex));
+-
+       return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
+               Instance, NetIndex));
+ }
+@@ -724,7 +715,6 @@
+       unsigned int    TmpLen;
+       char            KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
+-
+       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+               ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
+                       *pLen, NetIndex));
+@@ -733,22 +723,19 @@
+               if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
+-                      SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
+-                              (SK_U32)(-1));
++                      SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, (SK_U32)(-1));
+               }
+               *pLen = SK_PNMI_STRUCT_SIZE;
+               return (SK_PNMI_ERR_TOO_SHORT);
+       }
+-    /*
+-     * Check NetIndex
+-     */
++      /* Check NetIndex. */
+       if (NetIndex >= pAC->Rlmt.NumNets) {
+               return (SK_PNMI_ERR_UNKNOWN_NET);
+       }
+-      /* Update statistic */
++      /* Update statistics. */
+       SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
+       if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
+@@ -773,15 +760,12 @@
+               return (Ret);
+       }
+-      /*
+-       * Increment semaphores to indicate that an update was
+-       * already done
+-       */
++      /* Increment semaphores to indicate that an update was already done. */
+       pAC->Pnmi.MacUpdatedFlag ++;
+       pAC->Pnmi.RlmtUpdatedFlag ++;
+       pAC->Pnmi.SirqUpdatedFlag ++;
+-      /* Get vpd keys for instance calculation */
++      /* Get VPD keys for instance calculation. */
+       Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
+       if (Ret != SK_PNMI_ERR_OK) {
+@@ -795,13 +779,13 @@
+               return (SK_PNMI_ERR_GENERAL);
+       }
+-      /* Retrieve values */
++      /* Retrieve values. */
+       SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
++      
+       for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
+               InstanceNo = IdTable[TableIndex].InstanceNo;
+-              for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
+-                      InstanceCnt ++) {
++              for (InstanceCnt = 1; InstanceCnt <= InstanceNo; InstanceCnt ++) {
+                       DstOffset = IdTable[TableIndex].Offset +
+                               (InstanceCnt - 1) *
+@@ -998,7 +982,6 @@
+       unsigned int    PhysPortIndex;
+     unsigned int      MaxNetNumber;
+       int                     CounterIndex;
+-      int                     Ret;
+       SK_U16          MacStatus;
+       SK_U64          OverflowStatus;
+       SK_U64          Mask;
+@@ -1012,12 +995,7 @@
+       SK_U64          Delta;
+       SK_PNMI_ESTIMATE *pEst;
+       SK_U32          NetIndex;
+-      SK_GEPORT       *pPrt;
+-      SK_PNMI_VCT     *pVctBackupData;
+       SK_U32          RetCode;
+-      int             i;
+-      SK_U32          CableLength;
+-
+ #ifdef DEBUG
+       if (Event != SK_PNMI_EVT_XMAC_RESET) {
+@@ -1048,9 +1026,7 @@
+ #endif /* DEBUG */
+               OverflowStatus = 0;
+-              /*
+-               * Check which source caused an overflow interrupt.
+-               */
++              /* Check which source caused an overflow interrupt. */
+               if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
+                               MacStatus, &OverflowStatus) != 0) ||
+                       (OverflowStatus == 0)) {
+@@ -1068,7 +1044,6 @@
+                       Mask = (SK_U64)1 << CounterIndex;
+                       if ((OverflowStatus & Mask) == 0) {
+-
+                               continue;
+                       }
+@@ -1100,9 +1075,7 @@
+                       case SK_PNMI_HRX_IRLENGTH:
+                       case SK_PNMI_HRX_RESERVED:
+                       
+-                      /*
+-                       * the following counters aren't be handled (id > 63)
+-                       */
++                      /* The following counters aren't be handled (id > 63). */
+                       case SK_PNMI_HTX_SYNC:
+                       case SK_PNMI_HTX_SYNC_OCTET:
+                               break;
+@@ -1189,7 +1162,7 @@
+               if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
+-                              ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
++                              ("PNMI: ERR: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
+                               (unsigned int)Param.Para64));
+                       return (0);
+               }
+@@ -1208,16 +1181,14 @@
+       case SK_PNMI_EVT_CHG_EST_TIMER:
+               /*
+                * Calculate port switch average on a per hour basis
+-               *   Time interval for check       : 28125 ms
++               *   Time interval for check       : 28125 ms (SK_PNMI_EVT_TIMER_CHECK)
+                *   Number of values for average  : 8
+                *
+                * Be careful in changing these values, on change check
+                *   - typedef of SK_PNMI_ESTIMATE (Size of EstValue
+                *     array one less than value number)
+                *   - Timer initialization SkTimerStart() in SkPnmiInit
+-               *   - Delta value below must be multiplicated with
+-               *     power of 2
+-               *
++               *   - Delta value below must be multiplicated with power of 2
+                */
+               pEst = &pAC->Pnmi.RlmtChangeEstimate;
+               CounterIndex = pEst->EstValueIndex + 1;
+@@ -1240,7 +1211,7 @@
+                       Delta = NewestValue - OldestValue;
+               }
+               else {
+-                      /* Overflow situation */
++                      /* Overflow situation. */
+                       Delta = (SK_U64)(0 - OldestValue) + NewestValue;
+               }
+@@ -1266,8 +1237,9 @@
+               }
+               SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
++              
+               SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
+-                      28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
++                      SK_PNMI_EVT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
+                       EventParam);
+               break;
+@@ -1311,29 +1283,25 @@
+                               (unsigned int)Param.Para64));
+                       return (0);
+               }
+-#endif
++#endif /* DEBUG */
++
+               PhysPortIndex = (unsigned int)Param.Para64;
+-              /*
+-               * Update XMAC statistic to get fresh values
+-               */
+-              Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
+-              if (Ret != SK_PNMI_ERR_OK) {
++              /* Update XMAC statistic to get fresh values. */
++              if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
++                      SK_PNMI_ERR_OK) {
+                       SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
+                       return (0);
+               }
+-              /*
+-               * Increment semaphore to indicate that an update was
+-               * already done
+-               */
++
++              /* Increment semaphore to indicate that an update was already done. */
+               pAC->Pnmi.MacUpdatedFlag ++;
+               for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
+                       CounterIndex ++) {
+                       if (!StatAddr[CounterIndex][MacType].GetOffset) {
+-
+                               continue;
+                       }
+@@ -1366,14 +1334,15 @@
+               QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
+               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
+-              /* Bugfix for XMAC errata (#10620)*/
++              /* Bugfix for XMAC errata (#10620). */
+               if (MacType == SK_MAC_XMAC) {
+-                      /* Add incremental difference to offset (#10620)*/
++                      /* Add incremental difference to offset (#10620). */
+                       (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                               XM_RXE_SHT_ERR, &Val32);
+                       
+                       Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
+                                CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
++                      
+                       pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
+                               Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
+               }
+@@ -1403,7 +1372,7 @@
+               QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
+               (void)SK_DRIVER_SENDEVENT(pAC, IoC);
+-              /* Bugfix #10620 - get zero level for incremental difference */
++              /* Bugfix #10620 - get zero level for incremental difference. */
+               if (MacType == SK_MAC_XMAC) {
+                       (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
+@@ -1435,17 +1404,13 @@
+               }
+ #endif /* DEBUG */
+-              /*
+-               * For now, ignore event if NetIndex != 0.
+-               */
++              /* For now, ignore event if NetIndex != 0. */
+               if (Param.Para32[1] != 0) {
+                       return (0);
+               }
+-              /*
+-               * Nothing to do if port is already inactive
+-               */
++              /* Nothing to do if port is already inactive. */
+               if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+                       return (0);
+@@ -1476,7 +1441,6 @@
+                       CounterIndex ++) {
+                       if (!StatAddr[CounterIndex][MacType].GetOffset) {
+-
+                               continue;
+                       }
+@@ -1485,9 +1449,7 @@
+                       pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
+               }
+-              /*
+-               * Set port to inactive
+-               */
++              /* Set port to inactive. */
+               pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
+               pAC->Pnmi.MacUpdatedFlag --;
+@@ -1513,25 +1475,19 @@
+               }
+ #endif /* DEBUG */
+-              /*
+-               * For now, ignore event if NetIndex != 0.
+-               */
++              /* For now, ignore event if NetIndex != 0. */
+               if (Param.Para32[1] != 0) {
+                       return (0);
+               }
+-              /*
+-               * Nothing to do if port is already active
+-               */
++              /* Nothing to do if port is already inactive. */
+               if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+                       return (0);
+               }
+-              /*
+-               * Statistic maintenance
+-               */
++              /* Statistic maintenance. */
+               pAC->Pnmi.RlmtChangeCts ++;
+               pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
+@@ -1565,7 +1521,6 @@
+                       CounterIndex ++) {
+                       if (!StatAddr[CounterIndex][MacType].GetOffset) {
+-
+                               continue;
+                       }
+@@ -1574,16 +1529,14 @@
+                       pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
+               }
+-              /* Set port to active */
++              /* Set port to active. */
+               pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
+               pAC->Pnmi.MacUpdatedFlag --;
+               break;
+       case SK_PNMI_EVT_RLMT_SEGMENTATION:
+-              /*
+-               * Para.Para32[0] contains the NetIndex.
+-               */
++              /* Para.Para32[0] contains the NetIndex. */
+               /*
+                * Store a trap message in the trap buffer and generate an event for
+@@ -1598,71 +1551,53 @@
+                *  Param.Para32[0] contains the number of Nets.
+                *  Param.Para32[1] is reserved, contains -1.
+                */
+-          /*
+-       * Check number of nets
+-               */
++          /* Check number of nets. */
+               MaxNetNumber = pAC->GIni.GIMacsFound;
+-              if (((unsigned int)Param.Para32[0] < 1)
+-                      || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
++              
++              if (((unsigned int)Param.Para32[0] < 1) ||
++                      ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
++                      
+                       return (SK_PNMI_ERR_UNKNOWN_NET);
+               }
+-        if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
++        if ((unsigned int)Param.Para32[0] == 1) { /* SingleNet mode. */
+               pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
+         }
+-        else { /* dual net mode */
++        else { /* DualNet mode. */
+               pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
+         }
+         break;
+     case SK_PNMI_EVT_VCT_RESET:
+               PhysPortIndex = Param.Para32[0];
+-              pPrt = &pAC->GIni.GP[PhysPortIndex];
+-              pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
+               
+               if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
++                      
+                       RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
++                      
+                       if (RetCode == 2) {
+                               /*
+                                * VCT test is still running.
+                                * Start VCT timer counter again.
+                                */
+-                              SK_MEMSET((char *) &Param, 0, sizeof(Param));
++                              SK_MEMSET((char *)&Param, 0, sizeof(Param));
++                              
+                               Param.Para32[0] = PhysPortIndex;
+                               Param.Para32[1] = -1;
+-                              SkTimerStart(pAC, IoC,
+-                                      &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
+-                              4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
++                              
++                              SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex],
++                                      SK_PNMI_VCT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
++                              
+                               break;
+                       }
+-                      pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
+-                      pAC->Pnmi.VctStatus[PhysPortIndex] |=
+-                              (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
+                       
+-                      /* Copy results for later use to PNMI struct. */
+-                      for (i = 0; i < 4; i++)  {
+-                              if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
+-                                      if ((pPrt->PMdiPairLen[i] > 35) &&
+-                                              (pPrt->PMdiPairLen[i] < 0xff)) {
+-                                              pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
+-                                      }
+-                              }
+-                              if ((pPrt->PMdiPairLen[i] > 35) &&
+-                                      (pPrt->PMdiPairLen[i] != 0xff)) {
+-                                      CableLength = 1000 *
+-                                              (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
+-                              }
+-                              else {
+-                                      CableLength = 0;
+-                              }
+-                              pVctBackupData->PMdiPairLen[i] = CableLength;
+-                              pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
+-                      }
++                      VctGetResults(pAC, IoC, PhysPortIndex);
+                       
+-                      Param.Para32[0] = PhysPortIndex;
+-                      Param.Para32[1] = -1;
+-                      SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
+-                      SkEventDispatcher(pAC, IoC);
++                      EventParam.Para32[0] = PhysPortIndex;
++                      EventParam.Para32[1] = -1;
++                      SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, EventParam);
++
++                      /* SkEventDispatcher(pAC, IoC); */
+               }
+               
+               break;
+@@ -1710,14 +1645,13 @@
+       unsigned int    TableIndex;
+       int             Ret;
+-
+       if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
+               *pLen = 0;
+               return (SK_PNMI_ERR_UNKNOWN_OID);
+       }
+       
+-    /* Check NetIndex */
++    /* Check NetIndex. */
+       if (NetIndex >= pAC->Rlmt.NumNets) {
+               return (SK_PNMI_ERR_UNKNOWN_NET);
+       }
+@@ -1767,22 +1701,20 @@
+       SK_U32          Instance;
+       SK_U32          Id;
+-
+-      /* Check if the passed buffer has the right size */
++      /* Check if the passed buffer has the right size. */
+       if (*pLen < SK_PNMI_STRUCT_SIZE) {
+-              /* Check if we can return the error within the buffer */
++              /* Check if we can return the error within the buffer. */
+               if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
+-                      SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
+-                              (SK_U32)(-1));
++                      SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, (SK_U32)(-1));
+               }
+               *pLen = SK_PNMI_STRUCT_SIZE;
+               return (SK_PNMI_ERR_TOO_SHORT);
+       }
+       
+-    /* Check NetIndex */
++    /* Check NetIndex. */
+       if (NetIndex >= pAC->Rlmt.NumNets) {
+               return (SK_PNMI_ERR_UNKNOWN_NET);
+       }
+@@ -1810,12 +1742,11 @@
+       pAC->Pnmi.RlmtUpdatedFlag ++;
+       pAC->Pnmi.SirqUpdatedFlag ++;
+-      /* Preset/Set values */
++      /* PRESET/SET values. */
+       for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
+               if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
+                       (IdTable[TableIndex].Access != SK_PNMI_WO)) {
+-
+                       continue;
+               }
+@@ -1826,8 +1757,7 @@
+                       InstanceCnt ++) {
+                       DstOffset = IdTable[TableIndex].Offset +
+-                              (InstanceCnt - 1) *
+-                              IdTable[TableIndex].StructSize;
++                              (InstanceCnt - 1) * IdTable[TableIndex].StructSize;
+                       /*
+                        * Because VPD multiple instance variables are
+@@ -1837,9 +1767,7 @@
+                        */
+                       Instance = (SK_U32)InstanceCnt;
+-                      /*
+-                       * Evaluate needed buffer length
+-                       */
++                      /* Evaluate needed buffer length. */
+                       Len = 0;
+                       Ret = IdTable[TableIndex].Func(pAC, IoC,
+                               SK_PNMI_GET, IdTable[TableIndex].Id,
+@@ -1855,8 +1783,7 @@
+                               pAC->Pnmi.SirqUpdatedFlag --;
+                               SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
+-                              SK_PNMI_SET_STAT(pBuf,
+-                                      SK_PNMI_ERR_GENERAL, DstOffset);
++                              SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_GENERAL, DstOffset);
+                               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
+                               return (SK_PNMI_ERR_GENERAL);
+                       }
+@@ -1878,7 +1805,7 @@
+                               }
+                       }
+-                      /* Call the OID handler function */
++                      /* Call the OID handler function. */
+                       Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
+                               IdTable[TableIndex].Id, pBuf + DstOffset,
+                               &Len, Instance, TableIndex, NetIndex);
+@@ -1889,8 +1816,7 @@
+                               pAC->Pnmi.SirqUpdatedFlag --;
+                               SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
+-                              SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
+-                                      DstOffset);
++                              SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE, DstOffset);
+                               *pLen = SK_PNMI_MIN_STRUCT_SIZE;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+@@ -1924,7 +1850,7 @@
+               if (IdTable[i].Id == Id) {
+-                      return i;
++                      return (i);
+               }
+       }
+@@ -1965,16 +1891,13 @@
+ {
+       if (Id != OID_SKGE_ALL_DATA) {
+-              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
+-                      SK_PNMI_ERR003MSG);
++              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003, SK_PNMI_ERR003MSG);
+               *pLen = 0;
+               return (SK_PNMI_ERR_GENERAL);
+       }
+-      /*
+-       * Check instance. We only handle single instance variables
+-       */
++      /* Check instance. We only handle single instance variables. */
+       if (Instance != (SK_U32)(-1) && Instance != 1) {
+               *pLen = 0;
+@@ -2033,10 +1956,7 @@
+       int     Ret;
+       SK_U32  ActionOp;
+-
+-      /*
+-       * Check instance. We only handle single instance variables
+-       */
++      /* Check instance. We only handle single instance variables. */
+       if (Instance != (SK_U32)(-1) && Instance != 1) {
+               *pLen = 0;
+@@ -2049,10 +1969,10 @@
+               return (SK_PNMI_ERR_TOO_SHORT);
+       }
+-      /* Check if a get should be performed */
++      /* Check if a GET should be performed. */
+       if (Action == SK_PNMI_GET) {
+-              /* A get is easy. We always return the same value */
++              /* A GET is easy. We always return the same value. */
+               ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
+               SK_PNMI_STORE_U32(pBuf, ActionOp);
+               *pLen = sizeof(SK_U32);
+@@ -2060,13 +1980,13 @@
+               return (SK_PNMI_ERR_OK);
+       }
+-      /* Continue with PRESET/SET action */
++      /* Continue with PRESET/SET action. */
+       if (*pLen > sizeof(SK_U32)) {
+               return (SK_PNMI_ERR_BAD_VALUE);
+       }
+-      /* Check if the command is a known one */
++      /* Check if the command is a known one. */
+       SK_PNMI_READ_U32(pBuf, ActionOp);
+       if (*pLen > sizeof(SK_U32) ||
+               (ActionOp != SK_PNMI_ACT_IDLE &&
+@@ -2078,7 +1998,7 @@
+               return (SK_PNMI_ERR_BAD_VALUE);
+       }
+-      /* A preset ends here */
++      /* A PRESET ends here. */
+       if (Action == SK_PNMI_PRESET) {
+               return (SK_PNMI_ERR_OK);
+@@ -2087,19 +2007,15 @@
+       switch (ActionOp) {
+       case SK_PNMI_ACT_IDLE:
+-              /* Nothing to do */
++              /* Nothing to do. */
+               break;
+       case SK_PNMI_ACT_RESET:
+-              /*
+-               * Perform a driver reset or something that comes near
+-               * to this.
+-               */
++              /* Perform a driver reset or something that comes near to this. */
+               Ret = SK_DRIVER_RESET(pAC, IoC);
+               if (Ret != 0) {
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
+-                              SK_PNMI_ERR005MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005, SK_PNMI_ERR005MSG);
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+@@ -2116,13 +2032,12 @@
+               break;
+       case SK_PNMI_ACT_RESETCNT:
+-              /* Set all counters and timestamps to zero */
++              /* Set all counters and timestamps to zero. */
+               ResetCounter(pAC, IoC, NetIndex);
+               break;
+       default:
+-              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
+-                      SK_PNMI_ERR006MSG);
++              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006, SK_PNMI_ERR006MSG);
+               return (SK_PNMI_ERR_GENERAL);
+       }
+@@ -2166,25 +2081,21 @@
+       SK_U32  StatVal32;
+       SK_BOOL Is64BitReq = SK_FALSE;
+-      /*
+-       * Only the active Mac is returned
+-       */
++      /* Only the active MAC is returned. */
+       if (Instance != (SK_U32)(-1) && Instance != 1) {
+               *pLen = 0;
+               return (SK_PNMI_ERR_UNKNOWN_INST);
+       }
+-      /*
+-       * Check action type
+-       */
++      /* Check action type. */
+       if (Action != SK_PNMI_GET) {
+               *pLen = 0;
+               return (SK_PNMI_ERR_READ_ONLY);
+       }
+-      /* Check length */
++      /* Check length. */
+       switch (Id) {
+       case OID_802_3_PERMANENT_ADDRESS:
+@@ -2205,12 +2116,12 @@
+ #else /* SK_NDIS_64BIT_CTR */
+-              /* for compatibility, at least 32bit are required for OID */
++              /* For compatibility, at least 32 bits are required for OID. */
+               if (*pLen < sizeof(SK_U32)) {
+                       /*
+-                      * but indicate handling for 64bit values,
+-                      * if insufficient space is provided
+-                      */
++                       * Indicate handling for 64 bit values,
++                       * if insufficient space is provided.
++                       */
+                       *pLen = sizeof(SK_U64);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+@@ -2226,16 +2137,14 @@
+        * to indicate that an update was already done.
+        */
+       Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
+-      if ( Ret != SK_PNMI_ERR_OK) {
++      if (Ret != SK_PNMI_ERR_OK) {
+               *pLen = 0;
+               return (Ret);
+       }
+       pAC->Pnmi.MacUpdatedFlag ++;
+-      /*
+-       * Get value (MAC Index 0 identifies the virtual MAC)
+-       */
++      /* Get value (MAC index 0 identifies the virtual MAC). */
+       switch (Id) {
+       case OID_802_3_PERMANENT_ADDRESS:
+@@ -2251,7 +2160,7 @@
+       default:
+               StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
+-              /* by default 32bit values are evaluated */
++              /* By default 32 bit values are evaluated. */
+               if (!Is64BitReq) {
+                       StatVal32 = (SK_U32)StatVal;
+                       SK_PNMI_STORE_U32(pBuf, StatVal32);
+@@ -2305,21 +2214,19 @@
+       int                             MacType;
+       int                             Ret;
+       SK_U64                  StatVal;
+-      
+-      
+-      /* Calculate instance if wished. MAC index 0 is the virtual MAC */
++      /* Calculate instance if wished. MAC index 0 is the virtual MAC. */
+       PhysPortMax = pAC->GIni.GIMacsFound;
+       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
+       
+       MacType = pAC->GIni.GIMacType;
+-      if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
++      if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* DualNet mode. */
+               LogPortMax--;
+       }
+-      if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
+-              /* Check instance range */
++      if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried. */
++              /* Check instance range. */
+               if ((Instance < 1) || (Instance > LogPortMax)) {
+                       *pLen = 0;
+@@ -2329,20 +2236,20 @@
+               Limit = LogPortIndex + 1;
+       }
+-      else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
++      else { /* Instance == (SK_U32)(-1), get all Instances of that OID. */
+               LogPortIndex = 0;
+               Limit = LogPortMax;
+       }
+-      /* Check action */
++      /* Check action. */
+       if (Action != SK_PNMI_GET) {
+               *pLen = 0;
+               return (SK_PNMI_ERR_READ_ONLY);
+       }
+-      /* Check length */
++      /* Check length. */
+       if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
+               *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
+@@ -2361,7 +2268,7 @@
+       }
+       pAC->Pnmi.MacUpdatedFlag ++;
+-      /* Get value */
++      /* Get value. */
+       Offset = 0;
+       for (; LogPortIndex < Limit; LogPortIndex ++) {
+@@ -2467,19 +2374,16 @@
+       unsigned int    Limit;
+       unsigned int    Offset = 0;
+-      /*
+-       * Calculate instance if wished. MAC index 0 is the virtual
+-       * MAC.
+-       */
++      /* Calculate instance if wished. MAC index 0 is the virtual MAC. */
+       PhysPortMax = pAC->GIni.GIMacsFound;
+       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
+-      if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
++      if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* DualNet mode. */
+               LogPortMax--;
+       }
+-      if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
+-              /* Check instance range */
++      if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried. */
++              /* Check instance range. */
+               if ((Instance < 1) || (Instance > LogPortMax)) {
+                       *pLen = 0;
+@@ -2488,27 +2392,23 @@
+               LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
+               Limit = LogPortIndex + 1;
+       }
+-      else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
++      else { /* Instance == (SK_U32)(-1), get all Instances of that OID. */
+               LogPortIndex = 0;
+               Limit = LogPortMax;
+       }
+-      /*
+-       * Perform Action
+-       */
++      /* Perform action. */
+       if (Action == SK_PNMI_GET) {
+-              /* Check length */
++              /* Check length. */
+               if (*pLen < (Limit - LogPortIndex) * 6) {
+                       *pLen = (Limit - LogPortIndex) * 6;
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+-              /*
+-               * Get value
+-               */
++              /* Get value. */
+               for (; LogPortIndex < Limit; LogPortIndex ++) {
+                       switch (Id) {
+@@ -2532,8 +2432,7 @@
+                                               &pAC->Addr.Net[NetIndex].PermanentMacAddress);
+                               }
+                               else {
+-                                      PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+-                                              pAC, LogPortIndex);
++                                      PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
+                                       CopyMac(pBuf + Offset,
+                                               &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
+@@ -2542,8 +2441,7 @@
+                               break;
+                       default:
+-                              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
+-                                      SK_PNMI_ERR008MSG);
++                              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008, SK_PNMI_ERR008MSG);
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+@@ -2554,8 +2452,8 @@
+       }
+       else {
+               /*
+-               * The logical MAC address may not be changed only
+-               * the physical ones
++               * The logical MAC address may not be changed,
++               * only the physical ones.
+                */
+               if (Id == OID_SKGE_PHYS_FAC_ADDR) {
+@@ -2563,19 +2461,16 @@
+                       return (SK_PNMI_ERR_READ_ONLY);
+               }
+-              /*
+-               * Only the current address may be changed
+-               */
++              /* Only the current address may be changed. */
+               if (Id != OID_SKGE_PHYS_CUR_ADDR) {
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
+-                              SK_PNMI_ERR009MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009, SK_PNMI_ERR009MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+-              /* Check length */
++              /* Check length. */
+               if (*pLen < (Limit - LogPortIndex) * 6) {
+                       *pLen = (Limit - LogPortIndex) * 6;
+@@ -2587,32 +2482,26 @@
+                       return (SK_PNMI_ERR_BAD_VALUE);
+               }
+-              /*
+-               * Check Action
+-               */
++              /* Check action. */
+               if (Action == SK_PNMI_PRESET) {
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_OK);
+               }
+-              /*
+-               * Set OID_SKGE_MAC_CUR_ADDR
+-               */
++              /* Set OID_SKGE_MAC_CUR_ADDR.  */
+               for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
+                       /*
+                        * A set to virtual port and set of broadcast
+-                       * address will be ignored
++                       * address will be ignored.
+                        */
+                       if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
+                               "\xff\xff\xff\xff\xff\xff", 6) == 0) {
+-
+                               continue;
+                       }
+-                      PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
+-                              LogPortIndex);
++                      PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
+                       Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
+                               (SK_MAC_ADDR *)(pBuf + Offset),
+@@ -2665,10 +2554,7 @@
+       unsigned int    Offset = 0;
+       SK_U64          StatVal;
+-
+-      /*
+-       * Calculate instance if wished
+-       */
++      /* Calculate instance if wished. */
+       if (Instance != (SK_U32)(-1)) {
+               if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
+@@ -2684,25 +2570,21 @@
+               Limit = SKCS_NUM_PROTOCOLS;
+       }
+-      /*
+-       * Check action
+-       */
++      /* Check action. */
+       if (Action != SK_PNMI_GET) {
+               *pLen = 0;
+               return (SK_PNMI_ERR_READ_ONLY);
+       }
+-      /* Check length */
++      /* Check length. */
+       if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
+               *pLen = (Limit - Index) * sizeof(SK_U64);
+               return (SK_PNMI_ERR_TOO_SHORT);
+       }
+-      /*
+-       * Get value
+-       */
++      /* Get value. */
+       for (; Index < Limit; Index ++) {
+               switch (Id) {
+@@ -2728,8 +2610,7 @@
+                       break;
+               default:
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
+-                              SK_PNMI_ERR010MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010, SK_PNMI_ERR010MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -2739,9 +2620,7 @@
+               Offset += sizeof(SK_U64);
+       }
+-      /*
+-       * Store used buffer space
+-       */
++      /* Store used buffer space. */
+       *pLen = Offset;
+       return (SK_PNMI_ERR_OK);
+@@ -2784,10 +2663,7 @@
+       SK_U32          Val32;
+       SK_U64          Val64;
+-
+-      /*
+-       * Calculate instance if wished
+-       */
++      /* Calculate instance if wished. */
+       if ((Instance != (SK_U32)(-1))) {
+               if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
+@@ -2804,16 +2680,14 @@
+               Limit = (unsigned int) pAC->I2c.MaxSens;
+       }
+-      /*
+-       * Check action
+-       */
++      /* Check action. */
+       if (Action != SK_PNMI_GET) {
+               *pLen = 0;
+               return (SK_PNMI_ERR_READ_ONLY);
+       }
+-      /* Check length */
++      /* Check length. */
+       switch (Id) {
+       case OID_SKGE_SENSOR_VALUE:
+@@ -2872,38 +2746,33 @@
+               break;
+       default:
+-              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
+-                      SK_PNMI_ERR012MSG);
++              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012, SK_PNMI_ERR012MSG);
+               *pLen = 0;
+               return (SK_PNMI_ERR_GENERAL);
+       }
+-      /*
+-       * Get value
+-       */
++      /* Get value. */
+       for (Offset = 0; Index < Limit; Index ++) {
+               switch (Id) {
+               case OID_SKGE_SENSOR_INDEX:
+                       *(pBuf + Offset) = (char)Index;
+-                      Offset += sizeof(char);
++                      Offset ++;
+                       break;
+               case OID_SKGE_SENSOR_DESCR:
+                       Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
+-                      SK_MEMCPY(pBuf + Offset + 1,
+-                              pAC->I2c.SenTable[Index].SenDesc, Len);
++                      SK_MEMCPY(pBuf + Offset + 1, pAC->I2c.SenTable[Index].SenDesc, Len);
+                       *(pBuf + Offset) = (char)Len;
+                       Offset += Len + 1;
+                       break;
+               case OID_SKGE_SENSOR_TYPE:
+-                      *(pBuf + Offset) =
+-                              (char)pAC->I2c.SenTable[Index].SenType;
+-                      Offset += sizeof(char);
++                      *(pBuf + Offset) = (char)pAC->I2c.SenTable[Index].SenType;
++                      Offset ++;
+                       break;
+               case OID_SKGE_SENSOR_VALUE:
+@@ -2940,9 +2809,8 @@
+                       break;
+               case OID_SKGE_SENSOR_STATUS:
+-                      *(pBuf + Offset) =
+-                              (char)pAC->I2c.SenTable[Index].SenErrFlag;
+-                      Offset += sizeof(char);
++                      *(pBuf + Offset) = (char)pAC->I2c.SenTable[Index].SenErrFlag;
++                      Offset ++;
+                       break;
+               case OID_SKGE_SENSOR_WAR_CTS:
+@@ -2979,9 +2847,7 @@
+               }
+       }
+-      /*
+-       * Store used buffer space
+-       */
++      /* Store used buffer space. */
+       *pLen = Offset;
+       return (SK_PNMI_ERR_OK);
+@@ -3035,9 +2901,7 @@
+       int             Ret;
+       SK_U32          Val32;
+-      /*
+-       * Get array of all currently stored VPD keys
+-       */
++      /* Get array of all currently stored VPD keys. */
+       Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
+       if (Ret != SK_PNMI_ERR_OK) {
+               *pLen = 0;
+@@ -3082,21 +2946,19 @@
+               }
+       }
+-      /*
+-       * Get value, if a query should be performed
+-       */
++      /* Get value, if a query should be performed. */
+       if (Action == SK_PNMI_GET) {
+               switch (Id) {
+               case OID_SKGE_VPD_FREE_BYTES:
+-                      /* Check length of buffer */
++                      /* Check length of buffer. */
+                       if (*pLen < sizeof(SK_U32)) {
+                               *pLen = sizeof(SK_U32);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+-                      /* Get number of free bytes */
++                      /* Get number of free bytes. */
+                       pVpdStatus = VpdStat(pAC, IoC);
+                       if (pVpdStatus == NULL) {
+@@ -3121,7 +2983,7 @@
+                       break;
+               case OID_SKGE_VPD_ENTRIES_LIST:
+-                      /* Check length */
++                      /* Check length. */
+                       for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
+                               Len += SK_STRLEN(KeyArr[Index]) + 1;
+@@ -3132,7 +2994,7 @@
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+-                      /* Get value */
++                      /* Get value. */
+                       *(pBuf) = (char)Len - 1;
+                       for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
+@@ -3151,7 +3013,7 @@
+                       break;
+               case OID_SKGE_VPD_ENTRIES_NUMBER:
+-                      /* Check length */
++                      /* Check length. */
+                       if (*pLen < sizeof(SK_U32)) {
+                               *pLen = sizeof(SK_U32);
+@@ -3164,7 +3026,7 @@
+                       break;
+               case OID_SKGE_VPD_KEY:
+-                      /* Check buffer length, if it is large enough */
++                      /* Check buffer length, if it is large enough. */
+                       for (Len = 0, Index = FirstIndex;
+                               Index < LastIndex; Index ++) {
+@@ -3180,31 +3042,27 @@
+                        * Get the key to an intermediate buffer, because
+                        * we have to prepend a length byte.
+                        */
+-                      for (Offset = 0, Index = FirstIndex;
+-                              Index < LastIndex; Index ++) {
++                      for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) {
+                               Len = SK_STRLEN(KeyArr[Index]);
+                               *(pBuf + Offset) = (char)Len;
+-                              SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
+-                                      Len);
++                              SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index], Len);
+                               Offset += Len + 1;
+                       }
+                       *pLen = Offset;
+                       break;
+               case OID_SKGE_VPD_VALUE:
+-                      /* Check the buffer length if it is large enough */
+-                      for (Offset = 0, Index = FirstIndex;
+-                              Index < LastIndex; Index ++) {
++                      /* Check the buffer length if it is large enough. */
++                      for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) {
+                               BufLen = 256;
+                               if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
+                                       (int *)&BufLen) > 0 ||
+                                       BufLen >= SK_PNMI_VPD_DATALEN) {
+-                                      SK_ERR_LOG(pAC, SK_ERRCL_SW,
+-                                              SK_PNMI_ERR021,
++                                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR021,
+                                               SK_PNMI_ERR021MSG);
+                                       return (SK_PNMI_ERR_GENERAL);
+@@ -3221,16 +3079,14 @@
+                        * Get the value to an intermediate buffer, because
+                        * we have to prepend a length byte.
+                        */
+-                      for (Offset = 0, Index = FirstIndex;
+-                              Index < LastIndex; Index ++) {
++                      for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) {
+                               BufLen = 256;
+                               if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
+                                       (int *)&BufLen) > 0 ||
+                                       BufLen >= SK_PNMI_VPD_DATALEN) {
+-                                      SK_ERR_LOG(pAC, SK_ERRCL_SW,
+-                                              SK_PNMI_ERR022,
++                                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR022,
+                                               SK_PNMI_ERR022MSG);
+                                       *pLen = 0;
+@@ -3251,8 +3107,7 @@
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+-                      for (Offset = 0, Index = FirstIndex;
+-                              Index < LastIndex; Index ++) {
++                      for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) {
+                               if (VpdMayWrite(KeyArr[Index])) {
+@@ -3278,15 +3133,14 @@
+                       break;
+               default:
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
+-                              SK_PNMI_ERR023MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023, SK_PNMI_ERR023MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+       }
+       else {
+-              /* The only OID which can be set is VPD_ACTION */
++              /* The only OID which can be set is VPD_ACTION. */
+               if (Id != OID_SKGE_VPD_ACTION) {
+                       if (Id == OID_SKGE_VPD_FREE_BYTES ||
+@@ -3300,8 +3154,7 @@
+                               return (SK_PNMI_ERR_READ_ONLY);
+                       }
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
+-                              SK_PNMI_ERR024MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024, SK_PNMI_ERR024MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -3317,14 +3170,11 @@
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+-              /*
+-               * The first byte contains the VPD action type we should
+-               * perform.
+-               */
++              /* The first byte contains the VPD action type we should perform. */
+               switch (*pBuf) {
+               case SK_PNMI_VPD_IGNORE:
+-                      /* Nothing to do */
++                      /* Nothing to do. */
+                       break;
+               case SK_PNMI_VPD_CREATE:
+@@ -3356,13 +3206,13 @@
+                       SK_MEMCPY(Buf, pBuf + 4, Offset);
+                       Buf[Offset] = 0;
+-                      /* A preset ends here */
++                      /* A PRESET ends here. */
+                       if (Action == SK_PNMI_PRESET) {
+                               return (SK_PNMI_ERR_OK);
+                       }
+-                      /* Write the new entry or modify an existing one */
++                      /* Write the new entry or modify an existing one .*/
+                       Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
+                       if (Ret == SK_PNMI_VPD_NOWRITE ) {
+@@ -3394,7 +3244,7 @@
+                       break;
+               case SK_PNMI_VPD_DELETE:
+-                      /* Check if the buffer size is plausible */
++                      /* Check if the buffer size is plausible. */
+                       if (*pLen < 3) {
+                               *pLen = 3;
+@@ -3409,7 +3259,7 @@
+                       KeyStr[1] = pBuf[2];
+                       KeyStr[2] = 0;
+-                      /* Find the passed key in the array */
++                      /* Find the passed key in the array. */
+                       for (Index = 0; Index < KeyNo; Index ++) {
+                               if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
+@@ -3417,6 +3267,7 @@
+                                       break;
+                               }
+                       }
++
+                       /*
+                        * If we cannot find the key it is wrong, so we
+                        * return an appropriate error value.
+@@ -3432,7 +3283,7 @@
+                               return (SK_PNMI_ERR_OK);
+                       }
+-                      /* Ok, you wanted it and you will get it */
++                      /* Ok, you wanted it and you will get it. */
+                       Ret = VpdDelete(pAC, IoC, KeyStr);
+                       if (Ret != SK_PNMI_VPD_OK) {
+@@ -3505,23 +3356,21 @@
+       SK_U32          Val32;
+       SK_U64          Val64;
+       SK_U64          Val64RxHwErrs = 0;
++      SK_U64          Val64RxRunt = 0;
++      SK_U64          Val64RxFcs = 0;
+       SK_U64          Val64TxHwErrs = 0;
+       SK_BOOL         Is64BitReq = SK_FALSE;
+       char            Buf[256];
+       int                     MacType;
+-      /*
+-       * Check instance. We only handle single instance variables.
+-       */
++      /* Check instance. We only handle single instance variables. */
+       if (Instance != (SK_U32)(-1) && Instance != 1) {
+               *pLen = 0;
+               return (SK_PNMI_ERR_UNKNOWN_INST);
+       }
+-      /*
+-       * Check action. We only allow get requests.
+-       */
++      /* Check action. We only allow get requests. */
+       if (Action != SK_PNMI_GET) {
+               *pLen = 0;
+@@ -3530,9 +3379,7 @@
+       
+       MacType = pAC->GIni.GIMacType;
+       
+-      /*
+-       * Check length for the various supported OIDs
+-       */
++      /* Check length for the various supported OIDs. */
+       switch (Id) {
+       case OID_GEN_XMIT_ERROR:
+@@ -3546,14 +3393,12 @@
+ #else /* SK_NDIS_64BIT_CTR */
+-              /*
+-               * for compatibility, at least 32bit are required for oid
+-               */
++              /* For compatibility, at least 32bit are required for OID. */
+               if (*pLen < sizeof(SK_U32)) {
+                       /*
+-                      * but indicate handling for 64bit values,
+-                      * if insufficient space is provided
+-                      */
++                       * Indicate handling for 64bit values,
++                       * if insufficient space is provided.
++                       */
+                       *pLen = sizeof(SK_U64);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+@@ -3624,11 +3469,11 @@
+               break;
+       default:
+-              /* Checked later */
++              /* Checked later. */
+               break;
+       }
+-      /* Update statistic */
++      /* Update statistics. */
+       if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
+               Id == OID_SKGE_TX_HW_ERROR_CTS ||
+               Id == OID_SKGE_IN_ERRORS_CTS ||
+@@ -3636,7 +3481,8 @@
+               Id == OID_GEN_XMIT_ERROR ||
+               Id == OID_GEN_RCV_ERROR) {
+-              /* Force the XMAC to update its statistic counters and
++              /*
++               * Force the XMAC to update its statistic counters and
+                * Increment semaphore to indicate that an update was
+                * already done.
+                */
+@@ -3667,11 +3513,26 @@
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
+-                              GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
+-                              GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
+                               GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
+-              break;
++
++
++                      /*
++                      * In some cases the runt and fcs counters are incremented when collisions
++                      * occur. We have to correct those counters here.
++                      */
++                      Val64RxRunt = GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex);
++                      Val64RxFcs = GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex);
++
++                      if (Val64RxRunt > Val64RxFcs) {
++                              Val64RxRunt -= Val64RxFcs;
++                              Val64RxHwErrs += Val64RxRunt;
++                      }
++                      else {
++                              Val64RxFcs -= Val64RxRunt;
++                              Val64RxHwErrs += Val64RxFcs;
++                      }
++                      break;
+               case OID_SKGE_TX_HW_ERROR_CTS:
+               case OID_SKGE_OUT_ERROR_CTS:
+@@ -3685,9 +3546,7 @@
+               }
+       }
+-      /*
+-       * Retrieve value
+-       */
++      /* Retrieve value. */
+       switch (Id) {
+       case OID_SKGE_SUPPORTED_LIST:
+@@ -3697,11 +3556,11 @@
+                       *pLen = Len;
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+-              for (Offset = 0, Index = 0; Offset < Len;
+-                      Offset += sizeof(SK_U32), Index ++) {
++              for (Offset = 0, Index = 0; Offset < Len; Index ++) {
+                       Val32 = (SK_U32)IdTable[Index].Id;
+                       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
++                      Offset += sizeof(SK_U32);
+               }
+               *pLen = Len;
+               break;
+@@ -3727,8 +3586,7 @@
+       case OID_SKGE_DRIVER_DESCR:
+               if (pAC->Pnmi.pDriverDescription == NULL) {
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
+-                              SK_PNMI_ERR007MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007, SK_PNMI_ERR007MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -3737,8 +3595,7 @@
+               Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
+               if (Len > SK_PNMI_STRINGLEN1) {
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
+-                              SK_PNMI_ERR029MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029, SK_PNMI_ERR029MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -3757,8 +3614,7 @@
+       case OID_SKGE_DRIVER_VERSION:
+               if (pAC->Pnmi.pDriverVersion == NULL) {
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
+-                              SK_PNMI_ERR030MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, SK_PNMI_ERR030MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -3767,8 +3623,7 @@
+               Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
+               if (Len > SK_PNMI_STRINGLEN1) {
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
+-                              SK_PNMI_ERR031MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, SK_PNMI_ERR031MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -3787,8 +3642,7 @@
+       case OID_SKGE_DRIVER_RELDATE:
+               if (pAC->Pnmi.pDriverReleaseDate == NULL) {
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
+-                              SK_PNMI_ERR053MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR053, SK_PNMI_ERR053MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -3797,8 +3651,7 @@
+               Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
+               if (Len > SK_PNMI_STRINGLEN1) {
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
+-                              SK_PNMI_ERR054MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR054, SK_PNMI_ERR054MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -3817,8 +3670,7 @@
+       case OID_SKGE_DRIVER_FILENAME:
+               if (pAC->Pnmi.pDriverFileName == NULL) {
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
+-                              SK_PNMI_ERR055MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR055, SK_PNMI_ERR055MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -3827,8 +3679,7 @@
+               Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
+               if (Len > SK_PNMI_STRINGLEN1) {
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
+-                              SK_PNMI_ERR056MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR056, SK_PNMI_ERR056MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -3854,8 +3705,7 @@
+               Len = 256;
+               if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
+-                              SK_PNMI_ERR032MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032, SK_PNMI_ERR032MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -3863,8 +3713,7 @@
+               Len ++;
+               if (Len > SK_PNMI_STRINGLEN1) {
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
+-                              SK_PNMI_ERR033MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033, SK_PNMI_ERR033MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -3880,7 +3729,6 @@
+               break;
+       case OID_SKGE_HW_VERSION:
+-              /* Oh, I love to do some string manipulation */
+               if (*pLen < 5) {
+                       *pLen = 5;
+@@ -3889,9 +3737,9 @@
+               Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
+               pBuf[0] = 4;
+               pBuf[1] = 'v';
+-              pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
++              pBuf[2] = (char)('0' | ((Val8 >> 4) & 0x0f));
+               pBuf[3] = '.';
+-              pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
++              pBuf[4] = (char)('0' | (Val8 & 0x0f));
+               *pLen = 5;
+               break;
+@@ -3914,12 +3762,12 @@
+               break;
+       case OID_SKGE_VAUXAVAIL:
+-              *pBuf = (char) pAC->GIni.GIVauxAvail;
++              *pBuf = (char)pAC->GIni.GIVauxAvail;
+               *pLen = sizeof(char);
+               break;
+       case OID_SKGE_BUS_TYPE:
+-              *pBuf = (char) SK_PNMI_BUS_PCI;
++              *pBuf = (char)SK_PNMI_BUS_PCI;
+               *pLen = sizeof(char);
+               break;
+@@ -3968,31 +3816,31 @@
+               break;
+       case OID_SKGE_RLMT_MONITOR_NUMBER:
+-/* XXX Not yet implemented by RLMT therefore we return zero elements */
++              /* Not yet implemented by RLMT, therefore we return zero elements. */
+               Val32 = 0;
+               SK_PNMI_STORE_U32(pBuf, Val32);
+               *pLen = sizeof(SK_U32);
+               break;
+       case OID_SKGE_TX_SW_QUEUE_LEN:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
+                                       pAC->Pnmi.BufPort[1].TxSwQueueLen;
+                       }                       
+               }
+               else {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
+                                       pAC->Pnmi.Port[1].TxSwQueueLen;
+@@ -4004,24 +3852,24 @@
+       case OID_SKGE_TX_SW_QUEUE_MAX:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
+                                       pAC->Pnmi.BufPort[1].TxSwQueueMax;
+                       }
+               }
+               else {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
+                                       pAC->Pnmi.Port[1].TxSwQueueMax;
+@@ -4032,24 +3880,24 @@
+               break;
+       case OID_SKGE_TX_RETRY:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
+                                       pAC->Pnmi.BufPort[1].TxRetryCts;
+                       }
+               }
+               else {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].TxRetryCts +
+                                       pAC->Pnmi.Port[1].TxRetryCts;
+@@ -4060,24 +3908,24 @@
+               break;
+       case OID_SKGE_RX_INTR_CTS:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
+                                       pAC->Pnmi.BufPort[1].RxIntrCts;
+                       }
+               }
+               else {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].RxIntrCts +
+                                       pAC->Pnmi.Port[1].RxIntrCts;
+@@ -4088,24 +3936,24 @@
+               break;
+       case OID_SKGE_TX_INTR_CTS:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
+                                       pAC->Pnmi.BufPort[1].TxIntrCts;
+                       }
+               }
+               else {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].TxIntrCts +
+                                       pAC->Pnmi.Port[1].TxIntrCts;
+@@ -4116,24 +3964,24 @@
+               break;
+       case OID_SKGE_RX_NO_BUF_CTS:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
+                                       pAC->Pnmi.BufPort[1].RxNoBufCts;
+                       }
+               }
+               else {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
+                                       pAC->Pnmi.Port[1].RxNoBufCts;
+@@ -4144,24 +3992,24 @@
+               break;
+       case OID_SKGE_TX_NO_BUF_CTS:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
+                                       pAC->Pnmi.BufPort[1].TxNoBufCts;
+                       }
+               }
+               else {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
+                                       pAC->Pnmi.Port[1].TxNoBufCts;
+@@ -4172,24 +4020,24 @@
+               break;
+       case OID_SKGE_TX_USED_DESCR_NO:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
+                                       pAC->Pnmi.BufPort[1].TxUsedDescrNo;
+                       }
+               }
+               else {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
+                                       pAC->Pnmi.Port[1].TxUsedDescrNo;
+@@ -4200,24 +4048,24 @@
+               break;
+       case OID_SKGE_RX_DELIVERED_CTS:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
+                                       pAC->Pnmi.BufPort[1].RxDeliveredCts;
+                       }
+               }
+               else {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
+                                       pAC->Pnmi.Port[1].RxDeliveredCts;
+@@ -4228,24 +4076,24 @@
+               break;
+       case OID_SKGE_RX_OCTETS_DELIV_CTS:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
+                                       pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
+                       }
+               }
+               else {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
+                                       pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
+@@ -4266,13 +4114,13 @@
+               break;
+       case OID_SKGE_IN_ERRORS_CTS:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = Val64RxHwErrs +
+                                       pAC->Pnmi.BufPort[0].RxNoBufCts +
+@@ -4280,11 +4128,11 @@
+                       }
+               }
+               else {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = Val64RxHwErrs +
+                                       pAC->Pnmi.Port[0].RxNoBufCts +
+@@ -4296,13 +4144,13 @@
+               break;
+       case OID_SKGE_OUT_ERROR_CTS:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = Val64TxHwErrs +
+                                       pAC->Pnmi.BufPort[0].TxNoBufCts +
+@@ -4310,11 +4158,11 @@
+                       }
+               }
+               else {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = Val64TxHwErrs +
+                                       pAC->Pnmi.Port[0].TxNoBufCts +
+@@ -4326,24 +4174,24 @@
+               break;
+       case OID_SKGE_ERR_RECOVERY_CTS:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
+                                       pAC->Pnmi.BufPort[1].ErrRecoveryCts;
+                       }
+               }
+               else {
+-                      /* Dual net mode */
++                      /* DualNet mode. */
+                       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                               Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
+                       }
+-                      /* Single net mode */
++                      /* SingleNet mode. */
+                       else {
+                               Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
+                                       pAC->Pnmi.Port[1].ErrRecoveryCts;
+@@ -4367,7 +4215,7 @@
+               break;
+       case OID_GEN_RCV_ERROR:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+                       Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
+               }
+@@ -4376,7 +4224,7 @@
+               }
+               /*
+-               * by default 32bit values are evaluated
++               * By default 32bit values are evaluated.
+                */
+               if (!Is64BitReq) {
+                       Val32 = (SK_U32)Val64;
+@@ -4390,7 +4238,7 @@
+               break;
+       case OID_GEN_XMIT_ERROR:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+                       Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
+               }
+@@ -4399,7 +4247,7 @@
+               }
+               /*
+-               * by default 32bit values are evaluated
++               * By default 32bit values are evaluated.
+                */
+               if (!Is64BitReq) {
+                       Val32 = (SK_U32)Val64;
+@@ -4413,16 +4261,19 @@
+               break;
+       case OID_GEN_RCV_NO_BUFFER:
+-              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++              /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+               if (MacType == SK_MAC_XMAC) {
+-                      Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
++                      Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts + 
++                              GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex);
++
+               }
+               else {
+-                      Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
++                      Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts +
++                              GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex);
+               }
+               /*
+-               * by default 32bit values are evaluated
++               * By default 32bit values are evaluated.
+                */
+               if (!Is64BitReq) {
+                       Val32 = (SK_U32)Val64;
+@@ -4442,8 +4293,7 @@
+               break;
+       default:
+-              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
+-                      SK_PNMI_ERR034MSG);
++              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034, SK_PNMI_ERR034MSG);
+               *pLen = 0;
+               return (SK_PNMI_ERR_GENERAL);
+@@ -4500,25 +4350,17 @@
+       SK_U32          Val32;
+       SK_U64          Val64;
+-
+-      /*
+-       * Check instance. Only single instance OIDs are allowed here.
+-       */
++      /* Check instance. Only single instance OIDs are allowed here. */
+       if (Instance != (SK_U32)(-1) && Instance != 1) {
+               *pLen = 0;
+               return (SK_PNMI_ERR_UNKNOWN_INST);
+       }
+-      /*
+-       * Perform the requested action.
+-       */
++      /* Perform the requested action. */
+       if (Action == SK_PNMI_GET) {
+-              /*
+-               * Check if the buffer length is large enough.
+-               */
+-
++              /* Check if the buffer length is large enough. */
+               switch (Id) {
+               case OID_SKGE_RLMT_MODE:
+@@ -4551,8 +4393,7 @@
+                       break;
+               default:
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
+-                              SK_PNMI_ERR035MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035, SK_PNMI_ERR035MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -4571,9 +4412,7 @@
+               }
+               pAC->Pnmi.RlmtUpdatedFlag ++;
+-              /*
+-               * Retrieve Value
+-              */
++              /* Retrieve value. */
+               switch (Id) {
+               case OID_SKGE_RLMT_MODE:
+@@ -4651,17 +4490,17 @@
+               pAC->Pnmi.RlmtUpdatedFlag --;
+       }
+       else {
+-              /* Perform a preset or set */
++              /* Perform a PRESET or SET. */
+               switch (Id) {
+               case OID_SKGE_RLMT_MODE:
+-                      /* Check if the buffer length is plausible */
++                      /* Check if the buffer length is plausible. */
+                       if (*pLen < sizeof(char)) {
+                               *pLen = sizeof(char);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+-                      /* Check if the value range is correct */
++                      /* Check if the value range is correct. */
+                       if (*pLen != sizeof(char) ||
+                               (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
+                               *(SK_U8 *)pBuf > 15) {
+@@ -4669,21 +4508,21 @@
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+-                      /* The preset ends here */
++                      /* The PRESET ends here. */
+                       if (Action == SK_PNMI_PRESET) {
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_OK);
+                       }
+-                      /* Send an event to RLMT to change the mode */
++                      /* Send an event to RLMT to change the mode. */
+                       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
++                      
+                       EventParam.Para32[0] |= (SK_U32)(*pBuf);
+                       EventParam.Para32[1] = 0;
+                       if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
+                               EventParam) > 0) {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
+-                                      SK_PNMI_ERR037MSG);
++                              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037, SK_PNMI_ERR037MSG);
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+@@ -4691,20 +4530,25 @@
+                       break;
+               case OID_SKGE_RLMT_PORT_PREFERRED:
+-                      /* Check if the buffer length is plausible */
++                      /* PRESET/SET action makes no sense in Dual Net mode. */
++                      if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
++                              break;
++                      }
++                      
++                      /* Check if the buffer length is plausible. */
+                       if (*pLen < sizeof(char)) {
+                               *pLen = sizeof(char);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+-                      /* Check if the value range is correct */
++                      /* Check if the value range is correct. */
+                       if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
+                               (SK_U8)pAC->GIni.GIMacsFound) {
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+-                      /* The preset ends here */
++                      /* The PRESET ends here. */
+                       if (Action == SK_PNMI_PRESET) {
+                               *pLen = 0;
+@@ -4717,13 +4561,13 @@
+                        * make the decision which is the preferred port.
+                        */
+                       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
++                      
+                       EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
+                       EventParam.Para32[1] = NetIndex;
+                       if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
+                               EventParam) > 0) {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
+-                                      SK_PNMI_ERR038MSG);
++                              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038, SK_PNMI_ERR038MSG);
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+@@ -4731,22 +4575,20 @@
+                       break;
+               case OID_SKGE_RLMT_CHANGE_THRES:
+-                      /* Check if the buffer length is plausible */
++                      /* Check if the buffer length is plausible. */
+                       if (*pLen < sizeof(SK_U64)) {
+                               *pLen = sizeof(SK_U64);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+-                      /*
+-                       * There are not many restrictions to the
+-                       * value range.
+-                       */
++                      
++                      /* There are not many restrictions to the value range. */
+                       if (*pLen != sizeof(SK_U64)) {
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+-                      /* A preset ends here */
++                      /* The PRESET ends here. */
+                       if (Action == SK_PNMI_PRESET) {
+                               *pLen = 0;
+@@ -4761,7 +4603,7 @@
+                       break;
+               default:
+-                      /* The other OIDs are not be able for set */
++                      /* The other OIDs are not be able for set. */
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_READ_ONLY);
+               }
+@@ -4806,54 +4648,49 @@
+       SK_U32          Val32;
+       SK_U64          Val64;
+-      /*
+-       * Calculate the port indexes from the instance.
+-       */
++
++      /* Calculate the port indexes from the instance. */
+       PhysPortMax = pAC->GIni.GIMacsFound;
+       if ((Instance != (SK_U32)(-1))) {
+-              /* Check instance range */
++              /* Check instance range. */
+               if ((Instance < 1) || (Instance > PhysPortMax)) {
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_UNKNOWN_INST);
+               }
+-              /* Single net mode */
++              /* SingleNet mode. */
+               PhysPortIndex = Instance - 1;
+-              /* Dual net mode */
++              /* DualNet mode. */
+               if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                       PhysPortIndex = NetIndex;
+               }
+-              /* Both net modes */
++              /* Both net modes. */
+               Limit = PhysPortIndex + 1;
+       }
+       else {
+-              /* Single net mode */
++              /* SingleNet mode. */
+               PhysPortIndex = 0;
+               Limit = PhysPortMax;
+-              /* Dual net mode */
++              /* DualNet mode. */
+               if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                       PhysPortIndex = NetIndex;
+                       Limit = PhysPortIndex + 1;
+               }
+       }
+-      /*
+-       * Currently only get requests are allowed.
+-       */
++      /* Currently only GET requests are allowed. */
+       if (Action != SK_PNMI_GET) {
+               *pLen = 0;
+               return (SK_PNMI_ERR_READ_ONLY);
+       }
+-      /*
+-       * Check if the buffer length is large enough.
+-       */
++      /* Check if the buffer length is large enough. */
+       switch (Id) {
+       case OID_SKGE_RLMT_PORT_INDEX:
+@@ -4877,8 +4714,7 @@
+               break;
+       default:
+-              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
+-                      SK_PNMI_ERR039MSG);
++              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039, SK_PNMI_ERR039MSG);
+               *pLen = 0;
+               return (SK_PNMI_ERR_GENERAL);
+@@ -4896,9 +4732,7 @@
+       }
+       pAC->Pnmi.RlmtUpdatedFlag ++;
+-      /*
+-       * Get value
+-       */
++      /* Get value. */
+       Offset = 0;
+       for (; PhysPortIndex < Limit; PhysPortIndex ++) {
+@@ -5011,19 +4845,21 @@
+       int                     Ret;
+       SK_EVPARA       EventParam;
+       SK_U32          Val32;
++#ifdef SK_PHY_LP_MODE
++      SK_U8   CurrentPhyPowerState;
++#endif /* SK_PHY_LP_MODE */
+-      /*
+-       * Calculate instance if wished. MAC index 0 is the virtual MAC.
+-       */
++
++      /* Calculate instance if wished. MAC index 0 is the virtual MAC. */
+       PhysPortMax = pAC->GIni.GIMacsFound;
+       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
+-      if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
++      if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* DualNet mode. */
+               LogPortMax--;
+       }
+-      if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
+-              /* Check instance range */
++      if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried. */
++              /* Check instance range. */
+               if ((Instance < 1) || (Instance > LogPortMax)) {
+                       *pLen = 0;
+@@ -5033,18 +4869,16 @@
+               Limit = LogPortIndex + 1;
+       }
+-      else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
++      else { /* Instance == (SK_U32)(-1), get all Instances of that OID. */
+               LogPortIndex = 0;
+               Limit = LogPortMax;
+       }
+-      /*
+-       * Perform action
+-       */
++      /* Perform action. */
+       if (Action == SK_PNMI_GET) {
+-              /* Check length */
++              /* Check length. */
+               switch (Id) {
+               case OID_SKGE_PMD:
+@@ -5082,8 +4916,7 @@
+                       break;
+               default:
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
+-                              SK_PNMI_ERR041MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041, SK_PNMI_ERR041MSG);
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+@@ -5099,9 +4932,7 @@
+               }
+               pAC->Pnmi.SirqUpdatedFlag ++;
+-              /*
+-               * Get value
+-               */
++              /* Get value. */
+               Offset = 0;
+               for (; LogPortIndex < Limit; LogPortIndex ++) {
+@@ -5111,107 +4942,99 @@
+                       case OID_SKGE_PMD:
+                               *pBufPtr = pAC->Pnmi.PMD;
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       case OID_SKGE_CONNECTOR:
+                               *pBufPtr = pAC->Pnmi.Connector;
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       case OID_SKGE_PHY_TYPE:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                                       if (LogPortIndex == 0) {
+                                               continue;
+                                       }
+-                                      else {
+-                                              /* Get value for physical ports */
+-                                              PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+-                                                      pAC, LogPortIndex);
+-                                              Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
+-                                              SK_PNMI_STORE_U32(pBufPtr, Val32);
+-                                      }
++                                      /* Get value for physical port. */
++                                      PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
++                                      Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
+                               }
+-                              else { /* DualNetMode */
++                              else { /* DualNet mode. */
+                                       
+                                       Val32 = pAC->GIni.GP[NetIndex].PhyType;
+-                                      SK_PNMI_STORE_U32(pBufPtr, Val32);
+                               }
++                              SK_PNMI_STORE_U32(pBufPtr, Val32);
+                               Offset += sizeof(SK_U32);
+                               break;
+ #ifdef SK_PHY_LP_MODE
+                       case OID_SKGE_PHY_LP_MODE:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                                       if (LogPortIndex == 0) {
+                                               continue;
+                                       }
+-                                      else {
+-                                              /* Get value for physical ports */
+-                                              PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
+-                                              Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
+-                                              *pBufPtr = Val8;
+-                                      }
++                                      /* Get value for physical port. */
++                                      PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
++                                      *pBufPtr = (SK_U8)pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
+                               }
+-                              else { /* DualNetMode */
++                              else { /* DualNet mode. */
+                                       
+-                                      Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
+-                                      *pBufPtr = Val8;
++                                      *pBufPtr = (SK_U8)pAC->GIni.GP[NetIndex].PPhyPowerState;
+                               }
+                               Offset += sizeof(SK_U8);
+                               break;
+ #endif
+                       case OID_SKGE_LINK_CAP:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                                       if (LogPortIndex == 0) {
+-                                              /* Get value for virtual port */
++                                              /* Get value for virtual port. */
+                                               VirtualConf(pAC, IoC, Id, pBufPtr);
+                                       }
+                                       else {
+-                                              /* Get value for physical ports */
++                                              /* Get value for physical port. */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
+                                       }
+                               }
+-                              else { /* DualNetMode */
++                              else { /* DualNet mode. */
+                                       
+                                       *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
+                               }
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       case OID_SKGE_LINK_MODE:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                                       if (LogPortIndex == 0) {
+-                                              /* Get value for virtual port */
++                                              /* Get value for virtual port. */
+                                               VirtualConf(pAC, IoC, Id, pBufPtr);
+                                       }
+                                       else {
+-                                              /* Get value for physical ports */
++                                              /* Get value for physical port. */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
+                                       }
+                               }
+-                              else { /* DualNetMode */
++                              else { /* DualNet mode. */
+                               
+                                       *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
+                               }
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       case OID_SKGE_LINK_MODE_STATUS:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                                       if (LogPortIndex == 0) {
+-                                              /* Get value for virtual port */
++                                              /* Get value for virtual port. */
+                                               VirtualConf(pAC, IoC, Id, pBufPtr);
+                                       }
+                                       else {
+-                                              /* Get value for physical port */
++                                              /* Get value for physical port. */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+@@ -5219,147 +5042,147 @@
+                                                       CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
+                                       }
+                               }
+-                              else { /* DualNetMode */
++                              else { /* DualNet mode. */
+                                       
+                                       *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
+                               }
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       case OID_SKGE_LINK_STATUS:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                                       if (LogPortIndex == 0) {
+-                                              /* Get value for virtual port */
++                                              /* Get value for virtual port. */
+                                               VirtualConf(pAC, IoC, Id, pBufPtr);
+                                       }
+                                       else {
+-                                              /* Get value for physical ports */
++                                              /* Get value for physical port. */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+       
+                                               *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
+                                       }
+                               }
+-                              else { /* DualNetMode */
++                              else { /* DualNet mode. */
+                                       *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
+                               }
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       case OID_SKGE_FLOWCTRL_CAP:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                                       if (LogPortIndex == 0) {
+-                                              /* Get value for virtual port */
++                                              /* Get value for virtual port. */
+                                               VirtualConf(pAC, IoC, Id, pBufPtr);
+                                       }
+                                       else {
+-                                              /* Get value for physical ports */
++                                              /* Get value for physical port. */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+       
+                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
+                                       }
+                               }
+-                              else { /* DualNetMode */
++                              else { /* DualNet mode. */
+                               
+                                       *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
+                               }
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       case OID_SKGE_FLOWCTRL_MODE:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                                       if (LogPortIndex == 0) {
+-                                              /* Get value for virtual port */
++                                              /* Get value for virtual port. */
+                                               VirtualConf(pAC, IoC, Id, pBufPtr);
+                                       }
+                                       else {
+-                                              /* Get value for physical port */
++                                              /* Get value for physical port. */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+       
+                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
+                                       }
+                               }
+-                              else { /* DualNetMode */
++                              else { /* DualNet mode. */
+                                       *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
+                               }
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       case OID_SKGE_FLOWCTRL_STATUS:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                                       if (LogPortIndex == 0) {
+-                                              /* Get value for virtual port */
++                                              /* Get value for virtual port. */
+                                               VirtualConf(pAC, IoC, Id, pBufPtr);
+                                       }
+                                       else {
+-                                              /* Get value for physical port */
++                                              /* Get value for physical port. */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+       
+                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
+                                       }
+                               }
+-                              else { /* DualNetMode */
++                              else { /* DualNet mode. */
+                                       *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
+                               }
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       case OID_SKGE_PHY_OPERATION_CAP:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet Mode. */
+                                       if (LogPortIndex == 0) {
+-                                              /* Get value for virtual port */
++                                              /* Get value for virtual port. */
+                                               VirtualConf(pAC, IoC, Id, pBufPtr);
+                                       }
+                                       else {
+-                                              /* Get value for physical ports */
++                                              /* Get value for physical port. */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+       
+                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
+                                       }
+                               }
+-                              else { /* DualNetMode */
++                              else { /* DualNet mode. */
+                               
+                                       *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
+                               }
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       case OID_SKGE_PHY_OPERATION_MODE:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                                       if (LogPortIndex == 0) {
+-                                              /* Get value for virtual port */
++                                              /* Get value for virtual port. */
+                                               VirtualConf(pAC, IoC, Id, pBufPtr);
+                                       }
+                                       else {
+-                                              /* Get value for physical port */
++                                              /* Get value for physical port. */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
+                                       }
+                               }
+-                              else { /* DualNetMode */
++                              else { /* DualNet mode. */
+                               
+                                       *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
+                               }
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       case OID_SKGE_PHY_OPERATION_STATUS:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                                       if (LogPortIndex == 0) {
+-                                              /* Get value for virtual port */
++                                              /* Get value for virtual port. */
+                                               VirtualConf(pAC, IoC, Id, pBufPtr);
+                                       }
+                                       else {
+-                                              /* Get value for physical port */
++                                              /* Get value for physical port. */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+       
+@@ -5370,70 +5193,70 @@
+                               
+                                       *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
+                               }
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       case OID_SKGE_SPEED_CAP:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                                       if (LogPortIndex == 0) {
+-                                              /* Get value for virtual port */
++                                              /* Get value for virtual port. */
+                                               VirtualConf(pAC, IoC, Id, pBufPtr);
+                                       }
+                                       else {
+-                                              /* Get value for physical ports */
++                                              /* Get value for physical port. */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+       
+                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
+                                       }
+                               }
+-                              else { /* DualNetMode */
++                              else { /* DualNet mode. */
+                               
+                                       *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
+                               }
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       case OID_SKGE_SPEED_MODE:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                                       if (LogPortIndex == 0) {
+-                                              /* Get value for virtual port */
++                                              /* Get value for virtual port. */
+                                               VirtualConf(pAC, IoC, Id, pBufPtr);
+                                       }
+                                       else {
+-                                              /* Get value for physical port */
++                                              /* Get value for physical port. */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+       
+                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
+                                       }
+                               }
+-                              else { /* DualNetMode */
++                              else { /* DualNet mode. */
+                                       *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
+                               }
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       case OID_SKGE_SPEED_STATUS:
+-                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                                       if (LogPortIndex == 0) {
+-                                              /* Get value for virtual port */
++                                              /* Get value for virtual port. */
+                                               VirtualConf(pAC, IoC, Id, pBufPtr);
+                                       }
+                                       else {
+-                                              /* Get value for physical port */
++                                              /* Get value for physical port. */
+                                               PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+                                                       pAC, LogPortIndex);
+       
+                                               *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
+                                       }
+                               }
+-                              else { /* DualNetMode */
++                              else { /* DualNet mode. */
+                                       *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
+                               }
+-                              Offset += sizeof(char);
++                              Offset ++;
+                               break;
+                       
+                       case OID_SKGE_MTU:
+@@ -5486,40 +5309,33 @@
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               break;
+-#endif
++#endif /* SK_PHY_LP_MODE */
+       case OID_SKGE_MTU:
+-              if (*pLen < sizeof(SK_U32)) {
++              if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
+-                      *pLen = sizeof(SK_U32);
++                      *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+-              if (*pLen != sizeof(SK_U32)) {
+-
+-                      *pLen = 0;
+-                      return (SK_PNMI_ERR_BAD_VALUE);
+-              }
+               break;
+-
++      
+     default:
+               *pLen = 0;
+               return (SK_PNMI_ERR_READ_ONLY);
+       }
+-      /*
+-       * Perform preset or set
+-       */
++      /* Perform PRESET or SET. */
+       Offset = 0;
+       for (; LogPortIndex < Limit; LogPortIndex ++) {
++              Val8 = *(pBuf + Offset);
++
+               switch (Id) {
+               case OID_SKGE_LINK_MODE:
+-                      /* Check the value range */
+-                      Val8 = *(pBuf + Offset);
++                      /* Check the value range. */
+                       if (Val8 == 0) {
+-
+-                              Offset += sizeof(char);
++                              Offset++;
+                               break;
+                       }
+                       if (Val8 < SK_LMODE_HALF ||
+@@ -5530,51 +5346,68 @@
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+-                      /* The preset ends here */
++                      /* The PRESET ends here. */
+                       if (Action == SK_PNMI_PRESET) {
+                               return (SK_PNMI_ERR_OK);
+                       }
+-                      if (LogPortIndex == 0) {
+-
+-                              /*
+-                               * The virtual port consists of all currently
+-                               * active ports. Find them and send an event
+-                               * with the new link mode to SIRQ.
+-                               */
+-                              for (PhysPortIndex = 0;
+-                                      PhysPortIndex < PhysPortMax;
+-                                      PhysPortIndex ++) {
+-
+-                                      if (!pAC->Pnmi.Port[PhysPortIndex].
+-                                              ActiveFlag) {
+-
+-                                              continue;
+-                                      }
++                      if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
++                              if (LogPortIndex == 0) {
++                                      /*
++                                       * The virtual port consists of all currently
++                                       * active ports. Find them and send an event
++                                       * with the new link mode to SIRQ.
++                                       */
++                                      for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
++                                              PhysPortIndex ++) {
+-                                      EventParam.Para32[0] = PhysPortIndex;
++                                              if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
++                                                      continue;
++                                              }
++                                              
++                                              EventParam.Para32[0] = PhysPortIndex;
++                                              EventParam.Para32[1] = (SK_U32)Val8;
++                                              if (SkGeSirqEvent(pAC, IoC,
++                                                      SK_HWEV_SET_LMODE,
++                                                      EventParam) > 0) {
++                                                      
++                                                      SK_ERR_LOG(pAC, SK_ERRCL_SW,
++                                                              SK_PNMI_ERR043,
++                                                              SK_PNMI_ERR043MSG);
++                                                      
++                                                      *pLen = 0;
++                                                      return (SK_PNMI_ERR_GENERAL);
++                                              }
++                                      } /* for */
++                              }
++                              else {
++                                      /*
++                                       * Send an event with the new link mode to
++                                       * the SIRQ module.
++                                       */
++                                      EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
++                                              pAC, LogPortIndex);
+                                       EventParam.Para32[1] = (SK_U32)Val8;
+-                                      if (SkGeSirqEvent(pAC, IoC,
+-                                              SK_HWEV_SET_LMODE,
++                                      if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
+                                               EventParam) > 0) {
+-
++                                              
+                                               SK_ERR_LOG(pAC, SK_ERRCL_SW,
+                                                       SK_PNMI_ERR043,
+                                                       SK_PNMI_ERR043MSG);
+-
++                                              
+                                               *pLen = 0;
+                                               return (SK_PNMI_ERR_GENERAL);
+                                       }
+                               }
+                       }
+-                      else {
++                      else { /* DualNet mode. */
++
+                               /*
+                                * Send an event with the new link mode to
+                                * the SIRQ module.
+                                */
+-                              EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
+-                                      pAC, LogPortIndex);
++                              EventParam.Para32[0] = NetIndex;
+                               EventParam.Para32[1] = (SK_U32)Val8;
+                               if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
+                                       EventParam) > 0) {
+@@ -5587,15 +5420,13 @@
+                                       return (SK_PNMI_ERR_GENERAL);
+                               }
+                       }
+-                      Offset += sizeof(char);
++                      Offset++;
+                       break;
+               case OID_SKGE_FLOWCTRL_MODE:
+-                      /* Check the value range */
+-                      Val8 = *(pBuf + Offset);
++                      /* Check the value range. */
+                       if (Val8 == 0) {
+-
+-                              Offset += sizeof(char);
++                              Offset++;
+                               break;
+                       }
+                       if (Val8 < SK_FLOW_MODE_NONE ||
+@@ -5606,30 +5437,48 @@
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+-                      /* The preset ends here */
++                      /* The PRESET ends here. */
+                       if (Action == SK_PNMI_PRESET) {
+                               return (SK_PNMI_ERR_OK);
+                       }
+-                      if (LogPortIndex == 0) {
++                      if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
++                              if (LogPortIndex == 0) {
++                                      /*
++                                       * The virtual port consists of all currently
++                                       * active ports. Find them and send an event
++                                       * with the new flow control mode to SIRQ.
++                                       */
++                                      for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
++                                              PhysPortIndex ++) {
+-                              /*
+-                               * The virtual port consists of all currently
+-                               * active ports. Find them and send an event
+-                               * with the new flow control mode to SIRQ.
+-                               */
+-                              for (PhysPortIndex = 0;
+-                                      PhysPortIndex < PhysPortMax;
+-                                      PhysPortIndex ++) {
++                                              if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
++                                                      continue;
++                                              }
+-                                      if (!pAC->Pnmi.Port[PhysPortIndex].
+-                                              ActiveFlag) {
++                                              EventParam.Para32[0] = PhysPortIndex;
++                                              EventParam.Para32[1] = (SK_U32)Val8;
++                                              if (SkGeSirqEvent(pAC, IoC,
++                                                      SK_HWEV_SET_FLOWMODE,
++                                                      EventParam) > 0) {
++
++                                                      SK_ERR_LOG(pAC, SK_ERRCL_SW,
++                                                              SK_PNMI_ERR044,
++                                                              SK_PNMI_ERR044MSG);
+-                                              continue;
++                                                      *pLen = 0;
++                                                      return (SK_PNMI_ERR_GENERAL);
++                                              }
+                                       }
+-
+-                                      EventParam.Para32[0] = PhysPortIndex;
++                              }
++                              else {
++                                      /*
++                                       * Send an event with the new flow control
++                                       * mode to the SIRQ module.
++                                       */
++                                      EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
++                                              pAC, LogPortIndex);
+                                       EventParam.Para32[1] = (SK_U32)Val8;
+                                       if (SkGeSirqEvent(pAC, IoC,
+                                               SK_HWEV_SET_FLOWMODE,
+@@ -5644,17 +5493,16 @@
+                                       }
+                               }
+                       }
+-                      else {
++                      else { /* DualNet mode. */
++                              
+                               /*
+-                               * Send an event with the new flow control
+-                               * mode to the SIRQ module.
++                               * Send an event with the new link mode to
++                               * the SIRQ module.
+                                */
+-                              EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
+-                                      pAC, LogPortIndex);
++                              EventParam.Para32[0] = NetIndex;
+                               EventParam.Para32[1] = (SK_U32)Val8;
+-                              if (SkGeSirqEvent(pAC, IoC,
+-                                      SK_HWEV_SET_FLOWMODE, EventParam)
+-                                      > 0) {
++                              if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_FLOWMODE,
++                                      EventParam) > 0) {
+                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
+                                               SK_PNMI_ERR044,
+@@ -5664,15 +5512,14 @@
+                                       return (SK_PNMI_ERR_GENERAL);
+                               }
+                       }
+-                      Offset += sizeof(char);
++                      Offset++;
+                       break;
+               case OID_SKGE_PHY_OPERATION_MODE :
+-                      /* Check the value range */
+-                      Val8 = *(pBuf + Offset);
++                      /* Check the value range. */
+                       if (Val8 == 0) {
+-                              /* mode of this port remains unchanged */
+-                              Offset += sizeof(char);
++                              /* Mode of this port remains unchanged. */
++                              Offset++;
+                               break;
+                       }
+                       if (Val8 < SK_MS_MODE_AUTO ||
+@@ -5683,34 +5530,51 @@
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+-                      /* The preset ends here */
++                      /* The PRESET ends here. */
+                       if (Action == SK_PNMI_PRESET) {
+                               return (SK_PNMI_ERR_OK);
+                       }
+-                      if (LogPortIndex == 0) {
++                      if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
++                              if (LogPortIndex == 0) {
++                                      /*
++                                       * The virtual port consists of all currently
++                                       * active ports. Find them and send an event
++                                       * with new master/slave (role) mode to SIRQ.
++                                       */
++                                      for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
++                                              PhysPortIndex ++) {
+-                              /*
+-                               * The virtual port consists of all currently
+-                               * active ports. Find them and send an event
+-                               * with new master/slave (role) mode to SIRQ.
+-                               */
+-                              for (PhysPortIndex = 0;
+-                                      PhysPortIndex < PhysPortMax;
+-                                      PhysPortIndex ++) {
++                                              if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
++                                                      continue;
++                                              }
+-                                      if (!pAC->Pnmi.Port[PhysPortIndex].
+-                                              ActiveFlag) {
++                                              EventParam.Para32[0] = PhysPortIndex;
++                                              EventParam.Para32[1] = (SK_U32)Val8;
++                                              if (SkGeSirqEvent(pAC, IoC,
++                                                      SK_HWEV_SET_ROLE,
++                                                      EventParam) > 0) {
++
++                                                      SK_ERR_LOG(pAC, SK_ERRCL_SW,
++                                                              SK_PNMI_ERR042,
++                                                              SK_PNMI_ERR042MSG);
+-                                              continue;
++                                                      *pLen = 0;
++                                                      return (SK_PNMI_ERR_GENERAL);
++                                              }
+                                       }
+-
+-                                      EventParam.Para32[0] = PhysPortIndex;
++                              }
++                              else {
++                                      /*
++                                       * Send an event with the new master/slave
++                                       * (role) mode to the SIRQ module.
++                                       */
++                                      EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
++                                              pAC, LogPortIndex);
+                                       EventParam.Para32[1] = (SK_U32)Val8;
+                                       if (SkGeSirqEvent(pAC, IoC,
+-                                              SK_HWEV_SET_ROLE,
+-                                              EventParam) > 0) {
++                                              SK_HWEV_SET_ROLE, EventParam) > 0) {
+                                               SK_ERR_LOG(pAC, SK_ERRCL_SW,
+                                                       SK_PNMI_ERR042,
+@@ -5721,16 +5585,16 @@
+                                       }
+                               }
+                       }
+-                      else {
++                      else { /* DualNet mode. */
++
+                               /*
+-                               * Send an event with the new master/slave
+-                               * (role) mode to the SIRQ module.
++                               * Send an event with the new link mode to
++                               * the SIRQ module.
+                                */
+-                              EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
+-                                      pAC, LogPortIndex);
++                              EventParam.Para32[0] = NetIndex;
+                               EventParam.Para32[1] = (SK_U32)Val8;
+-                              if (SkGeSirqEvent(pAC, IoC,
+-                                      SK_HWEV_SET_ROLE, EventParam) > 0) {
++                              if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_ROLE,
++                                      EventParam) > 0) {
+                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
+                                               SK_PNMI_ERR042,
+@@ -5740,16 +5604,13 @@
+                                       return (SK_PNMI_ERR_GENERAL);
+                               }
+                       }
+-
+-                      Offset += sizeof(char);
++                      Offset++;
+                       break;
+               case OID_SKGE_SPEED_MODE:
+-                      /* Check the value range */
+-                      Val8 = *(pBuf + Offset);
++                      /* Check the value range. */
+                       if (Val8 == 0) {
+-
+-                              Offset += sizeof(char);
++                              Offset++;
+                               break;
+                       }
+                       if (Val8 < (SK_LSPEED_AUTO) ||
+@@ -5760,29 +5621,49 @@
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+-                      /* The preset ends here */
++                      /* The PRESET ends here. */
+                       if (Action == SK_PNMI_PRESET) {
+                               return (SK_PNMI_ERR_OK);
+                       }
+-                      if (LogPortIndex == 0) {
++                      if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
++                              if (LogPortIndex == 0) {
+-                              /*
+-                               * The virtual port consists of all currently
+-                               * active ports. Find them and send an event
+-                               * with the new flow control mode to SIRQ.
+-                               */
+-                              for (PhysPortIndex = 0;
+-                                      PhysPortIndex < PhysPortMax;
+-                                      PhysPortIndex ++) {
++                                      /*
++                                       * The virtual port consists of all currently
++                                       * active ports. Find them and send an event
++                                       * with the new flow control mode to SIRQ.
++                                       */
++                                      for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
++                                              PhysPortIndex ++) {
+-                                      if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
++                                              if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
++                                                      continue;
++                                              }
+-                                              continue;
+-                                      }
++                                              EventParam.Para32[0] = PhysPortIndex;
++                                              EventParam.Para32[1] = (SK_U32)Val8;
++                                              if (SkGeSirqEvent(pAC, IoC,
++                                                      SK_HWEV_SET_SPEED,
++                                                      EventParam) > 0) {
++
++                                                      SK_ERR_LOG(pAC, SK_ERRCL_SW,
++                                                              SK_PNMI_ERR045,
++                                                              SK_PNMI_ERR045MSG);
+-                                      EventParam.Para32[0] = PhysPortIndex;
++                                                      *pLen = 0;
++                                                      return (SK_PNMI_ERR_GENERAL);
++                                              }
++                                      }
++                              }
++                              else {
++                                      /*
++                                       * Send an event with the new flow control
++                                       * mode to the SIRQ module.
++                                       */
++                                      EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
++                                              pAC, LogPortIndex);
+                                       EventParam.Para32[1] = (SK_U32)Val8;
+                                       if (SkGeSirqEvent(pAC, IoC,
+                                               SK_HWEV_SET_SPEED,
+@@ -5797,16 +5678,15 @@
+                                       }
+                               }
+                       }
+-                      else {
++                      else { /* DualNet mode. */
++                              
+                               /*
+-                               * Send an event with the new flow control
+-                               * mode to the SIRQ module.
++                               * Send an event with the new link mode to
++                               * the SIRQ module.
+                                */
+-                              EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
+-                                      pAC, LogPortIndex);
++                              EventParam.Para32[0] = NetIndex;
+                               EventParam.Para32[1] = (SK_U32)Val8;
+-                              if (SkGeSirqEvent(pAC, IoC,
+-                                      SK_HWEV_SET_SPEED,
++                              if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_SPEED,
+                                       EventParam) > 0) {
+                                       SK_ERR_LOG(pAC, SK_ERRCL_SW,
+@@ -5817,23 +5697,25 @@
+                                       return (SK_PNMI_ERR_GENERAL);
+                               }
+                       }
+-                      Offset += sizeof(char);
++                      Offset++;
+                       break;
+-              case OID_SKGE_MTU :
+-                      /* Check the value range */
+-                      Val32 = *(SK_U32*)(pBuf + Offset);
++              case OID_SKGE_MTU:
++                      /* Check the value range. */
++                      SK_PNMI_READ_U32((pBuf + Offset), Val32);
++
+                       if (Val32 == 0) {
+-                              /* mtu of this port remains unchanged */
++                              /* MTU of this port remains unchanged. */
+                               Offset += sizeof(SK_U32);
+                               break;
+                       }
++
+                       if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+-                      /* The preset ends here */
++                      /* The PRESET ends here. */
+                       if (Action == SK_PNMI_PRESET) {
+                               return (SK_PNMI_ERR_OK);
+                       }
+@@ -5844,116 +5726,69 @@
+                       Offset += sizeof(SK_U32);
+                       break;
+-              
++
+ #ifdef SK_PHY_LP_MODE
+               case OID_SKGE_PHY_LP_MODE:
+-                      /* The preset ends here */
++                      /* The PRESET ends here. */
+                       if (Action == SK_PNMI_PRESET) {
+                               return (SK_PNMI_ERR_OK);
+                       }
+-                      if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                      if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */
+                               if (LogPortIndex == 0) {
+                                       Offset = 0;
+                                       continue;
+                               }
+-                              else {
+-                                      /* Set value for physical ports */
+-                                      PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
+-
+-                                      switch (*(pBuf + Offset)) {
+-                                              case 0:
+-                                                      /* If LowPowerMode is active, we can leave it. */
+-                                                      if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
+-
+-                                                              Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
+-                                                              
+-                                                              if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3)     {
+-                                                                      
+-                                                                      SkDrvInitAdapter(pAC);
+-                                                              }
+-                                                              break;
+-                                                      }
+-                                                      else {
+-                                                              *pLen = 0;
+-                                                              return (SK_PNMI_ERR_GENERAL);
+-                                                      }
+-                                              case 1:
+-                                              case 2:
+-                                              case 3:
+-                                              case 4:
+-                                                      /* If no LowPowerMode is active, we can enter it. */
+-                                                      if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
+-
+-                                                              if ((*(pBuf + Offset)) < 3)     {
+-                                                              
+-                                                                      SkDrvDeInitAdapter(pAC);
+-                                                              }
+-
+-                                                              Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
+-                                                              break;
+-                                                      }
+-                                                      else {
+-                                                              *pLen = 0;
+-                                                              return (SK_PNMI_ERR_GENERAL);
+-                                                      }
+-                                              default:
+-                                                      *pLen = 0;
+-                                                      return (SK_PNMI_ERR_BAD_VALUE);
+-                                      }
+-                              }
+                       }
+-                      else { /* DualNetMode */
+-                              
+-                              switch (*(pBuf + Offset)) {
+-                                      case 0:
+-                                              /* If we are in a LowPowerMode, we can leave it. */
+-                                              if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
++                      /* Set value for physical port. */
++                      PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
++                      CurrentPhyPowerState = pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
+-                                                      Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
+-                                                      
+-                                                      if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3)     {
++                      switch (Val8) {
++                              case PHY_PM_OPERATIONAL_MODE:
++                                      /* If LowPowerMode is active, we can leave it. */
++                                      if (CurrentPhyPowerState) {
+-                                                              SkDrvInitAdapter(pAC);
+-                                                      }
+-                                                      break;
+-                                              }
+-                                              else {
+-                                                      *pLen = 0;
+-                                                      return (SK_PNMI_ERR_GENERAL);
+-                                              }
+-                                      
+-                                      case 1:
+-                                      case 2:
+-                                      case 3:
+-                                      case 4:
+-                                              /* If we are not already in LowPowerMode, we can enter it. */
+-                                              if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
+-
+-                                                      if ((*(pBuf + Offset)) < 3)     {
+-
+-                                                              SkDrvDeInitAdapter(pAC);
+-                                                      }
+-                                                      else {
+-
+-                                                              Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
+-                                                      }
+-                                                      break;
+-                                              }
+-                                              else {
+-                                                      *pLen = 0;
+-                                                      return (SK_PNMI_ERR_GENERAL);
++                                              Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
++                                              
++                                              if ((CurrentPhyPowerState == PHY_PM_DEEP_SLEEP) ||
++                                                      (CurrentPhyPowerState == PHY_PM_IEEE_POWER_DOWN)) {
++                                                      
++                                                      SkDrvInitAdapter(pAC);
+                                               }
+-                                      
+-                                      default:
++                                              break;
++                                      }
++                                      else {
+                                               *pLen = 0;
+-                                              return (SK_PNMI_ERR_BAD_VALUE);
+-                              }
++                                              return (SK_PNMI_ERR_GENERAL);
++                                      }
++                              case PHY_PM_DEEP_SLEEP:
++                              case PHY_PM_IEEE_POWER_DOWN:
++                                      /* If no LowPowerMode is active, we can enter it. */
++                                      if (!CurrentPhyPowerState) {
++                                              SkDrvDeInitAdapter(pAC);
++                                      }
++
++                              case PHY_PM_ENERGY_DETECT:
++                              case PHY_PM_ENERGY_DETECT_PLUS:
++                                      /* If no LowPowerMode is active, we can enter it. */
++                                      if (!CurrentPhyPowerState) {
++
++                                              Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
++                                              break;
++                                      }
++                                      else {
++                                              *pLen = 0;
++                                              return (SK_PNMI_ERR_GENERAL);
++                                      }
++                              default:
++                                      *pLen = 0;
++                                      return (SK_PNMI_ERR_BAD_VALUE);
+                       }
+-                      Offset += sizeof(SK_U8);
++                      Offset++;
+                       break;
+-#endif
++#endif /* SK_PHY_LP_MODE */
+               default:
+             SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
+@@ -6003,14 +5838,11 @@
+       unsigned int    Limit;
+       unsigned int    Offset;
+       unsigned int    Entries;
+-
+       
+-      /*
+-       * Calculate instance if wished.
+-       */
+-      /* XXX Not yet implemented. Return always an empty table. */
++      /* Not implemented yet. Return always an empty table. */
+       Entries = 0;
++      /* Calculate instance if wished. */
+       if ((Instance != (SK_U32)(-1))) {
+               if ((Instance < 1) || (Instance > Entries)) {
+@@ -6027,12 +5859,10 @@
+               Limit = Entries;
+       }
+-      /*
+-       * Get/Set value
+-      */
++      /* GET/SET value. */
+       if (Action == SK_PNMI_GET) {
+-              for (Offset=0; Index < Limit; Index ++) {
++              for (Offset = 0; Index < Limit; Index ++) {
+                       switch (Id) {
+@@ -6054,32 +5884,29 @@
+               *pLen = Offset;
+       }
+       else {
+-              /* Only MONITOR_ADMIN can be set */
++              /* Only MONITOR_ADMIN can be set. */
+               if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_READ_ONLY);
+               }
+-              /* Check if the length is plausible */
++              /* Check if the length is plausible. */
+               if (*pLen < (Limit - Index)) {
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+-              /* Okay, we have a wide value range */
++              /* Okay, we have a wide value range. */
+               if (*pLen != (Limit - Index)) {
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_BAD_VALUE);
+               }
+-/*
+-              for (Offset=0; Index < Limit; Index ++) {
+-              }
+-*/
+-/*
+- * XXX Not yet implemented. Return always BAD_VALUE, because the table
+- * is empty.
+- */
++
++              /*
++               * Not yet implemented. Return always BAD_VALUE,
++               * because the table is empty.
++               */
+               *pLen = 0;
+               return (SK_PNMI_ERR_BAD_VALUE);
+       }
+@@ -6120,14 +5947,12 @@
+       PortActiveFlag = SK_FALSE;
+       PhysPortMax = pAC->GIni.GIMacsFound;
+       
+-      for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
+-              PhysPortIndex ++) {
++      for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; PhysPortIndex ++) {
+               pPrt = &pAC->GIni.GP[PhysPortIndex];
+-              /* Check if the physical port is active */
++              /* Check if the physical port is active. */
+               if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
+-
+                       continue;
+               }
+@@ -6136,12 +5961,13 @@
+               switch (Id) {
+               case OID_SKGE_PHY_TYPE:
+-                      /* Check if it is the first active port */
++                      /* Check if it is the first active port. */
+                       if (*pBuf == 0) {
+                               Val32 = pPrt->PhyType;
+                               SK_PNMI_STORE_U32(pBuf, Val32);
+                               continue;
+                       }
++                      break;
+               case OID_SKGE_LINK_CAP:
+@@ -6155,7 +5981,7 @@
+                       break;
+               case OID_SKGE_LINK_MODE:
+-                      /* Check if it is the first active port */
++                      /* Check if it is the first active port. */
+                       if (*pBuf == 0) {
+                               *pBuf = pPrt->PLinkModeConf;
+@@ -6163,9 +5989,8 @@
+                       }
+                       /*
+-                       * If we find an active port with a different link
+-                       * mode than the first one we return a value that
+-                       * indicates that the link mode is indeterminated.
++                       * If we find an active port with a different link mode
++                       * than the first one we return indeterminated.
+                        */
+                       if (*pBuf != pPrt->PLinkModeConf) {
+@@ -6174,10 +5999,10 @@
+                       break;
+               case OID_SKGE_LINK_MODE_STATUS:
+-                      /* Get the link mode of the physical port */
++                      /* Get the link mode of the physical port. */
+                       Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
+-                      /* Check if it is the first active port */
++                      /* Check if it is the first active port. */
+                       if (*pBuf == 0) {
+                               *pBuf = Val8;
+@@ -6185,10 +6010,8 @@
+                       }
+                       /*
+-                       * If we find an active port with a different link
+-                       * mode status than the first one we return a value
+-                       * that indicates that the link mode status is
+-                       * indeterminated.
++                       * If we find an active port with a different link mode status
++                       * than the first one we return indeterminated.
+                        */
+                       if (*pBuf != Val8) {
+@@ -6197,10 +6020,10 @@
+                       break;
+               case OID_SKGE_LINK_STATUS:
+-                      /* Get the link status of the physical port */
++                      /* Get the link status of the physical port. */
+                       Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
+-                      /* Check if it is the first active port */
++                      /* Check if it is the first active port. */
+                       if (*pBuf == 0) {
+                               *pBuf = Val8;
+@@ -6208,10 +6031,8 @@
+                       }
+                       /*
+-                       * If we find an active port with a different link
+-                       * status than the first one, we return a value
+-                       * that indicates that the link status is
+-                       * indeterminated.
++                       * If we find an active port with a different link status
++                       * than the first one we return indeterminated.
+                        */
+                       if (*pBuf != Val8) {
+@@ -6220,7 +6041,7 @@
+                       break;
+               case OID_SKGE_FLOWCTRL_CAP:
+-                      /* Check if it is the first active port */
++                      /* Check if it is the first active port. */
+                       if (*pBuf == 0) {
+                               *pBuf = pPrt->PFlowCtrlCap;
+@@ -6235,7 +6056,7 @@
+                       break;
+               case OID_SKGE_FLOWCTRL_MODE:
+-                      /* Check if it is the first active port */
++                      /* Check if it is the first active port. */
+                       if (*pBuf == 0) {
+                               *pBuf = pPrt->PFlowCtrlMode;
+@@ -6243,9 +6064,8 @@
+                       }
+                       /*
+-                       * If we find an active port with a different flow
+-                       * control mode than the first one, we return a value
+-                       * that indicates that the mode is indeterminated.
++                       * If we find an active port with a different flow-control mode
++                       * than the first one we return indeterminated.
+                        */
+                       if (*pBuf != pPrt->PFlowCtrlMode) {
+@@ -6254,7 +6074,7 @@
+                       break;
+               case OID_SKGE_FLOWCTRL_STATUS:
+-                      /* Check if it is the first active port */
++                      /* Check if it is the first active port. */
+                       if (*pBuf == 0) {
+                               *pBuf = pPrt->PFlowCtrlStatus;
+@@ -6262,10 +6082,8 @@
+                       }
+                       /*
+-                       * If we find an active port with a different flow
+-                       * control status than the first one, we return a
+-                       * value that indicates that the status is
+-                       * indeterminated.
++                       * If we find an active port with a different flow-control status
++                       * than the first one we return indeterminated.
+                        */
+                       if (*pBuf != pPrt->PFlowCtrlStatus) {
+@@ -6274,7 +6092,7 @@
+                       break;
+               
+               case OID_SKGE_PHY_OPERATION_CAP:
+-                      /* Check if it is the first active port */
++                      /* Check if it is the first active port. */
+                       if (*pBuf == 0) {
+                               *pBuf = pPrt->PMSCap;
+@@ -6289,7 +6107,7 @@
+                       break;
+               case OID_SKGE_PHY_OPERATION_MODE:
+-                      /* Check if it is the first active port */
++                      /* Check if it is the first active port. */
+                       if (*pBuf == 0) {
+                               *pBuf = pPrt->PMSMode;
+@@ -6297,9 +6115,8 @@
+                       }
+                       /*
+-                       * If we find an active port with a different master/
+-                       * slave mode than the first one, we return a value
+-                       * that indicates that the mode is indeterminated.
++                       * If we find an active port with a different master/slave mode
++                       * than the first one we return indeterminated.
+                        */
+                       if (*pBuf != pPrt->PMSMode) {
+@@ -6308,7 +6125,7 @@
+                       break;
+               case OID_SKGE_PHY_OPERATION_STATUS:
+-                      /* Check if it is the first active port */
++                      /* Check if it is the first active port. */
+                       if (*pBuf == 0) {
+                               *pBuf = pPrt->PMSStatus;
+@@ -6316,10 +6133,8 @@
+                       }
+                       /*
+-                       * If we find an active port with a different master/
+-                       * slave status than the first one, we return a
+-                       * value that indicates that the status is
+-                       * indeterminated.
++                       * If we find an active port with a different master/slave status
++                       * than the first one we return indeterminated.
+                        */
+                       if (*pBuf != pPrt->PMSStatus) {
+@@ -6328,7 +6143,7 @@
+                       break;
+               
+               case OID_SKGE_SPEED_MODE:
+-                      /* Check if it is the first active port */
++                      /* Check if it is the first active port. */
+                       if (*pBuf == 0) {
+                               *pBuf = pPrt->PLinkSpeed;
+@@ -6336,9 +6151,8 @@
+                       }
+                       /*
+-                       * If we find an active port with a different flow
+-                       * control mode than the first one, we return a value
+-                       * that indicates that the mode is indeterminated.
++                       * If we find an active port with a different link speed
++                       * than the first one we return indeterminated.
+                        */
+                       if (*pBuf != pPrt->PLinkSpeed) {
+@@ -6347,7 +6161,7 @@
+                       break;
+               
+               case OID_SKGE_SPEED_STATUS:
+-                      /* Check if it is the first active port */
++                      /* Check if it is the first active port. */
+                       if (*pBuf == 0) {
+                               *pBuf = pPrt->PLinkSpeedUsed;
+@@ -6355,10 +6169,8 @@
+                       }
+                       /*
+-                       * If we find an active port with a different flow
+-                       * control status than the first one, we return a
+-                       * value that indicates that the status is
+-                       * indeterminated.
++                       * If we find an active port with a different link speed used
++                       * than the first one we return indeterminated.
+                        */
+                       if (*pBuf != pPrt->PLinkSpeedUsed) {
+@@ -6368,9 +6180,7 @@
+               }
+       }
+-      /*
+-       * If no port is active return an indeterminated answer
+-       */
++      /* If no port is active return an indeterminated answer. */
+       if (!PortActiveFlag) {
+               switch (Id) {
+@@ -6487,16 +6297,15 @@
+ {
+       SK_U8   Result;
+-      /* Get the current mode, which can be full or half duplex */
++      /* Get the current mode, which can be full or half duplex. */
+       Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
+-      /* Check if no valid mode could be found (link is down) */
++      /* Check if no valid mode could be found (link is down). */
+       if (Result < SK_LMODE_STAT_HALF) {
+               Result = SK_LMODE_STAT_UNKNOWN;
+       }
+       else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
+-
+               /*
+                * Auto-negotiation was used to bring up the link. Change
+                * the already found duplex status that it indicates
+@@ -6541,22 +6350,19 @@
+       int                     Index;
+       int                     Ret;
+-
+       SK_MEMSET(pKeyArr, 0, KeyArrLen);
+-      /*
+-       * Get VPD key list
+-       */
+-      Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
++      /* Get VPD key list. */
++      Ret = VpdKeys(pAC, IoC, BufKeys, (int *)&BufKeysLen,
+               (int *)pKeyNo);
++      
+       if (Ret > 0) {
+-              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
+-                      SK_PNMI_ERR014MSG);
++              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014, SK_PNMI_ERR014MSG);
+               return (SK_PNMI_ERR_GENERAL);
+       }
+-      /* If no keys are available return now */
++      /* If no keys are available return now. */
+       if (*pKeyNo == 0 || BufKeysLen == 0) {
+               return (SK_PNMI_ERR_OK);
+@@ -6564,12 +6370,11 @@
+       /*
+        * If the key list is too long for us trunc it and give a
+        * errorlog notification. This case should not happen because
+-       * the maximum number of keys is limited due to RAM limitations
++       * the maximum number of keys is limited due to RAM limitations.
+        */
+       if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
+-              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
+-                      SK_PNMI_ERR015MSG);
++              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015, SK_PNMI_ERR015MSG);
+               *pKeyNo = SK_PNMI_VPD_ENTRIES;
+       }
+@@ -6582,14 +6387,12 @@
+               Offset ++) {
+               if (BufKeys[Offset] != 0) {
+-
+                       continue;
+               }
+               if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
+-                              SK_PNMI_ERR016MSG);
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016, SK_PNMI_ERR016MSG);
+                       return (SK_PNMI_ERR_GENERAL);
+               }
+@@ -6600,7 +6403,7 @@
+               StartOffset = Offset + 1;
+       }
+-      /* Last key not zero terminated? Get it anyway */
++      /* Last key not zero terminated? Get it anyway. */
+       if (StartOffset < Offset) {
+               SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
+@@ -6629,19 +6432,18 @@
+ {
+       SK_EVPARA       EventParam;
+-
+       /* Was the module already updated during the current PNMI call? */
+       if (pAC->Pnmi.SirqUpdatedFlag > 0) {
+               return (SK_PNMI_ERR_OK);
+       }
+-      /* Send an synchronuous update event to the module */
++      /* Send an synchronuous update event to the module. */
+       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
+-      if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
++      
++      if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam)) {
+-              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
+-                      SK_PNMI_ERR047MSG);
++              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047, SK_PNMI_ERR047MSG);
+               return (SK_PNMI_ERR_GENERAL);
+       }
+@@ -6669,21 +6471,19 @@
+ {
+       SK_EVPARA       EventParam;
+-
+       /* Was the module already updated during the current PNMI call? */
+       if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
+               return (SK_PNMI_ERR_OK);
+       }
+-      /* Send an synchronuous update event to the module */
++      /* Send an synchronuous update event to the module. */
+       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
+       EventParam.Para32[0] = NetIndex;
+       EventParam.Para32[1] = (SK_U32)-1;
+       if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
+-              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
+-                      SK_PNMI_ERR048MSG);
++              SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048, SK_PNMI_ERR048MSG);
+               return (SK_PNMI_ERR_GENERAL);
+       }
+@@ -6721,20 +6521,20 @@
+               return (SK_PNMI_ERR_OK);
+       }
+-      /* Send an update command to all MACs specified */
++      /* Send an update command to all MACs specified. */
+       for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
+               /*
+                * 2002-09-13 pweber:   Freeze the current SW counters.
+                *                      (That should be done as close as
+                *                      possible to the update of the
+-               *                      HW counters)
++               *                      HW counters).
+                */
+               if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
+                       pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
+               }
+                       
+-              /* 2002-09-13 pweber:  Update the HW counter  */
++              /* 2002-09-13 pweber:  Update the HW counter.  */
+               if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -6772,19 +6572,19 @@
+       SK_U64                  Val = 0;
+-      if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {   /* Dual net mode */
++      if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {   /* DualNet mode. */
+               PhysPortIndex = NetIndex;
+               
+               Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
+       }
+-      else {  /* Single Net mode */
++      else {  /* SingleNet mode. */
+               if (LogPortIndex == 0) {
+                       PhysPortMax = pAC->GIni.GIMacsFound;
+-                      /* Add counter of all active ports */
++                      /* Add counter of all active ports. */
+                       for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
+                               PhysPortIndex ++) {
+@@ -6794,11 +6594,11 @@
+                               }
+                       }
+-                      /* Correct value because of port switches */
++                      /* Correct value because of port switches. */
+                       Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
+               }
+               else {
+-                      /* Get counter value of physical port */
++                      /* Get counter value of physical port. */
+                       PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
+                       
+                       Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
+@@ -6844,7 +6644,7 @@
+       
+       MacType = pAC->GIni.GIMacType;
+       
+-      /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
++      /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */
+       if (MacType == SK_MAC_XMAC) {
+               pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
+       }
+@@ -6912,7 +6712,7 @@
+       case SK_PNMI_HTX_BURST:
+       case SK_PNMI_HTX_EXCESS_DEF:
+       case SK_PNMI_HTX_CARRIER:
+-              /* Not supported by GMAC */
++              /* Not supported by GMAC. */
+               if (MacType == SK_MAC_GMAC) {
+                       return (Val);
+               }
+@@ -6924,7 +6724,7 @@
+               break;
+       case SK_PNMI_HTX_MACC:
+-              /* GMAC only supports PAUSE MAC control frames */
++              /* GMAC only supports PAUSE MAC control frames. */
+               if (MacType == SK_MAC_GMAC) {
+                       HelpIndex = SK_PNMI_HTX_PMACC;
+               }
+@@ -6941,7 +6741,7 @@
+       case SK_PNMI_HTX_COL:
+       case SK_PNMI_HRX_UNDERSIZE:
+-              /* Not supported by XMAC */
++              /* Not supported by XMAC. */
+               if (MacType == SK_MAC_XMAC) {
+                       return (Val);
+               }
+@@ -6953,7 +6753,7 @@
+               break;
+       case SK_PNMI_HTX_DEFFERAL:
+-              /* Not supported by GMAC */
++              /* Not supported by GMAC. */
+               if (MacType == SK_MAC_GMAC) {
+                       return (Val);
+               }
+@@ -6971,7 +6771,7 @@
+                       HighVal = 0;
+               }
+               else {
+-                      /* Otherwise get contents of hardware register */
++                      /* Otherwise get contents of hardware register. */
+                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                                 StatAddr[StatIndex][MacType].Reg,
+                                                                                 &LowVal);
+@@ -6980,7 +6780,7 @@
+               break;
+       case SK_PNMI_HRX_BADOCTET:
+-              /* Not supported by XMAC */
++              /* Not supported by XMAC. */
+               if (MacType == SK_MAC_XMAC) {
+                       return (Val);
+               }
+@@ -6999,7 +6799,7 @@
+               return (Val);
+       case SK_PNMI_HRX_LONGFRAMES:
+-              /* For XMAC the SW counter is managed by PNMI */
++              /* For XMAC the SW counter is managed by PNMI. */
+               if (MacType == SK_MAC_XMAC) {
+                       return (pPnmiPrt->StatRxLongFrameCts);
+               }
+@@ -7019,7 +6819,7 @@
+               Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
+               if (MacType == SK_MAC_GMAC) {
+-                      /* For GMAC the SW counter is additionally managed by PNMI */
++                      /* For GMAC the SW counter is additionally managed by PNMI. */
+                       Val += pPnmiPrt->StatRxFrameTooLongCts;
+               }
+               else {
+@@ -7037,20 +6837,19 @@
+               break;
+               
+       case SK_PNMI_HRX_SHORTS:
+-              /* Not supported by GMAC */
++              /* Not supported by GMAC. */
+               if (MacType == SK_MAC_GMAC) {
+                       /* GM_RXE_FRAG?? */
+                       return (Val);
+               }
+               
+               /*
+-               * XMAC counts short frame errors even if link down (#10620)
+-               *
+-               * If link-down the counter remains constant
++               * XMAC counts short frame errors even if link down (#10620).
++               * If the link is down, the counter remains constant.
+                */
+               if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
+-                      /* Otherwise get incremental difference */
++                      /* Otherwise get incremental difference. */
+                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+                                                                                 StatAddr[StatIndex][MacType].Reg,
+                                                                                 &LowVal);
+@@ -7073,7 +6872,7 @@
+       case SK_PNMI_HRX_IRLENGTH:
+       case SK_PNMI_HRX_SYMBOL:
+       case SK_PNMI_HRX_CEXT:
+-              /* Not supported by GMAC */
++              /* Not supported by GMAC. */
+               if (MacType == SK_MAC_GMAC) {
+                       return (Val);
+               }
+@@ -7085,7 +6884,7 @@
+               break;
+       case SK_PNMI_HRX_PMACC_ERR:
+-              /* For GMAC the SW counter is managed by PNMI */
++              /* For GMAC the SW counter is managed by PNMI. */
+               if (MacType == SK_MAC_GMAC) {
+                       return (pPnmiPrt->StatRxPMaccErr);
+               }
+@@ -7096,13 +6895,13 @@
+               HighVal = pPnmiPrt->CounterHigh[StatIndex];
+               break;
+-      /* SW counter managed by PNMI */
++      /* SW counter managed by PNMI. */
+       case SK_PNMI_HTX_SYNC:
+               LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
+               HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
+               break;
+-      /* SW counter managed by PNMI */
++      /* SW counter managed by PNMI. */
+       case SK_PNMI_HTX_SYNC_OCTET:
+               LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
+               HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
+@@ -7110,17 +6909,19 @@
+       case SK_PNMI_HRX_FCS:
+               /*
+-               * Broadcom filters FCS errors and counts it in
+-               * Receive Error Counter register
++               * Broadcom filters FCS errors and counts them in
++               * Receive Error Counter register.
+                */
+               if (pPrt->PhyType == SK_PHY_BCOM) {
+-                      /* do not read while not initialized (PHY_READ hangs!)*/
++#ifdef GENESIS
++                      /* Do not read while not initialized (PHY_READ hangs!). */
+                       if (pPrt->PState != SK_PRT_RESET) {
+                               SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
+                               
+                               LowVal = Word;
+                       }
+                       HighVal = pPnmiPrt->CounterHigh[StatIndex];
++#endif /* GENESIS */
+               }
+               else {
+                       (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
+@@ -7140,7 +6941,7 @@
+       Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
+-      /* Correct value because of possible XMAC reset. XMAC Errata #2 */
++      /* Correct value because of possible XMAC reset (XMAC Errata #2). */
+       Val += pPnmiPrt->CounterOffset[StatIndex];
+       return (Val);
+@@ -7165,22 +6966,21 @@
+       unsigned int    PhysPortIndex;
+       SK_EVPARA       EventParam;
+-
+       SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
+-      /* Notify sensor module */
++      /* Notify sensor module. */
+       SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
+-      /* Notify RLMT module */
++      /* Notify RLMT module. */
+       EventParam.Para32[0] = NetIndex;
+       EventParam.Para32[1] = (SK_U32)-1;
+       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
+       EventParam.Para32[1] = 0;
+-      /* Notify SIRQ module */
++      /* Notify SIRQ module. */
+       SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
+-      /* Notify CSUM module */
++      /* Notify CSUM module. */
+ #ifdef SK_USE_CSUM
+       EventParam.Para32[0] = NetIndex;
+       EventParam.Para32[1] = (SK_U32)-1;
+@@ -7188,7 +6988,7 @@
+               EventParam);
+ #endif /* SK_USE_CSUM */
+       
+-      /* Clear XMAC statistic */
++      /* Clear XMAC statistics. */
+       for (PhysPortIndex = 0; PhysPortIndex <
+               (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
+@@ -7215,13 +7015,13 @@
+                       PhysPortIndex].StatRxPMaccErr));
+       }
+-      /*
+-       * Clear local statistics
+-       */
++      /* Clear local statistics. */
+       SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
+                 sizeof(pAC->Pnmi.VirtualCounterOffset));
++      
+       pAC->Pnmi.RlmtChangeCts = 0;
+       pAC->Pnmi.RlmtChangeTime = 0;
++      
+       SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
+               sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
+       pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
+@@ -7258,23 +7058,21 @@
+ SK_U32 TrapId,                /* SNMP ID of the trap */
+ unsigned int Size)    /* Space needed for trap entry */
+ {
+-      unsigned int            BufPad = pAC->Pnmi.TrapBufPad;
+-      unsigned int            BufFree = pAC->Pnmi.TrapBufFree;
+-      unsigned int            Beg = pAC->Pnmi.TrapQueueBeg;
+-      unsigned int            End = pAC->Pnmi.TrapQueueEnd;
++      unsigned int    BufPad = pAC->Pnmi.TrapBufPad;
++      unsigned int    BufFree = pAC->Pnmi.TrapBufFree;
++      unsigned int    Beg = pAC->Pnmi.TrapQueueBeg;
++      unsigned int    End = pAC->Pnmi.TrapQueueEnd;
+       char                    *pBuf = &pAC->Pnmi.TrapBuf[0];
+       int                     Wrap;
+-      unsigned int            NeededSpace;
+-      unsigned int            EntrySize;
++      unsigned int    NeededSpace;
++      unsigned int    EntrySize;
+       SK_U32                  Val32;
+       SK_U64                  Val64;
+-
+-      /* Last byte of entry will get a copy of the entry length */
++      /* Last byte of entry will get a copy of the entry length. */
+       Size ++;
+-      /*
+-       * Calculate needed buffer space */
++      /* Calculate needed buffer space. */
+       if (Beg >= Size) {
+               NeededSpace = Size;
+@@ -7289,7 +7087,7 @@
+        * Check if enough buffer space is provided. Otherwise
+        * free some entries. Leave one byte space between begin
+        * and end of buffer to make it possible to detect whether
+-       * the buffer is full or empty
++       * the buffer is full or empty.
+        */
+       while (BufFree < NeededSpace + 1) {
+@@ -7328,13 +7126,13 @@
+       }
+       BufFree -= NeededSpace;
+-      /* Save the current offsets */
++      /* Save the current offsets. */
+       pAC->Pnmi.TrapQueueBeg = Beg;
+       pAC->Pnmi.TrapQueueEnd = End;
+       pAC->Pnmi.TrapBufPad = BufPad;
+       pAC->Pnmi.TrapBufFree = BufFree;
+-      /* Initialize the trap entry */
++      /* Initialize the trap entry. */
+       *(pBuf + Beg + Size - 1) = (char)Size;
+       *(pBuf + Beg) = (char)Size;
+       Val32 = (pAC->Pnmi.TrapUnique) ++;
+@@ -7369,7 +7167,6 @@
+       unsigned int    Len;
+       unsigned int    DstOff = 0;
+-
+       while (Trap != End) {
+               Len = (unsigned int)*(pBuf + Trap);
+@@ -7414,7 +7211,6 @@
+       unsigned int    Entries = 0;
+       unsigned int    TotalLen = 0;
+-
+       while (Trap != End) {
+               Len = (unsigned int)*(pBuf + Trap);
+@@ -7471,14 +7267,14 @@
+       unsigned int    DescrLen;
+       SK_U32          Val32;
+-
+-      /* Get trap buffer entry */
++      /* Get trap buffer entry. */
+       DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
++      
+       pBuf = GetTrapEntry(pAC, TrapId,
+               SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
+       Offset = SK_PNMI_TRAP_SIMPLE_LEN;
+-      /* Store additionally sensor trap related data */
++      /* Store additionally sensor trap related data. */
+       Val32 = OID_SKGE_SENSOR_INDEX;
+       SK_PNMI_STORE_U32(pBuf + Offset, Val32);
+       *(pBuf + Offset + 4) = 4;
+@@ -7523,7 +7319,6 @@
+       char    *pBuf;
+       SK_U32  Val32;
+-
+       pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
+               SK_PNMI_TRAP_RLMT_CHANGE_LEN);
+@@ -7551,7 +7346,6 @@
+       char    *pBuf;
+       SK_U32  Val32;
+-
+       pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
+       Val32 = OID_SKGE_RLMT_PORT_INDEX;
+@@ -7571,12 +7365,11 @@
+  *    Nothing
+  */
+ PNMI_STATIC void CopyMac(
+-char *pDst,           /* Pointer to destination buffer */
++char          *pDst,  /* Pointer to destination buffer */
+ SK_MAC_ADDR *pMac)    /* Pointer of Source */
+ {
+       int     i;
+-
+       for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
+               *(pDst + i) = pMac->a[i];
+@@ -7616,17 +7409,14 @@
+       
+       SK_U32  RetCode = SK_PNMI_ERR_GENERAL;
+-      /*
+-       * Check instance. We only handle single instance variables
+-       */
++      /* Check instance. We only handle single instance variables. */
+       if (Instance != (SK_U32)(-1) && Instance != 1) {
+               *pLen = 0;
+               return (SK_PNMI_ERR_UNKNOWN_INST);
+       }
+       
+-    
+-    /* Check length */
++    /* Check length. */
+     switch (Id) {
+     case OID_PNP_CAPABILITIES:
+@@ -7664,14 +7454,10 @@
+         break;
+     }
+       
+-    /*
+-       * Perform action
+-       */
++      /* Perform action. */
+       if (Action == SK_PNMI_GET) {
+-              /*
+-               * Get value
+-               */
++              /* Get value. */
+               switch (Id) {
+               case OID_PNP_CAPABILITIES:
+@@ -7679,18 +7465,21 @@
+                       break;
+               case OID_PNP_QUERY_POWER:
+-                      /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
+-                       the miniport to indicate whether it can transition its NIC
+-                       to the low-power state.
+-                       A miniport driver must always return NDIS_STATUS_SUCCESS
+-                       to a query of OID_PNP_QUERY_POWER. */
++                      /*
++                       * The Windows DDK describes: An OID_PNP_QUERY_POWER requests
++                       * the miniport to indicate whether it can transition its NIC
++                       * to the low-power state.
++                       * A miniport driver must always return NDIS_STATUS_SUCCESS
++                       * to a query of OID_PNP_QUERY_POWER.
++                       */
+                       *pLen = sizeof(SK_DEVICE_POWER_STATE);
+             RetCode = SK_PNMI_ERR_OK;
+                       break;
+-                      /* NDIS handles these OIDs as write-only.
++                      /*
++                       * NDIS handles these OIDs as write-only.
+                        * So in case of get action the buffer with written length = 0
+-                       * is returned
++                       * is returned.
+                        */
+               case OID_PNP_SET_POWER:
+               case OID_PNP_ADD_WAKE_UP_PATTERN:
+@@ -7711,13 +7500,11 @@
+               return (RetCode);
+       }
+       
+-
+-      /*
+-       * Perform preset or set
+-       */
++      /* Perform PRESET or SET. */
+       
+-      /* POWER module does not support PRESET action */
++      /* The POWER module does not support PRESET action. */
+       if (Action == SK_PNMI_PRESET) {
++
+               return (SK_PNMI_ERR_OK);
+       }
+@@ -7749,7 +7536,7 @@
+ #ifdef SK_DIAG_SUPPORT
+ /*****************************************************************************
+  *
+- * DiagActions - OID handler function of Diagnostic driver 
++ * DiagActions - OID handler function of Diagnostic driver
+  *
+  * Description:
+  *    The code is simple. No description necessary.
+@@ -7776,22 +7563,17 @@
+ unsigned int TableIndex, /* Index to the Id table */
+ SK_U32 NetIndex)      /* NetIndex (0..n), in single net mode always zero */
+ {
+-
+       SK_U32  DiagStatus;
+       SK_U32  RetCode = SK_PNMI_ERR_GENERAL;
+-      /*
+-       * Check instance. We only handle single instance variables.
+-       */
++      /* Check instance. We only handle single instance variables. */
+       if (Instance != (SK_U32)(-1) && Instance != 1) {
+               *pLen = 0;
+               return (SK_PNMI_ERR_UNKNOWN_INST);
+       }
+-      /*
+-       * Check length.
+-       */
++    /* Check length. */
+       switch (Id) {
+       case OID_SKGE_DIAG_MODE:
+@@ -7809,10 +7591,9 @@
+       }
+       /* Perform action. */
+-
+-      /* GET value. */
+       if (Action == SK_PNMI_GET) {
++              /* Get value. */
+               switch (Id) {
+               case OID_SKGE_DIAG_MODE:
+@@ -7827,14 +7608,15 @@
+                       RetCode = SK_PNMI_ERR_GENERAL;
+                       break;
+               }
+-              return (RetCode); 
++              return (RetCode);
+       }
+       /* From here SET or PRESET value. */
+       
+       /* PRESET value is not supported. */
+       if (Action == SK_PNMI_PRESET) {
+-              return (SK_PNMI_ERR_OK); 
++
++              return (SK_PNMI_ERR_OK);
+       }
+       /* SET value. */
+@@ -7846,7 +7628,7 @@
+                               /* Attach the DIAG to this adapter. */
+                               case SK_DIAG_ATTACHED:
+-                                      /* Check if we come from running */
++                                      /* Check if we come from running. */
+                                       if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
+                                               RetCode = SkDrvLeaveDiagMode(pAC);
+@@ -7881,7 +7663,7 @@
+                                               /* If DiagMode is not active, we can enter it. */
+                                               if (!pAC->DiagModeActive) {
+-                                                      RetCode = SkDrvEnterDiagMode(pAC); 
++                                                      RetCode = SkDrvEnterDiagMode(pAC);
+                                               }
+                                               else {
+@@ -7900,7 +7682,7 @@
+                                       break;
+                               case SK_DIAG_IDLE:
+-                                      /* Check if we come from running */
++                                      /* Check if we come from running. */
+                                       if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
+                                               RetCode = SkDrvLeaveDiagMode(pAC);
+@@ -7946,7 +7728,7 @@
+ /*****************************************************************************
+  *
+- * Vct - OID handler function of  OIDs
++ * Vct - OID handler function of OIDs for Virtual Cable Tester (VCT)
+  *
+  * Description:
+  *    The code is simple. No description necessary.
+@@ -7982,153 +7764,150 @@
+       SK_U32          PhysPortIndex;
+       SK_U32          Limit;
+       SK_U32          Offset;
+-      SK_BOOL         Link;
+-      SK_U32          RetCode = SK_PNMI_ERR_GENERAL;
+-      int             i;
++      SK_U32          RetCode;
++      int                     i;
+       SK_EVPARA       Para;
+-      SK_U32          CableLength;
+-      
+-      /*
+-       * Calculate the port indexes from the instance.
+-       */
++
++      RetCode = SK_PNMI_ERR_GENERAL;
++
++      /* Calculate the port indexes from the instance. */
+       PhysPortMax = pAC->GIni.GIMacsFound;
+       LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
+-      
++
+       /* Dual net mode? */
+       if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+               LogPortMax--;
+       }
+-      
++
+       if ((Instance != (SK_U32) (-1))) {
+-              /* Check instance range. */
+-              if ((Instance < 2) || (Instance > LogPortMax)) {
+-                      *pLen = 0;
+-                      return (SK_PNMI_ERR_UNKNOWN_INST);
+-              }
+-              
++              /*
++               * Get one instance of that OID, so check the instance range:
++               * There is no virtual port with an Instance == 1, so we get
++               * the values from one physical port only.
++               */             
+               if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
+                       PhysPortIndex = NetIndex;
+               }
+-              else {
++              else {\r
++                      if ((Instance < 2) || (Instance > LogPortMax)) {\r
++                              *pLen = 0;\r
++                              return (SK_PNMI_ERR_UNKNOWN_INST);\r
++                      }
+                       PhysPortIndex = Instance - 2;
+               }
+               Limit = PhysPortIndex + 1;
+       }
+       else {
+               /*
+-               * Instance == (SK_U32) (-1), get all Instances of that OID.
+-               *
+-               * Not implemented yet. May be used in future releases.
++               * Instance == (SK_U32) (-1), so get all instances of that OID.
++               * There is no virtual port with an Instance == 1, so we get
++               * the values from all physical ports.
+                */
+               PhysPortIndex = 0;
+               Limit = PhysPortMax;
+       }
+-      
+-      pPrt = &pAC->GIni.GP[PhysPortIndex];
+-      if (pPrt->PHWLinkUp) {
+-              Link = SK_TRUE;
+-      }
+-      else {
+-              Link = SK_FALSE;
+-      }
+-      
+-      /* Check MAC type */
+-      if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
++
++      /* Check MAC type. */
++      if ((Id != OID_SKGE_VCT_CAPABILITIES) &&
++              (pAC->GIni.GP[PhysPortIndex].PhyType != SK_PHY_MARV_COPPER)) {
+               *pLen = 0;
+-              return (SK_PNMI_ERR_GENERAL);
++              return (SK_PNMI_ERR_NOT_SUPPORTED);
+       }
+-      
+-      /* Initialize backup data pointer. */
+-      pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
+-      
+-      /* Check action type */
++
++      /* Check action type. */
+       if (Action == SK_PNMI_GET) {
+-              /* Check length */
++              /* Check length. */
+               switch (Id) {
+-              
++
+               case OID_SKGE_VCT_GET:
+                       if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
+                               *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       break;
+-              
++
+               case OID_SKGE_VCT_STATUS:
++              case OID_SKGE_VCT_CAPABILITIES:
+                       if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
+                               *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
+                               return (SK_PNMI_ERR_TOO_SHORT);
+                       }
+                       break;
+-              
++
+               default:
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+               }       
+-              
+-              /* Get value */
++
++              /* Get value. */
+               Offset = 0;
+               for (; PhysPortIndex < Limit; PhysPortIndex++) {
++\r
++                      pPrt = &pAC->GIni.GP[PhysPortIndex];\r
++
+                       switch (Id) {
+-                      
++
+                       case OID_SKGE_VCT_GET:
+-                              if ((Link == SK_FALSE) &&
++                              if (!pPrt->PHWLinkUp &&
+                                       (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
++
+                                       RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
++
+                                       if (RetCode == 0) {
+-                                              pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
+-                                              pAC->Pnmi.VctStatus[PhysPortIndex] |=
+-                                                      (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
+-                                              
+-                                              /* Copy results for later use to PNMI struct. */
+-                                              for (i = 0; i < 4; i++)  {
+-                                                      if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
+-                                                              if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
+-                                                                      pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
+-                                                              }
+-                                                      }
+-                                                      if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
+-                                                              CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
+-                                                      }
+-                                                      else {
+-                                                              CableLength = 0;
+-                                                      }
+-                                                      pVctBackupData->PMdiPairLen[i] = CableLength;
+-                                                      pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
+-                                              }
++
++                                              /* VCT test is finished, so save the data. */
++                                              VctGetResults(pAC, IoC, PhysPortIndex);
+                                               Para.Para32[0] = PhysPortIndex;
+                                               Para.Para32[1] = -1;
+                                               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
+-                                              SkEventDispatcher(pAC, IoC);
+-                                      }
+-                                      else {
+-                                              ; /* VCT test is running. */
++
++                                              /* SkEventDispatcher(pAC, IoC); */
+                                       }
+                               }
+-                              
++
++                              /* Initialize backup data pointer. */
++                              pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
++
+                               /* Get all results. */
+                               CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
+-                              Offset += sizeof(SK_U8);
++
++                              Offset++;
+                               *(pBuf + Offset) = pPrt->PCableLen;
+-                              Offset += sizeof(SK_U8);
++                              Offset++;
+                               for (i = 0; i < 4; i++)  {
+-                                      SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
++
++                                      SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->MdiPairLen[i]);
+                                       Offset += sizeof(SK_U32);
+                               }
+                               for (i = 0; i < 4; i++)  {
+-                                      *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
+-                                      Offset += sizeof(SK_U8);
++
++                                      *(pBuf + Offset) = pVctBackupData->MdiPairSts[i];
++                                      Offset++;
+                               }
+-                              
++
+                               RetCode = SK_PNMI_ERR_OK;
+                               break;
+-              
++
+                       case OID_SKGE_VCT_STATUS:
+                               CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
+-                              Offset += sizeof(SK_U8);
++
++                              Offset++;
+                               RetCode = SK_PNMI_ERR_OK;
+                               break;
+-                      
++
++                      case OID_SKGE_VCT_CAPABILITIES:
++                              if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
++                                      *(pBuf + Offset) = SK_PNMI_VCT_NOT_SUPPORTED;
++                              }
++                              else {
++                                      *(pBuf + Offset) = SK_PNMI_VCT_SUPPORTED;
++                              }
++                              Offset++;
++
++                              RetCode = SK_PNMI_ERR_OK;
++                              break;
++
+                       default:
+                               *pLen = 0;
+                               return (SK_PNMI_ERR_GENERAL);
+@@ -8136,15 +7915,15 @@
+               } /* for */
+               *pLen = Offset;
+               return (RetCode);
+-      
++
+       } /* if SK_PNMI_GET */
+-      
++
+       /*
+        * From here SET or PRESET action. Check if the passed
+        * buffer length is plausible.
+        */
+-      
+-      /* Check length */
++
++      /* Check length. */
+       switch (Id) {
+       case OID_SKGE_VCT_SET:
+               if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
+@@ -8152,42 +7931,45 @@
+                       return (SK_PNMI_ERR_TOO_SHORT);
+               }
+               break;
+-      
++
+       default:
+               *pLen = 0;
+               return (SK_PNMI_ERR_GENERAL);
+       }
+-      
+-      /*
+-       * Perform preset or set.
+-       */
+-      
++
++      /* Perform PRESET or SET. */
++
+       /* VCT does not support PRESET action. */
+       if (Action == SK_PNMI_PRESET) {
++
+               return (SK_PNMI_ERR_OK);
+       }
+-      
++
+       Offset = 0;
+       for (; PhysPortIndex < Limit; PhysPortIndex++) {
++
++              pPrt = &pAC->GIni.GP[PhysPortIndex];
++
+               switch (Id) {
+               case OID_SKGE_VCT_SET: /* Start VCT test. */
+-                      if (Link == SK_FALSE) {
++                      if (!pPrt->PHWLinkUp) {
+                               SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
+-                              
++
+                               RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
++
+                               if (RetCode == 0) { /* RetCode: 0 => Start! */
+                                       pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
+-                                      pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
+-                                      pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
+-                                      
+-                                      /*
+-                                       * Start VCT timer counter.
+-                                       */
+-                                      SK_MEMSET((char *) &Para, 0, sizeof(Para));
++                                      pAC->Pnmi.VctStatus[PhysPortIndex] &=
++                                              ~(SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_LINK);
++
++                                      /* Start VCT timer counter. */
++                                      SK_MEMSET((char *)&Para, 0, sizeof(Para));
+                                       Para.Para32[0] = PhysPortIndex;
+                                       Para.Para32[1] = -1;
+-                                      SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
+-                                              4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
++
++                                      SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex],
++                                              SK_PNMI_VCT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
++
+                                       SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
+                                       RetCode = SK_PNMI_ERR_OK;
+                               }
+@@ -8203,7 +7985,7 @@
+                       }
+                       Offset += sizeof(SK_U32);
+                       break;
+-      
++
+               default:
+                       *pLen = 0;
+                       return (SK_PNMI_ERR_GENERAL);
+@@ -8215,6 +7997,65 @@
+ } /* Vct */
++PNMI_STATIC void VctGetResults(
++SK_AC         *pAC,
++SK_IOC                IoC,
++SK_U32                Port)
++{
++      SK_GEPORT       *pPrt;
++      int                     i;
++      SK_U8           PairLen;
++      SK_U8           PairSts;
++      SK_U32          MinLength;
++      SK_U32          CableLength;
++
++      pPrt = &pAC->GIni.GP[Port];
++
++      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
++              MinLength = 25;
++      }
++      else {
++              MinLength = 35;
++      }
++
++      /* Copy results for later use to PNMI struct. */
++      for (i = 0; i < 4; i++)  {
++
++              PairLen = pPrt->PMdiPairLen[i];
++
++              if (((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) == 0) && (i > 1)) {
++                      PairSts = SK_PNMI_VCT_NOT_PRESENT;
++              }
++              else {
++                      PairSts = pPrt->PMdiPairSts[i];
++              }
++
++              if ((PairSts == SK_PNMI_VCT_NORMAL_CABLE) &&
++                      (PairLen > 28) && (PairLen < 0xff)) {
++
++                      PairSts = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
++              }
++
++              /* Ignore values <= MinLength, the linear factor is 4/5. */
++              if ((PairLen > MinLength) && (PairLen < 0xff)) {
++                      
++                      CableLength = 1000UL * (PairLen - MinLength) * 4 / 5;
++              }
++              else {
++                      /* No cable or short cable. */
++                      CableLength = 0;
++              }
++
++              pAC->Pnmi.VctBackup[Port].MdiPairLen[i] = CableLength;
++              pAC->Pnmi.VctBackup[Port].MdiPairSts[i] = PairSts;
++      }
++
++      pAC->Pnmi.VctStatus[Port] &= ~SK_PNMI_VCT_PENDING;
++      pAC->Pnmi.VctStatus[Port] |= (SK_PNMI_VCT_NEW_VCT_DATA |
++              SK_PNMI_VCT_TEST_DONE);
++
++} /* GetVctResults */
++
+ PNMI_STATIC void CheckVctStatus(
+ SK_AC         *pAC,
+ SK_IOC                IoC,
+@@ -8224,54 +8065,57 @@
+ {
+       SK_GEPORT       *pPrt;
+       SK_PNMI_VCT     *pVctData;
++      SK_U8           VctStatus;
+       SK_U32          RetCode;
+-      
++
+       pPrt = &pAC->GIni.GP[PhysPortIndex];
+-      
++
+       pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
+       pVctData->VctStatus = SK_PNMI_VCT_NONE;
+-      
++
++      VctStatus = pAC->Pnmi.VctStatus[PhysPortIndex];
++
+       if (!pPrt->PHWLinkUp) {
+-              
++
+               /* Was a VCT test ever made before? */
+-              if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
+-                      if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
++              if (VctStatus & SK_PNMI_VCT_TEST_DONE) {
++                      if (VctStatus & SK_PNMI_VCT_LINK) {
+                               pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
+                       }
+                       else {
+                               pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
+                       }
+               }
+-              
++
+               /* Check VCT test status. */
+               RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
++
+               if (RetCode == 2) { /* VCT test is running. */
+                       pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
+               }
+               else { /* VCT data was copied to pAC here. Check PENDING state. */
+-                      if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
++                      if (VctStatus & SK_PNMI_VCT_PENDING) {
+                               pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
+                       }
+               }
+-              
++
+               if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
+                       pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
+               }
+       }
+       else {
+-              
+               /* Was a VCT test ever made before? */
+-              if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
++              if (VctStatus & SK_PNMI_VCT_TEST_DONE) {
+                       pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
+                       pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
+               }
+-              
++
+               /* DSP only valid in 100/1000 modes. */
+-              if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
+-                      SK_LSPEED_STAT_10MBPS) {        
++              if (pPrt->PLinkSpeedUsed != SK_LSPEED_STAT_10MBPS) {
+                       pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
+               }
+-      }
++      }\r
++
+ } /* CheckVctStatus */
+@@ -8314,29 +8158,29 @@
+       ReturnCode = SK_PNMI_ERR_GENERAL;
+       
+       SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
+-      SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
++      SK_MEMCPY(&Oid, (char *)pBuf + sizeof(SK_I32), sizeof(SK_U32));
+       HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
+       *pLen = *pLen - HeaderLength;
+-      SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
++      SK_MEMCPY((char *)pBuf + sizeof(SK_I32), (char *)pBuf + HeaderLength, *pLen);
+       
+       switch(Mode) {
+       case SK_GET_SINGLE_VAR:
+-              ReturnCode = SkPnmiGetVar(pAC, IoC, Oid, 
+-                              (char *) pBuf + sizeof(SK_I32), pLen,
++              ReturnCode = SkPnmiGetVar(pAC, IoC, Oid,
++                              (char *)pBuf + sizeof(SK_I32), pLen,
+                               ((SK_U32) (-1)), NetIndex);
+               SK_PNMI_STORE_U32(pBuf, ReturnCode);
+               *pLen = *pLen + sizeof(SK_I32);
+               break;
+       case SK_PRESET_SINGLE_VAR:
+-              ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid, 
+-                              (char *) pBuf + sizeof(SK_I32), pLen,
++              ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid,
++                              (char *)pBuf + sizeof(SK_I32), pLen,
+                               ((SK_U32) (-1)), NetIndex);
+               SK_PNMI_STORE_U32(pBuf, ReturnCode);
+               *pLen = *pLen + sizeof(SK_I32);
+               break;
+       case SK_SET_SINGLE_VAR:
+-              ReturnCode = SkPnmiSetVar(pAC, IoC, Oid, 
+-                              (char *) pBuf + sizeof(SK_I32), pLen,
++              ReturnCode = SkPnmiSetVar(pAC, IoC, Oid,
++                              (char *)pBuf + sizeof(SK_I32), pLen,
+                               ((SK_U32) (-1)), NetIndex);
+               SK_PNMI_STORE_U32(pBuf, ReturnCode);
+               *pLen = *pLen + sizeof(SK_I32);
+@@ -8357,3 +8201,86 @@
+       return (ReturnCode);
+ } /* SkGeIocGen */
++
++#ifdef SK_ASF
++/*****************************************************************************
++ *
++ * Asf
++ *
++ * Description:
++ *  The code is simple. No description necessary.
++ *
++ * Returns:
++ *  SK_PNMI_ERR_OK           The request was successfully performed.
++ *  SK_PNMI_ERR_GENERAL      A general severe internal error occured.
++ *  SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
++ *                           the correct data (e.g. a 32bit value is
++ *                           needed, but a 16 bit value was passed).
++ *  SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
++ *                           exist (e.g. port instance 3 on a two port
++ *                           adapter.
++ */
++
++PNMI_STATIC int Asf(
++SK_AC *pAC,     /* Pointer to adapter context */
++SK_IOC IoC,     /* IO context handle */
++int Action,     /* GET/PRESET/SET action */
++SK_U32 Id,      /* Object ID that is to be processed */
++char *pBuf,     /* Buffer used for the management data transfer */
++unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
++SK_U32 Instance,    /* Instance (1..n) that is to be queried or -1 */
++unsigned int TableIndex, /* Index to the Id table */
++SK_U32 NetIndex)    /* NetIndex (0..n), in single net mode always zero */
++{
++    SK_U32  RetCode = SK_PNMI_ERR_GENERAL;
++
++    /*
++     * Check instance. We only handle single instance variables.
++     */
++    if (Instance != (SK_U32)(-1) && Instance != 1) {
++
++        *pLen = 0;
++        return (SK_PNMI_ERR_UNKNOWN_INST);
++    }
++
++    /* Perform action. */
++    /* GET value. */
++    if (Action == SK_PNMI_GET) {
++        switch (Id) {
++            case OID_SKGE_ASF:  
++                RetCode = SkAsfGet(pAC, IoC, (SK_U8 *) pBuf, pLen);
++                break;
++            default:
++                RetCode = SkAsfGetOid( pAC, IoC, Id, Instance, (SK_U8 *) pBuf, pLen );
++                break;
++        }
++
++        return (RetCode); 
++    }
++
++    /* PRESET value. */
++    if (Action == SK_PNMI_PRESET) { 
++        switch (Id) {
++            case OID_SKGE_ASF:
++                RetCode = SkAsfPreSet(pAC, IoC, (SK_U8 *) pBuf, pLen);
++                break;
++            default:
++                RetCode = SkAsfPreSetOid( pAC, IoC, Id, Instance, (SK_U8 *) pBuf, pLen );
++                break;
++        }
++    }
++
++    /* SET value. */
++    if (Action == SK_PNMI_SET) {
++        switch (Id) {
++            case OID_SKGE_ASF:
++                RetCode = SkAsfSet(pAC, IoC, (SK_U8 *) pBuf, pLen);
++                break;
++            default:
++                RetCode = SkAsfSetOid( pAC, IoC, Id, Instance, (SK_U8 *) pBuf, pLen );
++                break;
++        }
++    }
++    return (RetCode);
++}
++#endif /* SK_ASF */
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skgesirq.c linux-2.6.9.new/drivers/net/sk98lin/skgesirq.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skgesirq.c     2004-10-19 05:53:06.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skgesirq.c     2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgesirq.c
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.92 $
+- * Date:      $Date: 2003/09/16 14:37:07 $
++ * Version:   $Revision: 2.21 $
++ * Date:      $Date: 2005/03/03 15:49:58 $
+  * Purpose:   Special IRQ module
+  *
+  ******************************************************************************/
+@@ -11,13 +11,12 @@
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2005 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+  *    the Free Software Foundation; either version 2 of the License, or
+  *    (at your option) any later version.
+- *
+  *    The information in this file is provided "AS IS" without warranty.
+  *
+  ******************************************************************************/
+@@ -38,7 +37,7 @@
+  *    right after this ISR.
+  *
+  *    The Interrupt source register of the adapter is NOT read by this module.
+- *  SO if the drivers implementor needs a while loop around the
++ *    SO if the drivers implementor needs a while loop around the
+  *    slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for
+  *    each loop entered.
+  *
+@@ -46,11 +45,6 @@
+  *
+  */
+-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+-static const char SysKonnectFileId[] =
+-      "@(#) $Id: skgesirq.c,v 1.92 2003/09/16 14:37:07 rschmidt Exp $ (C) Marvell.";
+-#endif
+-
+ #include "h/skdrv1st.h"               /* Driver Specific Definitions */
+ #ifndef SK_SLIM
+ #include "h/skgepnmi.h"               /* PNMI Definitions */
+@@ -58,6 +52,13 @@
+ #endif
+ #include "h/skdrv2nd.h"               /* Adapter Control and Driver specific Def. */
++/* local variables ************************************************************/
++
++#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
++static const char SysKonnectFileId[] =
++      "@(#) $Id: skgesirq.c,v 2.21 2005/03/03 15:49:58 rschmidt Exp $ (C) Marvell.";
++#endif
++
+ /* local function prototypes */
+ #ifdef GENESIS
+ static int    SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL);
+@@ -86,7 +87,7 @@
+       XM_RXF_511B,
+       XM_RXF_1023B,
+       XM_RXF_MAX_SZ
+-} ;
++};
+ #endif /* GENESIS */
+ #ifdef __C2MAN__
+@@ -109,8 +110,8 @@
+  * Returns: N/A
+  */
+ static void SkHWInitDefSense(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+@@ -119,7 +120,7 @@
+       pPrt->PAutoNegTimeOut = 0;
+-      if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
++      if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
+               pPrt->PLinkMode = pPrt->PLinkModeConf;
+               return;
+       }
+@@ -145,8 +146,8 @@
+  *
+  */
+ static SK_U8 SkHWSenseGetNext(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+@@ -155,18 +156,18 @@
+       pPrt->PAutoNegTimeOut = 0;
+-    if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
++      if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
+               /* Leave all as configured */
+               return(pPrt->PLinkModeConf);
+       }
+-    if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) {
++      if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) {
+               /* Return next mode AUTOBOTH */
+-        return ((SK_U8)SK_LMODE_AUTOBOTH);
++              return((SK_U8)SK_LMODE_AUTOBOTH);
+       }
+       /* Return default autofull */
+-    return ((SK_U8)SK_LMODE_AUTOFULL);
++      return((SK_U8)SK_LMODE_AUTOFULL);
+ }     /* SkHWSenseGetNext */
+@@ -179,8 +180,8 @@
+  * Returns: N/A
+  */
+ static void SkHWSenseSetNext(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ SK_U8 NewMode)        /* New Mode to be written in sense mode */
+ {
+@@ -190,7 +191,7 @@
+       pPrt->PAutoNegTimeOut = 0;
+-    if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
++      if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
+               return;
+       }
+@@ -214,8 +215,8 @@
+  * Returns: N/A
+  */
+ void SkHWLinkDown(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+@@ -227,11 +228,11 @@
+       /* Disable Receiver and Transmitter */
+       SkMacRxTxDisable(pAC, IoC, Port);
+-      
++
+       /* Init default sense mode */
+       SkHWInitDefSense(pAC, IoC, Port);
+-      if (pPrt->PHWLinkUp == SK_FALSE) {
++      if (!pPrt->PHWLinkUp) {
+               return;
+       }
+@@ -242,8 +243,8 @@
+       pPrt->PHWLinkUp = SK_FALSE;
+       /* Reset Port stati */
+-    pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
+-    pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
++      pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
++      pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
+       pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED;
+       /* Re-init Phy especially when the AutoSense default is set now */
+@@ -266,8 +267,8 @@
+  * Returns: N/A
+  */
+ void SkHWLinkUp(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+@@ -281,11 +282,11 @@
+       pPrt->PHWLinkUp = SK_TRUE;
+       pPrt->PAutoNegFail = SK_FALSE;
+-    pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
++      pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
+-    if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF &&
+-        pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL &&
+-        pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) {
++      if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF &&
++              pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL &&
++              pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) {
+               /* Link is up and no Auto-negotiation should be done */
+               /* Link speed should be the configured one */
+@@ -304,18 +305,18 @@
+               }
+               /* Set Link Mode Status */
+-              if (pPrt->PLinkMode == SK_LMODE_FULL) {
++              if (pPrt->PLinkMode == (SK_U8)SK_LMODE_FULL) {
+                       pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL;
+               }
+               else {
+-            pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF;
++                      pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF;
+               }
+               /* No flow control without auto-negotiation */
+-        pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
++              pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
+               /* enable Rx/Tx */
+-        (void)SkMacRxTxEnable(pAC, IoC, Port);
++              (void)SkMacRxTxEnable(pAC, IoC, Port);
+       }
+ }     /* SkHWLinkUp */
+@@ -329,14 +330,16 @@
+  * Returns: N/A
+  */
+ static void SkMacParity(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
+-int           Port)   /* Port Index of the port failed */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O context */
++int           Port)   /* Port Index (MAC_1 + n) */
+ {
+       SK_EVPARA       Para;
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+       SK_U32          TxMax;          /* Tx Max Size Counter */
++      TxMax = 0;
++
+       pPrt = &pAC->GIni.GP[Port];
+       /* Clear IRQ Tx Parity Error */
+@@ -355,7 +358,7 @@
+                       pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE));
+       }
+ #endif /* YUKON */
+-      
++
+       if (pPrt->PCheckPar) {
+               if (Port == MAC_1) {
+@@ -366,7 +369,7 @@
+               }
+               Para.Para64 = Port;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+-              
++
+               Para.Para32[0] = Port;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+@@ -378,7 +381,7 @@
+       if (pAC->GIni.GIGenesis) {
+               /* Snap statistic counters */
+               (void)SkXmUpdateStats(pAC, IoC, Port);
+-              
++
+               (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax);
+       }
+ #endif /* GENESIS */
+@@ -399,15 +402,15 @@
+ /******************************************************************************
+  *
+- *    SkGeHwErr() - Hardware Error service routine
++ *    SkGeYuHwErr() - Hardware Error service routine (Genesis and Yukon)
+  *
+  * Description: handles all HW Error interrupts
+  *
+  * Returns: N/A
+  */
+-static void SkGeHwErr(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++static void SkGeYuHwErr(
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O context */
+ SK_U32        HwStatus)       /* Interrupt status word */
+ {
+       SK_EVPARA       Para;
+@@ -423,10 +426,10 @@
+               }
+               /* Reset all bits in the PCI STATUS register */
+-              SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
+-              
++              SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word);
++
+               SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+-        SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
++              SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
+               SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+               Para.Para64 = 0;
+@@ -484,14 +487,18 @@
+ #endif /* YUKON */
+       if ((HwStatus & IS_RAM_RD_PAR) != 0) {
++
+               SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR);
++
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG);
+               Para.Para64 = 0;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
+       }
+       if ((HwStatus & IS_RAM_WR_PAR) != 0) {
++
+               SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR);
++
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG);
+               Para.Para64 = 0;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
+@@ -512,7 +519,7 @@
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
+               Para.Para64 = MAC_1;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+-              
++
+               Para.Para32[0] = MAC_1;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+       }
+@@ -524,37 +531,286 @@
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
+               Para.Para64 = MAC_2;
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
+-              
++
+               Para.Para32[0] = MAC_2;
+               SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
+       }
+-}     /* SkGeHwErr */
++}     /* SkGeYuHwErr */
++
++#ifdef YUK2
++/******************************************************************************
++ *
++ *    SkYuk2HwPortErr() - Service HW Errors for specified port (Yukon-2 only)
++ *
++ * Description: handles the HW Error interrupts for a specific port.
++ *
++ * Returns: N/A
++ */
++static void SkYuk2HwPortErr(
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
++SK_U32        HwStatus,       /* Interrupt status word */
++int           Port)           /* Port Index (MAC_1 + n) */
++{
++      SK_EVPARA       Para;
++      int                     Queue;
++
++      if (Port == MAC_2) {
++              HwStatus >>= 8;
++      }
++
++      if ((HwStatus & Y2_HWE_L1_MASK) == 0) {
++              return;
++      }
++
++      if ((HwStatus & Y2_IS_PAR_RD1) != 0) {
++              /* Clear IRQ */
++              SK_OUT16(IoC, SELECT_RAM_BUFFER(Port, B3_RI_CTRL), RI_CLR_RD_PERR);
++
++              if (Port == MAC_1) {
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E028, SKERR_SIRQ_E028MSG);
++              }
++              else {
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E030, SKERR_SIRQ_E030MSG);
++              }
++      }
++
++      if ((HwStatus & Y2_IS_PAR_WR1) != 0) {
++              /* Clear IRQ */
++              SK_OUT16(IoC, SELECT_RAM_BUFFER(Port, B3_RI_CTRL), RI_CLR_WR_PERR);
++              if (Port == MAC_1) {
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E029, SKERR_SIRQ_E029MSG);
++              }
++              else {
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E031, SKERR_SIRQ_E031MSG);
++              }
++      }
++
++      if ((HwStatus & Y2_IS_PAR_MAC1) != 0) {
++              /* Clear IRQ */
++              SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), GMF_CLI_TX_PE);
++
++              if (Port == MAC_1) {
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG);
++              }
++              else {
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG);
++              }
++      }
++
++      if ((HwStatus & Y2_IS_PAR_RX1) != 0) {
++              if (Port == MAC_1) {
++                      Queue = Q_R1;
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
++              }
++              else {
++                      Queue = Q_R2;
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
++              }
++              /* Clear IRQ */
++              SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_PAR);
++      }
++
++      if ((HwStatus & Y2_IS_TCP_TXS1) != 0) {
++              if (Port == MAC_1) {
++                      Queue = Q_XS1;
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E033, SKERR_SIRQ_E033MSG);
++              }
++              else {
++                      Queue = Q_XS2;
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E035, SKERR_SIRQ_E035MSG);
++              }
++              /* Clear IRQ */
++              SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_TCP);
++      }
++
++      if ((HwStatus & Y2_IS_TCP_TXA1) != 0) {
++              if (Port == MAC_1) {
++                      Queue = Q_XA1;
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E032, SKERR_SIRQ_E032MSG);
++              }
++              else {
++                      Queue = Q_XA2;
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E034, SKERR_SIRQ_E034MSG);
++              }
++              /* Clear IRQ */
++              SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_TCP);
++      }
++
++      Para.Para64 = Port;
++      SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
++
++      Para.Para32[0] = Port;
++      SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
++
++}     /* SkYuk2HwPortErr */
+ /******************************************************************************
+  *
+- *    SkGeSirqIsr() - Special Interrupt Service Routine
++ *    SkYuk2HwErr() - Hardware Error service routine (Yukon-2 only)
+  *
+- * Description: handles all non data transfer specific interrupts (slow path)
++ * Description: handles all HW Error interrupts
++ *
++ * Returns: N/A
++ */
++static void SkYuk2HwErr(
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
++SK_U32        HwStatus)       /* Interrupt status word */
++{
++      SK_EVPARA       Para;
++      SK_U16          Word;
++      SK_U32          DWord;
++      SK_U32          TlpHead[4];
++      int                     i;
++
++      /* This is necessary only for Rx timing measurements */
++      if ((HwStatus & Y2_IS_TIST_OV) != 0) {
++              /* increment Time Stamp Timer counter (high) */
++              pAC->GIni.GITimeStampCnt++;
++
++              /* Clear Time Stamp Timer IRQ */
++              SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ);
++      }
++
++      /* Evaluate Y2_IS_PCI_NEXP before Y2_IS_MST_ERR or Y2_IS_IRQ_STAT */
++      if ((HwStatus & Y2_IS_PCI_NEXP) != 0) {
++              /* PCI-Express Error occured which is not described in PEX spec. */
++              /*
++               * This error is also mapped either to Master Abort (Y2_IS_MST_ERR)
++               * or Target Abort (Y2_IS_IRQ_STAT) bit and can only be cleared there.
++               * Therefore handle this event just by printing an error log entry.
++               */
++              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E027, SKERR_SIRQ_E027MSG);
++      }
++
++      if ((HwStatus & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) != 0) {
++              /* PCI Errors occured */
++              if ((HwStatus & Y2_IS_IRQ_STAT) != 0) {
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG);
++              }
++              else {
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG);
++              }
++
++              /* Reset all bits in the PCI STATUS register */
++              SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word);
++
++              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
++              SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
++              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
++
++              Para.Para64 = 0;
++              SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
++      }
++
++      /* check for PCI-Express Uncorrectable Error*/
++      if ((HwStatus & Y2_IS_PCI_EXP) != 0) {
++              /*
++               * On PCI-Express bus bridges are called root complexes (RC).
++               * PCI-Express errors are recognized by the root complex too,
++               * which requests the system to handle the problem. After error
++               * occurence it may be that no access to the adapter may be performed
++               * any longer.
++               */
++
++              /* Get uncorrectable error status */
++              SK_IN32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), &DWord);
++
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
++                      ("PEX Uncorr.Error Status: 0x%08lX\n", DWord));
++
++              if (DWord != PEX_UNSUP_REQ) {
++                      /* ignore Unsupported Request Errors */
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E026, SKERR_SIRQ_E026MSG);
++              }
++
++              if ((DWord & (PEX_FATAL_ERRORS | PEX_POIS_TLP)) != 0) {
++                      /*
++                       * Stop only, if the uncorrectable error is fatal or
++                       * Poisoned TLP occured
++                       */
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Header Log:"));
++
++                      for (i = 0; i < 4; i++) {
++                              /* get TLP Header from Log Registers */
++                              SK_IN32(IoC, PCI_C(pAC, PEX_HEADER_LOG + i*4), TlpHead + i);
++
++                              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
++                                      (" 0x%08lX", TlpHead[i]));
++                      }
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("\n"));
++
++                      /* check for vendor defined broadcast message */
++                      if (TlpHead[0] == 0x73004001 && (SK_U8)TlpHead[1] == 0x7f) {
++
++                              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
++                                      ("Vendor defined broadcast message\n"));
++                      }
++                      else {
++                              Para.Para64 = 0;
++                              SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
++
++                              pAC->GIni.GIValHwIrqMask &= ~Y2_IS_PCI_EXP;
++                              /* Rewrite HW IRQ mask */
++                              SK_OUT32(IoC, B0_HWE_IMSK, pAC->GIni.GIValHwIrqMask);
++                      }
++              }
++              /* clear the interrupt */
++              SK_OUT32(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
++              SK_OUT32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), 0xffffffffUL);
++              SK_OUT32(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
++      }
++
++      for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
++
++              SkYuk2HwPortErr(pAC, IoC, HwStatus, i);
++      }
++
++}     /* SkYuk2HwErr */
++#endif /* YUK2 */
++
++/******************************************************************************
++ *
++ *    SkGeSirqIsr() - Wrapper for Special Interrupt Service Routine
++ *
++ * Description: calls the preselected special ISR (slow path)
+  *
+  * Returns: N/A
+  */
+ void SkGeSirqIsr(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O context */
++SK_U32        Istatus)        /* Interrupt status word */
++{
++      pAC->GIni.GIFunc.pSkGeSirqIsr(pAC, IoC, Istatus);
++}
++
++/******************************************************************************
++ *
++ *    SkGeYuSirqIsr() - Special Interrupt Service Routine
++ *
++ * Description: handles all non data transfer specific interrupts (slow path)
++ *
++ * Returns: N/A
++ */
++void SkGeYuSirqIsr(
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ SK_U32        Istatus)        /* Interrupt status word */
+ {
+       SK_EVPARA       Para;
+       SK_U32          RegVal32;       /* Read register value */
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+-      SK_U16          PhyInt;
++      SK_U16          PhyInt;
+       int                     i;
+       if (((Istatus & IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) {
+               /* read the HW Error Interrupt source */
+               SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
+-              
+-              SkGeHwErr(pAC, IoC, RegVal32);
++
++              SkGeYuHwErr(pAC, IoC, RegVal32);
+       }
+       /*
+@@ -569,7 +825,7 @@
+       }
+       if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) &&
+-          pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {
++              pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {
+               /* MAC 2 was not initialized but Packet timeout occured */
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,
+                       SKERR_SIRQ_E005MSG);
+@@ -590,8 +846,8 @@
+       }
+       if ((Istatus & IS_PA_TO_TX1) != 0) {
+-              
+-              pPrt = &pAC->GIni.GP[0];
++
++              pPrt = &pAC->GIni.GP[MAC_1];
+               /* May be a normal situation in a server with a slow network */
+               SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1);
+@@ -612,25 +868,18 @@
+                                * we ignore those
+                                */
+                               pPrt->HalfDupTimerActive = SK_TRUE;
+-#ifdef XXX
+-                              Len = sizeof(SK_U64);
+-                              SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
+-                                      &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 0),
+-                                      pAC->Rlmt.Port[0].Net->NetNumber);
+-                              
+-                              pPrt->LastOctets = Octets;
+-#endif /* XXX */
++
+                               /* Snap statistic counters */
+                               (void)SkXmUpdateStats(pAC, IoC, 0);
+                               (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_HI, &RegVal32);
+                               pPrt->LastOctets = (SK_U64)RegVal32 << 32;
+-                              
++
+                               (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_LO, &RegVal32);
+                               pPrt->LastOctets += RegVal32;
+-                              
++
+                               Para.Para32[0] = 0;
+                               SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
+                                       SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
+@@ -640,8 +889,8 @@
+       }
+       if ((Istatus & IS_PA_TO_TX2) != 0) {
+-              
+-              pPrt = &pAC->GIni.GP[1];
++
++              pPrt = &pAC->GIni.GP[MAC_2];
+               /* May be a normal situation in a server with a slow network */
+               SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2);
+@@ -653,25 +902,18 @@
+                                pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
+                               !pPrt->HalfDupTimerActive) {
+                               pPrt->HalfDupTimerActive = SK_TRUE;
+-#ifdef XXX
+-                              Len = sizeof(SK_U64);
+-                              SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
+-                                      &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 1),
+-                                      pAC->Rlmt.Port[1].Net->NetNumber);
+-                              
+-                              pPrt->LastOctets = Octets;
+-#endif /* XXX */
++
+                               /* Snap statistic counters */
+                               (void)SkXmUpdateStats(pAC, IoC, 1);
+                               (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_HI, &RegVal32);
+                               pPrt->LastOctets = (SK_U64)RegVal32 << 32;
+-                              
++
+                               (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_LO, &RegVal32);
+                               pPrt->LastOctets += RegVal32;
+-                              
++
+                               Para.Para32[0] = 1;
+                               SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
+                                       SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
+@@ -684,6 +926,7 @@
+       if ((Istatus & IS_R1_C) != 0) {
+               /* Clear IRQ */
+               SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);
++
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,
+                       SKERR_SIRQ_E006MSG);
+               Para.Para64 = MAC_1;
+@@ -695,6 +938,7 @@
+       if ((Istatus & IS_R2_C) != 0) {
+               /* Clear IRQ */
+               SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);
++
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,
+                       SKERR_SIRQ_E007MSG);
+               Para.Para64 = MAC_2;
+@@ -706,6 +950,7 @@
+       if ((Istatus & IS_XS1_C) != 0) {
+               /* Clear IRQ */
+               SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);
++
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,
+                       SKERR_SIRQ_E008MSG);
+               Para.Para64 = MAC_1;
+@@ -717,6 +962,7 @@
+       if ((Istatus & IS_XA1_C) != 0) {
+               /* Clear IRQ */
+               SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);
++
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,
+                       SKERR_SIRQ_E009MSG);
+               Para.Para64 = MAC_1;
+@@ -728,6 +974,7 @@
+       if ((Istatus & IS_XS2_C) != 0) {
+               /* Clear IRQ */
+               SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);
++
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,
+                       SKERR_SIRQ_E010MSG);
+               Para.Para64 = MAC_2;
+@@ -739,6 +986,7 @@
+       if ((Istatus & IS_XA2_C) != 0) {
+               /* Clear IRQ */
+               SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);
++
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,
+                       SKERR_SIRQ_E011MSG);
+               Para.Para64 = MAC_2;
+@@ -751,39 +999,37 @@
+       if ((Istatus & IS_EXT_REG) != 0) {
+               /* Test IRQs from PHY */
+               for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+-                      
++
+                       pPrt = &pAC->GIni.GP[i];
+-                      
++
+                       if (pPrt->PState == SK_PRT_RESET) {
+                               continue;
+                       }
+-                      
++
+ #ifdef GENESIS
+                       if (pAC->GIni.GIGenesis) {
+-                              
++
+                               switch (pPrt->PhyType) {
+-                              
++
+                               case SK_PHY_XMAC:
+                                       break;
+-                              
++
+                               case SK_PHY_BCOM:
+                                       SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt);
+-      
++
+                                       if ((PhyInt & ~PHY_B_DEF_MSK) != 0) {
+                                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+-                                                      ("Port %d Bcom Int: 0x%04X\n",
+-                                                      i, PhyInt));
++                                                      ("Port %d PHY Int: 0x%04X\n", i, PhyInt));
+                                               SkPhyIsrBcom(pAC, IoC, i, PhyInt);
+                                       }
+                                       break;
+ #ifdef OTHER_PHY
+                               case SK_PHY_LONE:
+                                       SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt);
+-                                      
++
+                                       if ((PhyInt & PHY_L_DEF_MSK) != 0) {
+                                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+-                                                      ("Port %d Lone Int: %x\n",
+-                                                      i, PhyInt));
++                                                      ("Port %d PHY Int: 0x%04X\n", i, PhyInt));
+                                               SkPhyIsrLone(pAC, IoC, i, PhyInt);
+                                       }
+                                       break;
+@@ -791,7 +1037,7 @@
+                               }
+                       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+                       if (pAC->GIni.GIYukon) {
+                               /* Read PHY Interrupt Status */
+@@ -799,8 +1045,7 @@
+                               if ((PhyInt & PHY_M_DEF_MSK) != 0) {
+                                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+-                                              ("Port %d Marv Int: 0x%04X\n",
+-                                              i, PhyInt));
++                                              ("Port %d PHY Int: 0x%04X\n", i, PhyInt));
+                                       SkPhyIsrGmac(pAC, IoC, i, PhyInt);
+                               }
+                       }
+@@ -808,13 +1053,13 @@
+               }
+       }
+-      /* I2C Ready interrupt */
++      /* TWSI Ready interrupt */
+       if ((Istatus & IS_I2C_READY) != 0) {
+ #ifdef SK_SLIM
+-        SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
+-#else         
++              SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
++#else
+               SkI2cIsr(pAC, IoC);
+-#endif                
++#endif
+       }
+       /* SW forced interrupt */
+@@ -829,7 +1074,7 @@
+                * us only a link going down.
+                */
+               /* clear interrupt */
+-              SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);
++              SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LNK_CLR_IRQ);
+       }
+       /* Check MAC after link sync counter */
+@@ -844,7 +1089,7 @@
+                * us only a link going down.
+                */
+               /* clear interrupt */
+-              SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ);
++              SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LNK_CLR_IRQ);
+       }
+       /* Check MAC after link sync counter */
+@@ -860,13 +1105,189 @@
+                       /* read the HW Error Interrupt source */
+                       SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
+-                      SkGeHwErr(pAC, IoC, RegVal32);
++                      SkGeYuHwErr(pAC, IoC, RegVal32);
+               }
+               SkHwtIsr(pAC, IoC);
+       }
+-}     /* SkGeSirqIsr */
++}     /* SkGeYuSirqIsr */
++
++#ifdef YUK2
++/******************************************************************************
++ *
++ *    SkYuk2PortSirq() - Service HW Errors for specified port (Yukon-2 only)
++ *
++ * Description: handles the HW Error interrupts for a specific port.
++ *
++ * Returns: N/A
++ */
++static void SkYuk2PortSirq(
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
++SK_U32        IStatus,        /* Interrupt status word */
++int           Port)           /* Port Index (MAC_1 + n) */
++{
++      SK_EVPARA       Para;
++      int                     Queue;
++      SK_U16          PhyInt;
++
++      if (Port == MAC_2) {
++              IStatus >>= 8;
++      }
++
++      /* Interrupt from PHY */
++      if ((IStatus & Y2_IS_IRQ_PHY1) != 0) {
++              /* Read PHY Interrupt Status */
++              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyInt);
++
++              if ((PhyInt & PHY_M_DEF_MSK) != 0) {
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
++                              ("Port %d PHY Int: 0x%04X\n", Port, PhyInt));
++                      SkPhyIsrGmac(pAC, IoC, Port, PhyInt);
++              }
++      }
++
++      /* Interrupt from MAC */
++      if ((IStatus & Y2_IS_IRQ_MAC1) != 0) {
++              SkMacIrq(pAC, IoC, Port);
++      }
++
++      if ((IStatus & (Y2_IS_CHK_RX1 | Y2_IS_CHK_TXS1 | Y2_IS_CHK_TXA1)) != 0) {
++              if ((IStatus & Y2_IS_CHK_RX1) != 0) {
++                      if (Port == MAC_1) {
++                              Queue = Q_R1;
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E006,
++                                      SKERR_SIRQ_E006MSG);
++                      }
++                      else {
++                              Queue = Q_R2;
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E007,
++                                      SKERR_SIRQ_E007MSG);
++                      }
++                      /* Clear IRQ */
++                      SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK);
++              }
++
++              if ((IStatus & Y2_IS_CHK_TXS1) != 0) {
++                      if (Port == MAC_1) {
++                              Queue = Q_XS1;
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E008,
++                                      SKERR_SIRQ_E008MSG);
++                      }
++                      else {
++                              Queue = Q_XS2;
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E010,
++                                      SKERR_SIRQ_E010MSG);
++                      }
++                      /* Clear IRQ */
++                      SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK);
++              }
++
++              if ((IStatus & Y2_IS_CHK_TXA1) != 0) {
++                      if (Port == MAC_1) {
++                              Queue = Q_XA1;
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E009,
++                                      SKERR_SIRQ_E009MSG);
++                      }
++                      else {
++                              Queue = Q_XA2;
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E011,
++                                      SKERR_SIRQ_E011MSG);
++                      }
++                      /* Clear IRQ */
++                      SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK);
++              }
++
++              Para.Para64 = Port;
++              SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
++
++              Para.Para32[0] = Port;
++              SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
++      }
++}     /* SkYuk2PortSirq */
++#endif /* YUK2 */
++
++/******************************************************************************
++ *
++ *    SkYuk2SirqIsr() - Special Interrupt Service Routine     (Yukon-2 only)
++ *
++ * Description: handles all non data transfer specific interrupts (slow path)
++ *
++ * Returns: N/A
++ */
++void SkYuk2SirqIsr(
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
++SK_U32        Istatus)        /* Interrupt status word */
++{
++#ifdef YUK2
++      SK_EVPARA       Para;
++      SK_U32          RegVal32;       /* Read register value */
++      SK_U8           Value;
++
++      /* HW Error indicated ? */
++      if (((Istatus & Y2_IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) {
++              /* read the HW Error Interrupt source */
++              SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
++
++              SkYuk2HwErr(pAC, IoC, RegVal32);
++      }
++
++      /* Interrupt from ASF Subsystem */
++      if ((Istatus & Y2_IS_ASF) != 0) {
++              /* clear IRQ */
++              /* later on clearing should be done in ASF ISR handler */
++              SK_IN8(IoC, B28_Y2_ASF_STAT_CMD, &Value);
++              Value |= Y2_ASF_CLR_HSTI;
++              SK_OUT8(IoC, B28_Y2_ASF_STAT_CMD, Value);
++              /* Call IRQ handler in ASF Module */
++              /* TBD */
++      }
++
++      /* Check IRQ from polling unit */
++      if ((Istatus & Y2_IS_POLL_CHK) != 0) {
++              /* Clear IRQ */
++              SK_OUT32(IoC, POLL_CTRL, PC_CLR_IRQ_CHK);
++
++              SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E036,
++                      SKERR_SIRQ_E036MSG);
++              Para.Para64 = 0;
++              SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
++      }
++
++      /* TWSI Ready interrupt */
++      if ((Istatus & Y2_IS_TWSI_RDY) != 0) {
++#ifdef SK_SLIM
++              SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
++#else
++              SkI2cIsr(pAC, IoC);
++#endif
++      }
++
++      /* SW forced interrupt */
++      if ((Istatus & Y2_IS_IRQ_SW) != 0) {
++              /* clear the software IRQ */
++              SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ);
++      }
++
++      if ((Istatus & Y2_IS_L1_MASK) != 0) {
++              SkYuk2PortSirq(pAC, IoC, Istatus, MAC_1);
++      }
++
++      if ((Istatus & Y2_IS_L2_MASK) != 0) {
++              SkYuk2PortSirq(pAC, IoC, Istatus, MAC_2);
++      }
++
++      /* Timer interrupt (served last) */
++      if ((Istatus & Y2_IS_TIMINT) != 0) {
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
++                      ("Timer Int: 0x%08lX\n", Istatus));
++              SkHwtIsr(pAC, IoC);
++      }
++#endif        /* YUK2 */
++
++}     /* SkYuk2SirqIsr */
+ #ifdef GENESIS
+@@ -880,8 +1301,8 @@
+  */
+ static int SkGePortCheckShorts(
+ SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* IO Context */
+-int           Port)           /* Which port should be checked */
++SK_IOC        IoC,            /* I/O Context */
++int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_U32          Shorts;                 /* Short Event Counter */
+       SK_U32          CheckShorts;    /* Check value for Short Event Counter */
+@@ -909,9 +1330,9 @@
+       RxCts = 0;
+       for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {
+-              
++
+               (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
+-              
++
+               RxCts += (SK_U64)RxTmp;
+       }
+@@ -928,11 +1349,11 @@
+               CheckShorts = 2;
+               (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts);
+-              
+-              if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
+-                  pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
+-                  (pPrt->PLinkMode == SK_LMODE_HALF ||
+-                       pPrt->PLinkMode == SK_LMODE_FULL)) {
++
++              if (pPrt->PLinkModeConf == (SK_U8)SK_LMODE_AUTOSENSE &&
++                      pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_UNKNOWN &&
++                      (pPrt->PLinkMode == (SK_U8)SK_LMODE_HALF ||
++                       pPrt->PLinkMode == (SK_U8)SK_LMODE_FULL)) {
+                       /*
+                        * This is autosensing and we are in the fallback
+                        * manual full/half duplex mode.
+@@ -941,16 +1362,16 @@
+                               /* Nothing received, restart link */
+                               pPrt->PPrevFcs = FcsErrCts;
+                               pPrt->PPrevShorts = Shorts;
+-                              
++
+                               return(SK_HW_PS_RESTART);
+                       }
+                       else {
+-                              pPrt->PLipaAutoNeg = SK_LIPA_MANUAL;
++                              pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_MANUAL;
+                       }
+               }
+               if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||
+-                  (!(FcsErrCts - pPrt->PPrevFcs))) {
++                      (!(FcsErrCts - pPrt->PPrevFcs))) {
+                       /*
+                        * Note: The compare with zero above has to be done the way shown,
+                        * otherwise the Linux driver will have a problem.
+@@ -995,29 +1416,25 @@
+  */
+ static int SkGePortCheckUp(
+ SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* IO Context */
+-int           Port)           /* Which port should be checked */
++SK_IOC        IoC,            /* I/O Context */
++int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+       SK_BOOL         AutoNeg;        /* Is Auto-negotiation used ? */
+       int                     Rtv;            /* Return value */
+       Rtv = SK_HW_PS_NONE;
+-      
++
+       pPrt = &pAC->GIni.GP[Port];
+-      if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+-              AutoNeg = SK_FALSE;
+-      }
+-      else {
+-              AutoNeg = SK_TRUE;
+-      }
++      AutoNeg = pPrt->PLinkMode != SK_LMODE_HALF &&
++                        pPrt->PLinkMode != SK_LMODE_FULL;
+ #ifdef GENESIS
+       if (pAC->GIni.GIGenesis) {
+               switch (pPrt->PhyType) {
+-              
++
+               case SK_PHY_XMAC:
+                       Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg);
+                       break;
+@@ -1038,7 +1455,7 @@
+       
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+-              
++
+               Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg);
+       }
+ #endif /* YUKON */
+@@ -1059,8 +1476,8 @@
+  */
+ static int SkGePortCheckUpXmac(
+ SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* IO Context */
+-int           Port,           /* Which port should be checked */
++SK_IOC        IoC,            /* I/O Context */
++int           Port,           /* Port Index (MAC_1 + n) */
+ SK_BOOL       AutoNeg)        /* Is Auto-negotiation used ? */
+ {
+       SK_U32          Shorts;         /* Short Event Counter */
+@@ -1098,7 +1515,7 @@
+                       XM_IN16(IoC, Port, XM_ISRC, &Isrc);
+                       IsrcSum |= Isrc;
+                       SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
+-                      
++
+                       if ((Isrc & XM_IS_INP_ASS) == 0) {
+                               /* It has been in sync since last time */
+                               /* Restart the PORT */
+@@ -1117,14 +1534,14 @@
+                                * Link Restart Workaround:
+                                *  it may be possible that the other Link side
+                                *  restarts its link as well an we detect
+-                               *  another LinkBroken. To prevent this
++                               *  another PLinkBroken. To prevent this
+                                *  happening we check for a maximum number
+                                *  of consecutive restart. If those happens,
+                                *  we do NOT restart the active link and
+                                *  check whether the link is now o.k.
+                                */
+                               pPrt->PLinkResCt++;
+-                              
++
+                               pPrt->PAutoNegTimeOut = 0;
+                               if (pPrt->PLinkResCt < SK_MAX_LRESTART) {
+@@ -1132,13 +1549,13 @@
+                               }
+                               pPrt->PLinkResCt = 0;
+-                              
++
+                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                                       ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));
+                       }
+                       else {
+                               pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
+-                              
++
+                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                                       ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));
+@@ -1165,7 +1582,7 @@
+                               if ((Isrc & XM_IS_INP_ASS) != 0) {
+                                       pPrt->PLinkBroken = SK_TRUE;
+                                       /* Re-Init Link partner Autoneg flag */
+-                                      pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
++                                      pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN;
+                                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                                               ("Link broken Port %d\n", Port));
+@@ -1178,7 +1595,7 @@
+               }
+               else {
+                       SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);
+-                      
++
+                       if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) {
+                               return(SK_HW_PS_RESTART);
+                       }
+@@ -1210,17 +1627,21 @@
+       }
+       if (AutoNeg) {
++              /* Auto-Negotiation Done ? */
+               if ((IsrcSum & XM_IS_AND) != 0) {
++
+                       SkHWLinkUp(pAC, IoC, Port);
++
+                       Done = SkMacAutoNegDone(pAC, IoC, Port);
++
+                       if (Done != SK_AND_OK) {
+                               /* Get PHY parameters, for debugging only */
+                               SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb);
+                               SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
+-                              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                                       ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n",
+-                                       Port, LpAb, ResAb));
+-                                      
++                                      Port, LpAb, ResAb));
++
+                               /* Try next possible mode */
+                               NextMode = SkHWSenseGetNext(pAC, IoC, Port);
+                               SkHWLinkDown(pAC, IoC, Port);
+@@ -1236,42 +1657,41 @@
+                        * (clear Page Received bit if set)
+                        */
+                       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
+-                      
++
+                       return(SK_HW_PS_LINK);
+               }
+-              
++
+               /* AutoNeg not done, but HW link is up. Check for timeouts */
+-              pPrt->PAutoNegTimeOut++;
+-              if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
++              if (pPrt->PAutoNegTimeOut++ >= SK_AND_MAX_TO) {
+                       /* Increase the Timeout counter */
+                       pPrt->PAutoNegTOCt++;
+                       /* Timeout occured */
+                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                               ("AutoNeg timeout Port %d\n", Port));
+-                      if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
+-                              pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
++                      if (pPrt->PLinkModeConf == (SK_U8)SK_LMODE_AUTOSENSE &&
++                              pPrt->PLipaAutoNeg != (SK_U8)SK_LIPA_AUTO) {
+                               /* Set Link manually up */
+                               SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
+                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                                       ("Set manual full duplex Port %d\n", Port));
+                       }
+-                      if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
+-                              pPrt->PLipaAutoNeg == SK_LIPA_AUTO &&
++                      if (pPrt->PLinkModeConf == (SK_U8)SK_LMODE_AUTOSENSE &&
++                              pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO &&
+                               pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) {
+                               /*
+                                * This is rather complicated.
+                                * we need to check here whether the LIPA_AUTO
+                                * we saw before is false alert. We saw at one
+-                               * switch ( SR8800) that on boot time it sends
++                               * switch (SR8800) that on boot time it sends
+                                * just one auto-neg packet and does no further
+                                * auto-negotiation.
+                                * Solution: we restart the autosensing after
+                                * a few timeouts.
+                                */
+                               pPrt->PAutoNegTOCt = 0;
+-                              pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
++                              pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN;
+                               SkHWInitDefSense(pAC, IoC, Port);
+                       }
+@@ -1282,18 +1702,18 @@
+       else {
+               /* Link is up and we don't need more */
+ #ifdef DEBUG
+-              if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
+-                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              if (pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO) {
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                               ("ERROR: Lipa auto detected on port %d\n", Port));
+               }
+ #endif /* DEBUG */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                       ("Link sync(GP), Port %d\n", Port));
+               SkHWLinkUp(pAC, IoC, Port);
+-              
++
+               /*
+-               * Link sync (GP) and so assume a good connection. But if not received
+-               * a bunch of frames received in a time slot (maybe broken tx cable)
++               * Link sync (GP) and so assume a good connection. But if no
++               * bunch of frames received in a time slot (maybe broken Tx cable)
+                * the port is restart.
+                */
+               return(SK_HW_PS_LINK);
+@@ -1314,8 +1734,8 @@
+  */
+ static int SkGePortCheckUpBcom(
+ SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* IO Context */
+-int           Port,           /* Which port should be checked */
++SK_IOC        IoC,            /* I/O Context */
++int           Port,           /* Port Index (MAC_1 + n) */
+ SK_BOOL       AutoNeg)        /* Is Auto-negotiation used ? */
+ {
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+@@ -1334,74 +1754,6 @@
+       /* Check for No HCD Link events (#10523) */
+       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);
+-#ifdef xDEBUG
+-      if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT) ==
+-              (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) {
+-
+-              SK_U32  Stat1, Stat2, Stat3;
+-
+-              Stat1 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
+-              CMSMPrintString(
+-                      pAC->pConfigTable,
+-                      MSG_TYPE_RUNTIME_INFO,
+-                      "CheckUp1 - Stat: %x, Mask: %x",
+-                      (void *)Isrc,
+-                      (void *)Stat1);
+-
+-              Stat1 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
+-              Stat2 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2);
+-              Stat1 = Stat1 << 16 | Stat2;
+-              Stat2 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
+-              Stat3 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
+-              Stat2 = Stat2 << 16 | Stat3;
+-              CMSMPrintString(
+-                      pAC->pConfigTable,
+-                      MSG_TYPE_RUNTIME_INFO,
+-                      "Ctrl/Stat: %x, AN Adv/LP: %x",
+-                      (void *)Stat1,
+-                      (void *)Stat2);
+-
+-              Stat1 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
+-              Stat2 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
+-              Stat1 = Stat1 << 16 | Stat2;
+-              Stat2 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
+-              Stat3 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3);
+-              Stat2 = Stat2 << 16 | Stat3;
+-              CMSMPrintString(
+-                      pAC->pConfigTable,
+-                      MSG_TYPE_RUNTIME_INFO,
+-                      "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
+-                      (void *)Stat1,
+-                      (void *)Stat2);
+-
+-              Stat1 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
+-              Stat2 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
+-              Stat1 = Stat1 << 16 | Stat2;
+-              Stat2 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
+-              Stat3 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
+-              Stat2 = Stat2 << 16 | Stat3;
+-              CMSMPrintString(
+-                      pAC->pConfigTable,
+-                      MSG_TYPE_RUNTIME_INFO,
+-                      "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
+-                      (void *)Stat1,
+-                      (void *)Stat2);
+-      }
+-#endif /* DEBUG */
+-
+       if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) {
+               /*
+                * Workaround BCom Errata:
+@@ -1414,14 +1766,6 @@
+                       (SK_U16)(Ctrl & ~PHY_CT_LOOP));
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("No HCD Link event, Port %d\n", Port));
+-#ifdef xDEBUG
+-              CMSMPrintString(
+-                      pAC->pConfigTable,
+-                      MSG_TYPE_RUNTIME_INFO,
+-                      "No HCD link event, port %d.",
+-                      (void *)Port,
+-                      (void *)NULL);
+-#endif /* DEBUG */
+       }
+       /* Not obsolete: link status bit is latched to 0 and autoclearing! */
+@@ -1431,72 +1775,6 @@
+               return(SK_HW_PS_NONE);
+       }
+-#ifdef xDEBUG
+-      {
+-              SK_U32  Stat1, Stat2, Stat3;
+-
+-              Stat1 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
+-              CMSMPrintString(
+-                      pAC->pConfigTable,
+-                      MSG_TYPE_RUNTIME_INFO,
+-                      "CheckUp1a - Stat: %x, Mask: %x",
+-                      (void *)Isrc,
+-                      (void *)Stat1);
+-
+-              Stat1 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
+-              Stat2 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
+-              Stat1 = Stat1 << 16 | PhyStat;
+-              Stat2 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
+-              Stat3 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
+-              Stat2 = Stat2 << 16 | Stat3;
+-              CMSMPrintString(
+-                      pAC->pConfigTable,
+-                      MSG_TYPE_RUNTIME_INFO,
+-                      "Ctrl/Stat: %x, AN Adv/LP: %x",
+-                      (void *)Stat1,
+-                      (void *)Stat2);
+-
+-              Stat1 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
+-              Stat2 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
+-              Stat1 = Stat1 << 16 | Stat2;
+-              Stat2 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
+-              Stat3 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
+-              Stat2 = Stat2 << 16 | ResAb;
+-              CMSMPrintString(
+-                      pAC->pConfigTable,
+-                      MSG_TYPE_RUNTIME_INFO,
+-                      "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
+-                      (void *)Stat1,
+-                      (void *)Stat2);
+-
+-              Stat1 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
+-              Stat2 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
+-              Stat1 = Stat1 << 16 | Stat2;
+-              Stat2 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
+-              Stat3 = 0;
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
+-              Stat2 = Stat2 << 16 | Stat3;
+-              CMSMPrintString(
+-                      pAC->pConfigTable,
+-                      MSG_TYPE_RUNTIME_INFO,
+-                      "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
+-                      (void *)Stat1,
+-                      (void *)Stat2);
+-      }
+-#endif /* DEBUG */
+-
+       /*
+        * Here we usually can check whether the link is in sync and
+        * auto-negotiation is done.
+@@ -1505,7 +1783,7 @@
+       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
+       SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
+-      
++
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
+@@ -1513,88 +1791,62 @@
+       if ((ResAb & PHY_B_1000S_MSF) != 0) {
+               /* Error */
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                      ("Master/Slave Fault port %d\n", Port));
+-              
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
++                      ("Master/Slave Fault, ResAb: 0x%04X\n", ResAb));
++
+               pPrt->PAutoNegFail = SK_TRUE;
+               pPrt->PMSStatus = SK_MS_STAT_FAULT;
+-              
++
+               return(SK_HW_PS_RESTART);
+       }
+       if ((PhyStat & PHY_ST_LSYNC) == 0) {
+               return(SK_HW_PS_NONE);
+       }
+-      
++
+       pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
+               SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
+-      
++
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("Port %d, ResAb: 0x%04X\n", Port, ResAb));
+       if (AutoNeg) {
++              /* Auto-Negotiation Over ? */
+               if ((PhyStat & PHY_ST_AN_OVER) != 0) {
+-                      
++
+                       SkHWLinkUp(pAC, IoC, Port);
+-                      
++
+                       Done = SkMacAutoNegDone(pAC, IoC, Port);
+-                      
++
+                       if (Done != SK_AND_OK) {
+ #ifdef DEBUG
+                               /* Get PHY parameters, for debugging only */
+                               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb);
+                               SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat);
+-                              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                                       ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
+                                       Port, LpAb, ExtStat));
+ #endif /* DEBUG */
+                               return(SK_HW_PS_RESTART);
+                       }
+                       else {
+-#ifdef xDEBUG
+-                              /* Dummy read ISR to prevent extra link downs/ups */
+-                              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
+-
+-                              if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
+-                                      CMSMPrintString(
+-                                              pAC->pConfigTable,
+-                                              MSG_TYPE_RUNTIME_INFO,
+-                                              "CheckUp2 - Stat: %x",
+-                                              (void *)ExtStat,
+-                                              (void *)NULL);
+-                              }
+-#endif /* DEBUG */
+                               return(SK_HW_PS_LINK);
+                       }
+               }
+       }
+       else {  /* !AutoNeg */
+-              /* Link is up and we don't need more. */
++              /* Link is up and we don't need more */
+ #ifdef DEBUG
+-              if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
+-                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              if (pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO) {
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                               ("ERROR: Lipa auto detected on port %d\n", Port));
+               }
+ #endif /* DEBUG */
+-#ifdef xDEBUG
+-              /* Dummy read ISR to prevent extra link downs/ups */
+-              SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
+-
+-              if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
+-                      CMSMPrintString(
+-                              pAC->pConfigTable,
+-                              MSG_TYPE_RUNTIME_INFO,
+-                              "CheckUp3 - Stat: %x",
+-                              (void *)ExtStat,
+-                              (void *)NULL);
+-              }
+-#endif /* DEBUG */
+-              
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                       ("Link sync(GP), Port %d\n", Port));
+               SkHWLinkUp(pAC, IoC, Port);
+-              
++
+               return(SK_HW_PS_LINK);
+       }
+@@ -1615,20 +1867,17 @@
+  */
+ static int SkGePortCheckUpGmac(
+ SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* IO Context */
+-int           Port,           /* Which port should be checked */
++SK_IOC        IoC,            /* I/O Context */
++int           Port,           /* Port Index (MAC_1 + n) */
+ SK_BOOL       AutoNeg)        /* Is Auto-negotiation used ? */
+ {
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+       int                     Done;
+-      SK_U16          PhyIsrc;        /* PHY Interrupt source */
+-      SK_U16          PhyStat;        /* PPY Status */
++      SK_U16          PhyStat;        /* PHY Status */
+       SK_U16          PhySpecStat;/* PHY Specific Status */
+       SK_U16          ResAb;          /* Master/Slave resolution */
+       SK_EVPARA       Para;
+-#ifdef DEBUG
+       SK_U16          Word;           /* I/O helper */
+-#endif /* DEBUG */
+       pPrt = &pAC->GIni.GP[Port];
+@@ -1642,94 +1891,125 @@
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
+-      /* Read PHY Interrupt Status */
+-      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc);
++      SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
+-      if ((PhyIsrc & PHY_M_IS_AN_COMPL) != 0) {
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                      ("Auto-Negotiation Completed, PhyIsrc: 0x%04X\n", PhyIsrc));
+-      }
++      if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) {
+-      if ((PhyIsrc & PHY_M_IS_LSP_CHANGE) != 0) {
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                      ("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc));
+-      }
++              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
+-      SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
+-      
+-      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
++              if ((ResAb & PHY_B_1000S_MSF) != 0) {
++                      /* Error */
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
++                              ("Master/Slave Fault, ResAb: 0x%04X\n", ResAb));
+-      if ((ResAb & PHY_B_1000S_MSF) != 0) {
+-              /* Error */
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                      ("Master/Slave Fault port %d\n", Port));
+-              
+-              pPrt->PAutoNegFail = SK_TRUE;
+-              pPrt->PMSStatus = SK_MS_STAT_FAULT;
+-              
+-              return(SK_HW_PS_RESTART);
++                      pPrt->PAutoNegFail = SK_TRUE;
++                      pPrt->PMSStatus = SK_MS_STAT_FAULT;
++
++                      return(SK_HW_PS_RESTART);
++              }
+       }
+       /* Read PHY Specific Status */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
+-      
++
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat));
+ #ifdef DEBUG
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word);
+-      if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 ||
++      if ((Word & PHY_ANE_RX_PG) != 0 ||
+               (PhySpecStat & PHY_M_PS_PAGE_REC) != 0)  {
+               /* Read PHY Next Page Link Partner */
+               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word);
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                      ("Page Received, NextPage: 0x%04X\n", Word));
++                      ("Page received, NextPage: 0x%04X\n", Word));
+       }
+ #endif /* DEBUG */
+       if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
++              /* Link down */
+               return(SK_HW_PS_NONE);
+       }
+-      
+-      if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0 ||
+-              (PhyIsrc & PHY_M_IS_DOWNSH_DET) != 0) {
+-              /* Downshift detected */
+-              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, SKERR_SIRQ_E025MSG);
+-              
+-              Para.Para64 = Port;
+-              SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para);
+-              
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                      ("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc));
++
++#ifdef XXX
++      SK_U16          PhyInt;
++      /* Read PHY Interrupt Status */
++      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyInt);
++
++      /* cross check that the link is really up */
++      if ((PhyInt & PHY_M_IS_LST_CHANGE) == 0) {
++              /* Link Status unchanged */
++              return(SK_HW_PS_NONE);
+       }
++#endif /* XXX */
+-      pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
+-              SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
++      if (pAC->GIni.GICopperType) {
++
++              if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) {
++
++                      if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0) {
++                              /* Downshift detected */
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025,
++                                      SKERR_SIRQ_E025MSG);
++      
++                              Para.Para64 = Port;
++                              SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para);
+       
+-      pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7);
++                              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                                      ("Downshift detected, PhySpecStat: 0x%04X\n", PhySpecStat));
++                      }
++
++                      pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
++                              SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
++              }
+       
++              if ((PhySpecStat & PHY_M_PS_MDI_X_STAT) != 0) {
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                              ("MDI Xover detected, PhyStat: 0x%04X\n", PhySpecStat));
++              }
++
++              /* on PHY 88E1112 cable length is in Reg. 26, Page 5 */
++              if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) {
++                      /* save page register */
++                      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_ADR, &Word);
++
++                      /* select page 5 to access VCT DSP distance register */
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 5);
++
++                      /* get VCT DSP distance */
++                      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL_2, &PhySpecStat);
++
++                      /* restore page register */
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, Word);
++
++                      pPrt->PCableLen = (SK_U8)(PhySpecStat & PHY_M_EC2_FO_AM_MSK);
++              }
++              else {
++                      pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7);
++              }
++      }
++
+       if (AutoNeg) {
+-              /* Auto-Negotiation Over ? */
++              /* Auto-Negotiation Complete ? */
+               if ((PhyStat & PHY_ST_AN_OVER) != 0) {
+-                      
++
+                       SkHWLinkUp(pAC, IoC, Port);
+-                      
++
+                       Done = SkMacAutoNegDone(pAC, IoC, Port);
+-                      
++
+                       if (Done != SK_AND_OK) {
+                               return(SK_HW_PS_RESTART);
+                       }
+-                      
++
+                       return(SK_HW_PS_LINK);
+               }
+       }
+       else {  /* !AutoNeg */
+-              /* Link is up and we don't need more */
+ #ifdef DEBUG
+-              if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
+-                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              if (pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO) {
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                               ("ERROR: Lipa auto detected on port %d\n", Port));
+               }
+ #endif /* DEBUG */
+@@ -1737,7 +2017,7 @@
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                       ("Link sync, Port %d\n", Port));
+               SkHWLinkUp(pAC, IoC, Port);
+-              
++
+               return(SK_HW_PS_LINK);
+       }
+@@ -1758,8 +2038,8 @@
+  */
+ static int SkGePortCheckUpLone(
+ SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* IO Context */
+-int           Port,           /* Which port should be checked */
++SK_IOC        IoC,            /* I/O Context */
++int           Port,           /* Port Index (MAC_1 + n) */
+ SK_BOOL       AutoNeg)        /* Is Auto-negotiation used ? */
+ {
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+@@ -1788,7 +2068,7 @@
+       StatSum |= PhyStat;
+       SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
+-      
++
+       if ((PhyStat & PHY_ST_LSYNC) == 0) {
+               /* Save Auto-negotiation Done bit */
+               pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER);
+@@ -1802,17 +2082,21 @@
+       }
+       if (AutoNeg) {
++              /* Auto-Negotiation Over ? */
+               if ((StatSum & PHY_ST_AN_OVER) != 0) {
++
+                       SkHWLinkUp(pAC, IoC, Port);
++
+                       Done = SkMacAutoNegDone(pAC, IoC, Port);
++
+                       if (Done != SK_AND_OK) {
+                               /* Get PHY parameters, for debugging only */
+                               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb);
+                               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat);
+-                              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                                       ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
+                                        Port, LpAb, ExtStat));
+-                                      
++
+                               /* Try next possible mode */
+                               NextMode = SkHWSenseGetNext(pAC, IoC, Port);
+                               SkHWLinkDown(pAC, IoC, Port);
+@@ -1833,15 +2117,14 @@
+                               return(SK_HW_PS_LINK);
+                       }
+               }
+-              
++
+               /* AutoNeg not done, but HW link is up. Check for timeouts */
+-              pPrt->PAutoNegTimeOut++;
+-              if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
++              if (pPrt->PAutoNegTimeOut++ >= SK_AND_MAX_TO) {
+                       /* Timeout occured */
+                       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                               ("AutoNeg timeout Port %d\n", Port));
+-                      if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
+-                              pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
++                      if (pPrt->PLinkModeConf == (SK_U8)SK_LMODE_AUTOSENSE &&
++                              pPrt->PLipaAutoNeg != (SK_U8)SK_LIPA_AUTO) {
+                               /* Set Link manually up */
+                               SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
+                               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+@@ -1855,8 +2138,8 @@
+       else {
+               /* Link is up and we don't need more */
+ #ifdef DEBUG
+-              if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
+-                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              if (pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO) {
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                               ("ERROR: Lipa auto detected on port %d\n", Port));
+               }
+ #endif /* DEBUG */
+@@ -1866,11 +2149,12 @@
+                * extra link down/ups
+                */
+               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
+-              
++
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+                       ("Link sync(GP), Port %d\n", Port));
++
+               SkHWLinkUp(pAC, IoC, Port);
+-              
++
+               return(SK_HW_PS_LINK);
+       }
+@@ -1889,8 +2173,8 @@
+  */
+ static int SkGePortCheckUpNat(
+ SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* IO Context */
+-int           Port,           /* Which port should be checked */
++SK_IOC        IoC,            /* I/O Context */
++int           Port,           /* Port Index (MAC_1 + n) */
+ SK_BOOL       AutoNeg)        /* Is Auto-negotiation used ? */
+ {
+       /* todo: National */
+@@ -1909,12 +2193,12 @@
+  */
+ int   SkGeSirqEvent(
+ SK_AC         *pAC,           /* Adapter Context */
+-SK_IOC                IoC,            /* Io Context */
++SK_IOC                IoC,            /* I/O Context */
+ SK_U32                Event,          /* Module specific Event */
+ SK_EVPARA     Para)           /* Event specific Parameter */
+ {
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+-      SK_U32          Port;
++      int                     Port;
+       SK_U32          Val32;
+       int                     PortStat;
+       SK_U8           Val8;
+@@ -1922,25 +2206,25 @@
+       SK_U64          Octets;
+ #endif /* GENESIS */
+-      Port = Para.Para32[0];
++      Port = (int)Para.Para32[0];
+       pPrt = &pAC->GIni.GP[Port];
+       switch (Event) {
+       case SK_HWEV_WATIM:
+               if (pPrt->PState == SK_PRT_RESET) {
+-              
++
+                       PortStat = SK_HW_PS_NONE;
+               }
+               else {
+                       /* Check whether port came up */
+-                      PortStat = SkGePortCheckUp(pAC, IoC, (int)Port);
++                      PortStat = SkGePortCheckUp(pAC, IoC, Port);
+               }
+               switch (PortStat) {
+               case SK_HW_PS_RESTART:
+                       if (pPrt->PHWLinkUp) {
+                               /* Set Link to down */
+-                              SkHWLinkDown(pAC, IoC, (int)Port);
++                              SkHWLinkDown(pAC, IoC, Port);
+                               /*
+                                * Signal directly to RLMT to ensure correct
+@@ -1958,19 +2242,23 @@
+                       SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para);
+                       break;
+               }
+-              
++
+               /* Start again the check Timer */
+               if (pPrt->PHWLinkUp) {
++
+                       Val32 = SK_WA_ACT_TIME;
+               }
+               else {
+                       Val32 = SK_WA_INA_TIME;
+-              }
+-              /* Todo: still needed for non-XMAC PHYs??? */
++                      if (pAC->GIni.GIYukon) {
++                              Val32 *= 5;
++                      }
++              }
+               /* Start workaround Errata #2 timer */
+               SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Val32,
+                       SKGE_HWAC, SK_HWEV_WATIM, Para);
++
+               break;
+       case SK_HWEV_PORT_START:
+@@ -1982,7 +2270,7 @@
+                       SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
+               }
+-              SkHWLinkDown(pAC, IoC, (int)Port);
++              SkHWLinkDown(pAC, IoC, Port);
+               /* Schedule Port RESET */
+               SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
+@@ -1990,6 +2278,7 @@
+               /* Start workaround Errata #2 timer */
+               SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
+                       SKGE_HWAC, SK_HWEV_WATIM, Para);
++
+               break;
+       case SK_HWEV_PORT_STOP:
+@@ -2004,7 +2293,7 @@
+               /* Stop Workaround Timer */
+               SkTimerStop(pAC, IoC, &pPrt->PWaTimer);
+-              SkHWLinkDown(pAC, IoC, (int)Port);
++              SkHWLinkDown(pAC, IoC, Port);
+               break;
+       case SK_HWEV_UPDATE_STAT:
+@@ -2013,7 +2302,7 @@
+       case SK_HWEV_CLEAR_STAT:
+               /* We do NOT need to clear any statistics */
+-              for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) {
++              for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) {
+                       pPrt->PPrevRx = 0;
+                       pPrt->PPrevFcs = 0;
+                       pPrt->PPrevShorts = 0;
+@@ -2085,23 +2374,18 @@
+                       pPrt->HalfDupTimerActive = SK_FALSE;
+                       if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
+                               pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) {
+-#ifdef XXX
+-                              Len = sizeof(SK_U64);
+-                              SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets,
+-                                      &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port),
+-                                      pAC->Rlmt.Port[Port].Net->NetNumber);
+-#endif /* XXX */
++
+                               /* Snap statistic counters */
+                               (void)SkXmUpdateStats(pAC, IoC, Port);
+                               (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_HI, &Val32);
+                               Octets = (SK_U64)Val32 << 32;
+-                              
++
+                               (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_LO, &Val32);
+                               Octets += Val32;
+-                              
++
+                               if (pPrt->LastOctets == Octets) {
+                                       /* Tx hanging, a FIFO flush restarts it */
+                                       SkMacFlushTxFifo(pAC, IoC, Port);
+@@ -2110,7 +2394,7 @@
+               }
+               break;
+ #endif /* GENESIS */
+-      
++
+       default:
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG);
+               break;
+@@ -2131,8 +2415,8 @@
+  */
+ static void SkPhyIsrBcom(
+ SK_AC         *pAC,           /* Adapter Context */
+-SK_IOC                IoC,            /* Io Context */
+-int                   Port,           /* Port Num = PHY Num */
++SK_IOC                IoC,            /* I/O Context */
++int                   Port,           /* Port Index (MAC_1 + n) */
+ SK_U16                IStatus)        /* Interrupt Status */
+ {
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+@@ -2145,7 +2429,7 @@
+               SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E022,
+                       SKERR_SIRQ_E022MSG);
+       }
+-      
++
+       if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) {
+               SkHWLinkDown(pAC, IoC, Port);
+@@ -2174,8 +2458,8 @@
+  */
+ static void SkPhyIsrGmac(
+ SK_AC         *pAC,           /* Adapter Context */
+-SK_IOC                IoC,            /* Io Context */
+-int                   Port,           /* Port Num = PHY Num */
++SK_IOC                IoC,            /* I/O Context */
++int                   Port,           /* Port Index (MAC_1 + n) */
+ SK_U16                IStatus)        /* Interrupt Status */
+ {
+       SK_GEPORT       *pPrt;          /* GIni Port struct pointer */
+@@ -2184,37 +2468,69 @@
+       pPrt = &pAC->GIni.GP[Port];
+-      if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) {
+-
+-              SkHWLinkDown(pAC, IoC, Port);
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              ("Port %d PHY IRQ, PhyIsrc: 0x%04X\n", Port, IStatus));
+-              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word);
++      if ((IStatus & PHY_M_IS_LST_CHANGE) != 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                      ("AutoNeg.Adv: 0x%04X\n", Word));
+-              
+-              /* Set Auto-negotiation advertisement */
+-              if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) {
+-                      /* restore Asymmetric Pause bit */
+-                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV,
+-                              (SK_U16)(Word | PHY_M_AN_ASP));
+-              }
+-              
++                      ("Link Status changed\n"));
++
+               Para.Para32[0] = (SK_U32)Port;
+-              /* Signal to RLMT */
+-              SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
++
++              if (pPrt->PHWLinkUp) {
++
++                      SkHWLinkDown(pAC, IoC, Port);
++
++                      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word);
++
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                              ("AutoNeg.Adv: 0x%04X\n", Word));
++
++                      /* Set Auto-negotiation advertisement */
++                      if (pAC->GIni.GIChipId != CHIP_ID_YUKON_FE &&
++                              pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) {
++                              /* restore Asymmetric Pause bit */
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV,
++                                      (SK_U16)(Word | PHY_M_AN_ASP));
++                      }
++
++                      /* Signal to RLMT */
++                      SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
++              }
++              else {
++                      if ((IStatus & PHY_M_IS_AN_COMPL) != 0) {
++                              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                                      ("Auto-Negotiation completed\n"));
++                      }
++
++                      if ((IStatus & PHY_M_IS_LSP_CHANGE) != 0) {
++                              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                                      ("Link Speed changed\n"));
++                      }
++
++                      SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_WATIM, Para);
++              }
+       }
+-      
++
+       if ((IStatus & PHY_M_IS_AN_ERROR) != 0) {
+-              /* Auto-Negotiation Error */
+-              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG);
++              /* the copper PHY makes 1 retry */
++              if (pAC->GIni.GICopperType) {
++                      /* not logged as error, it might be the first attempt */
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                              ("Auto-Negotiation Error\n"));
++              }
++              else {
++                      /* Auto-Negotiation Error */
++                      SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG);
++              }
+       }
+-      
++
+       if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) {
+               /* FIFO Overflow/Underrun Error */
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG);
+       }
+-      
++
+ }     /* SkPhyIsrGmac */
+ #endif /* YUKON */
+@@ -2230,8 +2546,8 @@
+  */
+ static void SkPhyIsrLone(
+ SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* Io Context */
+-int           Port,           /* Port Num = PHY Num */
++SK_IOC        IoC,            /* I/O Context */
++int           Port,           /* Port Index (MAC_1 + n) */
+ SK_U16        IStatus)        /* Interrupt Status */
+ {
+       SK_EVPARA       Para;
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/ski2c.c linux-2.6.9.new/drivers/net/sk98lin/ski2c.c
+--- linux-2.6.9.old/drivers/net/sk98lin/ski2c.c        2004-10-19 05:53:05.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/ski2c.c        1970-01-01 08:00:00.000000000 +0800
+@@ -1,1296 +0,0 @@
+-/******************************************************************************
+- *
+- * Name:      ski2c.c
+- * Project:   Gigabit Ethernet Adapters, TWSI-Module
+- * Version:   $Revision: 1.59 $
+- * Date:      $Date: 2003/10/20 09:07:25 $
+- * Purpose:   Functions to access Voltage and Temperature Sensor
+- *
+- ******************************************************************************/
+-
+-/******************************************************************************
+- *
+- *    (C)Copyright 1998-2002 SysKonnect.
+- *    (C)Copyright 2002-2003 Marvell.
+- *
+- *    This program is free software; you can redistribute it and/or modify
+- *    it under the terms of the GNU General Public License as published by
+- *    the Free Software Foundation; either version 2 of the License, or
+- *    (at your option) any later version.
+- *
+- *    The information in this file is provided "AS IS" without warranty.
+- *
+- ******************************************************************************/
+-
+-/*
+- *    I2C Protocol
+- */
+-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+-static const char SysKonnectFileId[] =
+-      "@(#) $Id: ski2c.c,v 1.59 2003/10/20 09:07:25 rschmidt Exp $ (C) Marvell. ";
+-#endif
+-
+-#include "h/skdrv1st.h"               /* Driver Specific Definitions */
+-#include "h/lm80.h"
+-#include "h/skdrv2nd.h"               /* Adapter Control- and Driver specific Def. */
+-
+-#ifdef __C2MAN__
+-/*
+-      I2C protocol implementation.
+-
+-      General Description:
+-
+-      The I2C protocol is used for the temperature sensors and for
+-      the serial EEPROM which hold the configuration.
+-
+-      This file covers functions that allow to read write and do
+-      some bulk requests a specified I2C address.
+-
+-      The Genesis has 2 I2C buses. One for the EEPROM which holds
+-      the VPD Data and one for temperature and voltage sensor.
+-      The following picture shows the I2C buses, I2C devices and
+-      their control registers.
+-
+-      Note: The VPD functions are in skvpd.c
+-.
+-.     PCI Config I2C Bus for VPD Data:
+-.
+-.                   +------------+
+-.                   | VPD EEPROM |
+-.                   +------------+
+-.                          |
+-.                          | <-- I2C
+-.                          |
+-.              +-----------+-----------+
+-.              |                       |
+-.     +-----------------+     +-----------------+
+-.     | PCI_VPD_ADR_REG |     | PCI_VPD_DAT_REG |
+-.     +-----------------+     +-----------------+
+-.
+-.
+-.     I2C Bus for LM80 sensor:
+-.
+-.                     +-----------------+
+-.                     | Temperature and |
+-.                     | Voltage Sensor  |
+-.                     |       LM80      |
+-.                     +-----------------+
+-.                             |
+-.                             |
+-.                     I2C --> |
+-.                             |
+-.                          +----+
+-.          +-------------->| OR |<--+
+-.          |               +----+   |
+-.     +------+------+               |
+-.     |                   |                 |
+-. +--------+  +--------+      +----------+
+-. | B2_I2C |  | B2_I2C |      |  B2_I2C  |
+-. | _CTRL  |  | _DATA  |      |   _SW    |
+-. +--------+  +--------+      +----------+
+-.
+-      The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
+-      and B2_I2C_DATA registers.
+-      For driver software it is recommended to use the I2C control and
+-      data register, because I2C bus timing is done by the ASIC and
+-      an interrupt may be received when the I2C request is completed.
+-
+-      Clock Rate Timing:                      MIN     MAX     generated by
+-              VPD EEPROM:                     50 kHz  100 kHz         HW
+-              LM80 over I2C Ctrl/Data reg.    50 kHz  100 kHz         HW
+-              LM80 over B2_I2C_SW register    0       400 kHz         SW
+-
+-      Note:   The clock generated by the hardware is dependend on the
+-              PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
+-              clock is 50 kHz.
+- */
+-intro()
+-{}
+-#endif
+-
+-#ifdef SK_DIAG
+-/*
+- * I2C Fast Mode timing values used by the LM80.
+- * If new devices are added to the I2C bus the timing values have to be checked.
+- */
+-#ifndef I2C_SLOW_TIMING
+-#define       T_CLK_LOW                       1300L   /* clock low time in ns */
+-#define       T_CLK_HIGH                       600L   /* clock high time in ns */
+-#define T_DATA_IN_SETUP                100L   /* data in Set-up Time */
+-#define T_START_HOLD           600L   /* start condition hold time */
+-#define T_START_SETUP          600L   /* start condition Set-up time */
+-#define       T_STOP_SETUP             600L   /* stop condition Set-up time */
+-#define T_BUS_IDLE                    1300L   /* time the bus must free after Tx */
+-#define       T_CLK_2_DATA_OUT         900L   /* max. clock low to data output valid */
+-#else /* I2C_SLOW_TIMING */
+-/* I2C Standard Mode Timing */
+-#define       T_CLK_LOW                       4700L   /* clock low time in ns */
+-#define       T_CLK_HIGH                      4000L   /* clock high time in ns */
+-#define T_DATA_IN_SETUP                250L   /* data in Set-up Time */
+-#define T_START_HOLD          4000L   /* start condition hold time */
+-#define T_START_SETUP         4700L   /* start condition Set-up time */
+-#define       T_STOP_SETUP            4000L   /* stop condition Set-up time */
+-#define T_BUS_IDLE                    4700L   /* time the bus must free after Tx */
+-#endif        /* !I2C_SLOW_TIMING */
+-
+-#define NS2BCLK(x)    (((x)*125)/10000)
+-
+-/*
+- * I2C Wire Operations
+- *
+- * About I2C_CLK_LOW():
+- *
+- * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
+- * clock to low, to prevent the ASIC and the I2C data client from driving the
+- * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
+- * send an 'ACK'). See also Concentrator Bugreport No. 10192.
+- */
+-#define I2C_DATA_HIGH(IoC)    SK_I2C_SET_BIT(IoC, I2C_DATA)
+-#define       I2C_DATA_LOW(IoC)       SK_I2C_CLR_BIT(IoC, I2C_DATA)
+-#define       I2C_DATA_OUT(IoC)       SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
+-#define       I2C_DATA_IN(IoC)        SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
+-#define       I2C_CLK_HIGH(IoC)       SK_I2C_SET_BIT(IoC, I2C_CLK)
+-#define       I2C_CLK_LOW(IoC)        SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
+-#define       I2C_START_COND(IoC)     SK_I2C_CLR_BIT(IoC, I2C_CLK)
+-
+-#define NS2CLKT(x)    ((x*125L)/10000)
+-
+-/*--------------- I2C Interface Register Functions --------------- */
+-
+-/*
+- * sending one bit
+- */
+-void SkI2cSndBit(
+-SK_IOC        IoC,    /* I/O Context */
+-SK_U8 Bit)    /* Bit to send */
+-{
+-      I2C_DATA_OUT(IoC);
+-      if (Bit) {
+-              I2C_DATA_HIGH(IoC);
+-      }
+-      else {
+-              I2C_DATA_LOW(IoC);
+-      }
+-      SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
+-      I2C_CLK_HIGH(IoC);
+-      SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
+-      I2C_CLK_LOW(IoC);
+-}     /* SkI2cSndBit*/
+-
+-
+-/*
+- * Signal a start to the I2C Bus.
+- *
+- * A start is signaled when data goes to low in a high clock cycle.
+- *
+- * Ends with Clock Low.
+- *
+- * Status: not tested
+- */
+-void SkI2cStart(
+-SK_IOC        IoC)    /* I/O Context */
+-{
+-      /* Init data and Clock to output lines */
+-      /* Set Data high */
+-      I2C_DATA_OUT(IoC);
+-      I2C_DATA_HIGH(IoC);
+-      /* Set Clock high */
+-      I2C_CLK_HIGH(IoC);
+-
+-      SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
+-
+-      /* Set Data Low */
+-      I2C_DATA_LOW(IoC);
+-
+-      SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
+-
+-      /* Clock low without Data to Input */
+-      I2C_START_COND(IoC);
+-
+-      SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
+-}     /* SkI2cStart */
+-
+-
+-void SkI2cStop(
+-SK_IOC        IoC)    /* I/O Context */
+-{
+-      /* Init data and Clock to output lines */
+-      /* Set Data low */
+-      I2C_DATA_OUT(IoC);
+-      I2C_DATA_LOW(IoC);
+-
+-      SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
+-
+-      /* Set Clock high */
+-      I2C_CLK_HIGH(IoC);
+-
+-      SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
+-
+-      /*
+-       * Set Data High:       Do it by setting the Data Line to Input.
+-       *                      Because of a pull up resistor the Data Line
+-       *                      floods to high.
+-       */
+-      I2C_DATA_IN(IoC);
+-
+-      /*
+-       *      When I2C activity is stopped
+-       *       o      DATA should be set to input and
+-       *       o      CLOCK should be set to high!
+-       */
+-      SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
+-}     /* SkI2cStop */
+-
+-
+-/*
+- * Receive just one bit via the I2C bus.
+- *
+- * Note:      Clock must be set to LOW before calling this function.
+- *
+- * Returns The received bit.
+- */
+-int SkI2cRcvBit(
+-SK_IOC        IoC)    /* I/O Context */
+-{
+-      int     Bit;
+-      SK_U8   I2cSwCtrl;
+-
+-      /* Init data as input line */
+-      I2C_DATA_IN(IoC);
+-
+-      SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
+-
+-      I2C_CLK_HIGH(IoC);
+-
+-      SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
+-
+-      SK_I2C_GET_SW(IoC, &I2cSwCtrl);
+-      
+-      Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
+-
+-      I2C_CLK_LOW(IoC);
+-      SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
+-
+-      return(Bit);
+-}     /* SkI2cRcvBit */
+-
+-
+-/*
+- * Receive an ACK.
+- *
+- * returns    0 If acknowledged
+- *            1 in case of an error
+- */
+-int SkI2cRcvAck(
+-SK_IOC        IoC)    /* I/O Context */
+-{
+-      /*
+-       * Received bit must be zero.
+-       */
+-      return(SkI2cRcvBit(IoC) != 0);
+-}     /* SkI2cRcvAck */
+-
+-
+-/*
+- * Send an NACK.
+- */
+-void SkI2cSndNAck(
+-SK_IOC        IoC)    /* I/O Context */
+-{
+-      /*
+-       * Received bit must be zero.
+-       */
+-      SkI2cSndBit(IoC, 1);
+-}     /* SkI2cSndNAck */
+-
+-
+-/*
+- * Send an ACK.
+- */
+-void SkI2cSndAck(
+-SK_IOC IoC)   /* I/O Context */
+-{
+-      /*
+-       * Received bit must be zero.
+-       */
+-      SkI2cSndBit(IoC, 0);
+-}     /* SkI2cSndAck */
+-
+-
+-/*
+- * Send one byte to the I2C device and wait for ACK.
+- *
+- * Return acknowleged status.
+- */
+-int SkI2cSndByte(
+-SK_IOC        IoC,    /* I/O Context */
+-int           Byte)   /* byte to send */
+-{
+-      int     i;
+-
+-      for (i = 0; i < 8; i++) {
+-              if (Byte & (1<<(7-i))) {
+-                      SkI2cSndBit(IoC, 1);
+-              }
+-              else {
+-                      SkI2cSndBit(IoC, 0);
+-              }
+-      }
+-
+-      return(SkI2cRcvAck(IoC));
+-}     /* SkI2cSndByte */
+-
+-
+-/*
+- * Receive one byte and ack it.
+- *
+- * Return byte.
+- */
+-int SkI2cRcvByte(
+-SK_IOC        IoC,    /* I/O Context */
+-int           Last)   /* Last Byte Flag */
+-{
+-      int     i;
+-      int     Byte = 0;
+-
+-      for (i = 0; i < 8; i++) {
+-              Byte <<= 1;
+-              Byte |= SkI2cRcvBit(IoC);
+-      }
+-
+-      if (Last) {
+-              SkI2cSndNAck(IoC);
+-      }
+-      else {
+-              SkI2cSndAck(IoC);
+-      }
+-
+-      return(Byte);
+-}     /* SkI2cRcvByte */
+-
+-
+-/*
+- * Start dialog and send device address
+- *
+- * Return 0 if acknowleged, 1 in case of an error
+- */
+-int   SkI2cSndDev(
+-SK_IOC        IoC,    /* I/O Context */
+-int           Addr,   /* Device Address */
+-int           Rw)             /* Read / Write Flag */
+-{
+-      SkI2cStart(IoC);
+-      Rw = ~Rw;
+-      Rw &= I2C_WRITE;
+-      return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
+-}     /* SkI2cSndDev */
+-
+-#endif /* SK_DIAG */
+-
+-/*----------------- I2C CTRL Register Functions ----------*/
+-
+-/*
+- * waits for a completion of an I2C transfer
+- *
+- * returns    0:      success, transfer completes
+- *                    1:      error,   transfer does not complete, I2C transfer
+- *                                             killed, wait loop terminated.
+- */
+-int   SkI2cWait(
+-SK_AC *pAC,   /* Adapter Context */
+-SK_IOC        IoC,    /* I/O Context */
+-int           Event)  /* complete event to wait for (I2C_READ or I2C_WRITE) */
+-{
+-      SK_U64  StartTime;
+-      SK_U64  CurrentTime;
+-      SK_U32  I2cCtrl;
+-
+-      StartTime = SkOsGetTime(pAC);
+-      
+-      do {
+-              CurrentTime = SkOsGetTime(pAC);
+-
+-              if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
+-                      
+-                      SK_I2C_STOP(IoC);
+-#ifndef SK_DIAG
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
+-#endif /* !SK_DIAG */
+-                      return(1);
+-              }
+-              
+-              SK_I2C_GET_CTL(IoC, &I2cCtrl);
+-
+-#ifdef xYUKON_DBG
+-              printf("StartTime=%lu, CurrentTime=%lu\n",
+-                      StartTime, CurrentTime);
+-              if (kbhit()) {
+-                      return(1);
+-              }
+-#endif /* YUKON_DBG */
+-      
+-      } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
+-
+-      return(0);
+-}     /* SkI2cWait */
+-
+-
+-/*
+- * waits for a completion of an I2C transfer
+- *
+- * Returns
+- *    Nothing
+- */
+-void SkI2cWaitIrq(
+-SK_AC *pAC,   /* Adapter Context */
+-SK_IOC        IoC)    /* I/O Context */
+-{
+-      SK_SENSOR       *pSen;
+-      SK_U64          StartTime;
+-      SK_U32          IrqSrc;
+-
+-      pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+-
+-      if (pSen->SenState == SK_SEN_IDLE) {
+-              return;
+-      }
+-
+-      StartTime = SkOsGetTime(pAC);
+-      
+-      do {
+-              if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
+-                      
+-                      SK_I2C_STOP(IoC);
+-#ifndef SK_DIAG
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
+-#endif /* !SK_DIAG */
+-                      return;
+-              }
+-              
+-              SK_IN32(IoC, B0_ISRC, &IrqSrc);
+-
+-      } while ((IrqSrc & IS_I2C_READY) == 0);
+-
+-      pSen->SenState = SK_SEN_IDLE;
+-      return;
+-}     /* SkI2cWaitIrq */
+-
+-/*
+- * writes a single byte or 4 bytes into the I2C device
+- *
+- * returns    0:      success
+- *                    1:      error
+- */
+-int SkI2cWrite(
+-SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* I/O Context */
+-SK_U32        I2cData,        /* I2C Data to write */
+-int           I2cDev,         /* I2C Device Address */
+-int           I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
+-int           I2cReg,         /* I2C Device Register Address */
+-int           I2cBurst)       /* I2C Burst Flag */
+-{
+-      SK_OUT32(IoC, B2_I2C_DATA, I2cData);
+-      
+-      SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst);
+-      
+-      return(SkI2cWait(pAC, IoC, I2C_WRITE));
+-}     /* SkI2cWrite*/
+-
+-
+-#ifdef        SK_DIAG
+-/*
+- * reads a single byte or 4 bytes from the I2C device
+- *
+- * returns    the word read
+- */
+-SK_U32 SkI2cRead(
+-SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* I/O Context */
+-int           I2cDev,         /* I2C Device Address */
+-int           I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
+-int           I2cReg,         /* I2C Device Register Address */
+-int           I2cBurst)       /* I2C Burst Flag */
+-{
+-      SK_U32  Data;
+-
+-      SK_OUT32(IoC, B2_I2C_DATA, 0);
+-      SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst);
+-      
+-      if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
+-              w_print("%s\n", SKERR_I2C_E002MSG);
+-      }
+-      
+-      SK_IN32(IoC, B2_I2C_DATA, &Data);
+-      
+-      return(Data);
+-}     /* SkI2cRead */
+-#endif /* SK_DIAG */
+-
+-
+-/*
+- * read a sensor's value
+- *
+- * This function reads a sensor's value from the I2C sensor chip. The sensor
+- * is defined by its index into the sensors database in the struct pAC points
+- * to.
+- * Returns
+- *            1 if the read is completed
+- *            0 if the read must be continued (I2C Bus still allocated)
+- */
+-int   SkI2cReadSensor(
+-SK_AC         *pAC,   /* Adapter Context */
+-SK_IOC                IoC,    /* I/O Context */
+-SK_SENSOR     *pSen)  /* Sensor to be read */
+-{
+-    if (pSen->SenRead != NULL) {
+-        return((*pSen->SenRead)(pAC, IoC, pSen));
+-    }
+-      else {
+-        return(0); /* no success */
+-      }
+-}     /* SkI2cReadSensor */
+-
+-/*
+- * Do the Init state 0 initialization
+- */
+-static int SkI2cInit0(
+-SK_AC *pAC)   /* Adapter Context */
+-{
+-      int     i;
+-
+-      /* Begin with first sensor */
+-      pAC->I2c.CurrSens = 0;
+-      
+-      /* Begin with timeout control for state machine */
+-      pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
+-      
+-      /* Set sensor number to zero */
+-      pAC->I2c.MaxSens = 0;
+-
+-#ifndef SK_DIAG
+-      /* Initialize Number of Dummy Reads */
+-      pAC->I2c.DummyReads = SK_MAX_SENSORS;
+-#endif
+-
+-      for (i = 0; i < SK_MAX_SENSORS; i++) {
+-              pAC->I2c.SenTable[i].SenDesc = "unknown";
+-              pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
+-              pAC->I2c.SenTable[i].SenThreErrHigh = 0;
+-              pAC->I2c.SenTable[i].SenThreErrLow = 0;
+-              pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
+-              pAC->I2c.SenTable[i].SenThreWarnLow = 0;
+-              pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
+-              pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
+-              pAC->I2c.SenTable[i].SenValue = 0;
+-              pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
+-              pAC->I2c.SenTable[i].SenErrCts = 0;
+-              pAC->I2c.SenTable[i].SenBegErrTS = 0;
+-              pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
+-              pAC->I2c.SenTable[i].SenRead = NULL;
+-              pAC->I2c.SenTable[i].SenDev = 0;
+-      }
+-
+-      /* Now we are "INIT data"ed */
+-      pAC->I2c.InitLevel = SK_INIT_DATA;
+-      return(0);
+-}     /* SkI2cInit0*/
+-
+-
+-/*
+- * Do the init state 1 initialization
+- *
+- * initialize the following register of the LM80:
+- * Configuration register:
+- * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
+- *
+- * Interrupt Mask Register 1:
+- * - all interrupts are Disabled (0xff)
+- *
+- * Interrupt Mask Register 2:
+- * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
+- *
+- * Fan Divisor/RST_OUT register:
+- * - Divisors set to 1 (bits 00), all others 0s.
+- *
+- * OS# Configuration/Temperature resolution Register:
+- * - all 0s
+- *
+- */
+-static int SkI2cInit1(
+-SK_AC *pAC,   /* Adapter Context */
+-SK_IOC        IoC)    /* I/O Context */
+-{
+-    int i;
+-    SK_U8 I2cSwCtrl;
+-      SK_GEPORT *pPrt;        /* GIni Port struct pointer */
+-
+-      if (pAC->I2c.InitLevel != SK_INIT_DATA) {
+-              /* ReInit not needed in I2C module */
+-              return(0);
+-      }
+-
+-    /* Set the Direction of I2C-Data Pin to IN */
+-    SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
+-    /* Check for 32-Bit Yukon with Low at I2C-Data Pin */
+-      SK_I2C_GET_SW(IoC, &I2cSwCtrl);
+-
+-      if ((I2cSwCtrl & I2C_DATA) == 0) {
+-              /* this is a 32-Bit board */
+-              pAC->GIni.GIYukon32Bit = SK_TRUE;
+-        return(0);
+-    }
+-
+-      /* Check for 64 Bit Yukon without sensors */
+-      if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) {
+-        return(0);
+-    }
+-
+-      (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0);
+-      
+-      (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0);
+-      
+-      (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0);
+-      
+-      (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
+-      
+-      (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV,
+-              LM80_CFG, 0);
+-      
+-      /*
+-       * MaxSens has to be updated here, because PhyType is not
+-       * set when performing Init Level 0
+-       */
+-    pAC->I2c.MaxSens = 5;
+-      
+-      pPrt = &pAC->GIni.GP[0];
+-      
+-      if (pAC->GIni.GIGenesis) {
+-              if (pPrt->PhyType == SK_PHY_BCOM) {
+-                      if (pAC->GIni.GIMacsFound == 1) {
+-                              pAC->I2c.MaxSens += 1;
+-                      }
+-                      else {
+-                              pAC->I2c.MaxSens += 3;
+-                      }
+-              }
+-      }
+-      else {
+-              pAC->I2c.MaxSens += 3;
+-      }
+-      
+-      for (i = 0; i < pAC->I2c.MaxSens; i++) {
+-              switch (i) {
+-              case 0:
+-                      pAC->I2c.SenTable[i].SenDesc = "Temperature";
+-                      pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
+-                      pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
+-                      pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
+-                      pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
+-                      pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
+-                      pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
+-                      break;
+-              case 1:
+-                      pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
+-                      pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+-                      pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
+-                      pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
+-                      pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
+-                      pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
+-                      pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
+-                      break;
+-              case 2:
+-                      pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
+-                      pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+-                      pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
+-                      pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
+-                      pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
+-                      pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
+-                      pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
+-                      pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
+-                      break;
+-              case 3:
+-                      pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
+-                      pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+-                      pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
+-                      pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
+-                      pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
+-                      pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
+-                      pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
+-                      break;
+-              case 4:
+-                      if (pAC->GIni.GIGenesis) {
+-                              if (pPrt->PhyType == SK_PHY_BCOM) {
+-                                      pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
+-                                      pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
+-                                      pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
+-                                      pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
+-                                      pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
+-                              }
+-                              else {
+-                                      pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
+-                                      pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
+-                                      pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
+-                                      pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
+-                                      pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
+-                              }
+-                      }
+-                      else {
+-                              pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
+-                              pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
+-                              pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
+-                              if (pAC->GIni.GIVauxAvail) {
+-                                      pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
+-                                      pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
+-                              }
+-                              else {
+-                                      pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
+-                                      pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
+-                              }
+-                      }
+-                      pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+-                      pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
+-                      break;
+-              case 5:
+-                      if (pAC->GIni.GIGenesis) {
+-                              pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
+-                              pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
+-                              pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
+-                              pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
+-                              pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
+-                      }
+-                      else {
+-                              pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5";
+-                              pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
+-                              pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
+-                              pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
+-                              pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
+-                      }
+-                      pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+-                      pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
+-                      break;
+-              case 6:
+-                      if (pAC->GIni.GIGenesis) {
+-                              pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
+-                      }
+-                      else {
+-                              pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
+-                      }
+-                      pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+-                      pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
+-                      pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
+-                      pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
+-                      pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
+-                      pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
+-                      break;
+-              case 7:
+-                      if (pAC->GIni.GIGenesis) {
+-                              pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
+-                              pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
+-                              pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
+-                              pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
+-                              pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
+-                              pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
+-                              pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
+-                      }
+-                      else {
+-                              pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
+-                              pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
+-                              pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
+-                              pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
+-                              pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
+-                              pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
+-                              pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
+-                      }
+-                      break;
+-              default:
+-                      SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
+-                              SKERR_I2C_E001, SKERR_I2C_E001MSG);
+-                      break;
+-              }
+-
+-              pAC->I2c.SenTable[i].SenValue = 0;
+-              pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
+-              pAC->I2c.SenTable[i].SenErrCts = 0;
+-              pAC->I2c.SenTable[i].SenBegErrTS = 0;
+-              pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
+-              pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
+-              pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
+-      }
+-
+-#ifndef SK_DIAG
+-      pAC->I2c.DummyReads = pAC->I2c.MaxSens;
+-#endif /* !SK_DIAG */
+-      
+-      /* Clear I2C IRQ */
+-      SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
+-      
+-      /* Now we are I/O initialized */
+-      pAC->I2c.InitLevel = SK_INIT_IO;
+-      return(0);
+-}     /* SkI2cInit1 */
+-
+-
+-/*
+- * Init level 2: Start first sensor read.
+- */
+-static int SkI2cInit2(
+-SK_AC *pAC,   /* Adapter Context */
+-SK_IOC        IoC)    /* I/O Context */
+-{
+-      int             ReadComplete;
+-      SK_SENSOR       *pSen;
+-
+-      if (pAC->I2c.InitLevel != SK_INIT_IO) {
+-              /* ReInit not needed in I2C module */
+-              /* Init0 and Init2 not permitted */
+-              return(0);
+-      }
+-
+-      pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+-      ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
+-
+-      if (ReadComplete) {
+-              SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
+-      }
+-
+-      /* Now we are correctly initialized */
+-      pAC->I2c.InitLevel = SK_INIT_RUN;
+-
+-      return(0);
+-}     /* SkI2cInit2*/
+-
+-
+-/*
+- * Initialize I2C devices
+- *
+- * Get the first voltage value and discard it.
+- * Go into temperature read mode. A default pointer is not set.
+- *
+- * The things to be done depend on the init level in the parameter list:
+- * Level 0:
+- *    Initialize only the data structures. Do NOT access hardware.
+- * Level 1:
+- *    Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
+- * Level 2:
+- *    Everything is possible. Interrupts may be used from now on.
+- *
+- * return:
+- *    0 = success
+- *    other = error.
+- */
+-int   SkI2cInit(
+-SK_AC *pAC,   /* Adapter Context */
+-SK_IOC        IoC,    /* I/O Context needed in levels 1 and 2 */
+-int           Level)  /* Init Level */
+-{
+-
+-      switch (Level) {
+-      case SK_INIT_DATA:
+-              return(SkI2cInit0(pAC));
+-      case SK_INIT_IO:
+-              return(SkI2cInit1(pAC, IoC));
+-      case SK_INIT_RUN:
+-              return(SkI2cInit2(pAC, IoC));
+-      default:
+-              break;
+-      }
+-
+-      return(0);
+-}     /* SkI2cInit */
+-
+-
+-#ifndef SK_DIAG
+-
+-/*
+- * Interrupt service function for the I2C Interface
+- *
+- * Clears the Interrupt source
+- *
+- * Reads the register and check it for sending a trap.
+- *
+- * Starts the timer if necessary.
+- */
+-void SkI2cIsr(
+-SK_AC *pAC,   /* Adapter Context */
+-SK_IOC        IoC)    /* I/O Context */
+-{
+-      SK_EVPARA       Para;
+-
+-      /* Clear I2C IRQ */
+-      SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
+-
+-      Para.Para64 = 0;
+-      SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
+-}     /* SkI2cIsr */
+-
+-
+-/*
+- * Check this sensors Value against the threshold and send events.
+- */
+-static void SkI2cCheckSensor(
+-SK_AC         *pAC,   /* Adapter Context */
+-SK_SENSOR     *pSen)
+-{
+-      SK_EVPARA       ParaLocal;
+-      SK_BOOL         TooHigh;        /* Is sensor too high? */
+-      SK_BOOL         TooLow;         /* Is sensor too low? */
+-      SK_U64          CurrTime;       /* Current Time */
+-      SK_BOOL         DoTrapSend;     /* We need to send a trap */
+-      SK_BOOL         DoErrLog;       /* We need to log the error */
+-      SK_BOOL         IsError;        /* We need to log the error */
+-
+-      /* Check Dummy Reads first */
+-      if (pAC->I2c.DummyReads > 0) {
+-              pAC->I2c.DummyReads--;
+-              return;
+-      }
+-
+-      /* Get the current time */
+-      CurrTime = SkOsGetTime(pAC);
+-
+-      /* Set para to the most useful setting: The current sensor. */
+-      ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
+-
+-      /* Check the Value against the thresholds. First: Error Thresholds */
+-      TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
+-      TooLow = (pSen->SenValue < pSen->SenThreErrLow);
+-              
+-      IsError = SK_FALSE;
+-      if (TooHigh || TooLow) {
+-              /* Error condition is satisfied */
+-              DoTrapSend = SK_TRUE;
+-              DoErrLog = SK_TRUE;
+-
+-              /* Now error condition is satisfied */
+-              IsError = SK_TRUE;
+-
+-              if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
+-                      /* This state is the former one */
+-
+-                      /* So check first whether we have to send a trap */
+-                      if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
+-                          CurrTime) {
+-                              /*
+-                               * Do NOT send the Trap. The hold back time
+-                               * has to run out first.
+-                               */
+-                              DoTrapSend = SK_FALSE;
+-                      }
+-
+-                      /* Check now whether we have to log an Error */
+-                      if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
+-                          CurrTime) {
+-                              /*
+-                               * Do NOT log the error. The hold back time
+-                               * has to run out first.
+-                               */
+-                              DoErrLog = SK_FALSE;
+-                      }
+-              }
+-              else {
+-                      /* We came from a different state -> Set Begin Time Stamp */
+-                      pSen->SenBegErrTS = CurrTime;
+-                      pSen->SenErrFlag = SK_SEN_ERR_ERR;
+-              }
+-
+-              if (DoTrapSend) {
+-                      /* Set current Time */
+-                      pSen->SenLastErrTrapTS = CurrTime;
+-                      pSen->SenErrCts++;
+-
+-                      /* Queue PNMI Event */
+-                      SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
+-                              SK_PNMI_EVT_SEN_ERR_UPP :
+-                              SK_PNMI_EVT_SEN_ERR_LOW),
+-                              ParaLocal);
+-              }
+-
+-              if (DoErrLog) {
+-                      /* Set current Time */
+-                      pSen->SenLastErrLogTS = CurrTime;
+-
+-                      if (pSen->SenType == SK_SEN_TEMP) {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG);
+-                      }
+-                      else if (pSen->SenType == SK_SEN_VOLT) {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG);
+-                      }
+-                      else {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG);
+-                      }
+-              }
+-      }
+-
+-      /* Check the Value against the thresholds */
+-      /* 2nd: Warning thresholds */
+-      TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
+-      TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
+-              
+-      if (!IsError && (TooHigh || TooLow)) {
+-              /* Error condition is satisfied */
+-              DoTrapSend = SK_TRUE;
+-              DoErrLog = SK_TRUE;
+-
+-              if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
+-                      /* This state is the former one */
+-
+-                      /* So check first whether we have to send a trap */
+-                      if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) {
+-                              /*
+-                               * Do NOT send the Trap. The hold back time
+-                               * has to run out first.
+-                               */
+-                              DoTrapSend = SK_FALSE;
+-                      }
+-
+-                      /* Check now whether we have to log an Error */
+-                      if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) {
+-                              /*
+-                               * Do NOT log the error. The hold back time
+-                               * has to run out first.
+-                               */
+-                              DoErrLog = SK_FALSE;
+-                      }
+-              }
+-              else {
+-                      /* We came from a different state -> Set Begin Time Stamp */
+-                      pSen->SenBegWarnTS = CurrTime;
+-                      pSen->SenErrFlag = SK_SEN_ERR_WARN;
+-              }
+-
+-              if (DoTrapSend) {
+-                      /* Set current Time */
+-                      pSen->SenLastWarnTrapTS = CurrTime;
+-                      pSen->SenWarnCts++;
+-
+-                      /* Queue PNMI Event */
+-                      SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
+-                              SK_PNMI_EVT_SEN_WAR_UPP :
+-                              SK_PNMI_EVT_SEN_WAR_LOW),
+-                              ParaLocal);
+-              }
+-
+-              if (DoErrLog) {
+-                      /* Set current Time */
+-                      pSen->SenLastWarnLogTS = CurrTime;
+-
+-                      if (pSen->SenType == SK_SEN_TEMP) {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG);
+-                      }
+-                      else if (pSen->SenType == SK_SEN_VOLT) {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG);
+-                      }
+-                      else {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG);
+-                      }
+-              }
+-      }
+-
+-      /* Check for NO error at all */
+-      if (!IsError && !TooHigh && !TooLow) {
+-              /* Set o.k. Status if no error and no warning condition */
+-              pSen->SenErrFlag = SK_SEN_ERR_OK;
+-      }
+-
+-      /* End of check against the thresholds */
+-
+-      /* Bug fix AF: 16.Aug.2001: Correct the init base
+-       * of LM80 sensor.
+-       */
+-      if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
+-
+-        pSen->SenInit = SK_SEN_DYN_INIT_NONE;
+-
+-              if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
+-                      /* 5V PCI-IO Voltage */
+-                      pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
+-                      pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
+-              }
+-              else {
+-                      /* 3.3V PCI-IO Voltage */
+-                      pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
+-                      pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
+-              }
+-      }
+-      
+-#ifdef TEST_ONLY
+-    /* Dynamic thresholds also for VAUX of LM80 sensor */
+-      if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
+-
+-        pSen->SenInit = SK_SEN_DYN_INIT_NONE;
+-
+-              /* 3.3V VAUX Voltage */
+-              if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
+-                      pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
+-                      pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
+-              }
+-              /* 0V VAUX Voltage */
+-              else {
+-                      pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
+-                      pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
+-              }
+-      }
+-
+-      /*
+-       * Check initialization state:
+-       * The VIO Thresholds need adaption
+-       */
+-      if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
+-           pSen->SenValue > SK_SEN_WARNLOW2C &&
+-           pSen->SenValue < SK_SEN_WARNHIGH2) {
+-              pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
+-              pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
+-              pSen->SenInit = SK_TRUE;
+-      }
+-
+-      if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
+-           pSen->SenValue > SK_SEN_WARNLOW2 &&
+-           pSen->SenValue < SK_SEN_WARNHIGH2C) {
+-              pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
+-              pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
+-              pSen->SenInit = SK_TRUE;
+-      }
+-#endif
+-
+-      if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
+-              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
+-      }
+-}     /* SkI2cCheckSensor */
+-
+-
+-/*
+- * The only Event to be served is the timeout event
+- *
+- */
+-int   SkI2cEvent(
+-SK_AC         *pAC,   /* Adapter Context */
+-SK_IOC                IoC,    /* I/O Context */
+-SK_U32                Event,  /* Module specific Event */
+-SK_EVPARA     Para)   /* Event specific Parameter */
+-{
+-      int                     ReadComplete;
+-      SK_SENSOR       *pSen;
+-      SK_U32          Time;
+-      SK_EVPARA       ParaLocal;
+-      int                     i;
+-
+-      /* New case: no sensors */
+-      if (pAC->I2c.MaxSens == 0) {
+-              return(0);
+-      }
+-
+-      switch (Event) {
+-      case SK_I2CEV_IRQ:
+-              pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+-              ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
+-
+-              if (ReadComplete) {
+-                      /* Check sensor against defined thresholds */
+-                      SkI2cCheckSensor(pAC, pSen);
+-
+-                      /* Increment Current sensor and set appropriate Timeout */
+-                      pAC->I2c.CurrSens++;
+-                      if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
+-                              pAC->I2c.CurrSens = 0;
+-                              Time = SK_I2C_TIM_LONG;
+-                      }
+-                      else {
+-                              Time = SK_I2C_TIM_SHORT;
+-                      }
+-
+-                      /* Start Timer */
+-                      ParaLocal.Para64 = (SK_U64)0;
+-
+-                      pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
+-                      
+-                      SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
+-                              SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
+-              }
+-        else {
+-                      /* Start Timer */
+-                      ParaLocal.Para64 = (SK_U64)0;
+-
+-                      pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
+-
+-            SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
+-                              SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
+-              }
+-              break;
+-      case SK_I2CEV_TIM:
+-              if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
+-
+-                      ParaLocal.Para64 = (SK_U64)0;
+-                      SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
+-
+-                      pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+-                      ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
+-
+-                      if (ReadComplete) {
+-                              /* Check sensor against defined thresholds */
+-                              SkI2cCheckSensor(pAC, pSen);
+-
+-                              /* Increment Current sensor and set appropriate Timeout */
+-                              pAC->I2c.CurrSens++;
+-                              if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
+-                                      pAC->I2c.CurrSens = 0;
+-                                      Time = SK_I2C_TIM_LONG;
+-                              }
+-                              else {
+-                                      Time = SK_I2C_TIM_SHORT;
+-                              }
+-
+-                              /* Start Timer */
+-                              ParaLocal.Para64 = (SK_U64)0;
+-
+-                              pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
+-
+-                              SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
+-                                      SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
+-                      }
+-              }
+-              else {
+-                      pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+-                      pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
+-                      SK_I2C_STOP(IoC);
+-
+-                      /* Increment Current sensor and set appropriate Timeout */
+-                      pAC->I2c.CurrSens++;
+-                      if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
+-                              pAC->I2c.CurrSens = 0;
+-                              Time = SK_I2C_TIM_LONG;
+-                      }
+-                      else {
+-                              Time = SK_I2C_TIM_SHORT;
+-                      }
+-
+-                      /* Start Timer */
+-                      ParaLocal.Para64 = (SK_U64)0;
+-
+-                      pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
+-
+-                      SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
+-                              SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
+-              }
+-              break;
+-      case SK_I2CEV_CLEAR:
+-              for (i = 0; i < SK_MAX_SENSORS; i++) {
+-                      pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
+-                      pAC->I2c.SenTable[i].SenErrCts = 0;
+-                      pAC->I2c.SenTable[i].SenWarnCts = 0;
+-                      pAC->I2c.SenTable[i].SenBegErrTS = 0;
+-                      pAC->I2c.SenTable[i].SenBegWarnTS = 0;
+-                      pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
+-                      pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
+-                      pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
+-                      pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
+-              }
+-              break;
+-      default:
+-              SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
+-      }
+-
+-      return(0);
+-}     /* SkI2cEvent*/
+-
+-#endif /* !SK_DIAG */
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/sklm80.c linux-2.6.9.new/drivers/net/sk98lin/sklm80.c
+--- linux-2.6.9.old/drivers/net/sk98lin/sklm80.c       2004-10-19 05:55:06.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/sklm80.c       2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      sklm80.c
+  * Project:   Gigabit Ethernet Adapters, TWSI-Module
+- * Version:   $Revision: 1.22 $
+- * Date:      $Date: 2003/10/20 09:08:21 $
++ * Version:   $Revision: 1.1 $
++ * Date:      $Date: 2003/12/19 14:02:31 $
+  * Purpose:   Functions to access Voltage and Temperature Sensor (LM80)
+  *
+  ******************************************************************************/
+@@ -27,7 +27,7 @@
+ */
+ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: sklm80.c,v 1.22 2003/10/20 09:08:21 rschmidt Exp $ (C) Marvell. ";
++      "@(#) $Id: sklm80.c,v 1.1 2003/12/19 14:02:31 mschmid Exp $ (C) Marvell. ";
+ #endif
+ #include "h/skdrv1st.h"               /* Driver Specific Definitions */
+@@ -111,12 +111,12 @@
+ /*
+  * read a sensors value (LM80 specific)
+  *
+- * This function reads a sensors value from the I2C sensor chip LM80.
++ * This function reads a sensors value from the TWSI sensor chip LM80.
+  * The sensor is defined by its index into the sensors database in the struct
+  * pAC points to.
+  *
+  * Returns    1 if the read is completed
+- *            0 if the read must be continued (I2C Bus still allocated)
++ *            0 if the read must be continued (TWSI Bus still allocated)
+  */
+ int SkLm80ReadSensor(
+ SK_AC         *pAC,   /* Adapter Context */
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skproc.c linux-2.6.9.new/drivers/net/sk98lin/skproc.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skproc.c       2004-10-19 05:53:11.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skproc.c       2006-12-07 14:35:03.000000000 +0800
+@@ -2,28 +2,34 @@
+  *
+  * Name:      skproc.c
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.11 $
+- * Date:      $Date: 2003/12/11 16:03:57 $
+- * Purpose:   Funktions to display statictic data
++ * Version:   $Revision: 1.14.2.4 $
++ * Date:      $Date: 2005/05/23 13:47:33 $
++ * Purpose:   Functions to display statictic data
+  *
+  ******************************************************************************/
+  
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect GmbH.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2005 Marvell.
++ *
++ *    Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet 
++ *      Server Adapters.
++ *
++ *    Author: Ralph Roesler (rroesler@syskonnect.de)
++ *            Mirko Lindner (mlindner@syskonnect.de)
++ *
++ *    Address all question to: linux@syskonnect.de
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+  *    the Free Software Foundation; either version 2 of the License, or
+  *    (at your option) any later version.
+  *
+- *    Created 22-Nov-2000
+- *    Author: Mirko Lindner (mlindner@syskonnect.de)
+- *
+  *    The information in this file is provided "AS IS" without warranty.
+  *
+- ******************************************************************************/
++ *****************************************************************************/
++
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+@@ -32,9 +38,16 @@
+ #include "h/skversion.h"
+ extern struct SK_NET_DEVICE *SkGeRootDev;
++
++/******************************************************************************
++ *
++ * Local Function Prototypes and Local Variables
++ *
++ *****************************************************************************/
++
+ static int sk_proc_print(void *writePtr, char *format, ...);
+ static void sk_gen_browse(void *buffer);
+-int len;
++static int len;
+ static int sk_seq_show(struct seq_file *seq, void *v);
+ static int sk_proc_open(struct inode *inode, struct file *file);
+@@ -52,16 +65,18 @@
+  *    sk_gen_browse -generic  print "summaries" entry 
+  *
+  * Description:
+- *  This function fills the proc entry with statistic data about 
+- *  the ethernet device.
++ *    This function fills the proc entry with statistic data about 
++ *    the ethernet device.
+  *  
+- * Returns: -
++ * Returns:   N/A
+  *    
+  */
+-static void sk_gen_browse(void *buffer)
++static void sk_gen_browse(
++void *buffer)  /* buffer where the statistics will be stored in */
+ {
+       struct SK_NET_DEVICE    *SkgeProcDev = SkGeRootDev;
+       struct SK_NET_DEVICE    *next;
++      SK_BOOL                 DisableStatistic = 0;
+       SK_PNMI_STRUCT_DATA     *pPnmiStruct;
+       SK_PNMI_STAT            *pPnmiStat;
+       unsigned long           Flags;  
+@@ -69,6 +84,7 @@
+       DEV_NET                 *pNet;
+       SK_AC                   *pAC;
+       char                    sens_msg[50];
++      int                     card_type;
+       int                     MaxSecurityCount = 0;
+       int                     t;
+       int                     i;
+@@ -91,7 +107,7 @@
+                       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+                       Size = SK_PNMI_STRUCT_SIZE;
+-#ifdef SK_DIAG_SUPPORT
++                      DisableStatistic = 0;
+                       if (pAC->BoardLevel == SK_INIT_DATA) {
+                               SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA));
+                               if (pAC->DiagModeActive == DIAG_NOTACTIVE) {
+@@ -100,13 +116,13 @@
+                       } else {
+                               SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1);
+                       }
+-#else
+-                      SkPnmiGetStruct(pAC, pAC->IoBase, 
+-                              pPnmiStruct, &Size, t-1);
+-#endif
+                       spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+-      
+                       if (strcmp(pAC->dev[t-1]->name, currDev->name) == 0) {
++                              if (!pAC->GIni.GIYukon32Bit)
++                                      card_type = 64;
++                              else
++                                      card_type = 32;
++
+                               pPnmiStat = &pPnmiStruct->Stat[0];
+                               len = sk_proc_print(buffer, 
+                                       "\nDetailed statistic for device %s\n",
+@@ -118,6 +134,17 @@
+                               len += sk_proc_print(buffer, 
+                                       "\nBoard statistics\n\n");
+                               len += sk_proc_print(buffer,
++                                      "Card name                      %s\n",
++                                      pAC->DeviceStr);
++                              len += sk_proc_print(buffer,
++                                      "Vendor/Device ID               %x/%x\n",
++                                      pAC->PciDev->vendor,
++                                      pAC->PciDev->device);
++                              len += sk_proc_print(buffer,
++                                      "Card type (Bit)                %d\n",
++                                      card_type);
++                                      
++                              len += sk_proc_print(buffer,
+                                       "Active Port                    %c\n",
+                                       'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
+                                       Net[t-1].PrefPort]->PortNumber);
+@@ -126,177 +153,239 @@
+                                       'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
+                                       Net[t-1].PrefPort]->PortNumber);
+-                              len += sk_proc_print(buffer,
+-                                      "Bus speed (MHz)                %d\n",
+-                                      pPnmiStruct->BusSpeed);
+-
+-                              len += sk_proc_print(buffer,
+-                                      "Bus width (Bit)                %d\n",
+-                                      pPnmiStruct->BusWidth);
+-                              len += sk_proc_print(buffer,
+-                                      "Driver version                 %s\n",
+-                                      VER_STRING);
+-                              len += sk_proc_print(buffer,
+-                                      "Hardware revision              v%d.%d\n",
+-                                      (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
+-                                      pAC->GIni.GIPciHwRev & 0x0F);
+-
+-                              /* Print sensor informations */
+-                              for (i=0; i < pAC->I2c.MaxSens; i ++) {
+-                                      /* Check type */
+-                                      switch (pAC->I2c.SenTable[i].SenType) {
+-                                      case 1:
+-                                              strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+-                                              strcat(sens_msg, " (C)");
+-                                              len += sk_proc_print(buffer,
+-                                                      "%-25s      %d.%02d\n",
+-                                                      sens_msg,
+-                                                      pAC->I2c.SenTable[i].SenValue / 10,
+-                                                      pAC->I2c.SenTable[i].SenValue % 10);
++                              if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) {
++                                      len += sk_proc_print(buffer,
++                                      "Interrupt Moderation           static (%d ints/sec)\n",
++                                      pAC->DynIrqModInfo.MaxModIntsPerSec);
++                              } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
++                                      len += sk_proc_print(buffer,
++                                      "Interrupt Moderation           dynamic (%d ints/sec)\n",
++                                      pAC->DynIrqModInfo.MaxModIntsPerSec);
++                              } else {
++                                      len += sk_proc_print(buffer,
++                                      "Interrupt Moderation           disabled\n");
++                              }
+-                                              strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+-                                              strcat(sens_msg, " (F)");
++                              if (pAC->GIni.GIPciBus == SK_PEX_BUS) {
++                                      len += sk_proc_print(buffer,
++                                              "Bus type                       PCI-Express\n");
++                                      len += sk_proc_print(buffer,
++                                              "Bus width (Lanes)              %d\n",
++                                              pAC->GIni.GIPexWidth);
++                              } else {
++                                      if (pAC->GIni.GIPciBus == SK_PCIX_BUS) {
+                                               len += sk_proc_print(buffer,
+-                                                      "%-25s      %d.%02d\n",
+-                                                      sens_msg,
+-                                                      ((((pAC->I2c.SenTable[i].SenValue)
+-                                                      *10)*9)/5 + 3200)/100,
+-                                                      ((((pAC->I2c.SenTable[i].SenValue)
+-                                                      *10)*9)/5 + 3200) % 10);
+-                                              break;
+-                                      case 2:
+-                                              strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+-                                              strcat(sens_msg, " (V)");
++                                                      "Bus type                       PCI-X\n");
++                                              if (pAC->GIni.GIPciMode == PCI_OS_SPD_X133) {
++                                                      len += sk_proc_print(buffer,
++                                                              "Bus speed (MHz)                133\n");
++                                              } else if (pAC->GIni.GIPciMode == PCI_OS_SPD_X100) {
++                                                      len += sk_proc_print(buffer,
++                                                              "Bus speed (MHz)                100\n");
++                                              } else if (pAC->GIni.GIPciMode == PCI_OS_SPD_X66) {
++                                                      len += sk_proc_print(buffer,
++                                                              "Bus speed (MHz)                66\n");
++                                              } else {
++                                                      len += sk_proc_print(buffer,
++                                                              "Bus speed (MHz)                33\n");
++                                              }
++                                      } else {
+                                               len += sk_proc_print(buffer,
+-                                                      "%-25s      %d.%03d\n",
+-                                                      sens_msg,
+-                                                      pAC->I2c.SenTable[i].SenValue / 1000,
+-                                                      pAC->I2c.SenTable[i].SenValue % 1000);
+-                                              break;
+-                                      case 3:
+-                                              strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+-                                              strcat(sens_msg, " (rpm)");
++                                                      "Bus type                       PCI\n");
+                                               len += sk_proc_print(buffer,
+-                                                      "%-25s      %d\n",
+-                                                      sens_msg,
+-                                                      pAC->I2c.SenTable[i].SenValue);
+-                                              break;
+-                                      default:
+-                                              break;
++                                                      "Bus speed (MHz)                %d\n",
++                                                      pPnmiStruct->BusSpeed);
+                                       }
++                                      len += sk_proc_print(buffer,
++                                              "Bus width (Bit)                %d\n",
++                                              pPnmiStruct->BusWidth);
+                               }
+-                              
+-                              /*Receive statistics */
+-                              len += sk_proc_print(buffer, 
+-                              "\nReceive statistics\n\n");
+                               len += sk_proc_print(buffer,
+-                                      "Received bytes                 %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxOctetsOkCts);
+-                              len += sk_proc_print(buffer,
+-                                      "Received packets               %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxOkCts);
+-#if 0
+-                              if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && 
+-                                      pAC->HWRevision < 12) {
+-                                      pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - 
+-                                              pPnmiStat->StatRxShortsCts;
+-                                      pPnmiStat->StatRxShortsCts = 0;
+-                              }
+-#endif
+-                              if (pNet->Mtu > 1500) 
+-                                      pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
+-                                              pPnmiStat->StatRxTooLongCts;
+-
+-                              len += sk_proc_print(buffer,
+-                                      "Receive errors                 %Lu\n",
+-                                      (unsigned long long) pPnmiStruct->InErrorsCts);
+-                              len += sk_proc_print(buffer,
+-                                      "Receive dropped                %Lu\n",
+-                                      (unsigned long long) pPnmiStruct->RxNoBufCts);
++                                      "Driver version                 %s (%s)\n",
++                                      VER_STRING, PATCHLEVEL);
+                               len += sk_proc_print(buffer,
+-                                      "Received multicast             %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxMulticastOkCts);
++                                      "Driver release date            %s\n",
++                                      pAC->Pnmi.pDriverReleaseDate);
+                               len += sk_proc_print(buffer,
+-                                      "Receive error types\n");
+-                              len += sk_proc_print(buffer,
+-                                      "   length                      %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxRuntCts);
+-                              len += sk_proc_print(buffer,
+-                                      "   buffer overflow             %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
+-                              len += sk_proc_print(buffer,
+-                                      "   bad crc                     %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxFcsCts);
+-                              len += sk_proc_print(buffer,
+-                                      "   framing                     %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxFramingCts);
+-                              len += sk_proc_print(buffer,
+-                                      "   missed frames               %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxMissedCts);
+-
+-                              if (pNet->Mtu > 1500)
+-                                      pPnmiStat->StatRxTooLongCts = 0;
++                                      "Hardware revision              v%d.%d\n",
++                                      (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
++                                      pAC->GIni.GIPciHwRev & 0x0F);
+-                              len += sk_proc_print(buffer,
+-                                      "   too long                    %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxTooLongCts);                                      
+-                              len += sk_proc_print(buffer,
+-                                      "   carrier extension           %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxCextCts);                         
+-                              len += sk_proc_print(buffer,
+-                                      "   too short                   %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxShortsCts);                               
+-                              len += sk_proc_print(buffer,
+-                                      "   symbol                      %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxSymbolCts);                               
+-                              len += sk_proc_print(buffer,
+-                                      "   LLC MAC size                %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxIRLengthCts);                             
+-                              len += sk_proc_print(buffer,
+-                                      "   carrier event               %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxCarrierCts);                              
+-                              len += sk_proc_print(buffer,
+-                                      "   jabber                      %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatRxJabberCts);                               
++                              if (!netif_running(pAC->dev[t-1])) {
++                                      len += sk_proc_print(buffer,
++                                              "\n      Device %s is down.\n"
++                                              "      Therefore no statistics are available.\n"
++                                              "      After bringing the device up (ifconfig)"
++                                              " statistics will\n"
++                                              "      be displayed.\n",
++                                              pAC->dev[t-1]->name);
++                                      DisableStatistic = 1;
++                              }
++                              /* Display only if statistic info available */
++                              /* Print sensor informations */
++                              if (!DisableStatistic) {
++                                      for (i=0; i < pAC->I2c.MaxSens; i ++) {
++                                              /* Check type */
++                                              switch (pAC->I2c.SenTable[i].SenType) {
++                                              case 1:
++                                                      strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
++                                                      strcat(sens_msg, " (C)");
++                                                      len += sk_proc_print(buffer,
++                                                              "%-25s      %d.%02d\n",
++                                                              sens_msg,
++                                                              pAC->I2c.SenTable[i].SenValue / 10,
++                                                              pAC->I2c.SenTable[i].SenValue %
++                                                              10);
++
++                                                      strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
++                                                      strcat(sens_msg, " (F)");
++                                                      len += sk_proc_print(buffer,
++                                                              "%-25s      %d.%02d\n",
++                                                              sens_msg,
++                                                              ((((pAC->I2c.SenTable[i].SenValue)
++                                                              *10)*9)/5 + 3200)/100,
++                                                              ((((pAC->I2c.SenTable[i].SenValue)
++                                                              *10)*9)/5 + 3200) % 10);
++                                                      break;
++                                              case 2:
++                                                      strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
++                                                      strcat(sens_msg, " (V)");
++                                                      len += sk_proc_print(buffer,
++                                                              "%-25s      %d.%03d\n",
++                                                              sens_msg,
++                                                              pAC->I2c.SenTable[i].SenValue / 1000,
++                                                              pAC->I2c.SenTable[i].SenValue % 1000);
++                                                      break;
++                                              case 3:
++                                                      strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
++                                                      strcat(sens_msg, " (rpm)");
++                                                      len += sk_proc_print(buffer,
++                                                              "%-25s      %d\n",
++                                                              sens_msg,
++                                                              pAC->I2c.SenTable[i].SenValue);
++                                                      break;
++                                              default:
++                                                      break;
++                                              }
++                                      }
++                      
++                                      /*Receive statistics */
++                                      len += sk_proc_print(buffer, 
++                                      "\nReceive statistics\n\n");
++
++                                      len += sk_proc_print(buffer,
++                                              "Received bytes                 %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxOctetsOkCts);
++                                      len += sk_proc_print(buffer,
++                                              "Received packets               %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxOkCts);
++#if 0
++                                      if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && 
++                                              pAC->HWRevision < 12) {
++                                              pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - 
++                                                      pPnmiStat->StatRxShortsCts;
++                                              pPnmiStat->StatRxShortsCts = 0;
++                                      }
++#endif
++                                      if (pAC->dev[t-1]->mtu > 1500) 
++                                              pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
++                                                      pPnmiStat->StatRxTooLongCts;
++
++                                      len += sk_proc_print(buffer,
++                                              "Receive errors                 %Lu\n",
++                                              (unsigned long long) pPnmiStruct->InErrorsCts);
++                                      len += sk_proc_print(buffer,
++                                              "Receive dropped                %Lu\n",
++                                              (unsigned long long) pPnmiStruct->RxNoBufCts);
++                                      len += sk_proc_print(buffer,
++                                              "Received multicast             %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxMulticastOkCts);
++#ifdef ADVANCED_STATISTIC_OUTPUT
++                                      len += sk_proc_print(buffer,
++                                              "Receive error types\n");
++                                      len += sk_proc_print(buffer,
++                                              "   length                      %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxRuntCts);
++                                      len += sk_proc_print(buffer,
++                                              "   buffer overflow             %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
++                                      len += sk_proc_print(buffer,
++                                              "   bad crc                     %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxFcsCts);
++                                      len += sk_proc_print(buffer,
++                                              "   framing                     %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxFramingCts);
++                                      len += sk_proc_print(buffer,
++                                              "   missed frames               %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxMissedCts);
++
++                                      if (pAC->dev[t-1]->mtu > 1500)
++                                              pPnmiStat->StatRxTooLongCts = 0;
++
++                                      len += sk_proc_print(buffer,
++                                              "   too long                    %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxTooLongCts);                                      
++                                      len += sk_proc_print(buffer,
++                                              "   carrier extension           %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxCextCts);                         
++                                      len += sk_proc_print(buffer,
++                                              "   too short                   %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxShortsCts);                               
++                                      len += sk_proc_print(buffer,
++                                              "   symbol                      %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxSymbolCts);                               
++                                      len += sk_proc_print(buffer,
++                                              "   LLC MAC size                %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxIRLengthCts);                             
++                                      len += sk_proc_print(buffer,
++                                              "   carrier event               %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxCarrierCts);                              
++                                      len += sk_proc_print(buffer,
++                                              "   jabber                      %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatRxJabberCts);                               
++#endif
+-                              /*Transmit statistics */
+-                              len += sk_proc_print(buffer, 
+-                              "\nTransmit statistics\n\n");
++                                      /*Transmit statistics */
++                                      len += sk_proc_print(buffer, 
++                                      "\nTransmit statistics\n\n");
+                               
+-                              len += sk_proc_print(buffer,
+-                                      "Transmited bytes               %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatTxOctetsOkCts);
+-                              len += sk_proc_print(buffer,
+-                                      "Transmited packets             %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatTxOkCts);
+-                              len += sk_proc_print(buffer,
+-                                      "Transmit errors                %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
+-                              len += sk_proc_print(buffer,
+-                                      "Transmit dropped               %Lu\n",
+-                                      (unsigned long long) pPnmiStruct->TxNoBufCts);
+-                              len += sk_proc_print(buffer,
+-                                      "Transmit collisions            %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
+-                              len += sk_proc_print(buffer,
+-                                      "Transmit error types\n");
+-                              len += sk_proc_print(buffer,
+-                                      "   excessive collision         %ld\n",
+-                                      pAC->stats.tx_aborted_errors);
+-                              len += sk_proc_print(buffer,
+-                                      "   carrier                     %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatTxCarrierCts);
+-                              len += sk_proc_print(buffer,
+-                                      "   fifo underrun               %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
+-                              len += sk_proc_print(buffer,
+-                                      "   heartbeat                   %Lu\n",
+-                                      (unsigned long long) pPnmiStat->StatTxCarrierCts);
+-                              len += sk_proc_print(buffer,
+-                                      "   window                      %ld\n",
+-                                      pAC->stats.tx_window_errors);
++                                      len += sk_proc_print(buffer,
++                                              "Transmitted bytes              %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatTxOctetsOkCts);
++                                      len += sk_proc_print(buffer,
++                                              "Transmitted packets            %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatTxOkCts);
++                                      len += sk_proc_print(buffer,
++                                              "Transmit errors                %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
++                                      len += sk_proc_print(buffer,
++                                              "Transmit dropped               %Lu\n",
++                                              (unsigned long long) pPnmiStruct->TxNoBufCts);
++                                      len += sk_proc_print(buffer,
++                                              "Transmit collisions            %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
++#ifdef ADVANCED_STATISTIC_OUTPUT
++                                      len += sk_proc_print(buffer,
++                                              "Transmit error types\n");
++                                      len += sk_proc_print(buffer,
++                                              "   excessive collision         %ld\n",
++                                              pAC->stats.tx_aborted_errors);
++                                      len += sk_proc_print(buffer,
++                                              "   carrier                     %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatTxCarrierCts);
++                                      len += sk_proc_print(buffer,
++                                              "   fifo underrun               %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
++                                      len += sk_proc_print(buffer,
++                                              "   heartbeat                   %Lu\n",
++                                              (unsigned long long) pPnmiStat->StatTxCarrierCts);
++                                      len += sk_proc_print(buffer,
++                                              "   window                      %ld\n",
++                                              pAC->stats.tx_window_errors);
++#endif
++                              } /* if (!DisableStatistic) */
+                               
+                       } /* if (strcmp(pACname, currDeviceName) == 0) */
+               }
+@@ -306,16 +395,20 @@
+ /*****************************************************************************
+  *
+- *      sk_proc_print -generic line print  
++ *      sk_proc_print - generic line print  
+  *
+  * Description:
+- *  This function fills the proc entry with statistic data about 
+- *  the ethernet device.
++ *    This function fills the proc entry with statistic data about the 
++ *    ethernet device.
+  *  
+- * Returns: number of bytes written
++ * Returns:
++ *    the number of bytes written
+  *      
+  */ 
+-static int sk_proc_print(void *writePtr, char *format, ...)
++static int sk_proc_print(
++void *writePtr, /* the buffer pointer         */
++char *format,   /* the format of the string   */
++...)            /* variable list of arguments */
+ {   
+ #define MAX_LEN_SINGLE_LINE 256
+       char     str[MAX_LEN_SINGLE_LINE];
+@@ -341,19 +434,22 @@
+  *      sk_seq_show - show proc information of a particular adapter
+  *
+  * Description:
+- *  This function fills the proc entry with statistic data about 
+- *  the ethernet device. It invokes the generic sk_gen_browse() to
+- *  print out all items one per one.
++ *    This function fills the proc entry with statistic data about the
++ *    ethernet device. It invokes the generic sk_gen_browse() to print
++ *    out all items one per one.
+  *  
+- * Returns: number of bytes written
++ * Returns:
++ *    the number of bytes written
+  *      
+  */
+-static int sk_seq_show(struct seq_file *seq, void *v)
++static int sk_seq_show(
++struct seq_file *seq,  /* the sequence pointer */
++void            *v)    /* additional pointer   */
+ {
+-    void *castedBuffer = (void *) seq;
+-    currDev = seq->private;
+-    sk_gen_browse(castedBuffer);
+-    return 0;
++      void *castedBuffer = (void *) seq;
++      currDev = seq->private;
++      sk_gen_browse(castedBuffer);
++      return 0;
+ }
+ /*****************************************************************************
+@@ -361,14 +457,17 @@
+  *      sk_proc_open - register the show function when proc is open'ed
+  *  
+  * Description:
+- *  This function is called whenever a sk98lin proc file is queried.
++ *    This function is called whenever a sk98lin proc file is queried.
+  *  
+- * Returns: the return value of single_open()
++ * Returns:
++ *    the return value of single_open()
+  *      
+  */
+-static int sk_proc_open(struct inode *inode, struct file *file)
++static int sk_proc_open(
++struct inode *inode,  /* the inode of the file   */
++struct file  *file)   /* the file pointer itself */
+ {
+-    return single_open(file, sk_seq_show, PDE(inode)->data);
++      return single_open(file, sk_seq_show, PDE(inode)->data);
+ }
+ /*******************************************************************************
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skqueue.c linux-2.6.9.new/drivers/net/sk98lin/skqueue.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skqueue.c      2004-10-19 05:53:43.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skqueue.c      2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skqueue.c
+  * Project:   Gigabit Ethernet Adapters, Event Scheduler Module
+- * Version:   $Revision: 1.20 $
+- * Date:      $Date: 2003/09/16 13:44:00 $
++ * Version:   $Revision: 2.3 $
++ * Date:      $Date: 2004/05/14 13:28:18 $
+  * Purpose:   Management of an event queue.
+  *
+  ******************************************************************************/
+@@ -28,7 +28,7 @@
+  */
+ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: skqueue.c,v 1.20 2003/09/16 13:44:00 rschmidt Exp $ (C) Marvell.";
++      "@(#) $Id: skqueue.c,v 2.3 2004/05/14 13:28:18 malthoff Exp $ (C) Marvell.";
+ #endif
+ #include "h/skdrv1st.h"               /* Driver Specific Definitions */
+@@ -48,10 +48,16 @@
+ #define PRINTF(a,b,c)
+-/*
+- * init event queue management
++/******************************************************************************
++ *
++ *    SkEventInit() - init event queue management
+  *
+- * Must be called during init level 0.
++ * Description:
++ *    This function initializes event queue management.
++ *    It must be called during init level 0.
++ *
++ * Returns:
++ *    nothing
+  */
+ void  SkEventInit(
+ SK_AC *pAC,   /* Adapter context */
+@@ -67,8 +73,17 @@
+       }
+ }
+-/*
+- * add event to queue
++/******************************************************************************
++ *
++ *    SkEventQueue()  -       add event to queue
++ *
++ * Description:
++ *    This function adds an event to the event queue.
++ *    At least Init Level 1 is required to queue events,
++ *    but will be scheduled add Init Level 2.
++ *
++ * returns:
++ *    nothing
+  */
+ void  SkEventQueue(
+ SK_AC         *pAC,   /* Adapters context */
+@@ -76,26 +91,45 @@
+ SK_U32                Event,  /* Event to be queued */
+ SK_EVPARA     Para)   /* Event parameter */
+ {
+-      pAC->Event.EvPut->Class = Class;
+-      pAC->Event.EvPut->Event = Event;
+-      pAC->Event.EvPut->Para = Para;
++
++      if (pAC->GIni.GILevel == SK_INIT_DATA) {
++              SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E003, SKERR_Q_E003MSG);
++      }
++      else {
++              pAC->Event.EvPut->Class = Class;
++              pAC->Event.EvPut->Event = Event;
++              pAC->Event.EvPut->Para = Para;
+       
+-      if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT])
+-              pAC->Event.EvPut = pAC->Event.EvQueue;
++              if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT])
++                      pAC->Event.EvPut = pAC->Event.EvQueue;
+-      if (pAC->Event.EvPut == pAC->Event.EvGet) {
+-              SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG);
++              if (pAC->Event.EvPut == pAC->Event.EvGet) {
++                      SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG);
++              }
+       }
+ }
+-/*
+- * event dispatcher
+- *    while event queue is not empty
+- *            get event from queue
+- *            send command to state machine
+- *    end
+- *    return error reported by individual Event function
+- *            0 if no error occured.
++/******************************************************************************
++ *
++ *    SkEventDispatcher() -    Event Dispatcher
++ *
++ * Description:
++ *    The event dispatcher performs the following operations:
++ *            o while event queue is not empty
++ *                    - get event from queue
++ *                    - send event to state machine
++ *              end
++ *
++ * CAUTION:
++ *    The event functions MUST report an error if performing a reinitialization
++ *    of the event queue, e.g. performing level Init 0..2 while in dispatcher
++ *    call!
++ *  ANY OTHER return value delays scheduling the other events in the
++ *    queue. In this case the event blocks the queue until
++ *  the error condition is cleared!
++ *
++ * Returns:
++ *    The return value error reported by individual event function
+  */
+ int   SkEventDispatcher(
+ SK_AC *pAC,   /* Adapters Context */
+@@ -105,6 +139,10 @@
+       SK_U32                  Class;
+       int                     Rtv;
++      if (pAC->GIni.GILevel != SK_INIT_RUN) {
++              SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E005, SKERR_Q_E005MSG);
++      }
++
+       pEv = pAC->Event.EvGet;
+       
+       PRINTF("dispatch get %x put %x\n", pEv, pAC->Event.ev_put);
+@@ -152,6 +190,11 @@
+                       Rtv = SkFdEvent(pAC, Ioc, pEv->Event, pEv->Para);
+                       break;
+ #endif /* SK_USE_LAC_EV */
++#ifdef SK_ASF
++              case SKGE_ASF :
++                      Rtv = SkAsfEvent(pAC,Ioc,pEv->Event,pEv->Para);
++                      break ;
++#endif
+ #ifdef        SK_USE_CSUM
+               case SKGE_CSUM :
+                       Rtv = SkCsEvent(pAC, Ioc, pEv->Event, pEv->Para);
+@@ -163,6 +206,20 @@
+               }
+               if (Rtv != 0) {
++                      /* 
++                       * Special Case: See CAUTION statement above.
++                       * We assume the event queue is reset.
++                       */
++                      if (pAC->Event.EvGet != pAC->Event.EvQueue &&
++                              pAC->Event.EvGet != pEv) {
++                              /*
++                               * Create an error log entry if the
++                               * event queue isn't reset.
++                               * In this case it may be blocked.
++                               */
++                              SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E004, SKERR_Q_E004MSG);
++                      }
++
+                       return(Rtv);
+               }
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skrlmt.c linux-2.6.9.new/drivers/net/sk98lin/skrlmt.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skrlmt.c       2004-10-19 05:54:37.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skrlmt.c       2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skrlmt.c
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.69 $
+- * Date:      $Date: 2003/04/15 09:39:22 $
++ * Version:   $Revision: 2.3 $
++ * Date:      $Date: 2005/05/04 09:47:53 $
+  * Purpose:   Manage links on SK-NET Adapters, esp. redundant ones.
+  *
+  ******************************************************************************/
+@@ -39,7 +39,7 @@
+ #ifndef       lint
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: skrlmt.c,v 1.69 2003/04/15 09:39:22 tschilli Exp $ (C) Marvell.";
++      "@(#) $Id: skrlmt.c,v 2.3 2005/05/04 09:47:53 tschilli Exp $ (C) Marvell.";
+ #endif        /* !defined(lint) */
+ #define __SKRLMT_C
+@@ -350,7 +350,7 @@
+     SK_BOOL           PhysicalAMacAddressSet;
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
+-              ("RLMT Init level %d.\n", Level))
++              ("RLMT Init level %d.\n", Level));
+       switch (Level) {
+       case SK_INIT_DATA:      /* Initialize data structures. */
+@@ -390,7 +390,7 @@
+       case SK_INIT_IO:        /* GIMacsFound first available here. */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
+-                      ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound))
++                      ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound));
+               pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
+@@ -512,7 +512,7 @@
+       }
+                       
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SkRlmtBuildCheckChain.\n"))
++              ("SkRlmtBuildCheckChain.\n"));
+       NumMacsUp = 0;
+@@ -558,7 +558,7 @@
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("Port %d checks %d other ports: %2X.\n", i,
+                               pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked,
+-                              pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5]))
++                              pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5]));
+       }
+ #endif        /* DEBUG */
+@@ -604,7 +604,7 @@
+       if ((CheckSrc == 0) || (CheckDest == 0)) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR,
+                       ("SkRlmtBuildPacket: Invalid %s%saddr.\n",
+-                       (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : "")))
++                       (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : "")));
+       }
+ #endif
+@@ -796,7 +796,7 @@
+                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX,
+-                              ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber))
++                              ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber));
+               }
+       }
+       return;
+@@ -835,7 +835,7 @@
+                * Bring it up.
+                */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+-                      ("SkRlmtPacketReceive: Received on PortDown.\n"))
++                      ("SkRlmtPacketReceive: Received on PortDown.\n"));
+               pRPort->PortState = SK_RLMT_PS_GOING_UP;
+               pRPort->GuTimeStamp = SkOsGetTime(pAC);
+@@ -849,7 +849,7 @@
+       }       /* PortDown && !SuspectTx */
+       else if (pRPort->CheckingState & SK_RLMT_PCS_RX) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+-                      ("SkRlmtPacketReceive: Stop bringing port down.\n"))
++                      ("SkRlmtPacketReceive: Stop bringing port down.\n"));
+               SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
+               pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
+               /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
+@@ -896,7 +896,7 @@
+       pRPort = &pAC->Rlmt.Port[PortNumber];
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+-              ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber))
++              ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber));
+       pRPacket = (SK_RLMT_PACKET*)pMb->pData;
+       pSPacket = (SK_SPTREE_PACKET*)pRPacket;
+@@ -917,7 +917,7 @@
+               /* Not sent to current MAC or registered MC address => Trash it. */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+-                      ("SkRlmtPacketReceive: Not for me.\n"))
++                      ("SkRlmtPacketReceive: Not for me.\n"));
+               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+               return;
+@@ -955,7 +955,7 @@
+                       pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
+                       pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+-                              ("SkRlmtPacketReceive: Duplicate MAC Address.\n"))
++                              ("SkRlmtPacketReceive: Duplicate MAC Address.\n"));
+                       /* Error Log entry. */
+                       SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG);
+@@ -963,7 +963,7 @@
+               else {
+                       /* Simply trash it. */
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+-                              ("SkRlmtPacketReceive: Sent by me.\n"))
++                              ("SkRlmtPacketReceive: Sent by me.\n"));
+               }
+               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+@@ -1007,7 +1007,7 @@
+ #endif        /* 0 */
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+-                              ("SkRlmtPacketReceive: Announce.\n"))
++                              ("SkRlmtPacketReceive: Announce.\n"));
+                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+                       break;
+@@ -1015,7 +1015,7 @@
+               case SK_PACKET_ALIVE:
+                       if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) {
+                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+-                                      ("SkRlmtPacketReceive: Alive Reply.\n"))
++                                      ("SkRlmtPacketReceive: Alive Reply.\n"));
+                               if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) ||
+                                       SK_ADDR_EQUAL(
+@@ -1046,7 +1046,7 @@
+                       }
+                       else {  /* Alive Request Packet. */
+                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+-                                      ("SkRlmtPacketReceive: Alive Request.\n"))
++                                      ("SkRlmtPacketReceive: Alive Request.\n"));
+                               pRPort->RxHelloCts++;
+@@ -1065,7 +1065,7 @@
+               case SK_PACKET_CHECK_TX:
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+-                              ("SkRlmtPacketReceive: Check your tx line.\n"))
++                              ("SkRlmtPacketReceive: Check your tx line.\n"));
+                       /* A port checking us requests us to check our tx line. */
+                       pRPort->CheckingState |= SK_RLMT_PCS_TX;
+@@ -1088,7 +1088,7 @@
+               case SK_PACKET_ADDR_CHANGED:
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+-                              ("SkRlmtPacketReceive: Address Change.\n"))
++                              ("SkRlmtPacketReceive: Address Change.\n"));
+                       /* Build the check chain. */
+                       SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
+@@ -1097,7 +1097,7 @@
+               default:
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+-                              ("SkRlmtPacketReceive: Unknown RLMT packet.\n"))
++                              ("SkRlmtPacketReceive: Unknown RLMT packet.\n"));
+                       /* RA;:;: ??? */
+                       SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+@@ -1107,7 +1107,7 @@
+               pSPacket->Ctrl == SK_RLMT_SPT_CTRL &&
+               (pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+-                      ("SkRlmtPacketReceive: BPDU Packet.\n"))
++                      ("SkRlmtPacketReceive: BPDU Packet.\n"));
+               /* Spanning Tree packet. */
+               pRPort->RxSpHelloCts++;
+@@ -1139,7 +1139,7 @@
+                                       pRPort->Root.Id[0], pRPort->Root.Id[1],
+                                       pRPort->Root.Id[2], pRPort->Root.Id[3],
+                                       pRPort->Root.Id[4], pRPort->Root.Id[5],
+-                                      pRPort->Root.Id[6], pRPort->Root.Id[7]))
++                                      pRPort->Root.Id[6], pRPort->Root.Id[7]));
+               }
+               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+@@ -1150,7 +1150,7 @@
+       }
+       else {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
+-                      ("SkRlmtPacketReceive: Unknown Packet Type.\n"))
++                      ("SkRlmtPacketReceive: Unknown Packet Type.\n"));
+               /* Unknown packet. */
+               SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
+@@ -1232,7 +1232,7 @@
+       if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n",
+-                              PortNumber, pRPort->PacketsPerTimeSlot))
++                              PortNumber, pRPort->PacketsPerTimeSlot));
+               /*
+                * Check segmentation if there was no receive at least twice
+@@ -1249,7 +1249,7 @@
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                       ("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n",
+-                              pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX))
++                              pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX));
+               if (pRPort->PortState != SK_RLMT_PS_DOWN) {
+                       NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue);
+@@ -1295,7 +1295,7 @@
+                       ("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n",
+                               PortNumber,
+                               pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot,
+-                              pRPort->PacketsPerTimeSlot))
++                              pRPort->PacketsPerTimeSlot));
+               
+               SkRlmtPortReceives(pAC, IoC, PortNumber);
+               if (pAC->Rlmt.CheckSwitch) {
+@@ -1345,7 +1345,7 @@
+                               i,
+                               pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx,
+                               *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32),
+-                              *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)))
++                              *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)));
+               if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) {
+                       if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) {
+@@ -1358,7 +1358,7 @@
+       if (PortFound) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Port %d received the last broadcast.\n", *pSelect))
++                      ("Port %d received the last broadcast.\n", *pSelect));
+               /* Look if another port's time stamp is similar. */
+               for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
+@@ -1373,7 +1373,7 @@
+                               PortFound = SK_FALSE;
+                               
+                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                                      ("Port %d received a broadcast at a similar time.\n", i))
++                                      ("Port %d received a broadcast at a similar time.\n", i));
+                               break;
+                       }
+               }
+@@ -1385,7 +1385,7 @@
+                       ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially "
+                        "latest broadcast (%u).\n",
+                               *pSelect,
+-                              BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp))
++                              BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp));
+       }
+ #endif        /* DEBUG */
+@@ -1434,7 +1434,7 @@
+                       PortFound = SK_TRUE;
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+                               ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n",
+-                                      *pSelect))
++                                      *pSelect));
+                       break;
+               }
+       }
+@@ -1483,7 +1483,7 @@
+                       }
+                       PortFound = SK_TRUE;
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                              ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect))
++                              ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect));
+                       break;
+               }
+       }
+@@ -1544,7 +1544,7 @@
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect))
++              ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect));
+       return (SK_TRUE);
+ }     /* SkRlmtSelectGoingUp */
+@@ -1590,7 +1590,7 @@
+                       }
+                       PortFound = SK_TRUE;
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                              ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect))
++                              ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect));
+                       break;
+               }
+       }
+@@ -1680,16 +1680,19 @@
+                       Para.Para32[1] = NetIdx;
+                       SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para);
+-                      if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
+-                              (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC,
+-                              pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber,
+-                              SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].
+-                              CurrentMacAddress, &SkRlmtMcAddr)) != NULL) {
+-                              /*
+-                               * Send announce packet to RLMT multicast address to force
+-                               * switches to learn the new location of the logical MAC address.
+-                               */
+-                              SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
++                      if (pAC->Rlmt.NumNets == 1) {
++                              if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
++                                      (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC,
++                                      pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber,
++                                      SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].
++                                      CurrentMacAddress, &SkRlmtMcAddr)) != NULL) {
++
++                                      /*
++                                       * Send announce packet to RLMT multicast address to force
++                                       * switches to learn the new location of the logical MAC address.
++                                       */
++                                      SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
++                              }
+                       }
+               }
+               else {
+@@ -1788,7 +1791,7 @@
+                       if (Para.Para32[1] != Active) {
+                               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                                      ("Active: %d, Para1: %d.\n", Active, Para.Para32[1]))
++                                      ("Active: %d, Para1: %d.\n", Active, Para.Para32[1]));
+                               pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1];
+                               Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
+                                       Port[Para.Para32[0]]->PortNumber;
+@@ -1868,7 +1871,7 @@
+                               pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1],
+                               pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3],
+                               pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5],
+-                              pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7]))
++                              pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7]));
+               if (!pNet->RootIdSet) {
+                       pNet->Root = pNet->Port[i]->Root;
+@@ -1963,13 +1966,13 @@
+       SK_U32                  i;
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0]))
++              ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0]));
+               if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad Parameter.\n"))
++                      ("Bad Parameter.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n"))
++                      ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n"));
+               return;
+       }
+@@ -1990,7 +1993,7 @@
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n"))
++              ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n"));
+ }     /* SkRlmtEvtPortStartTim */
+@@ -2018,21 +2021,21 @@
+       SK_EVPARA               Para2;
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0]))
++              ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0]));
+       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
+       if (!pRPort->PortStarted) {
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG);
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                              ("SK_RLMT_LINK_UP Event EMPTY.\n"))
++                              ("SK_RLMT_LINK_UP Event EMPTY.\n"));
+               return;
+       }
+       if (!pRPort->LinkDown) {
+               /* RA;:;: Any better solution? */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_LINK_UP Event EMPTY.\n"))
++                      ("SK_RLMT_LINK_UP Event EMPTY.\n"));
+               return;
+       }
+@@ -2082,16 +2085,19 @@
+       Para2.Para32[1] = (SK_U32)-1;
+       SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
+               SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2);
+-      
++
+       /* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */
+-      if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
+-              (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 &&
+-              (Para2.pParaPtr =
+-                      SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE,
+-                      &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr)
+-              ) != NULL) {
+-              /* Send "new" packet to RLMT multicast address. */
+-              SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
++      if (pAC->Rlmt.NumNets == 1) {
++              if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
++                      (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 &&
++                      (Para2.pParaPtr =
++                              SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE,
++                              &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr)
++                      ) != NULL) {
++
++                      /* Send "new" packet to RLMT multicast address. */
++                      SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
++              }
+       }
+       if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) {
+@@ -2110,7 +2116,7 @@
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_LINK_UP Event END.\n"))
++              ("SK_RLMT_LINK_UP Event END.\n"));
+ }     /* SkRlmtEvtLinkUp */
+@@ -2136,20 +2142,20 @@
+       SK_RLMT_PORT    *pRPort;
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0]))
++              ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0]));
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad Parameter.\n"))
++                      ("Bad Parameter.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_PORTUP_TIM Event EMPTY.\n"))
++                      ("SK_RLMT_PORTUP_TIM Event EMPTY.\n"));
+               return;
+       }
+       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
+       if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0]))
++                      ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0]));
+               return;
+       }
+@@ -2164,7 +2170,7 @@
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_PORTUP_TIM Event END.\n"))
++              ("SK_RLMT_PORTUP_TIM Event END.\n"));
+ }     /* SkRlmtEvtPortUpTim */
+@@ -2192,13 +2198,13 @@
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+               ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n",
+-                      Para.Para32[0], Event))
++                      Para.Para32[0], Event));
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad Parameter.\n"))
++                      ("Bad Parameter.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_PORTDOWN* Event EMPTY.\n"))
++                      ("SK_RLMT_PORTDOWN* Event EMPTY.\n"));
+               return;
+       }
+@@ -2206,7 +2212,7 @@
+       if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM &&
+               !(pRPort->CheckingState & SK_RLMT_PCS_TX))) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event))
++                      ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event));
+               return;
+       }
+       
+@@ -2243,7 +2249,7 @@
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event))
++              ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event));
+ }     /* SkRlmtEvtPortDownX */
+@@ -2270,7 +2276,7 @@
+       pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0]))
++              ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0]));
+       if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
+               pRPort->Net->LinksUp--;
+@@ -2289,7 +2295,7 @@
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_LINK_DOWN Event END.\n"))
++              ("SK_RLMT_LINK_DOWN Event END.\n"));
+ }     /* SkRlmtEvtLinkDown */
+@@ -2318,13 +2324,13 @@
+       SK_MAC_ADDR             *pNewMacAddr;
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0]))
++              ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0]));
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad Parameter.\n"))
++                      ("Bad Parameter.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_PORT_ADDR Event EMPTY.\n"))
++                      ("SK_RLMT_PORT_ADDR Event EMPTY.\n"));
+               return;
+       }
+@@ -2348,7 +2354,7 @@
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_PORT_ADDR Event END.\n"))
++                      ("SK_RLMT_PORT_ADDR Event END.\n"));
+ }     /* SkRlmtEvtPortAddr */
+@@ -2376,35 +2382,35 @@
+       SK_U32          PortNumber;
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0]))
++              ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0]));
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad Parameter.\n"))
++                      ("Bad Parameter.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_START Event EMPTY.\n"))
++                      ("SK_RLMT_START Event EMPTY.\n"));
+               return;
+       }
+       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad NetNumber %d.\n", Para.Para32[0]))
++                      ("Bad NetNumber %d.\n", Para.Para32[0]));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_START Event EMPTY.\n"))
++                      ("SK_RLMT_START Event EMPTY.\n"));
+               return;
+       }
+       if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_START Event EMPTY.\n"))
++                      ("SK_RLMT_START Event EMPTY.\n"));
+               return;
+       }
+       if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("All nets should have been started.\n"))
++                      ("All nets should have been started.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_START Event EMPTY.\n"))
++                      ("SK_RLMT_START Event EMPTY.\n"));
+               return;
+       }
+@@ -2438,7 +2444,7 @@
+       pAC->Rlmt.NetsStarted++;
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_START Event END.\n"))
++                      ("SK_RLMT_START Event END.\n"));
+ }     /* SkRlmtEvtStart */
+@@ -2466,35 +2472,35 @@
+       SK_U32          i;
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0]))
++              ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0]));
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad Parameter.\n"))
++                      ("Bad Parameter.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_STOP Event EMPTY.\n"))
++                      ("SK_RLMT_STOP Event EMPTY.\n"));
+               return;
+       }
+       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad NetNumber %d.\n", Para.Para32[0]))
++                      ("Bad NetNumber %d.\n", Para.Para32[0]));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_STOP Event EMPTY.\n"))
++                      ("SK_RLMT_STOP Event EMPTY.\n"));
+               return;
+       }
+       if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_STOP Event EMPTY.\n"))
++                      ("SK_RLMT_STOP Event EMPTY.\n"));
+               return;
+       }
+       if (pAC->Rlmt.NetsStarted == 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("All nets are stopped.\n"))
++                      ("All nets are stopped.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_STOP Event EMPTY.\n"))
++                      ("SK_RLMT_STOP Event EMPTY.\n"));
+               return;
+       }
+@@ -2529,7 +2535,7 @@
+       pAC->Rlmt.NetsStarted--;
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_STOP Event END.\n"))
++              ("SK_RLMT_STOP Event END.\n"));
+ }     /* SkRlmtEvtStop */
+@@ -2559,13 +2565,13 @@
+       SK_U32                  i;
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_TIM Event BEGIN.\n"))
++              ("SK_RLMT_TIM Event BEGIN.\n"));
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad Parameter.\n"))
++                      ("Bad Parameter.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_TIM Event EMPTY.\n"))
++                      ("SK_RLMT_TIM Event EMPTY.\n"));
+               return;
+       }
+@@ -2637,7 +2643,7 @@
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_TIM Event END.\n"))
++                      ("SK_RLMT_TIM Event END.\n"));
+ }     /* SkRlmtEvtTim */
+@@ -2665,13 +2671,13 @@
+ #endif        /* DEBUG */
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_SEG_TIM Event BEGIN.\n"))
++              ("SK_RLMT_SEG_TIM Event BEGIN.\n"));
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad Parameter.\n"))
++                      ("Bad Parameter.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_SEG_TIM Event EMPTY.\n"))
++                      ("SK_RLMT_SEG_TIM Event EMPTY.\n"));
+               return;
+       }
+@@ -2695,7 +2701,7 @@
+                                       InAddr8[3], InAddr8[4], InAddr8[5],
+                                       pAPort->Exact[k].a[0], pAPort->Exact[k].a[1],
+                                       pAPort->Exact[k].a[2], pAPort->Exact[k].a[3],
+-                                      pAPort->Exact[k].a[4], pAPort->Exact[k].a[5]))
++                                      pAPort->Exact[k].a[4], pAPort->Exact[k].a[5]));
+               }
+       }
+ #endif        /* xDEBUG */
+@@ -2703,7 +2709,7 @@
+       SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]);
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_SEG_TIM Event END.\n"))
++                      ("SK_RLMT_SEG_TIM Event END.\n"));
+ }     /* SkRlmtEvtSegTim */
+@@ -2732,18 +2738,18 @@
+       
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n"))
++              ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n"));
+       /* Should we ignore frames during port switching? */
+ #ifdef DEBUG
+       pMb = Para.pParaPtr;
+       if (pMb == NULL) {
+-              SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n"))
++              SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n"));
+       }
+       else if (pMb->pNext != NULL) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("More than one mbuf or pMb->pNext not set.\n"))
++                      ("More than one mbuf or pMb->pNext not set.\n"));
+       }
+ #endif        /* DEBUG */
+@@ -2761,7 +2767,7 @@
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_PACKET_RECEIVED Event END.\n"))
++              ("SK_RLMT_PACKET_RECEIVED Event END.\n"));
+ }     /* SkRlmtEvtPacketRx */
+@@ -2788,21 +2794,21 @@
+       SK_RLMT_PORT    *pRPort;
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_STATS_CLEAR Event BEGIN.\n"))
++              ("SK_RLMT_STATS_CLEAR Event BEGIN.\n"));
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad Parameter.\n"))
++                      ("Bad Parameter.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
++                      ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"));
+               return;
+       }
+       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad NetNumber %d.\n", Para.Para32[0]))
++                      ("Bad NetNumber %d.\n", Para.Para32[0]));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
++                      ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"));
+               return;
+       }
+@@ -2817,7 +2823,7 @@
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_STATS_CLEAR Event END.\n"))
++              ("SK_RLMT_STATS_CLEAR Event END.\n"));
+ }     /* SkRlmtEvtStatsClear */
+@@ -2841,28 +2847,28 @@
+ SK_EVPARA     Para)   /* SK_U32 NetNumber; SK_U32 -1 */
+ {
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_STATS_UPDATE Event BEGIN.\n"))
++              ("SK_RLMT_STATS_UPDATE Event BEGIN.\n"));
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad Parameter.\n"))
++                      ("Bad Parameter.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
++                      ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"));
+               return;
+       }
+       if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad NetNumber %d.\n", Para.Para32[0]))
++                      ("Bad NetNumber %d.\n", Para.Para32[0]));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
++                      ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"));
+               return;
+       }
+       /* Update statistics - currently always up-to-date. */
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_STATS_UPDATE Event END.\n"))
++              ("SK_RLMT_STATS_UPDATE Event END.\n"));
+ }     /* SkRlmtEvtStatsUpdate */
+@@ -2886,13 +2892,13 @@
+ SK_EVPARA     Para)   /* SK_U32 PortIndex; SK_U32 NetNumber */
+ {
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0]))
++              ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0]));
+       if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad NetNumber %d.\n", Para.Para32[1]))
++                      ("Bad NetNumber %d.\n", Para.Para32[1]));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
++                      ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"));
+               return;
+       }
+@@ -2905,7 +2911,7 @@
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG);
+                       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                              ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
++                              ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"));
+                       return;
+               }
+@@ -2919,7 +2925,7 @@
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_PREFPORT_CHANGE Event END.\n"))
++              ("SK_RLMT_PREFPORT_CHANGE Event END.\n"));
+ }     /* SkRlmtEvtPrefportChange */
+@@ -2945,37 +2951,37 @@
+       int i;
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_SET_NETS Event BEGIN.\n"))
++              ("SK_RLMT_SET_NETS Event BEGIN.\n"));
+       if (Para.Para32[1] != (SK_U32)-1) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad Parameter.\n"))
++                      ("Bad Parameter.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_SET_NETS Event EMPTY.\n"))
++                      ("SK_RLMT_SET_NETS Event EMPTY.\n"));
+               return;
+       }
+       if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS ||
+               Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad number of nets: %d.\n", Para.Para32[0]))
++                      ("Bad number of nets: %d.\n", Para.Para32[0]));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_SET_NETS Event EMPTY.\n"))
++                      ("SK_RLMT_SET_NETS Event EMPTY.\n"));
+               return;
+       }
+       if (Para.Para32[0] == pAC->Rlmt.NumNets) {      /* No change. */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_SET_NETS Event EMPTY.\n"))
++                      ("SK_RLMT_SET_NETS Event EMPTY.\n"));
+               return;
+       }
+       /* Entering and leaving dual mode only allowed while nets are stopped. */
+       if (pAC->Rlmt.NetsStarted > 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Changing dual mode only allowed while all nets are stopped.\n"))
++                      ("Changing dual mode only allowed while all nets are stopped.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_SET_NETS Event EMPTY.\n"))
++                      ("SK_RLMT_SET_NETS Event EMPTY.\n"));
+               return;
+       }
+@@ -3006,9 +3012,10 @@
+               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("RLMT: Changed to one net with two ports.\n"))
++                      ("RLMT: Changed to one net with two ports.\n"));
+       }
+       else if (Para.Para32[0] == 2) {
++              pAC->Rlmt.RlmtOff = SK_TRUE;
+               pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1];
+               pAC->Rlmt.Net[1].NumPorts = pAC->GIni.GIMacsFound - 1;
+               pAC->Rlmt.Net[0].NumPorts =
+@@ -3035,19 +3042,19 @@
+               SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("RLMT: Changed to two nets with one port each.\n"))
++                      ("RLMT: Changed to two nets with one port each.\n"));
+       }
+       else {
+               /* Not implemented for more than two nets. */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SetNets not implemented for more than two nets.\n"))
++                      ("SetNets not implemented for more than two nets.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_SET_NETS Event EMPTY.\n"))
++                      ("SK_RLMT_SET_NETS Event EMPTY.\n"));
+               return;
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_SET_NETS Event END.\n"))
++              ("SK_RLMT_SET_NETS Event END.\n"));
+ }     /* SkRlmtSetNets */
+@@ -3075,13 +3082,13 @@
+       SK_U32          PrevRlmtMode;
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-              ("SK_RLMT_MODE_CHANGE Event BEGIN.\n"))
++              ("SK_RLMT_MODE_CHANGE Event BEGIN.\n"));
+       if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Bad NetNumber %d.\n", Para.Para32[1]))
++                      ("Bad NetNumber %d.\n", Para.Para32[1]));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
++                      ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"));
+               return;
+       }
+@@ -3091,9 +3098,9 @@
+               Para.Para32[0] != SK_RLMT_MODE_CLS) {
+               pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS;
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Forced RLMT mode to CLS on single port net.\n"))
++                      ("Forced RLMT mode to CLS on single port net.\n"));
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
++                      ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"));
+               return;
+       }
+@@ -3159,7 +3166,7 @@
+       }       /* SK_RLMT_CHECK_SEG bit changed. */
+       SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("SK_RLMT_MODE_CHANGE Event END.\n"))
++                      ("SK_RLMT_MODE_CHANGE Event END.\n"));
+ }     /* SkRlmtEvtModeChange */
+@@ -3245,7 +3252,7 @@
+       default:        /* Create error log entry. */
+               SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
+-                      ("Unknown RLMT Event %d.\n", Event))
++                      ("Unknown RLMT Event %d.\n", Event));
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG);
+               break;
+       }       /* switch() */
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/sktimer.c linux-2.6.9.new/drivers/net/sk98lin/sktimer.c
+--- linux-2.6.9.old/drivers/net/sk98lin/sktimer.c      2004-10-19 05:53:13.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/sktimer.c      2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      sktimer.c
+  * Project:   Gigabit Ethernet Adapters, Event Scheduler Module
+- * Version:   $Revision: 1.14 $
+- * Date:      $Date: 2003/09/16 13:46:51 $
++ * Version:   $Revision: 2.2 $
++ * Date:      $Date: 2004/05/28 13:44:39 $
+  * Purpose:   High level timer functions.
+  *
+  ******************************************************************************/
+@@ -11,7 +11,7 @@
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect GmbH.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2004 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+@@ -22,13 +22,12 @@
+  *
+  ******************************************************************************/
+-
+ /*
+  *    Event queue and dispatcher
+  */
+ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: sktimer.c,v 1.14 2003/09/16 13:46:51 rschmidt Exp $ (C) Marvell.";
++      "@(#) $Id: sktimer.c,v 2.2 2004/05/28 13:44:39 rschmidt Exp $ (C) Marvell.";
+ #endif
+ #include "h/skdrv1st.h"               /* Driver Specific Definitions */
+@@ -62,7 +61,7 @@
+ {
+       switch (Level) {
+       case SK_INIT_DATA:
+-              pAC->Tim.StQueue = NULL;
++              pAC->Tim.StQueue = 0;
+               break;
+       case SK_INIT_IO:
+               SkHwtInit(pAC, Ioc);
+@@ -85,22 +84,20 @@
+       SK_TIMER        **ppTimPrev;
+       SK_TIMER        *pTm;
+-      /*
+-       * remove timer from queue
+-       */
++      /* remove timer from queue */
+       pTimer->TmActive = SK_FALSE;
+-      
++
+       if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) {
+               SkHwtStop(pAC, Ioc);
+       }
+-      
++
+       for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
+               ppTimPrev = &pTm->TmNext ) {
+-              
++
+               if (pTm == pTimer) {
+                       /*
+                        * Timer found in queue
+-                       * - dequeue it and
++                       * - dequeue it
+                        * - correct delta of the next timer
+                        */
+                       *ppTimPrev = pTm->TmNext;
+@@ -121,7 +118,7 @@
+ SK_AC         *pAC,           /* Adapters context */
+ SK_IOC                Ioc,            /* IoContext */
+ SK_TIMER      *pTimer,        /* Timer Pointer to be started */
+-SK_U32                Time,           /* Time value */
++SK_U32                Time,           /* Time Value (in microsec.) */
+ SK_U32                Class,          /* Event Class for this timer */
+ SK_U32                Event,          /* Event Value for this timer */
+ SK_EVPARA     Para)           /* Event Parameter for this timer */
+@@ -130,11 +127,6 @@
+       SK_TIMER        *pTm;
+       SK_U32          Delta;
+-      Time /= 16;             /* input is uS, clock ticks are 16uS */
+-      
+-      if (!Time)
+-              Time = 1;
+-
+       SkTimerStop(pAC, Ioc, pTimer);
+       pTimer->TmClass = Class;
+@@ -143,31 +135,26 @@
+       pTimer->TmActive = SK_TRUE;
+       if (!pAC->Tim.StQueue) {
+-              /* First Timer to be started */
++              /* first Timer to be started */
+               pAC->Tim.StQueue = pTimer;
+-              pTimer->TmNext = NULL;
++              pTimer->TmNext = 0;
+               pTimer->TmDelta = Time;
+-              
++
+               SkHwtStart(pAC, Ioc, Time);
+-              
++
+               return;
+       }
+-      /*
+-       * timer correction
+-       */
++      /* timer correction */
+       timer_done(pAC, Ioc, 0);
+-      /*
+-       * find position in queue
+-       */
++      /* find position in queue */
+       Delta = 0;
+       for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
+               ppTimPrev = &pTm->TmNext ) {
+-              
++
+               if (Delta + pTm->TmDelta > Time) {
+-                      /* Position found */
+-                      /* Here the timer needs to be inserted. */
++                      /* the timer needs to be inserted here */
+                       break;
+               }
+               Delta += pTm->TmDelta;
+@@ -179,9 +166,7 @@
+       pTimer->TmDelta = Time - Delta;
+       if (pTm) {
+-              /* There is a next timer
+-               * -> correct its Delta value.
+-               */
++              /* there is a next timer:  correct its Delta value */
+               pTm->TmDelta -= pTimer->TmDelta;
+       }
+@@ -210,7 +195,7 @@
+       int             Done = 0;
+       Delta = SkHwtRead(pAC, Ioc);
+-      
++
+       ppLast = &pAC->Tim.StQueue;
+       pTm = pAC->Tim.StQueue;
+       while (pTm && !Done) {
+@@ -228,13 +213,13 @@
+                       Done = 1;
+               }
+       }
+-      *ppLast = NULL;
++      *ppLast = 0;
+       /*
+        * pTm points to the first Timer that did not run out.
+        * StQueue points to the first Timer that run out.
+        */
+-      for ( pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) {
++      for (pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) {
+               SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, pTComp->TmPara);
+       }
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/sktwsi.c linux-2.6.9.new/drivers/net/sk98lin/sktwsi.c
+--- linux-2.6.9.old/drivers/net/sk98lin/sktwsi.c       1970-01-01 08:00:00.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/sktwsi.c       2006-12-07 14:35:03.000000000 +0800
+@@ -0,0 +1,1355 @@
++/******************************************************************************
++ *
++ * Name:      sktwsi.c
++ * Project:   Gigabit Ethernet Adapters, TWSI-Module
++ * Version:   $Revision: 1.9 $
++ * Date:      $Date: 2004/12/20 15:10:30 $
++ * Purpose:   Functions to access Voltage and Temperature Sensor
++ *
++ ******************************************************************************/
++
++/******************************************************************************
++ *
++ *    (C)Copyright 1998-2002 SysKonnect.
++ *    (C)Copyright 2002-2004 Marvell.
++ *
++ *    This program is free software; you can redistribute it and/or modify
++ *    it under the terms of the GNU General Public License as published by
++ *    the Free Software Foundation; either version 2 of the License, or
++ *    (at your option) any later version.
++ *    The information in this file is provided "AS IS" without warranty.
++ *
++ ******************************************************************************/
++
++/*
++ *    TWSI Protocol
++ */
++#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
++static const char SysKonnectFileId[] =
++      "@(#) $Id: sktwsi.c,v 1.9 2004/12/20 15:10:30 rschmidt Exp $ (C) Marvell.";
++#endif
++
++#include "h/skdrv1st.h"               /* Driver Specific Definitions */
++#include "h/lm80.h"
++#include "h/skdrv2nd.h"               /* Adapter Control- and Driver specific Def. */
++
++#ifdef __C2MAN__
++/*
++      TWSI protocol implementation.
++
++      General Description:
++
++      The TWSI protocol is used for the temperature sensors and for
++      the serial EEPROM which hold the configuration.
++
++      This file covers functions that allow to read write and do
++      some bulk requests a specified TWSI address.
++
++      The Genesis has 2 TWSI buses. One for the EEPROM which holds
++      the VPD Data and one for temperature and voltage sensor.
++      The following picture shows the TWSI buses, TWSI devices and
++      their control registers.
++
++      Note: The VPD functions are in skvpd.c
++.
++.     PCI Config TWSI Bus for VPD Data:
++.
++.                   +------------+
++.                   | VPD EEPROM |
++.                   +------------+
++.                          |
++.                          | <-- TWSI
++.                          |
++.              +-----------+-----------+
++.              |                       |
++.     +-----------------+     +-----------------+
++.     | PCI_VPD_ADR_REG |     | PCI_VPD_DAT_REG |
++.     +-----------------+     +-----------------+
++.
++.
++.     TWSI Bus for LM80 sensor:
++.
++.                     +-----------------+
++.                     | Temperature and |
++.                     | Voltage Sensor  |
++.                     |       LM80      |
++.                     +-----------------+
++.                             |
++.                             |
++.                     TWSI --> |
++.                             |
++.                          +----+
++.          +-------------->| OR |<--+
++.          |               +----+   |
++.     +------+------+               |
++.     |                   |                 |
++. +--------+  +--------+      +----------+
++. | B2_I2C |  | B2_I2C |      |  B2_I2C  |
++. | _CTRL  |  | _DATA  |      |   _SW    |
++. +--------+  +--------+      +----------+
++.
++      The TWSI bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
++      and B2_I2C_DATA registers.
++      For driver software it is recommended to use the TWSI control and
++      data register, because TWSI bus timing is done by the ASIC and
++      an interrupt may be received when the TWSI request is completed.
++
++      Clock Rate Timing:                      MIN     MAX     generated by
++              VPD EEPROM:                     50 kHz  100 kHz         HW
++              LM80 over TWSI Ctrl/Data reg.   50 kHz  100 kHz         HW
++              LM80 over B2_I2C_SW register    0       400 kHz         SW
++
++      Note:   The clock generated by the hardware is dependend on the
++              PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
++              clock is 50 kHz.
++ */
++intro()
++{}
++#endif
++
++#ifdef SK_DIAG
++/*
++ * TWSI Fast Mode timing values used by the LM80.
++ * If new devices are added to the TWSI bus the timing values have to be checked.
++ */
++#ifndef I2C_SLOW_TIMING
++#define T_CLK_LOW                     1300L   /* clock low time in ns */
++#define T_CLK_HIGH                     600L   /* clock high time in ns */
++#define T_DATA_IN_SETUP                100L   /* data in Set-up Time */
++#define T_START_HOLD           600L   /* start condition hold time */
++#define T_START_SETUP          600L   /* start condition Set-up time */
++#define T_STOP_SETUP           600L   /* stop condition Set-up time */
++#define T_BUS_IDLE                    1300L   /* time the bus must free after Tx */
++#define T_CLK_2_DATA_OUT       900L   /* max. clock low to data output valid */
++#else /* I2C_SLOW_TIMING */
++/* TWSI Standard Mode Timing */
++#define T_CLK_LOW                     4700L   /* clock low time in ns */
++#define T_CLK_HIGH                    4000L   /* clock high time in ns */
++#define T_DATA_IN_SETUP                250L   /* data in Set-up Time */
++#define T_START_HOLD          4000L   /* start condition hold time */
++#define T_START_SETUP         4700L   /* start condition Set-up time */
++#define T_STOP_SETUP          4000L   /* stop condition Set-up time */
++#define T_BUS_IDLE                    4700L   /* time the bus must free after Tx */
++#endif        /* !I2C_SLOW_TIMING */
++
++#define NS2BCLK(x)    (((x)*125)/10000)
++
++/*
++ * TWSI Wire Operations
++ *
++ * About I2C_CLK_LOW():
++ *
++ * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
++ * clock to low, to prevent the ASIC and the TWSI data client from driving the
++ * serial data line simultaneously (ASIC: last bit of a byte = '1', TWSI client
++ * send an 'ACK'). See also Concentrator Bugreport No. 10192.
++ */
++#define I2C_DATA_HIGH(IoC)    SK_I2C_SET_BIT(IoC, I2C_DATA)
++#define I2C_DATA_LOW(IoC)     SK_I2C_CLR_BIT(IoC, I2C_DATA)
++#define I2C_DATA_OUT(IoC)     SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
++#define I2C_DATA_IN(IoC)      SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
++#define I2C_CLK_HIGH(IoC)     SK_I2C_SET_BIT(IoC, I2C_CLK)
++#define I2C_CLK_LOW(IoC)      SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
++#define I2C_START_COND(IoC)   SK_I2C_CLR_BIT(IoC, I2C_CLK)
++
++#define NS2CLKT(x)    ((x*125L)/10000)
++
++/*--------------- TWSI Interface Register Functions --------------- */
++
++/*
++ * sending one bit
++ */
++void SkI2cSndBit(
++SK_IOC        IoC,    /* I/O Context */
++SK_U8 Bit)    /* Bit to send */
++{
++      I2C_DATA_OUT(IoC);
++      if (Bit) {
++              I2C_DATA_HIGH(IoC);
++      }
++      else {
++              I2C_DATA_LOW(IoC);
++      }
++      SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
++      I2C_CLK_HIGH(IoC);
++      SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
++      I2C_CLK_LOW(IoC);
++}     /* SkI2cSndBit*/
++
++
++/*
++ * Signal a start to the TWSI Bus.
++ *
++ * A start is signaled when data goes to low in a high clock cycle.
++ *
++ * Ends with Clock Low.
++ *
++ * Status: not tested
++ */
++void SkI2cStart(
++SK_IOC        IoC)    /* I/O Context */
++{
++      /* Init data and Clock to output lines */
++      /* Set Data high */
++      I2C_DATA_OUT(IoC);
++      I2C_DATA_HIGH(IoC);
++      /* Set Clock high */
++      I2C_CLK_HIGH(IoC);
++
++      SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
++
++      /* Set Data Low */
++      I2C_DATA_LOW(IoC);
++
++      SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
++
++      /* Clock low without Data to Input */
++      I2C_START_COND(IoC);
++
++      SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
++}     /* SkI2cStart */
++
++
++void SkI2cStop(
++SK_IOC        IoC)    /* I/O Context */
++{
++      /* Init data and Clock to output lines */
++      /* Set Data low */
++      I2C_DATA_OUT(IoC);
++      I2C_DATA_LOW(IoC);
++
++      SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
++
++      /* Set Clock high */
++      I2C_CLK_HIGH(IoC);
++
++      SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
++
++      /*
++       * Set Data High:       Do it by setting the Data Line to Input.
++       *                      Because of a pull up resistor the Data Line
++       *                      floods to high.
++       */
++      I2C_DATA_IN(IoC);
++
++      /*
++       *      When TWSI activity is stopped
++       *       o      DATA should be set to input and
++       *       o      CLOCK should be set to high!
++       */
++      SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
++}     /* SkI2cStop */
++
++
++/*
++ * Receive just one bit via the TWSI bus.
++ *
++ * Note:      Clock must be set to LOW before calling this function.
++ *
++ * Returns The received bit.
++ */
++int SkI2cRcvBit(
++SK_IOC        IoC)    /* I/O Context */
++{
++      int     Bit;
++      SK_U8   I2cSwCtrl;
++
++      /* Init data as input line */
++      I2C_DATA_IN(IoC);
++
++      SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
++
++      I2C_CLK_HIGH(IoC);
++
++      SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
++
++      SK_I2C_GET_SW(IoC, &I2cSwCtrl);
++
++      Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
++
++      I2C_CLK_LOW(IoC);
++      SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
++
++      return(Bit);
++}     /* SkI2cRcvBit */
++
++
++/*
++ * Receive an ACK.
++ *
++ * returns    0 If acknowledged
++ *            1 in case of an error
++ */
++int SkI2cRcvAck(
++SK_IOC        IoC)    /* I/O Context */
++{
++      /*
++       * Received bit must be zero.
++       */
++      return(SkI2cRcvBit(IoC) != 0);
++}     /* SkI2cRcvAck */
++
++
++/*
++ * Send an NACK.
++ */
++void SkI2cSndNAck(
++SK_IOC        IoC)    /* I/O Context */
++{
++      /*
++       * Received bit must be zero.
++       */
++      SkI2cSndBit(IoC, 1);
++}     /* SkI2cSndNAck */
++
++
++/*
++ * Send an ACK.
++ */
++void SkI2cSndAck(
++SK_IOC IoC)   /* I/O Context */
++{
++      /*
++       * Received bit must be zero.
++       */
++      SkI2cSndBit(IoC, 0);
++}     /* SkI2cSndAck */
++
++
++/*
++ * Send one byte to the TWSI device and wait for ACK.
++ *
++ * Return acknowleged status.
++ */
++int SkI2cSndByte(
++SK_IOC        IoC,    /* I/O Context */
++int           Byte)   /* byte to send */
++{
++      int     i;
++
++      for (i = 0; i < 8; i++) {
++              if (Byte & (1<<(7-i))) {
++                      SkI2cSndBit(IoC, 1);
++              }
++              else {
++                      SkI2cSndBit(IoC, 0);
++              }
++      }
++
++      return(SkI2cRcvAck(IoC));
++}     /* SkI2cSndByte */
++
++
++/*
++ * Receive one byte and ack it.
++ *
++ * Return byte.
++ */
++int SkI2cRcvByte(
++SK_IOC        IoC,    /* I/O Context */
++int           Last)   /* Last Byte Flag */
++{
++      int     i;
++      int     Byte = 0;
++
++      for (i = 0; i < 8; i++) {
++              Byte <<= 1;
++              Byte |= SkI2cRcvBit(IoC);
++      }
++
++      if (Last) {
++              SkI2cSndNAck(IoC);
++      }
++      else {
++              SkI2cSndAck(IoC);
++      }
++
++      return(Byte);
++}     /* SkI2cRcvByte */
++
++
++/*
++ * Start dialog and send device address
++ *
++ * Return 0 if acknowleged, 1 in case of an error
++ */
++int   SkI2cSndDev(
++SK_IOC        IoC,    /* I/O Context */
++int           Addr,   /* Device Address */
++int           Rw)             /* Read / Write Flag */
++{
++      SkI2cStart(IoC);
++      Rw = ~Rw;
++      Rw &= I2C_WRITE;
++      return(SkI2cSndByte(IoC, (Addr << 1) | Rw));
++}     /* SkI2cSndDev */
++
++#endif /* SK_DIAG */
++
++/*----------------- TWSI CTRL Register Functions ----------*/
++
++/*
++ * waits for a completion of an TWSI transfer
++ *
++ * returns    0:      success, transfer completes
++ *                    1:      error,   transfer does not complete, TWSI transfer
++ *                                             killed, wait loop terminated.
++ */
++int   SkI2cWait(
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
++int           Event)  /* complete event to wait for (I2C_READ or I2C_WRITE) */
++{
++      SK_U64  StartTime;
++      SK_U64  CurrentTime;
++      SK_U32  I2cCtrl;
++
++      StartTime = SkOsGetTime(pAC);
++
++      do {
++              CurrentTime = SkOsGetTime(pAC);
++
++              if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
++
++                      SK_I2C_STOP(IoC);
++#ifndef SK_DIAG
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
++#endif /* !SK_DIAG */
++                      return(1);
++              }
++
++              SK_I2C_GET_CTL(IoC, &I2cCtrl);
++
++#ifdef xYUKON_DBG
++              printf("StartTime=%lu, CurrentTime=%lu\n",
++                      StartTime, CurrentTime);
++              if (kbhit()) {
++                      return(1);
++              }
++#endif /* YUKON_DBG */
++
++      } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
++
++      return(0);
++}     /* SkI2cWait */
++
++
++/*
++ * waits for a completion of an TWSI transfer
++ *
++ * Returns
++ *    Nothing
++ */
++void SkI2cWaitIrq(
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC)    /* I/O Context */
++{
++      SK_SENSOR       *pSen;
++      SK_U64          StartTime;
++      SK_U32          IrqSrc;
++      SK_U32          IsTwsiReadyBit;
++
++      IsTwsiReadyBit = CHIP_ID_YUKON_2(pAC) ? Y2_IS_TWSI_RDY : IS_I2C_READY;
++
++      pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
++
++      if (pSen->SenState == SK_SEN_IDLE) {
++              return;
++      }
++
++      StartTime = SkOsGetTime(pAC);
++
++      do {
++              if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
++
++                      SK_I2C_STOP(IoC);
++#ifndef SK_DIAG
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
++#endif /* !SK_DIAG */
++                      return;
++              }
++
++              SK_IN32(IoC, B0_ISRC, &IrqSrc);
++
++      } while ((IrqSrc & IsTwsiReadyBit) == 0);
++
++      pSen->SenState = SK_SEN_IDLE;
++      return;
++}     /* SkI2cWaitIrq */
++
++/*
++ * writes a single byte or 4 bytes into the TWSI device
++ *
++ * returns    0:      success
++ *                    1:      error
++ */
++int SkI2cWrite(
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
++SK_U32        I2cData,        /* TWSI Data to write */
++int           I2cDev,         /* TWSI Device Address */
++int           I2cDevSize,     /* TWSI Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
++int           I2cReg,         /* TWSI Device Register Address */
++int           I2cBurst)       /* TWSI Burst Flag */
++{
++      SK_OUT32(IoC, B2_I2C_DATA, I2cData);
++
++      SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst);
++
++      return(SkI2cWait(pAC, IoC, I2C_WRITE));
++}     /* SkI2cWrite*/
++
++
++#ifdef        SK_DIAG
++/*
++ * reads a single byte or 4 bytes from the TWSI device
++ *
++ * returns    the word read
++ */
++SK_U32 SkI2cRead(
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
++int           I2cDev,         /* TWSI Device Address */
++int           I2cDevSize,     /* TWSI Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
++int           I2cReg,         /* TWSI Device Register Address */
++int           I2cBurst)       /* TWSI Burst Flag */
++{
++      SK_U32  Data;
++
++      SK_OUT32(IoC, B2_I2C_DATA, 0);
++      SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst);
++
++      if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
++              w_print("%s\n", SKERR_I2C_E002MSG);
++      }
++
++      SK_IN32(IoC, B2_I2C_DATA, &Data);
++
++      return(Data);
++}     /* SkI2cRead */
++#endif /* SK_DIAG */
++
++
++/*
++ * read a sensor's value
++ *
++ * This function reads a sensor's value from the TWSI sensor chip. The sensor
++ * is defined by its index into the sensors database in the struct pAC points
++ * to.
++ * Returns
++ *            1 if the read is completed
++ *            0 if the read must be continued (TWSI Bus still allocated)
++ */
++int   SkI2cReadSensor(
++SK_AC         *pAC,   /* Adapter Context */
++SK_IOC                IoC,    /* I/O Context */
++SK_SENSOR     *pSen)  /* Sensor to be read */
++{
++      if (pSen->SenRead != NULL) {
++              return((*pSen->SenRead)(pAC, IoC, pSen));
++      }
++
++      return(0); /* no success */
++}     /* SkI2cReadSensor */
++
++/*
++ * Do the Init state 0 initialization
++ */
++static int SkI2cInit0(
++SK_AC *pAC)   /* Adapter Context */
++{
++      int                     i;
++      SK_SENSOR       *pSen;
++
++      /* Begin with first sensor */
++      pAC->I2c.CurrSens = 0;
++
++      /* Begin with timeout control for state machine */
++      pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
++
++      /* Set sensor number to zero */
++      pAC->I2c.MaxSens = 0;
++
++#ifndef SK_DIAG
++      /* Initialize Number of Dummy Reads */
++      pAC->I2c.DummyReads = SK_MAX_SENSORS;
++#endif /* !SK_DIAG */
++
++      for (i = 0; i < SK_MAX_SENSORS; i++) {
++              pSen = &pAC->I2c.SenTable[i];
++
++              pSen->SenDesc = "unknown";
++              pSen->SenType = SK_SEN_UNKNOWN;
++              pSen->SenThreErrHigh = 0;
++              pSen->SenThreErrLow = 0;
++              pSen->SenThreWarnHigh = 0;
++              pSen->SenThreWarnLow = 0;
++              pSen->SenReg = LM80_FAN2_IN;
++              pSen->SenInit = SK_SEN_DYN_INIT_NONE;
++              pSen->SenValue = 0;
++              pSen->SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
++              pSen->SenErrCts = 0;
++              pSen->SenBegErrTS = 0;
++              pSen->SenState = SK_SEN_IDLE;
++              pSen->SenRead = NULL;
++              pSen->SenDev = 0;
++      }
++
++      /* Now we are "INIT data"ed */
++      pAC->I2c.InitLevel = SK_INIT_DATA;
++      return(0);
++}     /* SkI2cInit0*/
++
++
++/*
++ * Do the init state 1 initialization
++ *
++ * initialize the following register of the LM80:
++ * Configuration register:
++ * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
++ *
++ * Interrupt Mask Register 1:
++ * - all interrupts are Disabled (0xff)
++ *
++ * Interrupt Mask Register 2:
++ * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
++ *
++ * Fan Divisor/RST_OUT register:
++ * - Divisors set to 1 (bits 00), all others 0s.
++ *
++ * OS# Configuration/Temperature resolution Register:
++ * - all 0s
++ *
++ */
++static int SkI2cInit1(
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC)    /* I/O Context */
++{
++      int                     i;
++      SK_U8           I2cSwCtrl;
++      SK_GEPORT       *pPrt;  /* GIni Port struct pointer */
++      SK_SENSOR       *pSen;
++
++      if (pAC->I2c.InitLevel != SK_INIT_DATA) {
++              /* Re-init not needed in TWSI module */
++              return(0);
++      }
++
++      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC ||
++              pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
++              /* No sensors on Yukon-EC and Yukon-FE */
++              return(0);
++      }
++
++      /* Set the Direction of TWSI-Data Pin to IN */
++      SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
++      /* Check for 32-Bit Yukon with Low at TWSI-Data Pin */
++      SK_I2C_GET_SW(IoC, &I2cSwCtrl);
++
++      if ((I2cSwCtrl & I2C_DATA) == 0) {
++              /* this is a 32-Bit board */
++              pAC->GIni.GIYukon32Bit = SK_TRUE;
++              return(0);
++      }
++
++      /* Check for 64 Bit Yukon without sensors */
++      if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) {
++              return(0);
++      }
++
++      (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0);
++
++      (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0);
++
++      (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0);
++
++      (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
++
++      (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV,
++              LM80_CFG, 0);
++
++      /*
++       * MaxSens has to be updated here, because PhyType is not
++       * set when performing Init Level 0
++       */
++      pAC->I2c.MaxSens = 5;
++
++      pPrt = &pAC->GIni.GP[0];
++
++      if (pAC->GIni.GIGenesis) {
++              if (pPrt->PhyType == SK_PHY_BCOM) {
++                      if (pAC->GIni.GIMacsFound == 1) {
++                              pAC->I2c.MaxSens += 1;
++                      }
++                      else {
++                              pAC->I2c.MaxSens += 3;
++                      }
++              }
++      }
++      else {
++              pAC->I2c.MaxSens += 3;
++      }
++
++      for (i = 0; i < pAC->I2c.MaxSens; i++) {
++              pSen = &pAC->I2c.SenTable[i];
++              switch (i) {
++              case 0:
++                      pSen->SenDesc = "Temperature";
++                      pSen->SenType = SK_SEN_TEMP;
++                      pSen->SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
++                      pSen->SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
++                      pSen->SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
++                      pSen->SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
++                      pSen->SenReg = LM80_TEMP_IN;
++                      break;
++              case 1:
++                      pSen->SenDesc = "Voltage PCI";
++                      pSen->SenType = SK_SEN_VOLT;
++                      pSen->SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
++                      pSen->SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
++                      if (pAC->GIni.GIPciBus != SK_PEX_BUS) {
++                              pSen->SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
++                              pSen->SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
++                      }
++                      else {
++                              pSen->SenThreWarnLow = 0;
++                              pSen->SenThreErrLow = 0;
++                      }
++                      pSen->SenReg = LM80_VT0_IN;
++                      break;
++              case 2:
++                      pSen->SenDesc = "Voltage PCI-IO";
++                      pSen->SenType = SK_SEN_VOLT;
++                      pSen->SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
++                      pSen->SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
++                      if (pAC->GIni.GIPciBus != SK_PEX_BUS) {
++                              pSen->SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
++                              pSen->SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
++                      }
++                      else {
++                              pSen->SenThreWarnLow = 0;
++                              pSen->SenThreErrLow = 0;
++                      }
++                      pSen->SenReg = LM80_VT1_IN;
++                      pSen->SenInit = SK_SEN_DYN_INIT_PCI_IO;
++                      break;
++              case 3:
++                      if (pAC->GIni.GIGenesis) {
++                              pSen->SenDesc = "Voltage ASIC";
++                      }
++                      else {
++                              pSen->SenDesc = "Voltage VMAIN";
++                      }
++                      pSen->SenType = SK_SEN_VOLT;
++                      pSen->SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
++                      pSen->SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
++                      pSen->SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
++                      pSen->SenThreErrLow = SK_SEN_VDD_LOW_ERR;
++                      pSen->SenReg = LM80_VT2_IN;
++                      break;
++              case 4:
++                      if (pAC->GIni.GIGenesis) {
++                              if (pPrt->PhyType == SK_PHY_BCOM) {
++                                      pSen->SenDesc = "Voltage PHY A PLL";
++                                      pSen->SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
++                                      pSen->SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
++                                      pSen->SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
++                                      pSen->SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
++                              }
++                              else {
++                                      pSen->SenDesc = "Voltage PMA";
++                                      pSen->SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
++                                      pSen->SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
++                                      pSen->SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
++                                      pSen->SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
++                              }
++                      }
++                      else {
++                              pSen->SenDesc = "Voltage VAUX";
++                              pSen->SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
++                              pSen->SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
++                              if (pAC->GIni.GIVauxAvail) {
++                                      pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
++                                      pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
++                              }
++                              else {
++                                      pSen->SenThreErrLow = 0;
++                                      pSen->SenThreWarnLow = 0;
++                              }
++                      }
++                      pSen->SenType = SK_SEN_VOLT;
++                      pSen->SenReg = LM80_VT3_IN;
++                      break;
++              case 5:
++                      if (CHIP_ID_YUKON_2(pAC)) {
++                              if (pAC->GIni.GIChipRev == 0) {
++                                      pSen->SenDesc = "Voltage Core 1V3";
++                                      pSen->SenThreErrHigh = SK_SEN_CORE_1V3_HIGH_ERR;
++                                      pSen->SenThreWarnHigh = SK_SEN_CORE_1V3_HIGH_WARN;
++                                      pSen->SenThreWarnLow = SK_SEN_CORE_1V3_LOW_WARN;
++                                      pSen->SenThreErrLow = SK_SEN_CORE_1V3_LOW_ERR;
++                              }
++                              else {
++                                      pSen->SenDesc = "Voltage Core 1V2";
++                                      pSen->SenThreErrHigh = SK_SEN_CORE_1V2_HIGH_ERR;
++                                      pSen->SenThreWarnHigh = SK_SEN_CORE_1V2_HIGH_WARN;
++                                      pSen->SenThreWarnLow = SK_SEN_CORE_1V2_LOW_WARN;
++                                      pSen->SenThreErrLow = SK_SEN_CORE_1V2_LOW_ERR;
++                              }
++                      }
++                      else {
++                              if (pAC->GIni.GIGenesis) {
++                                      pSen->SenDesc = "Voltage PHY 2V5";
++                                      pSen->SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
++                                      pSen->SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
++                                      pSen->SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
++                                      pSen->SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
++                              }
++                              else {
++                                      pSen->SenDesc = "Voltage Core 1V5";
++                                      pSen->SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
++                                      pSen->SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
++                                      pSen->SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
++                                      pSen->SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
++                              }
++                      }
++                      pSen->SenType = SK_SEN_VOLT;
++                      pSen->SenReg = LM80_VT4_IN;
++                      break;
++              case 6:
++                      if (CHIP_ID_YUKON_2(pAC)) {
++                              pSen->SenDesc = "Voltage PHY 1V5";
++                              pSen->SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
++                              pSen->SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
++                              if (pAC->GIni.GIPciBus == SK_PEX_BUS) {
++                                      pSen->SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
++                                      pSen->SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
++                              }
++                              else {
++                                      pSen->SenThreWarnLow = 0;
++                                      pSen->SenThreErrLow = 0;
++                              }
++                      }
++                      else {
++                              if (pAC->GIni.GIGenesis) {
++                                      pSen->SenDesc = "Voltage PHY B PLL";
++                              }
++                              else {
++                                      pSen->SenDesc = "Voltage PHY 3V3";
++                              }
++                              pSen->SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
++                              pSen->SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
++                              pSen->SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
++                              pSen->SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
++                      }
++                      pSen->SenType = SK_SEN_VOLT;
++                      pSen->SenReg = LM80_VT5_IN;
++                      break;
++              case 7:
++                      if (pAC->GIni.GIGenesis) {
++                              pSen->SenDesc = "Speed Fan";
++                              pSen->SenType = SK_SEN_FAN;
++                              pSen->SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
++                              pSen->SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
++                              pSen->SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
++                              pSen->SenThreErrLow = SK_SEN_FAN_LOW_ERR;
++                              pSen->SenReg = LM80_FAN2_IN;
++                      }
++                      else {
++                              pSen->SenDesc = "Voltage PHY 2V5";
++                              pSen->SenType = SK_SEN_VOLT;
++                              pSen->SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
++                              pSen->SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
++                              pSen->SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
++                              pSen->SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
++                              pSen->SenReg = LM80_VT6_IN;
++                      }
++                      break;
++              default:
++                      SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
++                              SKERR_I2C_E001, SKERR_I2C_E001MSG);
++                      break;
++              }
++
++              pSen->SenValue = 0;
++              pSen->SenErrFlag = SK_SEN_ERR_OK;
++              pSen->SenErrCts = 0;
++              pSen->SenBegErrTS = 0;
++              pSen->SenState = SK_SEN_IDLE;
++              if (pSen->SenThreWarnLow != 0) {
++                      pSen->SenRead = SkLm80ReadSensor;
++              }
++              pSen->SenDev = LM80_ADDR;
++      }
++
++#ifndef SK_DIAG
++      pAC->I2c.DummyReads = pAC->I2c.MaxSens;
++#endif /* !SK_DIAG */
++
++      /* Clear TWSI IRQ */
++      SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
++
++      /* Now we are I/O initialized */
++      pAC->I2c.InitLevel = SK_INIT_IO;
++      return(0);
++}     /* SkI2cInit1 */
++
++
++/*
++ * Init level 2: Start first sensor read.
++ */
++static int SkI2cInit2(
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC)    /* I/O Context */
++{
++      int                     ReadComplete;
++      SK_SENSOR       *pSen;
++
++      if (pAC->I2c.InitLevel != SK_INIT_IO) {
++              /* ReInit not needed in TWSI module */
++              /* Init0 and Init2 not permitted */
++              return(0);
++      }
++
++      pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
++
++      ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
++
++      if (ReadComplete) {
++              SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
++      }
++
++      /* Now we are correctly initialized */
++      pAC->I2c.InitLevel = SK_INIT_RUN;
++
++      return(0);
++}     /* SkI2cInit2*/
++
++
++/*
++ * Initialize TWSI devices
++ *
++ * Get the first voltage value and discard it.
++ * Go into temperature read mode. A default pointer is not set.
++ *
++ * The things to be done depend on the init level in the parameter list:
++ * Level 0:
++ *    Initialize only the data structures. Do NOT access hardware.
++ * Level 1:
++ *    Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
++ * Level 2:
++ *    Everything is possible. Interrupts may be used from now on.
++ *
++ * return:
++ *    0 = success
++ *    other = error.
++ */
++int   SkI2cInit(
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context needed in levels 1 and 2 */
++int           Level)  /* Init Level */
++{
++
++      switch (Level) {
++      case SK_INIT_DATA:
++              return(SkI2cInit0(pAC));
++      case SK_INIT_IO:
++              return(SkI2cInit1(pAC, IoC));
++      case SK_INIT_RUN:
++              return(SkI2cInit2(pAC, IoC));
++      default:
++              break;
++      }
++
++      return(0);
++}     /* SkI2cInit */
++
++
++#ifndef SK_DIAG
++/*
++ * Interrupt service function for the TWSI Interface
++ *
++ * Clears the Interrupt source
++ *
++ * Reads the register and check it for sending a trap.
++ *
++ * Starts the timer if necessary.
++ */
++void SkI2cIsr(
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC)    /* I/O Context */
++{
++      SK_EVPARA       Para;
++
++      /* Clear TWSI IRQ */
++      SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
++
++      Para.Para64 = 0;
++      SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
++}     /* SkI2cIsr */
++
++
++/*
++ * Check this sensors Value against the threshold and send events.
++ */
++static void SkI2cCheckSensor(
++SK_AC         *pAC,   /* Adapter Context */
++SK_SENSOR     *pSen)
++{
++      SK_EVPARA       ParaLocal;
++      SK_BOOL         TooHigh;        /* Is sensor too high? */
++      SK_BOOL         TooLow;         /* Is sensor too low? */
++      SK_U64          CurrTime;       /* Current Time */
++      SK_BOOL         DoTrapSend;     /* We need to send a trap */
++      SK_BOOL         DoErrLog;       /* We need to log the error */
++      SK_BOOL         IsError;        /* Error occured */
++
++      /* Check Dummy Reads first */
++      if (pAC->I2c.DummyReads > 0) {
++              pAC->I2c.DummyReads--;
++              return;
++      }
++
++      /* Get the current time */
++      CurrTime = SkOsGetTime(pAC);
++
++      /* Set para to the most useful setting: The current sensor. */
++      ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
++
++      /* Check the Value against the thresholds. First: Error Thresholds */
++      TooHigh = pSen->SenValue > pSen->SenThreErrHigh;
++      TooLow  = pSen->SenValue < pSen->SenThreErrLow;
++
++      IsError = SK_FALSE;
++
++      if (TooHigh || TooLow) {
++              /* Error condition is satisfied */
++              DoTrapSend = SK_TRUE;
++              DoErrLog = SK_TRUE;
++
++              /* Now error condition is satisfied */
++              IsError = SK_TRUE;
++
++              if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
++                      /* This state is the former one */
++
++                      /* So check first whether we have to send a trap */
++                      if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD > CurrTime) {
++                              /*
++                               * Do NOT send the Trap. The hold back time
++                               * has to run out first.
++                               */
++                              DoTrapSend = SK_FALSE;
++                      }
++
++                      /* Check now whether we have to log an Error */
++                      if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD > CurrTime) {
++                              /*
++                               * Do NOT log the error. The hold back time
++                               * has to run out first.
++                               */
++                              DoErrLog = SK_FALSE;
++                      }
++              }
++              else {
++                      /* We came from a different state -> Set Begin Time Stamp */
++                      pSen->SenBegErrTS = CurrTime;
++                      pSen->SenErrFlag = SK_SEN_ERR_ERR;
++              }
++
++              if (DoTrapSend) {
++                      /* Set current Time */
++                      pSen->SenLastErrTrapTS = CurrTime;
++                      pSen->SenErrCts++;
++
++                      /* Queue PNMI Event */
++                      SkEventQueue(pAC, SKGE_PNMI, TooHigh ?
++                              SK_PNMI_EVT_SEN_ERR_UPP : SK_PNMI_EVT_SEN_ERR_LOW,
++                              ParaLocal);
++              }
++
++              if (DoErrLog) {
++                      /* Set current Time */
++                      pSen->SenLastErrLogTS = CurrTime;
++
++                      if (pSen->SenType == SK_SEN_TEMP) {
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG);
++                      }
++                      else if (pSen->SenType == SK_SEN_VOLT) {
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG);
++                      }
++                      else {
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG);
++                      }
++              }
++      }
++
++      /* Check the Value against the thresholds */
++      /* 2nd: Warning thresholds */
++      TooHigh = pSen->SenValue > pSen->SenThreWarnHigh;
++      TooLow  = pSen->SenValue < pSen->SenThreWarnLow;
++
++      if (!IsError && (TooHigh || TooLow)) {
++              /* Error condition is satisfied */
++              DoTrapSend = SK_TRUE;
++              DoErrLog = SK_TRUE;
++
++              if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
++                      /* This state is the former one */
++
++                      /* So check first whether we have to send a trap */
++                      if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) {
++                              /*
++                               * Do NOT send the Trap. The hold back time
++                               * has to run out first.
++                               */
++                              DoTrapSend = SK_FALSE;
++                      }
++
++                      /* Check now whether we have to log an Error */
++                      if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) {
++                              /*
++                               * Do NOT log the error. The hold back time
++                               * has to run out first.
++                               */
++                              DoErrLog = SK_FALSE;
++                      }
++              }
++              else {
++                      /* We came from a different state -> Set Begin Time Stamp */
++                      pSen->SenBegWarnTS = CurrTime;
++                      pSen->SenErrFlag = SK_SEN_ERR_WARN;
++              }
++
++              if (DoTrapSend) {
++                      /* Set current Time */
++                      pSen->SenLastWarnTrapTS = CurrTime;
++                      pSen->SenWarnCts++;
++
++                      /* Queue PNMI Event */
++                      SkEventQueue(pAC, SKGE_PNMI, TooHigh ?
++                              SK_PNMI_EVT_SEN_WAR_UPP : SK_PNMI_EVT_SEN_WAR_LOW, ParaLocal);
++              }
++
++              if (DoErrLog) {
++                      /* Set current Time */
++                      pSen->SenLastWarnLogTS = CurrTime;
++
++                      if (pSen->SenType == SK_SEN_TEMP) {
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG);
++                      }
++                      else if (pSen->SenType == SK_SEN_VOLT) {
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG);
++                      }
++                      else {
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG);
++                      }
++              }
++      }
++
++      /* Check for NO error at all */
++      if (!IsError && !TooHigh && !TooLow) {
++              /* Set o.k. Status if no error and no warning condition */
++              pSen->SenErrFlag = SK_SEN_ERR_OK;
++      }
++
++      /* End of check against the thresholds */
++
++      if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
++              /* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */
++              pSen->SenInit = SK_SEN_DYN_INIT_NONE;
++
++              if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
++                      /* 5V PCI-IO Voltage */
++                      pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
++                      pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
++              }
++              else {
++                      /* 3.3V PCI-IO Voltage */
++                      pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
++                      pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
++              }
++      }
++
++#ifdef TEST_ONLY
++      /* Dynamic thresholds also for VAUX of LM80 sensor */
++      if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
++
++              pSen->SenInit = SK_SEN_DYN_INIT_NONE;
++
++              /* 3.3V VAUX Voltage */
++              if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
++                      pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
++                      pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
++              }
++              /* 0V VAUX Voltage */
++              else {
++                      pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
++                      pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
++              }
++      }
++
++      /* Check initialization state: the VIO Thresholds need adaption */
++      if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
++               pSen->SenValue > SK_SEN_WARNLOW2C &&
++               pSen->SenValue < SK_SEN_WARNHIGH2) {
++
++              pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
++              pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
++              pSen->SenInit = SK_TRUE;
++      }
++
++      if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
++               pSen->SenValue > SK_SEN_WARNLOW2 &&
++               pSen->SenValue < SK_SEN_WARNHIGH2C) {
++
++              pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
++              pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
++              pSen->SenInit = SK_TRUE;
++      }
++#endif
++
++      if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
++              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
++      }
++}     /* SkI2cCheckSensor */
++
++
++/*
++ * The only Event to be served is the timeout event
++ *
++ */
++int   SkI2cEvent(
++SK_AC         *pAC,   /* Adapter Context */
++SK_IOC                IoC,    /* I/O Context */
++SK_U32                Event,  /* Module specific Event */
++SK_EVPARA     Para)   /* Event specific Parameter */
++{
++      int                     ReadComplete;
++      SK_SENSOR       *pSen;
++      SK_U32          Time;
++      SK_EVPARA       ParaLocal;
++      int                     i;
++
++      /* New case: no sensors */
++      if (pAC->I2c.MaxSens == 0) {
++              return(0);
++      }
++
++      switch (Event) {
++      case SK_I2CEV_IRQ:
++              pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
++              ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
++
++              if (ReadComplete) {
++                      /* Check sensor against defined thresholds */
++                      SkI2cCheckSensor(pAC, pSen);
++
++                      /* Increment Current sensor and set appropriate Timeout */
++                      pAC->I2c.CurrSens++;
++                      if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
++                              pAC->I2c.CurrSens = 0;
++                              Time = SK_I2C_TIM_LONG;
++                      }
++                      else {
++                              Time = SK_I2C_TIM_SHORT;
++                      }
++
++                      /* Start Timer */
++                      ParaLocal.Para64 = (SK_U64)0;
++
++                      pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
++
++                      SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
++                              SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
++              }
++              else {
++                      /* Start Timer */
++                      ParaLocal.Para64 = (SK_U64)0;
++
++                      pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
++
++                      SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
++                              SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
++              }
++              break;
++      case SK_I2CEV_TIM:
++              if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
++
++                      ParaLocal.Para64 = (SK_U64)0;
++                      SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
++
++                      pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
++                      ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
++
++                      if (ReadComplete) {
++                              /* Check sensor against defined thresholds */
++                              SkI2cCheckSensor(pAC, pSen);
++
++                              /* Increment Current sensor and set appropriate Timeout */
++                              pAC->I2c.CurrSens++;
++                              if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
++                                      pAC->I2c.CurrSens = 0;
++                                      Time = SK_I2C_TIM_LONG;
++                              }
++                              else {
++                                      Time = SK_I2C_TIM_SHORT;
++                              }
++
++                              /* Start Timer */
++                              ParaLocal.Para64 = (SK_U64)0;
++
++                              pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
++
++                              SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
++                                      SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
++                      }
++              }
++              else {
++                      pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
++                      pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
++                      SK_I2C_STOP(IoC);
++
++                      /* Increment Current sensor and set appropriate Timeout */
++                      pAC->I2c.CurrSens++;
++                      if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
++                              pAC->I2c.CurrSens = 0;
++                              Time = SK_I2C_TIM_LONG;
++                      }
++                      else {
++                              Time = SK_I2C_TIM_SHORT;
++                      }
++
++                      /* Start Timer */
++                      ParaLocal.Para64 = (SK_U64)0;
++
++                      pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
++
++                      SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
++                              SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
++              }
++              break;
++      case SK_I2CEV_CLEAR:
++              for (i = 0; i < SK_MAX_SENSORS; i++) {
++                      pSen = &pAC->I2c.SenTable[i];
++
++                      pSen->SenErrFlag = SK_SEN_ERR_OK;
++                      pSen->SenErrCts = 0;
++                      pSen->SenWarnCts = 0;
++                      pSen->SenBegErrTS = 0;
++                      pSen->SenBegWarnTS = 0;
++                      pSen->SenLastErrTrapTS = (SK_U64)0;
++                      pSen->SenLastErrLogTS = (SK_U64)0;
++                      pSen->SenLastWarnTrapTS = (SK_U64)0;
++                      pSen->SenLastWarnLogTS = (SK_U64)0;
++              }
++              break;
++      default:
++              SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
++      }
++
++      return(0);
++}     /* SkI2cEvent*/
++
++#endif /* !SK_DIAG */
++
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skvpd.c linux-2.6.9.new/drivers/net/sk98lin/skvpd.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skvpd.c        2004-10-19 05:54:32.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skvpd.c        2006-12-07 14:35:03.000000000 +0800
+@@ -1,22 +1,22 @@
+ /******************************************************************************
+  *
+  * Name:      skvpd.c
+- * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.37 $
+- * Date:      $Date: 2003/01/13 10:42:45 $
+- * Purpose:   Shared software to read and write VPD data
++ * Project:   Gigabit Ethernet Adapters, VPD-Module
++ * Version:   $Revision: 2.6 $
++ * Date:      $Date: 2004/11/02 10:47:39 $
++ * Purpose:   Shared software to read and write VPD
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+- *    (C)Copyright 1998-2003 SysKonnect GmbH.
++ *    (C)Copyright 1998-2002 SysKonnect.
++ *    (C)Copyright 2002-2004 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+  *    the Free Software Foundation; either version 2 of the License, or
+  *    (at your option) any later version.
+- *
+  *    The information in this file is provided "AS IS" without warranty.
+  *
+  ******************************************************************************/
+@@ -25,7 +25,7 @@
+       Please refer skvpd.txt for infomation how to include this module
+  */
+ static const char SysKonnectFileId[] =
+-      "@(#)$Id: skvpd.c,v 1.37 2003/01/13 10:42:45 rschmidt Exp $ (C) SK";
++      "@(#) $Id: skvpd.c,v 2.6 2004/11/02 10:47:39 rschmidt Exp $ (C) Marvell.";
+ #include "h/skdrv1st.h"
+ #include "h/sktypes.h"
+@@ -59,9 +59,10 @@
+       SK_U64  start_time;
+       SK_U16  state;
+-      SK_DBG_MSG(pAC,SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
++      SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+               ("VPD wait for %s\n", event?"Write":"Read"));
+       start_time = SkOsGetTime(pAC);
++
+       do {
+               if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC) {
+@@ -81,17 +82,18 @@
+                               ("ERROR:VPD wait timeout\n"));
+                       return(1);
+               }
+-              
++
+               VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state);
+-              
++
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+                       ("state = %x, event %x\n",state,event));
+-      } while((int)(state & PCI_VPD_FLAG) == event);
++      } while ((int)(state & PCI_VPD_FLAG) == event);
+       return(0);
+ }
+-#ifdef SKDIAG
++
++#ifdef SK_DIAG
+ /*
+  * Read the dword at address 'addr' from the VPD EEPROM.
+@@ -124,16 +126,15 @@
+       Rtv = 0;
+       VPD_IN32(pAC, IoC, PCI_VPD_DAT_REG, &Rtv);
+-      
++
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+               ("VPD read dword data = 0x%x\n",Rtv));
+       return(Rtv);
+ }
++#endif /* SK_DIAG */
+-#endif        /* SKDIAG */
+-
+-#if 0
++#ifdef XXX
+ /*
+       Write the dword 'data' at address 'addr' into the VPD EEPROM, and
+       verify that the data is written.
+@@ -151,7 +152,6 @@
+ . over all                    3.8 ms          13.2 ms
+ .
+-
+  Returns      0:      success
+                       1:      error,  I2C transfer does not terminate
+                       2:      error,  data verify error
+@@ -189,7 +189,8 @@
+       return(0);
+ }     /* VpdWriteDWord */
+-#endif        /* 0 */
++#endif /* XXX */
++
+ /*
+  *    Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
+@@ -215,7 +216,7 @@
+       pComp = (SK_U8 *) buf;
+       for (i = 0; i < Len; i++, buf++) {
+-              if ((i%sizeof(SK_U32)) == 0) {
++              if ((i % SZ_LONG) == 0) {
+                       /*
+                        * At the begin of each cycle read the Data Reg
+                        * So it is initialized even if only a few bytes
+@@ -233,14 +234,13 @@
+                       }
+               }
+-              /* Write current Byte */
+-              VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
+-                              *(SK_U8*)buf);
++              /* Write current byte */
++              VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i % SZ_LONG), *(SK_U8*)buf);
+-              if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) {
++              if (((i % SZ_LONG) == 3) || (i == (Len - 1))) {
+                       /* New Address needs to be written to VPD_ADDR reg */
+                       AdrReg = (SK_U16) Addr;
+-                      Addr += sizeof(SK_U32);
++                      Addr += SZ_LONG;
+                       AdrReg |= VPD_WRITE;    /* WRITE operation */
+                       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
+@@ -250,7 +250,7 @@
+                       if (Rtv != 0) {
+                               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                                       ("Write Timed Out\n"));
+-                              return(i - (i%sizeof(SK_U32)));
++                              return(i - (i % SZ_LONG));
+                       }
+                       /*
+@@ -265,18 +265,18 @@
+                       if (Rtv != 0) {
+                               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                                       ("Verify Timed Out\n"));
+-                              return(i - (i%sizeof(SK_U32)));
++                              return(i - (i % SZ_LONG));
+                       }
+-                      for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) {
+-                              
++                      for (j = 0; j <= (int)(i % SZ_LONG); j++, pComp++) {
++
+                               VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data);
+-                              
++
+                               if (Data != *pComp) {
+                                       /* Verify Error */
+                                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                                               ("WriteStream Verify Error\n"));
+-                                      return(i - (i%sizeof(SK_U32)) + j);
++                                      return(i - (i % SZ_LONG) + j);
+                               }
+                       }
+               }
+@@ -284,7 +284,7 @@
+       return(Len);
+ }
+-      
++
+ /*
+  *    Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
+@@ -304,10 +304,10 @@
+       int             Rtv;
+       for (i = 0; i < Len; i++, buf++) {
+-              if ((i%sizeof(SK_U32)) == 0) {
++              if ((i % SZ_LONG) == 0) {
+                       /* New Address needs to be written to VPD_ADDR reg */
+                       AdrReg = (SK_U16) Addr;
+-                      Addr += sizeof(SK_U32);
++                      Addr += SZ_LONG;
+                       AdrReg &= ~VPD_WRITE;   /* READ operation */
+                       VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
+@@ -318,13 +318,13 @@
+                               return(i);
+                       }
+               }
+-              VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
+-                      (SK_U8 *)buf);
++              VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i % SZ_LONG), (SK_U8 *)buf);
+       }
+       return(Len);
+ }
++
+ /*
+  *    Read ore writes 'len' bytes of VPD data, starting at 'addr' from
+  *    or to the I2C EEPROM.
+@@ -350,14 +350,14 @@
+               return(0);
+       vpd_rom_size = pAC->vpd.rom_size;
+-      
++
+       if (addr > vpd_rom_size - 4) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("Address error: 0x%x, exp. < 0x%x\n",
+                       addr, vpd_rom_size - 4));
+               return(0);
+       }
+-      
++
+       if (addr + len > vpd_rom_size) {
+               len = vpd_rom_size - addr;
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+@@ -374,8 +374,8 @@
+       return(Rtv);
+ }
+-#ifdef SKDIAG
++#if defined (SK_DIAG) || defined (SK_ASF)
+ /*
+  *    Read 'len' bytes of VPD data, starting at 'addr'.
+  *
+@@ -391,6 +391,7 @@
+       return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ));
+ }
++
+ /*
+  *    Write 'len' bytes of *but to the VPD EEPROM, starting at 'addr'.
+  *
+@@ -405,18 +406,27 @@
+ {
+       return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE));
+ }
+-#endif        /* SKDIAG */
++#endif /* SK_DIAG */
+-/*
+- * (re)initialize the VPD buffer
++
++/******************************************************************************
+  *
+- * Reads the VPD data from the EEPROM into the VPD buffer.
+- * Get the remaining read only and read / write space.
++ *    VpdInit() - (re)initialize the VPD buffer
+  *
+- * return     0:      success
+- *            1:      fatal VPD error
++ * Description:
++ *    Reads the VPD data from the EEPROM into the VPD buffer.
++ *    Get the remaining read only and read / write space.
++ *
++ * Note:
++ *    This is a local function and should be used locally only.
++ *    However, the ASF module needs to use this function also.
++ *    Therfore it has been published.
++ *
++ * Returns:
++ *    0:      success
++ *    1:      fatal VPD error
+  */
+-static int VpdInit(
++int VpdInit(
+ SK_AC *pAC,   /* Adapters context */
+ SK_IOC        IoC)    /* IO Context */
+ {
+@@ -427,14 +437,14 @@
+       SK_U16  dev_id;
+       SK_U32  our_reg2;
+-      SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. "));
+-      
++      SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit ... "));
++
+       VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id);
+-      
++
+       VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2);
+-      
++
+       pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14);
+-      
++
+       /*
+        * this function might get used before the hardware is initialized
+        * therefore we cannot always trust in GIChipId
+@@ -465,19 +475,15 @@
+                       ("Block Read Error\n"));
+               return(1);
+       }
+-      
++
+       pAC->vpd.vpd_size = vpd_size;
+       /* Asus K8V Se Deluxe bugfix. Correct VPD content */
+-      /* MBo April 2004 */
+-      if (((unsigned char)pAC->vpd.vpd_buf[0x3f] == 0x38) &&
+-          ((unsigned char)pAC->vpd.vpd_buf[0x40] == 0x3c) &&
+-          ((unsigned char)pAC->vpd.vpd_buf[0x41] == 0x45)) {
+-              printk("sk98lin: Asus mainboard with buggy VPD? "
+-                              "Correcting data.\n");
+-              pAC->vpd.vpd_buf[0x40] = 0x38;
+-      }
++      i = 62;
++      if (!SK_STRNCMP(pAC->vpd.vpd_buf + i, " 8<E", 4)) {
++              pAC->vpd.vpd_buf[i + 2] = '8';
++      }
+       /* find the end tag of the RO area */
+       if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) {
+@@ -485,9 +491,9 @@
+                       ("Encoding Error: RV Tag not found\n"));
+               return(1);
+       }
+-      
++
+       if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) {
+-              SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
++              SK_DBG_MSG(pAC, SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("Encoding Error: Invalid VPD struct size\n"));
+               return(1);
+       }
+@@ -497,7 +503,7 @@
+       for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) {
+               x += pAC->vpd.vpd_buf[i];
+       }
+-      
++
+       if (x != 0) {
+               /* checksum error */
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+@@ -511,7 +517,7 @@
+                       ("Encoding Error: RV Tag not found\n"));
+               return(1);
+       }
+-      
++
+       if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("Encoding Error: Invalid VPD struct size\n"));
+@@ -531,6 +537,7 @@
+       return(0);
+ }
++
+ /*
+  *    find the Keyword 'key' in the VPD buffer and fills the
+  *    parameter struct 'p' with it's values
+@@ -541,7 +548,7 @@
+ static SK_VPD_PARA *vpd_find_para(
+ SK_AC         *pAC,   /* common data base */
+ const char    *key,   /* keyword to find (e.g. "MN") */
+-SK_VPD_PARA *p)               /* parameter description struct */
++SK_VPD_PARA   *p)             /* parameter description struct */
+ {
+       char *v ;       /* points to VPD buffer */
+       int max;        /* Maximum Number of Iterations */
+@@ -556,10 +563,10 @@
+       if (*v != (char)RES_ID) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("Error: 0x%x missing\n", RES_ID));
+-              return NULL;
++              return(0);
+       }
+-      if (strcmp(key, VPD_NAME) == 0) {
++      if (SK_STRCMP(key, VPD_NAME) == 0) {
+               p->p_len = VPD_GET_RES_LEN(v);
+               p->p_val = VPD_GET_VAL(v);
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+@@ -569,7 +576,7 @@
+       v += 3 + VPD_GET_RES_LEN(v) + 3;
+       for (;; ) {
+-              if (SK_MEMCMP(key,v,2) == 0) {
++              if (SK_MEMCMP(key, v, 2) == 0) {
+                       p->p_len = VPD_GET_VPD_LEN(v);
+                       p->p_val = VPD_GET_VAL(v);
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+@@ -579,11 +586,11 @@
+               /* exit when reaching the "RW" Tag or the maximum of itera. */
+               max--;
+-              if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) {
++              if (SK_MEMCMP(VPD_RW, v, 2) == 0 || max == 0) {
+                       break;
+               }
+-              if (SK_MEMCMP(VPD_RV,v,2) == 0) {
++              if (SK_MEMCMP(VPD_RV, v, 2) == 0) {
+                       v += 3 + VPD_GET_VPD_LEN(v) + 3;        /* skip VPD-W */
+               }
+               else {
+@@ -600,9 +607,10 @@
+                       ("Key/Len Encoding error\n"));
+       }
+ #endif /* DEBUG */
+-      return NULL;
++      return(0);
+ }
++
+ /*
+  *    Move 'n' bytes. Begin with the last byte if 'n' is > 0,
+  *    Start with the last byte if n is < 0.
+@@ -637,6 +645,7 @@
+       }
+ }
++
+ /*
+  *    setup the VPD keyword 'key' at 'ip'.
+  *
+@@ -653,10 +662,11 @@
+       p = (SK_VPD_KEY *) ip;
+       p->p_key[0] = key[0];
+       p->p_key[1] = key[1];
+-      p->p_len = (unsigned char) len;
+-      SK_MEMCPY(&p->p_val,buf,len);
++      p->p_len = (unsigned char)len;
++      SK_MEMCPY(&p->p_val, buf, len);
+ }
++
+ /*
+  *    Setup the VPD end tag "RV" / "RW".
+  *    Also correct the remaining space variables vpd_free_ro / vpd_free_rw.
+@@ -682,7 +692,7 @@
+       if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) {
+               /* something wrong here, encoding error */
+-              SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
++              SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
+                       ("Encoding Error: invalid end tag\n"));
+               return(1);
+       }
+@@ -714,6 +724,7 @@
+       return(0);
+ }
++
+ /*
+  *    Insert a VPD keyword into the VPD buffer.
+  *
+@@ -747,11 +758,11 @@
+       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
+               ("VPD setup para key = %s, val = %s\n",key,buf));
+-      
++
+       vpd_size = pAC->vpd.vpd_size;
+       rtv = 0;
+-      ip = NULL;
++      ip = 0;
+       if (type == VPD_RW_KEY) {
+               /* end tag is "RW" */
+               free = pAC->vpd.v.vpd_free_rw;
+@@ -875,18 +886,18 @@
+               }
+       }
+-      if ((signed)strlen(VPD_NAME) + 1 <= *len) {
++      if ((signed)SK_STRLEN(VPD_NAME) + 1 <= *len) {
+               v = pAC->vpd.vpd_buf;
+-              strcpy(buf,VPD_NAME);
+-              n = strlen(VPD_NAME) + 1;
++              SK_STRCPY(buf, VPD_NAME);
++              n = SK_STRLEN(VPD_NAME) + 1;
+               buf += n;
+               *elements = 1;
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
+-                      ("'%c%c' ",v[0],v[1]));
++                      ("'%c%c' ", v[0], v[1]));
+       }
+       else {
+               *len = 0;
+-              SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
++              SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                       ("buffer overflow\n"));
+               return(2);
+       }
+@@ -894,17 +905,17 @@
+       v += 3 + VPD_GET_RES_LEN(v) + 3;
+       for (;; ) {
+               /* exit when reaching the "RW" Tag */
+-              if (SK_MEMCMP(VPD_RW,v,2) == 0) {
++              if (SK_MEMCMP(VPD_RW, v, 2) == 0) {
+                       break;
+               }
+-              if (SK_MEMCMP(VPD_RV,v,2) == 0) {
++              if (SK_MEMCMP(VPD_RV, v, 2) == 0) {
+                       v += 3 + VPD_GET_VPD_LEN(v) + 3;        /* skip VPD-W */
+                       continue;
+               }
+               if (n+3 <= *len) {
+-                      SK_MEMCPY(buf,v,2);
++                      SK_MEMCPY(buf, v, 2);
+                       buf += 2;
+                       *buf++ = '\0';
+                       n += 3;
+@@ -991,13 +1002,14 @@
+ {
+       if ((*key != 'Y' && *key != 'V') ||
+               key[1] < '0' || key[1] > 'Z' ||
+-              (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
++              (key[1] > '9' && key[1] < 'A') || SK_STRLEN(key) != 2) {
+               return(SK_FALSE);
+       }
+       return(SK_TRUE);
+ }
++
+ /*
+  *    Read the contents of the VPD EEPROM and copy it to the VPD
+  *    buffer if not already done. Insert/overwrite the keyword 'key'
+@@ -1026,7 +1038,7 @@
+       if ((*key != 'Y' && *key != 'V') ||
+               key[1] < '0' || key[1] > 'Z' ||
+-              (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
++              (key[1] > '9' && key[1] < 'A') || SK_STRLEN(key) != 2) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+                       ("illegal key tag, keyword not written\n"));
+@@ -1042,13 +1054,13 @@
+       }
+       rtv = 0;
+-      len = strlen(buf);
++      len = SK_STRLEN(buf);
+       if (len > VPD_MAX_LEN) {
+               /* cut it */
+               len = VPD_MAX_LEN;
+               rtv = 2;
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+-                      ("keyword too long, cut after %d bytes\n",VPD_MAX_LEN));
++                      ("keyword too long, cut after %d bytes\n", VPD_MAX_LEN));
+       }
+       if ((rtv2 = VpdSetupPara(pAC, key, buf, len, VPD_RW_KEY, OWR_KEY)) != 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+@@ -1059,6 +1071,7 @@
+       return(rtv);
+ }
++
+ /*
+  *    Read the contents of the VPD EEPROM and copy it to the
+  *    VPD buffer if not already done. Remove the VPD keyword
+@@ -1082,7 +1095,7 @@
+       vpd_size = pAC->vpd.vpd_size;
+-      SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key));
++      SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD delete key %s\n", key));
+       if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
+               if (VpdInit(pAC, IoC) != 0) {
+                       SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
+@@ -1119,6 +1132,7 @@
+       return(0);
+ }
++
+ /*
+  *    If the VPD buffer contains valid data write the VPD
+  *    read/write area back to the VPD EEPROM.
+@@ -1149,7 +1163,6 @@
+ }
+-
+ /*
+  *    Read the contents of the VPD EEPROM and copy it to the VPD buffer
+  *    if not already done. If the keyword "VF" is not present it will be
+@@ -1178,7 +1191,7 @@
+               }
+       }
+-      len = strlen(msg);
++      len = SK_STRLEN(msg);
+       if (len > VPD_MAX_LEN) {
+               /* cut it */
+               len = VPD_MAX_LEN;
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/skxmac2.c linux-2.6.9.new/drivers/net/sk98lin/skxmac2.c
+--- linux-2.6.9.old/drivers/net/sk98lin/skxmac2.c      2004-10-19 05:55:28.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/skxmac2.c      2006-12-07 14:35:03.000000000 +0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skxmac2.c
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.102 $
+- * Date:      $Date: 2003/10/02 16:53:58 $
++ * Version:   $Revision: 2.35 $
++ * Date:      $Date: 2005/05/24 08:35:04 $
+  * Purpose:   Contains functions to initialize the MACs and PHYs
+  *
+  ******************************************************************************/
+@@ -11,13 +11,12 @@
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect.
+- *    (C)Copyright 2002-2003 Marvell.
++ *    (C)Copyright 2002-2005 Marvell.
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+  *    the Free Software Foundation; either version 2 of the License, or
+  *    (at your option) any later version.
+- *
+  *    The information in this file is provided "AS IS" without warranty.
+  *
+  ******************************************************************************/
+@@ -37,7 +36,7 @@
+ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell.";
++      "@(#) $Id: skxmac2.c,v 2.35 2005/05/24 08:35:04 rschmidt Exp $ (C) Marvell.";
+ #endif
+ #ifdef GENESIS
+@@ -83,7 +82,7 @@
+  * Returns:
+  *    nothing
+  */
+-void SkXmPhyRead(
++int SkXmPhyRead(
+ SK_AC *pAC,                   /* Adapter Context */
+ SK_IOC        IoC,                    /* I/O Context */
+ int           Port,                   /* Port Index (MAC_1 + n) */
+@@ -94,13 +93,13 @@
+       SK_GEPORT       *pPrt;
+       pPrt = &pAC->GIni.GP[Port];
+-      
++
+       /* write the PHY register's address */
+       XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
+-      
++
+       /* get the PHY register's value */
+       XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
+-      
++
+       if (pPrt->PhyType != SK_PHY_XMAC) {
+               do {
+                       XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
+@@ -110,6 +109,8 @@
+               /* get the PHY register's value */
+               XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
+       }
++
++      return(0);
+ }     /* SkXmPhyRead */
+@@ -122,7 +123,7 @@
+  * Returns:
+  *    nothing
+  */
+-void SkXmPhyWrite(
++int SkXmPhyWrite(
+ SK_AC *pAC,           /* Adapter Context */
+ SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+@@ -133,26 +134,28 @@
+       SK_GEPORT       *pPrt;
+       pPrt = &pAC->GIni.GP[Port];
+-      
++
+       if (pPrt->PhyType != SK_PHY_XMAC) {
+               do {
+                       XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
+                       /* wait until 'Busy' is cleared */
+               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
+       }
+-      
++
+       /* write the PHY register's address */
+       XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
+-      
++
+       /* write the PHY register's value */
+       XM_OUT16(IoC, Port, XM_PHY_DATA, Val);
+-      
++
+       if (pPrt->PhyType != SK_PHY_XMAC) {
+               do {
+                       XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
+                       /* wait until 'Busy' is cleared */
+               } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
+       }
++
++      return(0);
+ }     /* SkXmPhyWrite */
+ #endif /* GENESIS */
+@@ -167,7 +170,7 @@
+  * Returns:
+  *    nothing
+  */
+-void SkGmPhyRead(
++int SkGmPhyRead(
+ SK_AC *pAC,                   /* Adapter Context */
+ SK_IOC        IoC,                    /* I/O Context */
+ int           Port,                   /* Port Index (MAC_1 + n) */
+@@ -176,52 +179,72 @@
+ {
+       SK_U16  Ctrl;
+       SK_GEPORT       *pPrt;
+-#ifdef VCPU
+-      u_long SimCyle;
+-      u_long SimLowTime;
+-      
+-      VCPUgetTime(&SimCyle, &SimLowTime);
+-      VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n",
+-              PhyReg, SimCyle, SimLowTime);
+-#endif /* VCPU */
+-      
++      SK_U32  StartTime;
++      SK_U32  CurrTime;
++      SK_U32  Delta;
++
+       pPrt = &pAC->GIni.GP[Port];
+-      
++
+       /* set PHY-Register offset and 'Read' OpCode (= 1) */
+       *pVal = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) |
+               GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD);
+       GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal);
+-      GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
+-      
++#ifdef DEBUG
+       /* additional check for MDC/MDIO activity */
+-      if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
++      GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
++
++      if ((Ctrl & GM_SMI_CT_OP_RD) == 0) {
++
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
++                      ("PHY read impossible on Port %d (Ctrl=0x%04x)\n", Port, Ctrl));
++
+               *pVal = 0;
+-              return;
++              return(1);
+       }
++#endif /* DEBUG */
+       *pVal |= GM_SMI_CT_BUSY;
+-      
+-      do {
++
++      SK_IN32(IoC, GMAC_TI_ST_VAL, &StartTime);
++
++      do {    /* wait until 'Busy' is cleared and 'ReadValid' is set */
+ #ifdef VCPU
+               VCPUwaitTime(1000);
+ #endif /* VCPU */
++              SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime);
++
++              if (CurrTime >= StartTime) {
++                      Delta = CurrTime - StartTime;
++              }
++              else {
++                      Delta = CurrTime + ~StartTime + 1;
++              }
++
++              if (Delta > SK_PHY_ACC_TO) {
++
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
++                              ("PHY read timeout on Port %d (Ctrl=0x%04x)\n", Port, Ctrl));
++                      return(1);
++              }
++
+               GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
+-      /* wait until 'ReadValid' is set */
+-      } while (Ctrl == *pVal);
+-      
+-      /* get the PHY register's value */
++              /* Error on reading SMI Control Register */
++              if (Ctrl == 0xffff) {
++                      return(1);
++              }
++
++      } while ((Ctrl ^ *pVal) != (GM_SMI_CT_RD_VAL | GM_SMI_CT_BUSY));
++
+       GM_IN16(IoC, Port, GM_SMI_DATA, pVal);
+-#ifdef VCPU
+-      VCPUgetTime(&SimCyle, &SimLowTime);
+-      VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
+-              SimCyle, SimLowTime);
+-#endif /* VCPU */
++      /* dummy read after GM_IN16() */
++      SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime);
++      return(0);
+ }     /* SkGmPhyRead */
+@@ -234,7 +257,7 @@
+  * Returns:
+  *    nothing
+  */
+-void SkGmPhyWrite(
++int SkGmPhyWrite(
+ SK_AC *pAC,           /* Adapter Context */
+ SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+@@ -243,54 +266,74 @@
+ {
+       SK_U16  Ctrl;
+       SK_GEPORT       *pPrt;
+-#ifdef VCPU
+-      SK_U32  DWord;
+-      u_long  SimCyle;
+-      u_long  SimLowTime;
+-      
+-      VCPUgetTime(&SimCyle, &SimLowTime);
+-      VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n",
+-              PhyReg, Val, SimCyle, SimLowTime);
+-#endif /* VCPU */
+-      
++      SK_U32  StartTime;
++      SK_U32  CurrTime;
++      SK_U32  Delta;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              ("SkGmPhyWrite Port:%d, Reg=%d, Val=0x%04X\n",
++               Port, PhyReg, Val));
++
+       pPrt = &pAC->GIni.GP[Port];
+-      
++
+       /* write the PHY register's value */
+       GM_OUT16(IoC, Port, GM_SMI_DATA, Val);
+-      
+-      /* set PHY-Register offset and 'Write' OpCode (= 0) */
+-      Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg);
+-      GM_OUT16(IoC, Port, GM_SMI_CTRL, Val);
+-
+-      GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
+-      
++#ifdef DEBUG
+       /* additional check for MDC/MDIO activity */
+-      if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
+-              return;
++      GM_IN16(IoC, Port, GM_SMI_DATA, &Ctrl);
++
++      if (Ctrl != Val) {
++
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
++                      ("PHY write impossible on Port %d (Val=0x%04x)\n", Port, Ctrl));
++
++              return(1);
+       }
+-      
+-      Val |= GM_SMI_CT_BUSY;
++#endif /* DEBUG */
+-      do {
+-#ifdef VCPU
+-              /* read Timer value */
+-              SK_IN32(IoC, B2_TI_VAL, &DWord);
++      /* set PHY-Register offset and 'Write' OpCode (= 0) */
++      Ctrl = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) |
++              GM_SMI_CT_REG_AD(PhyReg));
++      GM_OUT16(IoC, Port, GM_SMI_CTRL, Ctrl);
++
++      SK_IN32(IoC, GMAC_TI_ST_VAL, &StartTime);
++
++      do {    /* wait until 'Busy' is cleared */
++#ifdef VCPU
+               VCPUwaitTime(1000);
+ #endif /* VCPU */
++              SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime);
++
++              if (CurrTime >= StartTime) {
++                      Delta = CurrTime - StartTime;
++              }
++              else {
++                      Delta = CurrTime + ~StartTime + 1;
++              }
++
++              if (Delta > SK_PHY_ACC_TO) {
++
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
++                              ("PHY write timeout on Port %d (Ctrl=0x%04x)\n", Port, Ctrl));
++                      return(1);
++              }
++
+               GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
+-      /* wait until 'Busy' is cleared */
+-      } while (Ctrl == Val);
++              /* Error on reading SMI Control Register */
++              if (Ctrl == 0xffff) {
++                      return(1);
++              }
+       
+-#ifdef VCPU
+-      VCPUgetTime(&SimCyle, &SimLowTime);
+-      VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
+-              SimCyle, SimLowTime);
+-#endif /* VCPU */
++      } while ((Ctrl & GM_SMI_CT_BUSY) != 0);
++      /* dummy read after GM_IN16() */
++      SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime);
++
++      return(0);
+ }     /* SkGmPhyWrite */
+ #endif /* YUKON */
+@@ -312,16 +355,8 @@
+ int           PhyReg,         /* Register Address (Offset) */
+ SK_U16        *pVal)          /* Pointer to Value */
+ {
+-      void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal);
+-      if (pAC->GIni.GIGenesis) {
+-              r_func = SkXmPhyRead;
+-      }
+-      else {
+-              r_func = SkGmPhyRead;
+-      }
+-      
+-      r_func(pAC, IoC, Port, PhyReg, pVal);
++      pAC->GIni.GIFunc.pFnMacPhyRead(pAC, IoC, Port, PhyReg, pVal);
+ }     /* SkGePhyRead */
+@@ -341,16 +376,8 @@
+ int           PhyReg,         /* Register Address (Offset) */
+ SK_U16        Val)            /* Value */
+ {
+-      void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val);
+-      if (pAC->GIni.GIGenesis) {
+-              w_func = SkXmPhyWrite;
+-      }
+-      else {
+-              w_func = SkGmPhyWrite;
+-      }
+-      
+-      w_func(pAC, IoC, Port, PhyReg, Val);
++      pAC->GIni.GIFunc.pFnMacPhyWrite(pAC, IoC, Port, PhyReg, Val);
+ }     /* SkGePhyWrite */
+ #endif /* SK_DIAG */
+@@ -360,15 +387,15 @@
+  *    SkMacPromiscMode() - Enable / Disable Promiscuous Mode
+  *
+  * Description:
+- *   enables / disables promiscuous mode by setting Mode Register (XMAC) or
+- *   Receive Control Register (GMAC) dep. on board type       
++ *    enables / disables promiscuous mode by setting Mode Register (XMAC) or
++ *    Receive Control Register (GMAC) dep. on board type
+  *
+  * Returns:
+  *    nothing
+  */
+ void SkMacPromiscMode(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port,   /* Port Index (MAC_1 + n) */
+ SK_BOOL       Enable) /* Enable / Disable */
+ {
+@@ -377,11 +404,11 @@
+ #endif
+ #ifdef GENESIS
+       SK_U32  MdReg;
+-#endif        
++#endif
+ #ifdef GENESIS
+       if (pAC->GIni.GIGenesis) {
+-              
++
+               XM_IN32(IoC, Port, XM_MODE, &MdReg);
+               /* enable or disable promiscuous mode */
+               if (Enable) {
+@@ -394,12 +421,12 @@
+               XM_OUT32(IoC, Port, XM_MODE, MdReg);
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+-              
++
+               GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
+-              
++
+               /* enable or disable unicast and multicast filtering */
+               if (Enable) {
+                       RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
+@@ -420,28 +447,28 @@
+  *    SkMacHashing() - Enable / Disable Hashing
+  *
+  * Description:
+- *   enables / disables hashing by setting Mode Register (XMAC) or
+- *   Receive Control Register (GMAC) dep. on board type               
++ *    enables / disables hashing by setting Mode Register (XMAC) or
++ *    Receive Control Register (GMAC) dep. on board type
+  *
+  * Returns:
+  *    nothing
+  */
+ void SkMacHashing(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port,   /* Port Index (MAC_1 + n) */
+ SK_BOOL       Enable) /* Enable / Disable */
+ {
+ #ifdef YUKON
+       SK_U16  RcReg;
+-#endif        
++#endif
+ #ifdef GENESIS
+       SK_U32  MdReg;
+ #endif
+ #ifdef GENESIS
+       if (pAC->GIni.GIGenesis) {
+-              
++
+               XM_IN32(IoC, Port, XM_MODE, &MdReg);
+               /* enable or disable hashing */
+               if (Enable) {
+@@ -454,12 +481,12 @@
+               XM_OUT32(IoC, Port, XM_MODE, MdReg);
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+-              
++
+               GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
+-              
++
+               /* enable or disable multicast filtering */
+               if (Enable) {
+                       RcReg |= GM_RXCR_MCF_ENA;
+@@ -487,8 +514,8 @@
+  *     - don't set XMR_FS_ERR in status       SK_LENERR_OK_ON/OFF
+  *       for inrange length error frames
+  *     - don't set XMR_FS_ERR in status       SK_BIG_PK_OK_ON/OFF
+- *       for frames > 1514 bytes
+- *   - enable Rx of own packets         SK_SELF_RX_ON/OFF
++ *            for frames > 1514 bytes
++ *    - enable Rx of own packets                      SK_SELF_RX_ON/OFF
+  *
+  *    for incoming packets may be enabled/disabled by this function.
+  *    Additional modes may be added later.
+@@ -499,11 +526,11 @@
+  *    nothing
+  */
+ static void SkXmSetRxCmd(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ int           Mode)           /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
+-                                         SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
++                                              SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
+ {
+       SK_U16  OldRxCmd;
+       SK_U16  RxCmd;
+@@ -511,7 +538,7 @@
+       XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd);
+       RxCmd = OldRxCmd;
+-      
++
+       switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) {
+       case SK_STRIP_FCS_ON:
+               RxCmd |= XM_RX_STRIP_FCS;
+@@ -572,8 +599,8 @@
+  *    The features
+  *     - FCS (CRC) stripping,                         SK_STRIP_FCS_ON/OFF
+  *     - don't set GMR_FS_LONG_ERR            SK_BIG_PK_OK_ON/OFF
+- *       for frames > 1514 bytes
+- *   - enable Rx of own packets         SK_SELF_RX_ON/OFF
++ *            for frames > 1514 bytes
++ *    - enable Rx of own packets                      SK_SELF_RX_ON/OFF
+  *
+  *    for incoming packets may be enabled/disabled by this function.
+  *    Additional modes may be added later.
+@@ -584,20 +611,17 @@
+  *    nothing
+  */
+ static void SkGmSetRxCmd(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ int           Mode)           /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
+-                                         SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
++                                              SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
+ {
+-      SK_U16  OldRxCmd;
+       SK_U16  RxCmd;
+       if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) {
+-              
+-              GM_IN16(IoC, Port, GM_RX_CTRL, &OldRxCmd);
+-              RxCmd = OldRxCmd;
++              GM_IN16(IoC, Port, GM_RX_CTRL, &RxCmd);
+               if ((Mode & SK_STRIP_FCS_ON) != 0) {
+                       RxCmd |= GM_RXCR_CRC_DIS;
+@@ -605,17 +629,13 @@
+               else {
+                       RxCmd &= ~GM_RXCR_CRC_DIS;
+               }
+-              /* Write the new mode to the Rx control register if required */
+-              if (OldRxCmd != RxCmd) {
+-                      GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd);
+-              }
++              /* Write the new mode to the Rx Control register */
++              GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd);
+       }
+       if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) {
+-              
+-              GM_IN16(IoC, Port, GM_SERIAL_MODE, &OldRxCmd);
+-              RxCmd = OldRxCmd;
++              GM_IN16(IoC, Port, GM_SERIAL_MODE, &RxCmd);
+               if ((Mode & SK_BIG_PK_OK_ON) != 0) {
+                       RxCmd |= GM_SMOD_JUMBO_ENA;
+@@ -623,10 +643,8 @@
+               else {
+                       RxCmd &= ~GM_SMOD_JUMBO_ENA;
+               }
+-              /* Write the new mode to the Rx control register if required */
+-              if (OldRxCmd != RxCmd) {
+-                      GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd);
+-              }
++              /* Write the new mode to the Serial Mode register */
++              GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd);
+       }
+ }     /* SkGmSetRxCmd */
+@@ -641,17 +659,17 @@
+  *    nothing
+  */
+ void SkMacSetRxCmd(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ int           Mode)           /* Rx Mode */
+ {
+       if (pAC->GIni.GIGenesis) {
+-              
++
+               SkXmSetRxCmd(pAC, IoC, Port, Mode);
+       }
+       else {
+-              
++
+               SkGmSetRxCmd(pAC, IoC, Port, Mode);
+       }
+@@ -668,15 +686,15 @@
+  *    nothing
+  */
+ void SkMacCrcGener(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port,   /* Port Index (MAC_1 + n) */
+ SK_BOOL       Enable) /* Enable / Disable */
+ {
+       SK_U16  Word;
+       if (pAC->GIni.GIGenesis) {
+-              
++
+               XM_IN16(IoC, Port, XM_TX_CMD, &Word);
+               if (Enable) {
+@@ -689,9 +707,9 @@
+               XM_OUT16(IoC, Port, XM_TX_CMD, Word);
+       }
+       else {
+-              
++
+               GM_IN16(IoC, Port, GM_TX_CTRL, &Word);
+-              
++
+               if (Enable) {
+                       Word &= ~GM_TXCR_CRC_DIS;
+               }
+@@ -721,14 +739,14 @@
+  *    nothing
+  */
+ void SkXmClrExactAddr(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ int           StartNum,       /* Begin with this Address Register Index (0..15) */
+ int           StopNum)        /* Stop after finished with this Register Idx (0..15) */
+ {
+       int             i;
+-      SK_U16  ZeroAddr[3] = {0x0000, 0x0000, 0x0000};
++      SK_U16  ZeroAddr[3] = {0, 0, 0};
+       if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 ||
+               StartNum > StopNum) {
+@@ -738,7 +756,7 @@
+       }
+       for (i = StartNum; i <= StopNum; i++) {
+-              XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]);
++              XM_OUTADDR(IoC, Port, XM_EXM(i), ZeroAddr);
+       }
+ }     /* SkXmClrExactAddr */
+ #endif /* GENESIS */
+@@ -755,21 +773,21 @@
+  *    nothing
+  */
+ void SkMacFlushTxFifo(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
+ #ifdef GENESIS
+       SK_U32  MdReg;
+       if (pAC->GIni.GIGenesis) {
+-              
++
+               XM_IN32(IoC, Port, XM_MODE, &MdReg);
+               XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF);
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+               /* no way to flush the FIFO we have to issue a reset */
+@@ -791,8 +809,8 @@
+  *    nothing
+  */
+ void SkMacFlushRxFifo(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
+ #ifdef GENESIS
+@@ -805,7 +823,7 @@
+               XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF);
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+               /* no way to flush the FIFO we have to issue a reset */
+@@ -853,23 +871,23 @@
+  *    nothing
+  */
+ static void SkXmSoftRst(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
+-      SK_U16  ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000};
+-      
++      SK_U16  ZeroAddr[4] = {0, 0, 0, 0};
++
+       /* reset the statistics module */
+       XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT);
+       /* disable all XMAC IRQs */
+       XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
+-      
++
+       XM_OUT32(IoC, Port, XM_MODE, 0);                /* clear Mode Reg */
+-      
++
+       XM_OUT16(IoC, Port, XM_TX_CMD, 0);              /* reset TX CMD Reg */
+       XM_OUT16(IoC, Port, XM_RX_CMD, 0);              /* reset RX CMD Reg */
+-      
++
+       /* disable all PHY IRQs */
+       switch (pAC->GIni.GP[Port].PhyType) {
+       case SK_PHY_BCOM:
+@@ -887,13 +905,13 @@
+       }
+       /* clear the Hash Register */
+-      XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr);
++      XM_OUTHASH(IoC, Port, XM_HSM, ZeroAddr);
+       /* clear the Exact Match Address registers */
+       SkXmClrExactAddr(pAC, IoC, Port, 0, 15);
+-      
++
+       /* clear the Source Check Address registers */
+-      XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr);
++      XM_OUTHASH(IoC, Port, XM_SRC_CHK, ZeroAddr);
+ }     /* SkXmSoftRst */
+@@ -916,8 +934,8 @@
+  *    nothing
+  */
+ static void SkXmHardRst(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
+       SK_U32  Reg;
+@@ -940,19 +958,19 @@
+                       }
+                       SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
+-                      
++
+                       SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &Word);
+-              
++
+               } while ((Word & MFF_SET_MAC_RST) == 0);
+       }
+       /* For external PHYs there must be special handling */
+       if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
+-              
++
+               SK_IN32(IoC, B2_GP_IO, &Reg);
+-              
++
+               if (Port == 0) {
+-                      Reg |= GP_DIR_0;        /* set to output */
++                      Reg |= GP_DIR_0;        /* set to output */
+                       Reg &= ~GP_IO_0;        /* set PHY reset (active low) */
+               }
+               else {
+@@ -978,12 +996,12 @@
+  *    nothing
+  */
+ static void SkXmClearRst(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
+       SK_U32  DWord;
+-      
++
+       /* clear HW reset */
+       SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
+@@ -1000,7 +1018,7 @@
+               /* Clear PHY reset */
+               SK_OUT32(IoC, B2_GP_IO, DWord);
+-              /* Enable GMII interface */
++              /* enable GMII interface */
+               XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
+       }
+ }     /* SkXmClearRst */
+@@ -1020,8 +1038,8 @@
+  *    nothing
+  */
+ static void SkGmSoftRst(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
+       SK_U16  EmptyHash[4] = {0x0000, 0x0000, 0x0000, 0x0000};
+@@ -1030,19 +1048,18 @@
+       /* reset the statistics module */
+       /* disable all GMAC IRQs */
+-      SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
+-      
++      SK_OUT8(IoC, MR_ADDR(Port, GMAC_IRQ_MSK), 0);
++
+       /* disable all PHY IRQs */
+       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
+-      
++
+       /* clear the Hash Register */
+       GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, EmptyHash);
+-      /* Enable Unicast and Multicast filtering */
++      /* enable Unicast and Multicast filtering */
+       GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl);
+-      
+-      GM_OUT16(IoC, Port, GM_RX_CTRL,
+-              (SK_U16)(RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA));
++
++      GM_OUT16(IoC, Port, GM_RX_CTRL, RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
+ }     /* SkGmSoftRst */
+@@ -1057,16 +1074,16 @@
+  *    nothing
+  */
+ static void SkGmHardRst(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
+       SK_U32  DWord;
+-      
++
+       /* WA code for COMA mode */
+       if (pAC->GIni.GIYukonLite &&
+-              pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+-              
++              pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
++
+               SK_IN32(IoC, B2_GP_IO, &DWord);
+               DWord |= (GP_DIR_9 | GP_IO_9);
+@@ -1076,10 +1093,10 @@
+       }
+       /* set GPHY Control reset */
+-      SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
++      SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_SET);
+       /* set GMAC Control reset */
+-      SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
++      SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_SET);
+ }     /* SkGmHardRst */
+@@ -1094,24 +1111,27 @@
+  *    nothing
+  */
+ static void SkGmClearRst(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
+       SK_U32  DWord;
+-      
++      SK_U16  PhyId0;
++      SK_U16  PhyId1;
++      SK_U16  Word;
++
+ #ifdef XXX
+-              /* clear GMAC Control reset */
+-              SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
++      /* clear GMAC Control reset */
++      SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_CLR);
+-              /* set GMAC Control reset */
+-              SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
++      /* set GMAC Control reset */
++      SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_SET);
+ #endif /* XXX */
+       /* WA code for COMA mode */
+       if (pAC->GIni.GIYukonLite &&
+-              pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+-              
++              pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
++
+               SK_IN32(IoC, B2_GP_IO, &DWord);
+               DWord |= GP_DIR_9;              /* set to output */
+@@ -1121,30 +1141,74 @@
+               SK_OUT32(IoC, B2_GP_IO, DWord);
+       }
+-      /* set HWCFG_MODE */
+-      DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
+-              GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
+-              (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
+-              GPC_HWCFG_GMII_FIB);
++#ifdef VCPU
++      /* set MAC Reset before PHY reset is set */
++      SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_SET);
++#endif /* VCPU */
++
++      if (CHIP_ID_YUKON_2(pAC)) {
++              /* set GPHY Control reset */
++              SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_SET);
+-      /* set GPHY Control reset */
+-      SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
++              /* release GPHY Control reset */
++              SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_CLR);
++      }
++      else {
++              /* set HWCFG_MODE */
++              DWord = GPC_INT_POL | GPC_DIS_FC | GPC_DIS_SLEEP |
++                      GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
++                      (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
++                      GPC_HWCFG_GMII_FIB);
+-      /* release GPHY Control reset */
+-      SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
++              /* set GPHY Control reset */
++              SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
++
++              /* release GPHY Control reset */
++              SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
++      }
+ #ifdef VCPU
++      /* wait for internal initialization of GPHY */
++      VCPUprintf(0, "Waiting until PHY %d is ready to initialize\n", Port);
++      VCpuWait(10000);
++
++      /* release GMAC reset */
++      SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_CLR);
++
++      /* wait for stable GMAC clock */
+       VCpuWait(9000);
+ #endif /* VCPU */
+       /* clear GMAC Control reset */
+-      SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
++      SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_CLR);
++
++      if (HW_FEATURE(pAC, HWF_WA_DEV_472) && Port == MAC_2) {
++
++              /* clear GMAC 1 Control reset */
++              SK_OUT8(IoC, MR_ADDR(MAC_1, GMAC_CTRL), (SK_U8)GMC_RST_CLR);
++
++              do {
++                      /* set GMAC 2 Control reset */
++                      SK_OUT8(IoC, MR_ADDR(MAC_2, GMAC_CTRL), (SK_U8)GMC_RST_SET);
++
++                      /* clear GMAC 2 Control reset */
++                      SK_OUT8(IoC, MR_ADDR(MAC_2, GMAC_CTRL), (SK_U8)GMC_RST_CLR);
++
++                      SkGmPhyRead(pAC, IoC, MAC_2, PHY_MARV_ID0, &PhyId0);
++
++                      SkGmPhyRead(pAC, IoC, MAC_2, PHY_MARV_ID1, &PhyId1);
++
++                      SkGmPhyRead(pAC, IoC, MAC_2, PHY_MARV_INT_MASK, &Word);
++
++              } while (Word != 0 || PhyId0 != PHY_MARV_ID0_VAL ||
++                               PhyId1 != PHY_MARV_ID1_Y2);
++      }
+ #ifdef VCPU
+       VCpuWait(2000);
+-      
++
+       SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord);
+-                      
++
+       SK_IN32(IoC, B0_ISRC, &DWord);
+ #endif /* VCPU */
+@@ -1162,37 +1226,33 @@
+  *    nothing
+  */
+ void SkMacSoftRst(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
+-      SK_GEPORT       *pPrt;
+-
+-      pPrt = &pAC->GIni.GP[Port];
+-
+       /* disable receiver and transmitter */
+       SkMacRxTxDisable(pAC, IoC, Port);
+ #ifdef GENESIS
+       if (pAC->GIni.GIGenesis) {
+-              
++
+               SkXmSoftRst(pAC, IoC, Port);
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+-              
++
+               SkGmSoftRst(pAC, IoC, Port);
+       }
+ #endif /* YUKON */
+       /* flush the MAC's Rx and Tx FIFOs */
+       SkMacFlushTxFifo(pAC, IoC, Port);
+-      
++
+       SkMacFlushRxFifo(pAC, IoC, Port);
+-      pPrt->PState = SK_PRT_STOP;
++      pAC->GIni.GP[Port].PState = SK_PRT_STOP;
+ }     /* SkMacSoftRst */
+@@ -1207,25 +1267,27 @@
+  *    nothing
+  */
+ void SkMacHardRst(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
+-      
++
+ #ifdef GENESIS
+       if (pAC->GIni.GIGenesis) {
+-              
++
+               SkXmHardRst(pAC, IoC, Port);
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+-              
++
+               SkGmHardRst(pAC, IoC, Port);
+       }
+ #endif /* YUKON */
++      pAC->GIni.GP[Port].PHWLinkUp = SK_FALSE;
++
+       pAC->GIni.GP[Port].PState = SK_PRT_RESET;
+ }     /* SkMacHardRst */
+@@ -1241,21 +1303,21 @@
+  *    nothing
+  */
+ void SkMacClearRst(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
+-      
++
+ #ifdef GENESIS
+       if (pAC->GIni.GIGenesis) {
+-              
++
+               SkXmClearRst(pAC, IoC, Port);
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+-              
++
+               SkGmClearRst(pAC, IoC, Port);
+       }
+ #endif /* YUKON */
+@@ -1279,8 +1341,8 @@
+  *    nothing
+  */
+ void SkXmInitMac(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+@@ -1290,13 +1352,13 @@
+       pPrt = &pAC->GIni.GP[Port];
+       if (pPrt->PState == SK_PRT_STOP) {
+-              /* Port State: SK_PRT_STOP */
+               /* Verify that the reset bit is cleared */
+               SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
+               if ((SWord & MFF_SET_MAC_RST) != 0) {
+                       /* PState does not match HW state */
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++                              ("SkXmInitMac: PState does not match HW state"));
+                       /* Correct it */
+                       pPrt->PState = SK_PRT_RESET;
+               }
+@@ -1315,7 +1377,7 @@
+                        * Must be done AFTER first access to BCOM chip.
+                        */
+                       XM_IN16(IoC, Port, XM_MMU_CMD, &SWord);
+-                      
++
+                       XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE);
+                       if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) {
+@@ -1348,7 +1410,7 @@
+                        * Disable Power Management after reset.
+                        */
+                       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
+-                      
++
+                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
+                               (SK_U16)(SWord | PHY_B_AC_DIS_PM));
+@@ -1357,7 +1419,7 @@
+               /* Dummy read the Interrupt source register */
+               XM_IN16(IoC, Port, XM_ISRC, &SWord);
+-              
++
+               /*
+                * The auto-negotiation process starts immediately after
+                * clearing the reset. The auto-negotiation process should be
+@@ -1383,7 +1445,7 @@
+                * independent. Remember this when changing.
+                */
+               SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
+-              
++
+               XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord);
+       }
+@@ -1401,7 +1463,7 @@
+       SWord = SK_XM_THR_SL;                           /* for single port */
+       if (pAC->GIni.GIMacsFound > 1) {
+-              switch (pAC->GIni.GIPortUsage) {
++              switch (pPrt->PPortUsage) {
+               case SK_RED_LINK:
+                       SWord = SK_XM_THR_REDL;         /* redundant link */
+                       break;
+@@ -1424,7 +1486,7 @@
+       /* setup register defaults for the Rx Command Register */
+       SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK;
+-      if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
++      if (pPrt->PPortUsage == SK_JUMBO_LINK) {
+               SWord |= XM_RX_BIG_PK_OK;
+       }
+@@ -1436,7 +1498,7 @@
+                */
+               SWord |= XM_RX_DIS_CEXT;
+       }
+-      
++
+       XM_OUT16(IoC, Port, XM_RX_CMD, SWord);
+       /*
+@@ -1493,8 +1555,8 @@
+  *    nothing
+  */
+ void SkGmInitMac(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+@@ -1505,24 +1567,29 @@
+       pPrt = &pAC->GIni.GP[Port];
+       if (pPrt->PState == SK_PRT_STOP) {
+-              /* Port State: SK_PRT_STOP */
+               /* Verify that the reset bit is cleared */
+               SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord);
+-              
++
+               if ((DWord & GMC_RST_SET) != 0) {
+                       /* PState does not match HW state */
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                              ("SkGmInitMac: PState does not match HW state"));
+                       /* Correct it */
+                       pPrt->PState = SK_PRT_RESET;
+               }
++              else {
++                      /* enable all PHY interrupts */
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK,
++                              (SK_U16)PHY_M_DEF_MSK);
++              }
+       }
+       if (pPrt->PState == SK_PRT_RESET) {
+-              
++
+               SkGmHardRst(pAC, IoC, Port);
+               SkGmClearRst(pAC, IoC, Port);
+-              
++
+               /* Auto-negotiation ? */
+               if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+                       /* Auto-negotiation disabled */
+@@ -1532,10 +1599,10 @@
+                       /* disable auto-update for speed, duplex and flow-control */
+                       SWord |= GM_GPCR_AU_ALL_DIS;
+-                      
++
+                       /* setup General Purpose Control Register */
+                       GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
+-                      
++
+                       SWord = GM_GPCR_AU_ALL_DIS;
+               }
+               else {
+@@ -1546,7 +1613,10 @@
+               switch (pPrt->PLinkSpeed) {
+               case SK_LSPEED_AUTO:
+               case SK_LSPEED_1000MBPS:
+-                      SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100;
++                      if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) {
++
++                              SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100;
++                      }
+                       break;
+               case SK_LSPEED_100MBPS:
+                       SWord |= GM_GPCR_SPEED_100;
+@@ -1564,8 +1634,6 @@
+               /* flow-control settings */
+               switch (pPrt->PFlowCtrlMode) {
+               case SK_FLOW_MODE_NONE:
+-                      /* set Pause Off */
+-                      SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_OFF);
+                       /* disable Tx & Rx flow-control */
+                       SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
+                       break;
+@@ -1583,24 +1651,25 @@
+               GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
+               /* dummy read the Interrupt Source Register */
+-              SK_IN16(IoC, GMAC_IRQ_SRC, &SWord);
+-              
++              SK_IN16(IoC, MR_ADDR(Port, GMAC_IRQ_SRC), &SWord);
++
+ #ifndef VCPU
+               /* read Id from PHY */
+               SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1);
+-              
++
+               SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
+-#endif /* VCPU */
++#endif /* !VCPU */
+       }
+       (void)SkGmResetCounter(pAC, IoC, Port);
+       /* setup Transmit Control Register */
+-      GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres));
++      GM_OUT16(IoC, Port, GM_TX_CTRL, (SK_U16)TX_COL_THR(pPrt->PMacColThres));
+       /* setup Receive Control Register */
+-      GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA |
+-              GM_RXCR_CRC_DIS);
++      SWord = GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA | GM_RXCR_CRC_DIS;
++
++      GM_OUT16(IoC, Port, GM_RX_CTRL, SWord);
+       /* setup Transmit Flow Control Register */
+       GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff);
+@@ -1610,31 +1679,29 @@
+       GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);
+ #endif /* VCPU */
+-    SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) |
+-                      TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) |
+-                      TX_IPG_JAM_DATA(pPrt->PMacJamIpgData);
+-      
++      SWord = (SK_U16)(TX_JAM_LEN_VAL(pPrt->PMacJamLen) |
++              TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) |
++              TX_IPG_JAM_DATA(pPrt->PMacJamIpgData) |
++              TX_BACK_OFF_LIM(pPrt->PMacBackOffLim));
++
+       GM_OUT16(IoC, Port, GM_TX_PARAM, SWord);
+       /* configure the Serial Mode Register */
+-#ifdef VCPU
+-      GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);
+-#endif /* VCPU */
+-      
+-      SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData);
++      SWord = (SK_U16)(DATA_BLIND_VAL(pPrt->PMacDataBlind) |
++              GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData));
+       if (pPrt->PMacLimit4) {
+               /* reset of collision counter after 4 consecutive collisions */
+               SWord |= GM_SMOD_LIMIT_4;
+       }
+-      if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
++      if (pPrt->PPortUsage == SK_JUMBO_LINK) {
+               /* enable jumbo mode (Max. Frame Length = 9018) */
+               SWord |= GM_SMOD_JUMBO_ENA;
+       }
+-      
++
+       GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord);
+-      
++
+       /*
+        * configure the GMACs Station Addresses
+        * in PROM you can find our addresses at:
+@@ -1663,15 +1730,15 @@
+               else {
+                       GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
+               }
+-#else         
++#else
+               GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
+ #endif /* WA_DEV_16 */
+-              
++
+               /* virtual address: will be used for data */
+               SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord);
+               GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord);
+-              
++
+               /* reset Multicast filtering Hash registers 1-3 */
+               GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0);
+       }
+@@ -1684,18 +1751,6 @@
+       GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);
+       GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);
+-#if defined(SK_DIAG) || defined(DEBUG)
+-      /* read General Purpose Status */
+-      GM_IN16(IoC, Port, GM_GP_STAT, &SWord);
+-      
+-      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-              ("MAC Stat Reg.=0x%04X\n", SWord));
+-#endif /* SK_DIAG || DEBUG */
+-
+-#ifdef SK_DIAG
+-      c_print("MAC Stat Reg=0x%04X\n", SWord);
+-#endif /* SK_DIAG */
+-
+ }     /* SkGmInitMac */
+ #endif /* YUKON */
+@@ -1714,8 +1769,8 @@
+  *    nothing
+  */
+ void SkXmInitDupMd(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       switch (pAC->GIni.GP[Port].PLinkModeStatus) {
+@@ -1762,8 +1817,8 @@
+  *    nothing
+  */
+ void SkXmInitPauseMd(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+@@ -1773,11 +1828,11 @@
+       pPrt = &pAC->GIni.GP[Port];
+       XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
+-      
++
+       if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE ||
+               pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
+-              /* Disable Pause Frame Reception */
++              /* disable Pause Frame Reception */
+               Word |= XM_MMU_IGN_PF;
+       }
+       else {
+@@ -1785,10 +1840,10 @@
+                * enabling pause frame reception is required for 1000BT
+                * because the XMAC is not reset if the link is going down
+                */
+-              /* Enable Pause Frame Reception */
++              /* enable Pause Frame Reception */
+               Word &= ~XM_MMU_IGN_PF;
+-      }       
+-      
++      }
++
+       XM_OUT16(IoC, Port, XM_MMU_CMD, Word);
+       XM_IN32(IoC, Port, XM_MODE, &DWord);
+@@ -1811,10 +1866,10 @@
+               /* remember this value is defined in big endian (!) */
+               XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff);
+-              /* Set Pause Mode in Mode Register */
++              /* set Pause Mode in Mode Register */
+               DWord |= XM_PAUSE_MODE;
+-              /* Set Pause Mode in MAC Rx FIFO */
++              /* set Pause Mode in MAC Rx FIFO */
+               SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
+       }
+       else {
+@@ -1822,13 +1877,13 @@
+                * disable pause frame generation is required for 1000BT
+                * because the XMAC is not reset if the link is going down
+                */
+-              /* Disable Pause Mode in Mode Register */
++              /* disable Pause Mode in Mode Register */
+               DWord &= ~XM_PAUSE_MODE;
+-              /* Disable Pause Mode in MAC Rx FIFO */
++              /* disable Pause Mode in MAC Rx FIFO */
+               SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
+       }
+-      
++
+       XM_OUT32(IoC, Port, XM_MODE, DWord);
+ }     /* SkXmInitPauseMd*/
+@@ -1845,8 +1900,8 @@
+  *    nothing
+  */
+ static void SkXmInitPhyXmac(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ SK_BOOL       DoLoop)         /* Should a Phy LoopBack be set-up? */
+ {
+@@ -1855,12 +1910,12 @@
+       pPrt = &pAC->GIni.GP[Port];
+       Ctrl = 0;
+-      
++
+       /* Auto-negotiation ? */
+       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyXmac: no auto-negotiation Port %d\n", Port));
+-              /* Set DuplexMode in Config register */
++              /* set DuplexMode in Config register */
+               if (pPrt->PLinkMode == SK_LMODE_FULL) {
+                       Ctrl |= PHY_CT_DUP_MD;
+               }
+@@ -1873,9 +1928,9 @@
+       else {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyXmac: with auto-negotiation Port %d\n", Port));
+-              /* Set Auto-negotiation advertisement */
++              /* set Auto-negotiation advertisement */
+-              /* Set Full/half duplex capabilities */
++              /* set Full/half duplex capabilities */
+               switch (pPrt->PLinkMode) {
+               case SK_LMODE_AUTOHALF:
+                       Ctrl |= PHY_X_AN_HD;
+@@ -1891,7 +1946,7 @@
+                               SKERR_HWI_E015MSG);
+               }
+-              /* Set Flow-control capabilities */
++              /* set Flow-control capabilities */
+               switch (pPrt->PFlowCtrlMode) {
+               case SK_FLOW_MODE_NONE:
+                       Ctrl |= PHY_X_P_NO_PAUSE;
+@@ -1918,7 +1973,7 @@
+       }
+       if (DoLoop) {
+-              /* Set the Phy Loopback bit, too */
++              /* set the Phy Loopback bit, too */
+               Ctrl |= PHY_CT_LOOP;
+       }
+@@ -1939,8 +1994,8 @@
+  *    nothing
+  */
+ static void SkXmInitPhyBcom(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ SK_BOOL       DoLoop)         /* Should a Phy LoopBack be set-up? */
+ {
+@@ -1962,7 +2017,7 @@
+       /* manually Master/Slave ? */
+       if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
+               Ctrl2 |= PHY_B_1000C_MSE;
+-              
++
+               if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
+                       Ctrl2 |= PHY_B_1000C_MSC;
+               }
+@@ -1971,7 +2026,7 @@
+       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyBcom: no auto-negotiation Port %d\n", Port));
+-              /* Set DuplexMode in Config register */
++              /* set DuplexMode in Config register */
+               if (pPrt->PLinkMode == SK_LMODE_FULL) {
+                       Ctrl1 |= PHY_CT_DUP_MD;
+               }
+@@ -1989,7 +2044,7 @@
+       else {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyBcom: with auto-negotiation Port %d\n", Port));
+-              /* Set Auto-negotiation advertisement */
++              /* set Auto-negotiation advertisement */
+               /*
+                * Workaround BCOM Errata #1 for the C5 type.
+@@ -1997,8 +2052,8 @@
+                * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
+                */
+               Ctrl2 |= PHY_B_1000C_RD;
+-              
+-               /* Set Full/half duplex capabilities */
++
++               /* set Full/half duplex capabilities */
+               switch (pPrt->PLinkMode) {
+               case SK_LMODE_AUTOHALF:
+                       Ctrl2 |= PHY_B_1000C_AHD;
+@@ -2014,7 +2069,7 @@
+                               SKERR_HWI_E015MSG);
+               }
+-              /* Set Flow-control capabilities */
++              /* set Flow-control capabilities */
+               switch (pPrt->PFlowCtrlMode) {
+               case SK_FLOW_MODE_NONE:
+                       Ctrl3 |= PHY_B_P_NO_PAUSE;
+@@ -2036,27 +2091,27 @@
+               /* Restart Auto-negotiation */
+               Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
+       }
+-      
++
+       /* Initialize LED register here? */
+       /* No. Please do it in SkDgXmitLed() (if required) and swap
+-         init order of LEDs and XMAC. (MAl) */
+-      
++              init order of LEDs and XMAC. (MAl) */
++
+       /* Write 1000Base-T Control Register */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
+-      
++
+       /* Write AutoNeg Advertisement Register */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
+-      
++
+       if (DoLoop) {
+-              /* Set the Phy Loopback bit, too */
++              /* set the Phy Loopback bit, too */
+               Ctrl1 |= PHY_CT_LOOP;
+       }
+-      if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
++      if (pPrt->PPortUsage == SK_JUMBO_LINK) {
+               /* configure FIFO to high latency for transmission of ext. packets */
+               Ctrl4 |= PHY_B_PEC_HIGH_LA;
+@@ -2068,7 +2123,7 @@
+       /* Configure LED Traffic Mode and Jumbo Frame usage if specified */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4);
+-      
++
+       /* Write to the Phy control register */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+@@ -2078,17 +2133,17 @@
+ #ifdef YUKON
+-#ifndef SK_SLIM
++#ifdef SK_PHY_LP_MODE
+ /******************************************************************************
+  *
+  *    SkGmEnterLowPowerMode()
+  *
+- * Description:       
++ * Description:
+  *    This function sets the Marvell Alaska PHY to the low power mode
+  *    given by parameter mode.
+  *    The following low power modes are available:
+- *            
+- *            - Coma Mode (Deep Sleep):
++ *
++ *            - COMA Mode (Deep Sleep):
+  *                    Power consumption: ~15 - 30 mW
+  *                    The PHY cannot wake up on its own.
+  *
+@@ -2115,114 +2170,203 @@
+  *            1: error
+  */
+ int SkGmEnterLowPowerMode(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (e.g. MAC_1) */
+ SK_U8 Mode)           /* low power mode */
+ {
++      SK_U8   LastMode;
++      SK_U8   Byte;
+       SK_U16  Word;
++      SK_U16  ClkDiv;
+       SK_U32  DWord;
+-      SK_U8   LastMode;
++      SK_U32  PowerDownBit;
+       int             Ret = 0;
+-      if (pAC->GIni.GIYukonLite &&
+-          pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
++      if (!(CHIP_ID_YUKON_2(pAC) || (pAC->GIni.GIYukonLite &&
++              pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3))) {
+-              /* save current power mode */
+-              LastMode = pAC->GIni.GP[Port].PPhyPowerState;
+-              pAC->GIni.GP[Port].PPhyPowerState = Mode;
+-
+-              switch (Mode) {
+-                      /* coma mode (deep sleep) */
+-                      case PHY_PM_DEEP_SLEEP:
+-                              /* setup General Purpose Control Register */
+-                              GM_OUT16(IoC, 0, GM_GP_CTRL, GM_GPCR_FL_PASS |
+-                                      GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS);
+-
+-                              /* apply COMA mode workaround */
+-                              SkGmPhyWrite(pAC, IoC, Port, 29, 0x001f);
+-                              SkGmPhyWrite(pAC, IoC, Port, 30, 0xfff3);
+-
+-                              SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord);
+-
+-                              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+-                              
+-                              /* Set PHY to Coma Mode */
+-                              SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord | PCI_PHY_COMA);
+-                              
+-                              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+-
+-                      break;
+-                      
+-                      /* IEEE 22.2.4.1.5 compatible power down mode */
+-                      case PHY_PM_IEEE_POWER_DOWN:
+-                              /*
+-                               * - disable MAC 125 MHz clock
+-                               * - allow MAC power down
+-                               */
+-                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+-                              Word |= PHY_M_PC_DIS_125CLK;
+-                              Word &= ~PHY_M_PC_MAC_POW_UP;
+-                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
++              return(1);
++      }
+-                              /*
+-                               * register changes must be followed by a software
+-                               * reset to take effect
+-                               */
+-                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+-                              Word |= PHY_CT_RESET;
+-                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+-
+-                              /* switch IEEE compatible power down mode on */
+-                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+-                              Word |= PHY_CT_PDOWN;
+-                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+-                      break;
++      /* save current power mode */
++      LastMode = pAC->GIni.GP[Port].PPhyPowerState;
++      pAC->GIni.GP[Port].PPhyPowerState = Mode;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_POWM, SK_DBGCAT_CTRL,
++              ("SkGmEnterLowPowerMode: %u\n", Mode));
++
++      switch (Mode) {
++      /* COMA mode (deep sleep) */
++      case PHY_PM_DEEP_SLEEP:
++              /* clear PHY & MAC reset first */
++              SkGmClearRst(pAC, IoC, Port);
+-                      /* energy detect and energy detect plus mode */
+-                      case PHY_PM_ENERGY_DETECT:
+-                      case PHY_PM_ENERGY_DETECT_PLUS:
+-                              /*
+-                               * - disable MAC 125 MHz clock
+-                               */
+-                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+-                              Word |= PHY_M_PC_DIS_125CLK;
+-                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+-                              
+-                              /* activate energy detect mode 1 */
+-                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+-
+-                              /* energy detect mode */
+-                              if (Mode == PHY_PM_ENERGY_DETECT) {
+-                                      Word |= PHY_M_PC_EN_DET;
+-                              }
+-                              /* energy detect plus mode */
+-                              else {
+-                                      Word |= PHY_M_PC_EN_DET_PLUS;
++              /* setup General Purpose Control Register */
++              GM_OUT16(IoC, Port, GM_GP_CTRL, GM_GPCR_FL_PASS |
++                      GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS);
++
++              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
++
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      /* set power down bit */
++                      PowerDownBit = (Port == MAC_1) ? PCI_Y2_PHY1_POWD :
++                              PCI_Y2_PHY2_POWD;
++
++                      /* no COMA mode on Yukon-FE and Yukon-2 PHY */
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE ||
++                              pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) {
++
++                              /* set IEEE compatible Power Down Mode */
++                              Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PHY_CT_PDOWN);
++
++                              ClkDiv = 0;     /* divide clock by 2 */
++                      }
++                      else {
++                              ClkDiv = 1;     /* divide clock by 4 */
++                      }
++              }
++              else {
++                      /* apply COMA mode workaround */
++                      (void)SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_ADDR, 0x001f);
++
++                      Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xfff3);
++
++                      PowerDownBit = PCI_PHY_COMA;
++              }
++
++              SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord);
++
++              /* set PHY to PowerDown/COMA Mode */
++              SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord | PowerDownBit);
++
++              /* check if this routine was called from a for() loop */
++              if (pAC->GIni.GIMacsFound == 1 || Port == MAC_2) {
++
++                      /* ASF system clock stopped */
++                      SK_OUT8(IoC, B28_Y2_ASF_STAT_CMD, Y2_ASF_CLK_HALT);
++
++                      if (HW_FEATURE(pAC, HWF_RED_CORE_CLK_SUP)) {
++                              /* on Yukon-2 clock select value is 31 */
++                              DWord = (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) ?
++                                      (Y2_CLK_DIV_VAL_2(0) | Y2_CLK_SEL_VAL_2(31)) :
++                                       Y2_CLK_DIV_VAL(ClkDiv);
++
++                              /* check for Yukon-2 dual port PCI-Express adapter */
++                              if (!(pAC->GIni.GIMacsFound == 2 &&
++                                        pAC->GIni.GIPciBus == SK_PEX_BUS)) {
++                                      /* enable Core Clock Division */
++                                      DWord |= Y2_CLK_DIV_ENA;
+                               }
+-                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
++                              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                                      ("Set Core Clock: 0x%08X\n", DWord));
+-                              /*
+-                               * reinitialize the PHY to force a software reset
+-                               * which is necessary after the register settings
+-                               * for the energy detect modes.
+-                               * Furthermore reinitialisation prevents that the
+-                               * PHY is running out of a stable state.
+-                               */
+-                              SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
+-                      break;
++                              /* reduce Core Clock Frequency */
++                              SK_OUT32(IoC, B2_Y2_CLK_CTRL, DWord);
++                      }
+-                      /* don't change current power mode */
+-                      default:
+-                              pAC->GIni.GP[Port].PPhyPowerState = LastMode;
+-                              Ret = 1;
+-                      break;
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL &&
++                              pAC->GIni.GIChipRev > 1) {
++                              /* enable bits are inverted */
++                              Byte = 0;
++                      }
++                      else {
++                              Byte = (SK_U8)(Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
++                                      Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
++                                      Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
++                      }
++
++                      /* disable PCI & Core Clock, disable clock gating for both Links */
++                      SK_OUT8(IoC, B2_Y2_CLK_GATE, Byte);
++
++                      if (pAC->GIni.GIVauxAvail) {
++                              /* switch power to VAUX */
++                              SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA |
++                                      PC_VAUX_ON | PC_VCC_OFF));
++                      }
++#ifdef DEBUG
++                      SK_IN32(IoC, B0_CTST, &DWord);
++
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                              ("Ctrl/Stat & Switch: 0x%08x\n", DWord));
++#endif /* DEBUG */
++
++                      if (pAC->GIni.GIMacsFound == 1 &&
++                              pAC->GIni.GIPciBus == SK_PEX_BUS) {
++
++                              /* switch to D1 state */
++                              SK_OUT8(IoC, PCI_C(pAC, PCI_PM_CTL_STS), PCI_PM_STATE_D1);
++                      }
+               }
+-      }
+-      /* low power modes are not supported by this chip */
+-      else {
++
++              break;
++
++      /* IEEE 22.2.4.1.5 compatible power down mode */
++      case PHY_PM_IEEE_POWER_DOWN:
++
++              Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
++
++              Word |= PHY_M_PC_POL_R_DIS;
++
++              if (!CHIP_ID_YUKON_2(pAC)) {
++                      /* disable MAC 125 MHz clock */
++                      Word |= PHY_M_PC_DIS_125CLK;
++                      Word &= ~PHY_M_PC_MAC_POW_UP;
++              }
++              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
++
++              /* these register changes must be followed by a software reset */
++              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
++              Word |= PHY_CT_RESET;
++              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
++
++              /* switch IEEE compatible power down mode on */
++              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
++              Word |= PHY_CT_PDOWN;
++              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
++
++              break;
++
++      /* energy detect and energy detect plus mode */
++      case PHY_PM_ENERGY_DETECT:
++      case PHY_PM_ENERGY_DETECT_PLUS:
++
++              Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
++
++              Word |= PHY_M_PC_POL_R_DIS;
++
++              if (!CHIP_ID_YUKON_2(pAC)) {
++                      /* disable MAC 125 MHz clock */
++                      Word |= PHY_M_PC_DIS_125CLK;
++              }
++
++              if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
++                      /* enable Energy Detect (sense & pulse) */
++                      Word |= PHY_M_PC_ENA_ENE_DT;
++              }
++              else {
++                      /* clear energy detect mode bits */
++                      Word &= ~PHY_M_PC_EN_DET_MSK;
++
++                      Word |= (Mode == PHY_PM_ENERGY_DETECT) ? PHY_M_PC_EN_DET :
++                              PHY_M_PC_EN_DET_PLUS;
++              }
++
++              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
++
++              /* these register changes must be followed by a software reset */
++              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
++              Word |= PHY_CT_RESET;
++              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
++
++              break;
++
++      /* don't change current power mode */
++      default:
++              pAC->GIni.GP[Port].PPhyPowerState = LastMode;
+               Ret = 1;
++              break;
+       }
+       return(Ret);
+@@ -2233,7 +2377,7 @@
+  *
+  *    SkGmLeaveLowPowerMode()
+  *
+- * Description:       
++ * Description:
+  *    Leave the current low power mode and switch to normal mode
+  *
+  * Note:
+@@ -2243,115 +2387,146 @@
+  *            1:      error
+  */
+ int SkGmLeaveLowPowerMode(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (e.g. MAC_1) */
+ {
+       SK_U32  DWord;
++      SK_U32  PowerDownBit;
+       SK_U16  Word;
+       SK_U8   LastMode;
+       int             Ret = 0;
+-      if (pAC->GIni.GIYukonLite &&
+-              pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
++      if (!(CHIP_ID_YUKON_2(pAC) || (pAC->GIni.GIYukonLite &&
++              pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3))) {
+-              /* save current power mode */
+-              LastMode = pAC->GIni.GP[Port].PPhyPowerState;
+-              pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
+-
+-              switch (LastMode) {
+-                      /* coma mode (deep sleep) */
+-                      case PHY_PM_DEEP_SLEEP:
+-                              SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord);
+-
+-                              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+-                              
+-                              /* Release PHY from Coma Mode */
+-                              SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord & ~PCI_PHY_COMA);
+-                              
+-                              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+-                              
+-                              SK_IN32(IoC, B2_GP_IO, &DWord);
+-
+-                              /* set to output */
+-                              DWord |= (GP_DIR_9 | GP_IO_9);
+-
+-                              /* set PHY reset */
+-                              SK_OUT32(IoC, B2_GP_IO, DWord);
+-
+-                              DWord &= ~GP_IO_9; /* clear PHY reset (active high) */
+-
+-                              /* clear PHY reset */
+-                              SK_OUT32(IoC, B2_GP_IO, DWord);
+-                      break;
+-                      
+-                      /* IEEE 22.2.4.1.5 compatible power down mode */
+-                      case PHY_PM_IEEE_POWER_DOWN:
+-                              /*
+-                               * - enable MAC 125 MHz clock
+-                               * - set MAC power up
+-                               */
+-                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+-                              Word &= ~PHY_M_PC_DIS_125CLK;
+-                              Word |= PHY_M_PC_MAC_POW_UP;
+-                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
++              return(1);
++      }
+-                              /*
+-                               * register changes must be followed by a software
+-                               * reset to take effect
+-                               */
+-                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+-                              Word |= PHY_CT_RESET;
+-                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+-
+-                              /* switch IEEE compatible power down mode off */
+-                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+-                              Word &= ~PHY_CT_PDOWN;
+-                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+-                      break;
++      /* save current power mode */
++      LastMode = pAC->GIni.GP[Port].PPhyPowerState;
++      pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
+-                      /* energy detect and energy detect plus mode */
+-                      case PHY_PM_ENERGY_DETECT:
+-                      case PHY_PM_ENERGY_DETECT_PLUS:
+-                              /*
+-                               * - enable MAC 125 MHz clock
+-                               */
+-                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+-                              Word &= ~PHY_M_PC_DIS_125CLK;
+-                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+-                              
+-                              /* disable energy detect mode */
+-                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+-                              Word &= ~PHY_M_PC_EN_DET_MSK;
+-                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
++      SK_DBG_MSG(pAC, SK_DBGMOD_POWM, SK_DBGCAT_CTRL,
++              ("SkGmLeaveLowPowerMode: %u\n", LastMode));
+-                              /*
+-                               * reinitialize the PHY to force a software reset
+-                               * which is necessary after the register settings
+-                               * for the energy detect modes.
+-                               * Furthermore reinitialisation prevents that the
+-                               * PHY is running out of a stable state.
+-                               */
+-                              SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
+-                      break;
++      switch (LastMode) {
++      /* COMA mode (deep sleep) */
++      case PHY_PM_DEEP_SLEEP:
+-                      /* don't change current power mode */
+-                      default:
+-                              pAC->GIni.GP[Port].PPhyPowerState = LastMode;
+-                              Ret = 1;
+-                      break;
++              SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &Word);
++
++              /* reset all DState bits */
++              Word &= ~(PCI_PM_STATE_MSK);
++
++              /* switch to D0 state */
++              SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, Word);
++
++              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
++
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      /* disable Core Clock Division */
++                      SK_OUT32(IoC, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS);
++
++                      /* set power down bit */
++                      PowerDownBit = (Port == MAC_1) ? PCI_Y2_PHY1_POWD :
++                              PCI_Y2_PHY2_POWD;
+               }
+-      }
+-      /* low power modes are not supported by this chip */
+-      else {
++              else {
++                      PowerDownBit = PCI_PHY_COMA;
++              }
++
++              SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord);
++
++              /* Release PHY from PowerDown/COMA Mode */
++              SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord & ~PowerDownBit);
++
++              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
++
++              if (CHIP_ID_YUKON_2(pAC)) {
++                      /* no COMA mode on Yukon-FE */
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
++                              /* release IEEE compatible Power Down Mode */
++                              Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PHY_CT_ANE);
++                      }
++              }
++              else {
++                      SK_IN32(IoC, B2_GP_IO, &DWord);
++
++                      /* set to output */
++                      DWord |= (GP_DIR_9 | GP_IO_9);
++
++                      /* set PHY reset */
++                      SK_OUT32(IoC, B2_GP_IO, DWord);
++
++                      DWord &= ~GP_IO_9; /* clear PHY reset (active high) */
++
++                      /* clear PHY reset */
++                      SK_OUT32(IoC, B2_GP_IO, DWord);
++              }
++
++              break;
++
++      /* IEEE 22.2.4.1.5 compatible power down mode */
++      case PHY_PM_IEEE_POWER_DOWN:
++
++              if (pAC->GIni.GIChipId != CHIP_ID_YUKON_XL) {
++
++                      Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
++                      Word &= ~PHY_M_PC_DIS_125CLK;   /* enable MAC 125 MHz clock */
++                      Word |= PHY_M_PC_MAC_POW_UP;    /* set MAC power up */
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
++
++                      /* these register changes must be followed by a software reset */
++                      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
++                      Word |= PHY_CT_RESET;
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
++              }
++
++              /* switch IEEE compatible power down mode off */
++              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
++              Word &= ~PHY_CT_PDOWN;
++              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
++
++              break;
++
++      /* energy detect and energy detect plus mode */
++      case PHY_PM_ENERGY_DETECT:
++      case PHY_PM_ENERGY_DETECT_PLUS:
++
++              if (pAC->GIni.GIChipId != CHIP_ID_YUKON_XL) {
++
++                      Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
++
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
++                              /* disable Energy Detect */
++                              Word &= ~PHY_M_PC_ENA_ENE_DT;
++                      }
++                      else {
++                              /* disable energy detect mode & enable MAC 125 MHz clock */
++                              Word &= ~(PHY_M_PC_EN_DET_MSK | PHY_M_PC_DIS_125CLK);
++                      }
++
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
++
++                      /* these register changes must be followed by a software reset */
++                      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
++                      Word |= PHY_CT_RESET;
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
++              }
++              break;
++
++      /* don't change current power mode */
++      default:
++              pAC->GIni.GP[Port].PPhyPowerState = LastMode;
+               Ret = 1;
++              break;
+       }
+       return(Ret);
+ }     /* SkGmLeaveLowPowerMode */
+-#endif /* !SK_SLIM */
+-
++#endif /* SK_PHY_LP_MODE */
+ /******************************************************************************
+  *
+@@ -2365,74 +2540,168 @@
+  *    nothing
+  */
+ static void SkGmInitPhyMarv(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ SK_BOOL       DoLoop)         /* Should a Phy LoopBack be set-up? */
+ {
+       SK_GEPORT       *pPrt;
++      SK_BOOL         AutoNeg;
+       SK_U16          PhyCtrl;
+       SK_U16          C1000BaseT;
+       SK_U16          AutoNegAdv;
++      SK_U8           PauseMode;
++#ifndef VCPU
++      SK_U16          SWord;
++      SK_U16          PageReg;
++      SK_U16          LoopSpeed;
+       SK_U16          ExtPhyCtrl;
+       SK_U16          LedCtrl;
+-      SK_BOOL         AutoNeg;
++      SK_U16          LedOver;
+ #if defined(SK_DIAG) || defined(DEBUG)
+       SK_U16          PhyStat;
+       SK_U16          PhyStat1;
+       SK_U16          PhySpecStat;
+ #endif /* SK_DIAG || DEBUG */
++#endif /* !VCPU */
++
++      /* set Pause On */
++      PauseMode = (SK_U8)GMC_PAUSE_ON;
+       pPrt = &pAC->GIni.GP[Port];
+       /* Auto-negotiation ? */
+-      if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+-              AutoNeg = SK_FALSE;
+-      }
+-      else {
+-              AutoNeg = SK_TRUE;
+-      }
+-      
++      AutoNeg = pPrt->PLinkMode != SK_LMODE_HALF &&
++                        pPrt->PLinkMode != SK_LMODE_FULL;
++
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-              ("InitPhyMarv: Port %d, auto-negotiation %s\n",
+-               Port, AutoNeg ? "ON" : "OFF"));
++              ("InitPhyMarv: Port %d, Auto-neg. %s, LMode %d, LSpeed %d, FlowC %d\n",
++               Port, AutoNeg ? "ON" : "OFF",
++               pPrt->PLinkMode, pPrt->PLinkSpeed, pPrt->PFlowCtrlMode));
+-#ifdef VCPU
+-      VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n",
+-              Port, DoLoop);
+-#else /* VCPU */
+-      if (DoLoop) {
+-              /* Set 'MAC Power up'-bit, set Manual MDI configuration */
+-              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
+-                      PHY_M_PC_MAC_POW_UP);
++#ifndef VCPU
++      if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) {
++
++              if (DoLoop) {
++                      /* special setup for PHY 88E1112 */
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) {
++
++                              LoopSpeed = pPrt->PLinkSpeed;
++
++                              if (LoopSpeed == SK_LSPEED_AUTO) {
++                                      /* force 1000 Mbps */
++                                      LoopSpeed = SK_LSPEED_1000MBPS;
++                              }
++                              LoopSpeed += 2;
++
++                              /* save page register */
++                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_ADR, &PageReg);
++
++                              /* select page 2 to access MAC control register */
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 2);
++
++                              /* set MAC interface speed */
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, LoopSpeed << 4);
++
++                              /* restore page register */
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, PageReg);
++
++                              /* disable link pulses */
++                              SWord = PHY_M_PC_DIS_LINK_P;
++                      }
++                      else {
++                              /* set 'MAC Power up'-bit, set Manual MDI configuration */
++                              SWord = PHY_M_PC_MAC_POW_UP;
++                      }
++
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, SWord);
++              }
++              else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO &&
++                               pAC->GIni.GIChipId != CHIP_ID_YUKON_XL) {
++                      /* Read Ext. PHY Specific Control */
++                      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
++
++                      ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
++                              PHY_M_EC_MAC_S_MSK);
++
++                      ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
++
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) {
++                              /* on PHY 88E1111 there is a change for downshift control */
++                              ExtPhyCtrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA;
++                      }
++                      else {
++                              ExtPhyCtrl |= PHY_M_EC_M_DSC(2) | PHY_M_EC_S_DSC(3);
++                      }
++
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                              ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
++              }
+       }
+-      else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) {
+-              /* Read Ext. PHY Specific Control */
+-              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
+-              
+-              ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
+-                      PHY_M_EC_MAC_S_MSK);
+-              
+-              ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) |
+-                      PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
+-      
+-              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                      ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
++
++      if (CHIP_ID_YUKON_2(pAC)) {
++              /* Read PHY Specific Control */
++              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &PhyCtrl);
++
++              if (!DoLoop && pAC->GIni.GICopperType) {
++
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
++                              /* enable Automatic Crossover (!!! Bits 5..4) */
++                              PhyCtrl |= (SK_U16)(PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1);
++                      }
++                      else {
++                              /* disable Energy Detect Mode */
++                              PhyCtrl &= ~PHY_M_PC_EN_DET_MSK;
++
++                              /* enable Automatic Crossover */
++                              PhyCtrl |= (SK_U16)PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
++
++                              if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO &&
++                                      pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) {
++                                      /* on PHY 88E1112 there is a change for downshift control */
++                                      PhyCtrl &= ~PHY_M_PC_DSC_MSK;
++                                      PhyCtrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
++                              }
++                      }
++              }
++              /* workaround for deviation #4.88 (CRC errors) */
++              else {
++                      /* disable Automatic Crossover */
++                      PhyCtrl &= ~PHY_M_PC_MDIX_MSK;
++              }
++
++              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PhyCtrl);
++      }
++
++      /* special setup for PHY 88E1112 Fiber */
++      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL && !pAC->GIni.GICopperType) {
++              /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */
++              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 2);
++
++              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &SWord);
++
++              SWord &= ~PHY_M_MAC_MD_MSK;
++              SWord |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX);
++
++              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, SWord);
++
++              /* select page 1 to access Fiber registers */
++              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 1);
+       }
+       /* Read PHY Control */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
+       if (!AutoNeg) {
+-              /* Disable Auto-negotiation */
++              /* disable Auto-negotiation */
+               PhyCtrl &= ~PHY_CT_ANE;
+       }
+       PhyCtrl |= PHY_CT_RESET;
+-      /* Assert software reset */
++      /* assert software reset */
+       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
+-#endif /* VCPU */
++#endif /* !VCPU */
+       PhyCtrl = 0 /* PHY_CT_COL_TST */;
+       C1000BaseT = 0;
+@@ -2442,30 +2711,31 @@
+       if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
+               /* enable Manual Master/Slave */
+               C1000BaseT |= PHY_M_1000C_MSE;
+-              
++
+               if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
+                       C1000BaseT |= PHY_M_1000C_MSC;  /* set it to Master */
+               }
+       }
+-      
++
+       /* Auto-negotiation ? */
+       if (!AutoNeg) {
+-              
++
+               if (pPrt->PLinkMode == SK_LMODE_FULL) {
+-                      /* Set Full Duplex Mode */
++                      /* set Full Duplex Mode */
+                       PhyCtrl |= PHY_CT_DUP_MD;
+               }
+-              /* Set Master/Slave manually if not already done */
++              /* set Master/Slave manually if not already done */
+               if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
+                       C1000BaseT |= PHY_M_1000C_MSE;  /* set it to Slave */
+               }
+-              /* Set Speed */
++              /* set Speed */
+               switch (pPrt->PLinkSpeed) {
+               case SK_LSPEED_AUTO:
+               case SK_LSPEED_1000MBPS:
+-                      PhyCtrl |= PHY_CT_SP1000;
++                      PhyCtrl |= (((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) ?
++                                              PHY_CT_SP1000 : PHY_CT_SP100);
+                       break;
+               case SK_LSPEED_100MBPS:
+                       PhyCtrl |= PHY_CT_SP100;
+@@ -2477,38 +2747,65 @@
+                               SKERR_HWI_E019MSG);
+               }
++              if ((pPrt->PFlowCtrlMode == SK_FLOW_STAT_NONE) ||
++                      /* disable Pause also for 10/100 Mbps in half duplex mode */
++                      ((pPrt->PLinkMode == SK_LMODE_HALF) &&
++                       ((pPrt->PLinkSpeed == SK_LSPEED_STAT_100MBPS) ||
++                        (pPrt->PLinkSpeed == SK_LSPEED_STAT_10MBPS)))) {
++
++                      /* set Pause Off */
++                      PauseMode = (SK_U8)GMC_PAUSE_OFF;
++              }
++
++              SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), PauseMode);
++
+               if (!DoLoop) {
++                      /* assert software reset */
+                       PhyCtrl |= PHY_CT_RESET;
+               }
+       }
+       else {
+-              /* Set Auto-negotiation advertisement */
+-              
++              /* set Auto-negotiation advertisement */
++
+               if (pAC->GIni.GICopperType) {
+-                      /* Set Speed capabilities */
++                      /* set Speed capabilities */
+                       switch (pPrt->PLinkSpeed) {
+                       case SK_LSPEED_AUTO:
+-                              C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
++                              if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) {
++                                      C1000BaseT |= PHY_M_1000C_AFD;
++#ifdef xSK_DIAG
++                                      C1000BaseT |= PHY_M_1000C_AHD;
++#endif /* SK_DIAG */
++                              }
+                               AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
+                                       PHY_M_AN_10_FD | PHY_M_AN_10_HD;
+                               break;
+                       case SK_LSPEED_1000MBPS:
+-                              C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
++                              if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) {
++                                      C1000BaseT |= PHY_M_1000C_AFD;
++#ifdef xSK_DIAG
++                                      C1000BaseT |= PHY_M_1000C_AHD;
++#endif /* SK_DIAG */
++                              }
+                               break;
+                       case SK_LSPEED_100MBPS:
+-                              AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
+-                                      /* advertise 10Base-T also */
+-                                      PHY_M_AN_10_FD | PHY_M_AN_10_HD;
++                              if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_100MBPS) != 0) {
++                                      AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
++                                              /* advertise 10Base-T also */
++                                              PHY_M_AN_10_FD | PHY_M_AN_10_HD;
++                              }
+                               break;
+                       case SK_LSPEED_10MBPS:
+-                              AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD;
++                              if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_10MBPS) != 0) {
++                                      AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD;
++                              }
+                               break;
+                       default:
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
+                                       SKERR_HWI_E019MSG);
+                       }
+-                      /* Set Full/half duplex capabilities */
++                      /* set Full/half duplex capabilities */
+                       switch (pPrt->PLinkMode) {
+                       case SK_LMODE_AUTOHALF:
+                               C1000BaseT &= ~PHY_M_1000C_AFD;
+@@ -2524,8 +2821,8 @@
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
+                                       SKERR_HWI_E015MSG);
+                       }
+-                      
+-                      /* Set Flow-control capabilities */
++
++                      /* set Flow-control capabilities */
+                       switch (pPrt->PFlowCtrlMode) {
+                       case SK_FLOW_MODE_NONE:
+                               AutoNegAdv |= PHY_B_P_NO_PAUSE;
+@@ -2545,8 +2842,8 @@
+                       }
+               }
+               else {  /* special defines for FIBER (88E1011S only) */
+-                      
+-                      /* Set Full/half duplex capabilities */
++
++                      /* set Full/half duplex capabilities */
+                       switch (pPrt->PLinkMode) {
+                       case SK_LMODE_AUTOHALF:
+                               AutoNegAdv |= PHY_M_AN_1000X_AHD;
+@@ -2561,8 +2858,8 @@
+                               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
+                                       SKERR_HWI_E015MSG);
+                       }
+-                      
+-                      /* Set Flow-control capabilities */
++
++                      /* set Flow-control capabilities */
+                       switch (pPrt->PFlowCtrlMode) {
+                       case SK_FLOW_MODE_NONE:
+                               AutoNegAdv |= PHY_M_P_NO_PAUSE_X;
+@@ -2587,52 +2884,51 @@
+                       PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
+               }
+       }
+-      
++
+ #ifdef VCPU
+       /*
+        * E-mail from Gu Lin (08-03-2002):
+        */
+-      
++
+       /* Program PHY register 30 as 16'h0708 for simulation speed up */
+       SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */);
+-      
++
+       VCpuWait(2000);
+ #else /* VCPU */
+-      
+-      /* Write 1000Base-T Control Register */
+-      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
+-      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-              ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT));
+-      
++
++      if (pAC->GIni.GIChipId != CHIP_ID_YUKON_FE) {
++              /* Write 1000Base-T Control Register */
++              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                      ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT));
++      }
++
+       /* Write AutoNeg Advertisement Register */
+       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
+ #endif /* VCPU */
+-      
++
+       if (DoLoop) {
+-              /* Set the PHY Loopback bit */
++              /* set the PHY Loopback bit */
+               PhyCtrl |= PHY_CT_LOOP;
+ #ifdef XXX
+               /* Program PHY register 16 as 16'h0400 to force link good */
+               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD);
+-#endif /* XXX */
+-#ifndef VCPU
+               if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) {
+                       /* Write Ext. PHY Specific Control */
+                       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL,
+                               (SK_U16)((pPrt->PLinkSpeed + 2) << 4));
+               }
+-#endif /* VCPU */
++#endif /* XXX */
+       }
+ #ifdef TEST_ONLY
+       else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) {
+-                      /* Write PHY Specific Control */
+-                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
+-                              PHY_M_PC_EN_DET_MSK);
++              /* Write PHY Specific Control */
++              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_EN_DET_MSK);
+       }
+ #endif
+@@ -2645,27 +2941,83 @@
+       VCpuWait(2000);
+ #else
+-      LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS);
++      LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS);
++
++      LedOver = 0;
++
++      if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0)  {
++
++              if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
++                      /* on 88E3082 these bits are at 11..9 (shifted left) */
++                      LedCtrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1;
++
++                      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_FE_LED_PAR, &SWord);
+-      if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) {
+-              LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL;
++                      /* delete ACT LED control bits */
++                      SWord &= ~PHY_M_FELP_LED1_MSK;
++                      /* change ACT LED control to blink mode */
++                      SWord |= PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL);
++
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_FE_LED_PAR, SWord);
++              }
++              else if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) {
++                      /* save page register */
++                      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_ADR, &PageReg);
++
++                      /* select page 3 to access LED control register */
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 3);
++
++                      /* set LED Function Control register */
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, (SK_U16)
++                              (PHY_M_LEDC_LOS_CTRL(1) |               /* LINK/ACT */
++                               PHY_M_LEDC_INIT_CTRL(7) |              /* 10 Mbps */
++                               PHY_M_LEDC_STA1_CTRL(7) |              /* 100 Mbps */
++                               PHY_M_LEDC_STA0_CTRL(7)));             /* 1000 Mbps */
++
++                      /* set Polarity Control register */
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_STAT, (SK_U16)
++                              (PHY_M_POLC_LS1_P_MIX(4) | PHY_M_POLC_IS0_P_MIX(4) |
++                               PHY_M_POLC_LOS_CTRL(2) | PHY_M_POLC_INIT_CTRL(2) |
++                               PHY_M_POLC_STA1_CTRL(2) | PHY_M_POLC_STA0_CTRL(2)));
++
++                      /* restore page register */
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, PageReg);
++              }
++              else {
++                      /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
++                      LedCtrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
++
++                      /* on PHY 88E1111 there is a change for LED control */
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC &&
++                              (pAC->GIni.GILedBlinkCtrl & SK_DUAL_LED_ACT_LNK) != 0)  {
++                              /* Yukon-EC needs setting of 2 bits: 0,6=11) */
++                              LedCtrl |= PHY_M_LEDC_TX_C_LSB;
++                      }
++                      /* turn off the Rx LED (LED_RX) */
++                      LedOver |= PHY_M_LED_MO_RX(MO_LED_OFF);
++              }
+       }
+       if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) {
++              /* disable blink mode (LED_DUPLEX) on collisions */
+               LedCtrl |= PHY_M_LEDC_DP_CTRL;
+       }
+-      
++
+       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl);
+       if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) {
+               /* only in forced 100 Mbps mode */
+               if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) {
+-
+-                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER,
+-                              PHY_M_LED_MO_100(MO_LED_ON));
++                      /* turn on 100 Mbps LED (LED_LINK100) */
++                      LedOver |= PHY_M_LED_MO_100(MO_LED_ON);
+               }
+       }
++      if (LedOver != 0) {
++              /* set Manual LED Override */
++              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER, LedOver);
++      }
++
+ #ifdef SK_DIAG
+       c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl);
+       c_print("Set 1000 B-T=0x%04X\n", C1000BaseT);
+@@ -2678,30 +3030,33 @@
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
+-      
+-      /* Read 1000Base-T Control Register */
+-      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT);
+-      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-              ("1000B-T Ctrl =0x%04X\n", C1000BaseT));
+-      
++
+       /* Read AutoNeg Advertisement Register */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
+-      
+-      /* Read Ext. PHY Specific Control */
+-      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
+-      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-              ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
+-      
++
++      if (pAC->GIni.GIChipId != CHIP_ID_YUKON_FE) {
++              /* Read 1000Base-T Control Register */
++              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT);
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                      ("1000B-T Ctrl =0x%04X\n", C1000BaseT));
++
++              /* Read Ext. PHY Specific Control */
++              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                      ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
++      }
++
+       /* Read PHY Status */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("PHY Stat Reg.=0x%04X\n", PhyStat));
++
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("PHY Stat Reg.=0x%04X\n", PhyStat1));
+-      
++
+       /* Read PHY Specific Status */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+@@ -2718,6 +3073,8 @@
+       c_print("PHY Spec Reg=0x%04X\n", PhySpecStat);
+ #endif /* SK_DIAG */
++      /* enable all PHY interrupts */
++      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, (SK_U16)PHY_M_DEF_MSK);
+ #endif /* VCPU */
+ }     /* SkGmInitPhyMarv */
+@@ -2737,8 +3094,8 @@
+  *    nothing
+  */
+ static void SkXmInitPhyLone(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ SK_BOOL       DoLoop)         /* Should a Phy LoopBack be set-up? */
+ {
+@@ -2756,7 +3113,7 @@
+       /* manually Master/Slave ? */
+       if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
+               Ctrl2 |= PHY_L_1000C_MSE;
+-              
++
+               if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
+                       Ctrl2 |= PHY_L_1000C_MSC;
+               }
+@@ -2769,7 +3126,7 @@
+                */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyLone: no auto-negotiation Port %d\n", Port));
+-              /* Set DuplexMode in Config register */
++              /* set DuplexMode in Config register */
+               if (pPrt->PLinkMode == SK_LMODE_FULL) {
+                       Ctrl1 |= PHY_CT_DUP_MD;
+               }
+@@ -2778,7 +3135,6 @@
+               if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
+                       Ctrl2 |= PHY_L_1000C_MSE;       /* set it to Slave */
+               }
+-
+               /*
+                * Do NOT enable Auto-negotiation here. This would hold
+                * the link down because no IDLES are transmitted
+@@ -2787,9 +3143,9 @@
+       else {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyLone: with auto-negotiation Port %d\n", Port));
+-              /* Set Auto-negotiation advertisement */
++              /* set Auto-negotiation advertisement */
+-              /* Set Full/half duplex capabilities */
++              /* set Full/half duplex capabilities */
+               switch (pPrt->PLinkMode) {
+               case SK_LMODE_AUTOHALF:
+                       Ctrl2 |= PHY_L_1000C_AHD;
+@@ -2805,7 +3161,7 @@
+                               SKERR_HWI_E015MSG);
+               }
+-              /* Set Flow-control capabilities */
++              /* set Flow-control capabilities */
+               switch (pPrt->PFlowCtrlMode) {
+               case SK_FLOW_MODE_NONE:
+                       Ctrl3 |= PHY_L_P_NO_PAUSE;
+@@ -2827,19 +3183,19 @@
+               /* Restart Auto-negotiation */
+               Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
+       }
+-      
++
+       /* Write 1000Base-T Control Register */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
+-      
++
+       /* Write AutoNeg Advertisement Register */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
+       if (DoLoop) {
+-              /* Set the Phy Loopback bit, too */
++              /* set the Phy Loopback bit, too */
+               Ctrl1 |= PHY_CT_LOOP;
+       }
+@@ -2862,8 +3218,8 @@
+  *    nothing
+  */
+ static void SkXmInitPhyNat(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ SK_BOOL       DoLoop)         /* Should a Phy LoopBack be set-up? */
+ {
+@@ -2884,8 +3240,8 @@
+  *    nothing
+  */
+ void SkMacInitPhy(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ SK_BOOL       DoLoop)         /* Should a Phy LoopBack be set-up? */
+ {
+@@ -2895,7 +3251,7 @@
+ #ifdef GENESIS
+       if (pAC->GIni.GIGenesis) {
+-              
++
+               switch (pPrt->PhyType) {
+               case SK_PHY_XMAC:
+                       SkXmInitPhyXmac(pAC, IoC, Port, DoLoop);
+@@ -2914,10 +3270,10 @@
+               }
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+-              
++
+               SkGmInitPhyMarv(pAC, IoC, Port, DoLoop);
+       }
+ #endif /* YUKON */
+@@ -2939,8 +3295,8 @@
+  *    SK_AND_OTHER    Other error happened
+  */
+ static int SkXmAutoNegDoneXmac(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+@@ -2958,10 +3314,10 @@
+       if ((LPAb & PHY_X_AN_RFB) != 0) {
+               /* At least one of the remote fault bit is set */
+-              /* Error */
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
++
+               return(SK_AND_OTHER);
+       }
+@@ -2974,7 +3330,7 @@
+       }
+       else {
+               /* Error */
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                       ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               return(SK_AND_DUP_CAP);
+@@ -2984,19 +3340,19 @@
+       /* We are NOT using chapter 4.23 of the Xaqti manual */
+       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
+       if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC ||
+-           pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) &&
+-          (LPAb & PHY_X_P_SYM_MD) != 0) {
++               pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) &&
++              (LPAb & PHY_X_P_SYM_MD) != 0) {
+               /* Symmetric PAUSE */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
+       }
+       else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM &&
+-                 (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {
+-              /* Enable PAUSE receive, disable PAUSE transmit */
++                       (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {
++              /* enable PAUSE receive, disable PAUSE transmit */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
+       }
+       else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND &&
+-                 (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {
+-              /* Disable PAUSE receive, enable PAUSE transmit */
++                       (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {
++              /* disable PAUSE receive, enable PAUSE transmit */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
+       }
+       else {
+@@ -3022,8 +3378,8 @@
+  *    SK_AND_OTHER    Other error happened
+  */
+ static int SkXmAutoNegDoneBcom(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+@@ -3045,12 +3401,12 @@
+ 01-Sep-2000 RA;:;:
+       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
+ #endif        /* 0 */
+-      
++
+       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat);
+       if ((LPAb & PHY_B_AN_RF) != 0) {
+               /* Remote fault bit is set: Error */
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               return(SK_AND_OTHER);
+@@ -3065,23 +3421,23 @@
+       }
+       else {
+               /* Error */
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                       ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               return(SK_AND_DUP_CAP);
+       }
+-      
++
+ #ifdef TEST_ONLY
+ 01-Sep-2000 RA;:;:
+       /* Check Master/Slave resolution */
+       if ((ResAb & PHY_B_1000S_MSF) != 0) {
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                       ("Master/Slave Fault Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               pPrt->PMSStatus = SK_MS_STAT_FAULT;
+               return(SK_AND_OTHER);
+       }
+-      
++
+       pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
+               SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
+ #endif        /* 0 */
+@@ -3093,11 +3449,11 @@
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
+       }
+       else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRR) {
+-              /* Enable PAUSE receive, disable PAUSE transmit */
++              /* enable PAUSE receive, disable PAUSE transmit */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
+       }
+       else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRT) {
+-              /* Disable PAUSE receive, enable PAUSE transmit */
++              /* disable PAUSE receive, enable PAUSE transmit */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
+       }
+       else {
+@@ -3125,14 +3481,18 @@
+  *    SK_AND_OTHER    Other error happened
+  */
+ static int SkGmAutoNegDoneMarv(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+       SK_U16          LPAb;           /* Link Partner Ability */
+       SK_U16          ResAb;          /* Resolved Ability */
+       SK_U16          AuxStat;        /* Auxiliary Status */
++      SK_U8           PauseMode;      /* Pause Mode */
++
++      /* set Pause On */
++      PauseMode = (SK_U8)GMC_PAUSE_ON;
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("AutoNegDoneMarv, Port %d\n", Port));
+@@ -3142,78 +3502,105 @@
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("Link P.Abil.=0x%04X\n", LPAb));
+-      
++
+       if ((LPAb & PHY_M_AN_RF) != 0) {
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               return(SK_AND_OTHER);
+       }
+-      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
+-      
+-      /* Check Master/Slave resolution */
+-      if ((ResAb & PHY_B_1000S_MSF) != 0) {
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                      ("Master/Slave Fault Port %d\n", Port));
+-              pPrt->PAutoNegFail = SK_TRUE;
+-              pPrt->PMSStatus = SK_MS_STAT_FAULT;
+-              return(SK_AND_OTHER);
++      if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) {
++
++              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
++
++              /* Check Master/Slave resolution */
++              if ((ResAb & PHY_B_1000S_MSF) != 0) {
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
++                              ("Master/Slave Fault Port %d\n", Port));
++                      pPrt->PAutoNegFail = SK_TRUE;
++                      pPrt->PMSStatus = SK_MS_STAT_FAULT;
++                      return(SK_AND_OTHER);
++              }
++
++              pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
++                      (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE;
+       }
+-      
+-      pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
+-              (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE;
+-      
++
+       /* Read PHY Specific Status */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat);
+-      
++
+       /* Check Speed & Duplex resolved */
+-      if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) {
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                      ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port));
+-              pPrt->PAutoNegFail = SK_TRUE;
+-              pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
+-              return(SK_AND_DUP_CAP);
+-      }
+-      
+-      if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) {
+-              pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
+-      }
+-      else {
+-              pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
+-      }
+-      
+-      /* Check PAUSE mismatch ??? */
+-      /* We are using IEEE 802.3z/D5.0 Table 37-4 */
+-      if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) {
+-              /* Symmetric PAUSE */
+-              pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
+-      }
+-      else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) {
+-              /* Enable PAUSE receive, disable PAUSE transmit */
+-              pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
++      if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) {
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
++                      ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port));
++              pPrt->PAutoNegFail = SK_TRUE;
++              pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
++              return(SK_AND_DUP_CAP);
+       }
+-      else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) {
+-              /* Disable PAUSE receive, enable PAUSE transmit */
+-              pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
++
++      pPrt->PLinkModeStatus = (SK_U8)(((AuxStat & PHY_M_PS_FULL_DUP) != 0) ?
++              SK_LMODE_STAT_AUTOFULL : SK_LMODE_STAT_AUTOHALF);
++
++      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
++              /* set used link speed */
++              pPrt->PLinkSpeedUsed = (SK_U8)(((AuxStat & PHY_M_PS_SPEED_100) != 0) ?
++                      SK_LSPEED_STAT_100MBPS : SK_LSPEED_STAT_10MBPS);
+       }
+       else {
+-              /* PAUSE mismatch -> no PAUSE */
+-              pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
++              /* set used link speed */
++              switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
++              case (unsigned)PHY_M_PS_SPEED_1000:
++                      pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
++                      break;
++              case PHY_M_PS_SPEED_100:
++                      pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
++                      break;
++              default:
++                      pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
++              }
++
++              if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) {
++                      /* Tx & Rx Pause Enabled bits are at 9..8 */
++                      AuxStat >>= 6;
++
++                      if (!pAC->GIni.GICopperType) {
++                              /* always 1000 Mbps on fiber */
++                              pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
++                      }
++              }
++
++              AuxStat &= PHY_M_PS_PAUSE_MSK;
++              /* We are using IEEE 802.3z/D5.0 Table 37-4 */
++              if (AuxStat == PHY_M_PS_PAUSE_MSK) {
++                      /* Symmetric PAUSE */
++                      pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
++              }
++              else if (AuxStat == PHY_M_PS_RX_P_EN) {
++                      /* enable PAUSE receive, disable PAUSE transmit */
++                      pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
++              }
++              else if (AuxStat == PHY_M_PS_TX_P_EN) {
++                      /* disable PAUSE receive, enable PAUSE transmit */
++                      pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
++              }
++              else {
++                      /* PAUSE mismatch -> no PAUSE */
++                      pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
++              }
+       }
+-      
+-      /* set used link speed */
+-      switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
+-      case (unsigned)PHY_M_PS_SPEED_1000:
+-              pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
+-              break;
+-      case PHY_M_PS_SPEED_100:
+-              pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
+-              break;
+-      default:
+-              pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
++
++      if ((pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE) ||
++              /* disable Pause also for 10/100 Mbps in half duplex mode */
++              ((pPrt->PLinkSpeedUsed < (SK_U8)SK_LSPEED_STAT_1000MBPS) &&
++               pPrt->PLinkModeStatus == (SK_U8)SK_LMODE_STAT_AUTOHALF)) {
++
++              /* set Pause Off */
++              PauseMode = (SK_U8)GMC_PAUSE_OFF;
+       }
++      SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), PauseMode);
++
+       return(SK_AND_OK);
+ }     /* SkGmAutoNegDoneMarv */
+ #endif /* YUKON */
+@@ -3233,8 +3620,8 @@
+  *    SK_AND_OTHER    Other error happened
+  */
+ static int SkXmAutoNegDoneLone(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+@@ -3253,8 +3640,7 @@
+       if ((LPAb & PHY_L_AN_RF) != 0) {
+               /* Remote fault bit is set */
+-              /* Error */
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                       ("AutoNegFail: Remote fault bit set Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               return(SK_AND_OTHER);
+@@ -3267,11 +3653,11 @@
+       else {
+               pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
+       }
+-      
++
+       /* Check Master/Slave resolution */
+       if ((ResAb & PHY_L_1000S_MSF) != 0) {
+               /* Error */
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                       ("Master/Slave Fault Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+               pPrt->PMSStatus = SK_MS_STAT_FAULT;
+@@ -3288,7 +3674,7 @@
+       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
+       /* we must manually resolve the abilities here */
+       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
+-      
++
+       switch (pPrt->PFlowCtrlMode) {
+       case SK_FLOW_MODE_NONE:
+               /* default */
+@@ -3296,7 +3682,7 @@
+       case SK_FLOW_MODE_LOC_SEND:
+               if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
+                       (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) {
+-                      /* Disable PAUSE receive, enable PAUSE transmit */
++                      /* disable PAUSE receive, enable PAUSE transmit */
+                       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
+               }
+               break;
+@@ -3309,7 +3695,7 @@
+       case SK_FLOW_MODE_SYM_OR_REM:
+               if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
+                       PHY_L_QS_AS_PAUSE) {
+-                      /* Enable PAUSE receive, disable PAUSE transmit */
++                      /* enable PAUSE receive, disable PAUSE transmit */
+                       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
+               }
+               else if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
+@@ -3321,7 +3707,7 @@
+               SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
+                       SKERR_HWI_E016MSG);
+       }
+-      
++
+       return(SK_AND_OK);
+ }     /* SkXmAutoNegDoneLone */
+@@ -3339,8 +3725,8 @@
+  *    SK_AND_OTHER    Other error happened
+  */
+ static int SkXmAutoNegDoneNat(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+ /* todo: National */
+@@ -3360,9 +3746,9 @@
+  *    SK_AND_DUP_CAP  Duplex capability error happened
+  *    SK_AND_OTHER    Other error happened
+  */
+-int   SkMacAutoNegDone(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++int SkMacAutoNegDone(
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+@@ -3374,9 +3760,9 @@
+ #ifdef GENESIS
+       if (pAC->GIni.GIGenesis) {
+-              
++
+               switch (pPrt->PhyType) {
+-              
++
+               case SK_PHY_XMAC:
+                       Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port);
+                       break;
+@@ -3396,26 +3782,26 @@
+               }
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+-              
++
+               Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port);
+       }
+ #endif /* YUKON */
+-      
++
+       if (Rtv != SK_AND_OK) {
+               return(Rtv);
+       }
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("AutoNeg done Port %d\n", Port));
+-      
++
+       /* We checked everything and may now enable the link */
+       pPrt->PAutoNegFail = SK_FALSE;
+       SkMacRxTxEnable(pAC, IoC, Port);
+-      
++
+       return(SK_AND_OK);
+ }     /* SkMacAutoNegDone */
+@@ -3433,7 +3819,7 @@
+  */
+ static void SkXmSetRxTxEn(
+ SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* IO context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ int           Para)           /* Parameter to set: MAC or PHY LoopBack, Duplex Mode */
+ {
+@@ -3458,7 +3844,7 @@
+               Word &= ~XM_MMU_GMII_LOOP;
+               break;
+       }
+-      
++
+       switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) {
+       case SK_PHY_FULLD_ON:
+               Word |= XM_MMU_GMII_FD;
+@@ -3467,7 +3853,7 @@
+               Word &= ~XM_MMU_GMII_FD;
+               break;
+       }
+-      
++
+       XM_OUT16(IoC, Port, XM_MMU_CMD, Word | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
+       /* dummy read to ensure writing */
+@@ -3490,12 +3876,12 @@
+  */
+ static void SkGmSetRxTxEn(
+ SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* IO context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ int           Para)           /* Parameter to set: MAC LoopBack, Duplex Mode */
+ {
+       SK_U16  Ctrl;
+-      
++
+       GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl);
+       switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) {
+@@ -3515,12 +3901,13 @@
+               Ctrl &= ~GM_GPCR_DUP_FULL;
+               break;
+       }
+-      
+-    GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Ctrl | GM_GPCR_RX_ENA |
+-              GM_GPCR_TX_ENA));
++      GM_OUT16(IoC, Port, GM_GP_CTRL, Ctrl | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
++
++#ifdef XXX
+       /* dummy read to ensure writing */
+       GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl);
++#endif /* XXX */
+ }     /* SkGmSetRxTxEn */
+ #endif /* YUKON */
+@@ -3537,20 +3924,20 @@
+  */
+ void SkMacSetRxTxEn(
+ SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* IO context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ int           Para)
+ {
+ #ifdef GENESIS
+       if (pAC->GIni.GIGenesis) {
+-              
++
+               SkXmSetRxTxEn(pAC, IoC, Port, Para);
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+-              
++
+               SkGmSetRxTxEn(pAC, IoC, Port, Para);
+       }
+ #endif /* YUKON */
+@@ -3570,8 +3957,8 @@
+  *    != 0    Error happened
+  */
+ int SkMacRxTxEnable(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+@@ -3589,9 +3976,9 @@
+       }
+       if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF ||
+-           pPrt->PLinkMode == SK_LMODE_AUTOFULL ||
+-           pPrt->PLinkMode == SK_LMODE_AUTOBOTH) &&
+-           pPrt->PAutoNegFail) {
++               pPrt->PLinkMode == SK_LMODE_AUTOFULL ||
++               pPrt->PLinkMode == SK_LMODE_AUTOBOTH) &&
++               pPrt->PAutoNegFail) {
+               /* Auto-negotiation is not done or failed */
+               return(0);
+       }
+@@ -3600,9 +3987,9 @@
+       if (pAC->GIni.GIGenesis) {
+               /* set Duplex Mode and Pause Mode */
+               SkXmInitDupMd(pAC, IoC, Port);
+-              
++
+               SkXmInitPauseMd(pAC, IoC, Port);
+-      
++
+               /*
+                * Initialize the Interrupt Mask Register. Default IRQs are...
+                *      - Link Asynchronous Event
+@@ -3618,23 +4005,23 @@
+               /* add IRQ for Receive FIFO Overflow */
+               IntMask &= ~XM_IS_RXF_OV;
+ #endif /* DEBUG */
+-              
++
+               if (pPrt->PhyType != SK_PHY_XMAC) {
+                       /* disable GP0 interrupt bit */
+                       IntMask |= XM_IS_INP_ASS;
+               }
+               XM_OUT16(IoC, Port, XM_IMSK, IntMask);
+-      
++
+               /* get MMU Command Reg. */
+               XM_IN16(IoC, Port, XM_MMU_CMD, &Reg);
+-              
++
+               if (pPrt->PhyType != SK_PHY_XMAC &&
+                       (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
+                        pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) {
+                       /* set to Full Duplex */
+                       Reg |= XM_MMU_GMII_FD;
+               }
+-              
++
+               switch (pPrt->PhyType) {
+               case SK_PHY_BCOM:
+                       /*
+@@ -3644,7 +4031,7 @@
+                       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
+                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
+                               (SK_U16)(SWord & ~PHY_B_AC_DIS_PM));
+-            SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK,
++                      SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK,
+                               (SK_U16)PHY_B_DEF_MSK);
+                       break;
+ #ifdef OTHER_PHY
+@@ -3658,12 +4045,12 @@
+                       break;
+ #endif /* OTHER_PHY */
+               }
+-              
++
+               /* enable Rx/Tx */
+               XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+               /*
+@@ -3678,30 +4065,30 @@
+               /* add IRQ for Receive FIFO Overrun */
+               IntMask |= GM_IS_RX_FF_OR;
+ #endif /* DEBUG */
+-              
+-              SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask);
+-              
++
++              SK_OUT8(IoC, MR_ADDR(Port, GMAC_IRQ_MSK), (SK_U8)IntMask);
++
+               /* get General Purpose Control */
+               GM_IN16(IoC, Port, GM_GP_CTRL, &Reg);
+-              
++
+               if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
+                       pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) {
+                       /* set to Full Duplex */
+                       Reg |= GM_GPCR_DUP_FULL;
+               }
+-              
++
+               /* enable Rx/Tx */
+-        GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Reg | GM_GPCR_RX_ENA |
+-                      GM_GPCR_TX_ENA));
++              GM_OUT16(IoC, Port, GM_GP_CTRL, Reg | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
+-#ifndef VCPU
+-              /* Enable all PHY interrupts */
+-        SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK,
+-                      (SK_U16)PHY_M_DEF_MSK);
+-#endif /* VCPU */
++#ifdef XXX
++              /* dummy read to ensure writing */
++              GM_IN16(IoC, Port, GM_GP_CTRL, &Reg);
++#endif /* XXX */
+       }
+ #endif /* YUKON */
+-                                      
++
++      pAC->GIni.GP[Port].PState = SK_PRT_RUN;
++
+       return(0);
+ }     /* SkMacRxTxEnable */
+@@ -3717,33 +4104,38 @@
+  */
+ void SkMacRxTxDisable(
+ SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* IO context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_U16  Word;
+ #ifdef GENESIS
+       if (pAC->GIni.GIGenesis) {
+-              
++
+               XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
+-              
+-              XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
+-      
++
++              Word &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
++
++              XM_OUT16(IoC, Port, XM_MMU_CMD, Word);
++
+               /* dummy read to ensure writing */
+               XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+-              
++
+               GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
+-        GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Word & ~(GM_GPCR_RX_ENA |
+-                      GM_GPCR_TX_ENA)));
++              Word &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
++              GM_OUT16(IoC, Port, GM_GP_CTRL, Word);
++
++#ifdef XXX
+               /* dummy read to ensure writing */
+               GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
++#endif /* XXX */
+       }
+ #endif /* YUKON */
+@@ -3760,7 +4152,7 @@
+  */
+ void SkMacIrqDisable(
+ SK_AC *pAC,           /* Adapter Context */
+-SK_IOC        IoC,            /* IO context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+@@ -3772,18 +4164,18 @@
+ #ifdef GENESIS
+       if (pAC->GIni.GIGenesis) {
+-              
++
+               /* disable all XMAC IRQs */
+-              XM_OUT16(IoC, Port, XM_IMSK, 0xffff);   
+-              
+-              /* Disable all PHY interrupts */
++              XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
++
++              /* disable all PHY interrupts */
+               switch (pPrt->PhyType) {
+                       case SK_PHY_BCOM:
+                               /* Make sure that PHY is initialized */
+                               if (pPrt->PState != SK_PRT_RESET) {
+                                       /* NOT allowed if BCOM is in RESET state */
+                                       /* Workaround BCOM Errata (#10523) all BCom */
+-                                      /* Disable Power Management if link is down */
++                                      /* disable Power Management if link is down */
+                                       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Word);
+                                       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
+                                               (SK_U16)(Word | PHY_B_AC_DIS_PM));
+@@ -3802,16 +4194,16 @@
+               }
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+               /* disable all GMAC IRQs */
+-              SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
+-              
++              SK_OUT8(IoC, MR_ADDR(Port, GMAC_IRQ_MSK), 0);
++
+ #ifndef VCPU
+-              /* Disable all PHY interrupts */
++              /* disable all PHY interrupts */
+               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
+-#endif /* VCPU */
++#endif /* !VCPU */
+       }
+ #endif /* YUKON */
+@@ -3823,29 +4215,72 @@
+  *
+  *    SkXmSendCont() - Enable / Disable Send Continuous Mode
+  *
+- * Description:       enable / disable Send Continuous Mode on XMAC
++ * Description:       enable / disable Send Continuous Mode on XMAC resp.
++ *                                                            Packet Generation on GPHY
+  *
+  * Returns:
+  *    nothing
+  */
+ void SkXmSendCont(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port,   /* Port Index (MAC_1 + n) */
+ SK_BOOL       Enable) /* Enable / Disable */
+ {
++      SK_U16  Reg;
++      SK_U16  Save;
+       SK_U32  MdReg;
+-      XM_IN32(IoC, Port, XM_MODE, &MdReg);
++      if (pAC->GIni.GIGenesis) {
++              XM_IN32(IoC, Port, XM_MODE, &MdReg);
+-      if (Enable) {
+-              MdReg |= XM_MD_TX_CONT;
++              if (Enable) {
++                      MdReg |= XM_MD_TX_CONT;
++              }
++              else {
++                      MdReg &= ~XM_MD_TX_CONT;
++              }
++              /* setup Mode Register */
++              XM_OUT32(IoC, Port, XM_MODE, MdReg);
+       }
+       else {
+-              MdReg &= ~XM_MD_TX_CONT;
++              if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) {
++                      /* select page 18 */
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_ADDR, 18);
++
++                      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PAGE_DATA, &Reg);
++
++                      Reg &= ~0x003c;                 /* clear bits 5..2 */
++
++                      if (Enable) {
++                              /* enable packet generation, 1518 byte length */
++                              Reg |= (BIT_5S | BIT_3S);
++                      }
++
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, Reg);
++              }
++              else if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) {
++                      /* save page register */
++                      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_ADR, &Save);
++
++                      /* select page 6 to access Packet Generation register */
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 6);
++
++                      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Reg);
++
++                      Reg &= ~0x003f;                 /* clear bits 5..0 */
++
++                      if (Enable) {
++                              /* enable packet generation, 1518 byte length */
++                              Reg |= (BIT_3S | BIT_1S);
++                      }
++
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Reg);
++
++                      /* restore page register */
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, Save);
++              }
+       }
+-      /* setup Mode Register */
+-      XM_OUT32(IoC, Port, XM_MODE, MdReg);
+ }     /* SkXmSendCont */
+@@ -3860,8 +4295,8 @@
+  *    nothing
+  */
+ void SkMacTimeStamp(
+-SK_AC *pAC,   /* adapter context */
+-SK_IOC        IoC,    /* IO context */
++SK_AC *pAC,   /* Adapter Context */
++SK_IOC        IoC,    /* I/O Context */
+ int           Port,   /* Port Index (MAC_1 + n) */
+ SK_BOOL       Enable) /* Enable / Disable */
+ {
+@@ -3906,8 +4341,8 @@
+  *    is set true.
+  */
+ void SkXmAutoNegLipaXmac(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ SK_U16        IStatus)        /* Interrupt Status word to analyse */
+ {
+@@ -3921,6 +4356,7 @@
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04X\n",
+                       Port, IStatus));
++
+               pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
+       }
+ }     /* SkXmAutoNegLipaXmac */
+@@ -3936,8 +4372,8 @@
+  *    is set true.
+  */
+ void SkMacAutoNegLipaPhy(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ SK_U16        PhyStat)        /* PHY Status word to analyse */
+ {
+@@ -3951,6 +4387,7 @@
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04X\n",
+                       Port, PhyStat));
++
+               pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
+       }
+ }     /* SkMacAutoNegLipaPhy */
+@@ -3965,7 +4402,7 @@
+  *
+  * Note:
+  *    With an external PHY, some interrupt bits are not meaningfull any more:
+- *    - LinkAsyncEvent (bit #14)              XM_IS_LNK_AE
++ *    - LinkAsyncEvent (bit #14)              XM_IS_LNK_AE
+  *    - LinkPartnerReqConfig (bit #10)        XM_IS_LIPA_RC
+  *    - Page Received (bit #9)                XM_IS_RX_PAGE
+  *    - NextPageLoadedForXmt (bit #8)         XM_IS_TX_PAGE
+@@ -3977,8 +4414,8 @@
+  *    nothing
+  */
+ void SkXmIrq(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+@@ -3986,13 +4423,13 @@
+       SK_U16          IStatus;        /* Interrupt status read from the XMAC */
+       SK_U16          IStatus2;
+ #ifdef SK_SLIM
+-    SK_U64      OverflowStatus;
+-#endif        
++      SK_U64          OverflowStatus;
++#endif
+       pPrt = &pAC->GIni.GP[Port];
+-      
++
+       XM_IN16(IoC, Port, XM_ISRC, &IStatus);
+-      
++
+       /* LinkPartner Auto-negable? */
+       if (pPrt->PhyType == SK_PHY_XMAC) {
+               SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus);
+@@ -4003,7 +4440,7 @@
+                       XM_IS_RX_PAGE | XM_IS_TX_PAGE |
+                       XM_IS_AND | XM_IS_INP_ASS);
+       }
+-      
++
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+               ("XmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
+@@ -4113,40 +4550,40 @@
+  *    nothing
+  */
+ void SkGmIrq(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+       SK_U8           IStatus;        /* Interrupt status */
+ #ifdef SK_SLIM
+-    SK_U64      OverflowStatus;
++      SK_U64          OverflowStatus;
+ #else
+       SK_EVPARA       Para;
+-#endif        
++#endif
+       pPrt = &pAC->GIni.GP[Port];
+-      
+-      SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus);
+-      
++
++      SK_IN8(IoC, MR_ADDR(Port, GMAC_IRQ_SRC), &IStatus);
++
+ #ifdef XXX
+       /* LinkPartner Auto-negable? */
+       SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus);
+ #endif /* XXX */
+-      
++
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
+-              ("GmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
++              ("GmacIrq Port %d Isr 0x%02X\n", Port, IStatus));
+       /* Combined Tx & Rx Counter Overflow SIRQ Event */
+       if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) {
+               /* these IRQs will be cleared by reading GMACs register */
+ #ifdef SK_SLIM
+-        SkGmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus);
++              SkGmOverflowStatus(pAC, IoC, Port, (SK_U16)IStatus, &OverflowStatus);
+ #else
+               Para.Para32[0] = (SK_U32)Port;
+               Para.Para32[1] = (SK_U32)IStatus;
+               SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
+-#endif                
++#endif
+       }
+       if (IStatus & GM_IS_RX_FF_OR) {
+@@ -4185,8 +4622,8 @@
+  *    nothing
+  */
+ void SkMacIrq(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+ #ifdef GENESIS
+@@ -4195,7 +4632,7 @@
+               SkXmIrq(pAC, IoC, Port);
+       }
+ #endif /* GENESIS */
+-      
++
+ #ifdef YUKON
+       if (pAC->GIni.GIYukon) {
+               /* IRQ from GMAC */
+@@ -4222,8 +4659,8 @@
+  *    1:  something went wrong
+  */
+ int SkXmUpdateStats(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ unsigned int Port)    /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+@@ -4245,7 +4682,7 @@
+       do {
+               XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg);
+-              
++
+               if (++WaitIndex > 10) {
+                       SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG);
+@@ -4253,7 +4690,7 @@
+                       return(1);
+               }
+       } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0);
+-      
++
+       return(0);
+ }     /* SkXmUpdateStats */
+@@ -4272,19 +4709,19 @@
+  *    1:  something went wrong
+  */
+ int SkXmMacStatistic(
+-SK_AC *pAC,                   /* adapter context */
+-SK_IOC        IoC,                    /* IO context */
++SK_AC *pAC,                   /* Adapter Context */
++SK_IOC        IoC,                    /* I/O Context */
+ unsigned int Port,            /* Port Index (MAC_1 + n) */
+ SK_U16        StatAddr,               /* MIB counter base address */
+-SK_U32        SK_FAR *pVal)   /* ptr to return statistic value */
++SK_U32        SK_FAR *pVal)   /* Pointer to return statistic value */
+ {
+       if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) {
+-              
++
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
+-              
++
+               return(1);
+       }
+-      
++
+       XM_IN32(IoC, Port, StatAddr, pVal);
+       return(0);
+@@ -4303,12 +4740,12 @@
+  *    1:  something went wrong
+  */
+ int SkXmResetCounter(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ unsigned int Port)    /* Port Index (MAC_1 + n) */
+ {
+       XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
+-      /* Clear two times according to Errata #3 */
++      /* Clear two times according to XMAC Errata #3 */
+       XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
+       return(0);
+@@ -4335,11 +4772,11 @@
+  *    1:  something went wrong
+  */
+ int SkXmOverflowStatus(
+-SK_AC *pAC,                           /* adapter context */
+-SK_IOC        IoC,                            /* IO context */
++SK_AC *pAC,                           /* Adapter Context */
++SK_IOC        IoC,                            /* I/O Context */
+ unsigned int Port,                    /* Port Index (MAC_1 + n) */
+-SK_U16        IStatus,                        /* Interupt Status from MAC */
+-SK_U64        SK_FAR *pStatus)        /* ptr for return overflow status value */
++SK_U16        IStatus,                        /* Interrupt Status from MAC */
++SK_U64        SK_FAR *pStatus)        /* Pointer for return overflow status value */
+ {
+       SK_U64  Status; /* Overflow status */
+       SK_U32  RegVal;
+@@ -4351,7 +4788,7 @@
+               XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal);
+               Status |= (SK_U64)RegVal << 32;
+       }
+-      
++
+       if ((IStatus & XM_IS_TXC_OV) != 0) {
+               XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal);
+@@ -4378,8 +4815,8 @@
+  *    1:  something went wrong
+  */
+ int SkGmUpdateStats(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ unsigned int Port)    /* Port Index (MAC_1 + n) */
+ {
+       return(0);
+@@ -4400,24 +4837,27 @@
+  *    1:  something went wrong
+  */
+ int SkGmMacStatistic(
+-SK_AC *pAC,                   /* adapter context */
+-SK_IOC        IoC,                    /* IO context */
++SK_AC *pAC,                   /* Adapter Context */
++SK_IOC        IoC,                    /* I/O Context */
+ unsigned int Port,            /* Port Index (MAC_1 + n) */
+ SK_U16        StatAddr,               /* MIB counter base address */
+-SK_U32        SK_FAR *pVal)   /* ptr to return statistic value */
++SK_U32        SK_FAR *pVal)   /* Pointer to return statistic value */
+ {
+       if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) {
+-              
++
+               SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
+-              
+-              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
+                       ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr));
+               return(1);
+       }
+-              
++
+       GM_IN32(IoC, Port, StatAddr, pVal);
++      /* dummy read */
++      SK_IN16(IoC, B0_RAP, &StatAddr);
++
+       return(0);
+ }     /* SkGmMacStatistic */
+@@ -4434,8 +4874,8 @@
+  *    1:  something went wrong
+  */
+ int SkGmResetCounter(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ unsigned int Port)    /* Port Index (MAC_1 + n) */
+ {
+       SK_U16  Reg;    /* Phy Address Register */
+@@ -4446,16 +4886,16 @@
+       /* set MIB Clear Counter Mode */
+       GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR);
+-      
++
+       /* read all MIB Counters with Clear Mode set */
+       for (i = 0; i < GM_MIB_CNT_SIZE; i++) {
+               /* the reset is performed only when the lower 16 bits are read */
+               GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word);
+       }
+-      
++
+       /* clear MIB Clear Counter Mode */
+       GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg);
+-      
++
+       return(0);
+ }     /* SkGmResetCounter */
+@@ -4469,48 +4909,62 @@
+  *    resulting counter overflow status is written to <pStatus>, whereas the
+  *    the following bit coding is used:
+  *    63:56 - unused
+- *    55:48 - TxRx interrupt register bit7:0
+- *    32:47 - Rx interrupt register
++ *    55:48 - TxRx interrupt register bit 7:0
++ *    47:32 - Rx interrupt register
+  *    31:24 - unused
+- *    23:16 - TxRx interrupt register bit15:8
+- *    15:0  - Tx interrupt register
++ *    23:16 - TxRx interrupt register bit 15:8
++ *    15: 0 - Tx interrupt register
+  *
+  * Returns:
+  *    0:  success
+  *    1:  something went wrong
+  */
+ int SkGmOverflowStatus(
+-SK_AC *pAC,                           /* adapter context */
+-SK_IOC        IoC,                            /* IO context */
++SK_AC *pAC,                           /* Adapter Context */
++SK_IOC        IoC,                            /* I/O Context */
+ unsigned int Port,                    /* Port Index (MAC_1 + n) */
+-SK_U16        IStatus,                        /* Interupt Status from MAC */
+-SK_U64        SK_FAR *pStatus)        /* ptr for return overflow status value */
++SK_U16        IStatus,                        /* Interrupt Status from MAC */
++SK_U64        SK_FAR *pStatus)        /* Pointer for return overflow status value */
+ {
+-      SK_U64  Status;         /* Overflow status */
+       SK_U16  RegVal;
++#ifndef SK_SLIM
++      SK_U64  Status;         /* Overflow status */
+       Status = 0;
++#endif /* !SK_SLIM */
+       if ((IStatus & GM_IS_RX_CO_OV) != 0) {
+               /* this register is self-clearing after read */
+               GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal);
++
++#ifndef SK_SLIM
+               Status |= (SK_U64)RegVal << 32;
++#endif /* !SK_SLIM */
+       }
+-      
++
+       if ((IStatus & GM_IS_TX_CO_OV) != 0) {
+               /* this register is self-clearing after read */
+               GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal);
++
++#ifndef SK_SLIM
+               Status |= (SK_U64)RegVal;
++#endif /* !SK_SLIM */
+       }
+-      
++
+       /* this register is self-clearing after read */
+       GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal);
++
++#ifndef SK_SLIM
+       /* Rx overflow interrupt register bits (LoByte)*/
+       Status |= (SK_U64)((SK_U8)RegVal) << 48;
+       /* Tx overflow interrupt register bits (HiByte)*/
+       Status |= (SK_U64)(RegVal >> 8) << 16;
+       *pStatus = Status;
++#endif /* !SK_SLIM */
++
++      /* dummy read */
++      SK_IN16(IoC, B0_RAP, &RegVal);
+       return(0);
+ }     /* SkGmOverflowStatus */
+@@ -4526,57 +4980,114 @@
+  *  gets the results if 'StartTest' is true
+  *
+  * NOTE:      this test is meaningful only when link is down
+- *    
++ *
+  * Returns:
+  *    0:  success
+  *    1:      no YUKON copper
+  *    2:      test in progress
+  */
+ int SkGmCableDiagStatus(
+-SK_AC *pAC,           /* adapter context */
+-SK_IOC        IoC,            /* IO context */
++SK_AC *pAC,           /* Adapter Context */
++SK_IOC        IoC,            /* I/O Context */
+ int           Port,           /* Port Index (MAC_1 + n) */
+ SK_BOOL       StartTest)      /* flag for start / get result */
+ {
+       int             i;
++      int             CableDiagOffs;
++      int             MdiPairs;
++      SK_BOOL FastEthernet;
++      SK_BOOL Yukon2;
+       SK_U16  RegVal;
+       SK_GEPORT       *pPrt;
+       pPrt = &pAC->GIni.GP[Port];
+       if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
+-              
++
+               return(1);
+       }
++      Yukon2 = (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL);
++
++      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
++
++              CableDiagOffs = PHY_MARV_FE_VCT_TX;
++              FastEthernet = SK_TRUE;
++              MdiPairs = 2;
++      }
++      else {
++              CableDiagOffs = Yukon2 ? PHY_MARV_PHY_CTRL : PHY_MARV_CABLE_DIAG;
++              FastEthernet = SK_FALSE;
++              MdiPairs = 4;
++      }
++
+       if (StartTest) {
++
++              /* set to RESET to avoid PortCheckUp */
++              pPrt->PState = SK_PRT_RESET;
++
+               /* only start the cable test */
+-              if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) {
+-                      /* apply TDR workaround from Marvell */
+-                      SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e);
+-                      
+-                      SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00);
+-                      SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800);
+-                      SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400);
+-                      SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000);
+-                      SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100);
++              if (!FastEthernet) {
++
++                      if ((((pPrt->PhyId1 & PHY_I1_MOD_NUM) >> 4) == 2) &&
++                               ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4)) {
++                              /* apply TDR workaround for model 2, rev. < 4 */
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_ADDR, 0x001e);
++
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xcc00);
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc800);
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc400);
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc000);
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc100);
++                      }
++
++#ifdef YUKON_DBG
++                      if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) {
++                              /* set address to 1 for page 1 */
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 1);
++
++                              /* disable waiting period */
++                              SkGmPhyWrite(pAC, IoC, Port, CableDiagOffs,
++                                      PHY_M_CABD_DIS_WAIT);
++                      }
++#endif
++                      if (Yukon2) {
++                              /* set address to 5 for page 5 */
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 5);
++      
++#ifdef YUKON_DBG
++                              /* disable waiting period */
++                              SkGmPhyWrite(pAC, IoC, Port, CableDiagOffs + 1,
++                                      PHY_M_CABD_DIS_WAIT);
++#endif
++                      }
++                      else {
++                              /* set address to 0 for MDI[0] (Page 0) */
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0);
++                      }
+               }
++              else {
++                      RegVal = PHY_CT_RESET | PHY_CT_SP100;
+-              /* set address to 0 for MDI[0] */
+-              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0);
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, RegVal);
+-              /* Read Cable Diagnostic Reg */
+-              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
++#ifdef xYUKON_DBG
++                      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_FE_SPEC_2, &RegVal);
++                      /* disable waiting period */
++                      RegVal |= PHY_M_FESC_DIS_WAIT;
++
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_FE_SPEC_2, RegVal);
++#endif
++              }
+               /* start Cable Diagnostic Test */
+-              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG,
+-                      (SK_U16)(RegVal | PHY_M_CABD_ENA_TEST));
+-      
++              SkGmPhyWrite(pAC, IoC, Port, CableDiagOffs, PHY_M_CABD_ENA_TEST);
++
+               return(0);
+       }
+-      
++
+       /* Read Cable Diagnostic Reg */
+-      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
++      SkGmPhyRead(pAC, IoC, Port, CableDiagOffs, &RegVal);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+               ("PHY Cable Diag.=0x%04X\n", RegVal));
+@@ -4587,16 +5098,24 @@
+       }
+       /* get the test results */
+-      for (i = 0; i < 4; i++)  {
+-              /* set address to i for MDI[i] */
+-              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i);
++      for (i = 0; i < MdiPairs; i++)  {
++
++              if (!FastEthernet && !Yukon2) {
++                      /* set address to i for MDI[i] */
++                      SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i);
++              }
+               /* get Cable Diagnostic values */
+-              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
++              SkGmPhyRead(pAC, IoC, Port, CableDiagOffs, &RegVal);
+               pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK);
+               pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13);
++
++              if (FastEthernet || Yukon2) {
++                      /* get next register */
++                      CableDiagOffs++;
++              }
+       }
+       return(0);
+@@ -4605,3 +5124,4 @@
+ #endif /* YUKON */
+ /* End of file */
++
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/sky2.c linux-2.6.9.new/drivers/net/sk98lin/sky2.c
+--- linux-2.6.9.old/drivers/net/sk98lin/sky2.c 1970-01-01 08:00:00.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/sky2.c 2006-12-07 14:35:03.000000000 +0800
+@@ -0,0 +1,2737 @@
++/******************************************************************************
++ *
++ * Name:        sky2.c
++ * Project:     Yukon2 specific functions and implementations
++ * Version:     $Revision: 1.35.2.33 $
++ * Date:        $Date: 2005/06/17 14:09:32 $
++ * Purpose:     The main driver source module
++ *
++ *****************************************************************************/
++
++/******************************************************************************
++ *
++ *    (C)Copyright 1998-2002 SysKonnect GmbH.
++ *    (C)Copyright 2002-2005 Marvell.
++ *
++ *    Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet 
++ *      Server Adapters.
++ *
++ *    Author: Ralph Roesler (rroesler@syskonnect.de)
++ *            Mirko Lindner (mlindner@syskonnect.de)
++ *
++ *    Address all question to: linux@syskonnect.de
++ *
++ *    This program is free software; you can redistribute it and/or modify
++ *    it under the terms of the GNU General Public License as published by
++ *    the Free Software Foundation; either version 2 of the License, or
++ *    (at your option) any later version.
++ *
++ *    The information in this file is provided "AS IS" without warranty.
++ *
++ *****************************************************************************/
++
++#include "h/skdrv1st.h"
++#include "h/skdrv2nd.h"
++#include <linux/tcp.h>
++
++/******************************************************************************
++ *
++ * Local Function Prototypes
++ *
++ *****************************************************************************/
++
++static void InitPacketQueues(SK_AC *pAC,int Port);
++static void GiveTxBufferToHw(SK_AC *pAC,SK_IOC IoC,int Port);
++static void GiveRxBufferToHw(SK_AC *pAC,SK_IOC IoC,int Port,SK_PACKET *pPacket);
++static void FillReceiveTableYukon2(SK_AC *pAC,SK_IOC IoC,int Port);
++static SK_BOOL HandleReceives(SK_AC *pAC,int Port,SK_U16 Len,SK_U32 FrameStatus,SK_U16 Tcp1,SK_U16 Tcp2,SK_U32 Tist,SK_U16 Vlan);
++static void CheckForSendComplete(SK_AC *pAC,SK_IOC IoC,int Port,SK_PKT_QUEUE *pPQ,SK_LE_TABLE *pLETab,unsigned int Done);
++static void UnmapAndFreeTxPktBuffer(SK_AC *pAC,SK_PACKET *pSkPacket,int TxPort);
++static SK_BOOL AllocateAndInitLETables(SK_AC *pAC);
++static SK_BOOL AllocatePacketBuffersYukon2(SK_AC *pAC);
++static void FreeLETables(SK_AC *pAC);
++static void FreePacketBuffers(SK_AC *pAC);
++static SK_BOOL AllocAndMapRxBuffer(SK_AC *pAC,SK_PACKET *pSkPacket,int Port);
++#ifdef CONFIG_SK98LIN_NAPI
++static SK_BOOL HandleStatusLEs(SK_AC *pAC,int *WorkDone,int WorkToDo);
++#else
++static SK_BOOL HandleStatusLEs(SK_AC *pAC);
++#endif
++
++extern void   SkGeCheckTimer          (DEV_NET *pNet);
++extern void   SkLocalEventQueue(      SK_AC *pAC,
++                                      SK_U32 Class,
++                                      SK_U32 Event,
++                                      SK_U32 Param1,
++                                      SK_U32 Param2,
++                                      SK_BOOL Flag);
++extern void   SkLocalEventQueue64(    SK_AC *pAC,
++                                      SK_U32 Class,
++                                      SK_U32 Event,
++                                      SK_U64 Param,
++                                      SK_BOOL Flag);
++
++/******************************************************************************
++ *
++ * Local Variables
++ *
++ *****************************************************************************/
++
++#define MAX_NBR_RX_BUFFERS_IN_HW      0x15
++static SK_U8 NbrRxBuffersInHW;
++
++#if defined(__i386__) || defined(__x86_64__)
++#if defined(__x86_64__)
++#define FLUSH_OPC(le)
++/* #define FLUSH_OPC(le)                      \       */
++/*    cache0 = ((long *)(le))[0];             \       */
++/*    cache1 = ((long *)(le))[1];             \       */
++/*    ((volatile long *)(le))[0] = cache0;    \       */
++/*    ((volatile long *)(le))[1] = cache1;            */
++#else
++#define FLUSH_OPC(le) 
++#endif
++#else
++#define FLUSH_OPC(le) 
++#endif
++
++/******************************************************************************
++ *
++ * Global Functions
++ *
++ *****************************************************************************/
++
++int SkY2Xmit( struct sk_buff *skb, struct SK_NET_DEVICE *dev); 
++
++/*****************************************************************************
++ *
++ *    SkY2RestartStatusUnit - restarts teh status unit
++ *
++ * Description:
++ *    Reenables the status unit after any De-Init (e.g. when altering 
++ *    the sie of the MTU via 'ifconfig a.b.c.d mtu xxx')
++ *
++ * Returns:   N/A
++ */
++void SkY2RestartStatusUnit(
++SK_AC  *pAC)  /* pointer to adapter control context */
++{
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("==> SkY2RestartStatusUnit\n"));
++
++      /*
++      ** It might be that the TX timer is not started. Therefore
++      ** it is initialized here -> to be more investigated!
++      */
++      SK_OUT32(pAC->IoBase, STAT_TX_TIMER_INI, HW_MS_TO_TICKS(pAC,10));
++
++      pAC->StatusLETable.Done  = 0;
++      pAC->StatusLETable.Put   = 0;
++      pAC->StatusLETable.HwPut = 0;
++      SkGeY2InitStatBmu(pAC, pAC->IoBase, &pAC->StatusLETable);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("<== SkY2RestartStatusUnit\n"));
++}
++
++/*****************************************************************************
++ *
++ *    SkY2RlmtSend - sends out a single RLMT notification
++ *
++ * Description:
++ *    This function sends out an RLMT frame
++ *
++ * Returns:   
++ *    > 0 - on succes: the number of bytes in the message
++ *    = 0 - on resource shortage: this frame sent or dropped, now
++ *          the ring is full ( -> set tbusy)
++ *    < 0 - on failure: other problems ( -> return failure to upper layers)
++ */
++int SkY2RlmtSend (
++SK_AC          *pAC,       /* pointer to adapter control context           */
++int             PortNr,    /* index of port the packet(s) shall be send to */
++struct sk_buff *pMessage)  /* pointer to send-message                      */
++{
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("=== SkY2RlmtSend\n"));
++#if 0
++      return -1;   // temporarily do not send out RLMT frames
++#endif
++      skb_shinfo(pMessage)->nr_frags = (2*MAX_SKB_FRAGS) + PortNr;
++      return(SkY2Xmit(pMessage, pAC->dev[PortNr])); // SkY2Xmit needs device
++}
++
++/*****************************************************************************
++ *
++ *    SkY2AllocateResources - Allocates all required resources for Yukon2
++ *
++ * Description:
++ *    This function allocates all memory needed for the Yukon2. 
++ *    It maps also RX buffers to the LETables and initializes the
++ *    status list element table.
++ *
++ * Returns:   
++ *    SK_TRUE, if all resources could be allocated and setup succeeded
++ *    SK_FALSE, if an error 
++ */
++SK_BOOL SkY2AllocateResources (
++SK_AC  *pAC)  /* pointer to adapter control context */
++{
++      int CurrMac;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
++              ("==> SkY2AllocateResources\n"));
++
++      /*
++      ** Initialize the packet queue variables first
++      */
++      for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) {
++              InitPacketQueues(pAC, CurrMac);
++      }
++
++      /* 
++      ** Get sufficient memory for the LETables
++      */
++      if (!AllocateAndInitLETables(pAC)) {
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
++                      SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR,
++                      ("No memory for LETable.\n"));
++              return(SK_FALSE);
++      }
++
++      /*
++      ** Allocate and intialize memory for both RX and TX 
++      ** packet and fragment buffers. On an error, free 
++      ** previously allocated LETable memory and quit.
++      */
++      if (!AllocatePacketBuffersYukon2(pAC)) {
++              FreeLETables(pAC);
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
++                      SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR,
++                      ("No memory for Packetbuffers.\n"));
++              return(SK_FALSE);
++      }
++
++      /* 
++      ** Rx and Tx LE tables will be initialized in SkGeOpen() 
++      **
++      ** It might be that the TX timer is not started. Therefore
++      ** it is initialized here -> to be more investigated!
++      */
++      SK_OUT32(pAC->IoBase, STAT_TX_TIMER_INI, HW_MS_TO_TICKS(pAC,10));
++      SkGeY2InitStatBmu(pAC, pAC->IoBase, &pAC->StatusLETable);
++
++      pAC->MaxUnusedRxLeWorking = MAX_UNUSED_RX_LE_WORKING;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
++              ("<== SkY2AllocateResources\n"));
++
++      return (SK_TRUE);
++}
++
++/*****************************************************************************
++ *
++ *    SkY2FreeResources - Frees previously allocated resources of Yukon2
++ *
++ * Description:
++ *    This function frees all previously allocated memory of the Yukon2. 
++ *
++ * Returns: N/A
++ */
++void SkY2FreeResources (
++SK_AC  *pAC)  /* pointer to adapter control context */
++{
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("==> SkY2FreeResources\n"));
++
++      FreeLETables(pAC);
++      FreePacketBuffers(pAC);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("<== SkY2FreeResources\n"));
++}
++
++/*****************************************************************************
++ *
++ *    SkY2AllocateRxBuffers - Allocates the receive buffers for a port
++ *
++ * Description:
++ *    This function allocated all the RX buffers of the Yukon2. 
++ *
++ * Returns: N/A
++ */
++void SkY2AllocateRxBuffers (
++SK_AC    *pAC,   /* pointer to adapter control context */
++SK_IOC    IoC,         /* I/O control context                */
++int       Port)        /* port index of RX                   */
++{
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
++              ("==> SkY2AllocateRxBuffers (Port %c)\n", Port));
++
++      FillReceiveTableYukon2(pAC, IoC, Port);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
++              ("<== SkY2AllocateRxBuffers\n"));
++}
++
++/*****************************************************************************
++ *
++ *    SkY2FreeRxBuffers - Free's all allocates RX buffers of
++ *
++ * Description:
++ *    This function frees all RX buffers of the Yukon2 for a single port
++ *
++ * Returns: N/A
++ */
++void SkY2FreeRxBuffers (
++SK_AC    *pAC,   /* pointer to adapter control context */
++SK_IOC    IoC,         /* I/O control context                */
++int       Port)        /* port index of RX                   */
++{
++      SK_PACKET     *pSkPacket;
++      unsigned long  Flags;   /* for POP/PUSH macros */
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("==> SkY2FreeRxBuffers (Port %c)\n", Port));
++
++      if (pAC->RxPort[Port].ReceivePacketTable   != NULL) {
++              POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket);
++              while (pSkPacket != NULL) {
++                      if ((pSkPacket->pFrag) != NULL) {
++                              pci_unmap_page(pAC->PciDev,
++                              (dma_addr_t) pSkPacket->pFrag->pPhys,
++                              pSkPacket->pFrag->FragLen - 2,
++                              PCI_DMA_FROMDEVICE);
++
++                              DEV_KFREE_SKB_ANY(pSkPacket->pMBuf);
++                              pSkPacket->pMBuf        = NULL;
++                              pSkPacket->pFrag->pPhys = (SK_U64) 0;
++                              pSkPacket->pFrag->pVirt = NULL;
++                      }
++                      PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket);
++                      POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket);
++              }
++      }
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("<== SkY2FreeRxBuffers\n"));
++}
++
++/*****************************************************************************
++ *
++ *    SkY2FreeTxBuffers - Free's any currently maintained Tx buffer
++ *
++ * Description:
++ *    This function frees the TX buffers of the Yukon2 for a single port
++ *    which might be in use by a transmit action
++ *
++ * Returns: N/A
++ */
++void SkY2FreeTxBuffers (
++SK_AC    *pAC,   /* pointer to adapter control context */
++SK_IOC    IoC,         /* I/O control context                */
++int       Port)        /* port index of TX                   */
++{
++      SK_PACKET      *pSkPacket;
++      SK_FRAG        *pSkFrag;
++      unsigned long   Flags;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("==> SkY2FreeTxBuffers (Port %c)\n", Port));
++ 
++      if (pAC->TxPort[Port][0].TransmitPacketTable != NULL) {
++              POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxAQ_working, pSkPacket);
++              while (pSkPacket != NULL) {
++                      if ((pSkFrag = pSkPacket->pFrag) != NULL) {
++                              UnmapAndFreeTxPktBuffer(pAC, pSkPacket, Port);
++                      }
++                      PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->TxPort[Port][0].TxQ_free, pSkPacket);
++                      POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxAQ_working, pSkPacket);
++              }
++#if USE_SYNC_TX_QUEUE
++              POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxSQ_working, pSkPacket);
++              while (pSkPacket != NULL) {
++                      if ((pSkFrag = pSkPacket->pFrag) != NULL) {
++                              UnmapAndFreeTxPktBuffer(pAC, pSkPacket, Port);
++                      }
++                      PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->TxPort[Port][0].TxQ_free, pSkPacket);
++                      POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxSQ_working, pSkPacket);
++              }
++#endif
++      }
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("<== SkY2FreeTxBuffers\n"));
++}
++
++/*****************************************************************************
++ *
++ *    SkY2Isr - handle a receive IRQ for all yukon2 cards
++ *
++ * Description:
++ *    This function is called when a receive IRQ is set. (only for yukon2)
++ *    HandleReceives does the deferred processing of all outstanding
++ *    interrupt operations.
++ *
++ * Returns:   N/A
++ */
++SkIsrRetVar SkY2Isr (
++int              irq,     /* the irq we have received (might be shared!) */
++void            *dev_id,  /* current device id                           */
++struct  pt_regs *ptregs)  /* not used by our driver                      */
++{
++      struct SK_NET_DEVICE  *dev  = (struct SK_NET_DEVICE *)dev_id;
++      DEV_NET               *pNet = (DEV_NET*) dev->priv;
++      SK_AC                 *pAC  = pNet->pAC;
++      SK_U32                 IntSrc;
++      unsigned long          Flags;
++#ifndef CONFIG_SK98LIN_NAPI
++      SK_BOOL                handledStatLE    = SK_FALSE;
++#else
++      SK_BOOL                SetIntMask       = SK_FALSE;
++#endif
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++              ("==> SkY2Isr\n"));
++
++      SK_IN32(pAC->IoBase, B0_Y2_SP_ISRC2, &IntSrc);
++
++      if ((IntSrc == 0) && (!pNet->NetConsoleMode)){
++              SK_OUT32(pAC->IoBase, B0_Y2_SP_ICR, 2);
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++                      ("No Interrupt\n ==> SkY2Isr\n"));
++              return SkIsrRetNone;
++
++      }
++
++#ifdef Y2_RECOVERY
++      if (pNet->InRecover) {
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++                      ("Already in recover\n ==> SkY2Isr\n"));
++              SK_OUT32(pAC->IoBase, B0_Y2_SP_ICR, 2);
++              return SkIsrRetNone;
++      }
++#endif
++
++#ifdef CONFIG_SK98LIN_NAPI
++      if (netif_rx_schedule_prep(pAC->dev[0])) {
++              pAC->GIni.GIValIrqMask &= ~(Y2_IS_STAT_BMU);
++              SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
++              SetIntMask = SK_TRUE;
++              __netif_rx_schedule(pAC->dev[0]);
++      }
++
++      if (netif_rx_schedule_prep(pAC->dev[1])) {
++              if (!SetIntMask) {
++                      pAC->GIni.GIValIrqMask &= ~(Y2_IS_STAT_BMU);
++                      SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
++              }
++              __netif_rx_schedule(pAC->dev[1]);
++      }
++#else
++      handledStatLE = HandleStatusLEs(pAC);
++#endif
++
++      /* 
++      ** Check for Special Interrupts 
++      */
++      if ((IntSrc & ~Y2_IS_STAT_BMU) || pAC->CheckQueue || pNet->TimerExpired) {
++              pAC->CheckQueue = SK_FALSE;
++              spin_lock_irqsave(&pAC->SlowPathLock, Flags);
++#ifdef Y2_RECOVERY
++              if (pNet->TimerExpired) {
++                      SkGeCheckTimer(pNet);
++              }
++#endif
++              SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
++              SkEventDispatcher(pAC, pAC->IoBase);
++              spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
++      }
++
++      /* Speed enhancement for a2 chipsets */
++      if (HW_FEATURE(pAC, HWF_WA_DEV_42)) {
++              spin_lock_irqsave(&pAC->SetPutIndexLock, Flags);
++              SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_XA1,0), &pAC->TxPort[0][0].TxALET);
++              SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_R1,0), &pAC->RxPort[0].RxLET);
++              spin_unlock_irqrestore(&pAC->SetPutIndexLock, Flags);
++      }
++
++      /* 
++      ** Reenable interrupts and signal end of ISR 
++      */
++      SK_OUT32(pAC->IoBase, B0_Y2_SP_ICR, 2);
++                      
++      /*
++      ** Stop and restart TX timer in case a Status LE was handled
++      */
++#ifndef CONFIG_SK98LIN_NAPI
++      if ((HW_FEATURE(pAC, HWF_WA_DEV_43_418)) && (handledStatLE)) {
++              SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_STOP);
++              SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_START);
++      }
++#endif
++
++      if (!(IS_Q_EMPTY(&(pAC->TxPort[0][TX_PRIO_LOW].TxAQ_waiting)))) {
++              GiveTxBufferToHw(pAC, pAC->IoBase, 0);
++      }
++      if (!(IS_Q_EMPTY(&(pAC->TxPort[1][TX_PRIO_LOW].TxAQ_waiting)))) {
++              GiveTxBufferToHw(pAC, pAC->IoBase, 1);
++      }
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++              ("<== SkY2Isr\n"));
++
++      return SkIsrRetHandled;
++}     /* SkY2Isr */
++
++/*****************************************************************************
++ *
++ *    SkY2Xmit - Linux frame transmit function for Yukon2
++ *
++ * Description:
++ *    The system calls this function to send frames onto the wire.
++ *    It puts the frame in the tx descriptor ring. If the ring is
++ *    full then, the 'tbusy' flag is set.
++ *
++ * Returns:
++ *    0, if everything is ok
++ *    !=0, on error
++ *
++ * WARNING: 
++ *    returning 1 in 'tbusy' case caused system crashes (double
++ *    allocated skb's) !!!
++ */
++int SkY2Xmit(
++struct sk_buff       *skb,  /* socket buffer to be sent */
++struct SK_NET_DEVICE *dev)  /* via which device?        */
++{
++      DEV_NET         *pNet    = (DEV_NET*) dev->priv;
++      SK_AC           *pAC     = pNet->pAC;
++      SK_U8            FragIdx = 0;
++      SK_PACKET       *pSkPacket;
++      SK_FRAG         *PrevFrag;
++      SK_FRAG         *CurrFrag;
++      SK_PKT_QUEUE    *pWorkQueue;  /* corresponding TX queue */
++      SK_PKT_QUEUE    *pWaitQueue; 
++      SK_PKT_QUEUE    *pFreeQueue; 
++      SK_LE_TABLE     *pLETab;      /* corresponding LETable  */ 
++      skb_frag_t      *sk_frag;
++      SK_U64           PhysAddr;
++      unsigned long    Flags;
++      unsigned int     Port;
++      int              CurrFragCtr;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++              ("==> SkY2Xmit\n"));
++
++      /*
++      ** Get port and return if no free packet is available 
++      */
++      if (skb_shinfo(skb)->nr_frags > MAX_SKB_FRAGS) {
++              Port = skb_shinfo(skb)->nr_frags - (2*MAX_SKB_FRAGS);
++              skb_shinfo(skb)->nr_frags = 0;
++      } else {
++              Port = (pAC->RlmtNets == 2) ? pNet->PortNr : pAC->ActivePort;
++      }
++
++      if (IS_Q_EMPTY(&(pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free))) {
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
++                      SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR,
++                      ("Not free packets available for send\n"));
++              return 1; /* zero bytes sent! */
++      }
++
++      /*
++      ** Put any new packet to be sent in the waiting queue and 
++      ** handle also any possible fragment of that packet.
++      */
++      pWorkQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working);
++      pWaitQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting);
++      pFreeQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free);
++      pLETab     = &(pAC->TxPort[Port][TX_PRIO_LOW].TxALET);
++
++      /*
++      ** Normal send operations require only one fragment, because 
++      ** only one sk_buff data area is passed. 
++      ** In contradiction to this, scatter-gather (zerocopy) send
++      ** operations might pass one or more additional fragments 
++      ** where each fragment needs a separate fragment info packet.
++      */
++      if (((skb_shinfo(skb)->nr_frags + 1) * MAX_FRAG_OVERHEAD) > 
++                                      NUM_FREE_LE_IN_TABLE(pLETab)) {
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
++                      SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR,
++                      ("Not enough LE available for send\n"));
++              return 1; /* zero bytes sent! */
++      }
++      
++      if ((skb_shinfo(skb)->nr_frags + 1) > MAX_NUM_FRAGS) {
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
++                      SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR,
++                      ("Not even one fragment available for send\n"));
++              return 1; /* zero bytes sent! */
++      }
++
++      /*
++      ** Get first packet from free packet queue
++      */
++      POP_FIRST_PKT_FROM_QUEUE(pFreeQueue, pSkPacket);
++      if(pSkPacket == NULL) {
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
++                      SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR,
++                      ("Could not obtain free packet used for xmit\n"));
++              return 1; /* zero bytes sent! */
++      }
++
++      pSkPacket->pFrag = &(pSkPacket->FragArray[FragIdx]);
++
++      /* 
++      ** map the sk_buff to be available for the adapter 
++      */
++      PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
++                      virt_to_page(skb->data),
++                      ((unsigned long) skb->data & ~PAGE_MASK),
++                      skb_headlen(skb),
++                      PCI_DMA_TODEVICE);
++      pSkPacket->pMBuf          = skb;
++      pSkPacket->pFrag->pPhys   = PhysAddr;
++      pSkPacket->pFrag->FragLen = skb_headlen(skb);
++      pSkPacket->pFrag->pNext   = NULL; /* initial has no next default */
++      pSkPacket->NumFrags       = skb_shinfo(skb)->nr_frags + 1;
++
++      PrevFrag = pSkPacket->pFrag;
++
++      /*
++      ** Each scatter-gather fragment need to be mapped...
++      */
++        for ( CurrFragCtr = 0; 
++              CurrFragCtr < skb_shinfo(skb)->nr_frags;
++              CurrFragCtr++) {
++              FragIdx++;
++              sk_frag = &skb_shinfo(skb)->frags[CurrFragCtr];
++              CurrFrag = &(pSkPacket->FragArray[FragIdx]);
++
++              /* 
++              ** map the sk_buff to be available for the adapter 
++              */
++              PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
++                              sk_frag->page,
++                              sk_frag->page_offset,
++                              sk_frag->size,
++                              PCI_DMA_TODEVICE);
++
++              CurrFrag->pPhys   = PhysAddr;
++              CurrFrag->FragLen = sk_frag->size;
++              CurrFrag->pNext   = NULL;
++
++              /*
++              ** Add the new fragment to the list of fragments
++              */
++              PrevFrag->pNext = CurrFrag;
++              PrevFrag = CurrFrag;
++      }
++
++      /* 
++      ** Add packet to waiting packets queue 
++      */
++      PUSH_PKT_AS_LAST_IN_QUEUE(pWaitQueue, pSkPacket);
++      GiveTxBufferToHw(pAC, pAC->IoBase, Port);
++      dev->trans_start = jiffies;
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++              ("<== SkY2Xmit(return 0)\n"));
++      return (0);
++}     /* SkY2Xmit */
++
++#ifdef CONFIG_SK98LIN_NAPI
++/*****************************************************************************
++ *
++ *    SkY2Poll - NAPI Rx polling callback for Yukon2 chipsets
++ *
++ * Description:
++ *    Called by the Linux system in case NAPI polling is activated
++ *
++ * Returns
++ *    The number of work data still to be handled
++ *
++ * Notes
++ *    The slowpath lock needs to be set because HW accesses may
++ *    interfere with slowpath events (e.g. TWSI)
++ */
++int SkY2Poll(
++struct net_device *dev,     /* device that needs to be polled */
++int               *budget)  /* how many budget do we have?    */
++{
++      SK_AC          *pAC           = ((DEV_NET*)(dev->priv))->pAC;
++      int             WorkToDo      = min(*budget, dev->quota);
++      int             WorkDone      = 0;
++      SK_BOOL         handledStatLE = SK_FALSE;
++      unsigned long   Flags;       
++
++      spin_lock_irqsave(&pAC->SlowPathLock, Flags);
++      handledStatLE = HandleStatusLEs(pAC, &WorkDone, WorkToDo);
++
++      *budget -= WorkDone;
++      dev->quota -= WorkDone;
++
++      if(WorkDone < WorkToDo) {
++              netif_rx_complete(dev);
++              pAC->GIni.GIValIrqMask |= (Y2_IS_STAT_BMU);
++              SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
++              if ((HW_FEATURE(pAC, HWF_WA_DEV_43_418)) && (handledStatLE)) {
++                      SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_STOP);
++                      SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_START);
++              }
++      }
++      spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
++      return (WorkDone >= WorkToDo);
++}     /* SkY2Poll */
++#endif
++
++/******************************************************************************
++ *
++ *    SkY2PortStop - stop a port on Yukon2
++ *
++ * Description:
++ *    This function stops a port of the Yukon2 chip. This stop 
++ *    stop needs to be performed in a specific order:
++ * 
++ *    a) Stop the Prefetch unit
++ *    b) Stop the Port (MAC, PHY etc.)
++ *
++ * Returns: N/A
++ */
++void SkY2PortStop(
++SK_AC   *pAC,      /* adapter control context                             */
++SK_IOC   IoC,      /* I/O control context (address of adapter registers)  */
++int      Port,     /* port to stop (MAC_1 + n)                            */
++int      Dir,      /* StopDirection (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */
++int      RstMode)  /* Reset Mode (SK_SOFT_RST, SK_HARD_RST)               */
++{
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("==> SkY2PortStop (Port %c)\n", 'A' + Port));
++
++      /*
++      ** Stop the HW
++      */
++      SkGeStopPort(pAC, IoC, Port, Dir, RstMode);
++
++      /*
++      ** Move any TX packet from work queues into the free queue again
++      ** and initialize the TX LETable variables
++      */
++      SkY2FreeTxBuffers(pAC, pAC->IoBase, Port);
++      pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Bmu.RxTx.TcpWp    = 0;
++      pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Bmu.RxTx.MssValue = 0;
++      pAC->TxPort[Port][TX_PRIO_LOW].TxALET.BufHighAddr       = 0;
++      pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Done              = 0;    
++      pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Put               = 0;
++      // pAC->GIni.GP[Port].PState = SK_PRT_STOP;
++
++      /*
++      ** Move any RX packet from work queue into the waiting queue
++      ** and initialize the RX LETable variables
++      */
++      SkY2FreeRxBuffers(pAC, pAC->IoBase, Port);
++      pAC->RxPort[Port].RxLET.BufHighAddr = 0;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("<== SkY2PortStop()\n"));
++}
++
++/******************************************************************************
++ *
++ *    SkY2PortStart - start a port on Yukon2
++ *
++ * Description:
++ *    This function starts a port of the Yukon2 chip. This start 
++ *    action needs to be performed in a specific order:
++ * 
++ *    a) Initialize the LET indices (PUT/GET to 0)
++ *    b) Initialize the LET in HW (enables also prefetch unit)
++ *    c) Move all RX buffers from waiting queue to working queue
++ *       which involves also setting up of RX list elements
++ *    d) Initialize the FIFO settings of Yukon2 (Watermark etc.)
++ *    e) Initialize the Port (MAC, PHY etc.)
++ *    f) Initialize the MC addresses
++ *
++ * Returns:   N/A
++ */
++void SkY2PortStart(
++SK_AC   *pAC,   /* adapter control context                            */
++SK_IOC   IoC,   /* I/O control context (address of adapter registers) */
++int      Port)  /* port to start                                      */
++{
++      // SK_GEPORT *pPrt = &pAC->GIni.GP[Port];
++      SK_HWLE   *pLE;
++      SK_U32     DWord;
++      SK_U32     PrefetchReg; /* register for Put index */
++#if defined(__x86_64__)
++      long       cache0, cache1;
++#endif
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("==> SkY2PortStart (Port %c)\n", 'A' + Port));
++
++      /*
++      ** Initialize the LET indices
++      */
++      pAC->RxPort[Port].RxLET.Done                = 0; 
++      pAC->RxPort[Port].RxLET.Put                 = 0;
++      pAC->RxPort[Port].RxLET.HwPut               = 0;
++      pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Done  = 0;    
++      pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Put   = 0;
++      pAC->TxPort[Port][TX_PRIO_LOW].TxALET.HwPut = 0;
++      if (HW_SYNC_TX_SUPPORTED(pAC)) {
++              pAC->TxPort[Port][TX_PRIO_LOW].TxSLET.Done  = 0;    
++              pAC->TxPort[Port][TX_PRIO_LOW].TxSLET.Put   = 0;
++              pAC->TxPort[Port][TX_PRIO_LOW].TxSLET.HwPut = 0;
++      }
++      
++      if (HW_FEATURE(pAC, HWF_WA_DEV_420)) {
++              /*
++              ** It might be that we have to limit the RX buffers 
++              ** effectively passed to HW. Initialize the start
++              ** value in that case...
++              */
++              NbrRxBuffersInHW = 0;
++      }
++
++      /*
++      ** TODO on dual net adapters we need to check if
++      ** StatusLETable need to be set...
++      ** 
++      ** pAC->StatusLETable.Done  = 0;
++      ** pAC->StatusLETable.Put   = 0;
++      ** pAC->StatusLETable.HwPut = 0;
++      ** SkGeY2InitPrefetchUnit(pAC, pAC->IoBase, Q_ST, &pAC->StatusLETable);
++      */
++
++      /*
++      ** Initialize the LET in HW (enables also prefetch unit)
++      */
++      SkGeY2InitPrefetchUnit(pAC, IoC,(Port == 0) ? Q_R1 : Q_R2,
++                      &pAC->RxPort[Port].RxLET);
++      SkGeY2InitPrefetchUnit( pAC, IoC,(Port == 0) ? Q_XA1 : Q_XA2, 
++                      &pAC->TxPort[Port][TX_PRIO_LOW].TxALET);
++      if (HW_SYNC_TX_SUPPORTED(pAC)) {
++              SkGeY2InitPrefetchUnit( pAC, IoC, (Port == 0) ? Q_XS1 : Q_XS2,
++                              &pAC->TxPort[Port][TX_PRIO_HIGH].TxSLET);
++      }
++
++
++      /*
++      ** Using new values for the watermarks and the timer for
++      ** low latency optimization
++      */
++      if (pAC->LowLatency) {
++              SK_OUT8(IoC, STAT_FIFO_WM, 1);
++              SK_OUT8(IoC, STAT_FIFO_ISR_WM, 1);
++              SK_OUT32(IoC, STAT_LEV_TIMER_INI, 50);
++              SK_OUT32(IoC, STAT_ISR_TIMER_INI, 10);
++      }
++
++
++      /*
++      ** Initialize the Port (MAC, PHY etc.)
++      */
++      if (SkGeInitPort(pAC, IoC, Port)) {
++              if (Port == 0) {
++                      printk("%s: SkGeInitPort A failed.\n",pAC->dev[0]->name);
++              } else {
++                      printk("%s: SkGeInitPort B failed.\n",pAC->dev[1]->name);
++              }
++      }
++      
++      if (IS_GMAC(pAC)) {
++              /* disable Rx GMAC FIFO Flush Mode */
++              SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8) GMF_RX_F_FL_OFF);
++      }
++
++      /*
++      ** Initialize the MC addresses
++      */
++      SkAddrMcUpdate(pAC,IoC, Port);
++
++      SkMacRxTxEnable(pAC, IoC,Port);
++                              
++      if (pAC->RxPort[Port].UseRxCsum) {
++              SkGeRxCsum(pAC, IoC, Port, SK_TRUE);
++      
++              GET_RX_LE(pLE, &pAC->RxPort[Port].RxLET);
++              RXLE_SET_STACS1(pLE, pAC->CsOfs1);
++              RXLE_SET_STACS2(pLE, pAC->CsOfs2);
++              RXLE_SET_CTRL(pLE, 0);
++
++              RXLE_SET_OPC(pLE, OP_TCPSTART | HW_OWNER);
++              FLUSH_OPC(pLE);
++              if (Port == 0) {
++                      PrefetchReg=Y2_PREF_Q_ADDR(Q_R1,PREF_UNIT_PUT_IDX_REG);
++              } else {
++                      PrefetchReg=Y2_PREF_Q_ADDR(Q_R2,PREF_UNIT_PUT_IDX_REG);
++              }
++              DWord = GET_PUT_IDX(&pAC->RxPort[Port].RxLET);
++              SK_OUT32(IoC, PrefetchReg, DWord);
++              UPDATE_HWPUT_IDX(&pAC->RxPort[Port].RxLET);
++      }
++
++      pAC->GIni.GP[Port].PState = SK_PRT_RUN;
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("<== SkY2PortStart()\n"));
++}
++
++/******************************************************************************
++ *
++ * Local Functions
++ *
++ *****************************************************************************/
++
++/*****************************************************************************
++ *
++ *    InitPacketQueues - initialize SW settings of packet queues
++ *
++ * Description:
++ *    This function will initialize the packet queues for a port.
++ *
++ * Returns: N/A
++ */
++static void InitPacketQueues(
++SK_AC  *pAC,   /* pointer to adapter control context */
++int     Port)  /* index of port to be initialized    */
++{
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
++              ("==> InitPacketQueues(Port %c)\n", 'A' + Port));
++      
++      pAC->RxPort[Port].RxQ_working.pHead = NULL;
++      pAC->RxPort[Port].RxQ_working.pTail = NULL;
++      spin_lock_init(&pAC->RxPort[Port].RxQ_working.QueueLock);
++      
++      pAC->RxPort[Port].RxQ_waiting.pHead = NULL;
++      pAC->RxPort[Port].RxQ_waiting.pTail = NULL;
++      spin_lock_init(&pAC->RxPort[Port].RxQ_waiting.QueueLock);
++      
++      pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free.pHead = NULL;
++      pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free.pTail = NULL;
++      spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free.QueueLock);
++
++      pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working.pHead = NULL;
++      pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working.pTail = NULL;
++      spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working.QueueLock);
++      
++      pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting.pHead = NULL;
++      pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting.pTail = NULL;
++      spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting.QueueLock);
++      
++#if USE_SYNC_TX_QUEUE
++      pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.pHead = NULL;
++      pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.pTail = NULL;
++      spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.QueueLock);
++
++      pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_waiting.pHead = NULL;
++      pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_waiting.pTail = NULL;
++      spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_waiting.QueueLock);
++#endif
++      
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
++              ("<== InitPacketQueues(Port %c)\n", 'A' + Port));
++}     /* InitPacketQueues */
++
++/*****************************************************************************
++ *
++ *    GiveTxBufferToHw - commits a previously allocated DMA area to HW
++ *
++ * Description:
++ *    This functions gives transmit buffers to HW. If no list elements
++ *    are available the buffers will be queued. 
++ *
++ * Notes:
++ *       This function can run only once in a system at one time.
++ *
++ * Returns: N/A
++ */
++static void GiveTxBufferToHw(
++SK_AC   *pAC,   /* pointer to adapter control context         */
++SK_IOC   IoC,   /* I/O control context (address of registers) */
++int      Port)  /* port index for which the buffer is used    */
++{
++      SK_HWLE         *pLE;
++      SK_PACKET       *pSkPacket;
++      SK_FRAG         *pFrag;
++      SK_PKT_QUEUE    *pWorkQueue;   /* corresponding TX queue */
++      SK_PKT_QUEUE    *pWaitQueue; 
++      SK_LE_TABLE     *pLETab;       /* corresponding LETable  */ 
++      SK_BOOL          SetOpcodePacketFlag;
++      SK_U32           HighAddress;
++      SK_U32           LowAddress;
++      SK_U16           TcpSumStart; 
++      SK_U16           TcpSumWrite;
++      SK_U8            OpCode;
++      SK_U8            Ctrl;
++      unsigned long    Flags;
++      unsigned long    LockFlag;
++      int              Protocol;
++#ifdef NETIF_F_TSO
++      SK_U16           Mss;
++      int              TcpOptLen;
++      int              IpTcpLen;
++#endif
++#if defined(__x86_64__)
++      long             cache0, cache1;
++#endif
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++              ("==> GiveTxBufferToHw\n"));
++
++      if (IS_Q_EMPTY(&(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting))) {
++              return;
++      }
++
++      spin_lock_irqsave(&pAC->TxQueueLock, LockFlag);
++
++      /*
++      ** Initialize queue settings
++      */
++      pWorkQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working);
++      pWaitQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting);
++      pLETab     = &(pAC->TxPort[Port][TX_PRIO_LOW].TxALET);
++
++      POP_FIRST_PKT_FROM_QUEUE(pWaitQueue, pSkPacket);
++      while (pSkPacket != NULL) {
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++                      ("\tWe have a packet to send %p\n", pSkPacket));
++
++              /* 
++              ** the first frag of a packet gets opcode OP_PACKET 
++              */
++              SetOpcodePacketFlag     = SK_TRUE;
++              pFrag                   = pSkPacket->pFrag;
++
++              /* 
++              ** fill list elements with data from fragments 
++              */
++              while (pFrag != NULL) {
++                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++                              ("\tGet LE\n"));
++#ifdef NETIF_F_TSO
++                      Mss = skb_shinfo(pSkPacket->pMBuf)->tso_size;
++                      if (Mss) {
++                              TcpOptLen = ((pSkPacket->pMBuf->h.th->doff - 5) * 4);
++                              IpTcpLen  = ((pSkPacket->pMBuf->nh.iph->ihl * 4) + 
++                                              sizeof(struct tcphdr));
++                              Mss += (TcpOptLen + IpTcpLen + C_LEN_ETHERMAC_HEADER);
++                      }
++                      if (pLETab->Bmu.RxTx.MssValue != Mss) {
++                              pLETab->Bmu.RxTx.MssValue = Mss;
++                              /* Take a new LE for TSO from the table */
++                              GET_TX_LE(pLE, pLETab);
++
++#if 0
++                              if(pSkPacket->VlanId) {
++                                      TXLE_SET_OPC(pLE, OP_LRGLENVLAN | HW_OWNER);
++                                      TXLE_SET_VLAN(pLE, pSkPacket->VlanId);
++                                      pSkPacket->VlanId = 0;
++                                      Ctrl |= INS_VLAN;
++                              } else {
++#endif
++                                      TXLE_SET_OPC(pLE, OP_LRGLEN | HW_OWNER);
++#if 0
++                              }
++#endif
++                              /* set maximum segment size for new packet */
++                              TXLE_SET_LSLEN(pLE, pLETab->Bmu.RxTx.MssValue);
++                              FLUSH_OPC(pLE) ;
++                      }
++#endif
++                      GET_TX_LE(pLE, pLETab);
++                      Ctrl = 0;
++
++                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++                              ("\tGot empty LE %p idx %d\n", pLE, GET_PUT_IDX(pLETab)));
++
++                      SK_DBG_DUMP_TX_LE(pLE);
++
++                      LowAddress  = (SK_U32) (pFrag->pPhys & 0xffffffff);
++                      HighAddress = (SK_U32) (pFrag->pPhys >> 32);
++                      if (HighAddress != pLETab->BufHighAddr) {
++                              /* set opcode high part of the address in one LE */
++                              OpCode = OP_ADDR64 | HW_OWNER;
++      
++                              /* Set now the 32 high bits of the address */
++                              TXLE_SET_ADDR( pLE, HighAddress);
++      
++                              /* Set the opcode into the LE */
++                              TXLE_SET_OPC(pLE, OpCode);
++      
++                              /* Flush the LE to memory */
++                              FLUSH_OPC(pLE);
++      
++                              /* remember the HighAddress we gave to the Hardware */
++                              pLETab->BufHighAddr = HighAddress;
++                              
++                              /* get a new LE because we filled one with high address */
++                              GET_TX_LE(pLE, pLETab);
++                      }
++      
++                      /*
++                      ** TCP checksum offload
++                      */
++                      if ((pSkPacket->pMBuf->ip_summed == CHECKSUM_HW) && 
++                          (SetOpcodePacketFlag         == SK_TRUE)) {
++                              Protocol = ((SK_U8)pSkPacket->pMBuf->data[C_OFFSET_IPPROTO] & 0xff);
++                              /* if (Protocol & C_PROTO_ID_IP) { Ctrl = 0; } */ 
++                              if (Protocol & C_PROTO_ID_TCP) {
++                                      Ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
++                                      /* TCP Checksum Calculation Start Position */
++                                      TcpSumStart = C_LEN_ETHERMAC_HEADER + IP_HDR_LEN;
++                                      /* TCP Checksum Write Position */
++                                      TcpSumWrite = TcpSumStart + TCP_CSUM_OFFS;
++                              } else {
++                                      Ctrl = UDPTCP | CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
++                                      /* TCP Checksum Calculation Start Position */
++                                      TcpSumStart = ETHER_MAC_HDR_LEN + IP_HDR_LEN;
++                                      /* UDP Checksum Write Position */
++                                      TcpSumWrite = TcpSumStart + UDP_CSUM_OFFS;
++                              }
++      
++                              if ((Ctrl) && (pLETab->Bmu.RxTx.TcpWp != TcpSumWrite)) {
++                                      /* Update the last value of the write position */
++                                      pLETab->Bmu.RxTx.TcpWp = TcpSumWrite;
++      
++                                      /* Set the Lock field for this LE: */
++                                      /* Checksum calculation for one packet only */
++                                      TXLE_SET_LCKCS(pLE, 1);
++      
++                                      /* Set the start position for checksum. */
++                                      TXLE_SET_STACS(pLE, TcpSumStart);
++      
++                                      /* Set the position where the checksum will be writen */
++                                      TXLE_SET_WRICS(pLE, TcpSumWrite);
++      
++                                      /* Set the initial value for checksum */
++                                      /* PseudoHeader CS passed from Linux -> 0! */
++                                      TXLE_SET_INICS(pLE, 0);
++      
++                                      /* Set the opcode for tcp checksum */
++                                      TXLE_SET_OPC(pLE, OP_TCPLISW | HW_OWNER);
++      
++                                      /* Flush the LE to memory */
++                                      FLUSH_OPC(pLE);
++      
++                                      /* get a new LE because we filled one with data for checksum */
++                                      GET_TX_LE(pLE, pLETab);
++                              }
++                      } /* end TCP offload handling */
++      
++                      TXLE_SET_ADDR(pLE, LowAddress);
++                      TXLE_SET_LEN(pLE, pFrag->FragLen);
++      
++                      if (SetOpcodePacketFlag){
++#ifdef NETIF_F_TSO
++                              if (Mss) {
++                                      OpCode = OP_LARGESEND | HW_OWNER;
++                              } else {
++#endif
++                                      OpCode = OP_PACKET| HW_OWNER;
++#ifdef NETIF_F_TSO
++                              }
++#endif
++                              SetOpcodePacketFlag = SK_FALSE;
++                      } else {
++                              /* Follow packet in a sequence has always OP_BUFFER */
++                              OpCode = OP_BUFFER | HW_OWNER;
++                      }
++      
++                      pFrag = pFrag->pNext;
++                      if (pFrag == NULL) {
++                              /* mark last fragment */
++                              Ctrl |= EOP;
++                      }
++                      TXLE_SET_CTRL(pLE, Ctrl);
++                      TXLE_SET_OPC(pLE, OpCode);
++                      FLUSH_OPC(pLE);
++                      SK_DBG_DUMP_TX_LE(pLE);
++              }
++      
++              /* 
++              ** Remember next LE for tx complete 
++              */
++              pSkPacket->NextLE = GET_PUT_IDX(pLETab);
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++                      ("\tNext LE for pkt %p is %d\n", pSkPacket, pSkPacket->NextLE));
++
++              /* 
++              ** Add packet to working packets queue 
++              */
++              PUSH_PKT_AS_LAST_IN_QUEUE(pWorkQueue, pSkPacket);
++
++              /* 
++              ** give transmit start command
++              */
++              if (HW_FEATURE(pAC, HWF_WA_DEV_42)) {
++                      spin_lock(&pAC->SetPutIndexLock);
++                      SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_XA1,0), &pAC->TxPort[0][0].TxALET);
++                      spin_unlock(&pAC->SetPutIndexLock);
++              } else {
++                      /* write put index */
++                      if (Port == 0) { 
++                              SK_OUT32(pAC->IoBase, 
++                                      Y2_PREF_Q_ADDR(Q_XA1,PREF_UNIT_PUT_IDX_REG), 
++                                      GET_PUT_IDX(&pAC->TxPort[0][0].TxALET)); 
++                              UPDATE_HWPUT_IDX(&pAC->TxPort[0][0].TxALET);
++                      } else {
++                              SK_OUT32(pAC->IoBase, 
++                                      Y2_PREF_Q_ADDR(Q_XA2, PREF_UNIT_PUT_IDX_REG), 
++                                      GET_PUT_IDX(&pAC->TxPort[1][0].TxALET)); 
++                              UPDATE_HWPUT_IDX(&pAC->TxPort[1][0].TxALET);
++                      }
++              }
++      
++              if (IS_Q_EMPTY(&(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting))) {
++                      break; /* get out of while */
++              }
++              POP_FIRST_PKT_FROM_QUEUE(pWaitQueue, pSkPacket);
++      } /* while (pSkPacket != NULL) */
++
++      spin_unlock_irqrestore(&pAC->TxQueueLock, LockFlag);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++              ("<== GiveTxBufferToHw\n"));
++      return;
++}     /* GiveTxBufferToHw */
++
++/***********************************************************************
++ *
++ *    GiveRxBufferToHw - commits a previously allocated DMA area to HW
++ *
++ * Description:
++ *    This functions gives receive buffers to HW. If no list elements
++ *    are available the buffers will be queued. 
++ *
++ * Notes:
++ *       This function can run only once in a system at one time.
++ *
++ * Returns: N/A
++ */
++static void GiveRxBufferToHw(
++SK_AC      *pAC,      /* pointer to adapter control context         */
++SK_IOC      IoC,      /* I/O control context (address of registers) */
++int         Port,     /* port index for which the buffer is used    */
++SK_PACKET  *pPacket)  /* receive buffer(s)                          */
++{
++      SK_HWLE         *pLE;
++      SK_LE_TABLE     *pLETab;
++      SK_BOOL         Done = SK_FALSE;  /* at least on LE changed? */
++      SK_U32          LowAddress;
++      SK_U32          HighAddress;
++      SK_U32          PrefetchReg;      /* register for Put index  */
++      unsigned        NumFree;
++      unsigned        Required;
++      unsigned long   Flags;
++#if defined(__x86_64__)
++      long            cache0, cache1;
++#endif
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++      ("==> GiveRxBufferToHw(Port %c, Packet %p)\n", 'A' + Port, pPacket));
++
++      pLETab  = &pAC->RxPort[Port].RxLET;
++
++      if (Port == 0) {
++              PrefetchReg = Y2_PREF_Q_ADDR(Q_R1, PREF_UNIT_PUT_IDX_REG);
++      } else {
++              PrefetchReg = Y2_PREF_Q_ADDR(Q_R2, PREF_UNIT_PUT_IDX_REG);
++      } 
++
++      if (pPacket != NULL) {
++              /*
++              ** For the time being, we have only one packet passed
++              ** to this function which might be changed in future!
++              */
++              PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket);
++      }
++
++      /* 
++      ** now pPacket contains the very first waiting packet
++      */
++      POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket);
++      while (pPacket != NULL) {
++              if (HW_FEATURE(pAC, HWF_WA_DEV_420)) {
++                      if (NbrRxBuffersInHW >= MAX_NBR_RX_BUFFERS_IN_HW) {
++                              PUSH_PKT_AS_FIRST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket);
++                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++                                      ("<== GiveRxBufferToHw()\n"));
++                              return;
++                      } 
++                      NbrRxBuffersInHW++;
++              }
++
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++                      ("Try to add packet %p\n", pPacket));
++
++              /* 
++              ** Check whether we have enough listelements:
++              **
++              ** we have to take into account that each fragment 
++              ** may need an additional list element for the high 
++              ** part of the address here I simplified it by 
++              ** using MAX_FRAG_OVERHEAD maybe it's worth to split 
++              ** this constant for Rx and Tx or to calculate the
++              ** real number of needed LE's
++              */
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++                      ("\tNum %d Put %d Done %d Free %d %d\n",
++                      pLETab->Num, pLETab->Put, pLETab->Done,
++                      NUM_FREE_LE_IN_TABLE(pLETab),
++                      (NUM_FREE_LE_IN_TABLE(pLETab))));
++
++              Required = pPacket->NumFrags + MAX_FRAG_OVERHEAD;
++              NumFree = NUM_FREE_LE_IN_TABLE(pLETab);
++              if (NumFree) {
++                      NumFree--;
++              }
++
++              if (Required > NumFree ) {
++                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
++                              SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR,
++                              ("\tOut of LEs have %d need %d\n",
++                              NumFree, Required));
++
++                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++                              ("\tWaitQueue starts with packet %p\n", pPacket));
++                      PUSH_PKT_AS_FIRST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket);
++                      if (Done) {
++                              /*
++                              ** write Put index to BMU or Polling Unit and make the LE's
++                              ** available for the hardware
++                              */
++                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++                                      ("\tWrite new Put Idx\n"));
++
++                              SK_OUT32(IoC, PrefetchReg, GET_PUT_IDX(pLETab));
++                              UPDATE_HWPUT_IDX(pLETab);
++                      }
++                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++                              ("<== GiveRxBufferToHw()\n"));
++                      return;
++              } else {
++                      if (!AllocAndMapRxBuffer(pAC, pPacket, Port)) {
++                              /*
++                              ** Failure while allocating sk_buff might
++                              ** be due to temporary short of resources
++                              ** Maybe next time buffers are available.
++                              ** Until this, the packet remains in the 
++                              ** RX waiting queue...
++                              */
++                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
++                                      SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR,
++                                      ("Failed to allocate Rx buffer\n"));
++
++                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++                                      ("WaitQueue starts with packet %p\n", pPacket));
++                              PUSH_PKT_AS_FIRST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket);
++                              if (Done) {
++                                      /*
++                                      ** write Put index to BMU or Polling 
++                                      ** Unit and make the LE's
++                                      ** available for the hardware
++                                      */
++                                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++                                              ("\tWrite new Put Idx\n"));
++      
++                                      SK_OUT32(IoC, PrefetchReg, GET_PUT_IDX(pLETab));
++                                      UPDATE_HWPUT_IDX(pLETab);
++                              }
++                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++                                      ("<== GiveRxBufferToHw()\n"));
++                              return;
++                      }
++              }
++              Done = SK_TRUE;
++
++              LowAddress = (SK_U32) (pPacket->pFrag->pPhys & 0xffffffff);
++              HighAddress = (SK_U32) (pPacket->pFrag->pPhys >> 32);
++              if (HighAddress != pLETab->BufHighAddr) {
++                      /* get a new LE for high address */
++                      GET_RX_LE(pLE, pLETab);
++
++                      /* Set now the 32 high bits of the address */
++                      RXLE_SET_ADDR(pLE, HighAddress);
++
++                      /* Set the control bits of the address */
++                      RXLE_SET_CTRL(pLE, 0);
++
++                      /* Set the opcode into the LE */
++                      RXLE_SET_OPC(pLE, (OP_ADDR64 | HW_OWNER));
++
++                      /* Flush the LE to memory */
++                      FLUSH_OPC(pLE);
++
++                      /* remember the HighAddress we gave to the Hardware */
++                      pLETab->BufHighAddr = HighAddress;
++              }
++
++              /*
++              ** Fill data into listelement
++              */
++              GET_RX_LE(pLE, pLETab);
++              RXLE_SET_ADDR(pLE, LowAddress);
++              RXLE_SET_LEN(pLE, pPacket->pFrag->FragLen);
++              RXLE_SET_CTRL(pLE, 0);
++              RXLE_SET_OPC(pLE, (OP_PACKET | HW_OWNER));
++              FLUSH_OPC(pLE);
++
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++                      ("=== LE filled\n"));
++
++              SK_DBG_DUMP_RX_LE(pLE);
++
++              /* 
++              ** Remember next LE for rx complete 
++              */
++              pPacket->NextLE = GET_PUT_IDX(pLETab);
++
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++                      ("\tPackets Next LE is %d\n", pPacket->NextLE));
++
++              /* 
++              ** Add packet to working receive buffer queue and get
++              ** any next packet out of the waiting queue
++              */
++              PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_working, pPacket);
++              if (IS_Q_EMPTY(&(pAC->RxPort[Port].RxQ_waiting))) {
++                      break; /* get out of while processing */
++              }
++              POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket);
++      }
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++              ("\tWaitQueue is empty\n"));
++
++      if (Done) {
++              /*
++              ** write Put index to BMU or Polling Unit and make the LE's
++              ** available for the hardware
++              */
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++                      ("\tWrite new Put Idx\n"));
++
++              /* Speed enhancement for a2 chipsets */
++              if (HW_FEATURE(pAC, HWF_WA_DEV_42)) {
++                      spin_lock_irqsave(&pAC->SetPutIndexLock, Flags);
++                      SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_R1,0), pLETab);
++                      spin_unlock_irqrestore(&pAC->SetPutIndexLock, Flags);
++              } else {
++                      /* write put index */
++                      if (Port == 0) { 
++                              SK_OUT32(IoC, 
++                                      Y2_PREF_Q_ADDR(Q_R1, PREF_UNIT_PUT_IDX_REG), 
++                                      GET_PUT_IDX(pLETab)); 
++                      } else {
++                              SK_OUT32(IoC, 
++                                      Y2_PREF_Q_ADDR(Q_R2, PREF_UNIT_PUT_IDX_REG), 
++                                      GET_PUT_IDX(pLETab)); 
++                      }
++
++                      /* Update put index */
++                      UPDATE_HWPUT_IDX(pLETab);
++              }
++      }
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++              ("<== GiveRxBufferToHw()\n"));
++}       /* GiveRxBufferToHw */
++
++/***********************************************************************
++ *
++ *    FillReceiveTableYukon2 - map any waiting RX buffers to HW
++ *
++ * Description:
++ *    If the list element table contains more empty elements than 
++ *    specified this function tries to refill them.
++ *
++ * Notes:
++ *       This function can run only once per port in a system at one time.
++ *
++ * Returns: N/A
++ */
++static void FillReceiveTableYukon2(
++SK_AC   *pAC,   /* pointer to adapter control context */
++SK_IOC   IoC,   /* I/O control context                */
++int      Port)  /* port index of RX                   */
++{
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++              ("==> FillReceiveTableYukon2 (Port %c)\n", 'A' + Port));
++
++      if (NUM_FREE_LE_IN_TABLE(&pAC->RxPort[Port].RxLET) >
++              pAC->MaxUnusedRxLeWorking) {
++
++              /* 
++              ** Give alle waiting receive buffers down 
++              ** The queue holds all RX packets that
++              ** need a fresh allocation of the sk_buff.
++              */
++              if (pAC->RxPort[Port].RxQ_waiting.pHead != NULL) {
++                      SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++                      ("Waiting queue is not empty -> give it to HW"));
++                      GiveRxBufferToHw(pAC, IoC, Port, NULL);
++              }
++      }
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++              ("<== FillReceiveTableYukon2 ()\n"));
++}     /* FillReceiveTableYukon2 */
++
++/******************************************************************************
++ *
++ *
++ *    HandleReceives - will pass any ready RX packet to kernel
++ *
++ * Description:
++ *    This functions handles a received packet. It checks wether it is
++ *    valid, updates the receive list element table and gives the receive
++ *    buffer to Linux
++ *
++ * Notes:
++ *    This function can run only once per port at one time in the system.
++ *
++ * Returns: N/A
++ */
++static SK_BOOL HandleReceives(
++SK_AC  *pAC,          /* adapter control context                     */
++int     Port,         /* port on which a packet has been received    */
++SK_U16  Len,          /* number of bytes which was actually received */
++SK_U32  FrameStatus,  /* MAC frame status word                       */
++SK_U16  Tcp1,         /* first hw checksum                           */
++SK_U16  Tcp2,         /* second hw checksum                          */
++SK_U32  Tist,         /* timestamp                                   */
++SK_U16  Vlan)         /* Vlan Id                                     */
++{
++
++      SK_PACKET       *pSkPacket;
++      SK_LE_TABLE     *pLETab;
++      SK_MBUF         *pRlmtMbuf;  /* buffer for giving RLMT frame */
++      struct sk_buff  *pMsg;       /* ptr to message holding frame */
++#ifdef __ia64__
++      struct sk_buff  *pNewMsg;    /* used when IP aligning        */
++#endif
++              
++#ifdef CONFIG_SK98LIN_NAPI
++      SK_BOOL         SlowPathLock = SK_FALSE;
++#else
++      SK_BOOL         SlowPathLock = SK_TRUE;
++#endif
++      SK_BOOL         IsGoodPkt;
++      SK_BOOL         IsBc;
++      SK_BOOL         IsMc;
++      SK_EVPARA       EvPara;      /* an event parameter union     */
++      SK_I16          LenToFree;   /* must be signed integer       */
++
++      unsigned long   Flags;       /* for spin lock                */
++      unsigned int    RlmtNotifier;
++      unsigned short  Type;
++      int             IpFrameLength;
++      int             FrameLength; /* total length of recvd frame  */
++      int             HeaderLength;
++      int             NumBytes; 
++      int             Result;
++      int             Offset = 0;
++
++#ifdef Y2_SYNC_CHECK
++      SK_U16          MyTcp;
++#endif
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++              ("==> HandleReceives (Port %c)\n", 'A' + Port));
++
++      /* 
++      ** initialize vars for selected port 
++      */
++      pLETab = &pAC->RxPort[Port].RxLET;
++
++      /* 
++      ** check whether we want to receive this packet 
++      */
++      SK_Y2_RXSTAT_CHECK_PKT(Len, FrameStatus, IsGoodPkt);
++
++      /*
++      ** Remember length to free (in case of RxBuffer overruns;
++      ** unlikely, but might happen once in a while)
++      */
++      LenToFree = (SK_I16) Len;
++
++      /* 
++      ** maybe we put these two checks into the SK_RXDESC_CHECK_PKT macro too 
++      */
++      if (Len > pAC->RxPort[Port].RxBufSize) {
++              IsGoodPkt = SK_FALSE;
++      }
++
++      /*
++      ** take first receive buffer out of working queue 
++      */
++      POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket);
++      if (pSkPacket == NULL) {
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
++                      SK_DBGCAT_DRV_ERROR,
++                      ("Packet not available. NULL pointer.\n"));
++              return(SK_TRUE);
++      }
++
++      if (HW_FEATURE(pAC, HWF_WA_DEV_420)) {
++              NbrRxBuffersInHW--;
++      }
++
++      /* 
++      ** Verify the received length of the frame! Note that having 
++      ** multiple RxBuffers being aware of one single receive packet
++      ** (one packet spread over multiple RxBuffers) is not supported 
++      ** by this driver!
++      */
++      if ((Len > pAC->RxPort[Port].RxBufSize) || 
++              (Len > (SK_U16) pSkPacket->PacketLen)) {
++              IsGoodPkt = SK_FALSE;
++      }
++
++      /* 
++      ** Reset own bit in LE's between old and new Done index
++      ** This is not really necessary but makes debugging easier 
++      */
++      CLEAR_LE_OWN_FROM_DONE_TO(pLETab, pSkPacket->NextLE);
++
++      /* 
++      ** Free the list elements for new Rx buffers 
++      */
++      SET_DONE_INDEX(pLETab, pSkPacket->NextLE);
++      pMsg = pSkPacket->pMBuf;
++      FrameLength = Len;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++              ("Received frame of length %d on port %d\n",FrameLength, Port));
++
++      if (!IsGoodPkt) {
++              /* 
++              ** release the DMA mapping 
++              */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5)
++              pci_dma_sync_single(pAC->PciDev,
++                              (dma_addr_t) pSkPacket->pFrag->pPhys,
++                              pSkPacket->pFrag->FragLen,
++                              PCI_DMA_FROMDEVICE);
++
++#else
++              pci_dma_sync_single_for_cpu(pAC->PciDev,
++                              (dma_addr_t) pSkPacket->pFrag->pPhys,
++                              pSkPacket->pFrag->FragLen,
++                              PCI_DMA_FROMDEVICE);
++#endif
++
++              DEV_KFREE_SKB_ANY(pSkPacket->pMBuf);
++              PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket);
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++                      ("<== HandleReceives (Port %c)\n", 'A' + Port));
++
++              /*
++              ** Sanity check for RxBuffer overruns...
++              */
++              LenToFree = LenToFree - (pSkPacket->pFrag->FragLen);
++              while (LenToFree > 0) {
++                      POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket);
++                      if (HW_FEATURE(pAC, HWF_WA_DEV_420)) {
++                              NbrRxBuffersInHW--;
++                      }
++                      CLEAR_LE_OWN_FROM_DONE_TO(pLETab, pSkPacket->NextLE);
++                      SET_DONE_INDEX(pLETab, pSkPacket->NextLE);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5)
++                      pci_dma_sync_single(pAC->PciDev,
++                                      (dma_addr_t) pSkPacket->pFrag->pPhys,
++                                      pSkPacket->pFrag->FragLen,
++                                      PCI_DMA_FROMDEVICE);
++#else
++                      pci_dma_sync_single_for_device(pAC->PciDev,
++                                      (dma_addr_t) pSkPacket->pFrag->pPhys,
++                                      pSkPacket->pFrag->FragLen,
++                                      PCI_DMA_FROMDEVICE); 
++#endif
++
++                      DEV_KFREE_SKB_ANY(pSkPacket->pMBuf);
++                      PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket);
++                      LenToFree = LenToFree - ((SK_I16)(pSkPacket->pFrag->FragLen));
++                      
++                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV,
++                              SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR,
++                              ("<==HandleReceives (Port %c) drop faulty len pkt(2)\n",'A'+Port));
++              }
++              return(SK_TRUE);
++      } else {
++              /* 
++              ** Release the DMA mapping 
++              */
++              pci_unmap_single(pAC->PciDev,
++                               pSkPacket->pFrag->pPhys,
++                               pAC->RxPort[Port].RxBufSize,
++                               PCI_DMA_FROMDEVICE);
++
++              skb_put(pMsg, FrameLength);             /* set message len */
++              pMsg->ip_summed = CHECKSUM_NONE;        /* initial default */
++
++#ifdef Y2_SYNC_CHECK
++              pAC->FramesWithoutSyncCheck++;
++              if (pAC->FramesWithoutSyncCheck > Y2_RESYNC_WATERMARK) {
++                      if ((Tcp1 != 1) && (Tcp2 != 0)) {
++                              pAC->FramesWithoutSyncCheck = 0;
++                              MyTcp = (SK_U16) SkCsCalculateChecksum(
++                                              &pMsg->data[14],
++                                              FrameLength - 14);
++                              if (MyTcp != Tcp1) {
++                                      /* Queue port reset event */
++                                      SkLocalEventQueue(pAC, SKGE_DRV,
++                                      SK_DRV_RECOVER,Port,-1,SK_FALSE);
++                              }
++                      }
++              }
++#endif
++
++              if (pAC->RxPort[Port].UseRxCsum) {
++                      Type = ntohs(*((short*)&pMsg->data[12]));
++                      if (Type == 0x800) {
++                              *((char *)&(IpFrameLength)) = pMsg->data[16];
++                              *(((char *)&(IpFrameLength))+1) = pMsg->data[17];
++                              IpFrameLength = ntohs(IpFrameLength);
++                              HeaderLength  = FrameLength - IpFrameLength;
++                              if (HeaderLength == 0xe) {
++                                      Result = 
++                                          SkCsGetReceiveInfo(pAC,&pMsg->data[14],Tcp1,Tcp2, Port);
++                                      if ((Result == SKCS_STATUS_IP_FRAGMENT) ||
++                                          (Result == SKCS_STATUS_IP_CSUM_OK)  ||
++                                          (Result == SKCS_STATUS_TCP_CSUM_OK) ||
++                                          (Result == SKCS_STATUS_UDP_CSUM_OK)) {
++                                              pMsg->ip_summed = CHECKSUM_UNNECESSARY;
++                                      } else if ((Result == SKCS_STATUS_TCP_CSUM_ERROR)    ||
++                                                 (Result == SKCS_STATUS_UDP_CSUM_ERROR)    ||
++                                                 (Result == SKCS_STATUS_IP_CSUM_ERROR_UDP) ||
++                                                 (Result == SKCS_STATUS_IP_CSUM_ERROR_TCP) ||
++                                                 (Result == SKCS_STATUS_IP_CSUM_ERROR)) {
++                                              SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
++                                                      SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR,
++                                                      ("skge: CRC error. Frame dropped!\n"));
++                                              DEV_KFREE_SKB_ANY(pMsg);
++                                              PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket);
++                                              SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_RX_PROGRESS,
++                                                      ("<==HandleReceives(Port %c)\n",'A'+Port));
++                                              return(SK_TRUE);
++                                      } else {
++                                              pMsg->ip_summed = CHECKSUM_NONE;
++                                      }
++                              } /* end if (HeaderLength == valid) */
++                      } /* end if (Type == 0x800) -> IP frame */
++              } /* end if (pRxPort->UseRxCsum) */
++              
++              SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
++                      SK_DBGCAT_DRV_RX_PROGRESS,("V"));
++              RlmtNotifier = SK_RLMT_RX_PROTOCOL;
++
++              IsBc = (FrameStatus & GMR_FS_BC) ? SK_TRUE : SK_FALSE;
++              SK_RLMT_PRE_LOOKAHEAD(pAC,Port,FrameLength,
++                                      IsBc,&Offset,&NumBytes);
++              if (NumBytes != 0) {
++                      IsMc = (FrameStatus & GMR_FS_MC) ? SK_TRUE : SK_FALSE;
++                      SK_RLMT_LOOKAHEAD(pAC,Port,&pMsg->data[Offset],
++                                              IsBc,IsMc,&RlmtNotifier);
++              }
++
++              if (RlmtNotifier == SK_RLMT_RX_PROTOCOL) {
++                      SK_DBG_MSG(NULL,SK_DBGMOD_DRV,
++                              SK_DBGCAT_DRV_RX_PROGRESS,("W"));
++                      if ((Port == pAC->ActivePort)||(pAC->RlmtNets == 2)) {
++                              /* send up only frames from active port */
++                              SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
++                                      SK_DBGCAT_DRV_RX_PROGRESS,("U"));
++#ifdef xDEBUG
++                              DumpMsg(pMsg, "Rx");
++#endif
++                              SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
++                                      FrameLength, Port);
++#ifdef __ia64__
++                              pNewMsg = alloc_skb(pMsg->len, GFP_ATOMIC);
++                              skb_reserve(pNewMsg, 2); /* to align IP */
++                              SK_MEMCPY(pNewMsg->data,pMsg->data,pMsg->len);
++                              pNewMsg->ip_summed = pMsg->ip_summed;
++                              skb_put(pNewMsg, pMsg->len);
++                              DEV_KFREE_SKB_ANY(pMsg);
++                              pMsg = pNewMsg;
++#endif
++                              pMsg->dev = pAC->dev[Port];
++                              pMsg->protocol = eth_type_trans(pMsg,
++                                      pAC->dev[Port]);
++                              netif_rx(pMsg);
++                              pAC->dev[Port]->last_rx = jiffies;
++                      } else { /* drop frame */
++                              SK_DBG_MSG(NULL,SK_DBGMOD_DRV,
++                                      SK_DBGCAT_DRV_RX_PROGRESS,("D"));
++                              DEV_KFREE_SKB_ANY(pMsg);
++                      }
++              } else { /* This is an RLMT-packet! */
++                      SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
++                              SK_DBGCAT_DRV_RX_PROGRESS,("R"));
++                      pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
++                              pAC->IoBase, FrameLength);
++                      if (pRlmtMbuf != NULL) {
++                              pRlmtMbuf->pNext = NULL;
++                              pRlmtMbuf->Length = FrameLength;
++                              pRlmtMbuf->PortIdx = Port;
++                              EvPara.pParaPtr = pRlmtMbuf;
++                              SK_MEMCPY((char*)(pRlmtMbuf->pData),
++                                        (char*)(pMsg->data),FrameLength);
++
++                              if (SlowPathLock == SK_TRUE) {
++                                      spin_lock_irqsave(&pAC->SlowPathLock, Flags);
++                                      SkEventQueue(pAC, SKGE_RLMT,
++                                              SK_RLMT_PACKET_RECEIVED,
++                                              EvPara);
++                                      pAC->CheckQueue = SK_TRUE;
++                                      spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
++                              } else {
++                                      SkEventQueue(pAC, SKGE_RLMT,
++                                              SK_RLMT_PACKET_RECEIVED,
++                                              EvPara);
++                                      pAC->CheckQueue = SK_TRUE;
++                              }
++
++                              SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
++                                      SK_DBGCAT_DRV_RX_PROGRESS,("Q"));
++                      }
++                      if (pAC->dev[Port]->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
++#ifdef __ia64__
++                              pNewMsg = alloc_skb(pMsg->len, GFP_ATOMIC);
++                              skb_reserve(pNewMsg, 2); /* to align IP */
++                              SK_MEMCPY(pNewMsg->data,pMsg->data,pMsg->len);
++                              pNewMsg->ip_summed = pMsg->ip_summed;
++                              pNewMsg->len = pMsg->len;
++                              DEV_KFREE_SKB_ANY(pMsg);
++                              pMsg = pNewMsg;
++#endif
++                              pMsg->dev = pAC->dev[Port];
++                              pMsg->protocol = eth_type_trans(pMsg,pAC->dev[Port]);
++                              netif_rx(pMsg);
++                              pAC->dev[Port]->last_rx = jiffies;
++                      } else {
++                              DEV_KFREE_SKB_ANY(pMsg);
++                      }
++              } /* if packet for rlmt */
++              PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket);
++      } /* end if-else (IsGoodPkt) */
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++              ("<== HandleReceives (Port %c)\n", 'A' + Port));
++      return(SK_TRUE);
++
++}     /* HandleReceives */
++
++/***********************************************************************
++ *
++ *    CheckForSendComplete - Frees any freeable Tx bufffer 
++ *
++ * Description:
++ *    This function checks the queues of a port for completed send
++ *    packets and returns these packets back to the OS.
++ *
++ * Notes:
++ *    This function can run simultaneously for both ports if
++ *    the OS function OSReturnPacket() can handle this,
++ *
++ *    Such a send complete does not mean, that the packet is really
++ *    out on the wire. We just know that the adapter has copied it
++ *    into its internal memory and the buffer in the systems memory
++ *    is no longer needed.
++ *
++ * Returns: N/A
++ */
++static void CheckForSendComplete(
++SK_AC         *pAC,     /* pointer to adapter control context  */
++SK_IOC         IoC,     /* I/O control context                 */
++int            Port,    /* port index                          */
++SK_PKT_QUEUE  *pPQ,     /* tx working packet queue to check    */
++SK_LE_TABLE   *pLETab,  /* corresponding list element table    */
++unsigned int   Done)    /* done index reported for this LET    */
++{
++      SK_PACKET       *pSkPacket;
++      SK_PKT_QUEUE     SendCmplPktQ = { NULL, NULL, SPIN_LOCK_UNLOCKED };
++      SK_BOOL          DoWakeQueue  = SK_FALSE;
++      unsigned long    Flags;
++      unsigned         Put;
++      
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++              ("==> CheckForSendComplete(Port %c)\n", 'A' + Port));
++
++      /* 
++      ** Reset own bit in LE's between old and new Done index
++      ** This is not really necessairy but makes debugging easier 
++      */
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++              ("Clear Own Bits in TxTable from %d to %d\n",
++              pLETab->Done, (Done == 0) ?
++              NUM_LE_IN_TABLE(pLETab) :
++              (Done - 1)));
++
++      spin_lock_irqsave(&(pPQ->QueueLock), Flags);
++
++      CLEAR_LE_OWN_FROM_DONE_TO(pLETab, Done);
++
++      Put = GET_PUT_IDX(pLETab);
++
++      /* 
++      ** Check whether some packets have been completed 
++      */
++      PLAIN_POP_FIRST_PKT_FROM_QUEUE(pPQ, pSkPacket);
++      while (pSkPacket != NULL) {
++              
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++                      ("Check Completion of Tx packet %p\n", pSkPacket));
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++                      ("Put %d NewDone %d NextLe of Packet %d\n", Put, Done,
++                      pSkPacket->NextLE));
++
++              if ((Put > Done) &&
++                      ((pSkPacket->NextLE > Put) || (pSkPacket->NextLE <= Done))) {
++                      PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket);
++                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++                              ("Packet finished (a)\n"));
++              } else if ((Done > Put) &&
++                      (pSkPacket->NextLE > Put) && (pSkPacket->NextLE <= Done)) {
++                      PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket);
++                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++                              ("Packet finished (b)\n"));
++              } else if ((Done == TXA_MAX_LE-1) && (Put == 0) && (pSkPacket->NextLE == 0)) {
++                      PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket);
++                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++                              ("Packet finished (b)\n"));
++                      DoWakeQueue = SK_TRUE;
++              } else if (Done == Put) {
++                      /* all packets have been sent */
++                      PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket);
++                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++                              ("Packet finished (c)\n"));
++              } else {
++                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++                              ("Packet not yet finished\n"));
++                      PLAIN_PUSH_PKT_AS_FIRST_IN_QUEUE(pPQ, pSkPacket);
++                      break;
++              }
++              PLAIN_POP_FIRST_PKT_FROM_QUEUE(pPQ, pSkPacket);
++      }
++      spin_unlock_irqrestore(&(pPQ->QueueLock), Flags);
++
++      /* 
++      ** Set new done index in list element table
++      */
++      SET_DONE_INDEX(pLETab, Done);
++       
++      /*
++      ** All TX packets that are send complete should be added to
++      ** the free queue again for new sents to come
++      */
++      pSkPacket = SendCmplPktQ.pHead;
++      while (pSkPacket != NULL) {
++              while (pSkPacket->pFrag != NULL) {
++                      pci_unmap_page(pAC->PciDev,
++                                      (dma_addr_t) pSkPacket->pFrag->pPhys,
++                                      pSkPacket->pFrag->FragLen,
++                                      PCI_DMA_FROMDEVICE);
++                      pSkPacket->pFrag = pSkPacket->pFrag->pNext;
++              }
++
++              DEV_KFREE_SKB_ANY(pSkPacket->pMBuf);
++              pSkPacket->pMBuf        = NULL;
++              pSkPacket = pSkPacket->pNext; /* get next packet */
++      }
++
++      /*
++      ** Append the available TX packets back to free queue
++      */
++      if (SendCmplPktQ.pHead != NULL) { 
++              spin_lock_irqsave(&(pAC->TxPort[Port][0].TxQ_free.QueueLock), Flags);
++              if (pAC->TxPort[Port][0].TxQ_free.pTail != NULL) {
++                      pAC->TxPort[Port][0].TxQ_free.pTail->pNext = SendCmplPktQ.pHead;
++                      pAC->TxPort[Port][0].TxQ_free.pTail        = SendCmplPktQ.pTail;
++                      if (pAC->TxPort[Port][0].TxQ_free.pHead->pNext == NULL) {
++                              netif_wake_queue(pAC->dev[Port]);
++                      }
++              } else {
++                      pAC->TxPort[Port][0].TxQ_free.pHead = SendCmplPktQ.pHead;
++                      pAC->TxPort[Port][0].TxQ_free.pTail = SendCmplPktQ.pTail; 
++                      netif_wake_queue(pAC->dev[Port]);
++              }
++              if (Done == Put) {
++                      netif_wake_queue(pAC->dev[Port]);
++              }
++              if (DoWakeQueue) {
++                      netif_wake_queue(pAC->dev[Port]);
++                      DoWakeQueue = SK_FALSE;
++              }
++              spin_unlock_irqrestore(&pAC->TxPort[Port][0].TxQ_free.QueueLock, Flags);
++      }
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++              ("<== CheckForSendComplete()\n"));
++
++      return;
++}     /* CheckForSendComplete */
++
++/*****************************************************************************
++ *
++ *    UnmapAndFreeTxPktBuffer
++ *
++ * Description:
++ *      This function free any allocated space of receive buffers
++ *
++ * Arguments:
++ *      pAC - A pointer to the adapter context struct.
++ *
++ */
++static void UnmapAndFreeTxPktBuffer(
++SK_AC       *pAC,       /* pointer to adapter context             */
++SK_PACKET   *pSkPacket,       /* pointer to port struct of ring to fill */
++int          TxPort)    /* TX port index                          */
++{
++      SK_FRAG  *pFrag = pSkPacket->pFrag;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++              ("--> UnmapAndFreeTxPktBuffer\n"));
++
++      while (pFrag != NULL) {
++              pci_unmap_page(pAC->PciDev,
++                              (dma_addr_t) pFrag->pPhys,
++                              pFrag->FragLen,
++                              PCI_DMA_FROMDEVICE);
++              pFrag = pFrag->pNext;
++      }
++
++      DEV_KFREE_SKB_ANY(pSkPacket->pMBuf);
++      pSkPacket->pMBuf        = NULL;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
++              ("<-- UnmapAndFreeTxPktBuffer\n"));
++}
++
++/*****************************************************************************
++ *
++ *    HandleStatusLEs
++ *
++ * Description:
++ *    This function checks for any new status LEs that may have been 
++  *   received. Those status LEs may either be Rx or Tx ones.
++ *
++ * Returns:   N/A
++ */
++static SK_BOOL HandleStatusLEs(
++#ifdef CONFIG_SK98LIN_NAPI
++SK_AC *pAC,       /* pointer to adapter context   */
++int   *WorkDone,  /* Done counter needed for NAPI */
++int    WorkToDo)  /* ToDo counter for NAPI        */
++#else
++SK_AC *pAC)       /* pointer to adapter context   */
++#endif
++{
++      int       DoneTxA[SK_MAX_MACS];
++      int       DoneTxS[SK_MAX_MACS];
++      int       Port;
++      SK_BOOL   handledStatLE = SK_FALSE;
++      SK_BOOL   NewDone       = SK_FALSE;
++      SK_HWLE  *pLE;
++      SK_U16    HighVal;
++      SK_U32    LowVal;
++      SK_U8     OpCode;
++      int       i;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++              ("==> HandleStatusLEs\n"));
++
++      do {
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++                      ("Check next Own Bit of ST-LE[%d]: 0x%li \n",
++                      (pAC->StatusLETable.Done + 1) % NUM_LE_IN_TABLE(&pAC->StatusLETable),
++                       OWN_OF_FIRST_LE(&pAC->StatusLETable)));
++
++              while (OWN_OF_FIRST_LE(&pAC->StatusLETable) == HW_OWNER) {
++                      GET_ST_LE(pLE, &pAC->StatusLETable);
++                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++                              ("Working on finished status LE[%d]:\n",
++                              GET_DONE_INDEX(&pAC->StatusLETable)));
++                      SK_DBG_DUMP_ST_LE(pLE);
++                      handledStatLE = SK_TRUE;
++                      OpCode = STLE_GET_OPC(pLE) & ~HW_OWNER;
++                      Port = STLE_GET_LINK(pLE);
++
++#ifdef USE_TIST_FOR_RESET
++                      if (SK_ADAPTER_WAITING_FOR_TIST(pAC)) {
++                              /* do we just have a tist LE ? */
++                              if ((OpCode & OP_RXTIMESTAMP) == OP_RXTIMESTAMP) {
++                                      for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
++                                              if (SK_PORT_WAITING_FOR_ANY_TIST(pAC, i)) {
++                                                      /* if a port is waiting for any tist it is done */
++                                                      SK_CLR_STATE_FOR_PORT(pAC, i);
++                                                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP,
++                                                              ("Got any Tist on port %c (now 0x%X!!!)\n",
++                                                              'A' + i, pAC->AdapterResetState));
++                                              }
++                                              if (SK_PORT_WAITING_FOR_SPECIFIC_TIST(pAC, i)) {
++                                                      Y2_GET_TIST_LOW_VAL(pAC->IoBase, &LowVal);
++                                                      if ((pAC->MinTistHi != pAC->GIni.GITimeStampCnt) ||
++                                                              (pAC->MinTistLo < LowVal)) {
++                                                              /* time is up now */
++                                                              SK_CLR_STATE_FOR_PORT(pAC, i);
++                                                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP,
++                                                                      ("Got expected Tist on Port %c (now 0x%X)!!!\n",
++                                                                      'A' + i, pAC->AdapterResetState));
++#ifdef Y2_SYNC_CHECK
++                                                              pAC->FramesWithoutSyncCheck =
++                                                              Y2_RESYNC_WATERMARK;                                            
++#endif
++                                                      } else {
++                                                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP,
++                                                                      ("Got Tist %l:%l on Port %c but still waiting\n",
++                                                                      pAC->GIni.GITimeStampCnt, pAC->MinTistLo,
++                                                                      'A' + i));
++                                                      }
++                                              }
++                                      }
++#ifndef Y2_RECOVERY
++                                      if (!SK_ADAPTER_WAITING_FOR_TIST(pAC)) {
++                                              /* nobody needs tist anymore - turn it off */
++                                              Y2_DISABLE_TIST(pAC->IoBase);
++                                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP,
++                                              ("Turn off Tist !!!\n"));
++                                      }
++#endif
++                              } else if (OpCode == OP_TXINDEXLE) {
++                                      /*
++                                       * change OpCode to notify the folowing code
++                                       * to ignore the done index from this LE
++                                       * unfortunately tist LEs will be generated only
++                                       * for RxStat LEs
++                                       * so in order to get a safe Done index for a
++                                       * port currently waiting for a tist we have to
++                                       * get the done index directly from the BMU
++                                       */
++                                      OpCode = OP_MOD_TXINDEX;
++                                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP,
++                                              ("Mark unusable TX_INDEX LE!!!\n"));
++                              } else {
++                                      if (SK_PORT_WAITING_FOR_TIST(pAC, Port)) {
++                                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, 
++                                                      ("Ignore LE 0x%X on Port %c!!!\n",
++                                                      OpCode, 'A' + Port));
++                                              OpCode = OP_MOD_LE;
++#ifdef Y2_LE_CHECK
++                                              /* mark entries invalid */
++                                              pAC->LastOpc = 0xFF;
++                                              pAC->LastPort = 3;
++#endif
++                                      }
++                              }
++                      } /* if (SK_ADAPTER_WAITING_FOR_TIST(pAC)) */
++#endif
++
++
++
++
++
++#ifdef Y2_LE_CHECK
++                      if (pAC->LastOpc != 0xFF) {
++                              /* last opc is valid
++                               * check if current opcode follows last opcode
++                               */
++                              if ((((OpCode & OP_RXTIMESTAMP) == OP_RXTIMESTAMP) && (pAC->LastOpc != OP_RXSTAT)) ||
++                                  (((OpCode & OP_RXCHKS) == OP_RXCHKS) && (pAC->LastOpc != OP_RXTIMESTAMP)) ||
++                                  ((OpCode == OP_RXSTAT) && (pAC->LastOpc != OP_RXCHKS))) {
++
++                                      /* opcode sequence broken
++                                       * current LE is invalid
++                                       */
++
++                                      if (pAC->LastOpc == OP_RXTIMESTAMP) {
++                                              /* force invalid checksum */
++                                              pLE->St.StUn.StRxTCPCSum.RxTCPSum1 = 1;
++                                              pLE->St.StUn.StRxTCPCSum.RxTCPSum2 = 0;
++                                              OpCode = pAC->LastOpc = OP_RXCHKS;
++                                              Port = pAC->LastPort;
++                                      } else if (pAC->LastOpc == OP_RXCHKS) {
++                                              /* force invalid frame */
++                                              Port = pAC->LastPort;
++                                              pLE->St.Stat.BufLen = 64;
++                                              pLE->St.StUn.StRxStatWord = GMR_FS_CRC_ERR;
++                                              OpCode = pAC->LastOpc = OP_RXSTAT;
++#ifdef Y2_SYNC_CHECK
++                                              /* force rx sync check */
++                                              pAC->FramesWithoutSyncCheck = Y2_RESYNC_WATERMARK;
++#endif
++                                      } else if (pAC->LastOpc == OP_RXSTAT) {
++                                              /* create dont care tist */
++                                              pLE->St.StUn.StRxTimeStamp = 0;
++                                              OpCode = pAC->LastOpc = OP_RXTIMESTAMP;
++                                              /* dont know the port yet */
++                                      } else {
++#ifdef DEBUG
++                                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++                                                      ("Unknown LastOpc %X for Timestamp on port %c.\n",
++                                                      pAC->LastOpc, Port));
++#endif
++                                      }
++                              }
++                      }
++#endif
++
++                      switch (OpCode) {
++                      case OP_RXSTAT:
++#ifdef Y2_RECOVERY
++                              pAC->LastOpc = OP_RXSTAT;
++#endif
++                              /* 
++                              ** This is always the last Status LE belonging
++                              ** to a received packet -> handle it...
++                              */
++                              if ((Port != 0) && (Port != 1)) {
++                              /* Unknown port */
++                                      panic("sk98lin: Unknown port %d\n",
++                                      Port);
++                              }
++
++                              HandleReceives(
++                                      pAC,
++                                      Port,
++                                      STLE_GET_LEN(pLE),
++                                      STLE_GET_FRSTATUS(pLE),
++                                      pAC->StatusLETable.Bmu.Stat.TcpSum1,
++                                      pAC->StatusLETable.Bmu.Stat.TcpSum2,
++                                      pAC->StatusLETable.Bmu.Stat.RxTimeStamp,
++                                      pAC->StatusLETable.Bmu.Stat.VlanId);
++#ifdef CONFIG_SK98LIN_NAPI
++                              if (*WorkDone >= WorkToDo) {
++                                      break;
++                              }
++                              (*WorkDone)++;
++#endif
++                              break;
++                      case OP_RXVLAN:
++                              /* this value will be used for next RXSTAT */
++                              pAC->StatusLETable.Bmu.Stat.VlanId = STLE_GET_VLAN(pLE);
++                              break;
++                      case OP_RXTIMEVLAN:
++                              /* this value will be used for next RXSTAT */
++                              pAC->StatusLETable.Bmu.Stat.VlanId = STLE_GET_VLAN(pLE);
++                              /* fall through */
++                      case OP_RXTIMESTAMP:
++                              /* this value will be used for next RXSTAT */
++                              pAC->StatusLETable.Bmu.Stat.RxTimeStamp = STLE_GET_TIST(pLE);
++#ifdef Y2_RECOVERY
++                              pAC->LastOpc = OP_RXTIMESTAMP;
++                              pAC->LastPort = Port;
++#endif
++                              break;
++                      case OP_RXCHKSVLAN:
++                              /* this value will be used for next RXSTAT */
++                              pAC->StatusLETable.Bmu.Stat.VlanId = STLE_GET_VLAN(pLE);
++                              /* fall through */
++                      case OP_RXCHKS:
++                              /* this value will be used for next RXSTAT */
++                              pAC->StatusLETable.Bmu.Stat.TcpSum1 = STLE_GET_TCP1(pLE);
++                              pAC->StatusLETable.Bmu.Stat.TcpSum2 = STLE_GET_TCP2(pLE);
++#ifdef Y2_RECOVERY
++                              pAC->LastPort = Port;
++                              pAC->LastOpc = OP_RXCHKS;
++#endif
++                              break;
++                      case OP_RSS_HASH:
++                              /* this value will be used for next RXSTAT */
++#if 0
++                              pAC->StatusLETable.Bmu.Stat.RssHashValue = STLE_GET_RSS(pLE);
++#endif
++                              break;
++                      case OP_TXINDEXLE:
++                              /*
++                              ** :;:; TODO
++                              ** it would be possible to check for which queues
++                              ** the index has been changed and call 
++                              ** CheckForSendComplete() only for such queues
++                              */
++                              STLE_GET_DONE_IDX(pLE,LowVal,HighVal);
++                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++                                      ("LowVal: 0x%x HighVal: 0x%x\n", LowVal, HighVal));
++
++                              /*
++                              ** It would be possible to check whether we really
++                              ** need the values for second port or sync queue, 
++                              ** but I think checking whether we need them is 
++                              ** more expensive than the calculation
++                              */
++                              DoneTxA[0] = STLE_GET_DONE_IDX_TXA1(LowVal,HighVal);
++                              DoneTxS[0] = STLE_GET_DONE_IDX_TXS1(LowVal,HighVal);
++                              DoneTxA[1] = STLE_GET_DONE_IDX_TXA2(LowVal,HighVal);
++                              DoneTxS[1] = STLE_GET_DONE_IDX_TXS2(LowVal,HighVal);
++
++                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++                                      ("DoneTxa1 0x%x DoneTxS1: 0x%x DoneTxa2 0x%x DoneTxS2: 0x%x\n",
++                                      DoneTxA[0], DoneTxS[0], DoneTxA[1], DoneTxS[1]));
++
++                              NewDone = SK_TRUE;
++                              break;
++#ifdef USE_TIST_FOR_RESET
++                      case OP_MOD_TXINDEX:
++                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP,
++                                      ("OP_MOD_TXINDEX\n"));
++                              SK_IN16(pAC->IoBase, Q_ADDR(Q_XA1, Q_DONE), &DoneTxA[0]);
++                              if (pAC->GIni.GIMacsFound > 1) {
++                                      SK_IN16(pAC->IoBase, Q_ADDR(Q_XA2, Q_DONE), &DoneTxA[1]);
++                              }
++                              NewDone = SK_TRUE;
++                              break;
++                      case OP_MOD_LE:
++                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP,
++                              ("Ignore marked LE on port in Reset\n"));
++                              break;
++#endif
++
++                      default:
++                              /* 
++                              ** Have to handle the illegal Opcode in Status LE 
++                              */
++                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++                                      ("Unexpected OpCode\n"));
++                              break;
++                      }
++
++#ifdef Y2_RECOVERY
++                      OpCode = STLE_GET_OPC(pLE) & ~HW_OWNER;
++                      STLE_SET_OPC(pLE, OpCode);
++#else
++                      /* 
++                      ** Reset own bit we have to do this in order to detect a overflow 
++                      */
++                      STLE_SET_OPC(pLE, SW_OWNER);
++#endif
++              } /* while (OWN_OF_FIRST_LE(&pAC->StatusLETable) == HW_OWNER) */
++
++              /* 
++              ** Now handle any new transmit complete 
++              */
++              if (NewDone) {
++                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++                              ("Done Index for Tx BMU has been changed\n"));
++                      for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) {
++                              /* 
++                              ** Do we have a new Done idx ? 
++                              */
++                              if (DoneTxA[Port] != GET_DONE_INDEX(&pAC->TxPort[Port][0].TxALET)) {
++                                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++                                              ("Check TxA%d\n", Port + 1));
++                                      CheckForSendComplete(pAC, pAC->IoBase, Port,
++                                              &(pAC->TxPort[Port][0].TxAQ_working),
++                                              &pAC->TxPort[Port][0].TxALET,
++                                              DoneTxA[Port]);
++                              } else {
++                                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++                                              ("No changes for TxA%d\n", Port + 1));
++                              }
++#if USE_SYNC_TX_QUEUE
++                              if (HW_SYNC_TX_SUPPORTED(pAC)) {
++                                      /* 
++                                      ** Do we have a new Done idx ? 
++                                      */
++                                      if (DoneTxS[Port] !=
++                                              GET_DONE_INDEX(&pAC->TxPort[Port][0].TxSLET)) {
++                                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
++                                                      SK_DBGCAT_DRV_INT_SRC,
++                                                      ("Check TxS%d\n", Port));
++                                              CheckForSendComplete(pAC, pAC->IoBase, Port,
++                                                      &(pAC->TxPort[Port][0].TxSQ_working),
++                                                      &pAC->TxPort[Port][0].TxSLET,
++                                                      DoneTxS[Port]);
++                                      } else {
++                                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
++                                                      SK_DBGCAT_DRV_INT_SRC,
++                                                      ("No changes for TxS%d\n", Port));
++                                      }
++                              }
++#endif
++                      }
++              }
++              NewDone = SK_FALSE;
++
++              /* 
++              ** Check whether we have to refill our RX table  
++              */
++              if (HW_FEATURE(pAC, HWF_WA_DEV_420)) {
++                      if (NbrRxBuffersInHW < MAX_NBR_RX_BUFFERS_IN_HW) {
++                              for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) {
++                                      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++                                              ("Check for refill of RxBuffers on Port %c\n", 'A' + Port));
++                                      FillReceiveTableYukon2(pAC, pAC->IoBase, Port);
++                              }
++                      }
++              } else {
++                      for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) {
++                              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
++                                      ("Check for refill of RxBuffers on Port %c\n", 'A' + Port));
++                              if (NUM_FREE_LE_IN_TABLE(&pAC->RxPort[Port].RxLET) >= 64) {
++                                      FillReceiveTableYukon2(pAC, pAC->IoBase, Port);
++                              }
++                      }
++              }
++#ifdef CONFIG_SK98LIN_NAPI
++              if (*WorkDone >= WorkToDo) {
++                      break;
++              }
++#endif
++      } while (OWN_OF_FIRST_LE(&pAC->StatusLETable) == HW_OWNER);
++
++      /* 
++      ** Clear status BMU 
++      */
++      SK_OUT32(pAC->IoBase, STAT_CTRL, SC_STAT_CLR_IRQ);
++
++      return(handledStatLE);
++}     /* HandleStatusLEs */
++
++/*****************************************************************************
++ *
++ *    AllocateAndInitLETables - allocate memory for the LETable and init
++ *
++ * Description:
++ *    This function will allocate space for the LETable and will also  
++ *    initialize them. The size of the tables must have been specified 
++ *    before.
++ *
++ * Arguments:
++ *    pAC - A pointer to the adapter context struct.
++ *
++ * Returns:
++ *    SK_TRUE  - all LETables initialized
++ *    SK_FALSE - failed
++ */
++static SK_BOOL AllocateAndInitLETables(
++SK_AC *pAC)  /* pointer to adapter context */
++{
++      char           *pVirtMemAddr;
++      dma_addr_t     pPhysMemAddr = 0;
++      SK_U32         CurrMac;
++      unsigned       Size;
++      unsigned       Aligned;
++      unsigned       Alignment;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
++              ("==> AllocateAndInitLETables()\n"));
++
++      /*
++      ** Determine how much memory we need with respect to alignment
++      */
++      Alignment = MAX_LEN_OF_LE_TAB;
++      Size = 0;
++      for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) {
++              SK_ALIGN_SIZE(LE_TAB_SIZE(RX_MAX_LE), Alignment, Aligned);
++              Size += Aligned;
++              SK_ALIGN_SIZE(LE_TAB_SIZE(TXA_MAX_LE), Alignment, Aligned);
++              Size += Aligned;
++              SK_ALIGN_SIZE(LE_TAB_SIZE(TXS_MAX_LE), Alignment, Aligned);
++              Size += Aligned;
++      }
++      SK_ALIGN_SIZE(LE_TAB_SIZE(ST_MAX_LE), Alignment, Aligned);
++      Size += Aligned;
++      Size += Alignment;
++      pAC->SizeOfAlignedLETables = Size;
++      
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, 
++                      ("Need %08x bytes in total\n", Size));
++      
++      /*
++      ** Allocate the memory
++      */
++      pVirtMemAddr = pci_alloc_consistent(pAC->PciDev, Size, &pPhysMemAddr);
++      if (pVirtMemAddr == NULL) {
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, 
++                      SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR,
++                      ("AllocateAndInitLETables: kernel malloc failed!\n"));
++              return (SK_FALSE); 
++      }
++
++      /* 
++      ** Initialize the memory
++      */
++      SK_MEMSET(pVirtMemAddr, 0, Size);
++      ALIGN_ADDR(pVirtMemAddr, Alignment); /* Macro defined in skgew.h */
++      
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
++              ("Virtual address of LETab is %8p!\n", pVirtMemAddr));
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
++              ("Phys address of LETab is %8p!\n", (void *) pPhysMemAddr));
++
++      for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) {
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
++                      ("RxLeTable for Port %c", 'A' + CurrMac));
++              SkGeY2InitSingleLETable(
++                      pAC,
++                      &pAC->RxPort[CurrMac].RxLET,
++                      RX_MAX_LE,
++                      pVirtMemAddr,
++                      (SK_U32) (pPhysMemAddr & 0xffffffff),
++                      (SK_U32) (((SK_U64) pPhysMemAddr) >> 32));
++
++              SK_ALIGN_SIZE(LE_TAB_SIZE(RX_MAX_LE), Alignment, Aligned);
++              pVirtMemAddr += Aligned;
++              pPhysMemAddr += Aligned;
++
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
++                      ("TxALeTable for Port %c", 'A' + CurrMac));
++              SkGeY2InitSingleLETable(
++                      pAC,
++                      &pAC->TxPort[CurrMac][0].TxALET,
++                      TXA_MAX_LE,
++                      pVirtMemAddr,
++                      (SK_U32) (pPhysMemAddr & 0xffffffff),
++                      (SK_U32) (((SK_U64) pPhysMemAddr) >> 32));
++
++              SK_ALIGN_SIZE(LE_TAB_SIZE(TXA_MAX_LE), Alignment, Aligned);
++              pVirtMemAddr += Aligned;
++              pPhysMemAddr += Aligned;
++
++              SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
++                      ("TxSLeTable for Port %c", 'A' + CurrMac));
++              SkGeY2InitSingleLETable(
++                      pAC,
++                      &pAC->TxPort[CurrMac][0].TxSLET,
++                      TXS_MAX_LE,
++                      pVirtMemAddr,
++                      (SK_U32) (pPhysMemAddr & 0xffffffff),
++                      (SK_U32) (((SK_U64) pPhysMemAddr) >> 32));
++
++              SK_ALIGN_SIZE(LE_TAB_SIZE(TXS_MAX_LE), Alignment, Aligned);
++              pVirtMemAddr += Aligned;
++              pPhysMemAddr += Aligned;
++      }
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,("StLeTable"));
++
++      SkGeY2InitSingleLETable(
++              pAC,
++              &pAC->StatusLETable,
++              ST_MAX_LE,
++              pVirtMemAddr,
++              (SK_U32) (pPhysMemAddr & 0xffffffff),
++              (SK_U32) (((SK_U64) pPhysMemAddr) >> 32));
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, 
++              ("<== AllocateAndInitLETables(OK)\n"));
++      return(SK_TRUE);
++}     /* AllocateAndInitLETables */
++
++/*****************************************************************************
++ *
++ *    AllocatePacketBuffersYukon2 - allocate packet and fragment buffers
++ *
++ * Description:
++ *      This function will allocate space for the packets and fragments
++ *
++ * Arguments:
++ *      pAC - A pointer to the adapter context struct.
++ *
++ * Returns:
++ *      SK_TRUE  - Memory was allocated correctly
++ *      SK_FALSE - An error occured
++ */
++static SK_BOOL AllocatePacketBuffersYukon2(
++SK_AC *pAC)  /* pointer to adapter context */
++{
++      SK_PACKET       *pRxPacket;
++      SK_PACKET       *pTxPacket;
++      SK_U32           CurrBuff;
++      SK_U32           CurrMac;
++      unsigned long    Flags; /* needed for POP/PUSH functions */
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
++              ("==> AllocatePacketBuffersYukon2()"));
++
++      for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) {
++              /* 
++              ** Allocate RX packet space, initialize the packets and
++              ** add them to the RX waiting queue. Waiting queue means 
++              ** that packet and fragment are initialized, but no sk_buff
++              ** has been assigned to it yet.
++              */
++              pAC->RxPort[CurrMac].ReceivePacketTable = 
++                      kmalloc((RX_MAX_NBR_BUFFERS * sizeof(SK_PACKET)), GFP_KERNEL);
++
++              if (pAC->RxPort[CurrMac].ReceivePacketTable == NULL) {
++                      SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR,
++                              ("AllocatePacketBuffersYukon2: no mem RxPkts (port %i)",CurrMac));
++                      break;
++              } else {
++                      SK_MEMSET(pAC->RxPort[CurrMac].ReceivePacketTable, 0, 
++                              (RX_MAX_NBR_BUFFERS * sizeof(SK_PACKET)));
++
++                      pRxPacket = pAC->RxPort[CurrMac].ReceivePacketTable;
++
++                      for (CurrBuff=0;CurrBuff<RX_MAX_NBR_BUFFERS;CurrBuff++) {
++                              pRxPacket->pFrag = &(pRxPacket->FragArray[0]);
++                              pRxPacket->NumFrags = 1;
++                              PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[CurrMac].RxQ_waiting, pRxPacket);
++                              pRxPacket++;
++                      }
++              }
++
++              /*
++              ** Allocate TX packet space, initialize the packets and
++              ** add them to the TX free queue. Free queue means that
++              ** packet is available and initialized, but no fragment
++              ** has been assigned to it. (Must be done at TX side)
++              */
++              pAC->TxPort[CurrMac][0].TransmitPacketTable = 
++                      kmalloc((TX_MAX_NBR_BUFFERS * sizeof(SK_PACKET)), GFP_KERNEL);
++
++              if (pAC->TxPort[CurrMac][0].TransmitPacketTable == NULL) {
++                      SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR,
++                              ("AllocatePacketBuffersYukon2: no mem TxPkts (port %i)",CurrMac));
++                      kfree(pAC->RxPort[CurrMac].ReceivePacketTable);
++                      return(SK_FALSE);
++              } else {
++                      SK_MEMSET(pAC->TxPort[CurrMac][0].TransmitPacketTable, 0, 
++                              (TX_MAX_NBR_BUFFERS * sizeof(SK_PACKET)));
++              
++                      pTxPacket = pAC->TxPort[CurrMac][0].TransmitPacketTable;
++
++                      for (CurrBuff=0;CurrBuff<TX_MAX_NBR_BUFFERS;CurrBuff++) {
++                              PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->TxPort[CurrMac][0].TxQ_free, pTxPacket);
++                              pTxPacket++;
++                      }
++              }
++      } /* end for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) */
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT,
++              ("<== AllocatePacketBuffersYukon2 (OK)\n"));
++      return(SK_TRUE);
++
++}     /* AllocatePacketBuffersYukon2 */
++
++/*****************************************************************************
++ *
++ *    FreeLETables - release allocated memory of LETables
++ *
++ * Description:
++ *      This function will free all resources of the LETables
++ *
++ * Arguments:
++ *      pAC - A pointer to the adapter context struct.
++ *
++ * Returns: N/A
++ */
++static void FreeLETables(
++SK_AC *pAC)  /* pointer to adapter control context */
++{
++      dma_addr_t      pPhysMemAddr;
++      char            *pVirtMemAddr;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("==> FreeLETables()\n"));
++      
++      /*
++      ** The RxLETable is the first of all LET. 
++      ** Therefore we can use its address for the input 
++      ** of the free function.
++      */
++      pVirtMemAddr = (char *) pAC->RxPort[0].RxLET.pLETab;
++      pPhysMemAddr = (((SK_U64) pAC->RxPort[0].RxLET.pPhyLETABHigh << (SK_U64) 32) | 
++                      ((SK_U64) pAC->RxPort[0].RxLET.pPhyLETABLow));
++
++      /* free continuous memory */
++      pci_free_consistent(pAC->PciDev, pAC->SizeOfAlignedLETables,
++                          pVirtMemAddr, pPhysMemAddr);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("<== FreeLETables()\n"));
++}     /* FreeLETables */
++
++/*****************************************************************************
++ *
++ *    FreePacketBuffers - free's all packet buffers of an adapter
++ *
++ * Description:
++ *      This function will free all previously allocated memory of the 
++ *    packet buffers.
++ *
++ * Arguments:
++ *      pAC - A pointer to the adapter context struct.
++ *
++ * Returns: N/A
++ */
++static void FreePacketBuffers(
++SK_AC *pAC)  /* pointer to adapter control context */
++{
++      int Port;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("==> FreePacketBuffers()\n"));
++      
++      for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) {
++              kfree(pAC->RxPort[Port].ReceivePacketTable);
++              kfree(pAC->TxPort[Port][0].TransmitPacketTable);
++      }
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,
++              ("<== FreePacketBuffers()\n"));
++}     /* FreePacketBuffers */
++
++/*****************************************************************************
++ *
++ *    AllocAndMapRxBuffer - fill one buffer into the receive packet/fragment
++ *
++ * Description:
++ *    The function allocates a new receive buffer and assigns it to the
++ *    the passsed receive packet/fragment
++ *
++ * Returns:
++ *    SK_TRUE - a buffer was allocated and assigned
++ *    SK_FALSE - a buffer could not be added
++ */
++static SK_BOOL AllocAndMapRxBuffer(
++SK_AC      *pAC,        /* pointer to the adapter control context */
++SK_PACKET  *pSkPacket,  /* pointer to packet that is to fill      */
++int         Port)       /* port the packet belongs to             */
++{
++      struct sk_buff *pMsgBlock;  /* pointer to a new message block  */
++      SK_U64          PhysAddr;   /* physical address of a rx buffer */
++
++      SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++              ("--> AllocAndMapRxBuffer (Port: %i)\n", Port));
++
++      pMsgBlock = alloc_skb(pAC->RxPort[Port].RxBufSize, GFP_ATOMIC);
++      if (pMsgBlock == NULL) {
++              SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
++                      SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR,
++                      ("%s: Allocation of rx buffer failed !\n",
++                      pAC->dev[Port]->name));
++              SK_PNMI_CNT_NO_RX_BUF(pAC, pAC->RxPort[Port].PortIndex);
++              return(SK_FALSE);
++      }
++      skb_reserve(pMsgBlock, 8);
++
++      PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
++              virt_to_page(pMsgBlock->data),
++              ((unsigned long) pMsgBlock->data &
++              ~PAGE_MASK),
++              pAC->RxPort[Port].RxBufSize,
++              PCI_DMA_FROMDEVICE);
++
++      pSkPacket->pFrag->pVirt   = pMsgBlock->data;
++      pSkPacket->pFrag->pPhys   = PhysAddr;
++      pSkPacket->pFrag->FragLen = pAC->RxPort[Port].RxBufSize; /* for correct unmap */
++      pSkPacket->pMBuf          = pMsgBlock;  
++      pSkPacket->PacketLen      = pAC->RxPort[Port].RxBufSize;
++
++      SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
++              ("<-- AllocAndMapRxBuffer\n"));
++
++      return (SK_TRUE);
++}     /* AllocAndMapRxBuffer */
++
++/*******************************************************************************
++ *
++ * End of file
++ *
++ ******************************************************************************/
+diff -ruN linux-2.6.9.old/drivers/net/sk98lin/sky2le.c linux-2.6.9.new/drivers/net/sk98lin/sky2le.c
+--- linux-2.6.9.old/drivers/net/sk98lin/sky2le.c       1970-01-01 08:00:00.000000000 +0800
++++ linux-2.6.9.new/drivers/net/sk98lin/sky2le.c       2006-12-07 14:35:03.000000000 +0800
+@@ -0,0 +1,510 @@
++/*****************************************************************************
++ *
++ *    Name:           sky2le.c
++ *    Project:        Gigabit Ethernet Adapters, Common Modules
++ *    Version:        $Revision: 1.11 $
++ *    Date:           $Date: 2004/11/22 14:21:58 $
++ *    Purpose:        Functions for handling List Element Tables
++ *
++ *****************************************************************************/
++
++/******************************************************************************
++ *
++ *    (C)Copyright 2002-2004 Marvell.
++ *
++ *    This program is free software; you can redistribute it and/or modify
++ *    it under the terms of the GNU General Public License as published by
++ *    the Free Software Foundation; either version 2 of the License, or
++ *    (at your option) any later version.
++ *    The information in this file is provided "AS IS" without warranty.
++ *
++ ******************************************************************************/
++
++/*****************************************************************************
++ *
++ * Description:
++ *
++ * This module contains the code necessary for handling List Elements.
++ *
++ * Supported Gigabit Ethernet Chipsets:
++ *    Yukon-2 (PCI, PCI-X, PCI-Express)
++ *
++ * Include File Hierarchy:
++ *
++ *
++ *****************************************************************************/
++#include "h/skdrv1st.h"
++#include "h/skdrv2nd.h"
++
++/* defines *******************************************************************/
++/* typedefs ******************************************************************/
++/* global variables **********************************************************/
++/* local variables ***********************************************************/
++
++#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
++static const char SysKonnectFileId[] =
++      "@(#) $Id: sky2le.c,v 1.11 2004/11/22 14:21:58 malthoff Exp $ (C) Marvell.";
++#endif /* DEBUG || (!LINT && !SK_SLIM) */
++
++/* function prototypes *******************************************************/
++
++/*****************************************************************************
++ *
++ * SkGeY2InitSingleLETable() - initializes a list element table
++ *
++ * Description:
++ *    This function will initialize the selected list element table.
++ *    Should be called once during DriverInit. No InitLevel required.
++ *
++ * Arguments:
++ *    pAC                     - pointer to the adapter context struct.
++ *    pLETab          - pointer to list element table structure
++ *    NumLE           - number of list elements in this table
++ *    pVMem           - virtual address of memory allocated for this LE table
++ *    PMemLowAddr - physical address of memory to be used for the LE table
++ *    PMemHighAddr
++ *
++ * Returns:
++ *    nothing
++ */
++void SkGeY2InitSingleLETable(
++SK_AC *pAC,                   /* pointer to adapter context */
++SK_LE_TABLE   *pLETab,        /* pointer to list element table to be initialized */
++unsigned int NumLE,           /* number of list elements to be filled in tab */
++void  *pVMem,                 /* virtual address of memory used for list elements */
++SK_U32        PMemLowAddr,    /* physical addr of mem used for LE */
++SK_U32        PMemHighAddr)
++{
++      unsigned int i;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("==> SkGeY2InitSingleLETable()\n"));
++
++#ifdef DEBUG
++      if (NumLE != 2) {       /* not table for polling unit */
++              if ((NumLE % MIN_LEN_OF_LE_TAB) != 0 || NumLE > MAX_LEN_OF_LE_TAB) {
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
++                              ("ERROR: Illegal number of list elements %d\n", NumLE));
++              }
++      }
++#endif /* DEBUG */
++
++      /* special case: unused list element table */
++      if (NumLE == 0) {
++              PMemLowAddr = 0;
++              PMemHighAddr = 0;
++              pVMem = 0;
++      }
++
++      /*
++       * in order to get the best possible performance the macros to access
++       * list elements use & instead of %
++       * this requires the length of LE tables to be a power of 2
++       */
++
++      /*
++       * this code guarantees that we use the next power of 2 below the
++       * value specified for NumLe - this way some LEs in the table may
++       * not be used but the macros work correctly
++       * this code does not check for bad values below 128 because in such a
++       * case we cannot do anything here
++       */
++
++      if ((NumLE != 2) && (NumLE != 0)) {
++              /* no check for polling unit and unused sync Tx */
++              i = MIN_LEN_OF_LE_TAB;
++              while (NumLE > i) {
++                      i *= 2;
++                      if (i > MAX_LEN_OF_LE_TAB) {
++                              break;
++                      }
++              }
++              if (NumLE != i) {
++                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
++                              ("ERROR: Illegal number of list elements %d adjusted to %d\n",
++                              NumLE, (i / 2)));
++                      NumLE = i / 2;
++              }
++      }
++
++      /* set addresses */
++      pLETab->pPhyLETABLow = PMemLowAddr;
++      pLETab->pPhyLETABHigh = PMemHighAddr;
++      pLETab->pLETab = pVMem;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("contains %d LEs", NumLE));
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              (" and starts at virt %08lx and phys %08lx:%08lx\n",
++              pVMem, PMemHighAddr, PMemLowAddr));
++
++      /* initialize indexes */
++      pLETab->Done = 0;
++      pLETab->Put = 0;
++      pLETab->HwPut = 0;
++      /* initialize size */
++      pLETab->Num = NumLE;
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("<== SkGeY2InitSingleLETable()\n"));
++}     /* SkGeY2InitSingleLETable */
++
++/*****************************************************************************
++ *
++ * SkGeY2InitPrefetchUnit() - Initialize a Prefetch Unit
++ *
++ * Description:
++ *    Calling this function requires an already configured list element
++ *    table. The prefetch unit to be configured is specified in the parameter
++ *    'Queue'. The function is able to initialze the prefetch units of
++ *    the following queues: Q_R1, Q_R2, Q_XS1, Q_XS2, Q_XA1, Q_XA2.
++ *    The funcution should be called before SkGeInitPort().
++ *
++ * Arguments:
++ *    pAC - pointer to the adapter context struct.
++ *    IoC - I/O context.
++ *    Queue - I/O offset of queue e.g. Q_XA1.
++ *    pLETab - pointer to list element table to be initialized
++ *
++ * Returns: N/A
++ */
++void SkGeY2InitPrefetchUnit(
++SK_AC *pAC,                   /* pointer to adapter context */
++SK_IOC        IoC,                    /* I/O context */
++unsigned int Queue,           /* Queue offset for finding the right registers */
++SK_LE_TABLE   *pLETab)        /* pointer to list element table to be initialized */
++{
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("==> SkGeY2InitPrefetchUnit()\n"));
++
++#ifdef DEBUG
++      if (Queue != Q_R1 && Queue != Q_R2 && Queue != Q_XS1 &&
++              Queue != Q_XS2 && Queue != Q_XA1 && Queue != Q_XA2) {
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR,
++                      ("ERROR: Illegal queue identifier %x\n", Queue));
++      }
++#endif /* DEBUG */
++
++      /* disable the prefetch unit */
++      SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_CTRL_REG), PREF_UNIT_RST_SET);
++      SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_CTRL_REG), PREF_UNIT_RST_CLR);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("Base address: %08lx:%08lx\n", pLETab->pPhyLETABHigh,
++              pLETab->pPhyLETABLow));
++
++      /* Set the list base address  high part*/
++      SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_ADDR_HI_REG),
++              pLETab->pPhyLETABHigh);
++
++      /* Set the list base address low part */
++      SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_ADDR_LOW_REG),
++              pLETab->pPhyLETABLow);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("Last index: %d\n", pLETab->Num-1));
++
++      /* Set the list last index */
++      SK_OUT16(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_LAST_IDX_REG),
++              (SK_U16)(pLETab->Num - 1));
++
++      /* turn on prefetch unit */
++      SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_CTRL_REG), PREF_UNIT_OP_ON);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("<== SkGeY2InitPrefetchUnit()\n"));
++}     /* SkGeY2InitPrefetchUnit */
++
++
++/*****************************************************************************
++ *
++ * SkGeY2InitStatBmu() -      Initialize the Status BMU
++ *
++ * Description:
++ *    Calling this function requires an already configured list element
++ *    table. Ensure the status BMU is only initialized once during
++ *  DriverInit - InitLevel2 required.
++ *
++ * Arguments:
++ *    pAC - pointer to the adapter context struct.
++ *    IoC - I/O context.
++ *    pLETab - pointer to status LE table to be initialized
++ *
++ * Returns: N/A
++ */
++void SkGeY2InitStatBmu(
++SK_AC *pAC,                   /* pointer to adapter context */
++SK_IOC        IoC,                    /* I/O context */
++SK_LE_TABLE   *pLETab)        /* pointer to status LE table */
++{
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("==> SkGeY2InitStatBmu()\n"));
++
++      /* disable the prefetch unit */
++      SK_OUT32(IoC, STAT_CTRL, SC_STAT_RST_SET);
++      SK_OUT32(IoC, STAT_CTRL, SC_STAT_RST_CLR);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("Base address Low: %08lX\n", pLETab->pPhyLETABLow));
++
++      /* Set the list base address */
++      SK_OUT32(IoC, STAT_LIST_ADDR_LO, pLETab->pPhyLETABLow);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("Base address High: %08lX\n", pLETab->pPhyLETABHigh));
++
++      SK_OUT32(IoC, STAT_LIST_ADDR_HI, pLETab->pPhyLETABHigh);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("Last index: %d\n", pLETab->Num - 1));
++
++      /* Set the list last index */
++      SK_OUT16(IoC, STAT_LAST_IDX, (SK_U16)(pLETab->Num - 1));
++
++      if (HW_FEATURE(pAC, HWF_WA_DEV_43_418)) {
++
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++                      ("Set Tx index threshold\n"));
++              /* WA for dev. #4.3 */
++              SK_OUT16(IoC, STAT_TX_IDX_TH, ST_TXTH_IDX_MASK);
++
++              /* set Status-FIFO watermark */
++              SK_OUT8(IoC, STAT_FIFO_WM, 0x21);               /* WA for dev. #4.18 */
++
++              /* set Status-FIFO ISR watermark */
++              SK_OUT8(IoC, STAT_FIFO_ISR_WM, 0x07);   /* WA for dev. #4.18 */
++
++              /* WA for dev. #4.3 and #4.18 */
++              /* set Status-FIFO Tx timer init value */
++              SK_OUT32(IoC, STAT_TX_TIMER_INI, HW_MS_TO_TICKS(pAC, 10));
++      }
++      else {
++              /*
++               * Further settings may be added if required...
++               * 1) Status-FIFO watermark (STAT_FIFO_WM, STAT_FIFO_ISR_WM)
++               * 2) Status-FIFO timer values (STAT_TX_TIMER_INI,
++               *              STAT_LEV_TIMER_INI and STAT_ISR_TIMER_INI)
++               * but tests shows that the default values give the best results,
++               * therefore the defaults are used.
++               */
++
++              /*
++               * Theses settings should avoid the
++               * temporary hanging of the status BMU.
++               * May be not all required... still under investigation...
++               */
++              SK_OUT16(IoC, STAT_TX_IDX_TH, 0x000a);
++
++              /* set Status-FIFO watermark */
++              SK_OUT8(IoC, STAT_FIFO_WM, 0x10);
++
++
++              /* set Status-FIFO ISR watermark */
++              if (HW_FEATURE(pAC, HWF_WA_DEV_4109)) {
++                      SK_OUT8(IoC, STAT_FIFO_ISR_WM, 0x10);
++              }
++              else {
++                      SK_OUT8(IoC, STAT_FIFO_ISR_WM, 0x04);
++              }
++
++              SK_OUT32(IoC, STAT_ISR_TIMER_INI, 0x0190);
++      }
++
++      /* start Status-FIFO timer */
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("Start Status FiFo timer\n"));
++
++      /* enable the prefetch unit */
++      /* operational bit not functional for Yukon-EC, but fixed in Yukon-2 */
++      SK_OUT32(IoC, STAT_CTRL, SC_STAT_OP_ON);
++
++      /* start Status-FIFO timer */
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("Start Status FiFo timer\n"));
++
++      SK_OUT8(IoC, STAT_TX_TIMER_CTRL, TIM_START);
++      SK_OUT8(IoC, STAT_LEV_TIMER_CTRL, TIM_START);
++      SK_OUT8(IoC, STAT_ISR_TIMER_CTRL, TIM_START);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("<== SkGeY2InitStatBmu()\n"));
++}     /* SkGeY2InitStatBmu */
++
++#ifdef USE_POLLING_UNIT
++/*****************************************************************************
++ *
++ * SkGeY2InitPollUnit() -     Initialize the Polling Unit
++ *
++ * Description:
++ *    This function will write the data of one polling LE table into the
++ *  adapter.
++ *
++ * Arguments:
++ *    pAC - pointer to the adapter context struct.
++ *    IoC - I/O context.
++ *    pLETab - pointer to polling LE table to be initialized
++ *
++ * Returns: N/A
++ */
++void SkGeY2InitPollUnit(
++SK_AC *pAC,                   /* pointer to adapter context */
++SK_IOC        IoC,                    /* I/O context */
++SK_LE_TABLE   *pLETab)        /* pointer to polling LE table */
++{
++      SK_HWLE *pLE;
++      int     i;
++#ifdef VCPU
++      VCPU_VARS();
++#endif /* VCPU */
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("==> SkGeY2InitPollUnit()\n"));
++
++#ifdef VCPU
++      for (i = 0; i < SK_MAX_MACS; i++) {
++              GET_PO_LE(pLE, pLETab, i);
++              VCPU_START_AND_COPY_LE();
++              /* initialize polling LE but leave indexes invalid */
++              POLE_SET_OPC(pLE, OP_PUTIDX | HW_OWNER);
++              POLE_SET_LINK(pLE, i);
++              POLE_SET_RXIDX(pLE, 0);
++              POLE_SET_TXAIDX(pLE, 0);
++              POLE_SET_TXSIDX(pLE, 0);
++              VCPU_WRITE_LE();
++              SK_DBG_DUMP_PO_LE(pLE);
++      }
++#endif        /* VCPU */
++
++      /* disable the polling unit */
++      SK_OUT32(IoC, POLL_CTRL, PC_POLL_RST_SET);
++      SK_OUT32(IoC, POLL_CTRL, PC_POLL_RST_CLR);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("Base address Low: %08lX\n", pLETab->pPhyLETABLow));
++
++      /* Set the list base address */
++      SK_OUT32(IoC, POLL_LIST_ADDR_LO, pLETab->pPhyLETABLow);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("Base address High: %08lX\n", pLETab->pPhyLETABHigh));
++
++      SK_OUT32(IoC, POLL_LIST_ADDR_HI, pLETab->pPhyLETABHigh);
++
++      /* we don't need to write the last index - it is hardwired to 1 */
++
++      /* enable the prefetch unit */
++      SK_OUT32(IoC, POLL_CTRL, PC_POLL_OP_ON);
++
++      /*
++       * now we have to start the descriptor poll timer because it triggers
++       * the polling unit
++       */
++
++      /*
++       * still playing with the value (timer runs at 125 MHz)
++       * descriptor poll timer is enabled by GeInit
++       */
++      SK_OUT32(IoC, B28_DPT_INI,
++              (SK_DPOLL_DEF_Y2 * (SK_U32)pAC->GIni.GIHstClkFact / 100));
++
++      SK_OUT8(IoC, B28_DPT_CTRL, TIM_START);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
++              ("<== SkGeY2InitPollUnit()\n"));
++}     /* SkGeY2InitPollUnit */
++#endif        /* USE_POLLING_UNIT */
++
++
++/******************************************************************************
++ *
++ * SkGeY2SetPutIndex
++ *
++ * Description:
++ *   This function is writing the Done index of a transmit
++ *   list element table.
++ *
++ * Notes:
++ *    Dev. Issue 4.2
++ *
++ * Returns: N/A
++ */
++void SkGeY2SetPutIndex(
++SK_AC *pAC,                                   /* pointer to adapter context */
++SK_IOC        IoC,                                    /* pointer to the IO context */
++SK_U32        StartAddrPrefetchUnit,  /* start address of the prefetch unit */
++SK_LE_TABLE   *pLETab)                        /* list element table to work with */
++{
++      unsigned int Put;
++      SK_U16 EndOfListIndex;
++      SK_U16 HwGetIndex;
++      SK_U16 HwPutIndex;
++
++      /* set put index we would like to write */
++      Put = GET_PUT_IDX(pLETab);
++
++      /*
++       * in this case we wrap around
++       * new put is lower than last put given to hw
++       */
++      if (Put < pLETab->HwPut) {
++
++              /* set put index = last index of list */
++              EndOfListIndex = (NUM_LE_IN_TABLE(pLETab)-1);
++
++              /* read get index of hw prefetch unit */
++              SK_IN16(IoC, (StartAddrPrefetchUnit + PREF_UNIT_GET_IDX_REG),
++                      &HwGetIndex);
++
++              /* read put index of hw prefetch unit */
++              SK_IN16(IoC, (StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG),
++                      &HwPutIndex);
++
++              /* prefetch unit reached end of list */
++              /* prefetch unit reached first list element */
++              if (HwGetIndex == 0) {
++                      /* restore watermark */
++                      SK_OUT8(IoC, StartAddrPrefetchUnit + PREF_UNIT_FIFO_WM_REG, 0xe0U);
++                      /* write put index */
++                      SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG,
++                              (SK_U16)Put);
++
++                      /* remember put index  we wrote to hw */
++                      pLETab->HwPut = Put;
++              }
++              else if (HwGetIndex == EndOfListIndex) {
++                      /* set watermark to one list element */
++                      SK_OUT8(IoC, StartAddrPrefetchUnit + PREF_UNIT_FIFO_WM_REG, 8);
++                      /* set put index to first list element */
++                      SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG, 0);
++              }
++              /* prefetch unit did not reach end of list yet */
++              /* and we did not write put index to end of list yet */
++              else if ((HwPutIndex != EndOfListIndex) &&
++                               (HwGetIndex != EndOfListIndex)) {
++                      /* write put index */
++                      SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG,
++                              EndOfListIndex);
++              }
++              else {
++                      /* do nothing */
++              }
++      }
++      else {
++#ifdef XXX            /* leads in to problems in the Windows Driver */
++              if (Put != pLETab->HwPut) {
++                      /* write put index */
++                      SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG,
++                              (SK_U16)Put);
++                      /* update put index */
++                      UPDATE_HWPUT_IDX(pLETab);
++              }
++#else
++              /* write put index */
++              SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG,
++                      (SK_U16)Put);
++              /* update put index */
++              UPDATE_HWPUT_IDX(pLETab);
++#endif
++      }
++}     /* SkGeY2SetPutIndex */
++
index 8b89a90..9eec83c 100644 (file)
@@ -38,3 +38,4 @@ __find_get_block_slow-scale.patch
 debugging-fields-in-current.patch 
 increase-BH_LRU_SIZE.patch 
 tmp-debug.patch 
+linux-2.6.9-network_driver-for-sk98.patch