diff -urN linux-2.4.29-wt1-2xx/Documentation/Configure.help linux-2.4.29-wt1-syskonnect/Documentation/Configure.help --- linux-2.4.29-wt1-2xx/Documentation/Configure.help Sun Feb 6 00:47:49 2005 +++ linux-2.4.29-wt1-syskonnect/Documentation/Configure.help Sun Feb 6 22:21:26 2005 @@ -12169,6 +12169,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 @@ -12177,30 +12193,79 @@ - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter - 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 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 (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 (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 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 @@ -12220,6 +12285,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. @@ -12236,6 +12309,9 @@ say M here and read Documentation/modules.txt. This is recommended. The module will be called sk98lin.o. +CONFIG_SK98LIN_NAPI + NAPI is a new driver API designed to reduce CPU and interrupt load + when the driver is receiving lots of packets from the card. Sun GEM support CONFIG_SUNGEM diff -urN linux-2.4.29-wt1-2xx/Documentation/networking/sk98lin.txt linux-2.4.29-wt1-syskonnect/Documentation/networking/sk98lin.txt --- linux-2.4.29-wt1-2xx/Documentation/networking/sk98lin.txt Fri Feb 20 07:38:24 2004 +++ linux-2.4.29-wt1-syskonnect/Documentation/networking/sk98lin.txt Sun Feb 6 22:21:26 2005 @@ -1,38 +1,56 @@ -(C)Copyright 1999-2003 Marvell(R). +(C)Copyright 1999-2005 Marvell(R). All rights reserved -=========================================================================== +================================================================================ -sk98lin.txt created 15-Dec-2003 +sk98lin.txt created 17-Jan-2005 -Readme File for sk98lin v6.21 -Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX +Readme File for sk98lin v8.13.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,7 +58,7 @@ *** -3 Installation +4 Installation =============== It is recommended to download the latest version of the driver from the @@ -49,7 +67,7 @@ installed. For details on how to patch a Linux kernel, refer to the patch.txt file. -3.1 Driver Installation +4.1 Driver Installation ------------------------ The following steps describe the actions that are required to install @@ -110,13 +128,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 +171,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 +183,8 @@ *** -4 Driver Parameters + +5 Driver Parameters ==================== Parameters can be set at the command line after the module has been @@ -208,7 +227,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 +301,7 @@ with this parameter. -4.2 Adapter Parameters +5.2 Adapter Parameters ----------------------- Connection Type (SK-98xx V2.0 copper adapters only) @@ -379,7 +398,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 @@ -429,10 +447,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 @@ -459,7 +561,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 +579,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 -urN linux-2.4.29-wt1-2xx/drivers/net/Config.in linux-2.4.29-wt1-syskonnect/drivers/net/Config.in --- linux-2.4.29-wt1-2xx/drivers/net/Config.in Sun Feb 6 00:04:24 2005 +++ linux-2.4.29-wt1-syskonnect/drivers/net/Config.in Sun Feb 6 22:21:26 2005 @@ -274,6 +274,9 @@ tristate 'SB1250 Ethernet support' CONFIG_NET_SB1250_MAC fi dep_tristate 'Marvell Yukon Chipset / SysKonnect SK-98xx Support' CONFIG_SK98LIN $CONFIG_PCI +if [ "$CONFIG_SK98LIN" != "n" ]; then + bool ' Use Rx polling (NAPI)' CONFIG_SK98LIN_NAPI +fi dep_tristate 'Broadcom Tigon3 support' CONFIG_TIGON3 $CONFIG_PCI if [ "$CONFIG_MOMENCO_OCELOT_C" = "y" -o "$CONFIG_MOMENCO_JAGUAR_ATX" = "y" ]; then diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/Makefile linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/Makefile --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/Makefile Fri Feb 20 07:38:29 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/Makefile Sun Feb 6 22:21:26 2005 @@ -1,7 +1,57 @@ -# File: drivers/sk98lin/Makefile +#****************************************************************************** # -# Makefile for the SysKonnect SK-98xx device driver. +# Name: skge.c +# Project: GEnesis, PCI Gigabit Ethernet Adapter +# Version: $Revision: 1.9 $ +# Date: $Date: 2004/07/13 15:54:50 $ +# Purpose: The main driver source module # +#****************************************************************************** + +#****************************************************************************** +# +# (C)Copyright 1998-2002 SysKonnect GmbH. +# (C)Copyright 2002-2004 Marvell. +# +# Makefile for Marvell Yukon chipset and SysKonnect Gigabit Ethernet +# Server Adapter driver. (Kernel 2.4) +# +# 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.4,v $ +# 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:40:36 mlindner +# Fix: Add CONFIG_SK98LIN_ZEROCOPY as default value +# +# 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 +# +# +#****************************************************************************** + # # Standalone driver params @@ -14,13 +64,16 @@ obj-y := \ 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 \ @@ -78,15 +131,13 @@ # SK_DBGCAT_DRV_INT_SRC 0x04000000 interrupts sources # SK_DBGCAT_DRV_EVENT 0x08000000 driver events -EXTRA_CFLAGS += -I. -DSK_DIAG_SUPPORT -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM) +EXTRA_CFLAGS += -I. -DSK_USE_CSUM -DSK_DIAG_SUPPORT -DGENESIS \ + -DCONFIG_SK98LIN_ZEROCOPY -DYUKON -DYUK2 \ + $(DBGDEF) $(SKPARAM) include $(TOPDIR)/Rules.make clean: rm -f core *.o *.a *.s - - - - diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/build_no.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/build_no.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/build_no.c Mon Apr 21 22:41:03 2003 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/build_no.c Thu Jan 1 01:00:00 1970 @@ -1,10 +0,0 @@ -/****************************************************************************** - * - * Name: Build_No.c - * Version: 1.01 - * - */ - -static const char SysKonnectBuildNumber[] = - "@(#)SK-BUILD: 6.02 (20021219) PL: ALL.01"; -^Z \ No newline at end of file diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/lm80.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/lm80.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/lm80.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/lm80.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: lm80.h * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.1 $ + * Date: $Date: 2003/10/27 14:16:08 $ * Purpose: Contains all defines for the LM80 Chip * (National Semiconductor). * diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skaddr.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skaddr.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skaddr.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skaddr.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skaddr.h * Project: Gigabit Ethernet Adapters, ADDR-Modul + * Version: $Revision: 2.1 $ + * Date: $Date: 2003/10/27 14:16:07 $ * Purpose: Header file for Address Management (MC, UC, Prom). * ******************************************************************************/ diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skcsum.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skcsum.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skcsum.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skcsum.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skcsum.h * Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx) + * Version: $Revision: 2.2 $ + * Date: $Date: 2003/12/29 15:37:26 $ * Purpose: Store/verify Internet checksum in send/receive packets. * ******************************************************************************/ @@ -155,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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skdebug.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skdebug.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skdebug.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skdebug.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skdebug.h * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.2 $ + * Date: $Date: 2004/02/26 16:06:06 $ * Purpose: SK specific DEBUG support * ******************************************************************************/ @@ -56,6 +58,9 @@ #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 /* Debug events */ diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skdrv1st.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skdrv1st.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skdrv1st.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skdrv1st.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skdrv1st.h * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.5.2.4 $ + * Date: $Date: 2004/11/22 16:15:55 $ * Purpose: First header file for driver and all other modules * ******************************************************************************/ @@ -20,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 @@ -56,13 +44,9 @@ #define SK_ADDR_EQUAL(a1,a2) (!memcmp(a1,a2,6)) -#if !defined(__OPTIMIZE__) || !defined(__KERNEL__) -#warning You must compile this file with the correct options! -#warning See the last lines of the source file. -#error You must compile this driver with "-O". -#endif +#define SK_STRNCMP(s1,s2,len) strncmp(s1,s2,len) +#define SK_STRCPY(dest,src) strcpy(dest,src) -#include #include #include #include @@ -83,11 +67,7 @@ #include #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" @@ -95,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 @@ -193,3 +177,8 @@ #endif +/******************************************************************************* + * + * End of file + * + ******************************************************************************/ diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skdrv2nd.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skdrv2nd.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skdrv2nd.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skdrv2nd.h Sun Feb 6 22:21:26 2005 @@ -1,15 +1,17 @@ /****************************************************************************** * - * Name: skdrv2nd.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Purpose: Second header file for driver and all other modules + * Name: skdrv2nd.h + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.29.2.13 $ + * Date: $Date: 2004/11/25 15:23:19 $ + * Purpose: Second header file for driver and all other modules * ******************************************************************************/ /****************************************************************************** * * (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 @@ -40,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" @@ -51,151 +54,165 @@ #include "h/skrlmt.h" #include "h/skgedrv.h" -#define SK_PCI_ISCOMPLIANT(result, pdev) { \ - result = SK_FALSE; /* default */ \ - /* 3Com (0x10b7) */ \ - if (pdev->vendor == 0x10b7) { \ - /* Gigabit Ethernet Adapter (0x1700) */ \ - if ((pdev->device == 0x1700)) { \ - result = SK_TRUE; \ - } \ - /* SysKonnect (0x1148) */ \ - } else if (pdev->vendor == 0x1148) { \ - /* SK-98xx Gigabit Ethernet Server Adapter (0x4300) */ \ - /* SK-98xx V2.0 Gigabit Ethernet Adapter (0x4320) */ \ - if ((pdev->device == 0x4300) || \ - (pdev->device == 0x4320)) { \ - result = SK_TRUE; \ - } \ - /* D-Link (0x1186) */ \ - } else if (pdev->vendor == 0x1186) { \ - /* Gigabit Ethernet Adapter (0x4c00) */ \ - if ((pdev->device == 0x4c00)) { \ - result = SK_TRUE; \ - } \ - /* Marvell (0x11ab) */ \ - } else if (pdev->vendor == 0x11ab) { \ - /* Gigabit Ethernet Adapter (0x4320) */ \ - if ((pdev->device == 0x4320)) { \ - result = SK_TRUE; \ - } \ - /* CNet (0x1371) */ \ - } else if (pdev->vendor == 0x1371) { \ - /* GigaCard Network Adapter (0x434e) */ \ - if ((pdev->device == 0x434e)) { \ - result = SK_TRUE; \ - } \ - /* Linksys (0x1737) */ \ - } else if (pdev->vendor == 0x1737) { \ - /* Gigabit Network Adapter (0x1032) */ \ - /* Gigabit Network Adapter (0x1064) */ \ - if ((pdev->device == 0x1032) || \ - (pdev->device == 0x1064)) { \ - result = SK_TRUE; \ - } \ - } else { \ - result = SK_FALSE; \ - } \ -} +/****************************************************************************** + * + * 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 */ -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); +/* + * 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 void +#define SkIsrRetNone NULL +#define SkIsrRetHandled NULL + +#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* 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 @@ -204,20 +221,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 @@ -243,114 +256,421 @@ #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 */ +}; + +/****************************************************************************** + * + * Generic Yukon-II defines + * + ******************************************************************************/ + +#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; }; -/* Used interrupt bits in the interrupts source register *********************/ +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 */ -#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)) + /* 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 IRQ_HWE_MASK (IS_ERR_MSK) /* enable all HW irqs */ +#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); \ +} + +/* 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]; +#ifdef Y2_RECOVERY + struct timer_list KernelTimer; /* Kernel timer struct */ + int TransmitTimeoutTimer; /* Transmit timer */ + SK_BOOL TimerExpired; /* Transmit timer */ +#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; }; -/* 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)) @@ -362,139 +682,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 */ + 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 */ + int RxBufSize; /* length of receive buffers */ + 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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skerror.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skerror.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skerror.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skerror.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skerror.h * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.2 $ + * Date: $Date: 2004/05/24 15:27:19 $ * Purpose: SK specific Error log support * ******************************************************************************/ @@ -9,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. * ******************************************************************************/ @@ -34,7 +35,6 @@ #define SK_ERRCL_HW (1L<<4) /* Hardware Failure */ #define SK_ERRCL_COMM (1L<<5) /* Communication error */ - /* * Define Error Code Bases */ @@ -47,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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgedrv.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgedrv.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgedrv.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgedrv.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skgedrv.h * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.1 $ + * Date: $Date: 2003/10/27 14:16:08 $ * Purpose: Interface with the driver * ******************************************************************************/ diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgehw.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgehw.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgehw.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgehw.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skgehw.h * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.48 $ + * Date: $Date: 2005/01/11 08:54:13 $ * Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product Family * ******************************************************************************/ @@ -9,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. * ******************************************************************************/ @@ -112,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 @@ -130,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) @@ -178,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 */ @@ -218,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) */ @@ -227,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 */ @@ -264,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 */ @@ -277,12 +338,11 @@ #define PCI_SKEW_DAS (0xfL<<4) /* Bit 7.. 4: Skew Ctrl, DAS Ext */ #define PCI_SKEW_BASE 0xfL /* Bit 3.. 0: Skew Ctrl, Base */ - /* 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 @@ -295,21 +355,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 */ @@ -320,7 +379,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) */ @@ -331,7 +390,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) */ @@ -347,8 +466,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*/ @@ -398,14 +523,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 */ @@ -437,6 +571,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 */ /* @@ -446,9 +584,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 @@ -515,8 +657,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 */ /* @@ -530,7 +672,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 */ @@ -568,8 +719,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 */ @@ -581,17 +761,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 @@ -601,7 +781,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 */ @@ -626,20 +806,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 */ /* @@ -656,7 +838,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 */ @@ -674,18 +856,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 */ /* @@ -711,12 +894,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 @@ -740,11 +995,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) */ @@ -762,11 +1015,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 */ @@ -798,13 +1062,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 */ @@ -812,26 +1089,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 */ @@ -877,12 +1155,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 */ @@ -898,6 +1215,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 */ @@ -906,19 +1260,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 */ @@ -958,9 +1358,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 */ @@ -980,7 +1377,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 */ @@ -1030,10 +1427,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 */ @@ -1050,16 +1445,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 */ @@ -1169,7 +1568,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 */ @@ -1210,6 +1609,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 */ @@ -1258,6 +1692,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 */ @@ -1273,24 +1714,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 */ @@ -1298,16 +1739,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 */ @@ -1357,9 +1813,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 */ @@ -1370,7 +1826,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 */ @@ -1389,12 +1845,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 */ @@ -1405,86 +1865,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 */ @@ -1538,14 +2050,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) */ @@ -1577,15 +2089,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 @@ -1604,17 +2120,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; @@ -1626,29 +2142,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 */ @@ -1683,6 +2432,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 */ @@ -1691,6 +2444,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() * @@ -1702,11 +2459,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. @@ -1717,14 +2490,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() @@ -1738,19 +2511,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) * @@ -1775,22 +2539,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 */ @@ -1800,13 +2573,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); \ } @@ -1816,10 +2589,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))); \ } @@ -1829,16 +2602,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); \ } @@ -1848,13 +2621,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))); \ } @@ -1864,7 +2637,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) @@ -1883,22 +2656,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) { \ @@ -1906,13 +2688,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); \ } @@ -1922,10 +2704,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))); \ } @@ -1935,16 +2717,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); \ } @@ -1954,13 +2736,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))); \ } @@ -2008,30 +2790,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) { \ @@ -2042,7 +2824,7 @@ } \ } while ((Mmu & XM_MMU_PHY_RDY) == 0); \ XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \ - } \ + } \ } #endif /* DEBUG */ @@ -2050,17 +2832,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); \ - } \ + } \ } /* @@ -2069,12 +2851,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) @@ -2086,7 +2870,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 @@ -2105,12 +2889,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 *******************************************************************/ @@ -2122,3 +2921,4 @@ #endif /* __cplusplus */ #endif /* __INC_SKGEHW_H */ + diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgehwt.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgehwt.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgehwt.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgehwt.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skhwt.h * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 2.1 $ + * Date: $Date: 2003/10/27 14:16:09 $ * Purpose: Defines for the hardware timer functions * ******************************************************************************/ diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgei2c.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgei2c.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgei2c.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgei2c.h Thu Jan 1 01:00:00 1970 @@ -1,208 +0,0 @@ -/****************************************************************************** - * - * Name: skgei2c.h - * Project: Gigabit Ethernet Adapters, TWSI-Module - * 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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgeinit.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgeinit.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgeinit.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgeinit.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skgeinit.h * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.35 $ + * Date: $Date: 2004/12/17 11:17:25 $ * Purpose: Structures and prototypes for the GE Init Module * ******************************************************************************/ @@ -9,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. * ******************************************************************************/ @@ -58,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 */ @@ -81,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 */ @@ -102,31 +112,25 @@ #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 */ @@ -165,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 */ @@ -187,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 */ @@ -218,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 */ @@ -237,24 +241,24 @@ #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 */ +#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 */ @@ -264,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 */ @@ -288,18 +298,166 @@ /* 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_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 in units of 1 kB */ +#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_ENA_JUMBO_FRAME_SUPPORT(pAC) (pAC)->GIni.GIPortUsage = SK_JUMBO_LINK +#define HW_DIS_JUMBO_FRAME_SUPPORT(pAC) (pAC)->GIni.GIPortUsage = ???? +#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; /* @@ -309,7 +467,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 */ @@ -365,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; @@ -377,18 +537,27 @@ 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 GIChipCap; /* Adapter's Capabilities */ + int GIHstClkFact; /* Host Clock Factor (HstClk / 62.5 * 100) */ int GIPortUsage; /* Driver Port Usage */ int GILevel; /* Initialization Level completed */ int GIRamSize; /* The RAM size of the adapter in kB */ @@ -396,8 +565,10 @@ 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; @@ -415,7 +586,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) @@ -445,9 +616,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) @@ -462,6 +633,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, @@ -599,13 +788,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); @@ -622,28 +811,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, @@ -711,7 +900,7 @@ SK_AC *pAC, SK_IOC IoC, unsigned int Port, - SK_U16 IStatus, + SK_U16 IStatus, SK_U64 SK_FAR *pStatus); extern int SkGmOverflowStatus( @@ -727,6 +916,7 @@ int Port, SK_BOOL StartTest); +#ifdef SK_PHY_LP_MODE extern int SkGmEnterLowPowerMode( SK_AC *pAC, SK_IOC IoC, @@ -737,6 +927,7 @@ SK_AC *pAC, SK_IOC IoC, int Port); +#endif /* SK_PHY_LP_MODE */ #ifdef SK_DIAG extern void SkGePhyRead( @@ -792,6 +983,9 @@ extern void SkGeXmitLED(); extern void SkGeInitRamIface(); extern int SkGeInitAssignRamToQueues(); +extern void SkGePortVlan(); +extern void SkGeRxCsum(); +extern void SkGeRxRss(); /* * public functions in skxmac2.c @@ -801,7 +995,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(); @@ -812,11 +1006,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(); @@ -830,8 +1024,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(); @@ -842,10 +1038,11 @@ extern void SkXmSendCont(); #endif /* SK_DIAG */ -#endif /* SK_KR_PROTO */ +#endif /* SK_KR_PROTO */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __INC_SKGEINIT_H_ */ + diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgepnm2.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgepnm2.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgepnm2.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgepnm2.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skgepnm2.h * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 2.3 $ + * Date: $Date: 2004/03/19 16:19:59 $ * Purpose: Defines for Private Network Management Interface * ****************************************************************************/ @@ -68,9 +70,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 @@ -321,7 +323,7 @@ vSt, \ pAC->Pnmi.MacUpdatedFlag, \ pAC->Pnmi.RlmtUpdatedFlag, \ - pAC->Pnmi.SirqUpdatedFlag))}} + pAC->Pnmi.SirqUpdatedFlag));}} #else /* !DEBUG */ diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgepnmi.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgepnmi.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgepnmi.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgepnmi.h Sun Feb 6 22:21:26 2005 @@ -1,7 +1,9 @@ /***************************************************************************** * * Name: skgepnmi.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter + * 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 * ****************************************************************************/ @@ -29,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" @@ -39,7 +41,6 @@ */ #define SK_PNMI_MDB_VERSION 0x00030001 /* 3.1 */ - /* * Event definitions */ @@ -52,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 @@ -76,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() @@ -84,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 */ @@ -350,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. */ @@ -365,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. */ @@ -388,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 @@ -417,7 +465,6 @@ #define SK_SET_FULL_MIB 5 #define SK_PRESET_FULL_MIB 6 - /* * Define error numbers and messages for syslog */ @@ -450,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) @@ -492,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) @@ -512,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) @@ -824,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 @@ -854,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 { @@ -931,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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgesirq.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgesirq.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgesirq.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgesirq.h Sun Feb 6 22:21:26 2005 @@ -2,20 +2,21 @@ * * Name: skgesirq.h * Project: Gigabit Ethernet Adapters, Common Modules - * 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. * ******************************************************************************/ @@ -42,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 @@ -100,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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgetwsi.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgetwsi.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skgetwsi.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skgetwsi.h Sun Feb 6 22:21:26 2005 @@ -0,0 +1,241 @@ +/****************************************************************************** + * + * Name: skgetwsi.h + * Project: Gigabit Ethernet Adapters, TWSI-Module + * Version: $Revision: 1.6 $ + * Date: $Date: 2004/11/08 15:04:00 $ + * 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_1V2_VAL * C_PLUS_15) +#define SK_SEN_CORE_1V3_HIGH_WARN (SK_I32)(SK_SEN_CORE_1V2_VAL * C_PLUS_10) +#define SK_SEN_CORE_1V3_LOW_WARN (SK_I32)(SK_SEN_CORE_1V2_VAL * C_MINUS_5) +#define SK_SEN_CORE_1V3_LOW_ERR (SK_I32)(SK_SEN_CORE_1V2_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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/ski2c.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/ski2c.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/ski2c.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/ski2c.h Thu Jan 1 01:00:00 1970 @@ -1,175 +0,0 @@ -/****************************************************************************** - * - * Name: ski2c.h - * Project: Gigabit Ethernet Adapters, TWSI-Module - * 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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skqueue.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skqueue.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skqueue.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skqueue.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skqueue.h * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 2.3 $ + * Date: $Date: 2004/05/14 13:39:15 $ * Purpose: Defines for the Event queue * ******************************************************************************/ @@ -20,6 +22,10 @@ * ******************************************************************************/ +/* + * SKQUEUE.H contains all defines and types for the event queue + */ + #ifndef _SKQUEUE_H_ #define _SKQUEUE_H_ @@ -39,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 @@ -84,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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skrlmt.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skrlmt.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skrlmt.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skrlmt.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skrlmt.h * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 2.1 $ + * Date: $Date: 2003/10/27 14:16:09 $ * Purpose: Header file for Redundant Link ManagemenT. * ******************************************************************************/ diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/sktimer.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/sktimer.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/sktimer.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/sktimer.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: sktimer.h * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 2.1 $ + * Date: $Date: 2003/10/27 14:16:09 $ * Purpose: Defines for the timer functions * ******************************************************************************/ diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/sktwsi.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/sktwsi.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/sktwsi.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/sktwsi.h Sun Feb 6 22:21:26 2005 @@ -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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/sktypes.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/sktypes.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/sktypes.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/sktypes.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: sktypes.h * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.2 $ + * Date: $Date: 2004/07/09 13:29:49 $ * Purpose: Define data types for Linux * ******************************************************************************/ @@ -20,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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skversion.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skversion.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skversion.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skversion.h Sun Feb 6 22:21:26 2005 @@ -1,15 +1,17 @@ /****************************************************************************** * - * Name: version.h + * Name: skversion.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Purpose: SK specific Error log support + * Version: $Revision: 1.3 $ + * Date: $Date: 2004/07/09 13:33:59 $ + * Purpose: specific version strings and numbers * ******************************************************************************/ /****************************************************************************** * * (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 @@ -20,17 +22,15 @@ * ******************************************************************************/ -#ifdef lint -static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH."; -static const char SysKonnectBuildNumber[] = - "@(#)SK-BUILD: 6.22 PL: 01"; -#endif /* !defined(lint) */ - -#define BOOT_STRING "sk98lin: Network Device Driver v6.22\n" \ - "(C)Copyright 1999-2004 Marvell(R)." - -#define VER_STRING "6.22" -#define DRIVER_FILE_NAME "sk98lin" -#define DRIVER_REL_DATE "Jan-30-2004" - +#define BOOT_STRING "sk98lin: Network Device Driver v8.13.1.3\n" \ + "(C)Copyright 1999-2005 Marvell(R)." +#define VER_STRING "8.13.1.3" +#define PATCHLEVEL "01" +#define DRIVER_FILE_NAME "sk98lin" +#define DRIVER_REL_DATE "Jan-17-2005" +/******************************************************************************* + * + * End of file + * + ******************************************************************************/ diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skvpd.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skvpd.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/skvpd.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/skvpd.h Sun Feb 6 22:21:26 2005 @@ -1,20 +1,22 @@ /****************************************************************************** * * Name: skvpd.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter + * 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. * ******************************************************************************/ @@ -29,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 */ @@ -38,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() */ @@ -53,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 */ /* @@ -62,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 @@ -124,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) @@ -133,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, @@ -238,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, @@ -252,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(); @@ -267,3 +278,4 @@ #endif /* SK_KR_PROTO */ #endif /* __INC_SKVPD_H_ */ + diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/sky2le.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/sky2le.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/sky2le.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/sky2le.h Sun Feb 6 22:21:26 2005 @@ -0,0 +1,854 @@ +/****************************************************************************** + * + * Name: sky2le.h + * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 1.8 $ + * Date: $Date: 2004/11/09 14:26:38 $ + * 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 + +#define LE2DWord(value) (value) + +#else /* !SK_LITTLE_ENDIAN */ + +#define LE2DWord(value) \ + ((((value)<<24L) & 0xff000000L) + \ + (((value)<< 8L) & 0x00ff0000L) + \ + (((value)>> 8L) & 0x0000ff00L) + \ + (((value)>>24L) & 0x000000ffL)) + +#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 + +#define DWord2LE(value) (value) + +#else /* !SK_LITTLE_ENDIAN */ + +#define DWord2LE(value) \ + ((((value)<<24L) & 0xff000000L) + \ + (((value)<< 8L) & 0x00ff0000L) + \ + (((value)>> 8L) & 0x0000ff00L) + \ + (((value)>>24L) & 0x000000ffL)) + +#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 + +#define LE2Word(value) (value) + +#else /* !SK_LITTLE_ENDIAN */ + +#define LE2Word(value) \ + ((((value)<< 8L) & 0xff00) + \ + (((value)>> 8L) & 0x00ff)) + +#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 + +#define Word2LE(value) (value) + +#else /* !SK_LITTLE_ENDIAN */ + +#define Word2LE(value) \ + ((((value)<< 8L) & 0xff00) + \ + (((value)>> 8L) & 0x00ff)) + +#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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/xmac_ii.h linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/xmac_ii.h --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/h/xmac_ii.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/h/xmac_ii.h Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: xmac_ii.h * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.11 $ + * Date: $Date: 2005/01/04 14:14:20 $ * Purpose: Defines and Macros for Gigabit Ethernet Controller * ******************************************************************************/ @@ -9,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. * ******************************************************************************/ @@ -447,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 */ @@ -467,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, @@ -508,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 */ @@ -539,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 */ /*----------------------------------------------------------------------------*/ /* @@ -572,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 */ @@ -583,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 */ /*----------------------------------------------------------------------------*/ /* @@ -601,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 */ @@ -616,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. */ @@ -627,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 */ @@ -647,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 @@ -673,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 */ @@ -825,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 */ @@ -979,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 */ @@ -1027,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 @@ -1039,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 */ @@ -1084,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 */ @@ -1109,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 */ @@ -1215,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 */ @@ -1225,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 */ @@ -1238,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 @@ -1269,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 @@ -1429,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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skaddr.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skaddr.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skaddr.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skaddr.c Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skaddr.c * Project: Gigabit Ethernet Adapters, ADDR-Module + * Version: $Revision: 2.4 $ + * Date: $Date: 2004/11/12 14:03:54 $ * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode. * ******************************************************************************/ @@ -42,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.4 2004/11/12 14:03:54 mkunz Exp $ (C) Marvell."; #endif /* DEBUG ||!LINT || !SK_SLIM */ #define __SKADDR_C @@ -189,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; @@ -211,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", @@ -221,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 */ @@ -264,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", @@ -273,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; */ @@ -337,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); @@ -350,7 +356,7 @@ #endif /* !SK_SLIM */ #ifndef SK_SLIM - +#ifdef GENESIS /****************************************************************************** * * SkAddrXmacMcClear - clear the multicast table @@ -402,11 +408,11 @@ return (SK_ADDR_SUCCESS); } /* SkAddrXmacMcClear */ - +#endif /* GENESIS */ #endif /* !SK_SLIM */ #ifndef SK_SLIM - +#ifdef YUKON /****************************************************************************** * * SkAddrGmacMcClear - clear the multicast table @@ -445,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 */ @@ -487,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)) { @@ -497,9 +503,10 @@ return (SK_ADDR_SUCCESS); } /* SkAddrGmacMcClear */ +#endif /* YUKON */ #ifndef SK_ADDR_CHEAT - +#ifdef GENESIS /****************************************************************************** * * SkXmacMcHash - hash multicast address @@ -536,8 +543,9 @@ return (Crc & ((1 << HASH_BITS) - 1)); } /* SkXmacMcHash */ +#endif /* GENESIS */ - +#ifdef YUKON /****************************************************************************** * * SkGmacMcHash - hash multicast address @@ -595,7 +603,7 @@ return (Crc & ((1 << HASH_BITS) - 1)); } /* SkGmacMcHash */ - +#endif /* YUKON */ #endif /* !SK_ADDR_CHEAT */ /****************************************************************************** @@ -636,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 @@ -756,8 +768,9 @@ } } /* SkAddrXmacMcAdd */ +#endif /* GENESIS */ - +#ifdef YUKON /****************************************************************************** * * SkAddrGmacMcAdd - add a multicast address to a port @@ -819,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 */ @@ -843,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 */ } @@ -858,7 +871,7 @@ return (SK_MC_FILTERING_INEXACT); } /* SkAddrGmacMcAdd */ - +#endif /* YUKON */ #endif /* !SK_SLIM */ /****************************************************************************** @@ -890,7 +903,7 @@ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber) /* Port Number */ { - int ReturnCode; + int ReturnCode = SK_ADDR_ILLEGAL_PORT; #if (!defined(SK_SLIM) || defined(DEBUG)) if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); @@ -946,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. */ @@ -1041,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 */ @@ -1093,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 @@ -1155,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", @@ -1164,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 @@ -1371,7 +1384,7 @@ pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2], pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3], pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4], - pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5])) + pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5])); SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, ("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n", @@ -1380,7 +1393,7 @@ pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2], pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3], pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4], - pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5])) + pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5])); #endif /* DEBUG */ /* Write address to first exact match entry of active port. */ @@ -1422,7 +1435,7 @@ SK_U32 PortNumber, /* port whose promiscuous mode changes */ int NewPromMode) /* new promiscuous mode */ { - int ReturnCode; + 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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skcsum.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skcsum.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skcsum.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skcsum.c Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skcsum.c * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 2.1 $ + * Date: $Date: 2003/10/27 14:16:08 $ * Purpose: Store/verify Internet checksum in send/receive packets. * ******************************************************************************/ @@ -23,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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skdim.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skdim.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skdim.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skdim.c Sun Feb 6 22:21:26 2005 @@ -1,16 +1,29 @@ /****************************************************************************** * - * Name: skdim.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Purpose: All functions to maintain interrupt moderation + * Name: skdim.c + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.5 $ + * Date: $Date: 2004/07/17 13:28:43 $ + * Purpose: All functions regardig interrupt moderation * ******************************************************************************/ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2004 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 + * + * The technical manual for the adapters is available from SysKonnect's + * web pages: www.syskonnect.com + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -18,709 +31,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 - -/******************************************************************************* -** -** 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; - -#ifdef CONFIG_SMP - unsigned int SKNumCpus = smp_num_cpus; -#else - unsigned int SKNumCpus = 1; -#endif +/****************************************************************************** + * + * 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); + } - for (NbrCpu = 0; NbrCpu < SKNumCpus; NbrCpu++) { -#ifdef _LINUX_PROCESS_TIMING_H /* - ** all seconds and usec values being obtained from the - ** process_timing entries need to be adapted to jiffies - ** (in case we have a system supporting process times) + ** We have a Yukon2 compliant chipset if we come up to here + ** + if (pAC->GIni.GIMacsFound == 2) { + StatusPort1IntDiff = pAC->Pnmi.Port[1].StatusLeIntrCts - + M_DIMINFO.PrevPort1StatusIntrCts; + } + StatusPort0IntDiff = pAC->Pnmi.Port[0].StatusLeIntrCts - + M_DIMINFO.PrevPort0StatusIntrCts; */ - UserTime = UserTime + (kstat_percpu[NbrCpu].user.tv_sec * 10) - + (kstat_percpu[NbrCpu].user.tv_usec/100000); - NiceTime = NiceTime + (kstat_percpu[NbrCpu].nice.tv_sec * 10) - + (kstat_percpu[NbrCpu].nice.tv_usec/100000); - SystemTime = SystemTime + (kstat_percpu[NbrCpu].system.tv_sec * 10) - + (kstat_percpu[NbrCpu].system.tv_usec/100000); -#else - UserTime = UserTime + kstat.per_cpu_user[NbrCpu]; - NiceTime = NiceTime + kstat.per_cpu_nice[NbrCpu]; - SystemTime = SystemTime + kstat.per_cpu_system[NbrCpu]; -#endif - } - - UsedTime = UserTime + NiceTime + SystemTime; - - IdleTime = jif * SKNumCpus - 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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skethtool.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skethtool.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skethtool.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skethtool.c Sun Feb 6 22:21:26 2005 @@ -0,0 +1,1335 @@ +/****************************************************************************** + * + * Name: skethtool.c + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.3.2.5 $ + * Date: $Date: 2004/12/07 15:16:12 $ + * Purpose: All functions regarding ethtool handling + * + ******************************************************************************/ + +/****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2004 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 + * + * The technical manual for the adapters is available from SysKonnect's + * web pages: www.syskonnect.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. + * + *****************************************************************************/ + +#include "h/skdrv1st.h" +#include "h/skdrv2nd.h" +#include "h/skversion.h" +#include +#include +#include + +/****************************************************************************** + * + * 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, pAC->PciDev->slot_name, 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 + 1*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 + (1*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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skge.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skge.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skge.c Sun Feb 6 00:04:28 2005 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skge.c Sun Feb 6 22:26:01 2005 @@ -1,25 +1,23 @@ /****************************************************************************** * - * Name: skge.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.43 $ - * Date: $Date: 2004/01/29 15:47:07 $ - * Purpose: The main driver source module + * Name: skge.c + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.60.2.28 $ + * Date: $Date: 2004/12/23 18:40:09 $ + * Purpose: The main driver source module * ******************************************************************************/ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2004 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 * @@ -38,71 +36,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: - * - * - * - * "h/skdrv1st.h" - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * those three depending on kernel version used: - * - * - * - * - * - * "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,6 +70,7 @@ #include #include +#include #ifdef CONFIG_PROC_FS #include @@ -118,6 +79,10 @@ #include "h/skdrv1st.h" #include "h/skdrv2nd.h" +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) +#include +#endif + /******************************************************************************* * * Defines @@ -127,62 +92,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 void -#define SkIsrRetNone NULL -#define SkIsrRetHandled NULL +#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) /******************************************************************************* @@ -191,12 +108,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); @@ -212,24 +140,34 @@ 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 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*); /******************************************************************************* * @@ -237,9 +175,30 @@ * ******************************************************************************/ +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 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 = NULL; +static struct proc_dir_entry *pSkRootDir; extern int sk_proc_read( char *buffer, char **buffer_location, off_t offset, @@ -248,11 +207,6 @@ void *data); #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); - #ifdef DEBUG static void DumpMsg(struct sk_buff*, char*); static void DumpData(char*, int); @@ -262,13 +216,12 @@ /* global variables *********************************************************/ static const char *BootString = BOOT_STRING; struct SK_NET_DEVICE *SkGeRootDev = NULL; -static int probed __initdata = 0; 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; @@ -276,271 +229,368 @@ +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, 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 +}; + + /***************************************************************************** * - * skge_probe - find all SK-98xx adapters + * sk98lin_init_device - initialize the adapter * * Description: - * This function scans the PCI bus for SK-98xx adapters. Resources for - * each adapter are allocated and the adapter is brought into Init 1 + * 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 __init skge_probe (void) +static int __devinit sk98lin_init_device(struct pci_dev *pdev, + const struct pci_device_id *ent) + { - int boards_found = 0; - int vendor_flag = SK_FALSE; + 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 pci_dev *pdev = NULL; struct SK_NET_DEVICE *dev = NULL; - SK_BOOL DeviceFound = SK_FALSE; - SK_BOOL BootStringCount = SK_FALSE; int retval; #ifdef CONFIG_PROC_FS int proc_root_initialized = 0; struct proc_dir_entry *pProcFile; #endif - if (probed) - return -ENODEV; - probed++; - - if (!pci_present()) { /* is PCI support present? */ - return -ENODEV; + retval = pci_enable_device(pdev); + if (retval) { + printk(KERN_ERR "Cannot enable PCI device, " + "aborting.\n"); + return retval; } - while((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) { + dev = NULL; + pNet = NULL; - dev = NULL; - pNet = NULL; + /* INSERT * We have to find the power-management capabilities */ + /* Find power-management capability. */ - SK_PCI_ISCOMPLIANT(vendor_flag, pdev); - if (!vendor_flag) - continue; - /* Configure DMA attributes. */ - if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL) && - pci_set_dma_mask(pdev, (u64) 0xffffffff)) - continue; + /* 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 = init_etherdev(dev, sizeof(DEV_NET))) == NULL) { - printk(KERN_ERR "Unable to allocate etherdev " - "structure!\n"); - break; - } - pNet = dev->priv; - pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); - if (pNet->pAC == NULL){ - unregister_netdev(dev); - dev->get_stats = NULL; - kfree(dev->priv); - printk(KERN_ERR "Unable to allocate adapter " - "structure!\n"); - break; - } + if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == NULL) { + printk(KERN_ERR "Unable to allocate etherdev " + "structure!\n"); + return -ENODEV; + } - /* Print message */ - if (!BootStringCount) { - /* set display flag to TRUE so that */ - /* we only display this string ONCE */ - BootStringCount = SK_TRUE; - printk("%s\n", BootString); - } + pNet = dev->priv; + pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); + if (pNet->pAC == NULL){ + unregister_netdev(dev); + dev->get_stats = NULL; + kfree(dev->priv); + printk(KERN_ERR "Unable to allocate adapter " + "structure!\n"); + return -ENODEV; + } - 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; - retval = SkGeInitPCI(pAC); - if (retval) { - printk("SKGE: PCI setup failed: %i\n", retval); - unregister_netdev(dev); - dev->get_stats = NULL; - kfree(dev); - continue; - } + /* 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); + unregister_netdev(dev); + dev->get_stats = NULL; + kfree(dev); + return -ENODEV; + } + + + 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; + + pAC->Index = sk98lin_boards_found; + + if (SkGeBoardInit(dev, pAC)) { + unregister_netdev(dev); + kfree(dev); + return -ENODEV; + } else { + ProductStr(pAC); + } - dev->open = &SkGeOpen; - dev->stop = &SkGeClose; + /* shifter to later moment in time... */ + if (CHIP_ID_YUKON_2(pAC)) { + dev->hard_start_xmit = &SkY2Xmit; + } else { 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 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->ChipsetType) { - /* Use only if yukon hardware */ - /* SK and ZEROCOPY - fly baby... */ - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; - } + 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 - pAC->Index = boards_found; + /* Save the hardware revision */ + pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) + + (pAC->GIni.GIPciHwRev & 0x0F); - if (SkGeBoardInit(dev, pAC)) { - unregister_netdev(dev); - kfree(dev); - continue; - } + /* 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)); - /* 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"))))); + /* Save initial device name */ + strcpy(pNet->InitialDevName, dev->name); - SkGeYellowLED(pAC, pAC->IoBase, 1); + /* 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); + memcpy((caddr_t) &dev->dev_addr, + (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6); - /* First adapter... Create proc and print message */ + /* First adapter... Create proc and print message */ #ifdef CONFIG_PROC_FS - if (!DeviceFound) { - DeviceFound = SK_TRUE; - SK_MEMCPY(&SK_Root_Dir_entry, BootString, - sizeof(SK_Root_Dir_entry) - 1); - - /*Create proc (directory)*/ - if(!proc_root_initialized) { - pSkRootDir = create_proc_entry(SK_Root_Dir_entry, - S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net); - pSkRootDir->owner = THIS_MODULE; - proc_root_initialized = 1; - } + 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(!proc_root_initialized) { + pSkRootDir = create_proc_entry(SK_Root_Dir_entry, + S_IFDIR | S_IRUGO | S_IXUGO, proc_net); + pSkRootDir->owner = THIS_MODULE; + proc_root_initialized = 1; } + } - /* Create proc file */ - pProcFile = create_proc_entry(dev->name, - S_IFREG | S_IXUSR | S_IWGRP | S_IROTH, - pSkRootDir); + /* Create proc file */ + pProcFile = create_proc_entry(dev->name, + S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, + pSkRootDir); - pProcFile->read_proc = sk_proc_read; - pProcFile->write_proc = NULL; - pProcFile->nlink = 1; - pProcFile->size = sizeof(dev->name + 1); - pProcFile->data = (void *)pProcFile; - pProcFile->owner = THIS_MODULE; + pProcFile->read_proc = sk_proc_read; + pProcFile->write_proc = NULL; + pProcFile->nlink = 1; + pProcFile->size = sizeof(dev->name + 1); + pProcFile->data = (void *)pProcFile; + pProcFile->owner = THIS_MODULE; #endif - pNet->PortNr = 0; - pNet->NetNr = 0; + pNet->PortNr = 0; + pNet->NetNr = 0; - boards_found++; + sk98lin_boards_found++; + pci_set_drvdata(pdev, dev); - /* More then one port found */ - if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - if ((dev = init_etherdev(NULL, sizeof(DEV_NET))) == 0) { - printk(KERN_ERR "Unable to allocate etherdev " - "structure!\n"); - break; - } + /* More then one port found */ + if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { + if ((dev = init_etherdev(NULL, 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; - 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; + pAC->dev[1] = dev; + pNet = dev->priv; + pNet->PortNr = 1; + pNet->NetNr = 1; + pNet->pAC = pAC; -#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; - } + if (CHIP_ID_YUKON_2(pAC)) { + dev->hard_start_xmit = &SkY2Xmit; + } else { + dev->hard_start_xmit = &SkGeXmit; + } + 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 NETIF_F_TSO +#ifdef USE_SK_TSO_FEATURE + if (CHIP_ID_YUKON_2(pAC)) { + dev->features |= NETIF_F_TSO; + } #endif #endif - -#ifdef CONFIG_PROC_FS - pProcFile = create_proc_entry(dev->name, - S_IFREG | S_IXUSR | S_IWGRP | S_IROTH, - pSkRootDir); - pProcFile->read_proc = sk_proc_read; - pProcFile->write_proc = NULL; - pProcFile->nlink = 1; - pProcFile->size = sizeof(dev->name + 1); - pProcFile->data = (void *)pProcFile; - pProcFile->owner = THIS_MODULE; +#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 - memcpy((caddr_t) &dev->dev_addr, - (caddr_t) &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; - SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA)); - SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), - sizeof(SK_PNMI_STRUCT_DATA)); + /* Save initial device name */ + strcpy(pNet->InitialDevName, dev->name); - /* - * This is bollocks, but we need to tell the net-init - * code that it shall go for the next device. - */ -#ifndef MODULE - dev->base_addr = 0; +#ifdef CONFIG_PROC_FS + pProcFile = create_proc_entry(dev->name, + S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, + pSkRootDir); + pProcFile->read_proc = sk_proc_read; + pProcFile->write_proc = NULL; + pProcFile->nlink = 1; + pProcFile->size = sizeof(dev->name + 1); + pProcFile->data = (void *)pProcFile; + pProcFile->owner = THIS_MODULE; #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"); } - /* - * If we're at this point we're going through skge_probe() for - * the first time. Return success (0) if we've initialized 1 - * or more boards. Otherwise, return failure (-ENODEV). - */ + pAC->Index = sk98lin_boards_found; + sk98lin_max_boards_found = sk98lin_boards_found; + return 0; +} - return boards_found; -} /* skge_probe */ /***************************************************************************** @@ -566,7 +616,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; } @@ -603,6 +653,306 @@ 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; + + if (CHIP_ID_YUKON_2(pAC)) { + +#define TXPORT pAC->TxPort[pNet->PortNr][TX_PRIO_LOW] +#define RXPORT pAC->RxPort[pNet->PortNr] + + if (netif_running(pAC->dev[pNet->PortNr])) { + 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 (StartTimer == SK_TRUE) { + pNet->KernelTimer.expires = jiffies + (1*HZ)/4; /* 250ms */ + add_timer(&pNet->KernelTimer); + } +#endif + pNet->TimerExpired = SK_FALSE; + } +} +#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 */ + } + + + /* + * 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. + */ + SK_OUT16(IoC, 0x2804, 0x3832); + + + /* + * 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); + } + + SK_OUT16(IoC, 0x0f20, 0x0208); /* enable PME on magic packet */ + /* and on wake up frame */ + + /* + * 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 + /***************************************************************************** * @@ -634,7 +984,9 @@ if (pAC->IoBase) { iounmap(pAC->IoBase); } - if (pAC->pDescrMem) { + if (CHIP_ID_YUKON_2(pAC)) { + SkY2FreeResources(pAC); + } else { BoardFreeMem(pAC); } } @@ -644,28 +996,6 @@ MODULE_AUTHOR("Mirko Lindner "); 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"); -/* not used, just there because every driver should have them: */ -MODULE_PARM(options, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i"); -MODULE_PARM(debug, "i"); -/* 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 @@ -746,47 +1076,55 @@ static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", }; #endif -static int debug = 0; /* not used */ -static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */ - 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]; - -/***************************************************************************** - * - * skge_init_module - module initialization function - * - * Description: - * Very simple, only call skge_probe and return approriate result. - * - * Returns: - * 0, if everything is ok - * !=0, on error - */ -static int __init skge_init_module(void) -{ - int cards; - SkGeRootDev = NULL; - - /* just to avoid warnings ... */ - debug = 0; - options[0] = 0; +static char *LowLatency[SK_MAX_CARD_PARAM]; - cards = skge_probe(); - if (cards == 0) { - printk("sk98lin: No adapter found.\n"); - } - return cards ? 0 : -ENODEV; -} /* skge_init_module */ +#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 /***************************************************************************** * - * skge_cleanup_module - module unload function + * sk98lin_remove_device - device deinit function * * Description: * Disable adapter if it is still running, free resources, @@ -794,73 +1132,83 @@ * * Returns: N/A */ -static void __exit skge_cleanup_module(void) + +static void sk98lin_remove_device(struct pci_dev *pdev) { DEV_NET *pNet; SK_AC *pAC; struct SK_NET_DEVICE *next; unsigned long Flags; -SK_EVPARA EvPara; +struct net_device *dev = pci_get_drvdata(pdev); - while (SkGeRootDev) { - pNet = (DEV_NET*) SkGeRootDev->priv; - pAC = pNet->pAC; - next = pAC->Next; - netif_stop_queue(SkGeRootDev); - SkGeYellowLED(pAC, pAC->IoBase, 0); + /* Device not available. Return. */ + if (!dev) + return; - if(pAC->BoardLevel == SK_INIT_RUN) { - /* 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; - } - - if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){ - unregister_netdev(pAC->dev[1]); - kfree(pAC->dev[1]); - } + pNet = (DEV_NET*) dev->priv; + pAC = pNet->pAC; + next = pAC->Next; - FreeResources(SkGeRootDev); + netif_stop_queue(dev); + SkGeYellowLED(pAC, pAC->IoBase, 0); - SkGeRootDev->get_stats = NULL; - /* - * otherwise unregister_netdev calls get_stats with - * invalid IO ... :-( - */ - unregister_netdev(SkGeRootDev); - kfree(SkGeRootDev); - kfree(pAC); - SkGeRootDev = next; + 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]); + kfree(pAC->dev[1]); } + FreeResources(dev); + #ifdef CONFIG_PROC_FS - /* clear proc-dir */ - remove_proc_entry(pSkRootDir->name, proc_net); + /* 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 -} /* skge_cleanup_module */ + dev->get_stats = NULL; + /* + * otherwise unregister_netdev calls get_stats with + * invalid IO ... :-( + */ + unregister_netdev(dev); + kfree(dev); + kfree(pAC); + sk98lin_max_boards_found--; -module_init(skge_init_module); -module_exit(skge_cleanup_module); +#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 + +} /***************************************************************************** @@ -899,7 +1247,9 @@ spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock); spin_lock_init(&pAC->RxPort[i].RxDesRingLock); } + spin_lock_init(&pAC->SlowPathLock); + spin_lock_init(&pAC->SetPutIndexLock); /* for Yukon2 chipsets */ /* level 0 init common modules here */ @@ -923,10 +1273,7 @@ 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); @@ -938,52 +1285,103 @@ 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.GIPortUsage = 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 | SA_NET_RANDOM, pAC->Name, dev); - } else if (pAC->GIni.GIMacsFound == 1) { - Ret = request_irq(dev->irq, SkGeIsrOnePort, - SA_SHIRQ | SA_NET_RANDOM, 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)) { +#ifdef CONFIG_SK98LIN_NAPI + dev->poll = &SkGePoll; + dev->weight = 64; +#endif + if (pAC->GIni.GIMacsFound == 2) { + Ret = request_irq(dev->irq, SkGeIsr, + SA_SHIRQ | SA_NET_RANDOM, dev->name, dev); + } else if (pAC->GIni.GIMacsFound == 1) { + Ret = request_irq(dev->irq, SkGeIsrOnePort, + SA_SHIRQ | SA_NET_RANDOM, 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 | SA_NET_RANDOM, dev->name, dev); +#ifdef CONFIG_SK98LIN_NAPI + dev->poll = &SkY2Poll; + dev->weight = 64; +#endif } 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; @@ -995,7 +1393,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); } @@ -1095,16 +1498,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 */ @@ -1113,7 +1520,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 @@ -1128,34 +1535,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; iGIni.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; iGIni.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 @@ -1175,6 +1585,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 */ @@ -1217,11 +1628,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 */ @@ -1297,6 +1709,24 @@ return; } +#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) { @@ -1310,6 +1740,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) { @@ -1317,6 +1748,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 */ @@ -1324,6 +1756,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]); @@ -1333,6 +1766,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]); @@ -1343,38 +1777,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) { @@ -1388,18 +1812,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; @@ -1446,6 +1864,21 @@ return; } +#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) { @@ -1459,6 +1892,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 */ @@ -1466,6 +1900,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]); @@ -1476,24 +1911,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) { @@ -1507,17 +1936,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); @@ -1525,7 +1947,6 @@ return; } /* SkGeIsrOnePort */ - /**************************************************************************** * * SkGeOpen - handle start of initialized adapter @@ -1543,27 +1964,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 /* Set blink mode */ @@ -1583,6 +1998,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) { @@ -1598,20 +2018,61 @@ SkRlmtInit (pAC, pAC->IoBase, SK_INIT_RUN); SkTimerInit (pAC, pAC->IoBase, SK_INIT_RUN); pAC->BoardLevel = SK_INIT_RUN; + +#ifdef SK_YUKON2 +#if 0 + for (CurrMac=0; CurrMacGIni.GIMacsFound; CurrMac++) { + if (CHIP_ID_YUKON_2(pAC)) { + if (pPrt->PState >= SK_PRT_INIT) { + SkY2PortStart(pAC, pAC->IoBase, CurrMac); + } + } else { + /* Enable transmit descriptor polling. */ + SkGePollTxD(pAC, pAC->IoBase, CurrMac, SK_TRUE); + FillRxRing(pAC, &pAC->RxPort[CurrMac]); + SkMacRxTxEnable(pAC, pAC->IoBase, pNet->PortNr); + } + } +#endif +#endif + } - for (i=0; iGIni.GIMacsFound; i++) { - /* Enable transmit descriptor polling. */ - SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE); - FillRxRing(pAC, &pAC->RxPort[i]); + for (CurrMac=0; CurrMacGIni.GIMacsFound; CurrMac++) { +#ifdef SK_YUKON2 +#if 0 + if (CHIP_ID_YUKON_2(pAC)) { + if (pAC->GIni.GP[CurrMac].PState < SK_PRT_INIT) { + printk("SkGeOpen: will start port %i\n", CurrMac); + SkY2PortStart(pAC, pAC->IoBase, CurrMac); + } else { + printk("SkGeOpen: Port %i already started->skipped!\n", CurrMac); + } + } else { +#endif +#endif + 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; + 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 + } /* enable Interrupts */ SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); @@ -1620,25 +2081,27 @@ 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 + /* Initialize the kernel timer */ + init_timer(&pNet->KernelTimer); + pNet->KernelTimer.function = SkGeHandleKernelTimer; + pNet->KernelTimer.data = (unsigned long) pNet; + pNet->KernelTimer.expires = jiffies + (1*HZ)/4; /* initially 250ms */ + pNet->TimerExpired = SK_FALSE; + add_timer(&pNet->KernelTimer); +#endif + pAC->MaxPorts++; MOD_INC_USE_COUNT; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, @@ -1660,24 +2123,25 @@ * 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 + del_timer(&pNet->KernelTimer); +#endif -#ifdef SK_DIAG_SUPPORT if (pAC->DiagModeActive == DIAG_ACTIVE) { if (pAC->DiagFlowCtrl == SK_FALSE) { MOD_DEC_USE_COUNT; @@ -1697,7 +2161,6 @@ pAC->DiagFlowCtrl = SK_FALSE; } } -#endif netif_stop_queue(dev); @@ -1706,8 +2169,6 @@ else PortIdx = pNet->NetNr; - StopDrvCleanupTimer(pAC); - /* * Clear multicast table, promiscuous mode .... */ @@ -1719,46 +2180,77 @@ 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; + /* SkGeDeInit(pAC, pAC->IoBase); */ + /* pAC->BoardLevel = SK_INIT_DATA; */ + if (CHIP_ID_YUKON_2(pAC)) { + SkY2PortStop(pAC, pAC->IoBase, 0, SK_STOP_ALL, SK_HARD_RST); + } + else { + SkGeStopPort(pAC, pAC->IoBase, 0, 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; iGIni.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; CurrMacGIni.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 */ - ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE); - ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]); - ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]); + 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); + } } SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, @@ -1769,8 +2261,6 @@ sizeof(SK_PNMI_STRUCT_DATA)); pAC->MaxPorts--; - pNet->Up = 0; - MOD_DEC_USE_COUNT; return (0); } /* SkGeClose */ @@ -1829,9 +2319,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. @@ -1843,6 +2335,53 @@ 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); + } +#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); + + *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 /***************************************************************************** * @@ -1867,7 +2406,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 */ { @@ -1883,11 +2422,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); @@ -1915,6 +2457,7 @@ */ if (BytesSend < C_LEN_ETHERNET_MINSIZE) { if ((pMessage = skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) == NULL) { + spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); return 0; } pMessage->len = C_LEN_ETHERNET_MINSIZE; @@ -1972,7 +2515,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 @@ -2392,33 +2935,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 */ @@ -2440,6 +2990,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 */ @@ -2448,7 +3005,6 @@ FillRxRing(pAC, pRxPort); return; } - pAC->DynIrqModInfo.NbrProcessedDescr++; /* get length of frame and check it */ FrameLength = Control & BMU_BBC; @@ -2467,8 +3023,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, @@ -2478,8 +3034,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, @@ -2524,10 +3079,18 @@ 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); @@ -2547,11 +3110,18 @@ 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 + eth_copy_and_sum(pNewMsg, pMsg->data, FrameLength, 0); ReQueueRxBuffer(pAC, pRxPort, pMsg, @@ -2559,13 +3129,11 @@ 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; @@ -2574,119 +3142,75 @@ PhysAddr, pAC->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) { @@ -2714,32 +3238,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: @@ -2763,49 +3277,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 @@ -3013,12 +3484,15 @@ */ 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; +struct net_device *otherdev; +SK_AC *pAC; +unsigned long Flags; +int i; +#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")); @@ -3034,7 +3508,6 @@ return -EINVAL; } -#ifdef SK_DIAG_SUPPORT if (pAC->DiagModeActive == DIAG_ACTIVE) { if (pAC->DiagFlowCtrl == SK_FALSE) { return -1; /* still in use, deny any actions of MTU */ @@ -3042,15 +3515,16 @@ 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); - } + otherdev = pAC->dev[1 - pNet->NetNr]; + if (NewMtu <= 1500 && otherdev != dev + && netif_running(otherdev) && otherdev->mtu > 1500) + return 0; pAC->RxBufSize = NewMtu + 32; + while (pAC->RxBufSize % 8) { /* RxBufSize must be a multiple of 8 */ + pAC->RxBufSize = pAC->RxBufSize + 1; + } dev->mtu = NewMtu; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, @@ -3066,25 +3540,19 @@ /* ** 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); + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, + 0, -1, SK_FALSE); + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, + 1, -1, SK_TRUE); } else { - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, + 0, -1, SK_TRUE); } - /* - ** After calling the SkEventDispatcher(), RLMT is aware about - ** the stopped ports -> configuration can take place! - */ - SkEventDispatcher(pAC, pAC->IoBase); - for (i=0; iGIni.GIMacsFound; i++) { - spin_lock_irqsave( - &pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock, Flags); + spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock); netif_stop_queue(pAC->dev[i]); } @@ -3135,7 +3603,6 @@ ** enable/disable hardware support for long frames */ if (NewMtu > 1500) { -// pAC->JumboActivated = SK_TRUE; /* is never set back !!! */ pAC->GIni.GIPortUsage = SK_JUMBO_LINK; } else { if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { @@ -3152,9 +3619,8 @@ 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); @@ -3168,23 +3634,35 @@ SkTimerInit(pAC, pAC->IoBase, SK_INIT_RUN); /* - ** clear and reinit the rx rings here + ** clear and reinit the rx rings here, because of new MTU size */ for (i=0; iGIni.GIMacsFound; i++) { - ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE); - ClearRxRing(pAC, &pAC->RxPort[i]); - FillRxRing(pAC, &pAC->RxPort[i]); + if (CHIP_ID_YUKON_2(pAC)) { + SkY2FreeRxBuffers(pAC, pAC->IoBase, i); + SkY2FreeTxBuffers(pAC, pAC->IoBase, i); + SkY2AllocateRxBuffers(pAC, pAC->IoBase, i); + SkY2RestartStatusUnit(pAC); + SkY2PortStart(pAC, pAC->IoBase, i); + } else { +#ifdef CONFIG_SK98LIN_NAPI + WorkToDo = 1; + ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE, &WorkDone, WorkToDo); +#else + ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE); +#endif + ClearRxRing(pAC, &pAC->RxPort[i]); + FillRxRing(pAC, &pAC->RxPort[i]); - /* - ** Enable transmit descriptor polling - */ - SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE); - FillRxRing(pAC, &pAC->RxPort[i]); - }; + /* + ** Enable transmit descriptor polling + */ + SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE); + FillRxRing(pAC, &pAC->RxPort[i]); + } + } 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--) { @@ -3197,43 +3675,29 @@ 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); + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, + pAC->RlmtNets, -1, SK_FALSE); + if (otherdev != dev && netif_running(otherdev)) { + DEV_NET *pOtherNet = + (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv; + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, + pNet->PortNr, -1, SK_FALSE); + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, + pOtherNet->PortNr, -1, SK_TRUE); + } else { + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, + pNet->PortNr, -1, SK_TRUE); } } else { - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, + 0, -1, SK_TRUE); } - 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 0; } /* SkGeChangeMtu */ @@ -3254,42 +3718,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); } @@ -3334,32 +3794,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, @@ -3386,6 +3849,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; @@ -3404,10 +3868,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; @@ -3444,7 +3908,6 @@ fault_diag: kfree(pMemBuf); /* cleanup everything */ break; -#endif default: Err = -EOPNOTSUPP; } @@ -3476,12 +3939,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) { @@ -3524,17 +3987,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: @@ -3552,6 +4016,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 @@ -3591,7 +4064,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) ) { @@ -3617,40 +4090,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 */ } @@ -3669,14 +4142,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; + } } /* @@ -3771,9 +4260,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; } @@ -3801,7 +4287,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 { @@ -3893,7 +4379,7 @@ ** Decide whether to set new config value if somethig valid has ** been received. */ - if (IsLinkSpeedDefined) { + if (IsLinkSpeedDefined) { pAC->GIni.GP[1].PLinkSpeed = LinkSpeed; } @@ -3969,9 +4455,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; } @@ -4111,10 +4594,32 @@ } else { pAC->RlmtMode = 0; } - + +#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; @@ -4128,70 +4633,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)) { @@ -4200,28 +4684,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 */ @@ -4257,45 +4738,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 *********************************************/ /****************************************************************************/ @@ -4384,7 +4826,9 @@ SK_U64 SkOsGetTime(SK_AC *pAC) { SK_U64 PrivateJiffies; + SkOsGetTimeCurrent(pAC, &PrivateJiffies); + return PrivateJiffies; } /* SkOsGetTime */ @@ -4539,28 +4983,31 @@ * */ 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 */ + SK_OUT32(pAC->IoBase, B0_IMSK, 0); /* disable interrupts */ break; case SK_DRV_PORT_FAIL: FromPort = Param.Para32[0]; @@ -4571,218 +5018,285 @@ } 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[0]); + 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 ")); 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_irqsave( - &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags); - SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST); - SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST); - spin_unlock_irqrestore( - &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags); + spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); + 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_irqsave( - &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags); + spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); pAC->ActivePort = ToPort; #if 0 SetQueueSizes(pAC); @@ -4797,8 +5311,7 @@ pAC, pAC->ActivePort, DualNet)) { - spin_unlock_irqrestore( - &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags); + spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); spin_unlock_irqrestore( &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); @@ -4806,76 +5319,310 @@ 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); - spin_unlock_irqrestore( - &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags); + +#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; +#if (defined (Y2_RECOVERY) || defined (Y2_LE_CHECK)) + case SK_DRV_RECOVER: + FromPort = Param.Para32[0]; + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, + ("PORT RESET EVENT, Port: %d ", FromPort)); + 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); + +#ifdef Y2_RECOVERY + /* restart the kernel timer */ + pNet = (DEV_NET *) pAC->dev[FromPort]->priv; + if (!timer_pending(&pNet->KernelTimer)) { + pNet->KernelTimer.expires = + jiffies + (1*HZ)/4; /* 250ms */ + add_timer(&pNet->KernelTimer); + } +#endif + 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 @@ -4925,8 +5672,6 @@ } /* SkErrorLog */ -#ifdef SK_DIAG_SUPPORT - /***************************************************************************** * * SkDrvEnterDiagMode - handles DIAG attach request @@ -4952,7 +5697,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; @@ -4960,9 +5705,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; @@ -4994,16 +5740,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); } @@ -5146,14 +5892,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 @@ -5164,9 +5921,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"); @@ -5178,19 +5937,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 @@ -5202,23 +5956,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]; @@ -5244,27 +5997,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]; @@ -5303,3 +6053,4 @@ * End of file * ******************************************************************************/ + diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skgehwt.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skgehwt.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skgehwt.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skgehwt.c Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skgehwt.c * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 2.2 $ + * Date: $Date: 2004/05/28 13:39:04 $ * Purpose: Hardware Timer * ******************************************************************************/ @@ -9,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 @@ -25,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 */ @@ -42,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. @@ -71,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; } @@ -107,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. * @@ -127,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) { @@ -137,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; } } @@ -160,9 +156,9 @@ SK_IOC Ioc) /* IoContext */ { SkHwtStop(pAC, Ioc); - + pAC->Hwt.TStop = pAC->Hwt.TStart; - + SkTimerDone(pAC, Ioc); } diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skgeinit.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skgeinit.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skgeinit.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skgeinit.c Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skgeinit.c * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.68 $ + * Date: $Date: 2005/01/10 17:01:45 $ * Purpose: Contains functions to initialize the adapter * ******************************************************************************/ @@ -9,18 +11,16 @@ /****************************************************************************** * * (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. * ******************************************************************************/ - #include "h/skdrv1st.h" #include "h/skdrv2nd.h" @@ -30,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.68 2005/01/10 17:01:45 rschmidt Exp $ (C) Marvell."; #endif struct s_QOffTab { @@ -58,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: @@ -70,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.) */ { @@ -79,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 */ @@ -98,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.) */ { @@ -113,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); } @@ -134,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 */ @@ -168,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 */ { @@ -196,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 */ @@ -226,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 */ @@ -263,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 @@ -281,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 */ + + UsedKilobytes = 0; - /* Set standby queue size defaults for all standby ports */ + /* 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 @@ -387,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 @@ -403,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; @@ -413,44 +580,51 @@ 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->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); @@ -460,8 +634,13 @@ /* 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); @@ -501,8 +680,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); @@ -541,8 +720,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); @@ -581,14 +760,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 @@ -596,31 +772,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 */ + + /* enable frame flushing if jumbo frames used */ if (pAC->GIni.GIPortUsage == 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 */ @@ -628,23 +802,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); */ } @@ -652,7 +855,7 @@ } /* SkGeInitMacFifo */ -#ifdef SK_LNK_SYNC_CNT +#ifdef SK_LNK_SYNC_CNT /****************************************************************************** * * SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting @@ -673,8 +876,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 */ { @@ -684,7 +887,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: @@ -697,6 +900,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) { @@ -709,6 +913,7 @@ IrqPend = SK_TRUE; } } + if (!IrqPend) { SK_OUT32(IoC, B0_IMSK, NewIMsk); } @@ -717,15 +922,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) /****************************************************************************** @@ -757,8 +964,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 */ @@ -776,16 +983,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); @@ -803,13 +1010,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); } @@ -830,10 +1037,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) */ @@ -866,8 +1073,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); @@ -910,8 +1116,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; @@ -919,7 +1125,7 @@ pPrt = &pAC->GIni.GP[Port]; - if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) { + if (pPrt->PRxQSize <= SK_MIN_RXQ_SIZE) { RxQType = SK_RX_SRAM_Q; /* small Rx Queue */ } else { @@ -928,10 +1134,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); @@ -952,26 +1158,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 */ @@ -986,8 +1203,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; @@ -998,29 +1215,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 @@ -1044,20 +1295,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 */ @@ -1141,56 +1401,83 @@ * 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 id */ + 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 */ /* * 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); + SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CsrStop); + SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CsrStop); 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)); - XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff); + /* + * 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); + } +#endif /* GENESIS */ + 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. @@ -1198,18 +1485,12 @@ */ 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 + * we have a stable state and can reset the + * BMU, Pref 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 @@ -1217,48 +1498,96 @@ */ 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)); - /* Reset the MAC depending on the RstMode */ - if (RstMode == SK_SOFT_RST) { - SkMacSoftRst(pAC, IoC, Port); + if (pAC->GIni.GIAsfEnabled) { + + 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) { @@ -1270,71 +1599,113 @@ SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS); } #endif /* GENESIS */ - + #ifdef YUKON - if (pAC->GIni.GIYukon) { - /* Reset TX MAC FIFO */ + if (pAC->GIni.GIYukon && !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 prefetch unit ! */ - } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE); + SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, 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); } @@ -1354,8 +1725,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; @@ -1392,24 +1763,31 @@ 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 @@ -1425,8 +1803,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; @@ -1449,7 +1827,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); } @@ -1459,7 +1837,7 @@ /* Check for D0 state. */ SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); - + if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D0) { return(1); } @@ -1468,11 +1846,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); } @@ -1483,9 +1874,76 @@ 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 { + pAC->GIni.HwF.Features[HW_DEV_LIST] = + HWF_WA_DEV_427 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 | + HWF_WA_DEV_4115; + } + 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 @@ -1508,73 +1966,223 @@ * 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++; + } + } + + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) { +#ifdef XXX + if (pAC->GIni.GIPciBus != SK_PEX_BUS) { + /* enable Core Clock Division */ + SK_OUT32(IoC, B2_Y2_CLK_CTRL, Y2_CLK_DIV_VAL_2(0) | + Y2_CLK_DIV_ENA); + } +#endif /* XXX */ +#ifdef VCPU + /* 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) { @@ -1590,57 +2198,60 @@ 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); + } } } @@ -1648,70 +2259,129 @@ 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; + 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); } } - - 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); - /* clear GMAC Link Control reset */ - SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR); + 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 { + /* all Yukon-2 adapters work with 156 MHz host clock */ + pAC->GIni.GIHstClkFact = 2 * SK_FACT_78; + } + + 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); + + /* turn on Core Clock */ + SK_OUT8(IoC, B2_Y2_CLK_GATE, 0); } - /* all YU chips work with 78.125 MHz host clock */ - pAC->GIni.GIHstClkFact = SK_FACT_78; - - pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */ + 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; + } + +#ifdef SK_PHY_LP_MODE_DEEP_SLEEP + + 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); +#endif } #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 != '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: @@ -1721,65 +2391,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 != '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) { @@ -1792,7 +2495,9 @@ #endif } #endif /* YUKON */ - + + SkGeSetUpSupFeatures(pAC, IoC); + return(RetVal); } /* SkGeInit1 */ @@ -1813,9 +2518,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 */ @@ -1849,13 +2557,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++) { @@ -1865,8 +2573,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. @@ -1888,7 +2622,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 * @@ -1897,14 +2631,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; @@ -1919,7 +2653,7 @@ SkGeInit0(pAC, IoC); pAC->GIni.GILevel = SK_INIT_DATA; break; - + case SK_INIT_IO: /* Initialization Level 1 */ RetVal = SkGeInit1(pAC, IoC); @@ -1931,22 +2665,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) { @@ -1956,12 +2692,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; @@ -1984,77 +2721,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) { +#ifndef SK_DIAG + 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 /* SK_DIAG */ + + 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 + ) { /* 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 */ @@ -2088,8 +2827,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; @@ -2100,8 +2839,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); } @@ -2118,29 +2857,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 */ @@ -2148,3 +2887,4 @@ return(0); } /* SkGeInitPort */ + diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skgemib.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skgemib.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skgemib.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skgemib.c Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skgemib.c * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 2.7 $ + * Date: $Date: 2004/10/26 12:42:18 $ * Purpose: Private Network Management Interface Management Database * ****************************************************************************/ @@ -249,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, @@ -1067,6 +1246,11 @@ 0, SK_PNMI_WO, Vct, 0}, {OID_SKGE_VCT_STATUS, + 0, + 0, + 0, + SK_PNMI_RO, Vct, 0}, + {OID_SKGE_VCT_CAPABILITIES, 0, 0, 0, diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skgepnmi.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skgepnmi.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skgepnmi.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skgepnmi.c Sun Feb 6 22:21:26 2005 @@ -1,7 +1,9 @@ /***************************************************************************** * * Name: skgepnmi.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Project: Gigabit Ethernet Adapters, PNMI-Module + * Version: $Revision: 2.19 $ + * Date: $Date: 2004/10/29 09:09:43 $ * Purpose: Private Network Management Interface * ****************************************************************************/ @@ -20,10 +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.19 2004/10/29 09:09:43 tschilli Exp $ (C) Marvell."; +#endif #include "h/skdrv1st.h" #include "h/sktypes.h" @@ -35,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 @@ -69,7 +73,6 @@ int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf, unsigned int * pLen, SK_U32 NetIndex); - /* * Private Function prototypes */ @@ -109,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 @@ -350,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)); @@ -369,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; @@ -405,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; @@ -462,53 +460,27 @@ 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 : @@ -517,11 +489,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; @@ -549,17 +524,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); @@ -639,7 +614,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)); } @@ -721,7 +695,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)); @@ -730,22 +703,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)) != @@ -770,15 +740,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) { @@ -792,13 +759,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) * @@ -995,7 +962,6 @@ unsigned int PhysPortIndex; unsigned int MaxNetNumber; int CounterIndex; - int Ret; SK_U16 MacStatus; SK_U64 OverflowStatus; SK_U64 Mask; @@ -1009,12 +975,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) { @@ -1045,9 +1006,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)) { @@ -1065,7 +1024,6 @@ Mask = (SK_U64)1 << CounterIndex; if ((OverflowStatus & Mask) == 0) { - continue; } @@ -1097,9 +1055,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; @@ -1186,7 +1142,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); } @@ -1205,16 +1161,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; @@ -1237,7 +1191,7 @@ Delta = NewestValue - OldestValue; } else { - /* Overflow situation */ + /* Overflow situation. */ Delta = (SK_U64)(0 - OldestValue) + NewestValue; } @@ -1263,8 +1217,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; @@ -1308,29 +1263,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; } @@ -1363,14 +1314,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; } @@ -1400,7 +1352,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, @@ -1432,17 +1384,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); @@ -1473,7 +1421,6 @@ CounterIndex ++) { if (!StatAddr[CounterIndex][MacType].GetOffset) { - continue; } @@ -1482,9 +1429,7 @@ pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value; } - /* - * Set port to inactive - */ + /* Set port to inactive. */ pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE; pAC->Pnmi.MacUpdatedFlag --; @@ -1510,25 +1455,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)); @@ -1562,7 +1501,6 @@ CounterIndex ++) { if (!StatAddr[CounterIndex][MacType].GetOffset) { - continue; } @@ -1571,16 +1509,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 @@ -1595,71 +1531,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; @@ -1707,14 +1625,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); } @@ -1764,22 +1681,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); } @@ -1807,12 +1722,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; } @@ -1823,8 +1737,7 @@ InstanceCnt ++) { DstOffset = IdTable[TableIndex].Offset + - (InstanceCnt - 1) * - IdTable[TableIndex].StructSize; + (InstanceCnt - 1) * IdTable[TableIndex].StructSize; /* * Because VPD multiple instance variables are @@ -1834,9 +1747,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, @@ -1852,8 +1763,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); } @@ -1875,7 +1785,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); @@ -1886,8 +1796,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); } @@ -1921,7 +1830,7 @@ if (IdTable[i].Id == Id) { - return i; + return (i); } } @@ -1962,16 +1871,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; @@ -2030,10 +1936,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; @@ -2046,10 +1949,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); @@ -2057,13 +1960,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 && @@ -2075,7 +1978,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); @@ -2084,19 +1987,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); } @@ -2113,13 +2012,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); } @@ -2163,25 +2061,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: @@ -2202,12 +2096,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); } @@ -2223,16 +2117,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: @@ -2248,7 +2140,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); @@ -2302,21 +2194,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; @@ -2326,20 +2216,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); @@ -2358,7 +2248,7 @@ } pAC->Pnmi.MacUpdatedFlag ++; - /* Get value */ + /* Get value. */ Offset = 0; for (; LogPortIndex < Limit; LogPortIndex ++) { @@ -2464,19 +2354,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; @@ -2485,27 +2372,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) { @@ -2529,8 +2412,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); @@ -2539,8 +2421,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); @@ -2551,8 +2432,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) { @@ -2560,19 +2441,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; @@ -2584,32 +2462,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), @@ -2662,10 +2534,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)) { @@ -2681,25 +2550,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) { @@ -2725,8 +2590,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); @@ -2736,9 +2600,7 @@ Offset += sizeof(SK_U64); } - /* - * Store used buffer space - */ + /* Store used buffer space. */ *pLen = Offset; return (SK_PNMI_ERR_OK); @@ -2781,10 +2643,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)) { @@ -2801,16 +2660,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: @@ -2869,38 +2726,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: @@ -2937,9 +2789,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: @@ -2976,9 +2827,7 @@ } } - /* - * Store used buffer space - */ + /* Store used buffer space. */ *pLen = Offset; return (SK_PNMI_ERR_OK); @@ -3032,9 +2881,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; @@ -3079,21 +2926,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) { @@ -3118,7 +2963,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; @@ -3129,7 +2974,7 @@ return (SK_PNMI_ERR_TOO_SHORT); } - /* Get value */ + /* Get value. */ *(pBuf) = (char)Len - 1; for (Offset = 1, Index = 0; Index < KeyNo; Index ++) { @@ -3148,7 +2993,7 @@ break; case OID_SKGE_VPD_ENTRIES_NUMBER: - /* Check length */ + /* Check length. */ if (*pLen < sizeof(SK_U32)) { *pLen = sizeof(SK_U32); @@ -3161,7 +3006,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 ++) { @@ -3177,31 +3022,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); @@ -3218,16 +3059,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; @@ -3248,8 +3087,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])) { @@ -3275,15 +3113,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 || @@ -3297,8 +3134,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); @@ -3314,14 +3150,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: @@ -3353,13 +3186,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 ) { @@ -3391,7 +3224,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; @@ -3406,7 +3239,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) { @@ -3414,6 +3247,7 @@ break; } } + /* * If we cannot find the key it is wrong, so we * return an appropriate error value. @@ -3429,7 +3263,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) { @@ -3502,23 +3336,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; @@ -3527,9 +3359,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: @@ -3543,14 +3373,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); } @@ -3621,11 +3449,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 || @@ -3633,7 +3461,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. */ @@ -3664,11 +3493,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: @@ -3682,9 +3526,7 @@ } } - /* - * Retrieve value - */ + /* Retrieve value. */ switch (Id) { case OID_SKGE_SUPPORTED_LIST: @@ -3694,11 +3536,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; @@ -3724,8 +3566,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); @@ -3734,8 +3575,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); @@ -3754,8 +3594,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); @@ -3764,8 +3603,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); @@ -3784,8 +3622,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); @@ -3794,8 +3631,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); @@ -3814,8 +3650,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); @@ -3824,8 +3659,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); @@ -3851,8 +3685,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); @@ -3860,8 +3693,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); @@ -3877,7 +3709,6 @@ break; case OID_SKGE_HW_VERSION: - /* Oh, I love to do some string manipulation */ if (*pLen < 5) { *pLen = 5; @@ -3886,9 +3717,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; @@ -3911,12 +3742,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; @@ -3965,31 +3796,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; @@ -4001,24 +3832,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; @@ -4029,24 +3860,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; @@ -4057,24 +3888,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; @@ -4085,24 +3916,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; @@ -4113,24 +3944,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; @@ -4141,24 +3972,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; @@ -4169,24 +4000,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; @@ -4197,24 +4028,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; @@ -4225,24 +4056,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; @@ -4263,13 +4094,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 + @@ -4277,11 +4108,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 + @@ -4293,13 +4124,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 + @@ -4307,11 +4138,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 + @@ -4323,24 +4154,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; @@ -4364,7 +4195,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; } @@ -4373,7 +4204,7 @@ } /* - * by default 32bit values are evaluated + * By default 32bit values are evaluated. */ if (!Is64BitReq) { Val32 = (SK_U32)Val64; @@ -4387,7 +4218,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; } @@ -4396,7 +4227,7 @@ } /* - * by default 32bit values are evaluated + * By default 32bit values are evaluated. */ if (!Is64BitReq) { Val32 = (SK_U32)Val64; @@ -4410,16 +4241,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; @@ -4439,8 +4273,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); @@ -4497,25 +4330,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: @@ -4548,8 +4373,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); @@ -4568,9 +4392,7 @@ } pAC->Pnmi.RlmtUpdatedFlag ++; - /* - * Retrieve Value - */ + /* Retrieve value. */ switch (Id) { case OID_SKGE_RLMT_MODE: @@ -4648,17 +4470,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) { @@ -4666,21 +4488,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); @@ -4688,20 +4510,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; @@ -4714,13 +4541,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); @@ -4728,22 +4555,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; @@ -4758,7 +4583,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); } @@ -4803,54 +4628,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: @@ -4874,8 +4694,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); @@ -4893,9 +4712,7 @@ } pAC->Pnmi.RlmtUpdatedFlag ++; - /* - * Get value - */ + /* Get value. */ Offset = 0; for (; PhysPortIndex < Limit; PhysPortIndex ++) { @@ -5008,19 +4825,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; @@ -5030,18 +4849,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: @@ -5079,8 +4896,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); } @@ -5096,9 +4912,7 @@ } pAC->Pnmi.SirqUpdatedFlag ++; - /* - * Get value - */ + /* Get value. */ Offset = 0; for (; LogPortIndex < Limit; LogPortIndex ++) { @@ -5108,107 +4922,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); @@ -5216,147 +5022,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); @@ -5367,70 +5173,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: @@ -5483,40 +5289,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 || @@ -5527,51 +5326,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) { @@ -5584,15 +5400,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 || @@ -5603,30 +5417,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, @@ -5641,17 +5473,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, @@ -5661,15 +5492,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 || @@ -5680,34 +5510,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, @@ -5718,16 +5565,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, @@ -5737,16 +5584,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) || @@ -5757,29 +5601,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, @@ -5794,16 +5658,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, @@ -5814,23 +5677,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); } @@ -5841,116 +5706,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, @@ -6000,14 +5818,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)) { @@ -6024,12 +5839,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) { @@ -6051,32 +5864,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); } @@ -6117,14 +5927,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; } @@ -6133,12 +5941,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: @@ -6152,7 +5961,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; @@ -6160,9 +5969,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) { @@ -6171,10 +5979,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; @@ -6182,10 +5990,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) { @@ -6194,10 +6000,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; @@ -6205,10 +6011,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) { @@ -6217,7 +6021,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; @@ -6232,7 +6036,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; @@ -6240,9 +6044,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) { @@ -6251,7 +6054,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; @@ -6259,10 +6062,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) { @@ -6271,7 +6072,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; @@ -6286,7 +6087,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; @@ -6294,9 +6095,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) { @@ -6305,7 +6105,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; @@ -6313,10 +6113,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) { @@ -6325,7 +6123,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; @@ -6333,9 +6131,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) { @@ -6344,7 +6141,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; @@ -6352,10 +6149,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) { @@ -6365,9 +6160,7 @@ } } - /* - * If no port is active return an indeterminated answer - */ + /* If no port is active return an indeterminated answer. */ if (!PortActiveFlag) { switch (Id) { @@ -6484,16 +6277,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 @@ -6538,22 +6330,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); @@ -6561,12 +6350,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; } @@ -6579,14 +6367,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); } @@ -6597,7 +6383,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, @@ -6626,19 +6412,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); } @@ -6666,21 +6451,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); } @@ -6718,20 +6501,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); @@ -6769,19 +6552,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 ++) { @@ -6791,11 +6574,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); @@ -6841,7 +6624,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]; } @@ -6909,7 +6692,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); } @@ -6921,7 +6704,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; } @@ -6938,7 +6721,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); } @@ -6950,7 +6733,7 @@ break; case SK_PNMI_HTX_DEFFERAL: - /* Not supported by GMAC */ + /* Not supported by GMAC. */ if (MacType == SK_MAC_GMAC) { return (Val); } @@ -6968,7 +6751,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); @@ -6977,7 +6760,7 @@ break; case SK_PNMI_HRX_BADOCTET: - /* Not supported by XMAC */ + /* Not supported by XMAC. */ if (MacType == SK_MAC_XMAC) { return (Val); } @@ -6996,7 +6779,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); } @@ -7016,7 +6799,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 { @@ -7034,20 +6817,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); @@ -7070,7 +6852,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); } @@ -7082,7 +6864,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); } @@ -7093,13 +6875,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); @@ -7107,17 +6889,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, @@ -7137,7 +6921,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); @@ -7162,22 +6946,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; @@ -7185,7 +6968,7 @@ EventParam); #endif /* SK_USE_CSUM */ - /* Clear XMAC statistic */ + /* Clear XMAC statistics. */ for (PhysPortIndex = 0; PhysPortIndex < (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) { @@ -7212,13 +6995,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; @@ -7255,23 +7038,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; @@ -7286,7 +7067,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) { @@ -7325,13 +7106,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) ++; @@ -7366,7 +7147,6 @@ unsigned int Len; unsigned int DstOff = 0; - while (Trap != End) { Len = (unsigned int)*(pBuf + Trap); @@ -7411,7 +7191,6 @@ unsigned int Entries = 0; unsigned int TotalLen = 0; - while (Trap != End) { Len = (unsigned int)*(pBuf + Trap); @@ -7468,14 +7247,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; @@ -7520,7 +7299,6 @@ char *pBuf; SK_U32 Val32; - pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT, SK_PNMI_TRAP_RLMT_CHANGE_LEN); @@ -7548,7 +7326,6 @@ char *pBuf; SK_U32 Val32; - pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN); Val32 = OID_SKGE_RLMT_PORT_INDEX; @@ -7568,12 +7345,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]; @@ -7613,17 +7389,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: @@ -7661,14 +7434,10 @@ break; } - /* - * Perform action - */ + /* Perform action. */ if (Action == SK_PNMI_GET) { - /* - * Get value - */ + /* Get value. */ switch (Id) { case OID_PNP_CAPABILITIES: @@ -7676,18 +7445,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. */ - *pLen = sizeof(SK_DEVICE_POWER_STATE);; + /* + * 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: @@ -7708,13 +7480,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); } @@ -7746,7 +7516,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. @@ -7773,22 +7543,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: @@ -7806,10 +7571,9 @@ } /* Perform action. */ - - /* GET value. */ if (Action == SK_PNMI_GET) { + /* Get value. */ switch (Id) { case OID_SKGE_DIAG_MODE: @@ -7824,14 +7588,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. */ @@ -7843,7 +7608,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); @@ -7878,7 +7643,7 @@ /* If DiagMode is not active, we can enter it. */ if (!pAC->DiagModeActive) { - RetCode = SkDrvEnterDiagMode(pAC); + RetCode = SkDrvEnterDiagMode(pAC); } else { @@ -7897,7 +7662,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); @@ -7943,7 +7708,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. @@ -7979,15 +7744,13 @@ 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); @@ -7997,7 +7760,11 @@ } if ((Instance != (SK_U32) (-1))) { - /* Check instance range. */ + /* + * 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 ((Instance < 2) || (Instance > LogPortMax)) { *pLen = 0; return (SK_PNMI_ERR_UNKNOWN_INST); @@ -8013,34 +7780,26 @@ } 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) && + (pPrt->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: @@ -8051,6 +7810,7 @@ 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); @@ -8062,70 +7822,73 @@ return (SK_PNMI_ERR_GENERAL); } - /* Get value */ + /* Get value. */ Offset = 0; for (; PhysPortIndex < Limit; PhysPortIndex++) { + 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); @@ -8141,7 +7904,7 @@ * buffer length is plausible. */ - /* Check length */ + /* Check length. */ switch (Id) { case OID_SKGE_VCT_SET: if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) { @@ -8155,36 +7918,39 @@ 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; + 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)); + /* 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; } @@ -8212,6 +7978,78 @@ } /* 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; + } + +#if 0 + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) { + CableLength = pAC->Pnmi.VctBackup[Port].MdiPairLen[0]; + pAC->Pnmi.VctBackup[Port].MdiPairLen[0] = + pAC->Pnmi.VctBackup[Port].MdiPairLen[1]; + pAC->Pnmi.VctBackup[Port].MdiPairLen[1] = CableLength; + PairSts = pAC->Pnmi.VctBackup[Port].MdiPairSts[0]; + pAC->Pnmi.VctBackup[Port].MdiPairSts[0] = + pAC->Pnmi.VctBackup[Port].MdiPairSts[1]; + pAC->Pnmi.VctBackup[Port].MdiPairSts[1] = PairSts; + } +#endif /* 0 */ + + 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, @@ -8221,6 +8059,7 @@ { SK_GEPORT *pPrt; SK_PNMI_VCT *pVctData; + SK_U8 VctStatus; SK_U32 RetCode; pPrt = &pAC->GIni.GP[PhysPortIndex]; @@ -8228,11 +8067,13 @@ 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 { @@ -8242,11 +8083,12 @@ /* 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; } } @@ -8256,16 +8098,14 @@ } } 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; } } @@ -8311,29 +8151,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); @@ -8354,3 +8194,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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skgesirq.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skgesirq.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skgesirq.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skgesirq.c Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skgesirq.c * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.17 $ + * Date: $Date: 2004/07/02 15:24:06 $ * Purpose: Special IRQ module * ******************************************************************************/ @@ -9,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 +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. * @@ -44,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 */ @@ -56,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.17 2004/07/02 15:24:06 rschmidt Exp $ (C) Marvell."; +#endif + /* local function prototypes */ #ifdef GENESIS static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL); @@ -107,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 */ @@ -143,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 */ @@ -153,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 */ @@ -177,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 */ { @@ -188,7 +191,7 @@ pPrt->PAutoNegTimeOut = 0; - if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { + if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { return; } @@ -212,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 */ @@ -225,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; } @@ -240,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 */ @@ -264,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 */ @@ -279,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 */ @@ -306,14 +309,14 @@ 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 */ @@ -327,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 */ @@ -353,7 +358,7 @@ pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE)); } #endif /* YUKON */ - + if (pPrt->PCheckPar) { if (Port == MAC_1) { @@ -364,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); @@ -376,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 */ @@ -397,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; @@ -421,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; @@ -482,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); @@ -510,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); } @@ -522,24 +531,244 @@ 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) */ +{ + int Queue; + SK_EVPARA Para; + 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; + 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); + } + + if ((HwStatus & Y2_IS_PCI_EXP) != 0) { + /* PCI-Express uncorrectable Error occured */ + /* + * On PCI-Express bus bridges are called root complexes. + * 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. + */ + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E026, SKERR_SIRQ_E026MSG); + + /* Save uncorrectable error status */ + SK_IN32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), &DWord); + + /* 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); + + if ((DWord & PEX_FATAL_ERRORS) != 0) { + /* Stop only, if the uncorrectable error is fatal */ + 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); + } + } + + 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; @@ -551,8 +780,8 @@ 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); } /* @@ -567,7 +796,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); @@ -588,7 +817,7 @@ } if ((Istatus & IS_PA_TO_TX1) != 0) { - + pPrt = &pAC->GIni.GP[0]; /* May be a normal situation in a server with a slow network */ @@ -615,7 +844,7 @@ 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 */ @@ -624,11 +853,11 @@ (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); @@ -638,7 +867,7 @@ } if ((Istatus & IS_PA_TO_TX2) != 0) { - + pPrt = &pAC->GIni.GP[1]; /* May be a normal situation in a server with a slow network */ @@ -656,7 +885,7 @@ 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 */ @@ -665,11 +894,11 @@ (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); @@ -682,6 +911,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; @@ -693,6 +923,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; @@ -704,6 +935,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; @@ -715,6 +947,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; @@ -726,6 +959,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; @@ -737,6 +971,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; @@ -749,39 +984,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; @@ -797,8 +1030,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); } } @@ -806,13 +1038,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 */ @@ -827,7 +1059,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 */ @@ -842,7 +1074,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 */ @@ -858,13 +1090,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_U32 DwValue; + + /* 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_IN32(IoC, B28_Y2_ASF_STAT_CMD, &DwValue); + DwValue |= Y2_ASF_CLR_HSTI; + SK_OUT32(IoC, B28_Y2_ASF_STAT_CMD, DwValue); + /* 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%08X\n", Istatus)); + SkHwtIsr(pAC, IoC); + } +#endif /* YUK2 */ + +} /* SkYuk2SirqIsr */ #ifdef GENESIS @@ -878,8 +1286,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 */ @@ -907,9 +1315,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; } @@ -926,10 +1334,10 @@ 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->PLipaAutoNeg == SK_LIPA_UNKNOWN && + (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL)) { /* * This is autosensing and we are in the fallback @@ -939,7 +1347,7 @@ /* Nothing received, restart link */ pPrt->PPrevFcs = FcsErrCts; pPrt->PPrevShorts = Shorts; - + return(SK_HW_PS_RESTART); } else { @@ -948,7 +1356,7 @@ } 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. @@ -993,15 +1401,15 @@ */ 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) { @@ -1015,7 +1423,7 @@ if (pAC->GIni.GIGenesis) { switch (pPrt->PhyType) { - + case SK_PHY_XMAC: Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg); break; @@ -1036,7 +1444,7 @@ #ifdef YUKON if (pAC->GIni.GIYukon) { - + Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg); } #endif /* YUKON */ @@ -1057,8 +1465,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 */ @@ -1096,7 +1504,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 */ @@ -1122,7 +1530,7 @@ * check whether the link is now o.k. */ pPrt->PLinkResCt++; - + pPrt->PAutoNegTimeOut = 0; if (pPrt->PLinkResCt < SK_MAX_LRESTART) { @@ -1130,13 +1538,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)); @@ -1176,7 +1584,7 @@ } else { SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc); - + if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) { return(SK_HW_PS_RESTART); } @@ -1215,10 +1623,10 @@ /* 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)); - + /* Try next possible mode */ NextMode = SkHWSenseGetNext(pAC, IoC, Port); SkHWLinkDown(pAC, IoC, Port); @@ -1234,10 +1642,10 @@ * (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) { @@ -1281,14 +1689,14 @@ /* 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, + 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) @@ -1312,8 +1720,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 */ @@ -1332,74 +1740,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: @@ -1412,14 +1752,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! */ @@ -1429,72 +1761,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. @@ -1503,7 +1769,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)); @@ -1511,57 +1777,45 @@ 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); } } @@ -1570,29 +1824,15 @@ /* 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, + 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); } @@ -1613,14 +1853,13 @@ */ 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; @@ -1640,86 +1879,81 @@ 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) { + + 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); - + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc)); + ("Downshift detected, PhySpecStat: 0x%04X\n", PhySpecStat)); + } + + 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)); } pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; - + pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7); - + 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) { return(SK_HW_PS_RESTART); } - + return(SK_HW_PS_LINK); } } @@ -1727,7 +1961,7 @@ /* 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, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("ERROR: Lipa auto detected on port %d\n", Port)); } #endif /* DEBUG */ @@ -1735,7 +1969,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); } @@ -1756,8 +1990,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 */ @@ -1786,7 +2020,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); @@ -1800,17 +2034,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); @@ -1831,7 +2069,7 @@ 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) { @@ -1854,7 +2092,7 @@ /* 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, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("ERROR: Lipa auto detected on port %d\n", Port)); } #endif /* DEBUG */ @@ -1864,11 +2102,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); } @@ -1887,8 +2126,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 */ @@ -1907,7 +2146,7 @@ */ 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 */ { @@ -1926,7 +2165,7 @@ switch (Event) { case SK_HWEV_WATIM: if (pPrt->PState == SK_PRT_RESET) { - + PortStat = SK_HW_PS_NONE; } else { @@ -1956,19 +2195,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: @@ -1988,6 +2231,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: @@ -2095,11 +2339,11 @@ (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); @@ -2108,7 +2352,7 @@ } break; #endif /* GENESIS */ - + default: SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG); break; @@ -2129,8 +2373,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 */ @@ -2143,7 +2387,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); @@ -2172,8 +2416,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 */ @@ -2182,37 +2426,62 @@ 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, + ("PHY IRQ, PhyIsrc: 0x%04X\n", 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", IStatus)); + 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); } - + 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 */ @@ -2228,8 +2497,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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/ski2c.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/ski2c.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/ski2c.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/ski2c.c Thu Jan 1 01:00:00 1970 @@ -1,1294 +0,0 @@ -/****************************************************************************** - * - * Name: ski2c.c - * Project: Gigabit Ethernet Adapters, TWSI-Module - * 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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/sklm80.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/sklm80.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/sklm80.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/sklm80.c Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: sklm80.c * Project: Gigabit Ethernet Adapters, TWSI-Module + * Version: $Revision: 1.1 $ + * Date: $Date: 2003/12/19 14:02:31 $ * Purpose: Functions to access Voltage and Temperature Sensor (LM80) * ******************************************************************************/ @@ -25,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 */ @@ -109,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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skproc.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skproc.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skproc.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skproc.c Sun Feb 6 22:21:26 2005 @@ -2,26 +2,36 @@ * * Name: skproc.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Purpose: Funktions to display statictic data + * Version: $Revision: 1.14.2.2 $ + * Date: $Date: 2004/11/23 19:42:25 $ + * Purpose: Functions to display statictic data * ******************************************************************************/ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2004 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 + * + * The technical manual for the adapters is available from SysKonnect's + * web pages: www.syskonnect.com + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * - * Created 22-Nov-2000 - * Author: Mirko Lindner (mlindner@syskonnect.de) - * * The information in this file is provided "AS IS" without warranty. * - ******************************************************************************/ + *****************************************************************************/ #include @@ -30,9 +40,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; struct proc_dir_entry *file = NULL; @@ -41,19 +58,21 @@ * sk_proc_read - 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 * */ -int sk_proc_read(char *buffer, - char **buffer_location, - off_t offset, - int buffer_length, - int *eof, - void *data) +int sk_proc_read( +char *buffer, /* the buffer holding the display results */ +char **buffer_location, /* the buffer location */ +off_t offset, /* additional offset */ +int buffer_length, /* total buffer length */ +int *eof, /* End Of File (EOF) indication */ +void *data) /* the data pointer */ { void *castedBuffer = (void *) buffer; file = (struct proc_dir_entry*) data; @@ -77,16 +96,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; @@ -94,6 +115,7 @@ DEV_NET *pNet; SK_AC *pAC; char sens_msg[50]; + int card_type; int MaxSecurityCount = 0; int t; int i; @@ -116,7 +138,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) { @@ -125,13 +147,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, file->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", @@ -143,6 +165,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); @@ -151,177 +184,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) */ } @@ -331,16 +426,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]; diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skqueue.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skqueue.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skqueue.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skqueue.c Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skqueue.c * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 2.3 $ + * Date: $Date: 2004/05/14 13:28:18 $ * Purpose: Management of an event queue. * ******************************************************************************/ @@ -20,12 +22,13 @@ * ******************************************************************************/ + /* * Event queue and dispatcher */ #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 */ @@ -45,10 +48,16 @@ #define PRINTF(a,b,c) -/* - * init event queue management +/****************************************************************************** * - * Must be called during init level 0. + * SkEventInit() - init event queue management + * + * Description: + * This function initializes event queue management. + * It must be called during init level 0. + * + * Returns: + * nothing */ void SkEventInit( SK_AC *pAC, /* Adapter context */ @@ -64,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 */ @@ -73,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 */ @@ -102,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); @@ -149,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); @@ -160,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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skrlmt.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skrlmt.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skrlmt.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skrlmt.c Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skrlmt.c * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 2.2 $ + * Date: $Date: 2003/11/24 12:27:57 $ * Purpose: Manage links on SK-NET Adapters, esp. redundant ones. * ******************************************************************************/ @@ -37,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.2 2003/11/24 12:27:57 mkarl Exp $ (C) Marvell."; #endif /* !defined(lint) */ #define __SKRLMT_C @@ -348,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. */ @@ -388,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; @@ -510,7 +512,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SkRlmtBuildCheckChain.\n")) + ("SkRlmtBuildCheckChain.\n")); NumMacsUp = 0; @@ -556,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 */ @@ -602,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 @@ -794,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; @@ -833,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); @@ -847,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; */ @@ -894,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; @@ -915,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; @@ -953,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); @@ -961,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); @@ -1005,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; @@ -1013,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( @@ -1044,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++; @@ -1063,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; @@ -1086,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); @@ -1095,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); @@ -1105,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++; @@ -1137,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); @@ -1148,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); @@ -1230,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 @@ -1247,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); @@ -1293,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) { @@ -1343,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) { @@ -1356,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++) { @@ -1371,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; } } @@ -1383,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 */ @@ -1432,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; } } @@ -1481,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; } } @@ -1542,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 */ @@ -1588,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; } } @@ -1786,7 +1788,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; @@ -1866,7 +1868,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; @@ -1961,13 +1963,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; } @@ -1988,7 +1990,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 */ @@ -2016,21 +2018,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; } @@ -2108,7 +2110,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 */ @@ -2134,20 +2136,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; } @@ -2162,7 +2164,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 */ @@ -2190,13 +2192,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; } @@ -2204,7 +2206,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; } @@ -2241,7 +2243,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 */ @@ -2268,7 +2270,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--; @@ -2287,7 +2289,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 */ @@ -2316,13 +2318,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; } @@ -2346,7 +2348,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 */ @@ -2374,35 +2376,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; } @@ -2436,7 +2438,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 */ @@ -2464,35 +2466,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; } @@ -2527,7 +2529,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 */ @@ -2557,13 +2559,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; } @@ -2635,7 +2637,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_TIM Event END.\n")) + ("SK_RLMT_TIM Event END.\n")); } /* SkRlmtEvtTim */ @@ -2663,13 +2665,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; } @@ -2693,7 +2695,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 */ @@ -2701,7 +2703,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 */ @@ -2730,18 +2732,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 */ @@ -2759,7 +2761,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 */ @@ -2786,21 +2788,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; } @@ -2815,7 +2817,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 */ @@ -2839,28 +2841,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 */ @@ -2884,13 +2886,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; } @@ -2903,7 +2905,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; } @@ -2917,7 +2919,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 */ @@ -2943,37 +2945,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; } @@ -3004,7 +3006,7 @@ 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.Port[1].Net= &pAC->Rlmt.Net[1]; @@ -3033,19 +3035,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 */ @@ -3073,13 +3075,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; } @@ -3089,9 +3091,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; } @@ -3157,7 +3159,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 */ @@ -3243,7 +3245,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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/sktimer.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/sktimer.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/sktimer.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/sktimer.c Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: sktimer.c * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 2.2 $ + * Date: $Date: 2004/05/28 13:44:39 $ * Purpose: High level timer functions. * ******************************************************************************/ @@ -9,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 @@ -25,7 +27,7 @@ */ #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 */ @@ -82,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; @@ -118,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 */ @@ -127,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; @@ -140,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 = 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; @@ -176,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; } @@ -207,7 +195,7 @@ int Done = 0; Delta = SkHwtRead(pAC, Ioc); - + ppLast = &pAC->Tim.StQueue; pTm = pAC->Tim.StQueue; while (pTm && !Done) { @@ -231,7 +219,7 @@ * 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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/sktwsi.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/sktwsi.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/sktwsi.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/sktwsi.c Sun Feb 6 22:21:26 2005 @@ -0,0 +1,1340 @@ +/****************************************************************************** + * + * Name: sktwsi.c + * Project: Gigabit Ethernet Adapters, TWSI-Module + * Version: $Revision: 1.8 $ + * Date: $Date: 2004/10/26 09:26:08 $ + * 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.8 2004/10/26 09:26:08 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; + + /* 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++) { + 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) { + /* 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++) { + 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; + if (pAC->GIni.GIPciBus != SK_PEX_BUS) { + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR; + } + else { + pAC->I2c.SenTable[i].SenThreWarnLow = 0; + pAC->I2c.SenTable[i].SenThreErrLow = 0; + } + 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; + if (pAC->GIni.GIPciBus != SK_PEX_BUS) { + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR; + } + else { + pAC->I2c.SenTable[i].SenThreWarnLow = 0; + pAC->I2c.SenTable[i].SenThreErrLow = 0; + } + 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 = 0; + pAC->I2c.SenTable[i].SenThreWarnLow = 0; + } + } + pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; + pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN; + break; + case 5: + if (CHIP_ID_YUKON_2(pAC)) { + if (pAC->GIni.GIChipRev == 0) { + pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V3"; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V3_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V3_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V3_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V3_LOW_ERR; + } + else { + pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V2"; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V2_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V2_HIGH_WARN; + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V2_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V2_LOW_ERR; + } + } + else { + 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 (CHIP_ID_YUKON_2(pAC)) { + pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 1V5"; + pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR; + pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN; + if (pAC->GIni.GIPciBus == SK_PEX_BUS) { + pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN; + pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR; + } + else { + pAC->I2c.SenTable[i].SenThreWarnLow = 0; + pAC->I2c.SenTable[i].SenThreErrLow = 0; + } + } + else { + 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].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].SenType = SK_SEN_VOLT; + 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 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 */ + + /* 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 -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skvpd.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skvpd.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skvpd.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skvpd.c Sun Feb 6 22:21:26 2005 @@ -1,20 +1,22 @@ /****************************************************************************** * * Name: skvpd.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * 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. * ******************************************************************************/ @@ -23,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" @@ -57,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) { @@ -79,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. @@ -122,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. @@ -149,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 @@ -187,7 +189,8 @@ return(0); } /* VpdWriteDWord */ -#endif /* 0 */ +#endif /* XXX */ + /* * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from @@ -213,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 @@ -231,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); @@ -248,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)); } /* @@ -263,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); } } } @@ -282,7 +284,7 @@ return(Len); } - + /* * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from @@ -302,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); @@ -316,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. @@ -348,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, @@ -372,8 +374,8 @@ return(Rtv); } -#ifdef SKDIAG +#if defined (SK_DIAG) || defined (SK_ASF) /* * Read 'len' bytes of VPD data, starting at 'addr'. * @@ -389,6 +391,7 @@ return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ)); } + /* * Write 'len' bytes of *but to the VPD EEPROM, starting at 'addr'. * @@ -403,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 */ { @@ -425,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 @@ -463,18 +475,25 @@ ("Block Read Error\n")); return(1); } - + pAC->vpd.vpd_size = vpd_size; + /* Asus K8V Se Deluxe bugfix. Correct VPD content */ + i = 62; + if (!SK_STRNCMP(pAC->vpd.vpd_buf + i, " 8vpd.vpd_buf[i + 2] = '8'; + } + /* find the end tag of the RO area */ if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) { SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, ("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); } @@ -484,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, @@ -498,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")); @@ -518,6 +537,7 @@ return(0); } + /* * find the Keyword 'key' in the VPD buffer and fills the * parameter struct 'p' with it's values @@ -528,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 */ @@ -546,7 +566,7 @@ 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, @@ -556,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, @@ -566,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 { @@ -590,6 +610,7 @@ return(0); } + /* * Move 'n' bytes. Begin with the last byte if 'n' is > 0, * Start with the last byte if n is < 0. @@ -624,6 +645,7 @@ } } + /* * setup the VPD keyword 'key' at 'ip'. * @@ -640,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. @@ -669,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); } @@ -701,6 +724,7 @@ return(0); } + /* * Insert a VPD keyword into the VPD buffer. * @@ -734,7 +758,7 @@ 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; @@ -862,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); } @@ -881,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; @@ -978,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' @@ -1013,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")); @@ -1029,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, @@ -1046,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 @@ -1069,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, @@ -1106,6 +1132,7 @@ return(0); } + /* * If the VPD buffer contains valid data write the VPD * read/write area back to the VPD EEPROM. @@ -1136,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 @@ -1165,7 +1191,7 @@ } } - len = strlen(msg); + len = SK_STRLEN(msg); if (len > VPD_MAX_LEN) { /* cut it */ len = VPD_MAX_LEN; diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skxmac2.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skxmac2.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/skxmac2.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/skxmac2.c Sun Feb 6 22:21:26 2005 @@ -2,6 +2,8 @@ * * Name: skxmac2.c * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.31 $ + * Date: $Date: 2005/01/04 14:22:28 $ * Purpose: Contains functions to initialize the MACs and PHYs * ******************************************************************************/ @@ -9,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. * ******************************************************************************/ @@ -35,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.31 2005/01/04 14:22:28 rschmidt Exp $ (C) Marvell."; #endif #ifdef GENESIS @@ -81,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) */ @@ -92,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); @@ -108,6 +109,8 @@ /* get the PHY register's value */ XM_IN16(IoC, Port, XM_PHY_DATA, pVal); } + + return(0); } /* SkXmPhyRead */ @@ -120,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) */ @@ -131,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 */ @@ -165,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) */ @@ -174,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 */ @@ -232,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) */ @@ -241,54 +266,70 @@ { 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; + 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 */ @@ -310,16 +351,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 */ @@ -339,16 +372,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 */ @@ -358,15 +383,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 */ { @@ -375,11 +400,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) { @@ -392,12 +417,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); @@ -418,28 +443,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) { @@ -452,12 +477,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; @@ -485,8 +510,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. @@ -497,11 +522,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; @@ -509,7 +534,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; @@ -570,8 +595,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. @@ -582,20 +607,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; @@ -603,17 +625,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; @@ -621,10 +639,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 */ @@ -639,17 +655,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); } @@ -666,15 +682,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) { @@ -687,9 +703,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; } @@ -719,14 +735,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) { @@ -736,7 +752,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 */ @@ -753,21 +769,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 */ @@ -789,8 +805,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 @@ -803,7 +819,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 */ @@ -851,23 +867,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: @@ -885,13 +901,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 */ @@ -914,8 +930,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; @@ -938,17 +954,17 @@ } 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_IO_0; /* set PHY reset (active low) */ @@ -976,12 +992,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); @@ -998,7 +1014,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 */ @@ -1018,8 +1034,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}; @@ -1028,19 +1044,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 */ @@ -1055,16 +1070,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); @@ -1074,10 +1089,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 */ @@ -1092,24 +1107,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 */ @@ -1119,30 +1137,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 */ - /* set GPHY Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET); + if (CHIP_ID_YUKON_2(pAC)) { + /* set GPHY Control reset */ + SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)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 */ @@ -1160,37 +1222,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 */ @@ -1205,21 +1263,21 @@ * 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 */ @@ -1239,21 +1297,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 */ @@ -1277,8 +1335,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; @@ -1294,7 +1352,8 @@ 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; } @@ -1313,7 +1372,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) { @@ -1346,7 +1405,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)); @@ -1355,7 +1414,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 @@ -1381,7 +1440,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); } @@ -1434,7 +1493,7 @@ */ SWord |= XM_RX_DIS_CEXT; } - + XM_OUT16(IoC, Port, XM_RX_CMD, SWord); /* @@ -1491,8 +1550,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; @@ -1506,21 +1565,27 @@ /* 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 */ @@ -1530,10 +1595,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 { @@ -1544,7 +1609,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; @@ -1562,8 +1630,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; @@ -1581,24 +1647,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); @@ -1608,18 +1675,16 @@ 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 */ @@ -1630,9 +1695,9 @@ /* 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: @@ -1661,15 +1726,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); } @@ -1682,18 +1747,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 */ @@ -1712,8 +1765,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) { @@ -1760,8 +1813,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; @@ -1771,11 +1824,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 { @@ -1783,10 +1836,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); @@ -1809,10 +1862,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 { @@ -1820,13 +1873,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*/ @@ -1843,8 +1896,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? */ { @@ -1853,12 +1906,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; } @@ -1871,9 +1924,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; @@ -1889,7 +1942,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; @@ -1916,7 +1969,7 @@ } if (DoLoop) { - /* Set the Phy Loopback bit, too */ + /* set the Phy Loopback bit, too */ Ctrl |= PHY_CT_LOOP; } @@ -1937,8 +1990,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? */ { @@ -1960,7 +2013,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; } @@ -1969,7 +2022,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; } @@ -1987,7 +2040,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. @@ -1995,8 +2048,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; @@ -2012,7 +2065,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; @@ -2034,23 +2087,23 @@ /* 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; } @@ -2066,7 +2119,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, @@ -2076,17 +2129,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. * @@ -2113,114 +2166,157 @@ * 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_U16 Word; SK_U32 DWord; + SK_U32 PowerDownBit; 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 = 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); - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - /* - * 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; + 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 */ + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) { + /* set IEEE compatible Power Down Mode */ + Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PHY_CT_PDOWN); - /* don't change current power mode */ - default: - pAC->GIni.GP[Port].PPhyPowerState = LastMode; - Ret = 1; - break; + Word = 0; /* divide clock by 2 */ + } + else { + Word = 1; /* divide clock by 4 */ + } + + /* enable Core Clock Division */ + SK_OUT32(IoC, B2_Y2_CLK_CTRL, + ((pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) ? + (Y2_CLK_DIV_VAL_2(Word) | Y2_CLK_SEL_VAL_2(Y2_CLK_SELECT2_MSK)) : + Y2_CLK_DIV_VAL(Word)) | Y2_CLK_DIV_ENA); + + /* ASF system clock stopped */ + SK_OUT8(IoC, B28_Y2_ASF_STAT_CMD, Y2_ASF_CLK_HALT); } - } - /* low power modes are not supported by this chip */ - else { + 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) { + + SK_IN16(IoC, PCI_C(pAC, PCI_PM_CTL_STS), &Word); + + /* switch to D1 state */ + SK_OUT16(IoC, PCI_C(pAC, PCI_PM_CTL_STS), Word | PCI_PM_STATE_D1); + } + + 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); @@ -2231,7 +2327,7 @@ * * SkGmLeaveLowPowerMode() * - * Description: + * Description: * Leave the current low power mode and switch to normal mode * * Note: @@ -2241,115 +2337,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 */ /****************************************************************************** * @@ -2363,74 +2490,163 @@ * 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; +#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 */ 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(0) | PHY_M_EC_DOWN_S_ENA; + } + else { + ExtPhyCtrl |= 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)); + } } - 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 (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(0) | 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 register */ + 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; @@ -2440,30 +2656,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; @@ -2475,38 +2692,67 @@ 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 */ + SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_PAUSE_OFF); + } + else { + /* set Pause On */ + SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_PAUSE_ON); + } + 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; @@ -2522,8 +2768,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; @@ -2543,8 +2789,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; @@ -2559,8 +2805,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; @@ -2585,52 +2831,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 @@ -2643,27 +2888,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); + + /* 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))); - if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) { - LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL; + /* 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); @@ -2676,30 +2977,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, @@ -2716,6 +3020,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 */ @@ -2735,8 +3041,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? */ { @@ -2754,7 +3060,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; } @@ -2767,7 +3073,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; } @@ -2776,7 +3082,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 @@ -2785,9 +3090,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; @@ -2803,7 +3108,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; @@ -2825,19 +3130,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; } @@ -2860,8 +3165,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? */ { @@ -2882,8 +3187,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? */ { @@ -2893,7 +3198,7 @@ #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + switch (pPrt->PhyType) { case SK_PHY_XMAC: SkXmInitPhyXmac(pAC, IoC, Port, DoLoop); @@ -2912,10 +3217,10 @@ } } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { - + SkGmInitPhyMarv(pAC, IoC, Port, DoLoop); } #endif /* YUKON */ @@ -2937,8 +3242,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; @@ -2956,10 +3261,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); } @@ -2972,7 +3277,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); @@ -2982,19 +3287,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 { @@ -3020,8 +3325,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; @@ -3043,12 +3348,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); @@ -3063,23 +3368,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 */ @@ -3091,11 +3396,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 { @@ -3123,8 +3428,8 @@ * 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; @@ -3140,76 +3445,104 @@ 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; - + /* 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, + 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); - } - - 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; + return(SK_AND_DUP_CAP); } - - /* 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; + + 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 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; + else { + /* 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; + } } - 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; + + 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 */ + SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_PAUSE_OFF); } 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; + /* set Pause On */ + SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_PAUSE_ON); } return(SK_AND_OK); @@ -3231,8 +3564,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; @@ -3251,8 +3584,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); @@ -3265,11 +3597,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; @@ -3286,7 +3618,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 */ @@ -3294,7 +3626,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; @@ -3307,7 +3639,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) { @@ -3319,7 +3651,7 @@ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, SKERR_HWI_E016MSG); } - + return(SK_AND_OK); } /* SkXmAutoNegDoneLone */ @@ -3337,8 +3669,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 */ @@ -3358,9 +3690,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; @@ -3372,9 +3704,9 @@ #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + switch (pPrt->PhyType) { - + case SK_PHY_XMAC: Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port); break; @@ -3394,26 +3726,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 */ @@ -3431,7 +3763,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 */ { @@ -3456,7 +3788,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; @@ -3465,7 +3797,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 */ @@ -3488,12 +3820,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)) { @@ -3513,12 +3845,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 */ @@ -3535,20 +3868,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 */ @@ -3568,8 +3901,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; @@ -3587,9 +3920,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); } @@ -3598,9 +3931,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 @@ -3616,23 +3949,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: /* @@ -3642,7 +3975,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 @@ -3656,12 +3989,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) { /* @@ -3676,30 +4009,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 */ @@ -3715,33 +4048,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 */ @@ -3758,7 +4096,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; @@ -3770,18 +4108,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)); @@ -3800,16 +4138,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 */ @@ -3821,29 +4159,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 */ @@ -3858,8 +4239,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 */ { @@ -3904,8 +4285,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 */ { @@ -3919,6 +4300,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 */ @@ -3934,8 +4316,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 */ { @@ -3949,6 +4331,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 */ @@ -3963,7 +4346,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 @@ -3975,8 +4358,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; @@ -3984,13 +4367,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); @@ -4001,7 +4384,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)); @@ -4111,40 +4494,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) { @@ -4183,8 +4566,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 @@ -4193,7 +4576,7 @@ SkXmIrq(pAC, IoC, Port); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { /* IRQ from GMAC */ @@ -4220,8 +4603,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; @@ -4243,7 +4626,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); @@ -4251,7 +4634,7 @@ return(1); } } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0); - + return(0); } /* SkXmUpdateStats */ @@ -4270,19 +4653,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); @@ -4301,12 +4684,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); @@ -4333,11 +4716,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; @@ -4349,7 +4732,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); @@ -4376,8 +4759,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); @@ -4398,24 +4781,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 */ @@ -4432,8 +4818,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 */ @@ -4444,16 +4830,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 */ @@ -4467,48 +4853,62 @@ * resulting counter overflow status is written to , 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 */ @@ -4524,57 +4924,110 @@ * 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) { /* 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)); @@ -4585,16 +5038,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) { + /* get next register */ + CableDiagOffs++; + } } return(0); @@ -4603,3 +5064,4 @@ #endif /* YUKON */ /* End of file */ + diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/sky2.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/sky2.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/sky2.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/sky2.c Sun Feb 6 22:21:26 2005 @@ -0,0 +1,2707 @@ +/****************************************************************************** + * + * Name: sky2.c + * Project: Yukon2 specific functions and implementations + * Version: $Revision: 1.35.2.26 $ + * Date: $Date: 2004/12/22 12:48:48 $ + * Purpose: The main driver source module + * + *****************************************************************************/ + +/****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2004 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 + * + * The technical manual for the adapters is available from SysKonnect's + * web pages: www.syskonnect.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. + * + *****************************************************************************/ + +#include "h/skdrv1st.h" +#include "h/skdrv2nd.h" +#include + +/****************************************************************************** + * + * 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; +#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) { + 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; + + } + +#ifdef CONFIG_SK98LIN_NAPI + if (netif_rx_schedule_prep(dev)) { + pAC->GIni.GIValIrqMask &= ~(Y2_IS_STAT_BMU); + SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); + __netif_rx_schedule(dev); + } +#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; +} /* 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; + 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; + } + + /* + ** 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) */ + + 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->RxBufSize) { + IsGoodPkt = SK_FALSE; + } + + /* + ** take first receive buffer out of working queue + */ + POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket); + 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->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->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; + 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 { /* 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;CurrBuffpFrag = &(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;CurrBuffTxPort[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->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->RxBufSize, + PCI_DMA_FROMDEVICE); + + pSkPacket->pFrag->pVirt = pMsgBlock->data; + pSkPacket->pFrag->pPhys = PhysAddr; + pSkPacket->pFrag->FragLen = pAC->RxBufSize; /* for correct unmap */ + pSkPacket->pMBuf = pMsgBlock; + pSkPacket->PacketLen = pAC->RxBufSize; + + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("<-- AllocAndMapRxBuffer\n")); + + return (SK_TRUE); +} /* AllocAndMapRxBuffer */ + +/******************************************************************************* + * + * End of file + * + ******************************************************************************/ diff -urN linux-2.4.29-wt1-2xx/drivers/net/sk98lin/sky2le.c linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/sky2le.c --- linux-2.4.29-wt1-2xx/drivers/net/sk98lin/sky2le.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-wt1-syskonnect/drivers/net/sk98lin/sky2le.c Sun Feb 6 22:21:26 2005 @@ -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 */ +